ccimx95: backport NPU suppport from lf-6.12.49-2.2.0

https://onedigi.atlassian.net/browse/DEL-9987

Signed-off-by: Javier Viguera <javier.viguera@digi.com>
This commit is contained in:
Javier Viguera 2026-02-19 17:08:23 +01:00
parent 7736ba21ca
commit 11999b4810
20 changed files with 1274 additions and 0 deletions

View File

@ -358,6 +358,19 @@ OPTEE_PKGS ??= "optee-client optee-os"
PREFERRED_VERSION_opencv:mx8-nxp-bsp ??= "4.10.0.imx"
PREFERRED_VERSION_opencv:mx9-nxp-bsp ??= "4.10.0.imx"
# ML on ccimx95 (backport from NXP's lf-6.12.49-2.2.0)
PREFERRED_VERSION_flatbuffers-native:mx95-nxp-bsp ??= "24.3.25"
PREFERRED_VERSION_flatbuffers:mx95-nxp-bsp ??= "24.3.25"
PREFERRED_VERSION_neutron:mx95-nxp-bsp ??= "2.2.1"
PREFERRED_VERSION_nnstreamer-edge:mx95-nxp-bsp ??= "0.2.6"
PREFERRED_VERSION_nnstreamer:mx95-nxp-bsp ??= "2.4.2"
PREFERRED_VERSION_onnxruntime:mx95-nxp-bsp ??= "1.22.0"
PREFERRED_VERSION_python3-flatbuffers:mx95-nxp-bsp ??= "24.3.25"
PREFERRED_VERSION_tensorflow-lite-host-tools-native:mx95-nxp-bsp ??= "2.19.0"
PREFERRED_VERSION_tensorflow-lite-host-tools:mx95-nxp-bsp ??= "2.19.0"
PREFERRED_VERSION_tensorflow-lite-neutron-delegate:mx95-nxp-bsp ??= "2.19.0"
PREFERRED_VERSION_tensorflow-lite:mx95-nxp-bsp ??= "2.19.0"
EXTRA_IMAGEDEPENDS += "u-boot"
# Do not update fstab file when using wic images

View File

@ -0,0 +1,39 @@
From 6cb4d671a88e054744ce3029df9e733dc724ee76 Mon Sep 17 00:00:00 2001
From: Derek Bailey <dbaileychess@gmail.com>
Date: Mon, 19 Aug 2024 16:08:46 -0700
Subject: [PATCH] Fixes LICENSE file in python
Fixes: #8376
Upstream-Status: Backport [https://github.com/google/flatbuffers/commit/6cb4d671a88e054744ce3029df9e733dc724ee76]
---
python/setup.cfg | 2 +-
python/setup.py | 1 -
2 files changed, 1 insertion(+), 2 deletions(-)
diff --git a/python/setup.cfg b/python/setup.cfg
index e3647037..0c43b1cf 100644
--- a/python/setup.cfg
+++ b/python/setup.cfg
@@ -3,4 +3,4 @@ universal=1
[metadata]
license_files =
- ../license
\ No newline at end of file
+ ../LICENSE
\ No newline at end of file
diff --git a/python/setup.py b/python/setup.py
index 065b2754..21ddecb9 100644
--- a/python/setup.py
+++ b/python/setup.py
@@ -18,7 +18,6 @@ setup(
name='flatbuffers',
version='24.3.25',
license='Apache 2.0',
- license_files='../LICENSE',
author='Derek Bailey',
author_email='derekbailey@google.com',
url='https://google.github.io/flatbuffers/',
--
2.34.1

View File

@ -0,0 +1,7 @@
Name: flatbuffers
Description: memory efficient serialization library
Version: @version@
Requires:
Libs: -L@libdir@ -lflatbuffers
Cflags: -I@includedir@

View File

@ -0,0 +1,10 @@
FILESEXTRAPATHS:prepend := "${THISDIR}/files:"
SRC_URI:append = " file://flatbuffers.pc.in"
do_install:append() {
install -D -m 0644 ${WORKDIR}/flatbuffers.pc.in ${D}${libdir}/pkgconfig/flatbuffers.pc
sed -i 's:@version@:${PV}:g
s:@libdir@:${libdir}:g
s:@includedir@:${includedir}:g' ${D}${libdir}/pkgconfig/flatbuffers.pc
}

View File

@ -0,0 +1,34 @@
SUMMARY = "Memory Efficient Serialization Library"
HOMEPAGE = "https://github.com/google/flatbuffers"
SECTION = "console/tools"
LICENSE = "Apache-2.0"
PACKAGE_BEFORE_PN = "${PN}-compiler"
DEPENDS = "flatbuffers-native"
RDEPENDS:${PN}-compiler = "${PN}"
RDEPENDS:${PN}-${PYTHON_PN} = "${PN}"
RDEPENDS:${PN}-dev += "${PN}-compiler"
LIC_FILES_CHKSUM = "file://LICENSE;md5=3b83ef96387f14655fc854ddc3c6bd57"
SRCREV = "e6463926479bd6b330cbcf673f7e917803fd5831"
SRC_URI = "git://github.com/google/flatbuffers.git;branch=master;protocol=https"
CVE_CHECK_IGNORE += "CVE-2020-35864"
EXTRA_OECMAKE += "\
-DFLATBUFFERS_BUILD_TESTS=OFF \
-DFLATBUFFERS_BUILD_SHAREDLIB=ON \
"
EXTRA_OECMAKE:append:class-target = " -DFLATBUFFERS_FLATC_EXECUTABLE=${STAGING_BINDIR_NATIVE}/flatc"
inherit cmake python3native
S = "${WORKDIR}/git"
FILES:${PN}-compiler = "${bindir}"
BBCLASSEXTEND = "native nativesdk"

View File

@ -0,0 +1,16 @@
SUMMARY = "Memory Efficient Serialization Library - Python3 Modules"
HOMEPAGE = "https://github.com/google/flatbuffers"
SECTION = "console/tools"
LICENSE = "Apache-2.0"
LIC_FILES_CHKSUM = "file://../LICENSE;md5=3b83ef96387f14655fc854ddc3c6bd57"
SRCREV = "e6463926479bd6b330cbcf673f7e917803fd5831"
SRC_URI = "git://github.com/google/flatbuffers.git;branch=master;protocol=https \
file://0001-Fixes-LICENSE-file-in-python.patch"
S = "${WORKDIR}/git/python"
RDEPENDS:${PN} = "flatbuffers"
PATCHTOOL = "git"
inherit setuptools3

View File

@ -0,0 +1,8 @@
require recipes-libraries/neutron/neutron_1.0.0.bb
LIC_FILES_CHKSUM = "file://LICENSE.txt;md5=bc649096ad3928ec06a8713b8d787eac"
SRC_URI = "${NEUTRON_SRC};branch=${SRCBRANCH}"
NEUTRON_SRC ?= "git://github.com/nxp-imx/neutron.git;protocol=https"
SRCBRANCH = "lf-6.12.49_2.2.0"
SRCREV = "a7d5f17a9210c45aef2bbc9dc09d637f41fd3a7c"

View File

@ -0,0 +1,203 @@
# Copyright 2020-2025 NXP
DESCRIPTION = "cross-platform, high performance scoring engine for ML models"
SECTION = "devel"
LICENSE = "MIT & Apache-2.0"
LIC_FILES_CHKSUM_runtime = "file://LICENSE;md5=0f7e3b1308cb5c00b372a6e78835732d"
LIC_FILES_CHKSUM_model = "file://${S}/example-models/squeezenet/LICENSE;md5=3b83ef96387f14655fc854ddc3c6bd57"
LIC_FILES_CHKSUM = "${LIC_FILES_CHKSUM_runtime} ${LIC_FILES_CHKSUM_model}"
DEPENDS = "libpng zlib"
inherit setuptools3
SRC_URI = "${ONNXRUNTIME_SRC};branch=${SRCBRANCH}"
ONNXRUNTIME_SRC ?= "gitsm://github.com/nxp-imx/onnxruntime-imx.git;protocol=https"
SRCBRANCH = "lf-6.12.49_2.2.0"
SRCREV = "2ef0bb77e4b886c1d075b2bbc4ce0dc5b60c268b"
S = "${WORKDIR}/git"
inherit cmake python3native
OECMAKE_SOURCEPATH = "${S}/cmake"
OECMAKE_GENERATOR = "Unix Makefiles"
# Notes:
# Abseil:
# - FETCHCONTENT_FULLY_DISCONNECTED=OFF and do_configure:prepend() added to allow
# abseil build process (the issue was related to CMake not fetching sources)
EXTRA_OECMAKE += "\
-DFETCHCONTENT_FULLY_DISCONNECTED=OFF \
-DCMAKE_BUILD_TYPE=RelWithDebInfo \
-Donnxruntime_BUILD_UNIT_TESTS=ON \
-DCMAKE_VERBOSE_MAKEFILE:BOOL=ON \
"
PYTHON_DEPENDS = "\
${PYTHON_PN} \
${PYTHON_PN}-pip-native \
${PYTHON_PN}-numpy \
${PYTHON_PN}-numpy-native \
${PYTHON_PN}-packaging-native\
${PYTHON_PN}-pybind11\
${PYTHON_PN}-pybind11-native\
"
PYTHON_RDEPENDS = "\
${PYTHON_PN} \
${PYTHON_PN}-numpy \
${PYTHON_PN}-protobuf \
${PYTHON_PN}-coloredlogs \
${PYTHON_PN}-flatbuffers \
${PYTHON_PN}-sympy \
"
PACKAGECONFIG ?= "crosscompiling sharedlib python kleidiai ${PACKAGECONFIG_NPU}"
PACKAGECONFIG_NPU = ""
PACKAGECONFIG_NPU:mx95-nxp-bsp = "neutron"
PACKAGECONFIG_NPU:mx943-nxp-bsp = "neutron"
PACKAGECONFIG_NPU:mx8-nxp-bsp:imxgpu = "vsinpu"
PACKAGECONFIG_NPU:mx8mm-nxp-bsp = ""
PACKAGECONFIG[nsync] = "-Donnxruntime_USE_NSYNC=ON, -Donnxruntime_USE_NSYNC=OFF"
PACKAGECONFIG[prebuilt] = "-Donnxruntime_USE_PREBUILT_PB=ON, -Donnxruntime_USE_PREBUILT_PB=OFF"
PACKAGECONFIG[openmp] = "-Donnxruntime_USE_OPENMP=ON, -Donnxruntime_USE_OPENMP=OFF"
PACKAGECONFIG[trt] = "-Donnxruntime_USE_TRT=ON, -Donnxruntime_USE_TRT=OFF"
PACKAGECONFIG[nuphar] = "-Donnxruntime_USE_NUPHAR=ON, -Donnxruntime_USE_NUPHAR=OFF"
PACKAGECONFIG[brainslice] = "-Donnxruntime_USE_BRAINSLICE=ON, -Donnxruntime_USE_BRAINSLICE=OFF"
PACKAGECONFIG[python] = "-Donnxruntime_ENABLE_PYTHON=ON, -Donnxruntime_ENABLE_PYTHON=OFF, ${PYTHON_DEPENDS}, ${PYTHON_RDEPENDS}"
PACKAGECONFIG[sharedlib] = "-Donnxruntime_BUILD_SHARED_LIB=ON, -Donnxruntime_BUILD_SHARED_LIB=OFF"
PACKAGECONFIG[eigenblas] = "-Donnxruntime_USE_EIGEN_FOR_BLAS=ON, -Donnxruntime_USE_EIGEN_FOR_BLAS=OFF"
PACKAGECONFIG[openblas] = "-Donnxruntime_USE_OPENBLAS=ON, -Donnxruntime_USE_OPENBLAS=OFF"
PACKAGECONFIG[dnnl] = "-Donnxruntime_USE_DNNL=ON, -Donnxruntime_USE_DNNL=OFF"
PACKAGECONFIG[mklml] = "-Donnxruntime_USE_MKLML=ON, -Donnxruntime_USE_MKLML=OFF"
PACKAGECONFIG[gemmlowp] = "-Donnxruntime_USE_GEMMLOWP=ON, -Donnxruntime_USE_GEMMLOWP=OFF"
PACKAGECONFIG[ngraph] = "-Donnxruntime_USE_NGRAPH=ON, -Donnxruntime_USE_NGRAPH=OFF"
PACKAGECONFIG[openvino] = "-Donnxruntime_USE_OPENVINO=ON, -Donnxruntime_USE_OPENVINO=OFF"
PACKAGECONFIG[interop] = "-Donnxruntime_ENABLE_LANGUAGE_INTEROP_OPS=ON, -Donnxruntime_ENABLE_LANGUAGE_INTEROP_OPS=OFF"
PACKAGECONFIG[dml] = "-Donnxruntime_USE_DML=ON, -Donnxruntime_USE_DML=OFF"
PACKAGECONFIG[telemetry] = "-Donnxruntime_USE_TELEMETRY=ON, -Donnxruntime_USE_TELEMETRY=OFF"
PACKAGECONFIG[armnn-relu] = "-Donnxruntime_ARMNN_RELU_USE_CPU=ON, -Donnxruntime_ARMNN_RELU_USE_CPU=OFF"
PACKAGECONFIG[armnn-bn] = "-Donnxruntime_ARMNN_BN_USE_CPU=ON, -Donnxruntime_ARMNN_BN_USE_CPU=OFF"
PACKAGECONFIG[opschema] = "-Donnxruntime_PYBIND_EXPORT_OPSCHEMA=ON, -Donnxruntime_PYBIND_EXPORT_OPSCHEMA=OFF"
PACKAGECONFIG[nnapi] = "-Donnxruntime_USE_NNAPI_BUILTIN=ON, -Donnxruntime_USE_NNAPI_BUILTIN=OFF"
PACKAGECONFIG[tvm] = "-Donnxruntime_USE_TVM=ON, -Donnxruntime_USE_TVM=OFF"
PACKAGECONFIG[llvm] = "-Donnxruntime_USE_LLVM=ON, -Donnxruntime_USE_LLVM=OFF"
PACKAGECONFIG[microsoft] = "-Donnxruntime_ENABLE_MICROSOFT_INTERNAL=ON, -Donnxruntime_ENABLE_MICROSOFT_INTERNAL=OFF"
PACKAGECONFIG[eigenthreadpool] = "-Donnxruntime_USE_EIGEN_THREADPOOL=ON, -Donnxruntime_USE_EIGEN_THREADPOOL=OFF"
PACKAGECONFIG[tensorrt] = "-Donnxruntime_USE_TENSORRT=ON, -Donnxruntime_USE_TENSORRT=OFF"
PACKAGECONFIG[crosscompiling] = "-Donnxruntime_CROSS_COMPILING=ON, -Donnxruntime_CROSS_COMPILING=OFF "
PACKAGECONFIG[server] = "-Donnxruntime_BUILD_SERVER=ON, -Donnxruntime_BUILD_SERVER=OFF"
PACKAGECONFIG[x86] = "-Donnxruntime_BUILD:x86=ON, -Donnxruntime_BUILD:x86=OFF"
PACKAGECONFIG[fullprotobuf] = "-Donnxruntime_USE_FULL_PROTOBUF=ON, -Donnxruntime_USE_FULL_PROTOBUF=OFF"
PACKAGECONFIG[ops] = "-Donnxruntime_DISABLE_CONTRIB_OPS=ON, -Donnxruntime_DISABLE_CONTRIB_OPS=OFF"
PACKAGECONFIG[staticruntime] = "-Donnxruntime_MSVC_STATIC_RUNTIME=ON, -Donnxruntime_MSVC_STATIC_RUNTIME=OFF"
PACKAGECONFIG[runtests] = "-Donnxruntime_RUN_ONNX_TESTS=ON, -Donnxruntime_RUN_ONNX_TESTS=OFF"
PACKAGECONFIG[reports] = "-Donnxruntime_GENERATE_TEST_REPORTS=ON, -Donnxruntime_GENERATE_TEST_REPORTS=OFF"
PACKAGECONFIG[devmode] = "-Donnxruntime_DEV_MODE=ON, -Donnxruntime_DEV_MODE=OFF"
PACKAGECONFIG[cuda] = "-Donnxruntime_USE_CUDA=ON, -Donnxruntime_USE_CUDA=OFF"
PACKAGECONFIG[automl] = "-Donnxruntime_USE_AUTOML=ON, -Donnxruntime_USE_AUTOML=OFF"
PACKAGECONFIG[jemalloc] = "-Donnxruntime_USE_JEMALLOC=ON, -Donnxruntime_USE_JEMALLOC=OFF"
PACKAGECONFIG[mimalloc] = "-Donnxruntime_USE_MIMALLOC=ON, -Donnxruntime_USE_MIMALLOC=OFF"
PACKAGECONFIG[csharp] = "-Donnxruntime_BUILD_CSHARP=ON, -Donnxruntime_BUILD_CSHARP=OFF"
PACKAGECONFIG[java] = "-Donnxruntime_BUILD_JAVA=ON, -Donnxruntime_BUILD_JAVA=OFF"
PACKAGECONFIG[kleidiai] = "-Donnxruntime_USE_KLEIDIAI=ON, -Donnxruntime_USE_KLEIDIAI=OFF"
PACKAGECONFIG[neutron] = "-Donnxruntime_USE_NEUTRON=ON, -Donnxruntime_USE_NEUTRON=OFF, neutron nlohmann-json"
PACKAGECONFIG[vsinpu] = "-Donnxruntime_USE_VSINPU=ON, -Donnxruntime_USE_VSINPU=OFF, tim-vx"
do_configure[network] = "1"
do_configure:prepend() {
export HTTP_PROXY=${http_proxy}
export HTTPS_PROXY=${https_proxy}
export http_proxy=${http_proxy}
export https_proxy=${https_proxy}
}
do_compile[network] = "1"
do_compile:prepend() {
if ${@bb.utils.contains('PACKAGECONFIG', 'python', 'true', 'false', d)}; then
# required to pull pybind11
export HTTP_PROXY=${http_proxy}
export HTTPS_PROXY=${https_proxy}
export http_proxy=${http_proxy}
export https_proxy=${https_proxy}
fi
}
SETUPTOOLS_SETUP_PATH = "${B}"
do_compile:append() {
if ${@bb.utils.contains('PACKAGECONFIG', 'python', 'true', 'false', d)}; then
# Copy 'setup.py' to build dir
cp ${S}/setup.py ${B}
cp -r ${S}/onnxruntime/python ${B}/onnxruntime/
# Copy path file with path 'docs/python/README.rst' to build dir
mkdir -p ${B}/docs/python && cp ${S}/docs/python/README.rst ${B}/docs/python
setuptools3_do_compile
git config --global --add safe.directory ${WORKDIR}/build/pybind11/src/pybind11
fi
}
do_install:append() {
CP_ARGS="-Prf --preserve=mode,timestamps --no-preserve=ownership"
# Ensure target dir exists
install -d ${D}${bindir}/${BP}
# Copy squeezenet updated model from onnxruntime-imx repo
if [ -d ${S}/example-models/ ]; then
cp $CP_ARGS ${S}/example-models/squeezenet ${D}${bindir}/${BP}/
fi
# Copy label_image_onnx.py tool from onnxruntime-imx repo
cp ${S}/onnxruntime/core/providers/neutron/tools/label_image_onnx.py ${D}${bindir}/${BP}/
# If cmake installs 'onnx_test_runner' at bindir level, move to package
if [ -f ${D}${bindir}/onnx_test_runner ]; then
mv ${D}${bindir}/onnx_test_runner ${D}${bindir}/${BP}/
fi
# Install onnxruntime_perf_test in main package
install -m 0755 ${B}/onnxruntime_perf_test ${D}${bindir}/${BP}
# Install test binaries and data in test package
install -d ${D}${bindir}/${BP}/tests
install -m 0744 ${B}/libcustom_op_library.so ${D}${bindir}/${BP}/tests
install -m 0744 ${B}/onnxruntime_global_thread_pools_test ${D}${bindir}/${BP}/tests
install -m 0744 ${B}/onnxruntime_mlas_test ${D}${bindir}/${BP}/tests
install -m 0744 ${B}/onnxruntime_shared_lib_test ${D}${bindir}/${BP}/tests
install -m 0744 ${B}/onnxruntime_test_all ${D}${bindir}/${BP}/tests
cp $CP_ARGS ${B}/testdata ${D}${bindir}/${BP}/tests
if ${@bb.utils.contains('PACKAGECONFIG', 'python', 'true', 'false', d)}; then
setuptools3_do_install
find ${D}/${PYTHON_SITEPACKAGES_DIR} -type d -name "__pycache__" -exec rm -Rf {} +
git config --global --unset-all safe.directory ${TMPDIR}/.*/${PN}/.*/build/pybind11/src/pybind11
fi
rm ${D}/${PYTHON_SITEPACKAGES_DIR}/${PN}/capi/libonnxruntime.so*
}
# Make the package arch SOC-specific since the recipe now builds with SOC-specific configuration:
PACKAGE_ARCH = "${MACHINE_SOCARCH}"
# Adjust the Python runtime dependency inherited from setuptools3-base.bbclass
# since Python support for this recipe is conditional
RDEPENDS:${PN}:remove:class-target = " \
${@bb.utils.contains('PACKAGECONFIG', 'python', '', '${PYTHON_PN}-core', d)}"
# libonnxruntime_providers_shared.so is being packaged into -dev which is intended
INSANE_SKIP:${PN}-dev += "dev-elf"
# A separate tests package for the test binaries not appearing in the main package
PACKAGE_BEFORE_PN = "${PN}-tests"
FILES:${PN}-tests = "${bindir}/${BP}/tests/*"
# libcustom_op_library.so is in bindir, which is intended;
# onnxruntime_shared_lib_test requires the shlib to be in the same directory as testdata to run properly
INSANE_SKIP:${PN}-tests += "libdir"
INSANE_SKIP:${PN}-dbg += "libdir"

View File

@ -0,0 +1,5 @@
# Copyright 2020-2025 NXP
TENSORFLOW_LITE_SRC ?= "git://github.com/nxp-imx/tensorflow-imx.git;protocol=https"
SRCBRANCH_tf = "lf-6.12.49_2.2.0"
SRCREV_tf = "c6f244fe303bd5170fdd6b8d570fc0e3282fd38b"

View File

@ -0,0 +1,29 @@
# Copyright 2022-2025 NXP
DESCRIPTION = "Host tools required for build of TensorFlow Lite C++ Library unit tests and Evaluation Tools"
LICENSE = "Apache-2.0"
LIC_FILES_CHKSUM = "file://LICENSE;md5=4158a261ca7f2525513e31ba9c50ae98"
require tensorflow-lite-${PV}.inc
SRC_URI = "${TENSORFLOW_LITE_SRC};branch=${SRCBRANCH_tf};name=tf"
inherit cmake
S = "${WORKDIR}/git"
OECMAKE_SOURCEPATH = "${S}/tensorflow/lite/tools/cmake/native_tools"
BBCLASSEXTEND = "native nativesdk"
EXTRA_OECMAKE = " \
-DFETCHCONTENT_FULLY_DISCONNECTED=OFF \
-DCMAKE_SYSROOT=${PKG_CONFIG_SYSROOT_DIR} \
"
CXXFLAGS += "-fPIC"
do_configure[network] = "1"
do_configure:prepend() {
export HTTP_PROXY=${http_proxy}
export HTTPS_PROXY=${https_proxy}
export http_proxy=${http_proxy}
export https_proxy=${https_proxy}
}

View File

@ -0,0 +1,65 @@
# Copyright 2023-2025 NXP
DESCRIPTION = "TensorFlow Lite Neutron Delegate"
LICENSE = "Apache-2.0"
LIC_FILES_CHKSUM = "file://LICENSE.txt;md5=86d3f3a95c324c9479bd8986968f4327"
DEPENDS = "tensorflow-lite neutron tensorflow-lite-host-tools-native"
require tensorflow-lite-${PV}.inc
NEUTRON_DELEGATE_SRC ?= "git://github.com/nxp-imx/tflite-neutron-delegate.git;protocol=https"
SRCBRANCH_neutron = "lf-6.12.49_2.2.0"
SRCREV_neutron = "f24d08e5e1d461e669ece3c476c6dd340ce355cb"
SRCREV_FORMAT = "neutron_tf"
SRC_URI = "${NEUTRON_DELEGATE_SRC};branch=${SRCBRANCH_neutron};name=neutron \
${TENSORFLOW_LITE_SRC};branch=${SRCBRANCH_tf};name=tf;destsuffix=tfgit \
"
S = "${WORKDIR}/git"
inherit python3native cmake
EXTRA_OECMAKE = "-DCMAKE_SYSROOT=${PKG_CONFIG_SYSROOT_DIR}"
EXTRA_OECMAKE += " \
-DFETCHCONTENT_FULLY_DISCONNECTED=OFF \
-DTFLITE_HOST_TOOLS_DIR=${STAGING_BINDIR_NATIVE} \
-DFETCHCONTENT_SOURCE_DIR_TENSORFLOW=${WORKDIR}/tfgit \
-DTFLITE_LIB_LOC=${STAGING_DIR_HOST}${libdir}/libtensorflow-lite.so \
${S} \
"
CXXFLAGS += "-fPIC"
do_configure[network] = "1"
do_configure:prepend() {
export HTTP_PROXY=${http_proxy}
export HTTPS_PROXY=${https_proxy}
export http_proxy=${http_proxy}
export https_proxy=${https_proxy}
# There is no Fortran compiler in the toolchain, but bitbake sets this variable anyway
# with unavailable binary.
export FC=""
}
do_install() {
# install libraries
install -d ${D}${libdir}
for lib in ${B}/lib*.so*
do
cp --no-preserve=ownership -d $lib ${D}${libdir}
done
}
INHIBIT_PACKAGE_DEBUG_SPLIT = "1"
# Output library is unversioned
SOLIBS = ".so"
FILES_SOLIBSDEV = ""
# Work around do_package_qa error
INSANE_SKIP:${PN} += "buildpaths rpaths"
COMPATIBLE_MACHINE = "(mx943-nxp-bsp|mx95-nxp-bsp)"

View File

@ -0,0 +1,150 @@
# Copyright 2020-2025 NXP
DESCRIPTION = "TensorFlow Lite C++ Library"
LICENSE = "Apache-2.0"
LIC_FILES_CHKSUM = "file://LICENSE;md5=4158a261ca7f2525513e31ba9c50ae98"
DEPENDS = "flatbuffers python3-numpy-native python3-pip-native python3-pybind11-native python3-wheel-native unzip-native \
python3 jpeg zlib ${BPN}-host-tools-native"
require tensorflow-lite-${PV}.inc
SRC_URI = "${TENSORFLOW_LITE_SRC};branch=${SRCBRANCH_tf};name=tf"
SRC_URI += "https://storage.googleapis.com/download.tensorflow.org/models/mobilenet_v1_2018_08_02/mobilenet_v1_1.0_224_quant.tgz;name=model-mobv1"
SRC_URI[model-mobv1.sha256sum] = "d32432d28673a936b2d6281ab0600c71cf7226dfe4cdcef3012555f691744166"
S = "${WORKDIR}/git"
inherit python3native cmake
PACKAGECONFIG ??= "python-example ${PACKAGECONFIG_GPU_DELEGATE}"
PACKAGECONFIG_GPU_DELEGATE = ""
PACKAGECONFIG_GPU_DELEGATE:mx95-nxp-bsp = "gpu-delegate"
PACKAGECONFIG[gpu-delegate] = "-DTFLITE_ENABLE_GPU=on,-DTFLITE_ENABLE_GPU=off"
PACKAGECONFIG[python-example] = ",,,python3-pillow"
EXTRA_OECMAKE = " \
-DCMAKE_SYSROOT=${PKG_CONFIG_SYSROOT_DIR} \
-DFETCHCONTENT_FULLY_DISCONNECTED=OFF \
-DTFLITE_EVAL_TOOLS=on \
-DTFLITE_HOST_TOOLS_DIR=${STAGING_BINDIR_NATIVE} \
-DTFLITE_BUILD_SHARED_LIB=on \
-DTFLITE_ENABLE_NNAPI=off \
-DTFLITE_ENABLE_NNAPI_VERBOSE_VALIDATION=on \
-DTFLITE_ENABLE_RUY=on \
-DTFLITE_ENABLE_XNNPACK=on \
-DTFLITE_PYTHON_WRAPPER_BUILD_CMAKE2=on \
-DTFLITE_ENABLE_EXTERNAL_DELEGATE=on \
${S}/tensorflow/lite/ \
"
EXTRA_OECMAKE_BUILD = "benchmark_model label_image"
CXXFLAGS += "-fPIC"
do_configure[network] = "1"
do_configure:prepend() {
export HTTP_PROXY=${http_proxy}
export HTTPS_PROXY=${https_proxy}
export http_proxy=${http_proxy}
export https_proxy=${https_proxy}
# There is no Fortran compiler in the toolchain, but bitbake sets this variable anyway
# with unavailable binary.
export FC=""
}
do_compile:append () {
# build pip package
cd ${B}
CI_BUILD_PYTHON=${PYTHON} BUILD_NUM_JOBS=8 ${S}/tensorflow/lite/tools/pip_package/build_pip_package_with_cmake2.sh ${TARGET_ARCH}
}
do_install() {
# install libraries
install -d ${D}${libdir}
for lib in ${B}/lib*.so*
do
cp --no-preserve=ownership -d $lib ${D}${libdir}
done
# install header files
install -d ${D}${includedir}/tensorflow/lite
cd ${S}/tensorflow/lite
cp --parents \
$(find . -name "*.h*") \
${D}${includedir}/tensorflow/lite
install -d ${D}${includedir}/tensorflow/compiler/mlir/lite
cd ${S}/tensorflow/compiler/mlir/lite
cp --parents \
$(find . -name "*.h*") \
${D}${includedir}/tensorflow/compiler/mlir/lite
# install version.h from core
install -d ${D}${includedir}/tensorflow/core/public
cp ${S}/tensorflow/core/public/version.h ${D}${includedir}/tensorflow/core/public
# install ctstring_internal.h from core
install -d ${D}${includedir}/tensorflow/core/platform
cp ${S}/tensorflow/core/platform/ctstring_internal.h ${D}${includedir}/tensorflow/core/platform
# install ctstring_internal.h from tsl
install -d ${D}${includedir}/tsl/platform
cp ${S}/third_party/xla/third_party/tsl/tsl/platform/ctstring_internal.h ${D}${includedir}/tsl/platform
# install examples
install -d ${D}${bindir}/${PN}-${PV}/examples
install -m 0555 ${B}/examples/label_image/label_image ${D}${bindir}/${PN}-${PV}/examples
install -m 0555 ${B}/tools/benchmark/benchmark_model ${D}${bindir}/${PN}-${PV}/examples
install -m 0555 ${B}/tools/evaluation/coco_object_detection_run_eval ${D}${bindir}/${PN}-${PV}/examples
install -m 0555 ${B}/tools/evaluation/imagenet_image_classification_run_eval ${D}${bindir}/${PN}-${PV}/examples
install -m 0555 ${B}/tools/evaluation/inference_diff_run_eval ${D}${bindir}/${PN}-${PV}/examples
# install label_image data
cp ${S}/tensorflow/lite/examples/label_image/testdata/grace_hopper.bmp ${D}${bindir}/${PN}-${PV}/examples
cp ${S}/tensorflow/lite/java/ovic/src/testdata/labels.txt ${D}${bindir}/${PN}-${PV}/examples
# Install python example
if ${@bb.utils.contains('PACKAGECONFIG', 'python-example', 'true', 'false', d)}; then
cp ${S}/tensorflow/lite/examples/python/label_image.py ${D}${bindir}/${PN}-${PV}/examples
fi
# Install mobilenet tflite file
cp ${WORKDIR}/mobilenet_*.tflite ${D}${bindir}/${PN}-${PV}/examples
# Install pip package
install -d ${D}/${PYTHON_SITEPACKAGES_DIR}
${STAGING_BINDIR_NATIVE}/pip3 install --disable-pip-version-check -vvv --platform linux_${TARGET_ARCH} \
-t ${D}/${PYTHON_SITEPACKAGES_DIR} --no-cache-dir --no-deps \
${B}/tflite_pip/dist/tflite_runtime-*.whl
}
PACKAGE_ARCH = "${MACHINE_SOCARCH}"
RDEPENDS:${PN} = " \
python3 \
python3-numpy \
${RDEPENDS_OPENCL} \
"
RDEPENDS_OPENCL = "opencl-icd-loader-dev"
RDEPENDS_OPENCL:mx8mm-nxp-bsp = ""
INSANE_SKIP:${PN} += "dev-deps"
# TensorFlow and TensorFlow Lite both exports few files, suppress the error
# SSTATE_ALLOW_OVERLAP_FILES = "${D}${includedir}"
SSTATE_ALLOW_OVERLAP_FILES = "/"
INHIBIT_PACKAGE_DEBUG_SPLIT = "1"
INSANE_SKIP:${PN} += " \
already-stripped \
staticdev \
buildpaths \
"
FILES:${PN} += "${libdir}/python*"

View File

@ -0,0 +1,26 @@
SUMMARY = "NNStreamer-Edge library"
DESCRIPTION = "Remote source nodes for NNStreamer pipelines without GStreamer dependencies"
LICENSE = "Apache-2.0"
LIC_FILES_CHKSUM = "file://LICENSE;md5=095e13fef457e259d3bc155d0ed859f1"
DEPENDS = "\
gtest \
"
NNS_EDGE_SRC ?= "git://github.com/nnstreamer/nnstreamer-edge.git;protocol=https"
SRCBRANCH = "prod/tizen-9.0"
SRCREV = "e73acb740dce3ecbf8a650f45fab790afb400a95"
SRC_URI = "${NNS_EDGE_SRC};branch=${SRCBRANCH}"
S = "${WORKDIR}/git"
inherit cmake pkgconfig
EXTRA_OECMAKE = " \
-DENABLE_TEST=ON \
"
# The build produces a mix of versioned and unversioned libs, so custom packaging is required
FILES_SOLIBSDEV:remove = "${libdir}/lib*${SOLIBSDEV}"
FILES:${PN} += "${libdir}/libnnstreamer-edge-custom-test${SOLIBSDEV}"
FILES:${PN}-dev += "${libdir}/libnnstreamer-edge${SOLIBSDEV}"

View File

@ -0,0 +1,63 @@
From fd05c3f40c9ae1bdf2e05fc3581a00ec967fb9e3 Mon Sep 17 00:00:00 2001
From: Nicolas Goueslain <nicolas.goueslain@nxp.com>
Date: Wed, 23 Jul 2025 12:28:07 +0000
Subject: [PATCH] AIR-11938: tensor-filter-use-memcpy-ethosu-delegate
Upstream-Status: Inappropriate [i.MX specific]
Signed-off-by: Nicolas Goueslain <nicolas.goueslain@nxp.com>
---
.../tensor_filter/tensor_filter_tensorflow_lite.cc | 9 +++++++--
1 file changed, 7 insertions(+), 2 deletions(-)
diff --git a/ext/nnstreamer/tensor_filter/tensor_filter_tensorflow_lite.cc b/ext/nnstreamer/tensor_filter/tensor_filter_tensorflow_lite.cc
index 95ab68c6..86879932 100644
--- a/ext/nnstreamer/tensor_filter/tensor_filter_tensorflow_lite.cc
+++ b/ext/nnstreamer/tensor_filter/tensor_filter_tensorflow_lite.cc
@@ -244,6 +244,7 @@ class TFLiteInterpreter
char *model_path;
bool is_cached_after_first_invoke; /**< To cache again after first invoke */
bool is_xnnpack_delegated; /**< To check if XNNPACK delegate is used */
+ bool is_ethosu_delegated;
char *ext_delegate_path; /**< path to external delegate lib */
GHashTable *ext_delegate_kv_table; /**< external delegate key values options */
QNNBackendType qnn_backend_type; /**< QNN Delegate backend type */
@@ -332,6 +333,7 @@ TFLiteInterpreter::TFLiteInterpreter ()
is_cached_after_first_invoke = false;
is_xnnpack_delegated = false;
+ is_ethosu_delegated = false;
}
/**
@@ -366,7 +368,7 @@ TFLiteInterpreter::invoke (const GstTensorMemory *input, GstTensorMemory *output
* Therefore tensor data is to be manually copied from/to input/output
* GStreamer buffers memory whose address changes at every round.
*/
- if (is_xnnpack_delegated) {
+ if (is_xnnpack_delegated || is_ethosu_delegated) {
for (unsigned int i = 0; i < inputTensorMeta.num_tensors; ++i) {
tensor_ptr = inputTensorPtr[i];
g_assert (tensor_ptr->bytes == input[i].size);
@@ -395,7 +397,7 @@ TFLiteInterpreter::invoke (const GstTensorMemory *input, GstTensorMemory *output
* After the very first invoke, the output buffer address may change.
* To handle the case, memcpy the output buffer directly.
*/
- if (is_xnnpack_delegated || !is_cached_after_first_invoke) {
+ if (is_xnnpack_delegated || is_ethosu_delegated || !is_cached_after_first_invoke) {
for (unsigned int i = 0; i < outputTensorMeta.num_tensors; ++i) {
tensor_ptr = outputTensorPtr[i];
g_assert (tensor_ptr->bytes == output[i].size);
@@ -555,6 +557,9 @@ TFLiteInterpreter::loadModel (int num_threads, tflite_delegate_e delegate_e)
options = TfLiteExternalDelegateOptionsDefault (ext_delegate_path);
+ if (strcmp(ext_delegate_path, "libethosu_delegate.so") == 0){
+ is_ethosu_delegated = true;
+ }
/* Add optional key values to delegate configuration */
if (ext_delegate_kv_table) {
GHashTable *table = ext_delegate_kv_table;
--
2.34.1

View File

@ -0,0 +1,33 @@
From 68ed0ca853338c9436d5047777f3f395c0f2c5b2 Mon Sep 17 00:00:00 2001
From: Nolann Chobert <nolann.chobert@nxp.com>
Date: Mon, 28 Jul 2025 16:00:19 +0000
Subject: [PATCH] Fix libnnstreamer_customfilter_passthrough.so path
Custom filter path is set to Yocto build path which will trigger an error on target.
The appropriate path is /usr/lib/nnstreamer/customfilters/libnnstreamer_customfilter_passthrough.so.
Upstream-Status: Inappropriate [i.MX specific]
Signed-off-by: Nolann Chobert <nolann.chobert@nxp.com>
---
tests/nnstreamer_filter_extensions_common/meson.build | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/tests/nnstreamer_filter_extensions_common/meson.build b/tests/nnstreamer_filter_extensions_common/meson.build
index ecd1878b..eba2cc83 100644
--- a/tests/nnstreamer_filter_extensions_common/meson.build
+++ b/tests/nnstreamer_filter_extensions_common/meson.build
@@ -9,7 +9,9 @@ tizen_apptest_deps = [
# Format for adding subplugin into extensions -
# [name, extension abbreviation, dependencies, model file name/folder path/file path, test name]
extensions = []
-custom_filter_path = join_paths(meson.build_root(), 'tests', 'nnstreamer_example',
+nnst_prefix = get_option('prefix')
+nnst_libdir = join_paths(nnst_prefix, get_option('libdir'))
+custom_filter_path = join_paths(nnst_libdir, 'nnstreamer', 'customfilters',
'libnnstreamer_customfilter_passthrough.' + so_ext)
extensions += [['custom', 'custom', nnstreamer_unittest_deps, custom_filter_path, 'custom']]
extensions += [['custom', 'custom', nnstreamer_unittest_deps, custom_filter_path, 'custom-set']]
--
2.34.1

View File

@ -0,0 +1,125 @@
From e7585fe374349fb6e022c7515271a2ca475015b2 Mon Sep 17 00:00:00 2001
From: Nolann Chobert <nolann.chobert@nxp.com>
Date: Thu, 16 Oct 2025 17:39:33 +0200
Subject: [PATCH] [Filter/TFLite] Fix to provide default delegates
Some external delegates might need to access default delegates such as
XNNPACK to accelerate unsupported operations.
Upstream-Status: Pending
Signed-off-by: Nolann Chobert <nolann.chobert@nxp.com>
---
.../tensor_filter_tensorflow_lite.cc | 41 ++++++++++++-------
1 file changed, 26 insertions(+), 15 deletions(-)
diff --git a/ext/nnstreamer/tensor_filter/tensor_filter_tensorflow_lite.cc b/ext/nnstreamer/tensor_filter/tensor_filter_tensorflow_lite.cc
index 95ab68c6..d293e78c 100644
--- a/ext/nnstreamer/tensor_filter/tensor_filter_tensorflow_lite.cc
+++ b/ext/nnstreamer/tensor_filter/tensor_filter_tensorflow_lite.cc
@@ -98,13 +98,6 @@
#define TFLITE_SUBPLUGIN_NAME "tensorflow-lite"
#endif
-/**
- * @brief prevent usage by TFLite of default delegates that may not be supported
- */
-#if TFLITE_VERSION_MAJOR >= 2 && TFLITE_VERSION_MINOR >= 4
-#define TFLITE_RESOLVER_WITHOUT_DEFAULT_DELEGATES
-#endif
-
/**
* @brief Macro for debug mode.
*/
@@ -157,6 +150,7 @@ typedef struct {
GHashTable *ext_delegate_kv_table; /**< external delegate key values options */
QNNBackendType qnn_backend_type; /**< QNN Delegate backend type */
QNNPerformanceMode qnn_performance_mode; /**< QNN Delegate performance mode */
+ bool use_default_delegates; /**< whether to use default delegates in resolver */
} tflite_option_s;
/**
@@ -197,6 +191,10 @@ class TFLiteInterpreter
void setModelPath (const char *model_path);
void setExtDelegate (const char *lib_path, GHashTable *key_val);
void getExtDelegate (const char **lib_path, GHashTable **key_val);
+ void setUseDefaultDelegates (gboolean use_default)
+ {
+ use_default_delegates = use_default;
+ }
/** @brief get current model path */
const char *getModelPath ()
{
@@ -248,6 +246,7 @@ class TFLiteInterpreter
GHashTable *ext_delegate_kv_table; /**< external delegate key values options */
QNNBackendType qnn_backend_type; /**< QNN Delegate backend type */
QNNPerformanceMode qnn_performance_mode; /**< QNN Delegate performance mode */
+ bool use_default_delegates; /**< whether to use default delegates in resolver */
std::unique_ptr<tflite::Interpreter> interpreter;
std::unique_ptr<tflite::FlatBufferModel> model;
@@ -324,6 +323,7 @@ TFLiteInterpreter::TFLiteInterpreter ()
ext_delegate_kv_table = nullptr;
qnn_backend_type = QNN_BACKEND_UNDEFINED;
qnn_performance_mode = QNN_PERFMODE_Default;
+ use_default_delegates = FALSE;
g_mutex_init (&mutex);
@@ -460,12 +460,14 @@ TFLiteInterpreter::loadModel (int num_threads, tflite_delegate_e delegate_e)
interpreter = nullptr;
-#ifdef TFLITE_RESOLVER_WITHOUT_DEFAULT_DELEGATES
- tflite::ops::builtin::BuiltinOpResolverWithoutDefaultDelegates resolver;
-#else
- tflite::ops::builtin::BuiltinOpResolver resolver;
-#endif
- tflite::InterpreterBuilder (*model, resolver) (&interpreter);
+ if (use_default_delegates) {
+ tflite::ops::builtin::BuiltinOpResolver resolver;
+ tflite::InterpreterBuilder (*model, resolver) (&interpreter);
+ } else {
+ tflite::ops::builtin::BuiltinOpResolverWithoutDefaultDelegates resolver;
+ tflite::InterpreterBuilder (*model, resolver) (&interpreter);
+ }
+
if (!interpreter) {
ml_loge ("Failed to construct interpreter\n");
return -2;
@@ -1075,6 +1077,7 @@ TFLiteCore::init (tflite_option_s *option)
{
interpreter->setModelPath (option->model_file);
interpreter->setExtDelegate (option->ext_delegate_path, option->ext_delegate_kv_table);
+ interpreter->setUseDefaultDelegates (option->use_default_delegates);
interpreter->qnn_backend_type = option->qnn_backend_type;
interpreter->qnn_performance_mode = option->qnn_performance_mode;
num_threads = option->num_threads;
@@ -1395,6 +1398,13 @@ tflite_parseCustomOption (const GstTensorFilterProperties *prop, tflite_option_s
if (g_ascii_strcasecmp (pair[0], "NumThreads") == 0) {
option->num_threads = (int) g_ascii_strtoll (pair[1], NULL, 10);
+ } else if (g_ascii_strcasecmp (pair[0], "UseDefaultDelegates") == 0) {
+ if (g_ascii_strcasecmp (pair[1], "true") == 0 || g_ascii_strcasecmp (pair[1], "1") == 0)
+ option->use_default_delegates = TRUE;
+ else if (g_ascii_strcasecmp (pair[1], "false") == 0 || g_ascii_strcasecmp (pair[1], "0") == 0)
+ option->use_default_delegates = FALSE;
+ else
+ ml_logw ("Invalid value for UseDefaultDelegates (%s). Use 'true' or 'false'.", pair[1]);
} else if (g_ascii_strcasecmp (pair[0], "Delegate") == 0) {
if (g_ascii_strcasecmp (pair[1], "NNAPI") == 0)
option->delegate = TFLITE_DELEGATE_NNAPI;
@@ -1777,8 +1787,9 @@ _nns_filter_register_tflite (void)
{
nnstreamer_filter_probe (&NNS_support_tensorflow_lite);
nnstreamer_filter_set_custom_property_desc (NNS_support_tensorflow_lite.v0.name,
- "NumThreads", "Number of threads. Set 0 for default behaviors.", "Delegate",
- "TF-Lite delegation options: {'NNAPI', 'GPU', 'XNNPACK', 'External', 'QNN'}."
+ "NumThreads", "Number of threads. Set 0 for default behaviors.",
+ "UseDefaultDelegates", "Whether to use default delegates in resolver. Set 'true' or 'false'. Default is 'false'.",
+ "Delegate", "TF-Lite delegation options: {'NNAPI', 'GPU', 'XNNPACK', 'External', 'QNN'}."
" Do not specify to disable delegation.",
"ExtDelegateLib", "Path to external delegate shared library", "ExtDelegateKeyVal",
"key/values pairs optional parameters for delegate."
--
2.34.1

View File

@ -0,0 +1,179 @@
From 686e0ece0aef4f1d4bb24c893106f8d595016a30 Mon Sep 17 00:00:00 2001
From: Alexandru Firuti <alexandru.firuti@nxp.com>
Date: Tue, 18 Nov 2025 13:54:15 +0000
Subject: [PATCH] tensor_converter: add frame padding removal for GRAY8
- gst_tensor_converter_parse_video: add a new function for checking i.MX-specific
padding (gst_tensor_converter_video_stride_imx); if detected, set self->remove_imx_padding flag
- gst_tensor_converter_chain: for video media type, remove the paddding when either of
self->remove_padding and self->remove_imx_padding flags are set; in case there is no metadata
attached to padding, ignore the i.MX padding removal as the buffer is not coming from i.MX plugins;
add also logic to skip frame padding if it exists
Upstream-Status: Inappropriate [i.MX specific]
Signed-off-by: Alexandru Firuti <alexandru.firuti@nxp.com>
---
gst/nnstreamer/elements/gsttensor_converter.c | 50 ++++++++++++++++++-
gst/nnstreamer/elements/gsttensor_converter.h | 1 +
2 files changed, 49 insertions(+), 2 deletions(-)
diff --git a/gst/nnstreamer/elements/gsttensor_converter.c b/gst/nnstreamer/elements/gsttensor_converter.c
index 78f62247..b7a28a36 100644
--- a/gst/nnstreamer/elements/gsttensor_converter.c
+++ b/gst/nnstreamer/elements/gsttensor_converter.c
@@ -359,6 +359,7 @@ gst_tensor_converter_init (GstTensorConverter * self)
self->in_media_type = _NNS_MEDIA_INVALID;
self->frame_size = 0;
self->remove_padding = FALSE;
+ self->remove_imx_padding = FALSE;
self->externalConverter = NULL;
self->priv_data = NULL;
self->mode = _CONVERTER_MODE_NONE;
@@ -1032,7 +1033,7 @@ gst_tensor_converter_chain (GstPad * pad, GstObject * parent, GstBuffer * buf)
GstTensorsConfig new_config;
GstTensorInfo *_info;
GstBuffer *inbuf;
- gsize buf_size, frame_size;
+ gsize buf_size, frame_size, frame_padding;
guint frames_in, frames_out;
UNUSED (pad);
@@ -1073,7 +1074,7 @@ gst_tensor_converter_chain (GstPad * pad, GstObject * parent, GstBuffer * buf)
/** supposed 1 frame in buffer */
g_assert ((buf_size / self->frame_size) == 1);
- if (self->remove_padding) {
+ if (self->remove_padding || self->remove_imx_padding) {
GstMapInfo src_info, dest_info;
guint d0, d1;
unsigned int src_idx = 0, dest_idx = 0;
@@ -1104,6 +1105,13 @@ gst_tensor_converter_chain (GstPad * pad, GstObject * parent, GstBuffer * buf)
GstVideoMeta *video_meta = gst_buffer_get_video_meta (buf);
if (video_meta) {
offset = video_meta->stride[0];
+ } else if (self->remove_imx_padding && !self->remove_padding) {
+ /**
+ * If GstVideoMeta is missing, the buffer comes from a generic GStreamer plugin.
+ * Only the default 4-bytes alignment correction should be done, the i.MX specific
+ * one should be skipped.
+ */
+ break;
} else {
g_assert (offset % 4); /** Internal logic error! */
if (offset % 4) {
@@ -1111,12 +1119,22 @@ gst_tensor_converter_chain (GstPad * pad, GstObject * parent, GstBuffer * buf)
}
}
+ /* Calculate frame padding (padding at the end of entire frame) */
+ frame_padding = 0;
+ if (buf_size > frame_size) {
+ frame_padding = buf_size - frame_size;
+ }
+
for (d0 = 0; d0 < frames_in; d0++) {
for (d1 = 0; d1 < height; d1++) {
memcpy (dest_info.data + dest_idx, src_info.data + src_idx, size);
dest_idx += size;
src_idx += offset;
}
+ /* Skip frame padding if it exists (after all rows of current frame) */
+ if (frame_padding > 0 && d0 < (frames_in - 1)) {
+ src_idx += frame_padding;
+ }
}
gst_buffer_unmap (buf, &src_info);
@@ -1438,6 +1456,26 @@ gst_tensor_converter_video_stride (GstVideoFormat format, gint width)
return FALSE;
}
+/**
+ * @brief Determine if we need i.MX-specific zero-padding
+ * @return TRUE if we need to add (or remove) stride per row from the stream data.
+ */
+static gboolean
+gst_tensor_converter_video_stride_imx (GstVideoFormat format, gint width, gint height, gsize frame_size)
+{
+ switch (format) {
+ case GST_VIDEO_FORMAT_GRAY8:
+ if ((width % 16) || (height % 16) || (frame_size % 4096)) {
+ return TRUE;
+ }
+ break;
+ default:
+ break;
+ }
+
+ return FALSE;
+}
+
/**
* @brief Set the tensors config structure from video info (internal static function)
* @param self this pointer to GstTensorConverter
@@ -1459,6 +1497,7 @@ gst_tensor_converter_parse_video (GstTensorConverter * self,
GstVideoFormat format;
gint width, height, views;
guint i;
+ gsize size = 0; // Frame size
g_return_val_if_fail (config != NULL, FALSE);
@@ -1494,6 +1533,7 @@ gst_tensor_converter_parse_video (GstTensorConverter * self,
config->info.info[0].dimension[0] = 1;
config->info.info[0].dimension[1] = width;
config->info.info[0].dimension[2] = height;
+ size = 1 * width * height; // 1 byte per pixel
break;
case GST_VIDEO_FORMAT_GRAY16_BE:
case GST_VIDEO_FORMAT_GRAY16_LE:
@@ -1501,6 +1541,7 @@ gst_tensor_converter_parse_video (GstTensorConverter * self,
config->info.info[0].dimension[0] = 1;
config->info.info[0].dimension[1] = width;
config->info.info[0].dimension[2] = height;
+ size = 2 * 1 * width * height; // 2 bytes per pixel
break;
case GST_VIDEO_FORMAT_RGB:
case GST_VIDEO_FORMAT_BGR:
@@ -1508,6 +1549,7 @@ gst_tensor_converter_parse_video (GstTensorConverter * self,
config->info.info[0].dimension[0] = 3;
config->info.info[0].dimension[1] = width;
config->info.info[0].dimension[2] = height;
+ size = 1 * 3 * width * height; // 1 byte per channel, 3 channels
break;
case GST_VIDEO_FORMAT_RGBx:
case GST_VIDEO_FORMAT_BGRx:
@@ -1521,6 +1563,7 @@ gst_tensor_converter_parse_video (GstTensorConverter * self,
config->info.info[0].dimension[0] = 4;
config->info.info[0].dimension[1] = width;
config->info.info[0].dimension[2] = height;
+ size = 1 * 4 * width * height; // 1 byte per channel, 4 channels
break;
#if GST_CHECK_VERSION(1, 20, 0)
case GST_VIDEO_FORMAT_RGBP:
@@ -1571,6 +1614,9 @@ gst_tensor_converter_parse_video (GstTensorConverter * self,
"Please use 4 x n as image width for inputs; the width of your input is %d.\n",
width);
}
+ if (gst_tensor_converter_video_stride_imx (format, width, height, size)) {
+ self->remove_imx_padding = TRUE;
+ }
self->frame_size = GST_VIDEO_INFO_SIZE (&vinfo);
return (config->info.info[0].type != _NNS_END);
diff --git a/gst/nnstreamer/elements/gsttensor_converter.h b/gst/nnstreamer/elements/gsttensor_converter.h
index b1328bb6..75589540 100644
--- a/gst/nnstreamer/elements/gsttensor_converter.h
+++ b/gst/nnstreamer/elements/gsttensor_converter.h
@@ -92,6 +92,7 @@ struct _GstTensorConverter
gsize frame_size; /**< size of one frame */
gboolean remove_padding; /**< If true, zero-padding must be removed */
+ gboolean remove_imx_padding; /**< If true, i.MX-specific zero-padding must be removed */
gboolean tensors_configured; /**< True if already successfully configured tensors metadata */
GstTensorsConfig tensors_config; /**< output tensors info */
--
2.34.1

View File

@ -0,0 +1,45 @@
From ccf4eea69e320d23013e5ec526d8b4f52a89192c Mon Sep 17 00:00:00 2001
From: Elliot Chen <elliot.chen@nxp.com>
Date: Wed, 23 Jul 2025 12:55:32 +0000
Subject: [PATCH] tensor_converter: calculate the offset by video meta when
removing padding
Changes for imxvideoconvert_g2d RGB888 support introduced 4-bytes alignment [MMFMWK-9523].
Padding is used for dimensions that are not multiple of 4.
NNStreamer tensor_converter padding removal is done using a padding size calculated on the 4-bytes alignment of width value in bytes.
The attached patch fixes the mismatch by adjusting the offset used for padding removal in NNStreamer to the actual stride value coming in video meta from the GStreamer plugins.
Upstream-Status: Inappropriate [i.MX specific]
Signed-off-by: Elliot Chen <elliot.chen@nxp.com>
Signed-off-by: Nicolas Goueslain <nicolas.goueslain@nxp.com>
---
gst/nnstreamer/elements/gsttensor_converter.c | 12 +++++++++---
1 file changed, 9 insertions(+), 3 deletions(-)
diff --git a/gst/nnstreamer/elements/gsttensor_converter.c b/gst/nnstreamer/elements/gsttensor_converter.c
index c03fe87e..78f62247 100644
--- a/gst/nnstreamer/elements/gsttensor_converter.c
+++ b/gst/nnstreamer/elements/gsttensor_converter.c
@@ -1100,9 +1100,15 @@ gst_tensor_converter_chain (GstPad * pad, GstObject * parent, GstBuffer * buf)
*/
size = offset = type * color * width;
- g_assert (offset % 4); /** Internal logic error! */
- if (offset % 4) {
- offset += 4 - (offset % 4);
+ /* Calculate the offset by video meta if is exist */
+ GstVideoMeta *video_meta = gst_buffer_get_video_meta (buf);
+ if (video_meta) {
+ offset = video_meta->stride[0];
+ } else {
+ g_assert (offset % 4); /** Internal logic error! */
+ if (offset % 4) {
+ offset += 4 - (offset % 4);
+ }
}
for (d0 = 0; d0 < frames_in; d0++) {
--
2.34.1

View File

@ -0,0 +1,224 @@
SUMMARY = "NNStreamer, Stream Pipeline Paradigm for Neural Network Applications"
DESCRIPTION = "NNStreamer is a GStreamer plugin allowing to construct neural network applications with stream pipeline paradigm."
SECTION = "AI"
LICENSE = "LGPL-2.0-or-later"
LIC_FILES_CHKSUM = "\
file://LICENSE;md5=c25e5c1949624d71896127788f1ba590 \
file://debian/copyright;md5=0462ef8fa89a1f53f2e65e74940519ef \
"
DEPENDS = "\
bison-native \
flex-native \
orc-native \
glib-2.0 \
gstreamer1.0 \
gstreamer1.0-plugins-base \
gtest \
libpng \
"
SRCREV = "9cf11e0768892636622480fe1b5fc042b5a224ad"
SRC_URI = "git://github.com/nnstreamer/nnstreamer.git;branch=prod/tizen-9.0;protocol=https \
file://0001-AIR-11938-tensor-filter-use-memcpy-ethosu-delegate.patch \
file://0001-rgb888_support_nnstreamer.patch \
file://0001-Fix-libnnstreamer_customfilter_passthrough.so-path.patch \
file://0001-gray8_padding_removal.patch \
file://0001-Fix-to-provide-default-delegates.patch \
"
# Use git instead of quilt as patch tool to support patches with binary content
PATCHTOOL = "git"
S = "${WORKDIR}/git"
inherit meson pkgconfig
PACKAGECONFIG ??= "protobuf python3 query ${PACKAGECONFIG_SOC}"
PACKAGECONFIG_SOC ??= ""
PACKAGECONFIG_SOC:mx8-nxp-bsp:imxgpu ??= "tensorflow-lite"
PACKAGECONFIG_SOC:mx8mp-nxp-bsp ??= "tensorflow-lite tvm"
PACKAGECONFIG_SOC:mx9-nxp-bsp ??= "tensorflow-lite"
PACKAGECONFIG[flatbuf] = "\
-Dflatbuf-support=enabled, \
-Dflatbuf-support=disabled, \
flatbuffers-native flatbuffers, \
,,\
"
PACKAGECONFIG[grpc] = "\
-Dgrpc-support=enabled, \
-Dgrpc-support=disabled, \
grpc-native grpc, \
,,\
"
PACKAGECONFIG[protobuf] = "\
-Dprotobuf-support=enabled, \
-Dprotobuf-support=disabled, \
protobuf-native protobuf, \
,,\
"
PACKAGECONFIG[python3] = "\
-Dpython3-support=enabled, \
-Dpython3-support=disabled, \
python3 python3-numpy-native, \
,,\
"
PACKAGECONFIG[query] = "\
-Dnnstreamer-edge-support=enabled, \
-Dnnstreamer-edge-support=disabled, \
nnstreamer-edge, \
,,\
"
PACKAGECONFIG[tensorflow-lite] = "\
-Dtflite2-support=enabled, \
-Dtflite2-support=disabled, \
tensorflow-lite flatbuffers, \
,,\
"
PACKAGECONFIG[tvm] = "\
-Dtvm-support=enabled, \
-Dtvm-support=disabled, \
tvm, \
,,\
"
EXTRA_OEMESON += "\
-Denable-float16=true \
-Denable-test=true \
-Dinstall-test=true \
"
# FIXME: Remove this when the source warnings are fixed
CFLAGS += "-Wno-error"
do_install:append() {
rm -f ${D}/${bindir}/unittest-nnstreamer/tests/test_models/models/tvm_add_one.so_
}
PACKAGES =+ "\
${PN}-unittest \
${@bb.utils.contains('PACKAGECONFIG', 'flatbuf','${PN}-flatbuf', '', d)} \
${@bb.utils.contains('PACKAGECONFIG', 'flatbuf grpc','${PN}-grpc-flatbuf', '', d)} \
${@bb.utils.contains('PACKAGECONFIG', 'grpc','${PN}-grpc', '', d)} \
${@bb.utils.contains('PACKAGECONFIG', 'protobuf','${PN}-protobuf', '', d)} \
${@bb.utils.contains('PACKAGECONFIG', 'protobuf grpc','${PN}-grpc-protobuf', '', d)} \
${@bb.utils.contains('PACKAGECONFIG', 'python3','${PN}-python3', '', d)} \
${@bb.utils.contains('PACKAGECONFIG', 'query','${PN}-query', '', d)} \
${@bb.utils.contains('PACKAGECONFIG', 'tensorflow-lite','${PN}-tensorflow-lite', '', d)} \
${@bb.utils.contains('PACKAGECONFIG', 'tvm','${PN}-tvm', '', d)} \
"
RDEPENDS:${PN} = "\
gstreamer1.0-plugins-base \
"
RDEPENDS:${PN}-unittest = "gstreamer1.0-plugins-good nnstreamer ssat \
${@bb.utils.contains('PACKAGECONFIG', 'flatbuf','${PN}-flatbuf', '', d)} \
${@bb.utils.contains('PACKAGECONFIG', 'flatbuf grpc','${PN}-grpc-flatbuf', '', d)} \
${@bb.utils.contains('PACKAGECONFIG', 'grpc','${PN}-grpc', '', d)} \
${@bb.utils.contains('PACKAGECONFIG', 'protobuf','${PN}-protobuf', '', d)} \
${@bb.utils.contains('PACKAGECONFIG', 'protobuf grpc','${PN}-grpc-protobuf', '', d)} \
${@bb.utils.contains('PACKAGECONFIG', 'python3','${PN}-python3', '', d)} \
${@bb.utils.contains('PACKAGECONFIG', 'query','${PN}-query', '', d)} \
${@bb.utils.contains('PACKAGECONFIG', 'tensorflow-lite','${PN}-tensorflow-lite', '', d)} \
${@bb.utils.contains('PACKAGECONFIG', 'tvm','${PN}-tvm', '', d)} \
"
# The libraries are unversioned
SOLIBS = ".so"
FILES_SOLIBSDEV = ""
FILES:${PN} += "\
${libdir}/gstreamer-1.0/lib*${SOLIBS} \
"
FILES:${PN}-flatbuf = "\
${libdir}/nnstreamer/converters/libnnstreamer_converter_flatbuf.so \
${libdir}/nnstreamer/converters/libnnstreamer_converter_flexbuf.so \
${libdir}/nnstreamer/decoders/libnnstreamer_decoder_flatbuf.so \
${libdir}/nnstreamer/decoders/libnnstreamer_decoder_flexbuf.so \
"
FILES:${PN}-grpc = "\
${libdir}/gstreamer-1.0/libnnstreamer-grpc.so \
"
FILES:${PN}-grpc-flatbuf = "\
${libdir}/libnnstreamer_grpc_flatbuf.so \
"
FILES:${PN}-grpc-protobuf = "\
${libdir}/libnnstreamer_grpc_protobuf.so \
"
FILES:${PN}-protobuf = "\
${libdir}/nnstreamer/converters/libnnstreamer_converter_protobuf.so \
${libdir}/nnstreamer/decoders/libnnstreamer_decoder_protobuf.so \
${libdir}/libnnstreamer_protobuf.so \
"
FILES:${PN}-python3 = "\
${libdir}/nnstreamer/converters/libnnstreamer_converter_python3.so \
${libdir}/nnstreamer/decoders/libnnstreamer_decoder_python3.so \
${libdir}/nnstreamer/filters/libnnstreamer_filter_python3.so \
${libdir}/nnstreamer_python3.so \
${PYTHON_SITEPACKAGES_DIR}/nnstreamer_python.so \
"
FILES:${PN}-query = "\
${libdir}/gstreamer-1.0/libgstedge.so \
"
FILES:${PN}-tensorflow-lite = "\
${libdir}/nnstreamer/filters/libnnstreamer_filter_tensorflow2-lite.so \
"
FILES:${PN}-tvm = "\
${libdir}/nnstreamer/filters/libnnstreamer_filter_tvm.so \
"
FILES:${PN}-unittest = "\
${bindir}/unittest-nnstreamer/* \
${libdir}/libnnstreamer_unittest_util.so \
${libdir}/libcppfilter_test.so \
${libdir}/nnstreamer/customfilters/* \
${libdir}/nnstreamer/unittest/* \
"
# Libraries are unversioned, and the main package requires the symlink
# /usr/lib/libnnstreamer.so -> /usr/lib64/gstreamer-1.0/libnnstreamer.so,
# so disable QA dev-so
INSANE_SKIP:${PN} = "dev-so"
# The python3 package requires the symlink /usr/lib/python3.13/site-packages/nnstreamer_python.so,
# so disable QA dev-so
INSANE_SKIP:${PN}-python3 = "dev-so"
# The unittest package /usr/bin/unittest-nnstreamer/tests/libnnstreamer-edge-custom-test.so is correct,
# so silence the QA error
INSANE_SKIP:${PN}-unittest = "libdir"
# The dbg package requires /usr/bin/unittest-nnstreamer/tests/.debug/libnnstreamer-edge-custom-test.so,
# so silence the QA error
INSANE_SKIP:${PN}-dbg = "libdir"
do_install:append() {
# Fixes: 076a78ea [TVM/test] Add models for more architectures
bash -c "shopt -s extglob;
rm -f ${D}/${bindir}/unittest-nnstreamer/tests/test_models/models/tvm_add_one_!(${HOST_ARCH}).so_;
shopt -u extglob;"
# Check if python3 is enabled then install python module
if ${@bb.utils.contains('PACKAGECONFIG', 'python3', 'true', 'false', d)}; then
install -d ${D}${PYTHON_SITEPACKAGES_DIR}/
ln -sf ${libdir}/nnstreamer_python3.so ${D}${PYTHON_SITEPACKAGES_DIR}/nnstreamer_python.so
fi
}
PACKAGE_ARCH = "${MACHINE_SOCARCH}"