From 02d15235919f9047b934d49e8dc3a5b1a75a0643 Mon Sep 17 00:00:00 2001 From: Isaac Hermida Date: Thu, 11 Jan 2024 14:40:52 +0100 Subject: [PATCH] ccimx93: update ML/AI packages for NXP release 6.1.55-2.2.0 As part of the integration of the new ML package, also update the ethos-u-firmware binary built from Stash: Repo: emp/ethos_u_firmware.git Revision: bd5506ddba364ad04602d5009b77077f78450b97 Source: NXP's MCUXpresso SDK_2.14.2_MIMX9352xxxxM Co-authored-by: Javier Viguera Signed-off-by: Isaac Hermida Signed-off-by: Javier Viguera --- .../conf/machine/include/imx-digi-base.inc | 17 +- ...dparty-ippicv-Use-pre-downloaded-ipp.patch | 36 ++++ ...maller-version-of-download_models.py.patch | 179 ++++++++++++++++++ .../opencv/opencv/0001-Dont-use-isystem.patch | 28 +++ .../opencv/0001-Make-ts-module-external.patch | 42 ++++ ...-around-deprecated-ffmpeg-RAW-functi.patch | 31 +++ .../0003-To-fix-errors-as-following.patch | 70 +++++++ .../opencv/opencv/OpenCV_DNN_examples.patch | 141 ++++++++++++++ .../opencv/opencv/download.patch | 41 ++++ .../opencv/opencv_4.7.0.imx.bb | 23 +++ .../packagegroup/packagegroup-imx-ml.bbappend | 3 +- .../arm-compute-library_22.05.bbappend | 6 +- .../eiq-examples/eiq-examples_git.bb | 4 +- .../ethos-u-driver-stack_22.08.bbappend | 6 - .../ethos-u-driver-stack_23.08.bb | 11 ++ .../ethos-u-firmware/ccimx93/ethosu_firmware | Bin 242376 -> 242440 bytes .../ethos-u-firmware_22.08.bbappend | 17 -- .../ethos-u-firmware_23.08.bb | 21 ++ ...-u-vela_3.8.0.bb => ethos-u-vela_3.9.0.bb} | 4 +- .../modelrunner/modelrunner_2.3.0.bb | 44 ----- .../onnxruntime/onnxruntime-native_1.13.1.bb | 34 ---- ...untime_1.13.1.bb => onnxruntime_1.16.1.bb} | 23 +-- ...-2.11.1.inc => tensorflow-lite-2.12.1.inc} | 4 +- ...tensorflow-lite-ethosu-delegate_2.12.1.bb} | 4 +- ...b => tensorflow-lite-host-tools_2.12.1.bb} | 0 .../tensorflow-lite_2.%.bbappend | 12 -- ...te_2.11.1.bb => tensorflow-lite_2.12.1.bb} | 6 - 27 files changed, 649 insertions(+), 158 deletions(-) create mode 100644 meta-digi-arm/dynamic-layers/freescale-layer/recipes-support/opencv/opencv/0001-3rdparty-ippicv-Use-pre-downloaded-ipp.patch create mode 100644 meta-digi-arm/dynamic-layers/freescale-layer/recipes-support/opencv/opencv/0001-Add-smaller-version-of-download_models.py.patch create mode 100644 meta-digi-arm/dynamic-layers/freescale-layer/recipes-support/opencv/opencv/0001-Dont-use-isystem.patch create mode 100644 meta-digi-arm/dynamic-layers/freescale-layer/recipes-support/opencv/opencv/0001-Make-ts-module-external.patch create mode 100644 meta-digi-arm/dynamic-layers/freescale-layer/recipes-support/opencv/opencv/0001-Temporarliy-work-around-deprecated-ffmpeg-RAW-functi.patch create mode 100644 meta-digi-arm/dynamic-layers/freescale-layer/recipes-support/opencv/opencv/0003-To-fix-errors-as-following.patch create mode 100644 meta-digi-arm/dynamic-layers/freescale-layer/recipes-support/opencv/opencv/OpenCV_DNN_examples.patch create mode 100644 meta-digi-arm/dynamic-layers/freescale-layer/recipes-support/opencv/opencv/download.patch create mode 100644 meta-digi-arm/dynamic-layers/freescale-layer/recipes-support/opencv/opencv_4.7.0.imx.bb delete mode 100644 meta-digi-dey/dynamic-layers/meta-ml/recipes-libraries/ethos-u-driver-stack/ethos-u-driver-stack_22.08.bbappend create mode 100644 meta-digi-dey/dynamic-layers/meta-ml/recipes-libraries/ethos-u-driver-stack/ethos-u-driver-stack_23.08.bb delete mode 100644 meta-digi-dey/dynamic-layers/meta-ml/recipes-libraries/ethos-u-driver-stack/ethos-u-firmware_22.08.bbappend create mode 100644 meta-digi-dey/dynamic-layers/meta-ml/recipes-libraries/ethos-u-driver-stack/ethos-u-firmware_23.08.bb rename meta-digi-dey/dynamic-layers/meta-ml/recipes-libraries/ethos-u-vela/{ethos-u-vela_3.8.0.bb => ethos-u-vela_3.9.0.bb} (91%) delete mode 100644 meta-digi-dey/dynamic-layers/meta-ml/recipes-libraries/modelrunner/modelrunner_2.3.0.bb delete mode 100644 meta-digi-dey/dynamic-layers/meta-ml/recipes-libraries/onnxruntime/onnxruntime-native_1.13.1.bb rename meta-digi-dey/dynamic-layers/meta-ml/recipes-libraries/onnxruntime/{onnxruntime_1.13.1.bb => onnxruntime_1.16.1.bb} (89%) rename meta-digi-dey/dynamic-layers/meta-ml/recipes-libraries/tensorflow-lite/{tensorflow-lite-2.11.1.inc => tensorflow-lite-2.12.1.inc} (55%) rename meta-digi-dey/dynamic-layers/meta-ml/recipes-libraries/tensorflow-lite/{tensorflow-lite-ethosu-delegate_2.11.1.bb => tensorflow-lite-ethosu-delegate_2.12.1.bb} (94%) rename meta-digi-dey/dynamic-layers/meta-ml/recipes-libraries/tensorflow-lite/{tensorflow-lite-host-tools_2.11.1.bb => tensorflow-lite-host-tools_2.12.1.bb} (100%) delete mode 100644 meta-digi-dey/dynamic-layers/meta-ml/recipes-libraries/tensorflow-lite/tensorflow-lite_2.%.bbappend rename meta-digi-dey/dynamic-layers/meta-ml/recipes-libraries/tensorflow-lite/{tensorflow-lite_2.11.1.bb => tensorflow-lite_2.12.1.bb} (95%) diff --git a/meta-digi-arm/conf/machine/include/imx-digi-base.inc b/meta-digi-arm/conf/machine/include/imx-digi-base.inc index b3946d897..d04222f3c 100644 --- a/meta-digi-arm/conf/machine/include/imx-digi-base.inc +++ b/meta-digi-arm/conf/machine/include/imx-digi-base.inc @@ -278,22 +278,23 @@ PREFERRED_VERSION_optee-client:mx9-nxp-bsp ??= "4.0.0.imx" PREFERRED_VERSION_optee-test:mx8-nxp-bsp ??= "3.19.0.imx" PREFERRED_VERSION_optee-test:mx9-nxp-bsp ??= "4.0.0.imx" -# Machine learning backports from NXP's lf-6.1.36-2.1.0 release -PREFERRED_VERSION_ethos-u-vela:ccimx93 = "3.8.0" +# Machine learning backports from NXP's lf-6.1.55-2.2.0 release +PREFERRED_VERSION_ethos-u-driver-stack:ccimx93 = "23.08" +PREFERRED_VERSION_ethos-u-firmware:ccimx93 = "23.08" +PREFERRED_VERSION_ethos-u-vela:ccimx93 = "3.9.0" PREFERRED_VERSION_flatbuffers:ccimx93 = "2.0.7" PREFERRED_VERSION_flatbuffers-native:ccimx93 = "2.0.7" -PREFERRED_VERSION_onnxruntime:ccimx93 = "1.13.1" -PREFERRED_VERSION_onnxruntime-native:ccimx93 = "1.13.1" -PREFERRED_VERSION_tensorflow-lite:ccimx93 = "2.11.1" -PREFERRED_VERSION_tensorflow-lite-host-tools:ccimx93 = "2.11.1" -PREFERRED_VERSION_tensorflow-lite-host-tools-native:ccimx93 = "2.11.1" +PREFERRED_VERSION_onnxruntime:ccimx93 = "1.16.1" +PREFERRED_VERSION_tensorflow-lite:ccimx93 = "2.12.1" +PREFERRED_VERSION_tensorflow-lite-host-tools:ccimx93 = "2.12.1" +PREFERRED_VERSION_tensorflow-lite-host-tools-native:ccimx93 = "2.12.1" # Optee runtime packages to install OPTEE_PKGS ??= "optee-client optee-os" # Use i.MX opencv Version PREFERRED_VERSION_opencv:mx8-nxp-bsp ??= "4.6.0.imx" -PREFERRED_VERSION_opencv:mx9-nxp-bsp ??= "4.6.0.imx" +PREFERRED_VERSION_opencv:mx9-nxp-bsp ??= "4.7.0.imx" EXTRA_IMAGEDEPENDS += "u-boot" diff --git a/meta-digi-arm/dynamic-layers/freescale-layer/recipes-support/opencv/opencv/0001-3rdparty-ippicv-Use-pre-downloaded-ipp.patch b/meta-digi-arm/dynamic-layers/freescale-layer/recipes-support/opencv/opencv/0001-3rdparty-ippicv-Use-pre-downloaded-ipp.patch new file mode 100644 index 000000000..9e6a61371 --- /dev/null +++ b/meta-digi-arm/dynamic-layers/freescale-layer/recipes-support/opencv/opencv/0001-3rdparty-ippicv-Use-pre-downloaded-ipp.patch @@ -0,0 +1,36 @@ +From 9b4959b97d2e95d4b49cf6ca2a3fce3cdb484f2d Mon Sep 17 00:00:00 2001 +From: Ricardo Ribalda Delgado +Date: Thu, 31 Mar 2016 00:20:15 +0200 +Subject: [PATCH] 3rdparty/ippicv: Use pre-downloaded ipp + +Signed-off-by: Ricardo Ribalda Delgado +Signed-off-by: Ismo Puustinen + +--- + 3rdparty/ippicv/ippicv.cmake | 15 +-------------- + 1 file changed, 1 insertion(+), 14 deletions(-) + +diff --git a/3rdparty/ippicv/ippicv.cmake b/3rdparty/ippicv/ippicv.cmake +index 257af6fcc6..f88460450f 100644 +--- a/3rdparty/ippicv/ippicv.cmake ++++ b/3rdparty/ippicv/ippicv.cmake +@@ -34,18 +34,5 @@ function(download_ippicv root_var) + endif() + + set(THE_ROOT "${OpenCV_BINARY_DIR}/3rdparty/ippicv") +- ocv_download(FILENAME ${OPENCV_ICV_NAME} +- HASH ${OPENCV_ICV_HASH} +- URL +- "${OPENCV_IPPICV_URL}" +- "$ENV{OPENCV_IPPICV_URL}" +- "https://raw.githubusercontent.com/opencv/opencv_3rdparty/${IPPICV_COMMIT}/ippicv/" +- DESTINATION_DIR "${THE_ROOT}" +- ID IPPICV +- STATUS res +- UNPACK RELATIVE_URL) +- +- if(res) +- set(${root_var} "${THE_ROOT}/${OPENCV_ICV_PACKAGE_SUBDIR}" PARENT_SCOPE) +- endif() ++ set(${root_var} "${THE_ROOT}/${OPENCV_ICV_PACKAGE_SUBDIR}" PARENT_SCOPE) + endfunction() diff --git a/meta-digi-arm/dynamic-layers/freescale-layer/recipes-support/opencv/opencv/0001-Add-smaller-version-of-download_models.py.patch b/meta-digi-arm/dynamic-layers/freescale-layer/recipes-support/opencv/opencv/0001-Add-smaller-version-of-download_models.py.patch new file mode 100644 index 000000000..0aabee29f --- /dev/null +++ b/meta-digi-arm/dynamic-layers/freescale-layer/recipes-support/opencv/opencv/0001-Add-smaller-version-of-download_models.py.patch @@ -0,0 +1,179 @@ +From fca4d9eec289f22c081daa2c61a1110e3f268f92 Mon Sep 17 00:00:00 2001 +From: Tom Hochstein +Date: Tue, 1 Sep 2020 14:57:07 -0500 +Subject: [PATCH] Add smaller version of download_models.py + +Signed-off-by: Tom Hochstein +--- + testdata/dnn/download_models_basic.py | 159 ++++++++++++++++++++++++++ + 1 file changed, 159 insertions(+) + create mode 100644 testdata/dnn/download_models_basic.py + +diff --git a/testdata/dnn/download_models_basic.py b/testdata/dnn/download_models_basic.py +new file mode 100644 +index 0000000..5c8a616 +--- /dev/null ++++ b/testdata/dnn/download_models_basic.py +@@ -0,0 +1,159 @@ ++#!/usr/bin/env python ++ ++from __future__ import print_function ++import hashlib ++import sys ++import tarfile ++if sys.version_info[0] < 3: ++ from urllib2 import urlopen ++else: ++ from urllib.request import urlopen ++ ++ ++class Model: ++ MB = 1024*1024 ++ BUFSIZE = 10*MB ++ ++ def __init__(self, **kwargs): ++ self.name = kwargs.pop('name') ++ self.url = kwargs.pop('url', None) ++ self.filename = kwargs.pop('filename') ++ self.sha = kwargs.pop('sha', None) ++ self.archive = kwargs.pop('archive', None) ++ self.member = kwargs.pop('member', None) ++ ++ def __str__(self): ++ return 'Model <{}>'.format(self.name) ++ ++ def printRequest(self, r): ++ def getMB(r): ++ d = dict(r.info()) ++ for c in ['content-length', 'Content-Length']: ++ if c in d: ++ return int(d[c]) / self.MB ++ return '' ++ print(' {} {} [{} Mb]'.format(r.getcode(), r.msg, getMB(r))) ++ ++ def verify(self): ++ if not self.sha: ++ return False ++ print(' expect {}'.format(self.sha)) ++ sha = hashlib.sha1() ++ try: ++ with open(self.filename, 'rb') as f: ++ while True: ++ buf = f.read(self.BUFSIZE) ++ if not buf: ++ break ++ sha.update(buf) ++ print(' actual {}'.format(sha.hexdigest())) ++ return self.sha == sha.hexdigest() ++ except Exception as e: ++ print(' catch {}'.format(e)) ++ ++ def get(self): ++ if self.verify(): ++ print(' hash match - skipping') ++ return True ++ ++ if self.archive or self.member: ++ assert(self.archive and self.member) ++ print(' hash check failed - extracting') ++ print(' get {}'.format(self.member)) ++ self.extract() ++ else: ++ assert(self.url) ++ print(' hash check failed - downloading') ++ print(' get {}'.format(self.url)) ++ self.download() ++ ++ print(' done') ++ print(' file {}'.format(self.filename)) ++ return self.verify() ++ ++ def download(self): ++ try: ++ r = urlopen(self.url, timeout=60) ++ self.printRequest(r) ++ self.save(r) ++ except Exception as e: ++ print(' catch {}'.format(e)) ++ ++ def extract(self): ++ try: ++ with tarfile.open(self.archive) as f: ++ assert self.member in f.getnames() ++ self.save(f.extractfile(self.member)) ++ except Exception as e: ++ print(' catch {}'.format(e)) ++ ++ def save(self, r): ++ with open(self.filename, 'wb') as f: ++ print(' progress ', end='') ++ sys.stdout.flush() ++ while True: ++ buf = r.read(self.BUFSIZE) ++ if not buf: ++ break ++ f.write(buf) ++ print('>', end='') ++ sys.stdout.flush() ++ ++models = [ ++ Model( ++ name='Fcn', ++ url='http://dl.caffe.berkeleyvision.org/fcn8s-heavy-pascal.caffemodel', ++ sha='c449ea74dd7d83751d1357d6a8c323fcf4038962', ++ filename='fcn8s-heavy-pascal.caffemodel'), ++ Model( ++ name='SqueezeNet_v1.1', ++ url='https://raw.githubusercontent.com/DeepScale/SqueezeNet/b5c3f1a23713c8b3fd7b801d229f6b04c64374a5/SqueezeNet_v1.1/squeezenet_v1.1.caffemodel', ++ sha='3397f026368a45ae236403ccc81cfcbe8ebe1bd0', ++ filename='squeezenet_v1.1.caffemodel'), ++ Model( ++ name='Colorization', ++ url='https://raw.githubusercontent.com/richzhang/colorization/master/models/colorization_deploy_v2.prototxt', ++ sha='f528334e386a69cbaaf237a7611d833bef8e5219', ++ filename='colorization_deploy_v2.prototxt'), ++ Model( ++ name='Colorization', ++ url='http://eecs.berkeley.edu/~rich.zhang/projects/2016_colorization/files/demo_v2/colorization_release_v2.caffemodel', ++ sha='21e61293a3fa6747308171c11b6dd18a68a26e7f', ++ filename='colorization_release_v2.caffemodel'), ++ Model( ++ name='OpenPose/pose/coco', # https://github.com/CMU-Perceptual-Computing-Lab/openpose ++ url='http://posefs1.perception.cs.cmu.edu/OpenPose/models/pose/coco/pose_iter_440000.caffemodel', ++ sha='ac7e97da66f3ab8169af2e601384c144e23a95c1', ++ filename='openpose_pose_coco.caffemodel'), ++ Model( ++ name='YOLOv3', # https://pjreddie.com/darknet/yolo/ ++ url='https://pjreddie.com/media/files/yolov3.weights', ++ sha='520878f12e97cf820529daea502acca380f1cb8e', ++ filename='yolov3.weights'), ++ Model( ++ name='EAST', # https://github.com/argman/EAST (a TensorFlow model), https://arxiv.org/abs/1704.03155v2 (a paper) ++ url='https://www.dropbox.com/s/r2ingd0l3zt8hxs/frozen_east_text_detection.tar.gz?dl=1', ++ sha='3ca8233d6edd748f7ed23246c8ca24cbf696bb94', ++ filename='frozen_east_text_detection.tar.gz'), ++ Model( ++ name='EAST', ++ archive='frozen_east_text_detection.tar.gz', ++ member='frozen_east_text_detection.pb', ++ sha='fffabf5ac36f37bddf68e34e84b45f5c4247ed06', ++ filename='frozen_east_text_detection.pb'), ++] ++ ++# Note: models will be downloaded to current working directory ++# expected working directory is opencv_extra/testdata/dnn ++if __name__ == '__main__': ++ failedModels = [] ++ for m in models: ++ print(m) ++ if not m.get(): ++ failedModels.append(m.filename) ++ ++ if failedModels: ++ print("Following models have not been downloaded:") ++ for f in failedModels: ++ print("* {}".format(f)) ++ exit(15) +-- +2.17.1 + diff --git a/meta-digi-arm/dynamic-layers/freescale-layer/recipes-support/opencv/opencv/0001-Dont-use-isystem.patch b/meta-digi-arm/dynamic-layers/freescale-layer/recipes-support/opencv/opencv/0001-Dont-use-isystem.patch new file mode 100644 index 000000000..948a80faf --- /dev/null +++ b/meta-digi-arm/dynamic-layers/freescale-layer/recipes-support/opencv/opencv/0001-Dont-use-isystem.patch @@ -0,0 +1,28 @@ +From 66e50ee69fa9ee2469d349100e70d8b296c4b4dc Mon Sep 17 00:00:00 2001 +From: Khem Raj +Date: Tue, 11 Sep 2018 00:21:18 -0700 +Subject: [PATCH] Dont use isystem + +clang really does not like it + +Upstream-Status: Pending + +Signed-off-by: Khem Raj + +--- + cmake/OpenCVPCHSupport.cmake | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/cmake/OpenCVPCHSupport.cmake b/cmake/OpenCVPCHSupport.cmake +index 08cd06def4..46c9c02da3 100644 +--- a/cmake/OpenCVPCHSupport.cmake ++++ b/cmake/OpenCVPCHSupport.cmake +@@ -18,6 +18,8 @@ IF(CV_GCC) + SET(PCHSupport_FOUND TRUE) + ENDIF() + ++ SET(CMAKE_INCLUDE_SYSTEM_FLAG_C "-I") ++ SET(CMAKE_INCLUDE_SYSTEM_FLAG_CXX "-I") + SET(_PCH_include_prefix "-I") + SET(_PCH_isystem_prefix "-isystem") + SET(_PCH_define_prefix "-D") diff --git a/meta-digi-arm/dynamic-layers/freescale-layer/recipes-support/opencv/opencv/0001-Make-ts-module-external.patch b/meta-digi-arm/dynamic-layers/freescale-layer/recipes-support/opencv/opencv/0001-Make-ts-module-external.patch new file mode 100644 index 000000000..d56b8ae67 --- /dev/null +++ b/meta-digi-arm/dynamic-layers/freescale-layer/recipes-support/opencv/opencv/0001-Make-ts-module-external.patch @@ -0,0 +1,42 @@ +From 11bbf909e08594628bd757d989ae34cf1bfe200b Mon Sep 17 00:00:00 2001 +From: Mingli Yu +Date: Thu, 18 Jun 2020 05:51:38 +0000 +Subject: [PATCH] Make ts module external + +Make ts module external + +Reference: https://github.com/qbonnard/opencv/commit/6b229c5834cb9a0930425e762a6c7b03244d7abb + +Upstream-Status: Submitted [https://github.com/opencv/opencv/issues/8408] + +Signed-off-by: Mingli Yu +--- + modules/ts/CMakeLists.txt | 5 +---- + 1 file changed, 1 insertion(+), 4 deletions(-) + +diff --git a/modules/ts/CMakeLists.txt b/modules/ts/CMakeLists.txt +index f95bed0793..66f315bcca 100644 +--- a/modules/ts/CMakeLists.txt ++++ b/modules/ts/CMakeLists.txt +@@ -4,9 +4,6 @@ if(NOT BUILD_opencv_ts AND NOT BUILD_TESTS AND NOT BUILD_PERF_TESTS) + ocv_module_disable(ts) + endif() + +-set(OPENCV_MODULE_TYPE STATIC) +-set(OPENCV_MODULE_IS_PART_OF_WORLD FALSE) +- + if(WINRT) + # WINRT doesn't have access to environment variables + # so adding corresponding macros during CMake run +@@ -16,7 +13,7 @@ endif() + + ocv_warnings_disable(CMAKE_CXX_FLAGS -Wundef) + +-ocv_add_module(ts INTERNAL opencv_core opencv_imgproc opencv_imgcodecs opencv_videoio opencv_highgui) ++ocv_add_module(ts opencv_core opencv_imgproc opencv_imgcodecs opencv_videoio opencv_highgui) + + ocv_glob_module_sources() + ocv_module_include_directories() +-- +2.24.1 + diff --git a/meta-digi-arm/dynamic-layers/freescale-layer/recipes-support/opencv/opencv/0001-Temporarliy-work-around-deprecated-ffmpeg-RAW-functi.patch b/meta-digi-arm/dynamic-layers/freescale-layer/recipes-support/opencv/opencv/0001-Temporarliy-work-around-deprecated-ffmpeg-RAW-functi.patch new file mode 100644 index 000000000..1e47f8b16 --- /dev/null +++ b/meta-digi-arm/dynamic-layers/freescale-layer/recipes-support/opencv/opencv/0001-Temporarliy-work-around-deprecated-ffmpeg-RAW-functi.patch @@ -0,0 +1,31 @@ +From e4ec6cea72da9e9ae5ba57140fa2f5c63f1f8295 Mon Sep 17 00:00:00 2001 +From: Jason Wessel +Date: Wed, 9 May 2018 13:33:59 -0700 +Subject: [PATCH] Temporarliy work around deprecated ffmpeg RAW function + compile failure until next uprev + +Signed-off-by: Jason Wessel + +--- + modules/videoio/src/cap_ffmpeg_impl.hpp | 8 ++++++++ + 1 file changed, 8 insertions(+) + +diff --git a/modules/videoio/src/cap_ffmpeg_impl.hpp b/modules/videoio/src/cap_ffmpeg_impl.hpp +index 6dca724a89..ae55dd4555 100644 +--- a/modules/videoio/src/cap_ffmpeg_impl.hpp ++++ b/modules/videoio/src/cap_ffmpeg_impl.hpp +@@ -774,6 +774,14 @@ struct ImplMutex::Impl + + #endif + ++/* NOTE This is deprecated in ffmpeg and the code should be removed */ ++#ifndef AVFMT_RAWPICTURE ++#define AVFMT_RAWPICTURE 0x0020 ++#endif /* AVFMT_RAWPICTURE */ ++#ifndef CODEC_FLAG_GLOBAL_HEADER ++#define CODEC_FLAG_GLOBAL_HEADER AV_CODEC_FLAG_GLOBAL_HEADER ++#endif ++ + void ImplMutex::init() + { + impl = new Impl(); diff --git a/meta-digi-arm/dynamic-layers/freescale-layer/recipes-support/opencv/opencv/0003-To-fix-errors-as-following.patch b/meta-digi-arm/dynamic-layers/freescale-layer/recipes-support/opencv/opencv/0003-To-fix-errors-as-following.patch new file mode 100644 index 000000000..bb47ef2ba --- /dev/null +++ b/meta-digi-arm/dynamic-layers/freescale-layer/recipes-support/opencv/opencv/0003-To-fix-errors-as-following.patch @@ -0,0 +1,70 @@ +From f42c9b8c7bafcadc7e95fb25a391707f970eb426 Mon Sep 17 00:00:00 2001 +From: Huang Qiyu +Date: Fri, 19 May 2017 04:27:50 +0900 +Subject: [PATCH] To fix errors as following: + +"test_main.cpp:45: undefined reference to `parseCustomOptions(int, char**)'" +"perf_abs.cpp:13: undefined reference to `cvtest::param_seed'" +"test_superres.cpp:270: undefined reference to `checkIppStatus()'" + +Signed-off-by: Huang Qiyu + +Also add the visibility changes for certain OpenCL-related functions in +ts module. + +Signed-off-by: Ismo Puustinen + +--- + modules/ts/include/opencv2/ts.hpp | 4 ++-- + modules/ts/include/opencv2/ts/ocl_test.hpp | 2 +- + modules/ts/include/opencv2/ts/ts_ext.hpp | 2 +- + 3 files changed, 4 insertions(+), 4 deletions(-) + +diff --git a/modules/ts/include/opencv2/ts.hpp b/modules/ts/include/opencv2/ts.hpp +index ed7491a89a..80919d13ee 100644 +--- a/modules/ts/include/opencv2/ts.hpp ++++ b/modules/ts/include/opencv2/ts.hpp +@@ -728,7 +728,7 @@ protected: + } + }; + +-extern uint64 param_seed; ++CV_EXPORTS extern uint64 param_seed; + + struct DefaultRngAuto + { +@@ -791,7 +791,7 @@ private: + #endif + #endif + +-void parseCustomOptions(int argc, char **argv); ++CV_EXPORTS void parseCustomOptions(int argc, char **argv); + + #define CV_TEST_INIT0_NOOP (void)0 + +diff --git a/modules/ts/include/opencv2/ts/ocl_test.hpp b/modules/ts/include/opencv2/ts/ocl_test.hpp +index 11572e9f48..438112e2aa 100644 +--- a/modules/ts/include/opencv2/ts/ocl_test.hpp ++++ b/modules/ts/include/opencv2/ts/ocl_test.hpp +@@ -82,7 +82,7 @@ inline UMat ToUMat(InputArray src) + return dst; + } + +-extern int test_loop_times; ++CV_EXPORTS extern int test_loop_times; + + #define MAX_VALUE 357 + +diff --git a/modules/ts/include/opencv2/ts/ts_ext.hpp b/modules/ts/include/opencv2/ts/ts_ext.hpp +index b2a4cac241..b94c681c0c 100644 +--- a/modules/ts/include/opencv2/ts/ts_ext.hpp ++++ b/modules/ts/include/opencv2/ts/ts_ext.hpp +@@ -9,7 +9,7 @@ + #define OPENCV_TS_EXT_HPP + + namespace cvtest { +-void checkIppStatus(); ++CV_EXPORTS void checkIppStatus(); + extern bool skipUnstableTests; + extern bool runBigDataTests; + extern int testThreads; diff --git a/meta-digi-arm/dynamic-layers/freescale-layer/recipes-support/opencv/opencv/OpenCV_DNN_examples.patch b/meta-digi-arm/dynamic-layers/freescale-layer/recipes-support/opencv/opencv/OpenCV_DNN_examples.patch new file mode 100644 index 000000000..ef7831a5f --- /dev/null +++ b/meta-digi-arm/dynamic-layers/freescale-layer/recipes-support/opencv/opencv/OpenCV_DNN_examples.patch @@ -0,0 +1,141 @@ +From 3c4daafb54f961e376104a461ca7ec114ff0331a Mon Sep 17 00:00:00 2001 +From: Ludek Slosarcik +Date: Fri, 14 Feb 2020 15:46:50 +0100 +Subject: [PATCH] opencv_dnn: added video device for 2 examples, and change text labels + +Signed-off-by: Ludek Slosarcik + +Upstream-Status: Pending +--- + samples/cpp/logistic_regression.cpp | 2 +- + samples/dnn/classification.cpp | 7 ++++--- + samples/dnn/object_detection.cpp | 10 +++++----- + samples/dnn/segmentation.cpp | 2 +- + samples/dnn/text_detection.cpp | 5 +++-- + 5 files changed, 14 insertions(+), 12 deletions(-) + +Index: git/samples/cpp/logistic_regression.cpp +=================================================================== +--- git.orig/samples/cpp/logistic_regression.cpp ++++ git/samples/cpp/logistic_regression.cpp +@@ -28,7 +28,7 @@ static float calculateAccuracyPercent(co + + int main() + { +- const String filename = samples::findFile("data01.xml"); ++ const String filename = samples::findFile("../data/data01.xml"); + cout << "**********************************************************************" << endl; + cout << filename + << " contains digits 0 and 1 of 20 samples each, collected on an Android device" << endl; +Index: git/samples/dnn/classification.cpp +=================================================================== +--- git.orig/samples/dnn/classification.cpp ++++ git/samples/dnn/classification.cpp +@@ -12,6 +12,7 @@ std::string keys = + "{ help h | | Print help message. }" + "{ @alias | | An alias name of model to extract preprocessing parameters from models.yml file. }" + "{ zoo | models.yml | An optional path to file with preprocessing parameters }" ++ "{ device | 0 | camera device number. }" + "{ input i | | Path to input image or video file. Skip this argument to capture frames from a camera.}" + "{ initial_width | 0 | Preprocess input image by initial resizing to a specific width.}" + "{ initial_height | 0 | Preprocess input image by initial resizing to a specific height.}" +@@ -113,7 +114,7 @@ int main(int argc, char** argv) + if (parser.has("input")) + cap.open(parser.get("input")); + else +- cap.open(0); ++ cap.open(parser.get("device")); + //! [Open a video file or an image file or a camera stream] + + // Process frames. +@@ -195,14 +196,14 @@ int main(int argc, char** argv) + } + std::string label = format("Inference time of 1 round: %.2f ms", t1); + std::string label2 = format("Average time of 200 rounds: %.2f ms", timeRecorder.getTimeMilli()/200); +- putText(frame, label, Point(0, 15), FONT_HERSHEY_SIMPLEX, 0.5, Scalar(0, 255, 0)); +- putText(frame, label2, Point(0, 35), FONT_HERSHEY_SIMPLEX, 0.5, Scalar(0, 255, 0)); ++ putText(frame, label, Point(0, 20), FONT_HERSHEY_SIMPLEX, 0.8, Scalar(0, 0, 255), 2, 8, false); ++ putText(frame, label2, Point(0, 45), FONT_HERSHEY_SIMPLEX, 0.8, Scalar(0, 0, 255), 2, 8, false); + + // Print predicted class. + label = format("%s: %.4f", (classes.empty() ? format("Class #%d", classId).c_str() : + classes[classId].c_str()), + confidence); +- putText(frame, label, Point(0, 55), FONT_HERSHEY_SIMPLEX, 0.5, Scalar(0, 255, 0)); ++ putText(frame, label, Point(0, 70), FONT_HERSHEY_SIMPLEX, 0.8, Scalar(0, 0, 255), 2, 8, false); + + imshow(kWinName, frame); + } +Index: git/samples/dnn/object_detection.cpp +=================================================================== +--- git.orig/samples/dnn/object_detection.cpp ++++ git/samples/dnn/object_detection.cpp +@@ -260,13 +260,13 @@ int main(int argc, char** argv) + if (predictionsQueue.counter > 1) + { + std::string label = format("Camera: %.2f FPS", framesQueue.getFPS()); +- putText(frame, label, Point(0, 15), FONT_HERSHEY_SIMPLEX, 0.5, Scalar(0, 255, 0)); ++ putText(frame, label, Point(0, 20), FONT_HERSHEY_SIMPLEX, 0.8, Scalar(0, 0, 255), 2, 8, false); + + label = format("Network: %.2f FPS", predictionsQueue.getFPS()); +- putText(frame, label, Point(0, 30), FONT_HERSHEY_SIMPLEX, 0.5, Scalar(0, 255, 0)); ++ putText(frame, label, Point(0, 45), FONT_HERSHEY_SIMPLEX, 0.8, Scalar(0, 0, 255), 2, 8, false); + + label = format("Skipped frames: %d", framesQueue.counter - predictionsQueue.counter); +- putText(frame, label, Point(0, 45), FONT_HERSHEY_SIMPLEX, 0.5, Scalar(0, 255, 0)); ++ putText(frame, label, Point(0, 70), FONT_HERSHEY_SIMPLEX, 0.8, Scalar(0, 0, 255), 2, 8, false); + } + imshow(kWinName, frame); + } +@@ -302,7 +302,7 @@ int main(int argc, char** argv) + double freq = getTickFrequency() / 1000; + double t = net.getPerfProfile(layersTimes) / freq; + std::string label = format("Inference time: %.2f ms", t); +- putText(frame, label, Point(0, 15), FONT_HERSHEY_SIMPLEX, 0.5, Scalar(0, 255, 0)); ++ putText(frame, label, Point(0, 20), FONT_HERSHEY_SIMPLEX, 0.8, Scalar(0, 0, 255), 2, 8, false); + + imshow(kWinName, frame); + } +@@ -471,7 +471,7 @@ void drawPred(int classId, float conf, i + top = max(top, labelSize.height); + rectangle(frame, Point(left, top - labelSize.height), + Point(left + labelSize.width, top + baseLine), Scalar::all(255), FILLED); +- putText(frame, label, Point(left, top), FONT_HERSHEY_SIMPLEX, 0.5, Scalar()); ++ putText(frame, label, Point(left, top), FONT_HERSHEY_SIMPLEX, 0.8, Scalar()); + } + + void callback(int pos, void*) +Index: git/samples/dnn/segmentation.cpp +=================================================================== +--- git.orig/samples/dnn/segmentation.cpp ++++ git/samples/dnn/segmentation.cpp +@@ -162,7 +162,7 @@ int main(int argc, char** argv) + double freq = getTickFrequency() / 1000; + double t = net.getPerfProfile(layersTimes) / freq; + std::string label = format("Inference time: %.2f ms", t); +- putText(frame, label, Point(0, 15), FONT_HERSHEY_SIMPLEX, 0.5, Scalar(0, 255, 0)); ++ putText(frame, label, Point(0, 20), FONT_HERSHEY_SIMPLEX, 0.8, Scalar(0, 0, 255), 2, 8, false); + + imshow(kWinName, frame); + if (!classes.empty()) +Index: git/samples/dnn/text_detection.cpp +=================================================================== +--- git.orig/samples/dnn/text_detection.cpp ++++ git/samples/dnn/text_detection.cpp +@@ -30,6 +30,7 @@ using namespace cv::dnn; + const char* keys = + "{ help h | | Print help message. }" + "{ input i | | Path to input image or video file. Skip this argument to capture frames from a camera.}" ++ "{ device | 0 | camera device number. }" + "{ detModel dmp | | Path to a binary .pb file contains trained detector network.}" + "{ width | 320 | Preprocess input image by resizing to a specific width. It should be multiple by 32. }" + "{ height | 320 | Preprocess input image by resizing to a specific height. It should be multiple by 32. }" +@@ -106,7 +107,7 @@ int main(int argc, char** argv) + + // Open a video file or an image file or a camera stream. + VideoCapture cap; +- bool openSuccess = parser.has("input") ? cap.open(parser.get("input")) : cap.open(0); ++ bool openSuccess = parser.has("input") ? cap.open(parser.get("input")) : cap.open(parser.get("device")); + CV_Assert(openSuccess); + + static const std::string kWinName = "EAST: An Efficient and Accurate Scene Text Detector"; diff --git a/meta-digi-arm/dynamic-layers/freescale-layer/recipes-support/opencv/opencv/download.patch b/meta-digi-arm/dynamic-layers/freescale-layer/recipes-support/opencv/opencv/download.patch new file mode 100644 index 000000000..33ac48312 --- /dev/null +++ b/meta-digi-arm/dynamic-layers/freescale-layer/recipes-support/opencv/opencv/download.patch @@ -0,0 +1,41 @@ +From b18a280fab06a680d9f831bf8b462647f3cb6214 Mon Sep 17 00:00:00 2001 +From: Ross Burton +Date: Thu, 9 Jan 2020 16:24:24 +0000 +Subject: [PATCH] opencv: abort configure if we need to download + +This CMake module will download files during do_configure. This is bad as it +means we can't do offline builds. + +Add an option to disallow downloads by emitting a fatal error. + +Upstream-Status: Pending +Signed-off-by: Ross Burton + +--- + cmake/OpenCVDownload.cmake | 6 ++++++ + 1 file changed, 6 insertions(+) + +diff --git a/cmake/OpenCVDownload.cmake b/cmake/OpenCVDownload.cmake +index 63cf6d3238..4acf477f70 100644 +--- a/cmake/OpenCVDownload.cmake ++++ b/cmake/OpenCVDownload.cmake +@@ -14,6 +14,7 @@ + # RELATIVE_URL - if set, then URL is treated as a base, and FILENAME will be appended to it + # Note: uses OPENCV_DOWNLOAD_PATH folder as cache, default is /.cache + ++set(OPENCV_ALLOW_DOWNLOADS ON CACHE BOOL "Allow downloads") + set(HELP_OPENCV_DOWNLOAD_PATH "Cache directory for downloaded files") + if(DEFINED ENV{OPENCV_DOWNLOAD_PATH}) + set(OPENCV_DOWNLOAD_PATH "$ENV{OPENCV_DOWNLOAD_PATH}" CACHE PATH "${HELP_OPENCV_DOWNLOAD_PATH}") +@@ -156,6 +157,11 @@ function(ocv_download) + + # Download + if(NOT EXISTS "${CACHE_CANDIDATE}") ++ if(NOT OPENCV_ALLOW_DOWNLOADS) ++ message(FATAL_ERROR "Not going to download ${DL_FILENAME}") ++ return() ++ endif() ++ + ocv_download_log("#cmake_download \"${CACHE_CANDIDATE}\" \"${DL_URL}\"") + foreach(try ${OPENCV_DOWNLOAD_TRIES_LIST}) + ocv_download_log("#try ${try}") diff --git a/meta-digi-arm/dynamic-layers/freescale-layer/recipes-support/opencv/opencv_4.7.0.imx.bb b/meta-digi-arm/dynamic-layers/freescale-layer/recipes-support/opencv/opencv_4.7.0.imx.bb new file mode 100644 index 000000000..7f95691a1 --- /dev/null +++ b/meta-digi-arm/dynamic-layers/freescale-layer/recipes-support/opencv/opencv_4.7.0.imx.bb @@ -0,0 +1,23 @@ +# Copyright 2024 Digi International Inc. + +# +# Reuse meta-freescale's opencv_4.6.0.imx.bb +# +require recipes-support/opencv/opencv_4.6.0.imx.bb + +SRC_URI:remove = "file://0001-Add-missing-header-for-LIBAVCODEC_VERSION_INT.patch" + +SRCBRANCH = "4.7.0_imx" +SRCREV_opencv = "3acf6a50fcb4f774728d2338553ad646ccc14b14" + +# Update opencv_contrib +SRC_URI:remove = "git://github.com/opencv/opencv_contrib.git;destsuffix=git/contrib;name=contrib;branch=master;protocol=https" +SRC_URI += "git://github.com/opencv/opencv_contrib.git;destsuffix=git/contrib;name=contrib;branch=4.x;protocol=https" +SRCREV_contrib = "e247b680a6bd396f110274b6c214406a93171350" + +SRC_URI:remove = "git://github.com/opencv/opencv_extra.git;destsuffix=extra;name=extra;branch=master;protocol=https" +SRC_URI =+ "git://github.com/opencv/opencv_extra.git;destsuffix=extra;name=extra;branch=4.x;protocol=https" + +SRCREV_extra = "5abbd7e0546bbb34ae7487170383d3e571fb1dd1" + +COMPATIBLE_MACHINE = "(mx9-nxp-bsp)" diff --git a/meta-digi-dey/dynamic-layers/meta-ml/recipes-fsl/packagegroup/packagegroup-imx-ml.bbappend b/meta-digi-dey/dynamic-layers/meta-ml/recipes-fsl/packagegroup/packagegroup-imx-ml.bbappend index fdb3bab58..b9b63a1e7 100644 --- a/meta-digi-dey/dynamic-layers/meta-ml/recipes-fsl/packagegroup/packagegroup-imx-ml.bbappend +++ b/meta-digi-dey/dynamic-layers/meta-ml/recipes-fsl/packagegroup/packagegroup-imx-ml.bbappend @@ -1,9 +1,8 @@ -# Copyright 2023 Digi International Inc. +# Copyright 2023,2024 Digi International Inc. ML_NNSTREAMER_PKGS_LIST:remove = "nnstreamer-deepview-rt" ML_PKGS:mx9-nxp-bsp:remove = "deepview-rt-examples" -ML_PKGS:mx9-nxp-bsp:append = " modelrunner" # ARM ethos-u package ETHOS_U_PKGS:append:mx93-nxp-bsp = " \ diff --git a/meta-digi-dey/dynamic-layers/meta-ml/recipes-libraries/arm-compute-library/arm-compute-library_22.05.bbappend b/meta-digi-dey/dynamic-layers/meta-ml/recipes-libraries/arm-compute-library/arm-compute-library_22.05.bbappend index 33acf4538..f816bd719 100644 --- a/meta-digi-dey/dynamic-layers/meta-ml/recipes-libraries/arm-compute-library/arm-compute-library_22.05.bbappend +++ b/meta-digi-dey/dynamic-layers/meta-ml/recipes-libraries/arm-compute-library/arm-compute-library_22.05.bbappend @@ -1,6 +1,6 @@ -# Copyright 2023 Digi International Inc. +# Copyright 2023,2024 Digi International Inc. -SRCBRANCH = "lf-6.1.36_2.1.0" -SRCREV = "b956e65221fca7dadfd8bdfd13279beacce17bc9" +SRCBRANCH:ccimx93 = "imx_22.05" +SRCREV:ccimx93 = "37fc035060646db5048648da01db3738f08e3bfa" SCONS_MAXLINELENGTH = "" diff --git a/meta-digi-dey/dynamic-layers/meta-ml/recipes-libraries/eiq-examples/eiq-examples_git.bb b/meta-digi-dey/dynamic-layers/meta-ml/recipes-libraries/eiq-examples/eiq-examples_git.bb index fd523e780..43ad704a4 100644 --- a/meta-digi-dey/dynamic-layers/meta-ml/recipes-libraries/eiq-examples/eiq-examples_git.bb +++ b/meta-digi-dey/dynamic-layers/meta-ml/recipes-libraries/eiq-examples/eiq-examples_git.bb @@ -5,8 +5,8 @@ LIC_FILES_CHKSUM = "file://LICENSE;md5=86d3f3a95c324c9479bd8986968f4327" SRC_URI = "${EIQ_EXAMPLES_SRC};branch=${SRCBRANCH}" EIQ_EXAMPLES_SRC ?= "git://github.com/nxp-imx/eiq-example.git;protocol=https" -SRCBRANCH = "lf-6.1.36_2.1.0" -SRCREV = "47da4f9c4d568704f8835dde62cfc61f16e89ba6" +SRCBRANCH = "lf-6.1.55_2.2.0" +SRCREV = "4a21f2919e7e16ca1847672b6ed1ecfa60f1a86f" S = "${WORKDIR}/git" diff --git a/meta-digi-dey/dynamic-layers/meta-ml/recipes-libraries/ethos-u-driver-stack/ethos-u-driver-stack_22.08.bbappend b/meta-digi-dey/dynamic-layers/meta-ml/recipes-libraries/ethos-u-driver-stack/ethos-u-driver-stack_22.08.bbappend deleted file mode 100644 index dacfab396..000000000 --- a/meta-digi-dey/dynamic-layers/meta-ml/recipes-libraries/ethos-u-driver-stack/ethos-u-driver-stack_22.08.bbappend +++ /dev/null @@ -1,6 +0,0 @@ -# Copyright (C) 2023 Digi International - -LIC_FILES_CHKSUM = "file://LICENSE.txt;md5=e3fc50a88d0a364313df4b21ef20c29e" - -SRCBRANCH = "lf-6.1.36_2.1.0" -SRCREV = "98759f579297726474d6b32927694502c66ce15a" diff --git a/meta-digi-dey/dynamic-layers/meta-ml/recipes-libraries/ethos-u-driver-stack/ethos-u-driver-stack_23.08.bb b/meta-digi-dey/dynamic-layers/meta-ml/recipes-libraries/ethos-u-driver-stack/ethos-u-driver-stack_23.08.bb new file mode 100644 index 000000000..3696f747f --- /dev/null +++ b/meta-digi-dey/dynamic-layers/meta-ml/recipes-libraries/ethos-u-driver-stack/ethos-u-driver-stack_23.08.bb @@ -0,0 +1,11 @@ +# Copyright 2024 Digi International Inc. + +# +# Reuse meta-imx/meta-ml ethos-u-driver-stack_22.08.bb +# +require recipes-libraries/ethos-u-driver-stack/ethos-u-driver-stack_22.08.bb + +LIC_FILES_CHKSUM = "file://LICENSE.txt;md5=e3fc50a88d0a364313df4b21ef20c29e" + +SRCBRANCH = "lf-6.1.55_2.2.0" +SRCREV = "f8975c4d44e7893dcf106d4afaff55e30470b463" diff --git a/meta-digi-dey/dynamic-layers/meta-ml/recipes-libraries/ethos-u-driver-stack/ethos-u-firmware/ccimx93/ethosu_firmware b/meta-digi-dey/dynamic-layers/meta-ml/recipes-libraries/ethos-u-driver-stack/ethos-u-firmware/ccimx93/ethosu_firmware index 46306553d1be60ad2239684ccaee8324205a7230..6299689f854dcd3631a83f26aab7b089ce5727f1 100755 GIT binary patch delta 7471 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 delta 7457 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