mirror of
https://github.com/genodelabs/genode.git
synced 2025-02-20 09:46:20 +00:00
libyuv: add support to overwrite default allocator
Internally libyuv uses malloc & free for short time dynamic memory allocation during image transformation. The converted images are such large, that the Libc allocator will create and destroy new Genode dataspace per image. In time sensitive code paths, the overhead can be noticeable by the caller of the image transformation. The patch adds the option to register callbacks in the libyuv library to implement the image allocation by users of the library. They may implement caching strategies to avoid the overhead, e.g. as seen with qemu-usb and the webcam model.
This commit is contained in:
parent
63c5ec7390
commit
0d868515a5
26
repos/libports/include/libyuv/libyuv.h
Normal file
26
repos/libports/include/libyuv/libyuv.h
Normal file
@ -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_ */
|
@ -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
|
||||
|
@ -351,3 +351,4 @@ YUY2ToI420 T
|
||||
YUY2ToI422 T
|
||||
YUY2ToNV12 T
|
||||
YUY2ToY T
|
||||
libyuv_init T
|
||||
|
@ -1 +1 @@
|
||||
01cdd9be97364d27b8d6aa7aafc18ba0f2eb4c3f
|
||||
d53528820b90c03e8b8d23ef6bae7ad4337a3cf3
|
||||
|
@ -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
|
||||
|
||||
|
@ -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)
|
||||
|
@ -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 $@
|
||||
|
@ -1,4 +1,4 @@
|
||||
base
|
||||
libc
|
||||
stdcxx
|
||||
jpeg
|
||||
|
||||
|
57
repos/libports/src/lib/libyuv/memory.cc
Normal file
57
repos/libports/src/lib/libyuv/memory.cc
Normal file
@ -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 <base/log.h>
|
||||
|
||||
#include <stdlib.h>
|
||||
|
||||
|
||||
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);
|
||||
}
|
128
repos/libports/src/lib/libyuv/memory.patch
Normal file
128
repos/libports/src/lib/libyuv/memory.patch
Normal file
@ -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;
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user