From c41c4fd47ace513d58a4d9e2eb0e8915b2bd08b4 Mon Sep 17 00:00:00 2001
From: aeberhardt <alexandre.eberhardt@savoirfairelinux.com>
Date: Tue, 15 Oct 2024 14:29:45 -0400
Subject: [PATCH] build: greenscreen build with static libs to be portable

build greenscreen plugin using daemon contribs libraries
multiplatform for linux (x86_64-linux-gnu) and major android arch (arm64-v8a, armeabi-v7a, x86_64)

Change-Id: I51efdde9987846f3626812dbe942ec220c223048
---
 GreenScreen/CMakeLists.txt        | 283 +++++++++++++++++-------------
 GreenScreen/build.md              | 219 +++++++++++++++++++++--
 GreenScreen/data/preferences.json |   8 +
 SDK/certificate_requirements.txt  |   1 +
 SDK/jplManipulation.py            |   0
 build-plugin.py                   |  15 +-
 contrib/build-dependencies.sh     |   5 +-
 docker/Dockerfile_android         |  91 ++++++++++
 docker/Dockerfile_ubuntu_20.04    |  22 +--
 sign.md                           |  12 +-
 10 files changed, 490 insertions(+), 166 deletions(-)
 mode change 100644 => 100755 SDK/jplManipulation.py
 create mode 100644 docker/Dockerfile_android

diff --git a/GreenScreen/CMakeLists.txt b/GreenScreen/CMakeLists.txt
index 92e9dd2..15d3da0 100644
--- a/GreenScreen/CMakeLists.txt
+++ b/GreenScreen/CMakeLists.txt
@@ -1,154 +1,185 @@
-cmake_minimum_required(VERSION 3.10)
+cmake_minimum_required (VERSION 3.10)
 
-# Project setup
+# Set the project name and version
 set (ProjectName GreenScreen)
 set (Version 2.0.0)
-project(${ProjectName} VERSION ${Version})
 
-# Detect OS and architecture
-if(NOT CMAKE_SIZEOF_VOID_P EQUAL 8)
-    message(FATAL_ERROR "Unsupported architecture. Only x64 or aarch64 (arm64) is supported.")
-else()
-    set (ARCH $CMAKE_SYSTEM_PROCESSOR)
-endif()
-
-if(WIN32)
-    set(DISTRIBUTION "x64-windows")
-elseif(APPLE)
-    set(DISTRIBUTION "${ARCH}-apple-darwin")
-elseif(ANDROID)
-    set(DISTRIBUTION "android")
-else()
-    set(DISTRIBUTION "x86_64-linux-gnu")
-endif()
+project (${ProjectName} VERSION ${Version})
+
+# Set default options
+option (DEBUG "Build in debug mode" OFF)
 
-# Paths setup
-set (JAMI_PLUGINS_PATH ${PROJECT_SOURCE_DIR}/.. )
-set (DAEMON ${JAMI_PLUGINS_PATH}/daemon)
-set (DAEMON_SRC ${DAEMON}/src)
+# Set platform to build for
+set (PLATFORM_TYPE $ENV{PLATFORM_TYPE}) # can be LINUX or ANDROID
+if (PLATFORM_TYPE STREQUAL "ANDROID")
+    set (PLATFORM $ENV{ANDROID_ABI}) # can be arm64-v8a, armeabi-v7a or x86_64
+elseif(PLATFORM_TYPE STREQUAL "LINUX")
+    set (PLATFORM x86_64-linux-gnu) # can be x86_64-linux-gnu
+else()
+    message(FATAL_ERROR "Platform type not supported for now")
+endif ()
+
+# set compilation flags based on platform
+if (PLATFORM STREQUAL "x86_64-linux-gnu")
+    set (CONTRIB_PLATFORM x86_64-linux-gnu)
+elseif (PLATFORM STREQUAL "arm64-v8a")
+    set (CONTRIB_PLATFORM aarch64-linux-android)
+elseif (PLATFORM STREQUAL "armeabi-v7a")
+    set (CONTRIB_PLATFORM arm-linux-androideabi)
+elseif (PLATFORM STREQUAL "x86_64")
+    set (CONTRIB_PLATFORM x86_64-linux-android)
+endif ()
+
+# Set variables
+set (CMAKE_CXX_STANDARD 17)
+set (CMAKE_CXX_STANDARD_REQUIRED True)
+set (DAEMON ${PROJECT_SOURCE_DIR}/../daemon)
 set (CONTRIB_PATH ${DAEMON}/contrib)
-set (PLUGINS_LIB ${JAMI_PLUGINS_PATH}/lib)
-set (JPL_DIRECTORY ${PROJECT_BINARY_DIR}/jpl)
-set (JPL_FILE_NAME ${ProjectName}.jpl)
-set (SDK_PATH ${JAMI_PLUGINS_PATH}/SDK)
-set (PLUGIN_OUTPUT_DIR ${JPL_DIRECTORY}/lib/${DISTRIBUTION})
-
-message(Distribution:\ ${DISTRIBUTION})
-message(Building:\ ${ProjectName} ${Version})
-message(Build\ path:\ ${PROJECT_BINARY_DIR})
-message(JPL\ assembling\ path:\ ${JPL_DIRECTORY})
-message(JPL\ path:\ ${JAMI_PLUGINS_PATH}/build/${DISTRIBUTION}/${JPL_FILE_NAME})
-
-set(CMAKE_CXX_STANDARD 17)
-set(CMAKE_CXX_STANDARD_REQUIRED True)
-set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} /DMSGPACK_NO_BOOST /MT")
-set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} /DMSGPACK_NO_BOOST /MTd")
-
-set(plugin_SRC
+set (PLUGINS_LIB ${PROJECT_SOURCE_DIR}/../lib)
+set (CONTRIB_ROOT_PATH ${CONTRIB_PATH}/${CONTRIB_PLATFORM})
+set (CMAKE_BUILD_RPATH "$ORIGIN")
+set (SDK_PATH ${PROJECT_SOURCE_DIR}/../SDK)
+set (CMAKE_SHARED_LINKER_FLAGS "-Wl,-Bsymbolic")
+set (CMAKE_POSITION_INDEPENDENT_CODE ON)
+set (ONNX_PATH ${CONTRIB_ROOT_PATH})
+
+# Set platform specific variables
+if (PLATFORM_TYPE STREQUAL "ANDROID")
+    set (OpenCV_DIR ${CONTRIB_PATH}/native-${CONTRIB_PLATFORM}/opencv/build)
+    set (ONNX_SO_PATH ${CONTRIB_PATH}/native-${CONTRIB_PLATFORM}/onnx/build/Linux/Release/libonnxruntime.so)
+elseif (PLATFORM_TYPE STREQUAL "LINUX")
+    set (ONNX_SO_PATH ${CONTRIB_ROOT_PATH}/lib/onnxruntime/cpu/libonnxruntime.so)
+endif ()
+
+find_package (PkgConfig REQUIRED)
+list (APPEND PKG_CONFIG_EXECUTABLE "--static")
+
+list (APPEND CMAKE_FIND_ROOT_PATH ${CONTRIB_ROOT_PATH})
+set (CMAKE_FIND_ROOT_PATH_MODE_PACKAGE BOTH)
+list (APPEND CMAKE_PREFIX_PATH ${CONTRIB_ROOT_PATH})
+
+# Find required packages
+pkg_search_module (avformat REQUIRED IMPORTED_TARGET libavformat)
+pkg_search_module (avdevice REQUIRED IMPORTED_TARGET libavdevice)
+pkg_search_module (avfilter REQUIRED IMPORTED_TARGET libavfilter)
+pkg_search_module (avcodec REQUIRED IMPORTED_TARGET libavcodec)
+pkg_search_module (swresample REQUIRED IMPORTED_TARGET libswresample)
+pkg_search_module (swscale REQUIRED IMPORTED_TARGET libswscale)
+pkg_search_module (avutil REQUIRED IMPORTED_TARGET libavutil)
+
+find_package (OpenCV 4 REQUIRED)
+message ("OpenCV_LIBS: ${OpenCV_LIBS}")
+message ("OpenCV_INCLUDE: ${OpenCV_INCLUDE_DIRS}")
+
+add_definitions (-DMSGPACK_NO_BOOST)
+
+if (DEBUG)
+    set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -g -fsanitize=address -Wall -Wextra -Wno-unused-parameter")
+    add_definitions (-D__DEBUG__)
+else ()
+    set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -O3 -Wall -Wextra -Wno-unused-parameter")
+endif ()
+
+# Source files
+set (plugin_SRC
     main.cpp
+    VideoSubscriber.cpp
     pluginMediaHandler.cpp
     pluginProcessor.cpp
-    VideoSubscriber.cpp
+    ${PLUGINS_LIB}/common.cpp
     ${PLUGINS_LIB}/accel.cpp
     ${PLUGINS_LIB}/frameUtils.cpp
     ${PLUGINS_LIB}/frameFilter.cpp
 )
 
-set(plugin_HDR
-    VideoSubscriber.h
-    pluginMediaHandler.h
-    pluginProcessor.h
-    ${PLUGINS_LIB}/accel.h
-    ${PLUGINS_LIB}/frameScaler.h
-    ${PLUGINS_LIB}/frameUtils.h
-    ${PLUGINS_LIB}/pluglog.h
-    ${PLUGINS_LIB}/frameFilter.h
-)
-
 # Create shared library
-add_library(${ProjectName} SHARED ${plugin_SRC} ${plugin_HDR})
-
-# Find packages
-find_package(OpenCV REQUIRED)
-#onnxruntime is not supported by find_package yet, use https://medium.com/@massimilianoriva96/onnxruntime-integration-with-ubuntu-and-cmake-5d7af482136a
-find_package(onnxruntime REQUIRED)
-find_package(Python3 3.6 REQUIRED COMPONENTS Interpreter)
-
-list(APPEND EXTRA_LIBS ${OpenCV_LIBS} ${onnxruntime_LIBS})
-list(APPEND EXTRA_INCLUDES ${OpenCV_INCLUDE_DIRS} ${onnxruntime_INCLUDE_DIRS})
+add_library (${ProjectName} SHARED ${plugin_SRC})
 
 # Include directories
-target_include_directories(${ProjectName} PUBLIC
-    ${PROJECT_BINARY_DIR}
+target_include_directories (${ProjectName} PUBLIC
     ${PROJECT_SOURCE_DIR}
+    ${DAEMON}/src
+    ${CONTRIB_PATH}/${CONTRIB_PLATFORM}/include
+    ${CONTRIB_PATH}/${CONTRIB_PLATFORM}/include/opencv4
+    ${ONNX_PATH}/include/onnxruntime/session
+    ${ONNX_PATH}/include/onnxruntime/providers/cuda
     ${PLUGINS_LIB}
-    ${DAEMON_SRC}
-    ${CONTRIB_PATH}
-    ${CONTRIB_PATH}/build/fmt/include
-    ${CONTRIB_PATH}/build/opendht/include
-    ${CONTRIB_PATH}/build/msgpack-c/include
-    ${FFMPEG}/include
-    ${EXTRA_INCLUDES}
-    ${onnxruntime_INCLUDE_DIRS}/onnxruntime/include
-)
-
-# Link directories and libraries
-target_link_directories(${ProjectName} PUBLIC
-    ${CONTRIB_PATH}
-    ${CONTRIB_PATH}/build/fmt/msvc/Release
-    ${FFMPEG}/bin
 )
 
-target_link_libraries(${ProjectName} PUBLIC ${EXTRA_LIBS} ${onnxruntime_LIBRARY} swscale avutil )
-
-# Android-specific flags
-if(ANDROID)
-    set(CMAKE_ANDROID_ARCH_ABI arm64-v8a) # Set the desired ABI
-    set(CMAKE_ANDROID_STL_TYPE c++_shared) # Use C++ shared library
-    set(CMAKE_ANDROID_NDK_TOOLCHAIN_FILE ${CONTRIB_PATH}/build/cmake/android.toolchain.cmake)
-    set(CMAKE_ANDROID_STL_INCLUDE_DIR ${CONTRIB_PATH}/sysroot/usr/include)
-    set(CMAKE_ANDROID_STL_LIBRARIES ${CONTRIB_PATH}/sysroot/usr/lib)
-endif()
-
-if(CMAKE_CXX_FLAGS_DEBUG)
-    set(OUTPUT "${ProjectName}")
-    set(CLANG_OPTS "-g -fsanitize=address")
-    set(EXTRA_DEBUG_LIBRARIES "-lyaml-cpp")
-    set(EXTRA_DEFINES "-D__DEBUG__")
-else()
-    add_custom_command(
-        TARGET ${ProjectName}
-        PRE_BUILD
-        COMMAND ${Python3_EXECUTABLE} ${SDK_PATH}/jplManipulation.py --preassemble --plugin=${ProjectName}
-        COMMENT "Assembling Plugin files"
+if (PLATFORM_TYPE STREQUAL "ANDROID")
+    target_include_directories (${ProjectName} PUBLIC
+        ${ONNX_PATH}/include/onnxruntime/providers/nnapi
     )
-endif()
-
-add_custom_command(
-    TARGET ${ProjectName}
-    PRE_BUILD
-    COMMAND ${Python3_EXECUTABLE} ${SDK_PATH}/jplManipulation.py --preassemble --plugin=${ProjectName}
-    COMMENT "Assembling Plugin files"
+endif ()
+
+# Link directories
+link_directories (
+    ${CONTRIB_PATH}/${CONTRIB_PLATFORM}/lib
+    ${CONTRIB_PATH}/${CONTRIB_PLATFORM}/lib/opencv4/3rdparty
+    ${ONNX_PATH}/lib/onnxruntime/${ONNX_LIBS}
+    $ENV{CUDA_HOME}/lib64
 )
 
-# Copy shared library to jpl directory
-add_custom_command(
-    TARGET ${ProjectName}
-    POST_BUILD
-    COMMAND ${CMAKE_COMMAND} -E copy $<TARGET_FILE:${ProjectName}> ${PLUGIN_OUTPUT_DIR}
-    COMMENT "Copying output file to jpl directory"
+# Libraries to link
+set (LINK_LIBS
+    ${OpenCV_LIBS}
+    PkgConfig::avformat
+    PkgConfig::avdevice
+    PkgConfig::avfilter
+    PkgConfig::avcodec
+    PkgConfig::swresample
+    PkgConfig::swscale
+    PkgConfig::avutil
+    ${ONNX_SO_PATH}
 )
 
-add_custom_command(
-    TARGET ${ProjectName}
-    POST_BUILD
-    COMMAND ${CMAKE_COMMAND} -E copy ${PROJECT_SOURCE_DIR}/modelSRC/mModel.onnx ${JPL_DIRECTORY}/data/model/
-    COMMENT "Copying onnx model to jpl directory"
-)
+# Link libraries to the target
+target_link_libraries (${ProjectName} PUBLIC ${LINK_LIBS} )
 
-add_custom_command(
-    TARGET ${ProjectName}
-    POST_BUILD
-    COMMAND ${Python3_EXECUTABLE} ${SDK_PATH}/jplManipulation.py --assemble --plugin=${ProjectName}
-    COMMENT "Generating JPL archive"
+set_target_properties (${ProjectName} PROPERTIES
+    LIBRARY_OUTPUT_DIRECTORY "${PROJECT_BINARY_DIR}/jpl/lib/${PLATFORM}"
 )
+
+# JPL manipulation commands for copying runtime files and generating JPL archive
+if (PLATFORM_TYPE STREQUAL "ANDROID")
+    add_custom_command (
+        TARGET ${ProjectName}
+        POST_BUILD
+        COMMAND ${CMAKE_COMMAND} -E copy ${PROJECT_SOURCE_DIR}/modelSRC/mModel.onnx ${PROJECT_BINARY_DIR}/jpl/data/model/mModel.onnx
+        COMMAND ${CMAKE_COMMAND} -E copy ${PROJECT_SOURCE_DIR}/modelSRC/mModel.ort ${PROJECT_BINARY_DIR}/jpl/data/model/mModel.ort
+        COMMAND ${CMAKE_COMMAND} -E copy ${ONNX_SO_PATH} ${PROJECT_BINARY_DIR}/jpl/lib/${PLATFORM}/libonnxruntime.so
+        COMMENT "Copying runtime files"
+    )
+    add_custom_command (
+        TARGET ${ProjectName}
+        PRE_BUILD
+        COMMAND ${Python3_EXECUTABLE} ${SDK_PATH}/jplManipulation.py --preassemble --plugin=${ProjectName} --distribution=android
+        COMMENT "Assembling Plugin files"
+    )
+    add_custom_command (
+        TARGET ${ProjectName}
+        POST_BUILD
+        COMMAND ${Python3_EXECUTABLE} ${SDK_PATH}/jplManipulation.py --assemble --plugin=${ProjectName} --distribution=android
+        COMMENT "Generating JPL archive"
+    )
+elseif (PLATFORM_TYPE STREQUAL "LINUX")
+    add_custom_command (
+        TARGET ${ProjectName}
+        POST_BUILD
+        COMMAND ${CMAKE_COMMAND} -E copy ${PROJECT_SOURCE_DIR}/modelSRC/mModel.onnx ${PROJECT_BINARY_DIR}/jpl/data/model/mModel.onnx
+        COMMAND ${CMAKE_COMMAND} -E copy ${ONNX_SO_PATH} ${PROJECT_BINARY_DIR}/jpl/lib/${PLATFORM}/libonnxruntime.so.1.16.3
+        COMMENT "Copying runtime files"
+    )
+    add_custom_command (
+        TARGET ${ProjectName}
+        PRE_BUILD
+        COMMAND ${Python3_EXECUTABLE} ${SDK_PATH}/jplManipulation.py --preassemble --plugin=${ProjectName} --distribution=x86_64-linux-gnu
+        COMMENT "Assembling Plugin files"
+    )
+    add_custom_command (
+        TARGET ${ProjectName}
+        POST_BUILD
+        COMMAND ${Python3_EXECUTABLE} ${SDK_PATH}/jplManipulation.py --assemble --plugin=${ProjectName} --distribution=x86_64-linux-gnu
+        COMMENT "Generating JPL archive"
+    )
+endif ()
diff --git a/GreenScreen/build.md b/GreenScreen/build.md
index e89c2b1..60396cf 100644
--- a/GreenScreen/build.md
+++ b/GreenScreen/build.md
@@ -1,23 +1,212 @@
-# How to build the GreenScreen plugin
+# Jami Plugin Build Process
 
-## Libraries
-You will need the opencv library that you can build with : https://docs.jami.net/fr/jami-extensions/how-to-build.html#opencv-4-1-1
+This document outlines the steps to build a Jami plugin, specifically the `GreenScreen` plugin.
+For signing it, please reffer to `jami-plugins/sign.md`
 
-You will need the ONNXRuntime library with cmake integration (tu use find_package(onnxruntime)) that you can find here : https://medium.com/@massimilianoriva96/onnxruntime-integration-with-ubuntu-and-cmake-5d7af482136a
+You can build it for Linux architectures (`x86_64-linux-gnu`) and also for Android architectures (`arm64-v8a`, `armeabi-v7a`, `x86_64`). The example provided uses `arm64-v8a`, but feel free to replace it with the desired architecture.
 
-## JPL archive
-Then, go to the GreenScreen folder and run
+## Requirements:
+
+- `git`
+- `docker`
+
+Building the plugin directly on your computer is not recommended for compatibility reasons.
+
+## Step 1: Clone Jami Repositories
+
+Clone the Jami plugin and daemon repositories:
+
+```bash
+git clone https://review.jami.net/jami-plugins
+cd jami-plugins
+```
+
+For the daemon:
+
+```bash
+git submodule update --init --recursive
+```
+
+The structure should look like this:
+
+```
+|-jami-plugins
+	|-GreenScreen
+		|-build.md
+		|-CMakeLists.txt
+		|-data
+		|-modelSRC
+			|-mModel.onnx
+			|-mModel.ort
+		|-*.cpp
+		|-*.h
+	|-daemon
+		|-contrib
+	|-SDK
+		|jplManipulation.py
+	|-docker
+		|-Dockerfile_ubuntu_20.04
+		|-Dockerfile_android
+	|-sign.md
+```
+
+## Step 2: Build Docker Image
+
+Build the Docker image using the provided Dockerfile:
+
+### Linux:
+```bash
+docker build -f docker/Dockerfile_ubuntu_20.04 -t <DockerNameToReplace> .
+```
+
+### Android:
+```bash
+docker build -f docker/Dockerfile_android -t <DockerNameToReplace> .
+```
+
+## Step 3: Run Docker and Compile Dependencies
+
+Run the following Docker command to start building dependencies:
+> The dependencies are the libraries you will include in your plugin
+
+### Linux:
+```bash
+docker run -t --rm \
+    -v $(pwd):/root/jami/:rw \
+    -w /root/ \
+    -e BATCH_MODE=1 \
+    <DockerNameToReplace> /bin/bash -c "
+    cd ./jami/daemon/contrib
+    mkdir -p native
+    cd native
+    ../bootstrap --disable-x264 --enable-ffmpeg --disable-dhtnet \
+                 --disable-webrtc-audio-processing --disable-argon2 \
+                 --disable-asio --enable-fmt --disable-gcrypt --disable-gmp \
+                 --disable-gnutls --disable-gpg-error --disable-gsm \
+                 --disable-http_parser --disable-jack --disable-jsoncpp \
+                 --disable-libarchive --disable-libressl --enable-msgpack \
+                 --disable-natpmp --disable-nettle --enable-opencv --enable-opendht \
+                 --disable-pjproject --disable-portaudio --disable-restinio \
+                 --disable-secp256k1 --disable-speex --disable-speexdsp --disable-upnp \
+                 --disable-uuid --disable-yaml-cpp --enable-onnx --enable-opus && make list
+    make fetch opencv opencv_contrib
+    make -j24
+"
+```
+
+### Android:
+```bash
+docker run -t --rm \
+    -v $(pwd):/home/gradle/plugins:rw \
+    -w /home/gradle \
+    -e BATCH_MODE=1 \
+    <DockerNameToReplace> /bin/bash -c "
+    cd ./plugins/contrib
+    ANDROID_ABI='arm64-v8a' sh build-dependencies.sh
+    "
+```
+> **Note:** The build process for the `contrib` dependencies (particularly ONNX) may take a long time (~20 minutes).
+
+## Step 4: Build the Plugin
+
+Use the following command to build the `GreenScreen` plugin:
+
+### Linux:
+```bash
+docker run -t --rm \
+    -v $(pwd):/root/jami/:rw \
+    -w /root/ \
+    -e BATCH_MODE=1 \
+    <DockerNameToReplace> /bin/bash -c "
+    cd jami
+    PLATFORM_TYPE="LINUX" python3 build-plugin.py --projects='GreenScreen' --distribution=ubuntu
+"
+```
+> **Note:** If OpenCV fails to build due to a missing `libade.a`, create an empty file to bypass the issue:
+
+```bash
+sudo touch ./daemon/contrib/x86_64-linux-gnu/lib/opencv4/3rdparty/libade.a
+```
+
+### Android:
+```bash
+docker run -t --rm \
+    -v $(pwd):/home/gradle/plugins:rw \
+    -w /home/gradle \
+    -e BATCH_MODE=1 \
+    <DockerNameToReplace> /bin/bash -c "
+    export DAEMON=/home/gradle/plugins
+    cd ./plugins
+    PLATFORM_TYPE="ANDROID" ANDROID_ABI="arm64-v8a" python3 build-plugin.py --projects=GreenScreen --distribution=android
+    "
+```
+
+## Step 5: Change Ownership of the Built Plugin
+
+The default user in the Docker container who built the plugin is `root`. To manipulate the plugin, change the ownership of the output files to the current user:
+
+### Linux:
+```bash
+sudo chown ${USER}:${USER} build/
+sudo chown ${USER}:${USER} build/x86_64-linux-gnu/
+sudo chown ${USER}:${USER} build/x86_64-linux-gnu/GreenScreen.jpl
+```
+
+### Android:
 ```bash
-mkdir build-local
-cd build-local
-cmake ..
-cmake --build .
+sudo chown ${USER}:${USER} build/
+sudo chown ${USER}:${USER} build/android/
+sudo chown ${USER}:${USER} build/android/GreenScreen.jpl
 ```
 
-Then you will find your GreenScreen.jpl in jami-plugins/build/\<your distribution\>/
-It's the archive of your new jpl folder in build-local
+# You have now successfully built your plugin!
+## To add it to Jami, you now need to sign it by referring to `jami-plugins/sign.md`.
+
+## Additional documentation:
+
+### For a better understanding of plugins, here is what you should know:
+
+The plugins are designed to be compatible for everyone. This is challenging because there are many different systems, and each user may have different libraries installed.
+
+### About plugin building:
+The file used for the compilation is the `CMakelists.txt` in GreenScreen.
+It assembles the files, create the library and call the SDK scripts to manipulate the jpl.
+
+### About JPL Archive:
+In your folder `build/<distribution>`, you have the JPL archive, the Jami Plugin format.
+
+You can extract it like a zip, or view it before compression in your folder `jami-plugins/GreenScreen/build-local/jpl`.
+Inside, you'll find your libraries in `jpl/lib/<arch>`.
+You will find the `libGreenScreen.so`, and as in every plugin, you'll have `lib<PluginName>.so`.
+In GreenScreen, you will also find `libonnxruntime.so`, the ONNX library needed to use ONNX Runtime.
+
+### About Libraries:
+
+Libraries are built using `GreenScreen/CMakeLists.txt`.
+
+If you want your plugin to work on other computers, you need to understand that the plugin library (`libGreenScreen.so`) contains every needed library, linking them dynamically for system libraries and statically for additional libraries like OpenCV.
+
+System libraries must be dynamically linked because the user is supposed to have them installed, and statically linking them might cause compatibility issues.
+
+However, users won’t have every additional library at the required version, so you need to include the exact version in your plugin by statically linking it.
+
+Some useful commands:
+- See the linked shared libraries with `ldd libGreenScreen.so`.
+  > Helps verify that every dynamic library is found on the system.
+  > However, you can't see which library is statically linked, but you can verify if a symbol is defined.
+
+- See symbols in the library: `nm libGreenScreen.so | grep <YourSymbol>`.
+  > Helps with missing symbols during loading in Jami. "U" means undefined, and "T" means they are in the text section. See `man nm` for details.
+
+- Symbols can be hard to read. You can demangle them with `c++filt <YourSymbol>`.
+  > The symbols represent the low-level names of the functions.
+
+### About plugin's code
+
+The plugin is mainly in c++, located in the `jami-plugins/GreenScreen` folder.
+The media handler file is used to interact with jami's API (chat, audio and video).
+> e.g. receiving the frames of the video stream before transformation and sending the transformed frames.
 
-## Sign it
+The media subscriber file is used to modify the object received.
+> e.g. draw a mask over the background using opencv
 
-You still need to sign it in order to add it into jami
-Find documentation about it in jami-plugins/sign.md
diff --git a/GreenScreen/data/preferences.json b/GreenScreen/data/preferences.json
index ef1a50b..af038f7 100644
--- a/GreenScreen/data/preferences.json
+++ b/GreenScreen/data/preferences.json
@@ -8,6 +8,14 @@
         "scope": "plugin,Foreground Segmentation",
         "dependsOn": "!blur"
     },
+    {
+        "type": "Switch",
+        "key": "acceleration",
+        "title": "{{acceleration_title}}",
+        "summary": "{{acceleration_summary}}",
+        "defaultValue": "1",
+        "scope": "plugin"
+    },
     {
         "type": "Switch",
         "key": "blur",
diff --git a/SDK/certificate_requirements.txt b/SDK/certificate_requirements.txt
index 93e3307..3dbe2e9 100644
--- a/SDK/certificate_requirements.txt
+++ b/SDK/certificate_requirements.txt
@@ -4,3 +4,4 @@ fs==2.4.12
 pyOpenSSL==23.2.0
 msgpack==1.0.5
 zipp==1.0.0
+requests==2.31.0
diff --git a/SDK/jplManipulation.py b/SDK/jplManipulation.py
old mode 100644
new mode 100755
diff --git a/build-plugin.py b/build-plugin.py
index f9d8275..e4d932d 100755
--- a/build-plugin.py
+++ b/build-plugin.py
@@ -36,7 +36,7 @@ IOS_DISTRIBUTION_NAME = "ios"
 OSX_DISTRIBUTION_NAME = "osx"
 ANDROID_DISTRIBUTION_NAME = "android"
 WIN32_DISTRIBUTION_NAME = "win32"
-UBUNTU_DISTRIBUTION_NAME = "ubuntu"
+UNIX_DISTRIBUTION_NAME = "unix"
 
 def parse():
     parser = argparse.ArgumentParser(description='Builds Plugins projects')
@@ -75,7 +75,7 @@ def validate_args(parsed_args):
 
     # Filter unsupported distributions.
     supported_distros = [
-        ANDROID_DISTRIBUTION_NAME, UBUNTU_DISTRIBUTION_NAME,
+        ANDROID_DISTRIBUTION_NAME, UNIX_DISTRIBUTION_NAME,
         WIN32_DISTRIBUTION_NAME, OSX_DISTRIBUTION_NAME
     ]
 
@@ -119,7 +119,7 @@ def choose_distribution():
     return 'Unknown'
 
 
-def buildPlugin(pluginPath):
+def buildPlugin(pluginPath, distribution, arch=None):
     # Change the current working directory to pluginPath
     os.chdir(pluginPath)
 
@@ -131,7 +131,12 @@ def buildPlugin(pluginPath):
     os.chdir('build-local')
 
     # Prepare build-local
-    os.system('cmake ..')
+    if distribution == ANDROID_DISTRIBUTION_NAME:
+        abi=os.environ["ANDROID_ABI"]
+        ndk=os.environ["ANDROID_NDK"]
+        os.system(f'cmake .. -DCMAKE_TOOLCHAIN_FILE={ndk}/build/cmake/android.toolchain.cmake -DANDROID_PLATFORM=24 -DANDROID_ABI={abi}')
+    else:
+        os.system(f'cmake ..')
 
     # Run the cmake build command
     os.system('cmake --build .')
@@ -142,7 +147,7 @@ def main():
 
     for i, plugin in enumerate(args.projects):
         os.chdir(currentDir + "/" + plugin)
-        buildPlugin(currentDir + "/" + plugin)
+        buildPlugin(currentDir + "/" + plugin, args.distribution)
 
 if __name__ == "__main__":
     main()
diff --git a/contrib/build-dependencies.sh b/contrib/build-dependencies.sh
index 74a7f0b..3f9065a 100755
--- a/contrib/build-dependencies.sh
+++ b/contrib/build-dependencies.sh
@@ -116,4 +116,7 @@ cd ${CONTRIB_DIR}
 make list
 make fetch
 export PATH="$PATH:$CONTRIB_SYSROOT/bin"
-make $MAKEFLAGS .ffmpeg .fmt .opencv .onnx .freetype
+make $MAKEFLAGS .ffmpeg .fmt .msgpack .opencv .opendht .onnx .opus .freetype
+
+echo "Contribs built: .ffmpeg .fmt .msgpack .opencv .opendht .onnx .opus .freetype"
+echo "\033[1;32mContribs built successfully \033[1;0m"
diff --git a/docker/Dockerfile_android b/docker/Dockerfile_android
new file mode 100644
index 0000000..1cb522d
--- /dev/null
+++ b/docker/Dockerfile_android
@@ -0,0 +1,91 @@
+FROM gradle:jdk17-jammy
+
+ENV LANG en_US.utf8
+ENV LC_ALL en_US.utf8
+ENV DEBIAN_FRONTEND noninteractive
+
+# Script dependencies
+RUN apt-get update && apt-get install -y --no-install-recommends \
+    apt-transport-https \
+    ca-certificates \
+    gnupg \
+    software-properties-common \
+    wget
+
+# Jami build dependencies
+RUN apt-get update && apt-get install -y --no-install-recommends \
+    asciidoc \
+    autoconf \
+    autogen \
+    automake \
+    autopoint \
+    bc \
+    bison \
+    build-essential \
+    bzip2 \
+    cmake \
+    curl \
+    doxygen \
+    gettext \
+    git \
+    lib32stdc++6 \
+    lib32z1 \
+    libpcre2-dev \
+    libpcre3 \
+    libpcre3-dev \
+    libtool \
+    locales \
+    m4 \
+    nasm \
+    ninja-build \
+    pkg-config \
+    python-is-python3 \
+    ruby \
+    ruby-dev \
+    ssh \
+    unzip \
+    yasm \
+    zip \
+    && locale-gen $LANG $LC_ALL && update-locale $LANG $LC_ALL
+
+# CMake 3.26
+ADD contrib/install-cmake.sh /opt/install-cmake.sh
+RUN /opt/install-cmake.sh
+
+# Swig
+#RUN wget -O /tmp/swig.tar.gz https://github.com/swig/swig/archive/v4.2.1.tar.gz && \
+#	tar xzf  /tmp/swig.tar.gz -C /opt && \
+#	cd /opt/swig-4.2.1/ && ./autogen.sh && ./configure && make && make install && \
+#	cd .. && rm -rf /opt/swig-4.2.1 /tmp/swig.tar.gz
+
+# Install Fastlane
+RUN gem install fastlane -NV
+
+# Install Commandlinetools.
+ENV ANDROID_SDK_ROOT=/opt/android
+ARG ANDROID_CMD="commandlinetools-linux-11076708_latest.zip"
+RUN wget https://dl.google.com/android/repository/${ANDROID_CMD} -P /tmp && \
+    unzip -d $ANDROID_SDK_ROOT /tmp/$ANDROID_CMD && \
+    mkdir -p $ANDROID_SDK_ROOT/cmdline-tools/tools && cd $ANDROID_SDK_ROOT/cmdline-tools && mv NOTICE.txt source.properties bin lib tools/ && \
+    cd $ANDROID_SDK_ROOT/cmdline-tools/tools && ls
+ENV PATH "$PATH:$ANDROID_SDK_ROOT/cmdline-tools/tools:$ANDROID_SDK_ROOT/cmdline-tools/tools/bin:$ANDROID_SDK_ROOT/emulator:$ANDROID_SDK_ROOT/tools/bin:$ANDROID_SDK_ROOT/platform-tools:$ANDROID_SDK_ROOT/build-tools/${BUILD_TOOLS}"
+
+# Install android SDK libraries, NDK.
+ARG API_LEVEL="34"
+ARG BUILD_TOOLS="34.0.0"
+RUN sdkmanager --update
+RUN yes Y | sdkmanager --licenses
+RUN sdkmanager --channel=1 --no_https "platforms;android-${API_LEVEL}" \
+    'extras;android;m2repository' \
+    'extras;google;m2repository' \
+    'ndk;26.3.11579264' \
+    "build-tools;${BUILD_TOOLS}"
+ENV ANDROID_SDK=${ANDROID_SDK_ROOT}
+ENV ANDROID_NDK=${ANDROID_SDK_ROOT}/ndk/26.3.11579264
+
+# Define environment variables.
+ENV JAVA_HOME=/opt/java/openjdk/
+ENV ANDROID_HOME=/opt/android
+ENV PATH="$PATH:/opt/java/openjdk/bin:$ANDROID_SDK_ROOT/cmdline-tools/tools:$ANDROID_SDK_ROOT/cmdline-tools/tools/bin:$ANDROID_SDK_ROOT/emulator:$ANDROID_SDK_ROOT/tools/bin:$ANDROID_SDK_ROOT/platform-tools:$ANDROID_SDK_ROOT/build-tools/${BUILD_TOOLS}"
+
+CMD [ "/bin/bash" ]
\ No newline at end of file
diff --git a/docker/Dockerfile_ubuntu_20.04 b/docker/Dockerfile_ubuntu_20.04
index 16cf4ed..488cd48 100644
--- a/docker/Dockerfile_ubuntu_20.04
+++ b/docker/Dockerfile_ubuntu_20.04
@@ -1,6 +1,8 @@
 FROM ubuntu:20.04
 
+ENV DISABLE_PIPEWIRE=true
 ENV DEBIAN_FRONTEND noninteractive
+ENV WITH_FREETYPE=1
 
 # Speed up mk-build-deps
 RUN apt-get clean && \
@@ -30,7 +32,7 @@ RUN apt-get clean && \
         libcanberra-gtk3-dev \
         libclutter-gtk-1.0-dev \
         libclutter-1.0-dev \
-        libfreetype-dev \
+        libfreetype6-dev \
         libglib2.0-dev \
         libgtk-3-dev \
         libnotify-dev \
@@ -53,11 +55,6 @@ RUN apt-get clean && \
         libspeex-dev \
         libspeexdsp-dev \
         uuid-dev \
-        libavcodec-dev \
-        libavutil-dev \
-        libavformat-dev \
-        libswscale-dev \
-        libavdevice-dev \
         libopus-dev \
         libudev-dev \
         libgsm1-dev \
@@ -78,18 +75,15 @@ RUN apt-get clean && \
         lcov gcovr \
         libxcb-shape0-dev \
         ninja-build \
-        libsystemd-dev
-
-ENV DISABLE_PIPEWIRE=true
-RUN apt-get install -y python3 python3-pip python3-setuptools \
-                       python3-wheel
-
-RUN ls -la /usr/include/c++/8/charconv
+        libsystemd-dev \
+        python3 \
+        python3-pip \
+        python3-setuptools \
+        python3-wheel
 
 # CMake 3.26
 ADD contrib/install-cmake.sh /opt/install-cmake.sh
 RUN /opt/install-cmake.sh
 
 RUN chown 1001:1001 /root
-ENV WITH_FREETYPE=1
 WORKDIR /root
diff --git a/sign.md b/sign.md
index ae2bafe..4f4ed9f 100644
--- a/sign.md
+++ b/sign.md
@@ -1,8 +1,9 @@
+
 # Certifying and Adding Your Plugin to Jami
 
 To add your plugin built on Jami, you need to certify it by signing it with keys and certificates.
 
-First, you will generate a unique developer key and certificate, which will be used to create a certificate for each plugin. Then, you will sign your plugin archive (.jpl) using the plugin’s certificate key.
+First, you will generate a unique developer key and certificate, which will be used to create a certificate for each plugin. Then, you will sign your jami plugin archive (.jpl) using the plugin’s certificate key.
 
 After that, you will be able to add your signed plugin to Jami.
 
@@ -20,7 +21,6 @@ Install the necessary dependencies in a Python environment:
 cd jami-plugins/SDK
 pip install -r requirements.txt
 pip install -r certificate_requirements.txt
-pip install requests
 ```
 
 ## Create the Developer Key and Certificate
@@ -52,7 +52,7 @@ openssl x509 -in ../certificate/<CertificateName.crt> -text -noout
 Sign your plugin archive using the created certificate:
 
 ```bash
-python3 ./certKey.py --plugin sign --issuer ../certificate/<YourPlugin> --path ../build/<your distribution>/<YourPlugin.jpl> ../build/<your distribution>/signed/<YourPluginSigned>
+python3 ./certKey.py --plugin sign --issuer ../certificate/<YourPlugin> --path ../build/<your distribution>/<YourPlugin.jpl> ../build/<YourDistribution>/signed/<YourPluginSigned>
 ```
 
 ## Complete example with developer=Alexandre, plugin=AudioFilter, distribution=x86_64-linux-gnu:
@@ -67,13 +67,15 @@ python3 ./certKey.py --plugin sign --issuer ../certificate/AudioFilter --path ..
 
 ## Display the Signed Files
 
-Verify that the signed file is generated correctly:
+
+Verify that the signed archive is generated correctly:
 
 ```bash
-ls ../build/<your distribution>/signed
+ls ../build/<YourDistribution>/signed
 ```
 
 ## Add Your Plugin to Jami
 
 You can now add your signed `.jpl` archive to Jami.
 
+>**Note:** On Android, the application verifies that your plugin is not self-signed but signed by the root SFL store CA. To disable this verification, you can set `force=true` in `JamiPluginManager::installPlugin` in `daemon/src/plugin/jamipluginmanager.cpp`. This will bypass the validity check but you still need to sign it.
-- 
GitLab