diff --git a/repos/libports/include/libyuv/libyuv.h b/repos/libports/include/libyuv/libyuv.h
new file mode 100644
index 0000000000..bd9cebfc96
--- /dev/null
+++ b/repos/libports/include/libyuv/libyuv.h
@@ -0,0 +1,26 @@
+/*
+ * \brief Libyuv initialization to overwrite default libc memory/free allocator
+ * \author Alexander Boettcher
+ * \date 2023-09-15
+ */
+
+/*
+ * Copyright (C) 2023 Genode Labs GmbH
+ *
+ * This file is part of the Genode OS framework, which is distributed
+ * under the terms of the GNU Affero General Public License version 3.
+ */
+
+#ifndef _INCLUDE__LIBYUV__LIBYUV_H_
+#define _INCLUDE__LIBYUV__LIBYUV_H_
+
+/* use same namespace as used in contrib libyuv sources */
+namespace libyuv
+{
+ typedef void * (*type_malloc)(unsigned long);
+ typedef void (*type_free )(void *);
+
+ extern "C" void libyuv_init(type_malloc os_malloc, type_free os_free);
+}
+
+#endif /* _INCLUDE__LIBYUV_LIBYUV_H_ */
diff --git a/repos/libports/lib/mk/libyuv.inc b/repos/libports/lib/mk/libyuv.inc
index 813769a194..8788884fb5 100644
--- a/repos/libports/lib/mk/libyuv.inc
+++ b/repos/libports/lib/mk/libyuv.inc
@@ -3,13 +3,18 @@ SHARED_LIB = yes
YUV_PORT := $(call select_from_ports,libyuv)
YUV_DIR = $(YUV_PORT)/src/lib/libyuv
+LIB_DIR = $(REP_DIR)/src/lib/libyuv
+
LIBS = libc stdcxx jpeg
+INC_DIR += $(REP_DIR)/include
INC_DIR += $(YUV_PORT)/include
-SRC_CC = $(notdir $(wildcard $(YUV_DIR)/source/*.cc))
+SRC_CC = $(notdir $(wildcard $(YUV_DIR)/source/*.cc))
+SRC_CC += memory.cc
CC_CXX_WARN_STRICT = -Wextra -Werror
CC_OPT += -Wno-unused-parameter -DHAVE_JPEG
-vpath %.cc $(YUV_DIR)/source
+vpath memory.cc $(LIB_DIR)
+vpath %.cc $(YUV_DIR)/source
diff --git a/repos/libports/lib/symbols/libyuv b/repos/libports/lib/symbols/libyuv
index e9b31dc5e3..e31c345f14 100644
--- a/repos/libports/lib/symbols/libyuv
+++ b/repos/libports/lib/symbols/libyuv
@@ -351,3 +351,4 @@ YUY2ToI420 T
YUY2ToI422 T
YUY2ToNV12 T
YUY2ToY T
+libyuv_init T
diff --git a/repos/libports/ports/libyuv.hash b/repos/libports/ports/libyuv.hash
index ff1ba76773..b00eb92182 100644
--- a/repos/libports/ports/libyuv.hash
+++ b/repos/libports/ports/libyuv.hash
@@ -1 +1 @@
-01cdd9be97364d27b8d6aa7aafc18ba0f2eb4c3f
+d53528820b90c03e8b8d23ef6bae7ad4337a3cf3
diff --git a/repos/libports/ports/libyuv.port b/repos/libports/ports/libyuv.port
index ba7e8fdc05..c987c9633b 100644
--- a/repos/libports/ports/libyuv.port
+++ b/repos/libports/ports/libyuv.port
@@ -10,6 +10,6 @@ DIRS := include include/libyuv
DIR_CONTENT(include) := src/lib/libyuv/include/libyuv.h
DIR_CONTENT(include/libyuv) := src/lib/libyuv/include/libyuv/*.h
-PATCHES := src/lib/libyuv/constraints.patch
+PATCHES := src/lib/libyuv/constraints.patch src/lib/libyuv/memory.patch
PATCH_OPT := -d src/lib/libyuv -p1
diff --git a/repos/libports/recipes/api/libyuv/content.mk b/repos/libports/recipes/api/libyuv/content.mk
index 22c66df785..9b0803da5d 100644
--- a/repos/libports/recipes/api/libyuv/content.mk
+++ b/repos/libports/recipes/api/libyuv/content.mk
@@ -5,6 +5,7 @@ PORT_DIR := $(call port_dir,$(REP_DIR)/ports/libyuv)
include:
mkdir $@
cp -r $(PORT_DIR)/include/* $@/
+ cp -r $(REP_DIR)/include/libyuv $@/
lib/symbols/libyuv:
$(mirror_from_rep_dir)
diff --git a/repos/libports/recipes/src/libyuv/content.mk b/repos/libports/recipes/src/libyuv/content.mk
index 9b83f440e6..f0830f3937 100644
--- a/repos/libports/recipes/src/libyuv/content.mk
+++ b/repos/libports/recipes/src/libyuv/content.mk
@@ -2,7 +2,8 @@ MIRROR_FROM_REP_DIR := lib/mk/libyuv.inc \
lib/mk/spec/arm_v8/libyuv.mk \
lib/mk/spec/x86_32/libyuv.mk \
lib/mk/spec/x86_64/libyuv.mk \
- lib/import/import-libyuv.mk
+ lib/import/import-libyuv.mk \
+ include/libyuv
content: src/lib/libyuv include LICENSE $(MIRROR_FROM_REP_DIR)
@@ -11,6 +12,7 @@ PORT_DIR := $(call port_dir,$(REP_DIR)/ports/libyuv)
src/lib/libyuv:
mkdir -p $@
cp -r $(PORT_DIR)/src/lib/libyuv/source $@
+ cp -r $(REP_DIR)/src/lib/libyuv/* $@
include:
mkdir -p $@
diff --git a/repos/libports/recipes/src/libyuv/used_apis b/repos/libports/recipes/src/libyuv/used_apis
index 8935f6c215..ba836f18bc 100644
--- a/repos/libports/recipes/src/libyuv/used_apis
+++ b/repos/libports/recipes/src/libyuv/used_apis
@@ -1,4 +1,4 @@
+base
libc
stdcxx
jpeg
-
diff --git a/repos/libports/src/lib/libyuv/memory.cc b/repos/libports/src/lib/libyuv/memory.cc
new file mode 100644
index 0000000000..bde842159c
--- /dev/null
+++ b/repos/libports/src/lib/libyuv/memory.cc
@@ -0,0 +1,57 @@
+/*
+ * \brief Support to overwrite default memory allocator of libyuv
+ * \author Alexander Boettcher
+ */
+
+/*
+ * Copyright (C) 2023 Genode Labs GmbH
+ *
+ * This file is part of the Genode OS framework, which is distributed
+ * under the terms of the GNU Affero General Public License version 2.
+ */
+
+#include
+
+#include
+
+
+typedef void * (*type_malloc)(unsigned long);
+typedef void (*type_free )(void *);
+
+
+static type_malloc use_malloc(type_malloc m = malloc)
+{
+ static auto defined_malloc = m;
+ return defined_malloc;
+}
+
+
+static type_free use_free(type_free f = free)
+{
+ static auto defined_free = f;
+ return defined_free;
+}
+
+
+extern "C" void libyuv_init(type_malloc os_malloc, type_free os_free)
+{
+ if (!os_malloc || !os_free) {
+ Genode::error("invalid libyuv allocator specified");
+ return;
+ }
+
+ use_malloc(os_malloc);
+ use_free (os_free);
+}
+
+
+extern "C" void *libyuv_malloc(unsigned long size)
+{
+ return use_malloc()(size);
+}
+
+
+extern "C" void libyuv_free(void *ptr)
+{
+ use_free()(ptr);
+}
diff --git a/repos/libports/src/lib/libyuv/memory.patch b/repos/libports/src/lib/libyuv/memory.patch
new file mode 100644
index 0000000000..eb9171a183
--- /dev/null
+++ b/repos/libports/src/lib/libyuv/memory.patch
@@ -0,0 +1,128 @@
+--- libyuv/include/libyuv/row.h
++++ libyuv/include/libyuv/row.h
+@@ -20,6 +20,9 @@
+ extern "C" {
+ #endif
+
++extern void *libyuv_malloc(unsigned long size);
++extern void libyuv_free(void *ptr);
++
+ // TODO: Fix Win32 build
+ // https://bugs.chromium.org/p/libyuv/issues/detail?id=900
+ #if defined(__pnacl__) || defined(__CLR_VER) || defined(_M_IX86) || \
+@@ -785,11 +788,11 @@
+ #define IS_ALIGNED(p, a) (!((uintptr_t)(p) & ((a)-1)))
+
+ #define align_buffer_64(var, size) \
+- uint8_t* var##_mem = (uint8_t*)(malloc((size) + 63)); /* NOLINT */ \
++ uint8_t* var##_mem = (uint8_t*)(libyuv_malloc((size) + 63)); /* NOLINT */ \
+ uint8_t* var = (uint8_t*)(((intptr_t)(var##_mem) + 63) & ~63) /* NOLINT */
+
+ #define free_aligned_buffer_64(var) \
+- free(var##_mem); \
++ libyuv_free(var##_mem); \
+ var = 0
+
+ #if defined(__APPLE__) || defined(__x86_64__) || defined(__llvm__)
+--- libyuv/source/convert_jpeg.cc
++++ libyuv/source/convert_jpeg.cc
+@@ -32,6 +32,10 @@
+ int h;
+ };
+
++extern void *libyuv_malloc(unsigned long size);
++extern void libyuv_free(void *ptr);
++
++
+ static void JpegCopyI420(void* opaque,
+ const uint8_t* const* data,
+ const int* strides,
+--- libyuv/source/convert_to_argb.cc
++++ libyuv/source/convert_to_argb.cc
+@@ -23,6 +23,9 @@
+ extern "C" {
+ #endif
+
++extern void *libyuv_malloc(unsigned long size);
++extern void libyuv_free(void *ptr);
++
+ // Convert camera sample to ARGB with cropping, rotation and vertical flip.
+ // src_width is used for source stride computation
+ // src_height is used to compute location of planes, and indicate inversion
+@@ -76,7 +79,7 @@
+
+ if (need_buf) {
+ int argb_size = crop_width * 4 * abs_crop_height;
+- rotate_buffer = (uint8_t*)malloc(argb_size); /* NOLINT */
++ rotate_buffer = (uint8_t*)libyuv_malloc(argb_size); /* NOLINT */
+ if (!rotate_buffer) {
+ return 1; // Out of memory runtime error.
+ }
+@@ -366,7 +369,7 @@
+ r = ARGBRotate(dst_argb, dst_stride_argb, dest_argb, dest_dst_stride_argb,
+ crop_width, abs_crop_height, rotation);
+ }
+- free(rotate_buffer);
++ libyuv_free(rotate_buffer);
+ } else if (rotation) {
+ src = sample + (src_width * crop_y + crop_x) * 4;
+ r = ARGBRotate(src, src_width * 4, dst_argb, dst_stride_argb, crop_width,
+--- libyuv/source/convert_to_i420.cc
++++ libyuv/source/convert_to_i420.cc
+@@ -19,6 +19,9 @@
+ extern "C" {
+ #endif
+
++extern void *libyuv_malloc(unsigned long size);
++extern void libyuv_free(void *ptr);
++
+ // Convert camera sample to I420 with cropping, rotation and vertical flip.
+ // src_width is used for source stride computation
+ // src_height is used to compute location of planes, and indicate inversion
+@@ -76,7 +79,7 @@
+ if (need_buf) {
+ int y_size = crop_width * abs_crop_height;
+ int uv_size = ((crop_width + 1) / 2) * ((abs_crop_height + 1) / 2);
+- rotate_buffer = (uint8_t*)malloc(y_size + uv_size * 2); /* NOLINT */
++ rotate_buffer = (uint8_t*)libyuv_malloc(y_size + uv_size * 2); /* NOLINT */
+ if (!rotate_buffer) {
+ return 1; // Out of memory runtime error.
+ }
+@@ -260,7 +263,7 @@
+ tmp_v, tmp_v_stride, crop_width, abs_crop_height,
+ rotation);
+ }
+- free(rotate_buffer);
++ libyuv_free(rotate_buffer);
+ }
+
+ return r;
+--- libyuv/source/scale_argb.cc
++++ libyuv/source/scale_argb.cc
+@@ -23,6 +23,9 @@
+ extern "C" {
+ #endif
+
++extern void *libyuv_malloc(unsigned long size);
++extern void libyuv_free(void *ptr);
++
+ static __inline int Abs(int v) {
+ return v >= 0 ? v : -v;
+ }
+@@ -1071,7 +1074,7 @@
+ int clip_width,
+ int clip_height,
+ enum FilterMode filtering) {
+- uint8_t* argb_buffer = (uint8_t*)malloc(src_width * src_height * 4);
++ uint8_t* argb_buffer = (uint8_t*)libyuv_malloc(src_width * src_height * 4);
+ int r;
+ (void)src_fourcc; // TODO(fbarchard): implement and/or assert.
+ (void)dst_fourcc;
+@@ -1081,7 +1084,7 @@
+ r = ARGBScaleClip(argb_buffer, src_width * 4, src_width, src_height, dst_argb,
+ dst_stride_argb, dst_width, dst_height, clip_x, clip_y,
+ clip_width, clip_height, filtering);
+- free(argb_buffer);
++ libyuv_free(argb_buffer);
+ return r;
+ }