add threading to xfer
authorGood Guy <good1.2guy@gmail.com>
Sun, 15 May 2016 20:24:48 +0000 (14:24 -0600)
committerGood Guy <good1.2guy@gmail.com>
Sun, 15 May 2016 20:24:48 +0000 (14:24 -0600)
14 files changed:
cinelerra-5.1/cinelerra/atrack.C
cinelerra-5.1/cinelerra/mediadb.C
cinelerra-5.1/cinelerra/strack.C
cinelerra-5.1/cinelerra/vtrack.C
cinelerra-5.1/guicast/Makefile
cinelerra-5.1/guicast/bcbitmap.C
cinelerra-5.1/guicast/bccmdl.py
cinelerra-5.1/guicast/bccmodels.h
cinelerra-5.1/guicast/bcsignals.C
cinelerra-5.1/guicast/bcsignals.h
cinelerra-5.1/guicast/linklist.h
cinelerra-5.1/guicast/xfer.C
cinelerra-5.1/guicast/xfer.h
cinelerra-5.1/plugins/Makefile

index 1ef123dae4fdd014aa0be421ca415068b56bb9fe..9387ed9d4120e2154015c9fed922f8300dc69ae8 100644 (file)
@@ -127,7 +127,7 @@ int ATrack::load_defaults(BC_Hash *defaults)
 
 void ATrack::set_default_title()
 {
-       Track *current = ListItem<Track>::owner->first;
+       Track *current = ListItem<Track>::list->first;
        int i;
        for(i = 0; current; current = NEXT)
        {
index 2c057c098197d1dd0feaf85b1cfd25ac0f51533a..bb2e826cc42e0981843f94aa307ae4f3826cc406 100644 (file)
@@ -189,7 +189,7 @@ Clip(int clip_id, double start, double end, int index)
 Clip::
 ~Clip()
 {
-       Clips *clips = (Clips *)owner;
+       Clips *clips = (Clips *)list;
        if( clips && clips->current == this ) clips->current = 0;
 }
 
index 82435a2ae33029be60f6aa323607bf3812eab6ce..ffa6a5b1e1f5c29f80b3b8986ea9062ce9cd1267 100644 (file)
@@ -45,7 +45,7 @@ int STrack::load_defaults(BC_Hash *defaults)
 
 void STrack::set_default_title()
 {
-       Track *current = ListItem<Track>::owner->first;
+       Track *current = ListItem<Track>::list->first;
        int i;
        for(i = 0; current; current = NEXT)
        {
index c61ee3c370ba7ebd02445e9eeec5493ec508ff4d..580191adc08d5bab439d339e07130dc46b3d62f6 100644 (file)
@@ -107,7 +107,7 @@ int VTrack::load_defaults(BC_Hash *defaults)
 
 void VTrack::set_default_title()
 {
-       Track *current = ListItem<Track>::owner->first;
+       Track *current = ListItem<Track>::list->first;
        int i;
        for(i = 0; current; current = NEXT)
        {
index fbf609da811f3f6df992afdcd33200407e935448..ba5e6cc38c3694ef8a9f4b8a0ff8adc1942eb73c 100644 (file)
@@ -115,7 +115,7 @@ $(shell echo $(OBJS) > $(OBJDIR)/objs)
 all: $(OUTPUT) $(UTILS)
 
 $(OBJDIR)/bcxfer.o:    bcxfer.C xfer.C xfer.h
-       $(CXX) `cat $(OBJDIR)/c_flags` -c $< -o $@
+       $(CXX) `cat $(OBJDIR)/c_flags` -O3 -c $< -o $@
 
 bcxfer.C:      bccmdl.py
        python < ./bccmdl.py > bcxfer.C
index e9118da47ab9c1248516ba647ba67dec81fcd39e..231ce559a8039a7b652d1dbc459e6d7db5fdffdd 100644 (file)
@@ -56,7 +56,7 @@ BC_BitmapImage::~BC_BitmapImage()
 
 bool BC_BitmapImage::is_avail()
 {
-       return owner == &bitmap->avail;
+       return list == &bitmap->avail;
 }
 
 BC_BitmapImage *BC_Bitmap::cur_bfr()
index 2850fe503ad810865b806c0091aedd2bdc90b57b..0c730de07c6ff6b61ab3a3bebef5450b52e1d5b3 100755 (executable)
@@ -392,13 +392,17 @@ base = {
 }
 
 cmodels = []
+bcmodels = {}
 layout = {}
-dtype = {}
+dtype = { None: None }
 special = {}
+mx_bcmdl = -1
 
-def add_cmodel(nm, typ=None, *args):
-  global cmodels, layout, dtype
+def add_cmodel(n, nm, typ=None, *args):
+  global cmodels, bcmodels, layout, dtype, mx_bcmdl
   cmodels += [nm,]
+  bcmodels[n] = nm
+  if( n > mx_bcmdl ): mx_bcmdl = n
   dtype[nm] = typ
   layout[nm] = args
 
@@ -406,44 +410,44 @@ def specialize(fr_cmdl, to_cmdl, fn):
   global special
   special[(fr_cmdl, to_cmdl)] = fn
 
-add_cmodel("bc_transparency")
-add_cmodel("bc_compressed")
-
-add_cmodel("bc_rgb8", "i8", "rgb8")
-add_cmodel("bc_rgb565", "i8", "rgb565")
-add_cmodel("bc_bgr565", "i8", "bgr565")
-add_cmodel("bc_bgr888", "i8", "bgr888")
-add_cmodel("bc_bgr8888", "i8", "bgr8888")
-
-add_cmodel("bc_rgb888", "i8", "rgb888")
-add_cmodel("bc_rgba8888", "i8", "rgb888", "a8")
-add_cmodel("bc_argb8888", "i8", "a8", "rgb888")
-add_cmodel("bc_abgr8888", "i8", "a8", "bgr888")
-add_cmodel("bc_rgb161616", "i16", "rgb161616")
-add_cmodel("bc_rgba16161616", "i16", "rgb161616", "a16")
-add_cmodel("bc_yuv888", "i8", "yuv888")
-add_cmodel("bc_yuva8888", "i8", "yuv888", "a8")
-add_cmodel("bc_yuv161616", "i16", "yuv161616")
-add_cmodel("bc_yuva16161616", "i16", "yuv161616", "a16")
-
-add_cmodel("bc_yuv422", "i8", "yuyv8888")
-add_cmodel("bc_uvy422", "i8", "uyvy8888")
-add_cmodel("bc_a8")
-add_cmodel("bc_a16")
-add_cmodel("bc_a_float")
-add_cmodel("bc_yuv101010", "i16", "yuv10101010")
-add_cmodel("bc_vyu888", "i8", "vyu888")
-add_cmodel("bc_uyva8888", "i8", "uyv888", "a8")
-add_cmodel("bc_rgb_float", "fp", "rgbfloat")
-add_cmodel("bc_rgba_float", "fp", "rgbfloat", "afp")
-
-add_cmodel("bc_yuv420p", "i8", "yuv420p")
-add_cmodel("bc_yuv422p", "i8", "yuv422p")
-add_cmodel("bc_yuv444p", "i8", "yuv444p")
-add_cmodel("bc_yuv411p", "i8", "yuv411p")
-add_cmodel("bc_yuv410p", "i8", "yuv410p")
-add_cmodel("bc_rgb_floatp", "fp", "rgbfltp")
-add_cmodel("bc_rgba_floatp", "fp", "rgbfltp", "afpp")
+add_cmodel( 0, "bc_transparency")
+add_cmodel( 1, "bc_compressed")
+
+add_cmodel( 2, "bc_rgb8", "i8", "rgb8")
+add_cmodel( 3, "bc_rgb565", "i8", "rgb565")
+add_cmodel( 4, "bc_bgr565", "i8", "bgr565")
+add_cmodel( 5, "bc_bgr888", "i8", "bgr888")
+add_cmodel( 6, "bc_bgr8888", "i8", "bgr8888")
+
+add_cmodel( 9, "bc_rgb888", "i8", "rgb888")
+add_cmodel(10, "bc_rgba8888", "i8", "rgb888", "a8")
+add_cmodel(20, "bc_argb8888", "i8", "a8", "rgb888")
+add_cmodel(21, "bc_abgr8888", "i8", "a8", "bgr888")
+add_cmodel(11, "bc_rgb161616", "i16", "rgb161616")
+add_cmodel(12, "bc_rgba16161616", "i16", "rgb161616", "a16")
+add_cmodel(13, "bc_yuv888", "i8", "yuv888")
+add_cmodel(14, "bc_yuva8888", "i8", "yuv888", "a8")
+add_cmodel(15, "bc_yuv161616", "i16", "yuv161616")
+add_cmodel(16, "bc_yuva16161616", "i16", "yuv161616", "a16")
+
+add_cmodel(18, "bc_yuv422", "i8", "yuyv8888")
+add_cmodel(19, "bc_uvy422", "i8", "uyvy8888")
+add_cmodel(22, "bc_a8")
+add_cmodel(23, "bc_a16")
+add_cmodel(31, "bc_a_float")
+add_cmodel(24, "bc_yuv101010", "i16", "yuv10101010")
+add_cmodel(25, "bc_vyu888", "i8", "vyu888")
+add_cmodel(26, "bc_uyva8888", "i8", "uyv888", "a8")
+add_cmodel(29, "bc_rgb_float", "fp", "rgbfloat")
+add_cmodel(30, "bc_rgba_float", "fp", "rgbfloat", "afp")
+
+add_cmodel( 7, "bc_yuv420p", "i8", "yuv420p")
+add_cmodel( 8, "bc_yuv422p", "i8", "yuv422p")
+add_cmodel(27, "bc_yuv444p", "i8", "yuv444p")
+add_cmodel(17, "bc_yuv411p", "i8", "yuv411p")
+add_cmodel(28, "bc_yuv410p", "i8", "yuv410p")
+add_cmodel(32, "bc_rgb_floatp", "fp", "rgbfltp")
+add_cmodel(33, "bc_rgba_floatp", "fp", "rgbfltp", "afpp")
 
 specialize("bc_rgba8888", "bc_transparency", "XFER_rgba8888_to_transparency")
 
@@ -498,7 +502,7 @@ def gen_xfer_proto(pfx, cls, fr_cmdl, to_cmdl):
   print "%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 "()",
+  print "(unsigned y0, unsigned y1)",
 
 def gen_xfer_fn(fr_cmdl, to_cmdl):
   global layout, dtype, adata
@@ -574,7 +578,7 @@ for fr_cmdl in cmodels:
   for to_cmdl in cmodels:
     otyp = dtype[to_cmdl]
     if( is_specialized(fr_cmdl, to_cmdl) ):
-      print "  void %s();" % (special[(fr_cmdl, to_cmdl)])
+      print "  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);
@@ -592,24 +596,27 @@ for fr_cmdl in cmodels:
 print ""
 print "void %sxfer()" % class_qual
 print "{"
-print "  switch(in_colormodel) {"
-for fr_cmdl in cmodels:
+mx_no = mx_bcmdl + 1
+print "  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]
-  if( ityp is None ):
-    if( not fr_cmdl in [it[0] for it in special] ): continue
-  print "  case %s:" % (fr_cmdl.upper())
-  print "    switch(out_colormodel) {"
-  for to_cmdl in cmodels:
-    if( is_specialized(fr_cmdl, to_cmdl) ):
-      print "    case %s: %s(); break;" % (to_cmdl.upper(), special[(fr_cmdl, to_cmdl)])
-      continue
+  print "  { // %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]
-    if( ityp is None or otyp is None ): continue
-    print "    case %s:" % (to_cmdl.upper()),
-    print "xfer_%s_to_%s();  break;" % (fr_cmdl[3:], to_cmdl[3:])
-  print "    }"
-  print "    break;"
-print "  }"
+    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
+    fn = "&%s%s" % (class_qual, xfn) if( xfn ) else "0"
+    print "%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\""
index b6c397b3af535a83be04754fa3d3316794cd78ec..94a9bbcd80a136ceb1f56586bdcaafefebe768e3 100644 (file)
@@ -124,6 +124,7 @@ public:
 
        static void init_yuv();
        static int bc_to_x(int color_model);
+       static void bcxfer_stop_slicers();
 };
 
 
index 609ea1e2afbbbd0c5633948c9dcc77f0241d2dc0..3886cd64579e3663d1c339889c1066c5d8483dc0 100644 (file)
@@ -21,6 +21,7 @@
 
 #include "bcsignals.h"
 #include "bcwindowbase.h"
+#include "bccmodels.h"
 #include "bckeyboard.h"
 #include "bcresources.h"
 
@@ -419,6 +420,10 @@ void BC_Signals::set_sighup_exit(int enable)
 BC_Signals::BC_Signals()
 {
 }
+BC_Signals::~BC_Signals()
+{
+  BC_CModels::bcxfer_stop_slicers();
+}
 
 void BC_Signals::dump_traces(FILE *fp)
 {
index f5d4fa04609cfa5dfb7468bc46dbca0616038d08..05d44f8732701d18505f0e0ca66224b058fbec18 100644 (file)
@@ -64,6 +64,7 @@ class BC_Signals
        static int x_error_handler(Display *display, XErrorEvent *event);
 public:
        BC_Signals();
+       ~BC_Signals();
        void initialize();
        void initialize2();
        void terminate();
index 284a0ebfaeed2fc65eabf340c58a31853eb8d1a3..000f0f212324d1d708dc2fa06a9e6adc3f8d9888 100644 (file)
@@ -7,12 +7,12 @@ template<class TYPE>
 class ListItem {
 public:
        TYPE *previous, *next;
-       List<TYPE> *owner;
+       List<TYPE> *list;
 
-       int get_item_number() { return !owner ? -1 : owner->number_of(this); }
-       ListItem() { owner = 0;  previous = next = 0; }
-       ListItem(List<TYPE> &me) { owner = me;  previous = next = 0; }
-       virtual ~ListItem() { if( owner ) owner->remove_pointer(this); }
+       int get_item_number() { return !list ? -1 : list->number_of(this); }
+       ListItem() { list = 0;  previous = next = 0; }
+       ListItem(List<TYPE> &me) { list = me;  previous = next = 0; }
+       virtual ~ListItem() { if( list ) list->remove_pointer(this); }
 };
 
 template<class TYPE>
@@ -57,7 +57,7 @@ public:
 template<class TYPE>
 TYPE* List<TYPE>::append(TYPE *item)
 {
-       item->owner = this;  item->next = 0;
+       item->list = this;  item->next = 0;
        if( !last ) { item->previous = 0; first = item; }
        else { item->previous = last;  last->next = item; }
        return last = item;
@@ -67,7 +67,7 @@ template<class TYPE>
 TYPE* List<TYPE>::insert_before(TYPE *here, TYPE *item)
 {
        if( !here || !last ) return append(item);
-       item->owner = this;  item->next = here;
+       item->list = this;  item->next = here;
        *( !(item->previous=here->previous) ? &first : &here->previous->next ) = item;
        return here->previous = item;
 }
@@ -76,7 +76,7 @@ template<class TYPE>
 TYPE* List<TYPE>::insert_after(TYPE *here, TYPE *item)
 {
        if( !here || !last ) return append(item);
-       item->owner = this;  item->previous = here;
+       item->list = this;  item->previous = here;
        *( !(item->next=here->next) ? &last : &here->next->previous ) = item;
        return here->next = item;
 }
@@ -89,7 +89,7 @@ void List<TYPE>::remove_pointer(ListItem<TYPE> *item)
        TYPE *previous = item->previous, *next = item->next;
        *( previous ? &previous->next : &first ) = next;
        *( next ? &next->previous : &last ) = previous;
-       item->owner = 0;
+       item->list = 0;
 }
 
 template<class TYPE>
index c689b6b6a8b4cf3be0f7085d8b726626001cc5df..87ad6bdd5b619971865f53a14f8a7b2b552722fc 100644 (file)
@@ -245,9 +245,9 @@ void BC_CModels::transfer(
 // specialized functions
 
 //  in bccmdl.py:  specialize("bc_rgba8888", "bc_transparency", "XFER_rgba8888_to_transparency")
-void BC_Xfer::XFER_rgba8888_to_transparency()
+void BC_Xfer::XFER_rgba8888_to_transparency(unsigned y0, unsigned y1)
 {
-  for( unsigned i=0; i<out_h; ++i ) {
+  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;
@@ -261,3 +261,109 @@ void BC_Xfer::XFER_rgba8888_to_transparency()
   } 
 }
 
+BC_Xfer::SlicerList BC_Xfer::slicers;
+
+BC_Xfer::SlicerList::SlicerList()
+{
+  waiting = new Condition(0, "BC_Xfer::SlicerList", 1);
+  count = 0;
+}
+
+BC_Xfer::SlicerList::~SlicerList()
+{
+  reset();
+  delete waiting;
+}
+
+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)
+{
+  while( !first ) {
+    if( count < BC_Resources::machine_cpus ) {
+      append(new Slicer(xp));
+      ++count;
+    }
+    else
+      waiting->lock("BC_Xfer::SlicerList::get_slicer");
+  }
+  Slicer *slicer = first;
+  remove_pointer(slicer);
+  return slicer;
+}
+
+void BC_Xfer::xfer_slices(int slices)
+{
+  if( !xfn ) return;
+  int max_slices = BC_Resources::machine_cpus/2+1;
+  if( slices > max_slices ) slices = max_slices;
+  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);
+      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();
+    slicers.waiting->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();
+}
+
index ddbca7f07636e586ea81e2026d32e19edcda1b48..bb69407fcf912cf87295f8b22e82cf8f9db5646f 100644 (file)
@@ -1,4 +1,9 @@
 #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) {
@@ -78,7 +83,7 @@ ZTYP(float);
 
 
 #define xfer_flat_row_out(oty_t) \
-  for( unsigned i=0; i<out_h; ++i ) { \
+  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) \
@@ -90,7 +95,7 @@ ZTYP(float);
 
 // yuv420p  2x2
 #define xfer_yuv420p_row_out(oty_t) \
-  for( unsigned i=0; i<out_h; ++i ) { \
+  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; \
@@ -112,7 +117,7 @@ ZTYP(float);
 
 // yuv422p  2x1
 #define xfer_yuv422p_row_out(oty_t) \
-  for( unsigned i=0; i<out_h; ++i ) { \
+  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; \
@@ -134,7 +139,7 @@ ZTYP(float);
 
 // yuv444p  1x1
 #define xfer_yuv444p_row_out(oty_t) \
-  for( unsigned i=0; i<out_h; ++i ) { \
+  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); \
@@ -153,7 +158,7 @@ ZTYP(float);
 
 // yuv411p  4x1
 #define xfer_yuv411p_row_out(oty_t) \
-  for( unsigned i=0; i<out_h; ++i ) { \
+  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; \
@@ -175,7 +180,7 @@ ZTYP(float);
 
 // yuv410p  4x4
 #define xfer_yuv410p_row_out(oty_t) \
-  for( unsigned i=0; i<out_h; ++i ) { \
+  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; \
@@ -197,7 +202,7 @@ ZTYP(float);
 
 // rgb_floatp
 #define xfer_rgb_fltp_row_out(oty_t) \
-  for( unsigned i=0; i<out_h; ++i ) { \
+  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); \
@@ -262,6 +267,31 @@ public:
   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;
+    Condition *waiting;
+    Slicer *get_slicer(BC_Xfer *xp);
+    void reset();
+    SlicerList();
+    ~SlicerList();
+  };
+  static SlicerList slicers;
 
   static void init();
   static class Tables { public: Tables() { init(); } } tables;
index 2467e78d8e6fee89a02230d0678413ccfecf6821..c979a9c732bb6bd9babae85938e5e5d4159e3cd4 100644 (file)
@@ -37,7 +37,6 @@ DIRS = \
        delayvideo \
        denoise \
        denoisefft \
-       denoisemjpeg \
        denoiseseltempavg \
        denoisevideo \
        despike \
@@ -58,7 +57,6 @@ DIRS = \
        gamma \
        gradient \
        graphic \
-       greycstoration \
        histogram \
        histogram_bezier \
        holo \
@@ -139,7 +137,11 @@ DIRS = \
        theme_suv \
        theme_unflat \
 
+# too costly
 #      findobject \
+#      greycstoration \
+# not finished
+#      denoisemjpeg \
 
 DATA = $(PLUGIN_DIR)/fonts $(PLUGIN_DIR)/shapes
 LADSPA = $(BINDIR)/ladspa