xfer parallel build, reload vwindow, snap/grab fixes, shader memeory leak
authorGood Guy <[email protected]>
Thu, 1 Feb 2018 20:50:09 +0000 (13:50 -0700)
committerGood Guy <[email protected]>
Thu, 1 Feb 2018 20:50:09 +0000 (13:50 -0700)
13 files changed:
cinelerra-5.1/cinelerra/assetpopup.C
cinelerra-5.1/cinelerra/mwindow.C
cinelerra-5.1/cinelerra/vwindow.C
cinelerra-5.1/cinelerra/vwindow.h
cinelerra-5.1/configure.ac
cinelerra-5.1/guicast/Makefile
cinelerra-5.1/guicast/bccmdl.py
cinelerra-5.1/guicast/bcxfer.C [new file with mode: 0644]
cinelerra-5.1/guicast/bcxfer.h [new file with mode: 0644]
cinelerra-5.1/guicast/vframe3d.C
cinelerra-5.1/guicast/xfer.C [deleted file]
cinelerra-5.1/guicast/xfer.h [deleted file]
cinelerra-5.1/guicast/xfer/Makefile [new file with mode: 0644]

index d39aaa13e5c96be7ce326c0119bb8c2c1a402bb8..1afb19e4580940c2b98b1d20a19755f19b3d1fc7 100644 (file)
@@ -809,7 +809,8 @@ int SnapshotMenuItem::handle_event()
 
                double position = edl->local_session->get_selectionstart(1);
                int64_t source_position = (int64_t)(position * edl->get_frame_rate());
-               ret = render_engine.vrender->process_buffer(frame, source_position, 0);
+               ret = !render_engine.vrender ? 1 :
+                       render_engine.vrender->process_buffer(frame, source_position, 0);
                if( !ret )
                        ret = file.write_video_buffer(1);
                file.close_file();
@@ -965,6 +966,7 @@ int GrabshotPopup::grab_event(XEvent *event)
        int cw = lx1-lx0, ch = ly1-ly0;
        hide_window();
        sync_display();
+       grab_thread->done = 1;
 
        MWindow *mwindow = grab_thread->mwindow;
        Preferences *preferences = mwindow->preferences;
@@ -996,12 +998,15 @@ int GrabshotPopup::grab_event(XEvent *event)
                asset->format = FILE_PPM;
                break;
        }
+
 // no odd dimensions
        int rw = get_root_w(0), rh = get_root_h(0);
        if( cx < 0 ) { cw += cx;  cx = 0; }
        if( cy < 0 ) { ch += cy;  cy = 0; }
        if( cx+cw > rw ) cw = rw-cx;
        if( cy+ch > rh ) ch = rh-cy;
+       if( !cw || !ch ) return 1;
+
        VFrame vframe(cw,ch, BC_RGB888);
        if( cx+cw < rw ) ++cw;
        if( cy+ch < rh ) ++ch;
@@ -1040,7 +1045,6 @@ int GrabshotPopup::grab_event(XEvent *event)
                asset->remove_user();
        }
 
-       grab_thread->done = 1;
        return 1;
 }
 
index 1f69fd504e785390946c478552a394248a75945b..d14f228c14754e29d1f26826bbd824636d5f3d9f 100644 (file)
@@ -3280,6 +3280,10 @@ void MWindow::update_project(int load_mode)
                        if( !vwindow->is_running() ) continue;
                        vwindow->close_window();
                }
+               for( int i=0; i<edl->vwindow_edls.size(); ++i ) {
+                       VWindow *vwindow = get_viewer(1, -1);
+                       vwindow->change_source(i);
+               }
                if(debug) PRINT_TRACE
                select_zwindow(0);
                close_mixers();
index 8de4eb73170154add8af0a090bb621e81107e84c..1bb3f0c355a29c8358630acdc719dc1939ef7991 100644 (file)
@@ -137,8 +137,6 @@ void VWindow::handle_done_event(int result)
        }
 }
 
-
-
 BC_Window* VWindow::new_gui()
 {
 //printf("VWindow::create_objects 1\n");
@@ -164,6 +162,12 @@ BC_Window* VWindow::new_gui()
        return gui;
 }
 
+void VWindow::handle_close_event(int result)
+{
+       delete playback_engine;
+       playback_engine = 0;
+}
+
 
 EDL* VWindow::get_edl()
 {
index a9ee980ad88628d915103481769c374913c75d08..a858d5c0e22ab3b095bb65379fdb7ceffca94cad 100644 (file)
@@ -41,6 +41,7 @@ public:
        ~VWindow();
 
        void handle_done_event(int result);
+       void handle_close_event(int result);
        BC_Window* new_gui();
 
        void load_defaults();
index dcfd41d4e82f5b2247cd016dec432b4dc353dec3..70326a93886138ff9f7009937f8312a3e9164e54 100644 (file)
@@ -9,7 +9,13 @@ AC_LANG_C
 AC_PROG_CXX
 
 CFG_CFLAGS+=" -fno-omit-frame-pointer -fno-math-errno -fno-signed-zeros"
-CFG_CFLAGS+=" -pthread -Wall -Wno-unused-result -Wno-format-truncation"
+CFG_CFLAGS+=" -pthread -Wall"
+# misguided pedantic warnings
+CFG_CFLAGS+=" -Wno-unused-result"
+CFG_CFLAGS+=" -Wno-stringop-truncation"
+CFG_CFLAGS+=" -Wno-stringop-overflow"
+CFG_CFLAGS+=" -Wno-format-truncation"
+CFG_CFLAGS+=" -Wno-format-overflow"
 CFG_CFLAGS+=" -D__STDC_CONSTANT_MACROS"
 CFG_CFLAGS+=" -D__STDC_LIMIT_MACROS"
 CFG_CFLAGS+=" -DPNG_SKIP_SETJMP_CHECK=1"
index 43404b597c92dd97e4c7688b935f76c8a2f70776..c1e036599456e2b005e18aadfa9deb633e87e68c 100644 (file)
@@ -65,7 +65,6 @@ OBJS = \
        $(OBJDIR)/bcwindowbase.o \
        $(OBJDIR)/bcwindowdraw.o \
        $(OBJDIR)/bcwindowevents.o \
-       $(OBJDIR)/bcxfer.o \
        $(OBJDIR)/condition.o \
        $(OBJDIR)/errorbox.o \
        $(OBJDIR)/filesystem.o \
@@ -83,6 +82,7 @@ OBJS = \
 OUTPUT = $(OBJDIR)/libguicast.a
 
 UTILS = $(OBJDIR)/bootstrap $(OBJDIR)/pngtoh $(OBJDIR)/pngtoraw
+BCXFER = xfer/$(OBJDIR)/xfer.o
 
 CFLAGS += -I/usr/include/freetype2
 
@@ -91,14 +91,13 @@ $(shell echo $(OBJS) > $(OBJDIR)/objs)
 
 all: $(OUTPUT) $(UTILS)
 
-$(OBJDIR)/bcxfer.o:    bcxfer.C xfer.C xfer.h
-       $(CXX) `cat $(OBJDIR)/c_flags` -O3 -c $< -o $@
+$(BCXFER):     bccmdl.py bcxfer.C bcxfer.h
+       python2.7 < ./bccmdl.py
+       +make -C xfer
 
-bcxfer.C:      bccmdl.py
-       python2.7 < ./bccmdl.py > bcxfer.C
-
-$(OUTPUT): $(OBJS)
-       ar rcs $(OUTPUT) `cat $(OBJDIR)/objs`
+$(OUTPUT): $(OBJS) $(BCXFER)
+       ar rc $(OUTPUT) `cat $(OBJDIR)/objs` `ls -1 $(dir $(BCXFER))/xfer*.o`
+       ar rs $(OUTPUT) `ls -1 $(dir $(BCXFER))/xfer*.o`
 
 $(OBJDIR)/bootstrap:
        gcc -O2 $(BOOTSTRAPFLAGS) bootstrap.c -o $(OBJDIR)/bootstrap
@@ -111,7 +110,7 @@ $(OBJDIR)/pngtoraw: pngtoraw.c
 
 clean:
        rm -rf $(OBJDIR)
-       rm -f bcxfer.C
+       make -C xfer clean
 
 install:
 
index 4c184bd060470dc397228a4dccbc169dcff35d3e..bae50c50a119b5c9245e702a89d7d5b833f1e030 100755 (executable)
@@ -554,21 +554,21 @@ def is_planar(nm):
 def is_float(nm):
   return nm in ["bc_rgb_float", "bc_rgba_float", "bc_rgb_floatp", "bc_rgba_floatp", ]
 
-def gen_xfer_proto(pfx, cls, fr_cmdl, to_cmdl):
+def gen_xfer_proto(fd, pfx, cls, fr_cmdl, to_cmdl):
   global dtype, ctype
-  print "%svoid %sxfer_%s_to_%s" % (pfx, cls, fr_cmdl[3:], to_cmdl[3:]),
+  print >>fd, "%svoid %sxfer_%s_to_%s" % (pfx, cls, fr_cmdl[3:], to_cmdl[3:]),
   ityp = dtype[fr_cmdl];  fr_typ = ctype[ityp];
   otyp = dtype[to_cmdl];  to_typ = ctype[otyp];
-  print "(unsigned y0, unsigned y1)",
+  print >>fd, "(unsigned y0, unsigned y1)",
 
-def gen_xfer_fn(fr_cmdl, to_cmdl):
+def gen_xfer_fn(fd, fr_cmdl, to_cmdl):
   global layout, dtype, adata
   ityp = dtype[fr_cmdl];  otyp = dtype[to_cmdl]
   if( ityp is None or otyp is None ): return
   # xfr fn header
-  gen_xfer_proto("", class_qual, fr_cmdl, to_cmdl);
+  gen_xfer_proto(fd, "", class_qual, fr_cmdl, to_cmdl);
   # xfr fn body
-  print "{"
+  print >>fd, "{"
   # loops / pointer preload
   in_xfer = "flat" if not is_planar(fr_cmdl) else \
     fr_cmdl[3:] if is_yuv(fr_cmdl) else \
@@ -576,105 +576,122 @@ def gen_xfer_fn(fr_cmdl, to_cmdl):
   out_xfer = "flat" if not is_planar(to_cmdl) else \
     to_cmdl[3:] if is_yuv(to_cmdl) else \
     "rgbp" if not has_alpha(to_cmdl) else "rgbap"
-  print " xfer_%s_row_out(%s) xfer_%s_row_in(%s)" % \
+  print >>fd, " xfer_%s_row_out(%s) xfer_%s_row_in(%s)" % \
      (out_xfer, ctype[otyp], in_xfer, ctype[ityp],)
   # load inp
   if( is_float(to_cmdl) and is_yuv(fr_cmdl) ):
-    for ic in layout[fr_cmdl]: print "%s" % (base[ic][ityp]['r']),
+    for ic in layout[fr_cmdl]: print >>fd, "%s" % (base[ic][ityp]['r']),
     if( ityp == "i8" ):
-      print "\n float r, g, b; YUV::yuv.yuv_to_rgb_8(r, g, b, y, u, v);",
+      print >>fd, "\n float r, g, b; YUV::yuv.yuv_to_rgb_8(r, g, b, y, u, v);",
     elif( ityp == "i16" ):
-      print "\n float r, g, b; YUV::yuv.yuv_to_rgb_16(r, g, b, y, u, v);",
+      print >>fd, "\n float r, g, b; YUV::yuv.yuv_to_rgb_16(r, g, b, y, u, v);",
     if( has_alpha(fr_cmdl) or has_alpha(to_cmdl) ):
       if( not has_alpha(fr_cmdl) ):
-        print " z_float fa = 1;",
+        print >>fd, " z_float fa = 1;",
       elif( ityp == "i8" ):
-        print " float fa = fclp(a,256);",
+        print >>fd, " float fa = fclp(a,256);",
       elif( ityp == "i16" ):
-        print " float fa = fclp(a,65536);",
+        print >>fd, " float fa = fclp(a,65536);",
   else:
-    for ic in layout[fr_cmdl]: print "%s" % (base[ic][otyp]['r']),
+    for ic in layout[fr_cmdl]: print >>fd, "%s" % (base[ic][otyp]['r']),
     if( has_alpha(to_cmdl) and not has_alpha(fr_cmdl) ):
-      print "%s" % (adata[otyp]),
-  print ""
+      print >>fd, "%s" % (adata[otyp]),
+  print >>fd, ""
   # xfer
   if( is_rgb(fr_cmdl) and is_yuv(to_cmdl) ):
     if( otyp == "i8" ):
-      print " int32_t y, u, v;  YUV::yuv.rgb_to_yuv_8(r, g, b, y, u, v);"
+      print >>fd, " int32_t y, u, v;  YUV::yuv.rgb_to_yuv_8(r, g, b, y, u, v);"
     elif( otyp == "i16" ):
-      print " int32_t y, u, v;  YUV::yuv.rgb_to_yuv_16(r, g, b, y, u, v);"
+      print >>fd, " int32_t y, u, v;  YUV::yuv.rgb_to_yuv_16(r, g, b, y, u, v);"
   elif( is_yuv(fr_cmdl) and is_rgb(to_cmdl)):
     if( otyp == "i8" ):
-      print " int32_t r, g, b;  YUV::yuv.yuv_to_rgb_8(r, g, b, y, u, v);"
+      print >>fd, " int32_t r, g, b;  YUV::yuv.yuv_to_rgb_8(r, g, b, y, u, v);"
     elif( otyp == "i16" ):
-      print " int32_t r, g, b;  YUV::yuv.yuv_to_rgb_16(r, g, b, y, u, v);"
+      print >>fd, " int32_t r, g, b;  YUV::yuv.yuv_to_rgb_16(r, g, b, y, u, v);"
   # blend
   if( has_bgcolor(fr_cmdl,to_cmdl) ):
-    print "%s" % (base["bbg"][otyp])
+    print >>fd, "%s" % (base["bbg"][otyp])
   elif( has_alpha(fr_cmdl) and not has_alpha(to_cmdl) ):
     if( is_rgb(to_cmdl) ):
-      print "%s" % (base["brgb"][otyp])
+      print >>fd, "%s" % (base["brgb"][otyp])
     elif( is_yuv(to_cmdl) ):
-      print "%s" % (base["byuv"][otyp])
+      print >>fd, "%s" % (base["byuv"][otyp])
   # store out
   for oc in layout[to_cmdl]:
-    print "%s" % (base[oc][otyp]['w']),
-  print "xfer_end"
-  print "}"
-  print ""
+    print >>fd, "%s" % (base[oc][otyp]['w']),
+  print >>fd, "xfer_end"
+  print >>fd, "}"
+  print >>fd, ""
 
 # output code file
 class_qual = "BC_Xfer::"
-
-print "#include \"xfer.h\""
-print ""
+xfn = "xfer/xfer.h"
+fd = open(xfn, "w")
+xid = "".join([chr(x) if chr(x).isalnum() else '_' for x in range(256)])
+xid = "__" + xfn.upper()[xfn.rfind("/")+1:].translate("".join(xid)) + "__"
+print >>fd, "#ifndef %s" % xid
+print >>fd, "#define %s" % xid
+print >>fd, ""
+xfd = open("bcxfer.h")
+fd.write(xfd.read())
+xfd.close()
 
 for fr_cmdl in cmodels:
   ityp = dtype[fr_cmdl]
   for to_cmdl in cmodels:
     otyp = dtype[to_cmdl]
     if( is_specialized(fr_cmdl, to_cmdl) ):
-      print "  void %s(unsigned y0, unsigned y1);" % (special[(fr_cmdl, to_cmdl)])
+      print >>fd, "  void %s(unsigned y0, unsigned y1);" % (special[(fr_cmdl, to_cmdl)])
       continue
     if( ityp is None or otyp is None ): continue
-    gen_xfer_proto("  ", "", fr_cmdl, to_cmdl);
-    print ";"
+    gen_xfer_proto(fd, "  ", "", fr_cmdl, to_cmdl);
+    print >>fd, ";"
 # end of class definition
-print "};"
-print ""
+print >>fd, "};"
+print >>fd, ""
+print >>fd, "#endif"
+fd.close()
+xfn = xfn[:xfn.rfind(".h")]
 
 # xfer functions
 for fr_cmdl in cmodels:
+  fd = open(xfn + "_" + fr_cmdl + ".C", "w")
+  print >>fd, "#include \"xfer.h\""
+  print >>fd, ""
   for to_cmdl in cmodels:
-    gen_xfer_fn(fr_cmdl, to_cmdl)
+    gen_xfer_fn(fd, fr_cmdl, to_cmdl)
+  fd.close()
 
+fd = open(xfn + ".C", "w")
 # transfer switch
-print ""
-print "void %sxfer()" % class_qual
-print "{"
+print >>fd, "#include \"xfer.h\""
+print >>fd, ""
+print >>fd, "void %sxfer()" % class_qual
+print >>fd, "{"
 mx_no = mx_bcmdl + 1
-print "  static xfer_fn xfns[%d][%d] = {" % (mx_no, mx_no)
+print >>fd, "  static xfer_fn xfns[%d][%d] = {" % (mx_no, mx_no)
 for fr_no in range(mx_no):
   fr_cmdl = bcmodels.get(fr_no)
   ityp = dtype[fr_cmdl]
-  print "  { // %s" % (fr_cmdl.upper() if ityp else "None")
+  print >>fd, "  { // %s" % (fr_cmdl.upper() if ityp else "None")
   n = 0
   for to_no in range(mx_no):
     to_cmdl = bcmodels.get(to_no)
     otyp = dtype[to_cmdl]
     xfn = special[(fr_cmdl, to_cmdl)] if( is_specialized(fr_cmdl, to_cmdl) ) else \
       "xfer_%s_to_%s" % (fr_cmdl[3:], to_cmdl[3:]) if ( ityp and otyp ) else None
-    if( n > 72 ): print ""; n = 0
-    if( n == 0 ): print "   ",; n += 4
+    if( n > 72 ): print >>fd, ""; n = 0
+    if( n == 0 ): print >>fd, "   ",; n += 4
     fn = "&%s%s" % (class_qual, xfn) if( xfn ) else "0"
-    print "%s, " % (fn),
+    print >>fd, "%s, " % (fn),
     n += len(fn) + 3
-  print "}, "
-print "  }; "
-print "  xfn = xfns[in_colormodel][out_colormodel];"
-print "  xfer_slices(out_w*out_h/0x80000+1);"
-print "}"
-print ""
-print "#include \"xfer.C\""
-print ""
+  print >>fd, "}, "
+print >>fd, "  }; "
+print >>fd, "  xfn = xfns[in_colormodel][out_colormodel];"
+print >>fd, "  xfer_slices(out_w*out_h/0x80000+1);"
+print >>fd, "}"
+print >>fd, ""
+print >>fd, "#include \"bcxfer.C\""
+print >>fd, ""
+fd.close()
 
diff --git a/cinelerra-5.1/guicast/bcxfer.C b/cinelerra-5.1/guicast/bcxfer.C
new file mode 100644 (file)
index 0000000..4425812
--- /dev/null
@@ -0,0 +1,281 @@
+
+void BC_Xfer::init(
+       uint8_t **output_rows, int out_colormodel, int out_x, int out_y, int out_w, int out_h,
+               uint8_t *out_yp, uint8_t *out_up, uint8_t *out_vp, uint8_t *out_ap, int out_rowspan,
+       uint8_t **input_rows, int in_colormodel, int in_x, int in_y, int in_w, int in_h,
+               uint8_t *in_yp, uint8_t *in_up, uint8_t *in_vp, uint8_t *in_ap, int in_rowspan,
+       int bg_color)
+{
+       // prevent bounds errors on poorly dimensioned macro pixel formats
+       switch( in_colormodel ) {
+       case BC_UVY422:
+       case BC_YUV422:   in_w &= ~1;               break;  // 2x1
+       case BC_YUV420P:
+       case BC_YUV420PI: in_w &= ~1;  in_h &= ~1;  break;  // 2x2
+       case BC_YUV422P:  in_w &= ~1;               break;  // 2x1
+       case BC_YUV410P:  in_w &= ~3;  in_h &= ~3;  break;  // 4x4
+       case BC_YUV411P:  in_w &= ~3;               break;  // 4x1
+       }
+       switch( out_colormodel ) {
+       case BC_UVY422:
+       case BC_YUV422:  out_w &= ~1;               break;
+       case BC_YUV420P:
+       case BC_YUV420PI: out_w &= ~1; out_h &= ~1; break;
+       case BC_YUV422P: out_w &= ~1;               break;
+       case BC_YUV410P: out_w &= ~3; out_h &= ~3;  break;
+       case BC_YUV411P: out_w &= ~3;               break;
+       }
+       this->output_rows = output_rows;
+       this->input_rows = input_rows;
+       this->out_yp = out_yp;
+       this->out_up = out_up;
+       this->out_vp = out_vp;
+       this->out_ap = out_ap;
+       this->in_yp = in_yp;
+       this->in_up = in_up;
+       this->in_vp = in_vp;
+       this->in_ap = in_ap;
+       this->in_x = in_x;
+       this->in_y = in_y;
+       this->in_w = in_w;
+       this->in_h = in_h;
+       this->out_x = out_x;
+       this->out_y = out_y;
+       this->out_w = out_w;
+       this->out_h = out_h;
+       this->in_colormodel = in_colormodel;
+       switch( in_colormodel ) {
+       case BC_GBRP:
+               in_rowspan = in_w * sizeof(uint8_t);
+               break;
+       case BC_RGB_FLOATP:
+       case BC_RGBA_FLOATP:
+               if( !BC_CModels::has_alpha(out_colormodel) )
+                       this->in_colormodel = BC_RGB_FLOATP;
+               in_rowspan = in_w * sizeof(float);
+               break;
+       }
+       this->total_in_w = in_rowspan;
+       this->out_colormodel = out_colormodel;
+       switch( out_colormodel ) {
+       case BC_GBRP:
+               out_rowspan = out_w * sizeof(uint8_t);
+               break;
+       case BC_RGB_FLOATP:
+       case BC_RGBA_FLOATP:
+               out_rowspan = out_w * sizeof(float);
+               break;
+       }
+       this->total_out_w = out_rowspan;
+       this->bg_color = bg_color;
+       this->bg_r = (bg_color>>16) & 0xff;
+       this->bg_g = (bg_color>>8) & 0xff;
+       this->bg_b = (bg_color>>0) & 0xff;
+
+       this->in_pixelsize = BC_CModels::calculate_pixelsize(in_colormodel);
+       this->out_pixelsize = BC_CModels::calculate_pixelsize(out_colormodel);
+       this->scale = (out_w != in_w) || (in_x != 0);
+
+/* + 1 so we don't overflow when calculating in advance */
+       column_table = new int[out_w+1];
+        double hscale = (double)in_w/out_w;
+       for( int i=0; i<out_w; ++i ) {
+                       column_table[i] = ((int)(hscale * i) + in_x) * in_pixelsize;
+                       if( in_colormodel == BC_YUV422 || in_colormodel == BC_UVY422 )
+                               column_table[i] &= ~3;
+       }
+        double vscale = (double)in_h/out_h;
+       row_table = new int[out_h];
+        for( int i=0; i<out_h; ++i )
+                row_table[i] = (int)(vscale * i) + in_y;
+}
+
+BC_Xfer::BC_Xfer(uint8_t **output_rows, uint8_t **input_rows,
+       uint8_t *out_yp, uint8_t *out_up, uint8_t *out_vp,
+       uint8_t *in_yp, uint8_t *in_up, uint8_t *in_vp,
+       int in_x, int in_y, int in_w, int in_h, int out_x, int out_y, int out_w, int out_h,
+       int in_colormodel, int out_colormodel, int bg_color, int in_rowspan, int out_rowspan)
+{
+       init(output_rows, out_colormodel, out_x, out_y, out_w, out_h,
+               out_yp, out_up, out_vp, 0, out_rowspan,
+            input_rows, in_colormodel, in_x, in_y, in_w, in_h,
+               in_yp, in_up, in_vp, 0, in_rowspan,  bg_color);
+}
+
+BC_Xfer::BC_Xfer(
+       uint8_t **output_ptrs, int out_colormodel,
+               int out_x, int out_y, int out_w, int out_h, int out_rowspan,
+       uint8_t **input_ptrs, int in_colormodel,
+               int in_x, int in_y, int in_w, int in_h, int in_rowspan,
+       int bg_color)
+{
+       uint8_t *out_yp = 0, *out_up = 0, *out_vp = 0, *out_ap = 0;
+       uint8_t *in_yp = 0,  *in_up = 0,  *in_vp = 0,  *in_ap = 0;
+       if( BC_CModels::is_planar(in_colormodel) ) {
+               in_yp = input_ptrs[0]; in_up = input_ptrs[1]; in_vp = input_ptrs[2];
+               if( BC_CModels::has_alpha(in_colormodel) ) in_ap = input_ptrs[3];
+       }
+       if( BC_CModels::is_planar(out_colormodel) ) {
+               out_yp = output_ptrs[0]; out_up = output_ptrs[1]; out_vp = output_ptrs[2];
+               if( BC_CModels::has_alpha(out_colormodel) ) out_ap = output_ptrs[3];
+       }
+       init(output_ptrs, out_colormodel, out_x, out_y, out_w, out_h,
+                out_yp, out_up, out_vp, out_ap, out_rowspan,
+            input_ptrs, in_colormodel, in_x, in_y, in_w, in_h,
+                in_yp, in_up, in_vp, in_ap, in_rowspan,  bg_color);
+}
+
+BC_Xfer::~BC_Xfer()
+{
+       delete [] column_table;
+       delete [] row_table;
+}
+
+void BC_CModels::transfer(unsigned char **output_rows, unsigned char **input_rows,
+        unsigned char *out_yp, unsigned char *out_up, unsigned char *out_vp,
+        unsigned char *in_yp, unsigned char *in_up, unsigned char *in_vp,
+        int in_x, int in_y, int in_w, int in_h, int out_x, int out_y, int out_w, int out_h,
+        int in_colormodel, int out_colormodel, int bg_color, int in_rowspan, int out_rowspan)
+{
+       BC_Xfer xfer(output_rows, input_rows,
+               out_yp, out_up, out_vp, in_yp, in_up, in_vp,
+               in_x, in_y, in_w, in_h, out_x, out_y, out_w, out_h,
+               in_colormodel, out_colormodel, bg_color, in_rowspan, out_rowspan);
+       xfer.xfer();
+}
+
+void BC_CModels::transfer(
+       uint8_t **output_ptrs, int out_colormodel,
+               int out_x, int out_y, int out_w, int out_h, int out_rowspan,
+       uint8_t **input_ptrs, int in_colormodel,
+               int in_x, int in_y, int in_w, int in_h, int in_rowspan,  int bg_color)
+{
+       BC_Xfer xfer(
+               output_ptrs, out_colormodel, out_x, out_y, out_w, out_h, out_rowspan,
+               input_ptrs, in_colormodel, in_x, in_y, in_w, in_h, in_rowspan,  bg_color);
+       xfer.xfer();
+}
+
+// specialized functions
+
+//  in bccmdl.py:  specialize("bc_rgba8888", "bc_transparency", "XFER_rgba8888_to_transparency")
+void BC_Xfer::XFER_rgba8888_to_transparency(unsigned y0, unsigned y1)
+{
+  for( unsigned i=y0; i<y1; ++i ) {
+    uint8_t *outp = output_rows[i + out_y] + out_x * out_pixelsize;
+    uint8_t *inp_row = input_rows[row_table[i]];
+    int bit_no = 0, bit_vec = 0;
+    for( unsigned j=0; j<out_w; ) {
+      uint8_t *inp = inp_row + column_table[j];
+      if( inp[3] < 127 ) bit_vec |= 0x01 << bit_no;
+      bit_no = ++j & 7;
+      if( !bit_no ) { *outp++ = bit_vec;  bit_vec = 0; }
+    }
+    if( bit_no ) *outp = bit_vec;
+  }
+}
+
+BC_Xfer::SlicerList BC_Xfer::slicers;
+
+BC_Xfer::SlicerList::SlicerList()
+{
+  count = 0;
+}
+
+BC_Xfer::SlicerList::~SlicerList()
+{
+  reset();
+}
+
+void BC_Xfer::SlicerList::reset()
+{
+  lock("BC_Xfer::SlicerList::reset");
+  while( last ) remove(last);
+  count = 0;
+  unlock();
+}
+
+BC_Xfer::Slicer *BC_Xfer::SlicerList::get_slicer(BC_Xfer *xp)
+{
+  Slicer *slicer = first;
+  if( !slicer ) {
+    if( count < BC_Resources::machine_cpus ) {
+      slicer = new Slicer(xp);
+      ++count;
+    }
+  }
+  else
+    remove_pointer(slicer);
+  return slicer;
+}
+
+void BC_Xfer::xfer_slices(int slices)
+{
+  if( !xfn ) return;
+  int max_slices = BC_Resources::machine_cpus/2;
+  if( slices > max_slices ) slices = max_slices;
+  if( slices < 1 ) slices = 1;
+  Slicer *active[slices];
+  unsigned y0 = 0, y1 = out_h;
+  int slices1 = slices-1;
+  if( slices1 > 0 ) {
+    slicers.lock("BC_Xfer::xfer_slices");
+    for( int i=0; i<slices1; y0=y1 ) {
+      Slicer *slicer = slicers.get_slicer(this);
+      if( !slicer ) { slices1 = i;  break; }
+      active[i] = slicer;
+      y1 = out_h * ++i / slices;
+      slicer->slice(this, y0, y1);
+    }
+    slicers.unlock();
+  }
+  (this->*xfn)(y0, out_h);
+  if( slices1 > 0 ) {
+    for( int i=0; i<slices1; ++i )
+      active[i]->complete->lock("BC_Xfer::xfer_slices");
+    slicers.lock("BC_Xfer::xfer_slices");
+    for( int i=0; i<slices1; ++i )
+      slicers.append(active[i]);
+    slicers.unlock();
+  }
+}
+
+BC_Xfer::Slicer::Slicer(BC_Xfer *xp)
+{
+  this->xp = xp;
+  init = new Condition(0, "BC_Xfer::Slicer::init", 0);
+  complete = new Condition(0, "BC_Xfer::Slicer::complete", 0);
+  done = 0;
+  start();
+}
+BC_Xfer::Slicer::~Slicer()
+{
+  done = 1;
+  init->unlock();
+  join();
+}
+
+void BC_Xfer::Slicer::slice(BC_Xfer *xp, unsigned y0, unsigned y1)
+{
+  this->xp = xp;
+  this->y0 = y0;
+  this->y1 = y1;
+  init->unlock();
+}
+
+void BC_Xfer::Slicer::run()
+{
+  while( !done ) {
+    init->lock("Slicer::run");
+    if( done ) break;
+    xfer_fn xfn = xp->xfn;
+    (xp->*xfn)(y0, y1);
+    complete->unlock();
+  }
+}
+
+void BC_CModels::bcxfer_stop_slicers()
+{
+  BC_Xfer::slicers.reset();
+}
+
diff --git a/cinelerra-5.1/guicast/bcxfer.h b/cinelerra-5.1/guicast/bcxfer.h
new file mode 100644 (file)
index 0000000..efcbc41
--- /dev/null
@@ -0,0 +1,275 @@
+#include "bccmodels.h"
+#include "bcresources.h"
+#include "condition.h"
+#include "linklist.h"
+#include "mutex.h"
+#include "thread.h"
+#include "clip.h"
+
+static inline float clp(const int n, float v) {
+ v *= ((float)(n*(1-1./0x1000000)));
+ return v < 0 ? 0 : v >= n ? n-1 : v;
+}
+
+static inline float fclp(float v, const int n) {
+ v /= ((float)(n*(1-1./0x1000000)));
+ return v < 0 ? 0 : v > 1 ? 1 : v;
+}
+
+#include <stdint.h>
+
+#define ZTYP(ty) typedef ty z_##ty __attribute__ ((__unused__))
+ZTYP(int);
+ZTYP(float);
+
+
+#define xfer_flat_row_out(oty_t) \
+  for( unsigned i=y0; i<y1; ++i ) { \
+    oty_t *out = (oty_t *)(output_rows[i + out_y] + out_x * out_pixelsize); \
+
+#define xfer_flat_row_in(ity_t) \
+    uint8_t *inp_row = input_rows[row_table[i]]; \
+    for( unsigned j=0; j<out_w; ++j ) { \
+      ity_t *inp = (ity_t *)(inp_row + column_table[j]); \
+
+#define xfer_end } }
+
+// yuv420p  2x2
+#define xfer_yuv420p_row_out(oty_t) \
+  for( unsigned i=y0; i<y1; ++i ) { \
+    int out_rofs = i * total_out_w + out_x; \
+    oty_t *yop = (oty_t *)(out_yp + out_rofs); \
+    out_rofs = i / 2 * total_out_w / 2 + out_x / 2; \
+    oty_t *uop = (oty_t *)(out_up + out_rofs); \
+    oty_t *vop = (oty_t *)(out_vp + out_rofs); \
+
+#define xfer_yuv420p_row_in(ity_t) \
+    int in_r = row_table[i]; \
+    int in_rofs = in_r * total_in_w; \
+    uint8_t *yip_row = in_yp + in_rofs; \
+    in_rofs = in_r / 2 * total_in_w / 2; \
+    uint8_t *uip_row = in_up + in_rofs; \
+    uint8_t *vip_row = in_vp + in_rofs; \
+    for( unsigned j=0; j<out_w; ++j ) { \
+      int in_ofs = column_table[j]; \
+      ity_t *yip = (ity_t *)(yip_row + in_ofs); \
+      in_ofs /= 2; \
+      ity_t *uip = (ity_t *)(uip_row + in_ofs); \
+      ity_t *vip = (ity_t *)(vip_row + in_ofs); \
+
+// yuv420pi  2x2
+#define xfer_yuv420pi_row_out(oty_t) \
+  for( unsigned i=y0; i<y1; ++i ) { \
+    int out_rofs = i * total_out_w + out_x; \
+    oty_t *yop = (oty_t *)(out_yp + out_rofs); \
+    int ot_k = ((i/4)<<1) + (i&1); \
+    out_rofs = ot_k * total_out_w / 2 + out_x / 2; \
+    oty_t *uop = (oty_t *)(out_up + out_rofs); \
+    oty_t *vop = (oty_t *)(out_vp + out_rofs); \
+
+#define xfer_yuv420pi_row_in(ity_t) \
+    int in_r = row_table[i]; \
+    int in_rofs = in_r * total_in_w; \
+    uint8_t *yip_row = in_yp + in_rofs; \
+    int in_k = ((in_r/4)<<1) + (in_r&1); \
+    in_rofs = in_k * total_in_w / 2; \
+    uint8_t *uip_row = in_up + in_rofs; \
+    uint8_t *vip_row = in_vp + in_rofs; \
+    for( unsigned j=0; j<out_w; ++j ) { \
+      int in_ofs = column_table[j]; \
+      ity_t *yip = (ity_t *)(yip_row + in_ofs); \
+      in_ofs /= 2; \
+      ity_t *uip = (ity_t *)(uip_row + in_ofs); \
+      ity_t *vip = (ity_t *)(vip_row + in_ofs); \
+
+// yuv422p  2x1
+#define xfer_yuv422p_row_out(oty_t) \
+  for( unsigned i=y0; i<y1; ++i ) { \
+    int out_rofs = i * total_out_w + out_x; \
+    oty_t *yop = (oty_t *)(out_yp + out_rofs); \
+    out_rofs = i * total_out_w / 2 + out_x / 2; \
+    oty_t *uop = (oty_t *)(out_up + out_rofs); \
+    oty_t *vop = (oty_t *)(out_vp + out_rofs); \
+
+#define xfer_yuv422p_row_in(ity_t) \
+    int in_rofs = row_table[i] * total_in_w; \
+    uint8_t *yip_row = in_yp + in_rofs; \
+    in_rofs /= 2; \
+    uint8_t *uip_row = in_up + in_rofs; \
+    uint8_t *vip_row = in_vp + in_rofs; \
+    for( unsigned j=0; j<out_w; ++j ) { \
+      int in_ofs = column_table[j]; \
+      ity_t *yip = (ity_t *)(yip_row + in_ofs); \
+      in_ofs /= 2; \
+      ity_t *uip = (ity_t *)(uip_row + in_ofs); \
+      ity_t *vip = (ity_t *)(vip_row + in_ofs); \
+
+// yuv444p  1x1
+#define xfer_yuv444p_row_out(oty_t) \
+  for( unsigned i=y0; i<y1; ++i ) { \
+    int out_rofs = i * total_out_w + out_x; \
+    oty_t *yop = (oty_t *)((oty_t *)(out_yp + out_rofs)); \
+    oty_t *uop = (oty_t *)(out_up + out_rofs); \
+    oty_t *vop = (oty_t *)(out_vp + out_rofs); \
+
+#define xfer_yuv444p_row_in(ity_t) \
+    int in_rofs = row_table[i] * total_in_w; \
+    uint8_t *yip_row = in_yp + in_rofs; \
+    uint8_t *uip_row = in_up + in_rofs; \
+    uint8_t *vip_row = in_vp + in_rofs; \
+    for( unsigned j=0; j<out_w; ++j ) { \
+      int in_ofs = column_table[j]; \
+      ity_t *yip = (ity_t *)(yip_row + in_ofs); \
+      ity_t *uip = (ity_t *)(uip_row + in_ofs); \
+      ity_t *vip = (ity_t *)(vip_row + in_ofs); \
+
+// yuv411p  4x1
+#define xfer_yuv411p_row_out(oty_t) \
+  for( unsigned i=y0; i<y1; ++i ) { \
+    int out_rofs = i * total_out_w + out_x; \
+    oty_t *yop = (oty_t *)(out_yp + out_rofs); \
+    out_rofs = i * total_out_w / 4 + out_x / 4; \
+    oty_t *uop = (oty_t *)(out_up + out_rofs); \
+    oty_t *vop = (oty_t *)(out_vp + out_rofs); \
+
+#define xfer_yuv411p_row_in(ity_t) \
+    int in_rofs = row_table[i] * total_in_w; \
+    uint8_t *yip_row = in_yp + in_rofs; \
+    in_rofs /= 4; \
+    uint8_t *uip_row = in_up + in_rofs; \
+    uint8_t *vip_row = in_vp + in_rofs; \
+    for( unsigned j=0; j<out_w; ++j ) { \
+      int in_ofs = column_table[j]; \
+      ity_t *yip = (ity_t *)(yip_row + in_ofs); \
+      in_ofs /= 4; \
+      ity_t *uip = (ity_t *)(uip_row + in_ofs); \
+      ity_t *vip = (ity_t *)(vip_row + in_ofs); \
+
+// yuv410p  4x4
+#define xfer_yuv410p_row_out(oty_t) \
+  for( unsigned i=y0; i<y1; ++i ) { \
+    int out_rofs = i * total_out_w + out_x; \
+    oty_t *yop = (oty_t *)(out_yp + out_rofs); \
+    out_rofs = i / 4 * total_out_w / 4 + out_x / 4; \
+    oty_t *uop = (oty_t *)(out_up + out_rofs); \
+    oty_t *vop = (oty_t *)(out_vp + out_rofs); \
+
+#define xfer_yuv410p_row_in(ity_t) \
+    int in_rofs = row_table[i] * total_in_w; \
+    uint8_t *yip_row = in_yp + in_rofs; \
+    in_rofs = row_table[i] / 4 * total_in_w / 4; \
+    uint8_t *uip_row = in_up + in_rofs; \
+    uint8_t *vip_row = in_vp + in_rofs; \
+    for( unsigned j=0; j<out_w; ++j ) { \
+      int in_ofs = column_table[j]; \
+      ity_t *yip = (ity_t *)(yip_row + in_ofs); \
+      in_ofs /= 4; \
+      ity_t *uip = (ity_t *)(uip_row + in_ofs); \
+      ity_t *vip = (ity_t *)(vip_row + in_ofs); \
+
+// rgb planar
+#define xfer_rgbp_row_out(oty_t) \
+  for( unsigned i=y0; i<y1; ++i ) { \
+    int out_rofs = i * total_out_w + out_x; \
+    oty_t *rop = (oty_t *)(out_yp + out_rofs); \
+    oty_t *gop = (oty_t *)(out_up + out_rofs); \
+    oty_t *bop = (oty_t *)(out_vp + out_rofs); \
+
+#define xfer_rgbap_row_out(oty_t) \
+  xfer_rgbp_row_out(oty_t) \
+    oty_t *aop = (oty_t *)(out_ap + out_rofs); \
+
+
+#define xfer_row_in_rgbp(ity_t) \
+    int in_rofs = row_table[i] * total_in_w; \
+    uint8_t *rip_row = in_yp + in_rofs; \
+    uint8_t *gip_row = in_up + in_rofs; \
+    uint8_t *bip_row = in_vp + in_rofs; \
+
+#define xfer_row_in_rgbap(oty_t) \
+  xfer_row_in_rgbp(ity_t) \
+    uint8_t *aip_row = in_ap + in_rofs; \
+
+
+#define xfer_col_in_rgbp(ity_t) \
+    for( unsigned j=0; j<out_w; ++j ) { \
+      int in_ofs = column_table[j]; \
+      ity_t *rip = (ity_t *)(rip_row + in_ofs); \
+      ity_t *gip = (ity_t *)(gip_row + in_ofs); \
+      ity_t *bip = (ity_t *)(bip_row + in_ofs); \
+
+#define xfer_col_in_rgbap(ity_t) \
+  xfer_col_in_rgbp(ity_t) \
+    ity_t *aip = (ity_t *)(aip_row + in_ofs); \
+
+
+#define xfer_rgbp_row_in(ity_t) \
+  xfer_row_in_rgbp(ity_t) \
+    xfer_col_in_rgbp(ity_t) \
+
+#define xfer_rgbap_row_in(ity_t) \
+  xfer_row_in_rgbap(ity_t) \
+    xfer_col_in_rgbap(ity_t) \
+
+
+class BC_Xfer {
+  BC_Xfer(const BC_Xfer&) {}
+public:
+  BC_Xfer(uint8_t **output_rows, uint8_t **input_rows,
+    uint8_t *out_yp, uint8_t *out_up, uint8_t *out_vp,
+    uint8_t *in_yp, uint8_t *in_up, uint8_t *in_vp,
+    int in_x, int in_y, int in_w, int in_h, int out_x, int out_y, int out_w, int out_h,
+    int in_colormodel, int out_colormodel, int bg_color, int in_rowspan, int out_rowspan);
+  BC_Xfer(uint8_t **output_ptrs, int out_colormodel,
+      int out_x, int out_y, int out_w, int out_h, int out_rowspan,
+    uint8_t **input_ptrs, int in_colormodel,
+      int in_x, int in_y, int in_w, int in_h, int in_rowspan,
+    int bg_color);
+  ~BC_Xfer();
+
+  uint8_t **output_rows, **input_rows;
+  uint8_t *out_yp, *out_up, *out_vp, *out_ap;
+  uint8_t *in_yp, *in_up, *in_vp, *in_ap;
+  int in_x, in_y; unsigned in_w, in_h;
+  int out_x, out_y; unsigned out_w, out_h;
+  int in_colormodel, out_colormodel;
+  uint32_t bg_color, total_in_w, total_out_w;
+  int scale;
+  int out_pixelsize, in_pixelsize;
+  int *row_table, *column_table;
+  uint32_t bg_r, bg_g, bg_b;
+
+  void xfer();
+  void xfer_slices(int slices);
+  typedef void (BC_Xfer::*xfer_fn)(unsigned y0, unsigned y1);
+  xfer_fn xfn;
+
+  class Slicer : public ListItem<Slicer>, public Thread {
+  public:
+    Condition *init, *complete;
+    Slicer(BC_Xfer *xp);
+    ~Slicer();
+    void slice(BC_Xfer *xp, unsigned y0, unsigned y1);
+    void run();
+    BC_Xfer *xp;
+    int done, y0, y1;
+  };
+
+  class SlicerList : public List<Slicer>, public Mutex {
+  public:
+    int count;
+    Slicer *get_slicer(BC_Xfer *xp);
+    void reset();
+    SlicerList();
+    ~SlicerList();
+  };
+  static SlicerList slicers;
+
+  void init(
+    uint8_t **output_rows, int out_colormodel, int out_x, int out_y, int out_w, int out_h,
+      uint8_t *out_yp, uint8_t *out_up, uint8_t *out_vp, uint8_t *out_ap, int out_rowspan,
+    uint8_t **input_rows, int in_colormodel, int in_x, int in_y, int in_w, int in_h,
+      uint8_t *in_yp, uint8_t *in_up, uint8_t *in_vp, uint8_t *in_ap, int in_rowspan,
+    int bg_color);
+
+// generated code concatentated here
index 8d5f88e8c839fd137358ae9aa0fd3155d8c6d9db..35f1ac69d9b1766955dd1eabe8b0df35a59d834c 100644 (file)
@@ -413,6 +413,7 @@ unsigned int VFrame::make_shader(const char **fragments, ...)
        }
 
 //printf("VFrame::make_shader\n%s\n", program);
+       delete [] program;
 #endif
        return result;
 }
diff --git a/cinelerra-5.1/guicast/xfer.C b/cinelerra-5.1/guicast/xfer.C
deleted file mode 100644 (file)
index 4425812..0000000
+++ /dev/null
@@ -1,281 +0,0 @@
-
-void BC_Xfer::init(
-       uint8_t **output_rows, int out_colormodel, int out_x, int out_y, int out_w, int out_h,
-               uint8_t *out_yp, uint8_t *out_up, uint8_t *out_vp, uint8_t *out_ap, int out_rowspan,
-       uint8_t **input_rows, int in_colormodel, int in_x, int in_y, int in_w, int in_h,
-               uint8_t *in_yp, uint8_t *in_up, uint8_t *in_vp, uint8_t *in_ap, int in_rowspan,
-       int bg_color)
-{
-       // prevent bounds errors on poorly dimensioned macro pixel formats
-       switch( in_colormodel ) {
-       case BC_UVY422:
-       case BC_YUV422:   in_w &= ~1;               break;  // 2x1
-       case BC_YUV420P:
-       case BC_YUV420PI: in_w &= ~1;  in_h &= ~1;  break;  // 2x2
-       case BC_YUV422P:  in_w &= ~1;               break;  // 2x1
-       case BC_YUV410P:  in_w &= ~3;  in_h &= ~3;  break;  // 4x4
-       case BC_YUV411P:  in_w &= ~3;               break;  // 4x1
-       }
-       switch( out_colormodel ) {
-       case BC_UVY422:
-       case BC_YUV422:  out_w &= ~1;               break;
-       case BC_YUV420P:
-       case BC_YUV420PI: out_w &= ~1; out_h &= ~1; break;
-       case BC_YUV422P: out_w &= ~1;               break;
-       case BC_YUV410P: out_w &= ~3; out_h &= ~3;  break;
-       case BC_YUV411P: out_w &= ~3;               break;
-       }
-       this->output_rows = output_rows;
-       this->input_rows = input_rows;
-       this->out_yp = out_yp;
-       this->out_up = out_up;
-       this->out_vp = out_vp;
-       this->out_ap = out_ap;
-       this->in_yp = in_yp;
-       this->in_up = in_up;
-       this->in_vp = in_vp;
-       this->in_ap = in_ap;
-       this->in_x = in_x;
-       this->in_y = in_y;
-       this->in_w = in_w;
-       this->in_h = in_h;
-       this->out_x = out_x;
-       this->out_y = out_y;
-       this->out_w = out_w;
-       this->out_h = out_h;
-       this->in_colormodel = in_colormodel;
-       switch( in_colormodel ) {
-       case BC_GBRP:
-               in_rowspan = in_w * sizeof(uint8_t);
-               break;
-       case BC_RGB_FLOATP:
-       case BC_RGBA_FLOATP:
-               if( !BC_CModels::has_alpha(out_colormodel) )
-                       this->in_colormodel = BC_RGB_FLOATP;
-               in_rowspan = in_w * sizeof(float);
-               break;
-       }
-       this->total_in_w = in_rowspan;
-       this->out_colormodel = out_colormodel;
-       switch( out_colormodel ) {
-       case BC_GBRP:
-               out_rowspan = out_w * sizeof(uint8_t);
-               break;
-       case BC_RGB_FLOATP:
-       case BC_RGBA_FLOATP:
-               out_rowspan = out_w * sizeof(float);
-               break;
-       }
-       this->total_out_w = out_rowspan;
-       this->bg_color = bg_color;
-       this->bg_r = (bg_color>>16) & 0xff;
-       this->bg_g = (bg_color>>8) & 0xff;
-       this->bg_b = (bg_color>>0) & 0xff;
-
-       this->in_pixelsize = BC_CModels::calculate_pixelsize(in_colormodel);
-       this->out_pixelsize = BC_CModels::calculate_pixelsize(out_colormodel);
-       this->scale = (out_w != in_w) || (in_x != 0);
-
-/* + 1 so we don't overflow when calculating in advance */
-       column_table = new int[out_w+1];
-        double hscale = (double)in_w/out_w;
-       for( int i=0; i<out_w; ++i ) {
-                       column_table[i] = ((int)(hscale * i) + in_x) * in_pixelsize;
-                       if( in_colormodel == BC_YUV422 || in_colormodel == BC_UVY422 )
-                               column_table[i] &= ~3;
-       }
-        double vscale = (double)in_h/out_h;
-       row_table = new int[out_h];
-        for( int i=0; i<out_h; ++i )
-                row_table[i] = (int)(vscale * i) + in_y;
-}
-
-BC_Xfer::BC_Xfer(uint8_t **output_rows, uint8_t **input_rows,
-       uint8_t *out_yp, uint8_t *out_up, uint8_t *out_vp,
-       uint8_t *in_yp, uint8_t *in_up, uint8_t *in_vp,
-       int in_x, int in_y, int in_w, int in_h, int out_x, int out_y, int out_w, int out_h,
-       int in_colormodel, int out_colormodel, int bg_color, int in_rowspan, int out_rowspan)
-{
-       init(output_rows, out_colormodel, out_x, out_y, out_w, out_h,
-               out_yp, out_up, out_vp, 0, out_rowspan,
-            input_rows, in_colormodel, in_x, in_y, in_w, in_h,
-               in_yp, in_up, in_vp, 0, in_rowspan,  bg_color);
-}
-
-BC_Xfer::BC_Xfer(
-       uint8_t **output_ptrs, int out_colormodel,
-               int out_x, int out_y, int out_w, int out_h, int out_rowspan,
-       uint8_t **input_ptrs, int in_colormodel,
-               int in_x, int in_y, int in_w, int in_h, int in_rowspan,
-       int bg_color)
-{
-       uint8_t *out_yp = 0, *out_up = 0, *out_vp = 0, *out_ap = 0;
-       uint8_t *in_yp = 0,  *in_up = 0,  *in_vp = 0,  *in_ap = 0;
-       if( BC_CModels::is_planar(in_colormodel) ) {
-               in_yp = input_ptrs[0]; in_up = input_ptrs[1]; in_vp = input_ptrs[2];
-               if( BC_CModels::has_alpha(in_colormodel) ) in_ap = input_ptrs[3];
-       }
-       if( BC_CModels::is_planar(out_colormodel) ) {
-               out_yp = output_ptrs[0]; out_up = output_ptrs[1]; out_vp = output_ptrs[2];
-               if( BC_CModels::has_alpha(out_colormodel) ) out_ap = output_ptrs[3];
-       }
-       init(output_ptrs, out_colormodel, out_x, out_y, out_w, out_h,
-                out_yp, out_up, out_vp, out_ap, out_rowspan,
-            input_ptrs, in_colormodel, in_x, in_y, in_w, in_h,
-                in_yp, in_up, in_vp, in_ap, in_rowspan,  bg_color);
-}
-
-BC_Xfer::~BC_Xfer()
-{
-       delete [] column_table;
-       delete [] row_table;
-}
-
-void BC_CModels::transfer(unsigned char **output_rows, unsigned char **input_rows,
-        unsigned char *out_yp, unsigned char *out_up, unsigned char *out_vp,
-        unsigned char *in_yp, unsigned char *in_up, unsigned char *in_vp,
-        int in_x, int in_y, int in_w, int in_h, int out_x, int out_y, int out_w, int out_h,
-        int in_colormodel, int out_colormodel, int bg_color, int in_rowspan, int out_rowspan)
-{
-       BC_Xfer xfer(output_rows, input_rows,
-               out_yp, out_up, out_vp, in_yp, in_up, in_vp,
-               in_x, in_y, in_w, in_h, out_x, out_y, out_w, out_h,
-               in_colormodel, out_colormodel, bg_color, in_rowspan, out_rowspan);
-       xfer.xfer();
-}
-
-void BC_CModels::transfer(
-       uint8_t **output_ptrs, int out_colormodel,
-               int out_x, int out_y, int out_w, int out_h, int out_rowspan,
-       uint8_t **input_ptrs, int in_colormodel,
-               int in_x, int in_y, int in_w, int in_h, int in_rowspan,  int bg_color)
-{
-       BC_Xfer xfer(
-               output_ptrs, out_colormodel, out_x, out_y, out_w, out_h, out_rowspan,
-               input_ptrs, in_colormodel, in_x, in_y, in_w, in_h, in_rowspan,  bg_color);
-       xfer.xfer();
-}
-
-// specialized functions
-
-//  in bccmdl.py:  specialize("bc_rgba8888", "bc_transparency", "XFER_rgba8888_to_transparency")
-void BC_Xfer::XFER_rgba8888_to_transparency(unsigned y0, unsigned y1)
-{
-  for( unsigned i=y0; i<y1; ++i ) {
-    uint8_t *outp = output_rows[i + out_y] + out_x * out_pixelsize;
-    uint8_t *inp_row = input_rows[row_table[i]];
-    int bit_no = 0, bit_vec = 0;
-    for( unsigned j=0; j<out_w; ) {
-      uint8_t *inp = inp_row + column_table[j];
-      if( inp[3] < 127 ) bit_vec |= 0x01 << bit_no;
-      bit_no = ++j & 7;
-      if( !bit_no ) { *outp++ = bit_vec;  bit_vec = 0; }
-    }
-    if( bit_no ) *outp = bit_vec;
-  }
-}
-
-BC_Xfer::SlicerList BC_Xfer::slicers;
-
-BC_Xfer::SlicerList::SlicerList()
-{
-  count = 0;
-}
-
-BC_Xfer::SlicerList::~SlicerList()
-{
-  reset();
-}
-
-void BC_Xfer::SlicerList::reset()
-{
-  lock("BC_Xfer::SlicerList::reset");
-  while( last ) remove(last);
-  count = 0;
-  unlock();
-}
-
-BC_Xfer::Slicer *BC_Xfer::SlicerList::get_slicer(BC_Xfer *xp)
-{
-  Slicer *slicer = first;
-  if( !slicer ) {
-    if( count < BC_Resources::machine_cpus ) {
-      slicer = new Slicer(xp);
-      ++count;
-    }
-  }
-  else
-    remove_pointer(slicer);
-  return slicer;
-}
-
-void BC_Xfer::xfer_slices(int slices)
-{
-  if( !xfn ) return;
-  int max_slices = BC_Resources::machine_cpus/2;
-  if( slices > max_slices ) slices = max_slices;
-  if( slices < 1 ) slices = 1;
-  Slicer *active[slices];
-  unsigned y0 = 0, y1 = out_h;
-  int slices1 = slices-1;
-  if( slices1 > 0 ) {
-    slicers.lock("BC_Xfer::xfer_slices");
-    for( int i=0; i<slices1; y0=y1 ) {
-      Slicer *slicer = slicers.get_slicer(this);
-      if( !slicer ) { slices1 = i;  break; }
-      active[i] = slicer;
-      y1 = out_h * ++i / slices;
-      slicer->slice(this, y0, y1);
-    }
-    slicers.unlock();
-  }
-  (this->*xfn)(y0, out_h);
-  if( slices1 > 0 ) {
-    for( int i=0; i<slices1; ++i )
-      active[i]->complete->lock("BC_Xfer::xfer_slices");
-    slicers.lock("BC_Xfer::xfer_slices");
-    for( int i=0; i<slices1; ++i )
-      slicers.append(active[i]);
-    slicers.unlock();
-  }
-}
-
-BC_Xfer::Slicer::Slicer(BC_Xfer *xp)
-{
-  this->xp = xp;
-  init = new Condition(0, "BC_Xfer::Slicer::init", 0);
-  complete = new Condition(0, "BC_Xfer::Slicer::complete", 0);
-  done = 0;
-  start();
-}
-BC_Xfer::Slicer::~Slicer()
-{
-  done = 1;
-  init->unlock();
-  join();
-}
-
-void BC_Xfer::Slicer::slice(BC_Xfer *xp, unsigned y0, unsigned y1)
-{
-  this->xp = xp;
-  this->y0 = y0;
-  this->y1 = y1;
-  init->unlock();
-}
-
-void BC_Xfer::Slicer::run()
-{
-  while( !done ) {
-    init->lock("Slicer::run");
-    if( done ) break;
-    xfer_fn xfn = xp->xfn;
-    (xp->*xfn)(y0, y1);
-    complete->unlock();
-  }
-}
-
-void BC_CModels::bcxfer_stop_slicers()
-{
-  BC_Xfer::slicers.reset();
-}
-
diff --git a/cinelerra-5.1/guicast/xfer.h b/cinelerra-5.1/guicast/xfer.h
deleted file mode 100644 (file)
index efcbc41..0000000
+++ /dev/null
@@ -1,275 +0,0 @@
-#include "bccmodels.h"
-#include "bcresources.h"
-#include "condition.h"
-#include "linklist.h"
-#include "mutex.h"
-#include "thread.h"
-#include "clip.h"
-
-static inline float clp(const int n, float v) {
- v *= ((float)(n*(1-1./0x1000000)));
- return v < 0 ? 0 : v >= n ? n-1 : v;
-}
-
-static inline float fclp(float v, const int n) {
- v /= ((float)(n*(1-1./0x1000000)));
- return v < 0 ? 0 : v > 1 ? 1 : v;
-}
-
-#include <stdint.h>
-
-#define ZTYP(ty) typedef ty z_##ty __attribute__ ((__unused__))
-ZTYP(int);
-ZTYP(float);
-
-
-#define xfer_flat_row_out(oty_t) \
-  for( unsigned i=y0; i<y1; ++i ) { \
-    oty_t *out = (oty_t *)(output_rows[i + out_y] + out_x * out_pixelsize); \
-
-#define xfer_flat_row_in(ity_t) \
-    uint8_t *inp_row = input_rows[row_table[i]]; \
-    for( unsigned j=0; j<out_w; ++j ) { \
-      ity_t *inp = (ity_t *)(inp_row + column_table[j]); \
-
-#define xfer_end } }
-
-// yuv420p  2x2
-#define xfer_yuv420p_row_out(oty_t) \
-  for( unsigned i=y0; i<y1; ++i ) { \
-    int out_rofs = i * total_out_w + out_x; \
-    oty_t *yop = (oty_t *)(out_yp + out_rofs); \
-    out_rofs = i / 2 * total_out_w / 2 + out_x / 2; \
-    oty_t *uop = (oty_t *)(out_up + out_rofs); \
-    oty_t *vop = (oty_t *)(out_vp + out_rofs); \
-
-#define xfer_yuv420p_row_in(ity_t) \
-    int in_r = row_table[i]; \
-    int in_rofs = in_r * total_in_w; \
-    uint8_t *yip_row = in_yp + in_rofs; \
-    in_rofs = in_r / 2 * total_in_w / 2; \
-    uint8_t *uip_row = in_up + in_rofs; \
-    uint8_t *vip_row = in_vp + in_rofs; \
-    for( unsigned j=0; j<out_w; ++j ) { \
-      int in_ofs = column_table[j]; \
-      ity_t *yip = (ity_t *)(yip_row + in_ofs); \
-      in_ofs /= 2; \
-      ity_t *uip = (ity_t *)(uip_row + in_ofs); \
-      ity_t *vip = (ity_t *)(vip_row + in_ofs); \
-
-// yuv420pi  2x2
-#define xfer_yuv420pi_row_out(oty_t) \
-  for( unsigned i=y0; i<y1; ++i ) { \
-    int out_rofs = i * total_out_w + out_x; \
-    oty_t *yop = (oty_t *)(out_yp + out_rofs); \
-    int ot_k = ((i/4)<<1) + (i&1); \
-    out_rofs = ot_k * total_out_w / 2 + out_x / 2; \
-    oty_t *uop = (oty_t *)(out_up + out_rofs); \
-    oty_t *vop = (oty_t *)(out_vp + out_rofs); \
-
-#define xfer_yuv420pi_row_in(ity_t) \
-    int in_r = row_table[i]; \
-    int in_rofs = in_r * total_in_w; \
-    uint8_t *yip_row = in_yp + in_rofs; \
-    int in_k = ((in_r/4)<<1) + (in_r&1); \
-    in_rofs = in_k * total_in_w / 2; \
-    uint8_t *uip_row = in_up + in_rofs; \
-    uint8_t *vip_row = in_vp + in_rofs; \
-    for( unsigned j=0; j<out_w; ++j ) { \
-      int in_ofs = column_table[j]; \
-      ity_t *yip = (ity_t *)(yip_row + in_ofs); \
-      in_ofs /= 2; \
-      ity_t *uip = (ity_t *)(uip_row + in_ofs); \
-      ity_t *vip = (ity_t *)(vip_row + in_ofs); \
-
-// yuv422p  2x1
-#define xfer_yuv422p_row_out(oty_t) \
-  for( unsigned i=y0; i<y1; ++i ) { \
-    int out_rofs = i * total_out_w + out_x; \
-    oty_t *yop = (oty_t *)(out_yp + out_rofs); \
-    out_rofs = i * total_out_w / 2 + out_x / 2; \
-    oty_t *uop = (oty_t *)(out_up + out_rofs); \
-    oty_t *vop = (oty_t *)(out_vp + out_rofs); \
-
-#define xfer_yuv422p_row_in(ity_t) \
-    int in_rofs = row_table[i] * total_in_w; \
-    uint8_t *yip_row = in_yp + in_rofs; \
-    in_rofs /= 2; \
-    uint8_t *uip_row = in_up + in_rofs; \
-    uint8_t *vip_row = in_vp + in_rofs; \
-    for( unsigned j=0; j<out_w; ++j ) { \
-      int in_ofs = column_table[j]; \
-      ity_t *yip = (ity_t *)(yip_row + in_ofs); \
-      in_ofs /= 2; \
-      ity_t *uip = (ity_t *)(uip_row + in_ofs); \
-      ity_t *vip = (ity_t *)(vip_row + in_ofs); \
-
-// yuv444p  1x1
-#define xfer_yuv444p_row_out(oty_t) \
-  for( unsigned i=y0; i<y1; ++i ) { \
-    int out_rofs = i * total_out_w + out_x; \
-    oty_t *yop = (oty_t *)((oty_t *)(out_yp + out_rofs)); \
-    oty_t *uop = (oty_t *)(out_up + out_rofs); \
-    oty_t *vop = (oty_t *)(out_vp + out_rofs); \
-
-#define xfer_yuv444p_row_in(ity_t) \
-    int in_rofs = row_table[i] * total_in_w; \
-    uint8_t *yip_row = in_yp + in_rofs; \
-    uint8_t *uip_row = in_up + in_rofs; \
-    uint8_t *vip_row = in_vp + in_rofs; \
-    for( unsigned j=0; j<out_w; ++j ) { \
-      int in_ofs = column_table[j]; \
-      ity_t *yip = (ity_t *)(yip_row + in_ofs); \
-      ity_t *uip = (ity_t *)(uip_row + in_ofs); \
-      ity_t *vip = (ity_t *)(vip_row + in_ofs); \
-
-// yuv411p  4x1
-#define xfer_yuv411p_row_out(oty_t) \
-  for( unsigned i=y0; i<y1; ++i ) { \
-    int out_rofs = i * total_out_w + out_x; \
-    oty_t *yop = (oty_t *)(out_yp + out_rofs); \
-    out_rofs = i * total_out_w / 4 + out_x / 4; \
-    oty_t *uop = (oty_t *)(out_up + out_rofs); \
-    oty_t *vop = (oty_t *)(out_vp + out_rofs); \
-
-#define xfer_yuv411p_row_in(ity_t) \
-    int in_rofs = row_table[i] * total_in_w; \
-    uint8_t *yip_row = in_yp + in_rofs; \
-    in_rofs /= 4; \
-    uint8_t *uip_row = in_up + in_rofs; \
-    uint8_t *vip_row = in_vp + in_rofs; \
-    for( unsigned j=0; j<out_w; ++j ) { \
-      int in_ofs = column_table[j]; \
-      ity_t *yip = (ity_t *)(yip_row + in_ofs); \
-      in_ofs /= 4; \
-      ity_t *uip = (ity_t *)(uip_row + in_ofs); \
-      ity_t *vip = (ity_t *)(vip_row + in_ofs); \
-
-// yuv410p  4x4
-#define xfer_yuv410p_row_out(oty_t) \
-  for( unsigned i=y0; i<y1; ++i ) { \
-    int out_rofs = i * total_out_w + out_x; \
-    oty_t *yop = (oty_t *)(out_yp + out_rofs); \
-    out_rofs = i / 4 * total_out_w / 4 + out_x / 4; \
-    oty_t *uop = (oty_t *)(out_up + out_rofs); \
-    oty_t *vop = (oty_t *)(out_vp + out_rofs); \
-
-#define xfer_yuv410p_row_in(ity_t) \
-    int in_rofs = row_table[i] * total_in_w; \
-    uint8_t *yip_row = in_yp + in_rofs; \
-    in_rofs = row_table[i] / 4 * total_in_w / 4; \
-    uint8_t *uip_row = in_up + in_rofs; \
-    uint8_t *vip_row = in_vp + in_rofs; \
-    for( unsigned j=0; j<out_w; ++j ) { \
-      int in_ofs = column_table[j]; \
-      ity_t *yip = (ity_t *)(yip_row + in_ofs); \
-      in_ofs /= 4; \
-      ity_t *uip = (ity_t *)(uip_row + in_ofs); \
-      ity_t *vip = (ity_t *)(vip_row + in_ofs); \
-
-// rgb planar
-#define xfer_rgbp_row_out(oty_t) \
-  for( unsigned i=y0; i<y1; ++i ) { \
-    int out_rofs = i * total_out_w + out_x; \
-    oty_t *rop = (oty_t *)(out_yp + out_rofs); \
-    oty_t *gop = (oty_t *)(out_up + out_rofs); \
-    oty_t *bop = (oty_t *)(out_vp + out_rofs); \
-
-#define xfer_rgbap_row_out(oty_t) \
-  xfer_rgbp_row_out(oty_t) \
-    oty_t *aop = (oty_t *)(out_ap + out_rofs); \
-
-
-#define xfer_row_in_rgbp(ity_t) \
-    int in_rofs = row_table[i] * total_in_w; \
-    uint8_t *rip_row = in_yp + in_rofs; \
-    uint8_t *gip_row = in_up + in_rofs; \
-    uint8_t *bip_row = in_vp + in_rofs; \
-
-#define xfer_row_in_rgbap(oty_t) \
-  xfer_row_in_rgbp(ity_t) \
-    uint8_t *aip_row = in_ap + in_rofs; \
-
-
-#define xfer_col_in_rgbp(ity_t) \
-    for( unsigned j=0; j<out_w; ++j ) { \
-      int in_ofs = column_table[j]; \
-      ity_t *rip = (ity_t *)(rip_row + in_ofs); \
-      ity_t *gip = (ity_t *)(gip_row + in_ofs); \
-      ity_t *bip = (ity_t *)(bip_row + in_ofs); \
-
-#define xfer_col_in_rgbap(ity_t) \
-  xfer_col_in_rgbp(ity_t) \
-    ity_t *aip = (ity_t *)(aip_row + in_ofs); \
-
-
-#define xfer_rgbp_row_in(ity_t) \
-  xfer_row_in_rgbp(ity_t) \
-    xfer_col_in_rgbp(ity_t) \
-
-#define xfer_rgbap_row_in(ity_t) \
-  xfer_row_in_rgbap(ity_t) \
-    xfer_col_in_rgbap(ity_t) \
-
-
-class BC_Xfer {
-  BC_Xfer(const BC_Xfer&) {}
-public:
-  BC_Xfer(uint8_t **output_rows, uint8_t **input_rows,
-    uint8_t *out_yp, uint8_t *out_up, uint8_t *out_vp,
-    uint8_t *in_yp, uint8_t *in_up, uint8_t *in_vp,
-    int in_x, int in_y, int in_w, int in_h, int out_x, int out_y, int out_w, int out_h,
-    int in_colormodel, int out_colormodel, int bg_color, int in_rowspan, int out_rowspan);
-  BC_Xfer(uint8_t **output_ptrs, int out_colormodel,
-      int out_x, int out_y, int out_w, int out_h, int out_rowspan,
-    uint8_t **input_ptrs, int in_colormodel,
-      int in_x, int in_y, int in_w, int in_h, int in_rowspan,
-    int bg_color);
-  ~BC_Xfer();
-
-  uint8_t **output_rows, **input_rows;
-  uint8_t *out_yp, *out_up, *out_vp, *out_ap;
-  uint8_t *in_yp, *in_up, *in_vp, *in_ap;
-  int in_x, in_y; unsigned in_w, in_h;
-  int out_x, out_y; unsigned out_w, out_h;
-  int in_colormodel, out_colormodel;
-  uint32_t bg_color, total_in_w, total_out_w;
-  int scale;
-  int out_pixelsize, in_pixelsize;
-  int *row_table, *column_table;
-  uint32_t bg_r, bg_g, bg_b;
-
-  void xfer();
-  void xfer_slices(int slices);
-  typedef void (BC_Xfer::*xfer_fn)(unsigned y0, unsigned y1);
-  xfer_fn xfn;
-
-  class Slicer : public ListItem<Slicer>, public Thread {
-  public:
-    Condition *init, *complete;
-    Slicer(BC_Xfer *xp);
-    ~Slicer();
-    void slice(BC_Xfer *xp, unsigned y0, unsigned y1);
-    void run();
-    BC_Xfer *xp;
-    int done, y0, y1;
-  };
-
-  class SlicerList : public List<Slicer>, public Mutex {
-  public:
-    int count;
-    Slicer *get_slicer(BC_Xfer *xp);
-    void reset();
-    SlicerList();
-    ~SlicerList();
-  };
-  static SlicerList slicers;
-
-  void init(
-    uint8_t **output_rows, int out_colormodel, int out_x, int out_y, int out_w, int out_h,
-      uint8_t *out_yp, uint8_t *out_up, uint8_t *out_vp, uint8_t *out_ap, int out_rowspan,
-    uint8_t **input_rows, int in_colormodel, int in_x, int in_y, int in_w, int in_h,
-      uint8_t *in_yp, uint8_t *in_up, uint8_t *in_vp, uint8_t *in_ap, int in_rowspan,
-    int bg_color);
-
-// generated code concatentated here
diff --git a/cinelerra-5.1/guicast/xfer/Makefile b/cinelerra-5.1/guicast/xfer/Makefile
new file mode 100644 (file)
index 0000000..0a28901
--- /dev/null
@@ -0,0 +1,18 @@
+export TOPDIR ?= $(CURDIR)/../..
+include $(TOPDIR)/global_config
+
+$(shell mkdir -p $(OBJDIR) )
+$(shell echo $(CFLAGS) > $(OBJDIR)/c_flags)
+
+OUTPUT := $(OBJDIR)/xfer.o
+
+all:   $(OUTPUT)
+
+clean:
+       rm -rf $(OBJDIR) xfer*.[Ch]
+
+$(OBJDIR)/%.o:          %.C
+       $(CXX) -I.. `cat $(OBJDIR)/c_flags` -O3 -DMSGQUAL=$* -c $< -o $@
+
+$(OUTPUT): $(patsubst %.C,$(OBJDIR)/%.o,$(wildcard *.C))
+