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();
int cw = lx1-lx0, ch = ly1-ly0;
hide_window();
sync_display();
+ grab_thread->done = 1;
MWindow *mwindow = grab_thread->mwindow;
Preferences *preferences = mwindow->preferences;
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;
asset->remove_user();
}
- grab_thread->done = 1;
return 1;
}
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();
}
}
-
-
BC_Window* VWindow::new_gui()
{
//printf("VWindow::create_objects 1\n");
return gui;
}
+void VWindow::handle_close_event(int result)
+{
+ delete playback_engine;
+ playback_engine = 0;
+}
+
EDL* VWindow::get_edl()
{
~VWindow();
void handle_done_event(int result);
+ void handle_close_event(int result);
BC_Window* new_gui();
void load_defaults();
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"
$(OBJDIR)/bcwindowbase.o \
$(OBJDIR)/bcwindowdraw.o \
$(OBJDIR)/bcwindowevents.o \
- $(OBJDIR)/bcxfer.o \
$(OBJDIR)/condition.o \
$(OBJDIR)/errorbox.o \
$(OBJDIR)/filesystem.o \
OUTPUT = $(OBJDIR)/libguicast.a
UTILS = $(OBJDIR)/bootstrap $(OBJDIR)/pngtoh $(OBJDIR)/pngtoraw
+BCXFER = xfer/$(OBJDIR)/xfer.o
CFLAGS += -I/usr/include/freetype2
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
clean:
rm -rf $(OBJDIR)
- rm -f bcxfer.C
+ make -C xfer clean
install:
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 \
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()
--- /dev/null
+
+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();
+}
+
--- /dev/null
+#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
}
//printf("VFrame::make_shader\n%s\n", program);
+ delete [] program;
#endif
return result;
}
+++ /dev/null
-
-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();
-}
-
+++ /dev/null
-#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
--- /dev/null
+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))
+