Skip to content

Commit

Permalink
#973: fix libyuv build on win32 by inlining the memalign code (C++ an…
Browse files Browse the repository at this point in the history
…d C don't seem to mix well with cython on win32 + MSVC..)

git-svn-id: https://xpra.org/svn/Xpra/trunk@11874 3bb7dfac-3a0b-4e04-842a-767bc560f471
  • Loading branch information
totaam committed Feb 7, 2016
1 parent 5236f29 commit 6a7fe93
Show file tree
Hide file tree
Showing 2 changed files with 30 additions and 14 deletions.
16 changes: 14 additions & 2 deletions src/setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -180,7 +180,7 @@ def is_msvc():

memoryview_ENABLED = sys.version>='2.7'
csc_opencl_ENABLED = DEFAULT and pkg_config_ok("--exists", "OpenCL") and check_pyopencl_AMD()
csc_libyuv_ENABLED = DEFAULT and memoryview_ENABLED and pkg_config_ok("--exists", "libyuv")
csc_libyuv_ENABLED = DEFAULT and memoryview_ENABLED and pkg_config_ok("--exists", "libyuv", fallback=WIN32)

#Cython / gcc / packagingt build options:
annotate_ENABLED = True
Expand Down Expand Up @@ -1087,6 +1087,12 @@ def glob_recurse(srcdir):
else:
vpx_lib_names = ["vpxmt", "vpxmtd"] #for libvpx 1.1.0

libyuv_path = WIN32_BUILD_LIB_PREFIX + "libyuv"
libyuv_include_dir = os.path.join(libyuv_path, "include")
libyuv_lib_dir = os.path.join(libyuv_path, "lib")
libyuv_bin_dir = os.path.join(libyuv_path, "bin")
libyuv_lib_names = ["yuv"]

# Same for PyGTK / GTK3:
# http://www.pygtk.org/downloads.html
if PYTHON3:
Expand Down Expand Up @@ -1620,6 +1626,10 @@ def add_keywords(path_dirs=[], inc_dirs=[], lib_dirs=[], libs=[], noref=True, no
add_keywords([webp_bin_dir], [webp_include_dir],
[webp_lib_dir],
webp_lib_names, nocmt=True)
elif "libyuv" in pkgs_options[0]:
add_keywords([libyuv_bin_dir], [libyuv_include_dir],
[libyuv_lib_dir],
libyuv_lib_names)
elif ("nvenc4" in pkgs_options[0]) or ("nvenc5" in pkgs_options[0]) or ("nvenc6" in pkgs_options[0]):
for x in ("pycuda", "pytools"):
if x not in external_includes:
Expand Down Expand Up @@ -1897,8 +1907,10 @@ def cython_add(*args, **kwargs):
assert not PYTHON3
bmod = "old"
buffers_c = "xpra/buffers/%s_buffers.c" % bmod
inline_c = "xpra/inline.c"
memalign_c = "xpra/buffers/memalign.c"
#convenience grouping for codecs:
membuffers_c = ["xpra/buffers/memalign.c", "xpra/inline.c", buffers_c]
membuffers_c = [memalign_c, inline_c, buffers_c]


toggle_packages(dbus_ENABLED, "xpra.dbus")
Expand Down
28 changes: 16 additions & 12 deletions src/xpra/codecs/csc_libyuv/colorspace_converter.pyx
Original file line number Diff line number Diff line change
Expand Up @@ -18,15 +18,11 @@ from xpra.codecs.image_wrapper import ImageWrapper


cdef extern from "stdlib.h":
int posix_memalign(void **memptr, size_t alignment, size_t size)
void free(void *ptr)
void* malloc(size_t size)

DEF MEMALIGN_ALIGNMENT = 16
cdef void *xmemalign(size_t size):
cdef void *memptr = NULL
if posix_memalign(&memptr, MEMALIGN_ALIGNMENT, size):
return NULL
return memptr
cdef extern from "../../buffers/memalign.h":
cdef unsigned int MEMALIGN_ALIGNMENT

#inlined here because linking messes up with c++..
cdef extern from "Python.h":
Expand Down Expand Up @@ -102,6 +98,12 @@ cdef FilterMode get_filtermode(int speed):
cdef inline int roundup(int n, int m):
return (n + m - 1) & ~(m - 1)

cdef inline unsigned long roundupl(unsigned long n, unsigned long m):
return (n + m - 1) & ~(m - 1)

cdef inline void *memalign_ptr(void *ptr):
return <void *> roundupl(<unsigned long> ptr, MEMALIGN_ALIGNMENT)


def init_module():
#nothing to do!
Expand Down Expand Up @@ -210,7 +212,8 @@ cdef class ColorspaceConverter:
self.out_offsets[i] = self.out_buffer_size
#add one extra line to height so we can access a full rowstride at a time,
#no matter where we start to read on the last line
self.out_buffer_size += self.out_size[i] + self.out_stride[i]
#and round up to memalign each plane:
self.out_buffer_size += roundupl(self.out_size[i] + self.out_stride[i], MEMALIGN_ALIGNMENT)
if self.scaling:
self.scaled_width[i] = dst_width // xdiv
self.scaled_height[i] = dst_height // ydiv
Expand All @@ -219,7 +222,7 @@ cdef class ColorspaceConverter:
self.scaled_offsets[i] = self.scaled_buffer_size
self.scaled_buffer_size += self.scaled_size[i] + self.out_stride[i]
if self.scaling:
self.output_buffer = <uint8_t *> xmemalign(self.out_buffer_size)
self.output_buffer = <uint8_t *> malloc(self.out_buffer_size)
else:
self.output_buffer = NULL
log("buffer size=%i, scaling=%s, filtermode=%s", self.out_buffer_size, self.scaling, get_fiter_mode_str(self.filtermode))
Expand Down Expand Up @@ -325,9 +328,10 @@ cdef class ColorspaceConverter:
output_buffer = self.output_buffer
else:
#allocate output buffer:
output_buffer = <unsigned char*> xmemalign(self.out_buffer_size)
output_buffer = <unsigned char*> malloc(self.out_buffer_size)
for i in range(3):
out_planes[i] = output_buffer + self.out_offsets[i]
#offsets are aligned, so this is safe and gives us aligned pointers:
out_planes[i] = <uint8_t*> (<unsigned long> memalign_ptr(output_buffer) + self.out_offsets[i])
with nogil:
result = ARGBToI420(input_image, stride,
out_planes[0], self.out_stride[0],
Expand All @@ -342,7 +346,7 @@ cdef class ColorspaceConverter:
strides = []
if self.scaling:
start = time.time()
scaled_buffer = <unsigned char*> xmemalign(self.scaled_buffer_size)
scaled_buffer = <unsigned char*> malloc(self.scaled_buffer_size)
with nogil:
for i in range(3):
scaled_planes[i] = scaled_buffer + self.scaled_offsets[i]
Expand Down

0 comments on commit 6a7fe93

Please sign in to comment.