sams transition icons, misc fixes, youtube formats
[goodguy/history.git] / cinelerra-5.1 / guicast / xfer.C
index c689b6b6a8b4cf3be0f7085d8b726626001cc5df..e4ac81feeca8ff1ff8a2b9ca4bc4e8d48e2f4df4 100644 (file)
@@ -1,100 +1,4 @@
 
-// Compression coefficients straight out of jpeglib
-#define R_TO_Y    0.29900
-#define G_TO_Y    0.58700
-#define B_TO_Y    0.11400
-
-#define R_TO_U    -0.16874
-#define G_TO_U    -0.33126
-#define B_TO_U    0.50000
-
-#define R_TO_V    0.50000
-#define G_TO_V    -0.41869
-#define B_TO_V    -0.08131
-
-// Decompression coefficients straight out of jpeglib
-#define V_TO_R    1.40200
-#define V_TO_G    -0.71414
-
-#define U_TO_G    -0.34414
-#define U_TO_B    1.77200
-
-int BC_Xfer::rtoy_tab[0x100], BC_Xfer::gtoy_tab[0x100], BC_Xfer::btoy_tab[0x100];
-int BC_Xfer::rtou_tab[0x100], BC_Xfer::gtou_tab[0x100], BC_Xfer::btou_tab[0x100];
-int BC_Xfer::rtov_tab[0x100], BC_Xfer::gtov_tab[0x100], BC_Xfer::btov_tab[0x100];
-int BC_Xfer::vtor_tab[0x100], BC_Xfer::vtog_tab[0x100];
-int BC_Xfer::utog_tab[0x100], BC_Xfer::utob_tab[0x100];
-float BC_Xfer::vtor_float_tab[0x100], BC_Xfer::vtog_float_tab[0x100];
-float BC_Xfer::utog_float_tab[0x100], BC_Xfer::utob_float_tab[0x100];
-int BC_Xfer::rtoy_tab16[0x10000], BC_Xfer::gtoy_tab16[0x10000], BC_Xfer::btoy_tab16[0x10000];
-int BC_Xfer::rtou_tab16[0x10000], BC_Xfer::gtou_tab16[0x10000], BC_Xfer::btou_tab16[0x10000];
-int BC_Xfer::rtov_tab16[0x10000], BC_Xfer::gtov_tab16[0x10000], BC_Xfer::btov_tab16[0x10000];
-int BC_Xfer::vtor_tab16[0x10000], BC_Xfer::vtog_tab16[0x10000];
-int BC_Xfer::utog_tab16[0x10000], BC_Xfer::utob_tab16[0x10000];
-float BC_Xfer::v16tor_float_tab[0x10000], BC_Xfer::v16tog_float_tab[0x10000];
-float BC_Xfer::u16tog_float_tab[0x10000], BC_Xfer::u16tob_float_tab[0x10000];
-
-BC_Xfer::Tables BC_Xfer::tables;
-
-void BC_Xfer::init()
-{
-       for( int i=0; i<0x100; ++i ) {
-               rtoy_tab[i] = (int)(R_TO_Y * 0x10000 * i);
-               rtou_tab[i] = (int)(R_TO_U * 0x10000 * i);
-               rtov_tab[i] = (int)(R_TO_V * 0x10000 * i);
-
-               gtoy_tab[i] = (int)(G_TO_Y * 0x10000 * i);
-               gtou_tab[i] = (int)(G_TO_U * 0x10000 * i);
-               gtov_tab[i] = (int)(G_TO_V * 0x10000 * i);
-
-               btoy_tab[i] = (int)(B_TO_Y * 0x10000 * i);
-               btou_tab[i] = (int)(B_TO_U * 0x10000 * i) + 0x800000;
-               btov_tab[i] = (int)(B_TO_V * 0x10000 * i) + 0x800000;
-       }
-
-       for( int i=0; i<0x10000; ++i ) {
-               rtoy_tab16[i] = (int)(R_TO_Y * 0x100 * i);
-               rtou_tab16[i] = (int)(R_TO_U * 0x100 * i);
-               rtov_tab16[i] = (int)(R_TO_V * 0x100 * i);
-
-               gtoy_tab16[i] = (int)(G_TO_Y * 0x100 * i);
-               gtou_tab16[i] = (int)(G_TO_U * 0x100 * i);
-               gtov_tab16[i] = (int)(G_TO_V * 0x100 * i);
-
-               btoy_tab16[i] = (int)(B_TO_Y * 0x100 * i);
-               btou_tab16[i] = (int)(B_TO_U * 0x100 * i) + 0x800000;
-               btov_tab16[i] = (int)(B_TO_V * 0x100 * i) + 0x800000;
-       }
-
-       for( int i=-0x80; i<0x80; ++i ) {
-               vtor_tab[i+0x80] = (int)(V_TO_R * 0x10000 * i);
-               vtog_tab[i+0x80] = (int)(V_TO_G * 0x10000 * i);
-               utog_tab[i+0x80] = (int)(U_TO_G * 0x10000 * i);
-               utob_tab[i+0x80] = (int)(U_TO_B * 0x10000 * i);
-       }
-
-       for( int i=-0x80; i<0x80; ++i ) {
-               vtor_float_tab[i+0x80] = V_TO_R * i / 0xff;
-               vtog_float_tab[i+0x80] = V_TO_G * i / 0xff;
-               utog_float_tab[i+0x80] = U_TO_G * i / 0xff;
-               utob_float_tab[i+0x80] = U_TO_B * i / 0xff;
-       }
-
-       for( int i=-0x8000; i<0x8000; ++i ) {
-               vtor_tab16[i+0x8000] = (int)(V_TO_R * 0x100 * i);
-               vtog_tab16[i+0x8000] = (int)(V_TO_G * 0x100 * i);
-               utog_tab16[i+0x8000] = (int)(U_TO_G * 0x100 * i);
-               utob_tab16[i+0x8000] = (int)(U_TO_B * 0x100 * i);
-       }
-
-       for( int i=-0x8000; i<0x8000; ++i ) {
-               v16tor_float_tab[i+0x8000] = V_TO_R * i / 0xffff;
-               v16tog_float_tab[i+0x8000] = V_TO_G * i / 0xffff;
-               u16tog_float_tab[i+0x8000] = U_TO_G * i / 0xffff;
-               u16tob_float_tab[i+0x8000] = U_TO_B * i / 0xffff;
-       }
-}
-
 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,
@@ -106,7 +10,8 @@ void BC_Xfer::init(
        switch( in_colormodel ) {
        case BC_UVY422:
        case BC_YUV422:   in_w &= ~1;               break;  // 2x1
-       case BC_YUV420P:  in_w &= ~1;  in_h &= ~1;  break;  // 2x2
+       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
@@ -114,7 +19,8 @@ void BC_Xfer::init(
        switch( out_colormodel ) {
        case BC_UVY422:
        case BC_YUV422:  out_w &= ~1;               break;
-       case BC_YUV420P: out_w &= ~1; out_h &= ~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;
@@ -141,6 +47,8 @@ void BC_Xfer::init(
        switch( in_colormodel ) {
        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;
        }
@@ -162,7 +70,7 @@ void BC_Xfer::init(
        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 */ 
+/* + 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 ) {
@@ -245,9 +153,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;
@@ -258,6 +166,110 @@ void BC_Xfer::XFER_rgba8888_to_transparency()
       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();
 }