diff --git a/README.md b/README.md
index c35af57..a1f8b0e 100644
--- a/README.md
+++ b/README.md
@@ -21,6 +21,8 @@
- [Why is iVSR needed](#12-why-is-ivsr-needed)
- [iVSR Components](#13-ivsr-components)
- [Capabilities of iVSR](#14-capabilities-of-ivsr)
+ - [Video Super Resolution (VSR)](#141-video-super-resolution-vsr)
+ - [Smart Video Processing (SVP)](#142-smart-video-processing-svp)
2. [Setup iVSR env on linux](#2-setup-ivsr-env-on-linux)
- [Install GPU kernel packages(Optional)](#21-optional-install-gpu-kernel-packages)
- [Install dependencies and build iVSR manually](#22-install-dependencies-and-build-ivsr-manually)
@@ -60,7 +62,7 @@ For a detailed introduction to the iVSR SDK API, please refer to [this introduct
We've also included a `vsr_sample` as a demonstration of its usage.
In order to support the widely-used media processing solution FFmpeg, we've provided an iVSR SDK plugin to simplify integration.
-This plugin is integrated into FFmpeg's `dnn_processing` filter in the [FFmpeg documentation](https://ffmpeg.org/ffmpeg-filters.html#dnn_005fprocessing-1) in the libavfilter library, serving as a new `ivsr` backend to this filter. Please note that the patches provided in this project are specifically for FFmpeg n7.1.
+This plugin is integrated into FFmpeg's `dnn_processing` filter in the [FFmpeg documentation](https://ffmpeg.org/ffmpeg-filters.html#dnn_005fprocessing-1) in the libavfilter library, serving as a new `ivsr` backend to this filter. The patches provided in this project target **FFmpeg n8.1**.
### 1.3.3 OpenVINO patches and extension
In [this folder](./ivsr_ov/based_on_openvino_2022.3/patches), you'll find patches for OpenVINO that enable the Enhanced BasicVSR model. These patches utilize OpenVINO's [Custom OpenVINO™ Operations](https://docs.openvino.ai/2024/documentation/openvino-extensibility/custom-openvino-operations.html) feature, which allows users to support models with custom operations not inherently supported by OpenVINO.
@@ -129,7 +131,7 @@ The software was validated on:
- Host OS: Linux-based OS (Ubuntu 22.04 or Rocky Linux 9.3)
- Docker-based OS: Ubuntu 22.04 or Rocky Linux 9.3
- OpenVINO: [2022.3](https://github.com/openvinotoolkit/openvino/tree/2022.3.0), [2023.2](https://github.com/openvinotoolkit/openvino/tree/2023.2.0), or [2024.5](https://github.com/openvinotoolkit/openvino/tree/2024.5.0)
-- FFmpeg: [n7.1](https://github.com/FFmpeg/FFmpeg/tree/n7.1)
+- FFmpeg: [n8.1](https://github.com/FFmpeg/FFmpeg/tree/n8.1)
Building iVSR requires the installation of the GPU driver (optional), OpenCV, OpenVINO, and FFmpeg.
We provide **three** ways to install requirements and build iVSR SDK & iVSR FFmpeg plugin:
diff --git a/build.sh b/build.sh
index d52e2ba..ac149fc 100755
--- a/build.sh
+++ b/build.sh
@@ -6,11 +6,11 @@
set -e
base_dir=$(pwd)
-ov_version=2022.3
+ov_version=2026.1
# Function to display usage information
usage() {
- echo "Usage: $0 --ov_version [2022.3|2023.2|2024.5]"
+ echo "Usage: $0 --ov_version [2022.3|2024.5|2026.1]"
exit 1
}
@@ -18,8 +18,8 @@ prepare_dependencies() {
echo "Preparing dependencies..."
sudo apt-get install -y --no-install-recommends \
curl ca-certificates gpg-agent software-properties-common
-
- sudo apt-get install -y --no-install-recommends --fix-missing \
+
+ sudo apt-get install -y --no-install-recommends \
autoconf \
automake \
build-essential \
@@ -52,10 +52,14 @@ install_openvino_from_source() {
git submodule update --init --recursive
## applying ov22.3 patches to enable Enhanced BasicVSR model
- for patch_file in $(find ../patches -iname "*.patch" | sort -n);do
- echo "Applying: ${patch_file}"
- git am --whitespace=fix ${patch_file}
- done
+ if git tag --points-at HEAD 2>/dev/null | grep -q "^${ov_branch}$"; then
+ for patch_file in $(find ../patches -iname "*.patch" | sort -n);do
+ echo "Applying: ${patch_file}"
+ git am --whitespace=fix ${patch_file}
+ done
+ else
+ echo "OpenVINO patches already applied, skipping..."
+ fi
mkdir -p build && cd build && \
cmake \
@@ -95,8 +99,10 @@ build_install_ivsr_sdk() {
ivsr_sdk_dir=${base_dir}/ivsr_sdk/
cd ${ivsr_sdk_dir}
+ rm -rf build
mkdir -p build && cd build && cmake \
-DENABLE_LOG=OFF -DENABLE_PERF=OFF -DENABLE_THREADPROCESS=ON \
+ -DENABLE_IRGUARD=${enable_irguard} \
-DCMAKE_BUILD_TYPE=Release .. && \
make -j $(nproc --all)
sudo make install
@@ -109,20 +115,51 @@ build_ffmpeg() {
DEBIAN_FRONTEND=noninteractive sudo apt-get install -y --no-install-recommends \
ca-certificates tar g++ wget pkg-config nasm yasm libglib2.0-dev flex bison gobject-introspection libgirepository1.0-dev \
python3-dev libx11-dev libxv-dev libxt-dev libasound2-dev libpango1.0-dev libtheora-dev libvisual-0.4-dev libgl1-mesa-dev \
- libcurl4-gnutls-dev librtmp-dev libx264-dev libx265-dev libde265-dev libva-dev libtbb-dev
-
- # Add commands to build FFMPEG from source
+ libcurl4-gnutls-dev librtmp-dev libx264-dev libx265-dev libde265-dev libva-dev libtbb-dev \
+ patchutils
+
ffmpeg_dir=$base_dir/ivsr_ffmpeg_plugin/ffmpeg
+ ffmpeg_tag=n8.1
ffmpeg_repo=https://github.com/FFmpeg/FFmpeg.git
- if [ ! -d "${ffmpeg_dir}" ]; then
- git clone --depth 1 --branch n7.1 ${ffmpeg_repo} ${ffmpeg_dir}
+ if [ ! -d "${ffmpeg_dir}/.git" ]; then
+ git clone --depth 1 --branch ${ffmpeg_tag} ${ffmpeg_repo} ${ffmpeg_dir}
git config --global --add safe.directory ${ffmpeg_dir}
fi
- # Apply patches
- cd ${ffmpeg_dir} && cp -rf $base_dir/ivsr_ffmpeg_plugin/patches/*.patch .
- git am --whitespace=fix *.patch
+ cd ${ffmpeg_dir}
+ git am --abort 2>/dev/null || true
+ # Ensure the target tag is locally reachable (handles a prior clone at a different tag)
+ if ! git rev-parse "${ffmpeg_tag}" >/dev/null 2>&1; then
+ git fetch --depth 1 origin "refs/tags/${ffmpeg_tag}:refs/tags/${ffmpeg_tag}"
+ fi
+ git checkout -f "${ffmpeg_tag}"
+
+ # ---------------------------------------------------------------
+ # Apply all iVSR patches for n8.1.
+ # Patch 0001: strip configure, dnn_interface.c, and swscale_unscaled.c
+ # hunks — those three files are fully covered by patch 0004.
+ # Patch 0004: n8.1-native patch for configure, dnn_interface.c and
+ # swscale_unscaled.c (exact n8.1 context; no sed required).
+ # Patches 0002/0003: fix-ups for dnn_backend_ivsr.c (added by 0001).
+ # ---------------------------------------------------------------
+ rm -f *.patch
+ cp "$base_dir/ivsr_ffmpeg_plugin/patches/"*.patch .
+
+ filterdiff \
+ -x '*/configure' \
+ -x '*/dnn_interface.c' \
+ -x '*/swscale_unscaled.c' \
+ 0001-*.patch | \
+ git apply --3way --ignore-whitespace -
+
+ git apply --ignore-whitespace 0004-*.patch
+
+ # Stage new files added by 0001 so 3-way merge can resolve them
+ git add -A
+
+ git apply --3way --whitespace=fix 0002-*.patch
+ git apply --3way --whitespace=fix 0003-*.patch
./configure \
--enable-gpl \
@@ -143,14 +180,33 @@ build_ffmpeg() {
install_openvino_from_apt() {
echo "Installing OpenVINO from apt..."
local version=$1
+ local key_url=https://apt.repos.intel.com/intel-gpg-keys/GPG-PUB-KEY-INTEL-SW-PRODUCTS.PUB
+ local keyring=/etc/apt/trusted.gpg.d/intel.gpg
- wget -qO - https://apt.repos.intel.com/intel-gpg-keys/GPG-PUB-KEY-INTEL-SW-PRODUCTS.PUB | sudo apt-key add -
+ # Download GPG key with timeout; fail loudly if it doesn't work
+ if ! wget --timeout=30 --tries=3 -O /tmp/intel-sw-products.pub "${key_url}"; then
+ echo "ERROR: Failed to download Intel GPG key from ${key_url}" >&2
+ exit 1
+ fi
+ sudo gpg --output "${keyring}" --dearmor /tmp/intel-sw-products.pub
+ rm -f /tmp/intel-sw-products.pub
- echo "deb https://apt.repos.intel.com/openvino/2023 ubuntu22 main" | sudo tee /etc/apt/sources.list.d/intel-openvino-2023.list
- echo "deb https://apt.repos.intel.com/openvino/2024 ubuntu22 main" | sudo tee /etc/apt/sources.list.d/intel-openvino-2024.list
+ if [ ! -s "${keyring}" ]; then
+ echo "ERROR: Intel GPG keyring is empty after dearmor step." >&2
+ exit 1
+ fi
+
+ # Unified repo (all versions from 2024 onwards live here; no year in path)
+ # Detect Ubuntu codename suffix expected by the repo (ubuntu22 / ubuntu24)
+ local ubuntu_major
+ ubuntu_major=$(lsb_release -rs | cut -d. -f1)
+ local dist="ubuntu${ubuntu_major}"
+
+ echo "deb https://apt.repos.intel.com/openvino ${dist} main" \
+ | sudo tee /etc/apt/sources.list.d/intel-openvino.list
sudo -E apt-get update && \
- DEBIAN_FRONTEND=noninteractive sudo -E apt-get install -y openvino-$version.0
+ DEBIAN_FRONTEND=noninteractive sudo -E apt-get install -y openvino-${version}.0
}
main() {
@@ -165,6 +221,12 @@ main() {
shift
done
+ # irguard model protection is required for OV 2022.3 and 2024.5
+ case "${ov_version}" in
+ 2022.3|2024.5) enable_irguard=ON ;;
+ *) enable_irguard=OFF ;;
+ esac
+
prepare_dependencies
config_git_users
if [ "$ov_version" = "2022.3" ]; then
diff --git a/docs/docker_image_build.md b/docs/docker_image_build.md
index 9d17cef..4c38108 100644
--- a/docs/docker_image_build.md
+++ b/docs/docker_image_build.md
@@ -20,15 +20,44 @@ sudo systemctl restart docker
```bash
cd ./ivsr_ffmpeg_plugin
-./build_docker.sh --enable_ov_patch [true|false] --ov_version [2022.3|2023.2|2024.5|2024.5s] --os_version [rockylinux9|ubuntu22]
+./build_docker.sh --enable_ov_patch [true|false] --ov_version [2022.3|2023.2|2024.5|2024.5s|2026.1] --os_version [rockylinux9|ubuntu22]
```
-- `enable_ov_patch`: Set as `true` or `false` to enable or disable the application of OpenVINO 2022.3 patches, which are needed to support the Enhanced BasicVSR model.
-- `ov_version`: Set the OpenVINO version to `2022.3`, `2023.2`, `2024.5`, or `2024.5s`. These versions will be built and installed. The `2024.5s` version means installing OpenVINO 2024.5 via apt or yum, not building and installing from source code. iVSR currently supports OpenVINO 2022.3, 2023.2, and 2024.5. However, the patches to enable the Enhanced BasicVSR model are only for OpenVINO 2022.3.
-- `os_version`: Set OS version of Docker image to `ubuntu22` (Ubuntu 22.04) or `rockylinux9` (Rocky Linux 9.3) to build docker image based on specific OS.
-If the docker image builds successfully, you can see a docker image named `ffmpeg_ivsr_sdk_${os_version}_ov${ov_version}` such as `ffmpeg_ivsr_sdk_ubuntu22_ov2022.3` or `ffmpeg_ivsr_sdk_rockylinux9_ov2022.3` in the output of `docker image ls`.
+- `enable_ov_patch`: Set to `true` or `false` to enable or disable OpenVINO 2022.3 patches, which are needed to support the Enhanced BasicVSR model. Ignored for all versions other than `2022.3`.
+- `ov_version`: OpenVINO version to install. `2022.3`, `2023.2`, and `2024.5` are built from source; `2024.5s` and `2026.1` install via apt. The patches to enable the Enhanced BasicVSR model are only available for `2022.3`.
+- `os_version`: Base OS — `ubuntu22` (Ubuntu 22.04) or `rockylinux9` (Rocky Linux 9.3).
-### 4. Start Docker Container
+If the docker image builds successfully, you can see a docker image named `ffmpeg_ivsr_sdk_${os_version}_ov${ov_version}` in the output of `docker image ls`:
+
+```bash
+docker image ls | grep ffmpeg_ivsr_sdk
+```
+
+For example:
+
+```
+ffmpeg_ivsr_sdk_ubuntu22_ov2026.1 latest ...
+ffmpeg_ivsr_sdk_ubuntu22_ov2024.5s latest ...
+ffmpeg_ivsr_sdk_rockylinux9_ov2022.3 latest ...
+```
+
+### 4. Sanity-check the image (no model required)
+
+Verify the `ivsr` backend is registered in the built FFmpeg:
+
+```bash
+docker run --rm ffmpeg_ivsr_sdk__ov:latest \
+ ffmpeg -filters 2>&1 | grep ivsr
+```
+
+Verify the installed OpenVINO version:
+
+```bash
+docker run --rm ffmpeg_ivsr_sdk__ov:latest \
+ python3 -c "import openvino; print(openvino.__version__)"
+```
+
+### 5. Start Docker Container
```bash
# The backslash at the end of the line indicates that the command continues on the next line
@@ -39,10 +68,46 @@ sudo docker run -itd --name ffmpeg_ivsr_sdk_container --privileged \
-e no_proxy=$no_proxy \
--shm-size=128g \
--device=/dev/dri:/dev/dri \
- ffmpeg_ivsr_sdk__:latest bash
+ ffmpeg_ivsr_sdk__ov:latest bash
# Open another shell terminal to interact with the running container
sudo docker exec -it ffmpeg_ivsr_sdk_container bash
```
-Note `--device=/dev/dri:/dev/dri` is specified in the command to add the host gpu device to container.
\ No newline at end of file
+`--device=/dev/dri:/dev/dri` passes the host GPU through to the container for GPU inference (`device=GPU`).
+
+### 6. Run inference
+
+Mount your model directory and a test video, then run the desired model. The examples below use `docker run --rm` for a one-shot test; replace the image tag, model path, and video path as needed.
+
+**Enhanced EDSR (2× upscale, `rgb24` input, `model_type=2`):**
+
+```bash
+docker run --rm \
+ -v /path/to/models:/models:ro \
+ -v /path/to/input.mp4:/input.mp4:ro \
+ -v /path/to/output:/output \
+ ffmpeg_ivsr_sdk__ov:latest \
+ ffmpeg -hide_banner -y -i /input.mp4 \
+ -vf 'format=rgb24,dnn_processing=dnn_backend=ivsr:model=/models/:input=input:output=output:nif=1:device=CPU:model_type=2:normalize_factor=255.0' \
+ -pix_fmt yuv420p /output/edsr_out.mp4
+```
+
+Expected: output resolution is 2× the input (e.g. 1280×720 → 2560×1440).
+
+**SVP-Basic Y-channel (pre-filter / bitrate reduction, `yuv420p` input, `model_type=1`):**
+
+```bash
+docker run --rm \
+ -v /path/to/models:/models:ro \
+ -v /path/to/input.mp4:/input.mp4:ro \
+ -v /path/to/output:/output \
+ ffmpeg_ivsr_sdk__ov:latest \
+ ffmpeg -hide_banner -y -i /input.mp4 \
+ -vf 'format=yuv420p,dnn_processing=dnn_backend=ivsr:model=/models/:input=input:output=output:nif=1:device=CPU:model_type=1' \
+ -pix_fmt yuv420p /output/svp_out.mp4
+```
+
+Expected: output resolution matches input; bitrate is reduced compared to re-encoding without SVP.
+
+For additional FFmpeg filter options and command-line examples for all supported models, see the [FFmpeg plugin README](../ivsr_ffmpeg_plugin/README.md).
diff --git a/ivsr_ffmpeg_plugin/README.md b/ivsr_ffmpeg_plugin/README.md
index fbc2a78..5083efd 100644
--- a/ivsr_ffmpeg_plugin/README.md
+++ b/ivsr_ffmpeg_plugin/README.md
@@ -1,11 +1,15 @@
# iVSR FFmpeg plugin - iVSR SDK based
The folder `ivsr_ffmpeg_plugin` enables model inference using FFmpeg with iVSR SDK as backend. It provides additional `ivsr` backend for the DNN interface called by the `dnn_processing` filter.
-The patches included in `patches` folder are specifically for FFmpeg n7.1.
+The patches included in `patches` folder are specifically for FFmpeg n8.1.
+## Docker image build and test
+
+For full instructions on building the Docker image, see [docs/docker_image_build.md](../docs/docker_image_build.md).
+
## How to run inference with FFmpeg-plugin
To run inference with iVSR SDK, you need to specify `ivsr` as the backend for the `dnn_processing` filter. Here is an example of how to do it: `dnn_processing=dnn_backend=ivsr`.
Additionally, there are other parameters that you can use. These parameters are listed in the table below:
@@ -18,12 +22,12 @@ Additionally, there are other parameters that you can use. These parameters are
|output|output name of the model|NULL|output|
|device|device for inference task|CPU|CPU or GPU|
|model_type|type for models|0|0 for Enhanced BasicVSR, 1 for SVP models, 2 for Enhanced EDSR, 3 for one CUSTOM VSR, 4 for TSENet|
-|normalize_factor|factor for normalization|1.0|255.0 for Enhanced EDSR, 1.0 for other models supported in current version|
-|num_streams|number of execution streams for the throughput mode (now valid only for GPU devices).|1|use `benchmark_app` (a tool provided by OpenVINO Toolkit), to get the appropriate value for the best throughput|
-|extension|extension lib file full path, required for loading Enhanced BasicVSR model|
-|op_xml|custom op xml file full path, required for loading Enhanced BasicVSR model|
-|nif|number of input frames in batch sent to the DNN backend|1|3 for Enhanced BasicVSR, 1 for other models supported in current version|
-|nireq|number of request|0|use the default setting or set it to match the number of cpu cores|
+|normalize_factor|normalizing factor for models that do not require input normalization to [0, 1]|1.0|255.0 for Enhanced EDSR, 1.0 for all other models|
+|num_streams|number of execution streams for throughput mode (valid only for GPU devices)|1|use `benchmark_app` to determine the best value|
+|extension|extension lib file full path, required for Enhanced BasicVSR|—|—|
+|op_xml|custom op xml file full path, required for Enhanced BasicVSR|—|—|
+|nif|number of input frames in batch sent to the DNN backend|1|3 for Enhanced BasicVSR, 1 for other models|
+|nireq|number of infer requests|0|leave as default or set to match CPU core count|
Here are some examples of FFmpeg command lines to run inference with the supported models using the `ivsr` backend.
diff --git a/ivsr_ffmpeg_plugin/dockerfiles/rockylinux9/Dockerfile b/ivsr_ffmpeg_plugin/dockerfiles/rockylinux9/Dockerfile
index ee1298b..aada420 100644
--- a/ivsr_ffmpeg_plugin/dockerfiles/rockylinux9/Dockerfile
+++ b/ivsr_ffmpeg_plugin/dockerfiles/rockylinux9/Dockerfile
@@ -167,7 +167,7 @@ RUN cmake .. \
#build ffmpeg with iVSR SDK backend
RUN dnf -y --enablerepo=crb install nasm
RUN dnf -y --enablerepo=devel install yasm
-RUN dnf -y install diffutils
+RUN dnf -y install diffutils patchutils
# build libx264
WORKDIR ${WORKSPACE}
@@ -195,16 +195,23 @@ ARG FFMPEG_IVSR_SDK_PLUGIN_DIR=${IVSR_DIR}/ivsr_ffmpeg_plugin
ARG FFMPEG_DIR=${FFMPEG_IVSR_SDK_PLUGIN_DIR}/ffmpeg
ARG FFMPEG_REPO=https://github.com/FFmpeg/FFmpeg.git
-ARG FFMPEG_VERSION=n7.1
+ARG FFMPEG_VERSION=n8.1
WORKDIR ${FFMPEG_DIR}
RUN git clone ${FFMPEG_REPO} ${FFMPEG_DIR} && \
git checkout ${FFMPEG_VERSION}
COPY ./ivsr_ffmpeg_plugin/patches/*.patch ${FFMPEG_DIR}/
-RUN { set -e; \
- for patch_file in $(find -iname "*.patch" | sort -n); do \
- echo "Applying: ${patch_file}"; \
- git am --whitespace=fix ${patch_file}; \
- done; }
+# Patch 0001 was written for n7.1 context; exclude the three files covered by
+# the n8.1-native patch 0004, then apply 0004 for those files, and apply 0002/0003.
+RUN filterdiff \
+ -x '*/configure' \
+ -x '*/dnn_interface.c' \
+ -x '*/swscale_unscaled.c' \
+ 0001-*.patch | \
+ git apply --3way --ignore-whitespace - && \
+ git apply --ignore-whitespace 0004-*.patch && \
+ git add -A && \
+ git apply --3way --whitespace=fix 0002-*.patch && \
+ git apply --3way --whitespace=fix 0003-*.patch
RUN ./configure \
--extra-cflags=-fopenmp \
diff --git a/ivsr_ffmpeg_plugin/dockerfiles/rockylinux9/ov2024.5s.dockerfile b/ivsr_ffmpeg_plugin/dockerfiles/rockylinux9/ov2024.5s.dockerfile
index ca73eab..aec916a 100644
--- a/ivsr_ffmpeg_plugin/dockerfiles/rockylinux9/ov2024.5s.dockerfile
+++ b/ivsr_ffmpeg_plugin/dockerfiles/rockylinux9/ov2024.5s.dockerfile
@@ -80,7 +80,7 @@ RUN cmake .. \
#build ffmpeg with iVSR SDK backend
RUN dnf -y --enablerepo=crb install nasm
RUN dnf -y --enablerepo=devel install yasm
-RUN dnf -y install diffutils
+RUN dnf -y install diffutils patchutils
# build libx264
WORKDIR ${WORKSPACE}
@@ -108,16 +108,23 @@ ARG FFMPEG_IVSR_SDK_PLUGIN_DIR=${IVSR_DIR}/ivsr_ffmpeg_plugin
ARG FFMPEG_DIR=${FFMPEG_IVSR_SDK_PLUGIN_DIR}/ffmpeg
ARG FFMPEG_REPO=https://github.com/FFmpeg/FFmpeg.git
-ARG FFMPEG_VERSION=n7.1
+ARG FFMPEG_VERSION=n8.1
WORKDIR ${FFMPEG_DIR}
RUN git clone ${FFMPEG_REPO} ${FFMPEG_DIR} && \
git checkout ${FFMPEG_VERSION}
COPY ./ivsr_ffmpeg_plugin/patches/*.patch ${FFMPEG_DIR}/
-RUN { set -e; \
- for patch_file in $(find -iname "*.patch" | sort -n); do \
- echo "Applying: ${patch_file}"; \
- git am --whitespace=fix ${patch_file}; \
- done; }
+# Patch 0001 was written for n7.1 context; exclude the three files covered by
+# the n8.1-native patch 0004, then apply 0004 for those files, and apply 0002/0003.
+RUN filterdiff \
+ -x '*/configure' \
+ -x '*/dnn_interface.c' \
+ -x '*/swscale_unscaled.c' \
+ 0001-*.patch | \
+ git apply --3way --ignore-whitespace - && \
+ git apply --ignore-whitespace 0004-*.patch && \
+ git add -A && \
+ git apply --3way --whitespace=fix 0002-*.patch && \
+ git apply --3way --whitespace=fix 0003-*.patch
RUN ./configure \
--extra-cflags=-fopenmp \
diff --git a/ivsr_ffmpeg_plugin/dockerfiles/ubuntu22/ov2026.1.dockerfile b/ivsr_ffmpeg_plugin/dockerfiles/ubuntu22/ov2026.1.dockerfile
new file mode 100644
index 0000000..a2feb5e
--- /dev/null
+++ b/ivsr_ffmpeg_plugin/dockerfiles/ubuntu22/ov2026.1.dockerfile
@@ -0,0 +1,154 @@
+# SPDX-License-Identifier: BSD 3-Clause License
+#
+# Copyright (c) 2025, Intel Corporation
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are met:
+#
+# * Redistributions of source code must retain the above copyright notice, this
+# list of conditions and the following disclaimer.
+#
+# * Redistributions in binary form must reproduce the above copyright notice,
+# this list of conditions and the following disclaimer in the documentation
+# and/or other materials provided with the distribution.
+#
+# * Neither the name of the copyright holder nor the names of its
+# contributors may be used to endorse or promote products derived from
+# this software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+# DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+# Base image
+ARG IMAGE=ubuntu@sha256:ed1544e454989078f5dec1bfdabd8c5cc9c48e0705d07b678ab6ae3fb61952d2
+FROM $IMAGE AS base
+
+# Set non-interactive frontend for package installation
+ARG DEBIAN_FRONTEND=noninteractive
+
+# Install essential utilities
+RUN apt-get update && \
+ apt-get install -y --no-install-recommends \
+ curl ca-certificates gpg-agent software-properties-common && \
+ rm -rf /var/lib/apt/lists/*
+
+# Configure shell
+SHELL ["/bin/bash", "-o", "pipefail", "-c"]
+
+FROM base AS build
+LABEL vendor="Intel Corporation"
+
+# Create workspace directory
+RUN mkdir -p /workspace/ivsr
+
+ARG WORKSPACE=/workspace
+
+# Install common dependencies
+RUN apt-get update && \
+ apt-get install -y --no-install-recommends --fix-missing \
+ autoconf \
+ automake \
+ build-essential \
+ apt-utils cmake cython3 flex bison gcc g++ git make patch pkg-config wget \
+ libdrm-dev libudev-dev libtool libusb-1.0-0-dev xz-utils ocl-icd-opencl-dev opencl-headers \
+ && apt-get clean && rm -rf /var/lib/apt/lists/*
+
+# Install OpenVINO 2026.1 from apt
+# Uses the unified repo (no year in path) introduced for 2026.x releases
+RUN wget https://apt.repos.intel.com/intel-gpg-keys/GPG-PUB-KEY-INTEL-SW-PRODUCTS.PUB && \
+ apt-key add GPG-PUB-KEY-INTEL-SW-PRODUCTS.PUB && \
+ echo "deb https://apt.repos.intel.com/openvino ubuntu22 main" | tee /etc/apt/sources.list.d/intel-openvino.list && \
+ apt-get update && \
+ apt-get install -y openvino-2026.1.0 && \
+ rm -f GPG-PUB-KEY-INTEL-SW-PRODUCTS.PUB
+
+# Set the working directory
+WORKDIR /workspace
+
+# Install FFmpeg dependencies (patchutils provides filterdiff, required for n8.1 patch application)
+RUN apt-get update && \
+ apt-get install -y --no-install-recommends \
+ ca-certificates tar g++ wget pkg-config nasm yasm libglib2.0-dev flex bison gobject-introspection libgirepository1.0-dev \
+ python3-dev libx11-dev libxv-dev libxt-dev libasound2-dev libpango1.0-dev libtheora-dev libvisual-0.4-dev libgl1-mesa-dev \
+ libcurl4-gnutls-dev librtmp-dev libx264-dev libx265-dev libde265-dev libva-dev libtbb-dev patchutils && \
+ rm -rf /var/lib/apt/lists/*
+
+# Build iVSR SDK
+COPY ./ivsr_sdk ${WORKSPACE}/ivsr/ivsr_sdk
+WORKDIR ${WORKSPACE}/ivsr/ivsr_sdk
+RUN rm -rf build && mkdir -p build && cd build && \
+ cmake .. -DENABLE_LOG=OFF -DENABLE_PERF=OFF -DENABLE_THREADPROCESS=ON -DCMAKE_BUILD_TYPE=Release && \
+ make -j16 && \
+ make install && \
+ echo "Building iVSR SDK finished."
+
+# Build and install FFmpeg n8.1 with libivsr support
+ARG FFMPEG_REPO=https://github.com/FFmpeg/FFmpeg.git
+ARG FFMPEG_VERSION=n8.1
+ARG FFMPEG_IVSR_SDK_PLUGIN_DIR=${WORKSPACE}/ivsr/ivsr_ffmpeg_plugin
+WORKDIR ${FFMPEG_IVSR_SDK_PLUGIN_DIR}/ffmpeg
+RUN git config --global user.email "noname@example.com" && \
+ git config --global user.name "no name" && \
+ git clone ${FFMPEG_REPO} . && \
+ git checkout ${FFMPEG_VERSION}
+
+COPY ./ivsr_ffmpeg_plugin/patches/*.patch ./
+# Patch 0001 was written for n7.1 context; exclude the three files covered by the
+# n8.1-native patch 0004, then apply 0004 for those files, and finally apply the
+# fix-up patches 0002/0003.
+RUN filterdiff \
+ -x '*/configure' \
+ -x '*/dnn_interface.c' \
+ -x '*/swscale_unscaled.c' \
+ 0001-*.patch | \
+ git apply --3way --ignore-whitespace - && \
+ git apply --ignore-whitespace 0004-*.patch && \
+ git add -A && \
+ git apply --3way --whitespace=fix 0002-*.patch && \
+ git apply --3way --whitespace=fix 0003-*.patch
+
+RUN ./configure \
+ --enable-gpl \
+ --enable-nonfree \
+ --disable-static \
+ --disable-doc \
+ --enable-shared \
+ --enable-version3 \
+ --enable-libivsr \
+ --enable-libx264 \
+ --enable-libx265 && \
+ make -j16 && \
+ make install
+
+# for GPU
+RUN apt-get update && \
+ apt-get install -y --no-install-recommends ocl-icd-libopencl1 && \
+ apt-get clean ; \
+ rm -rf /var/lib/apt/lists/* && rm -rf /tmp/*
+# hadolint ignore=DL3003
+# 24.31.30508.7
+RUN mkdir /tmp/gpu_deps && cd /tmp/gpu_deps && \
+ curl -L -O https://github.com/intel/intel-graphics-compiler/releases/download/igc-1.0.17384.11/intel-igc-core_1.0.17384.11_amd64.deb && \
+ curl -L -O https://github.com/intel/intel-graphics-compiler/releases/download/igc-1.0.17384.11/intel-igc-opencl_1.0.17384.11_amd64.deb && \
+ curl -L -O https://github.com/intel/compute-runtime/releases/download/24.31.30508.7/intel-level-zero-gpu-dbgsym_1.3.30508.7_amd64.ddeb && \
+ curl -L -O https://github.com/intel/compute-runtime/releases/download/24.31.30508.7/intel-level-zero-gpu_1.3.30508.7_amd64.deb && \
+ curl -L -O https://github.com/intel/compute-runtime/releases/download/24.31.30508.7/intel-opencl-icd-dbgsym_24.31.30508.7_amd64.ddeb && \
+ curl -L -O https://github.com/intel/compute-runtime/releases/download/24.31.30508.7/intel-opencl-icd_24.31.30508.7_amd64.deb && \
+ curl -L -O https://github.com/intel/compute-runtime/releases/download/24.31.30508.7/libigdgmm12_22.4.1_amd64.deb && \
+ dpkg -i ./*.deb && rm -Rf /tmp/gpu_deps
+
+ENV LIBVA_DRIVER_NAME=iHD
+ENV LIBVA_DRIVERS_PATH=/usr/lib/x86_64-linux-gnu/dri
+
+# Set the working directory back to /workspace
+WORKDIR /workspace
+CMD ["/bin/bash"]
diff --git a/ivsr_ffmpeg_plugin/patches/0004-n8.1-compat-dnn_interface-swscale.patch b/ivsr_ffmpeg_plugin/patches/0004-n8.1-compat-dnn_interface-swscale.patch
new file mode 100644
index 0000000..ec9509a
--- /dev/null
+++ b/ivsr_ffmpeg_plugin/patches/0004-n8.1-compat-dnn_interface-swscale.patch
@@ -0,0 +1,213 @@
+diff --git a/configure b/configure
+index 1759694..4b15289 100755
+--- a/configure
++++ b/configure
+@@ -262,6 +262,8 @@ External library support:
+ --enable-libopencolorio enable color management via OpenColorIO [no]
+ --enable-libopenvino enable OpenVINO as a DNN module backend
+ for DNN based filters like dnn_processing [no]
++ --enable-libivsr enable iVSR SDK as a DNN module backend
++ for DNN based Super Resolution filters [no]
+ --enable-libopus enable Opus de/encoding via libopus [no]
+ --enable-libplacebo enable libplacebo library [no]
+ --enable-libpulse enable Pulseaudio input via libpulse [no]
+@@ -2070,6 +2072,7 @@ EXTERNAL_LIBRARY_LIST="
+ libopenjpeg
+ libopenmpt
+ libopenvino
++ libivsr
+ libopus
+ libplacebo
+ libpulse
+@@ -3026,7 +3029,7 @@ dirac_parse_select="golomb"
+ dovi_rpudec_select="golomb"
+ dovi_rpuenc_select="golomb"
+ dnn_deps="avformat swscale"
+-dnn_deps_any="libtensorflow libopenvino libtorch"
++dnn_deps_any="libtensorflow libopenvino libtorch libivsr"
+ error_resilience_select="me_cmp"
+ evcparse_select="golomb"
+ faandct_deps="faan"
+@@ -7347,6 +7350,7 @@ enabled libopenmpt && require_pkg_config libopenmpt "libopenmpt >= 0.2.65
+ enabled libopenvino && { { check_pkg_config libopenvino openvino openvino/c/openvino.h ov_core_create && enable openvino2; } ||
+ { check_pkg_config libopenvino openvino c_api/ie_c_api.h ie_c_api_version ||
+ require libopenvino c_api/ie_c_api.h ie_c_api_version -linference_engine_c_api; } }
++enabled libivsr && require libivsr ivsr.h ivsr_init -livsr
+ enabled libopus && {
+ enabled libopus_decoder && {
+ require_pkg_config libopus opus opus_multistream.h opus_multistream_decoder_create
+diff --git a/libavfilter/dnn/dnn_interface.c b/libavfilter/dnn/dnn_interface.c
+index 7080ab1..6d47920 100644
+--- a/libavfilter/dnn/dnn_interface.c
++++ b/libavfilter/dnn/dnn_interface.c
+@@ -33,6 +33,7 @@
+ extern const DNNModule ff_dnn_backend_openvino;
+ extern const DNNModule ff_dnn_backend_tf;
+ extern const DNNModule ff_dnn_backend_torch;
++extern const DNNModule ff_dnn_backend_ivsr;
+
+ #define OFFSET(x) offsetof(DnnContext, x)
+ #define FLAGS AV_OPT_FLAG_FILTERING_PARAM
+@@ -78,6 +79,9 @@ static const DnnBackendInfo dnn_backend_info_list[] = {
+ #if CONFIG_LIBTORCH
+ {offsetof(DnnContext, torch_option), .module = &ff_dnn_backend_torch},
+ #endif
++#if CONFIG_LIBIVSR
++ {offsetof(DnnContext, ivsr_option), .module = &ff_dnn_backend_ivsr},
++#endif
+ };
+
+ const DNNModule *ff_get_dnn_module(DNNBackendType backend_type, void *log_ctx)
+@@ -103,6 +107,14 @@ void ff_dnn_init_child_class(DnnContext *ctx)
+ }
+ }
+
++void ff_dnn_uninit_child_class(DnnContext *ctx)
++{
++ for (int i = 0; i < FF_ARRAY_ELEMS(dnn_backend_info_list); i++) {
++ const AVClass **ptr = (const AVClass **) ((char *) ctx + dnn_backend_info_list[i].offset);
++ av_opt_free(ptr);
++ }
++}
++
+ void *ff_dnn_child_next(DnnContext *obj, void *prev) {
+ size_t pre_offset;
+
+diff --git a/libswscale/swscale_unscaled.c b/libswscale/swscale_unscaled.c
+index f612f88..d61f7c8 100644
+--- a/libswscale/swscale_unscaled.c
++++ b/libswscale/swscale_unscaled.c
+@@ -2121,6 +2121,106 @@ static int float_y_to_uint_y_wrapper(SwsInternal *c,
+ return srcSliceH;
+ }
+
++static int uint16_y_to_float_y_wrapper(SwsInternal *c,
++ const uint8_t *const src[],
++ const int srcStride[], int srcSliceY,
++ int srcSliceH, uint8_t *const dst[],
++ const int dstStride[])
++{
++ int y, x;
++ const ptrdiff_t srcStrideUint16 = srcStride[0] >> 1;
++ const ptrdiff_t dstStrideFloat = dstStride[0] >> 2;
++ const uint16_t *srcPtr = (const uint16_t *)(src[0] + srcStride[0] * srcSliceY);
++ float *dstPtr = (float *)(dst[0] + dstStride[0] * srcSliceY);
++ const float float_norm_factor = 1.0f / 65535.0f;
++
++ for (y = 0; y < srcSliceH; ++y) {
++ for (x = 0; x < c->opts.src_w; ++x) {
++ dstPtr[x] = (float)srcPtr[x] * float_norm_factor;
++ }
++ srcPtr += srcStrideUint16;
++ dstPtr += dstStrideFloat;
++ }
++
++ return srcSliceH;
++}
++
++static int float_y_to_uint16_y_wrapper(SwsInternal *c,
++ const uint8_t *const src[],
++ const int srcStride[], int srcSliceY,
++ int srcSliceH, uint8_t *const dst[],
++ const int dstStride[])
++{
++ int y, x;
++ const ptrdiff_t srcStrideFloat = srcStride[0] >> 2;
++ const ptrdiff_t dstStrideUint16 = dstStride[0] >> 1;
++ const float *srcPtr = (const float *)(src[0] + srcStride[0] * srcSliceY);
++ uint16_t *dstPtr = (uint16_t *)(dst[0] + dstStride[0] * srcSliceY);
++
++ for (y = 0; y < srcSliceH; ++y) {
++ for (x = 0; x < c->opts.src_w; ++x) {
++ dstPtr[x] = av_clip_uint16(lrintf(65535.0f * srcPtr[x]));
++ }
++ srcPtr += srcStrideFloat;
++ dstPtr += dstStrideUint16;
++ }
++
++ return srcSliceH;
++}
++
++static int uint10_y_to_float_y_wrapper(SwsInternal *c,
++ const uint8_t *const src[],
++ const int srcStride[], int srcSliceY,
++ int srcSliceH, uint8_t *const dst[],
++ const int dstStride[])
++{
++ int y, x;
++ const ptrdiff_t srcStrideUint16 = srcStride[0] >> 1;
++ const ptrdiff_t dstStrideFloat = dstStride[0] >> 2;
++ const uint16_t *srcPtr = (const uint16_t *)(src[0] + srcStride[0] * srcSliceY);
++ float *dstPtr = (float *)(dst[0] + dstStride[0] * srcSliceY);
++ const float float_norm_factor = 1.0f / 1023.0f;
++
++ for (y = 0; y < srcSliceH; ++y) {
++ for (x = 0; x < c->opts.src_w; ++x) {
++ dstPtr[x] = (float)srcPtr[x] * float_norm_factor;
++ }
++ srcPtr += srcStrideUint16;
++ dstPtr += dstStrideFloat;
++ }
++
++ return srcSliceH;
++}
++
++static int float_y_to_uint10_y_wrapper(SwsInternal *c,
++ const uint8_t *const src[],
++ const int srcStride[], int srcSliceY,
++ int srcSliceH, uint8_t *const dst[],
++ const int dstStride[])
++{
++ int y, x;
++ const ptrdiff_t srcStrideFloat = srcStride[0] >> 2;
++ const ptrdiff_t dstStrideUint16 = dstStride[0] >> 1;
++ const float *srcPtr = (const float *)(src[0] + srcStride[0] * srcSliceY);
++ uint16_t *dstPtr = (uint16_t *)(dst[0] + dstStride[0] * srcSliceY);
++
++ for (y = 0; y < srcSliceH; ++y) {
++ for (x = 0; x < c->opts.src_w; ++x) {
++ int value = lrintf(1023.0f * srcPtr[x]);
++ if (value < 0) {
++ value = 0;
++ } else if (value > 1023) {
++ value = 1023;
++ }
++ dstPtr[x] = (uint16_t)value;
++ }
++ srcPtr += srcStrideFloat;
++ dstPtr += dstStrideUint16;
++ }
++
++ return srcSliceH;
++}
++
+ /* unscaled copy like stuff (assumes nearly identical formats) */
+ static int packedCopyWrapper(SwsInternal *c, const uint8_t *const src[],
+ const int srcStride[], int srcSliceY, int srcSliceH,
+@@ -2631,6 +2731,26 @@ void ff_get_unscaled_swscale(SwsInternal *c)
+ c->convert_unscaled = float_y_to_uint_y_wrapper;
+ }
+
++ /* 16bit Y to float Y */
++ if (srcFormat == AV_PIX_FMT_GRAY16 && dstFormat == AV_PIX_FMT_GRAYF32){
++ c->convert_unscaled = uint16_y_to_float_y_wrapper;
++ }
++
++ /* float Y to 16bit Y */
++ if (srcFormat == AV_PIX_FMT_GRAYF32 && dstFormat == AV_PIX_FMT_GRAY16){
++ c->convert_unscaled = float_y_to_uint16_y_wrapper;
++ }
++
++ /* 10bit Y to float Y */
++ if (srcFormat == AV_PIX_FMT_GRAY10 && dstFormat == AV_PIX_FMT_GRAYF32){
++ c->convert_unscaled = uint10_y_to_float_y_wrapper;
++ }
++
++ /* float Y to 10bit Y */
++ if (srcFormat == AV_PIX_FMT_GRAYF32 && dstFormat == AV_PIX_FMT_GRAY10){
++ c->convert_unscaled = float_y_to_uint10_y_wrapper;
++ }
++
+ /* LQ converters if -sws 0 or -sws 4*/
+ if (c->opts.flags&(SWS_FAST_BILINEAR|SWS_POINT)) {
+ /* yv12_to_yuy2 */
diff --git a/ivsr_sdk/CMakeLists.txt b/ivsr_sdk/CMakeLists.txt
index 2deecef..efb9688 100644
--- a/ivsr_sdk/CMakeLists.txt
+++ b/ivsr_sdk/CMakeLists.txt
@@ -15,6 +15,8 @@ SET(CMAKE_CXX_FLAGS_RELEASE "$ENV{CXXFLAGS} -O3 -Wall")
set(SDK_PRIVATE_HEADERS ${CMAKE_CURRENT_SOURCE_DIR}/privates/include)
+option(ENABLE_IRGUARD "Enable irguard model protection (requires prebuilt libirguard.a)" OFF)
+
add_subdirectory(src)
add_subdirectory(privates)
diff --git a/ivsr_sdk/privates/CMakeLists.txt b/ivsr_sdk/privates/CMakeLists.txt
index c84e37a..b55dfdf 100644
--- a/ivsr_sdk/privates/CMakeLists.txt
+++ b/ivsr_sdk/privates/CMakeLists.txt
@@ -6,8 +6,10 @@ cmake_minimum_required(VERSION 3.10)
option(REBUILD_IRGUARD "Enables cpu id checking" OFF)
-if(REBUILD_IRGUARD)
- add_subdirectory(model_guard)
-else()
- add_subdirectory(model_guard.bin)
+if(ENABLE_IRGUARD)
+ if(REBUILD_IRGUARD)
+ add_subdirectory(model_guard)
+ else()
+ add_subdirectory(model_guard.bin)
+ endif()
endif()
diff --git a/ivsr_sdk/src/CMakeLists.txt b/ivsr_sdk/src/CMakeLists.txt
index 432a13f..4ac7093 100644
--- a/ivsr_sdk/src/CMakeLists.txt
+++ b/ivsr_sdk/src/CMakeLists.txt
@@ -38,9 +38,11 @@ target_link_libraries(${TARGET_NAME} PRIVATE openvino::runtime)
find_package(OpenMP REQUIRED)
target_link_libraries(${TARGET_NAME} PRIVATE OpenMP::OpenMP_CXX)
-if (REBUILD_IRGUARD)
- target_link_libraries(${TARGET_NAME} PRIVATE irguard z)
-else()
- target_link_libraries(${TARGET_NAME} PRIVATE ${CMAKE_LIBRARY_OUTPUT_DIRECTORY}/libirguard.a z)
+if (ENABLE_IRGUARD)
+ if (REBUILD_IRGUARD)
+ target_link_libraries(${TARGET_NAME} PRIVATE irguard z)
+ else()
+ target_link_libraries(${TARGET_NAME} PRIVATE ${CMAKE_LIBRARY_OUTPUT_DIRECTORY}/libirguard.a z)
+ endif()
endif()
diff --git a/ivsr_sdk/src/ov_engine.cpp b/ivsr_sdk/src/ov_engine.cpp
index 95f36d5..7f9fa76 100644
--- a/ivsr_sdk/src/ov_engine.cpp
+++ b/ivsr_sdk/src/ov_engine.cpp
@@ -13,7 +13,9 @@
#include
#include
+#ifdef ENABLE_IRGUARD
#include
+#endif
#include "omp.h"
#include "utils.hpp"
@@ -78,7 +80,11 @@ IVSRStatus ov_engine::init_impl() {
try {
model = instance_.read_model(model_path_);
} catch (const std::exception& e) {
+#ifdef ENABLE_IRGUARD
model = irguard::load_model(instance_, model_path_);
+#else
+ throw;
+#endif
}
bool multiple_inputs = false;