GreenScreen: blur functionality

GitLab: #15
Change-Id: Iafc8b410ebe0228eca9b780504382347b38fd8cc
diff --git a/GreenScreen/CMakeLists.txt b/GreenScreen/CMakeLists.txt
index fc399b7..b19d1fd 100644
--- a/GreenScreen/CMakeLists.txt
+++ b/GreenScreen/CMakeLists.txt
@@ -2,7 +2,7 @@
 
 # set the project name
 set (ProjectName GreenScreen)
-set (Version 1.0.2)
+set (Version 2.0.0)
 
 project(${ProjectName} VERSION ${Version})
 
@@ -55,15 +55,16 @@
                pluginProcessor.cpp
                ./../lib/accel.cpp
                ./../lib/frameUtils.cpp
+               ./../lib/frameFilter.cpp
+               ${DAEMON_SRC}/string_utils.cpp
                )
 
 set(plugin_HDR pluginMediaHandler.h
                videoSubscriber.h
                pluginProcessor.h
-               ./../lib/accel.h
-               ./../lib/frameScaler.h
-               ./../lib/frameUtils.h
                ./../lib/pluglog.h
+               ./../lib/mediaStream.h
+               ./../lib/audioFormat.h
                )
 
 
@@ -87,11 +88,13 @@
 target_link_directories(${ProjectName} PUBLIC ${CONTRIB_PATH}
                                         ${CONTRIB_PATH}/build/opencv/build/lib/Release
                                         ${CONTRIB_PATH}/build/opencv/build/3rdparty/lib/Release
-                                        ${FFMPEG}/bin
+                                        ${FFMPEG}/lib
                                         ${ONNX_DIR}
+                                        ${CONTRIB_PATH}/msvc/lib/x64
                                         )
 
-target_link_libraries(${ProjectName} PUBLIC swscale avutil libpng libjpeg-turbo opencv_imgcodecs411 opencv_imgproc411 opencv_core411 onnxruntime zlib)
+target_link_libraries(${ProjectName} PUBLIC libavfilter libswscale libavformat libavcodec libavutil libvpx libx264 libopus libmfx
+                                            libzlib ws2_32 Bcrypt Crypt32 Secur32 Dnsapi opencv_imgproc411 opencv_core411 onnxruntime msvcrt)
 endif()
 
 add_custom_command(
diff --git a/GreenScreen/build.sh b/GreenScreen/build.sh
index 2f0b65f..a04f9e9 100755
--- a/GreenScreen/build.sh
+++ b/GreenScreen/build.sh
@@ -56,9 +56,19 @@
   esac
 done
 
+cp -r ffmpeg ${CONTRIB_PATH}/src/
+
 if [ "${PLATFORM}" = "linux-gnu" ]
 then
-    python3 ./../SDK/jplManipulation.py --preassemble --plugin=${PLUGIN_NAME} 
+    if [ -f "${CONTRIB_PATH}/native/.ffmpeg" ]; then
+        rm "${CONTRIB_PATH}/native/.ffmpeg"
+    fi
+    WORKPATH=$(pwd)
+    cd "${CONTRIB_PATH}/native/"
+    make .ffmpeg -j$(nproc)
+    rm .ffmpeg
+    cd ${WORKPATH}
+    python3 ./../SDK/jplManipulation.py --preassemble --plugin=${PLUGIN_NAME}
 
     CONTRIB_PLATFORM_CURT=${ARCH}
     CONTRIB_PLATFORM=${CONTRIB_PLATFORM_CURT}-${PLATFORM}
@@ -85,6 +95,7 @@
     -I"${PLUGINS_LIB}" \
     ./../lib/accel.cpp \
     ./../lib/frameUtils.cpp \
+    ./../lib/frameFilter.cpp \
     main.cpp \
     videoSubscriber.cpp \
     pluginMediaHandler.cpp \
@@ -93,13 +104,15 @@
     -L"${CONTRIB_PATH}/${CONTRIB_PLATFORM}/lib/opencv4/3rdparty/" \
     -L"${ONNX_PATH}/lib/onnxruntime/${ONNX_LIBS}" \
     -L"${CUDA_HOME}/lib64/" \
+    -l:libavfilter.a \
     -l:libswscale.a \
+    -l:libavformat.a \
+    -l:libavcodec.a \
     -l:libavutil.a \
-    -lopencv_imgcodecs \
+    -l:libvpx.a \
+    -l:libx264.a \
     -lopencv_imgproc \
     -lopencv_core \
-    -llibpng \
-    -llibjpeg-turbo \
     -lva ${CUBLASLT} \
     -lonnxruntime \
     -o "build-local/jpl/lib/${CONTRIB_PLATFORM}/${SO_FILE_NAME}"
@@ -219,6 +232,16 @@
         export EXTRA_LDFLAGS="${EXTRA_LDFLAGS} -L${ANDROID_SYSROOT}/usr/lib/x86_64-linux-android -L${ANDROID_SYSROOT}/usr/lib/x86_64-linux-android/21"
         fi
 
+        if [ -f "${CONTRIB_PATH}/native-${CONTRIB_PLATFORM}/.ffmpeg" ]; then
+            rm "${CONTRIB_PATH}/native-${CONTRIB_PLATFORM}/.ffmpeg"
+        fi
+
+        WORKPATH=$(pwd)
+        cd "${CONTRIB_PATH}/native-${CONTRIB_PLATFORM}/"
+        make .ffmpeg -j$(nproc)
+        rm .ffmpeg
+        cd ${WORKPATH}
+
         #=========================================================
         #    Compile CPU FEATURES, NEEDED FOR OPENCV
         #=========================================================
@@ -254,6 +277,7 @@
         -I"${PLUGINS_LIB}" \
         ./../lib/accel.cpp \
         ./../lib/frameUtils.cpp \
+        ./../lib/frameFilter.cpp \
         main.cpp \
         videoSubscriber.cpp \
         pluginMediaHandler.cpp \
@@ -261,13 +285,18 @@
         cpu-features.o \
         -L"${CONTRIB_PATH}/${CONTRIB_PLATFORM}/lib/" \
         -L"${ONNX_PATH}/lib/" \
+        -lavfilter \
         -lswscale \
+        -lavformat \
+        -lavcodec \
         -lavutil \
-        -lopencv_imgcodecs \
+        -lvpx \
+        -lx264 \
+        -lspeex \
+        -lopus \
+        -liconv \
         -lopencv_imgproc \
         -lopencv_core \
-        -llibpng \
-        -llibjpeg-turbo \
         -llog -lz \
         -lonnxruntime \
         --sysroot=$ANDROID_SYSROOT \
@@ -289,3 +318,7 @@
 fi
 
 python3 ./../SDK/jplManipulation.py --assemble --plugin=${PLUGIN_NAME} --distribution=${PLATFORM} --extraPath=${ONNX_LIBS}
+cd ${CONTRIB_PATH}/src/ffmpeg/
+# ffmpeg build configuration files were changed during plugin build
+# this git checkout will remove these changes
+git checkout -- .
diff --git a/GreenScreen/ffmpeg/package.json b/GreenScreen/ffmpeg/package.json
new file mode 100644
index 0000000..395a10a
--- /dev/null
+++ b/GreenScreen/ffmpeg/package.json
@@ -0,0 +1,35 @@
+{
+    "name": "ffmpeg",
+    "version": "9f38fac053010205806ece11e6aea9b7d3bde041",
+    "url": "https://github.com/FFmpeg/FFmpeg/archive/__VERSION__.tar.gz",
+    "deps": [
+        "zlib",
+        "vpx",
+        "x264",
+        "opus",
+        "ffnvcodec",
+        "media-sdk"
+    ],
+    "patches": [
+        "change-RTCP-ratio.patch",
+        "rtp_ext_abs_send_time.patch",
+        "libopusenc-enable-FEC.patch",
+        "libopusdec-enable-FEC.patch"
+    ],
+    "win_patches": [
+        "windows-configure.patch",
+        "windows-configure-ffnvcodec.patch",
+        "windows-configure-libmfx.patch"
+    ],
+    "project_paths": [],
+    "with_env" : "10.0.16299.0",
+    "custom_scripts": {
+        "pre_build": [],
+        "build": [
+            "call \"%CONTRIB_SRC_DIR%\\ffmpeg\\build_ffmpeg.bat\"",
+            "cd Build/win32/x64/lib & ren *.a *.lib"
+        ],
+        "post_build": []
+    }
+}
+
diff --git a/GreenScreen/ffmpeg/rules.mak b/GreenScreen/ffmpeg/rules.mak
new file mode 100644
index 0000000..7b06d39
--- /dev/null
+++ b/GreenScreen/ffmpeg/rules.mak
@@ -0,0 +1,357 @@
+FFMPEG_HASH := 9f38fac053010205806ece11e6aea9b7d3bde041
+FFMPEG_URL := https://git.ffmpeg.org/gitweb/ffmpeg.git/snapshot/$(FFMPEG_HASH).tar.gz
+
+PKGS+=ffmpeg
+
+ifeq ($(call need_pkg,"libavutil >= 55.75.100 libavcodec >= 57.106.101 libavformat >= 57.82.100 libavdevice >= 57.8.101 libavfilter >= 6.105.100 libswscale >= 4.7.103 libswresample >= 2.9.100"),)
+PKGS_FOUND += ffmpeg
+endif
+
+DEPS_ffmpeg = iconv zlib vpx opus speex x264
+
+FFMPEGCONF = \
+	--cc="$(CC)" \
+	--pkg-config="$(PKG_CONFIG)"
+
+#disable everything
+FFMPEGCONF += \
+	--disable-everything \
+	--enable-zlib \
+	--enable-gpl \
+	--enable-swscale \
+	--enable-bsfs \
+	--disable-filters \
+	--disable-programs \
+	--disable-postproc
+
+FFMPEGCONF += \
+	--disable-protocols \
+	--enable-protocol=crypto \
+	--enable-protocol=file \
+	--enable-protocol=rtp \
+	--enable-protocol=srtp \
+	--enable-protocol=tcp \
+	--enable-protocol=udp \
+	--enable-protocol=unix \
+	--enable-protocol=pipe
+
+#enable muxers/demuxers
+FFMPEGCONF += \
+	--disable-demuxers \
+	--disable-muxers \
+	--enable-muxer=rtp \
+	--enable-muxer=g722 \
+	--enable-muxer=h263 \
+	--enable-muxer=h264 \
+	--enable-muxer=hevc \
+	--enable-muxer=webm \
+	--enable-muxer=ogg \
+	--enable-muxer=pcm_s16be \
+	--enable-muxer=pcm_s16le \
+	--enable-demuxer=rtp \
+	--enable-demuxer=mjpeg \
+	--enable-demuxer=mjpeg_2000 \
+	--enable-demuxer=mpegvideo \
+	--enable-demuxer=image_jpeg_pipe \
+	--enable-demuxer=image_png_pipe \
+	--enable-demuxer=image_webp_pipe \
+	--enable-demuxer=matroska \
+	--enable-demuxer=m4v \
+	--enable-demuxer=mp3 \
+	--enable-demuxer=ogg \
+	--enable-demuxer=flac \
+	--enable-demuxer=wav \
+	--enable-demuxer=ac3 \
+	--enable-demuxer=g722 \
+	--enable-demuxer=pcm_mulaw \
+	--enable-demuxer=pcm_alaw \
+	--enable-demuxer=pcm_s16be \
+	--enable-demuxer=pcm_s16le \
+	--enable-demuxer=h263 \
+	--enable-demuxer=h264 \
+	--enable-demuxer=hevc
+
+#enable parsers
+FFMPEGCONF += \
+	--enable-parser=h263 \
+	--enable-parser=h264 \
+	--enable-parser=hevc \
+	--enable-parser=mpeg4video \
+	--enable-parser=vp8 \
+	--enable-parser=vp9 \
+	--enable-parser=opus
+
+#encoders/decoders
+FFMPEGCONF += \
+	--enable-encoder=adpcm_g722 \
+	--enable-decoder=adpcm_g722 \
+	--enable-encoder=rawvideo \
+	--enable-decoder=rawvideo \
+	--enable-encoder=libx264 \
+	--enable-decoder=h264 \
+	--enable-encoder=pcm_alaw \
+	--enable-decoder=pcm_alaw \
+	--enable-encoder=pcm_mulaw \
+	--enable-decoder=pcm_mulaw \
+	--enable-encoder=mpeg4 \
+	--enable-decoder=mpeg4 \
+	--enable-encoder=libvpx_vp8 \
+	--enable-decoder=vp8 \
+	--enable-decoder=vp9 \
+	--enable-encoder=h263 \
+	--enable-encoder=h263p \
+	--enable-decoder=h263 \
+	--enable-encoder=mjpeg \
+	--enable-decoder=mjpeg \
+	--enable-decoder=mjpegb \
+	--enable-libspeex \
+	--enable-libopus \
+	--enable-libvpx \
+	--enable-libx264 \
+	--enable-encoder=libspeex \
+	--enable-decoder=libspeex \
+	--enable-encoder=libopus \
+	--enable-decoder=libopus
+
+# decoders for ringtones and audio streaming
+FFMPEGCONF += \
+	--enable-decoder=flac \
+	--enable-decoder=vorbis \
+	--enable-decoder=aac \
+	--enable-decoder=ac3 \
+	--enable-decoder=eac3 \
+	--enable-decoder=mp3 \
+	--enable-decoder=pcm_u24be \
+	--enable-decoder=pcm_u24le \
+	--enable-decoder=pcm_u32be \
+	--enable-decoder=pcm_u32le \
+	--enable-decoder=pcm_u8 \
+	--enable-decoder=pcm_f16le \
+	--enable-decoder=pcm_f24le \
+	--enable-decoder=pcm_f32be \
+	--enable-decoder=pcm_f32le \
+	--enable-decoder=pcm_f64be \
+	--enable-decoder=pcm_f64le \
+	--enable-decoder=pcm_s16be \
+	--enable-decoder=pcm_s16be_planar \
+	--enable-decoder=pcm_s16le \
+	--enable-decoder=pcm_s16le_planar \
+	--enable-decoder=pcm_s24be \
+	--enable-decoder=pcm_s24le \
+	--enable-decoder=pcm_s24le_planar \
+	--enable-decoder=pcm_s32be \
+	--enable-decoder=pcm_s32le \
+	--enable-decoder=pcm_s32le_planar \
+	--enable-decoder=pcm_s64be \
+	--enable-decoder=pcm_s64le \
+	--enable-decoder=pcm_s8 \
+	--enable-decoder=pcm_s8_planar \
+	--enable-decoder=pcm_u16be \
+	--enable-decoder=pcm_u16le
+
+#encoders/decoders for images
+FFMPEGCONF += \
+	--enable-encoder=jpegls \
+	--enable-decoder=jpegls \
+	--enable-encoder=ljpeg \
+	--enable-decoder=jpeg2000 \
+	--enable-encoder=png \
+	--enable-decoder=png
+
+#filters
+FFMPEGCONF += \
+	--enable-filter=scale \
+	--enable-filter=overlay \
+	--enable-filter=format \
+	--enable-filter=fps \
+	--enable-filter=transpose \
+	--enable-filter=rotate \
+	--enable-filter=alphamerge \
+	--enable-filter=boxblur \
+	--enable-filter=lut \
+	--enable-filter=negate \
+	--enable-filter=colorkey \
+	--enable-filter=split
+
+
+#platform specific options
+
+ifdef HAVE_WIN32
+FFMPEGCONF += \
+	--enable-indev=dshow \
+	--enable-indev=gdigrab \
+	--enable-dxva2
+endif
+
+ifdef HAVE_LINUX
+FFMPEGCONF += --enable-pic
+ifdef HAVE_ANDROID
+# Android Linux
+FFMPEGCONF += \
+	--target-os=android \
+	--enable-jni \
+	--enable-mediacodec \
+	--enable-decoder=vp8_mediacodec \
+	--enable-decoder=h264_mediacodec \
+	--enable-decoder=mpeg4_mediacodec \
+	--enable-decoder=hevc_mediacodec \
+	--enable-cross-compile \
+	--ranlib=$(RANLIB) \
+	--strip=$(STRIP) \
+	--cc=$(CC) \
+	--cxx=$(CXX) \
+	--ld=$(CC) \
+	--ar=$(AR)
+# ASM not working on Android x86 https://trac.ffmpeg.org/ticket/4928
+ifeq ($(ARCH),i386)
+FFMPEGCONF += --disable-asm
+endif
+ifeq ($(ARCH),x86_64)
+FFMPEGCONF += --disable-asm
+endif
+else
+# Desktop Linux
+DEPS_ffmpeg += ffnvcodec
+FFMPEGCONF += \
+	--target-os=linux \
+	--enable-indev=v4l2 \
+	--enable-indev=xcbgrab \
+	--enable-vdpau \
+	--enable-hwaccel=h264_vdpau \
+	--enable-hwaccel=mpeg4_vdpau \
+	--enable-vaapi \
+	--enable-hwaccel=h264_vaapi \
+	--enable-hwaccel=mpeg4_vaapi \
+	--enable-hwaccel=h263_vaapi \
+	--enable-hwaccel=vp8_vaapi \
+	--enable-hwaccel=mjpeg_vaapi \
+	--enable-hwaccel=hevc_vaapi \
+	--enable-encoder=h264_vaapi \
+	--enable-encoder=vp8_vaapi \
+	--enable-encoder=mjpeg_vaapi \
+	--enable-encoder=hevc_vaapi
+# ffnvcodec is not supported on ARM then we enable it here for i386 and x86_64
+ifeq ($(ARCH),$(filter $(ARCH),i386 x86_64))
+FFMPEGCONF += --enable-cuvid \
+	      --enable-ffnvcodec \
+	      --enable-nvdec \
+	      --enable-nvenc \
+	      --enable-hwaccel=h264_nvdec \
+	      --enable-hwaccel=hevc_nvdec \
+	      --enable-hwaccel=vp8_nvdec \
+	      --enable-hwaccel=mjpeg_nvdec \
+	      --enable-encoder=h264_nvenc \
+	      --enable-encoder=hevc_nvenc
+endif
+# End Desktop Linux:
+endif
+# End HAVE_LINUX:
+endif
+
+ifdef HAVE_MACOSX
+FFMPEGCONF += \
+	--enable-avfoundation \
+	--enable-indev=avfoundation \
+	--enable-videotoolbox \
+	--enable-hwaccel=h263_videotoolbox \
+	--enable-hwaccel=h264_videotoolbox \
+	--enable-hwaccel=mpeg4_videotoolbox \
+	--enable-hwaccel=hevc_videotoolbox \
+	--enable-encoder=h264_videotoolbox \
+	--enable-encoder=hevc_videotoolbox \
+	--disable-securetransport
+endif
+
+ifdef HAVE_IOS
+FFMPEGCONF += \
+	--enable-videotoolbox \
+	--enable-hwaccel=h263_videotoolbox \
+	--enable-hwaccel=h264_videotoolbox \
+	--enable-hwaccel=mpeg4_videotoolbox \
+	--enable-hwaccel=hevc_videotoolbox \
+	--enable-encoder=h264_videotoolbox \
+	--enable-encoder=hevc_videotoolbox \
+	--target-os=darwin \
+	--enable-cross-compile \
+	--enable-pic
+endif
+
+ifndef HAVE_IOS
+ifndef HAVE_ANDROID
+ifdef HAVE_CROSS_COMPILE
+FFMPEGCONF += --cross-prefix=$(HOST)-
+endif
+endif
+endif
+
+# x86 stuff
+ifeq ($(ARCH),i386)
+FFMPEGCONF += --arch=x86
+endif
+
+ifeq ($(ARCH),x86_64)
+FFMPEGCONF += --arch=x86_64
+endif
+
+# ARM stuff
+ifeq ($(ARCH),arm)
+FFMPEGCONF += --arch=arm
+ifdef HAVE_ARMV7A
+FFMPEGCONF += --cpu=cortex-a8
+endif
+ifdef HAVE_ARMV6
+FFMPEGCONF += --cpu=armv6 --disable-neon
+endif
+endif
+
+# ARM64 stuff
+ifeq ($(ARCH),aarch64)
+FFMPEGCONF += --arch=aarch64
+endif
+ifeq ($(ARCH),arm64)
+FFMPEGCONF += --arch=aarch64
+endif
+
+# Windows
+ifdef HAVE_WIN32
+DEPS_ffmpeg += ffnvcodec
+FFMPEGCONF += --target-os=mingw32 \
+    --enable-w32threads \
+    --disable-decoder=dca \
+	--enable-cuvid \
+	--enable-ffnvcodec \
+	--enable-nvdec \
+	--enable-nvenc \
+	--enable-hwaccel=h264_nvdec \
+	--enable-hwaccel=hevc_nvdec \
+	--enable-hwaccel=vp8_nvdec \
+	--enable-hwaccel=mjpeg_nvdec \
+	--enable-encoder=h264_nvenc \
+	--enable-encoder=hevc_nvenc
+endif
+
+$(TARBALLS)/ffmpeg-$(FFMPEG_HASH).tar.gz:
+	$(call download,$(FFMPEG_URL))
+
+.sum-ffmpeg: ffmpeg-$(FFMPEG_HASH).tar.gz
+
+ffmpeg: ffmpeg-$(FFMPEG_HASH).tar.gz
+	rm -Rf $@ $@-$(FFMPEG_HASH)
+	mkdir -p $@-$(FFMPEG_HASH)
+	(cd $@-$(FFMPEG_HASH) && tar x $(if ${BATCH_MODE},,-v) --strip-components=1 -f $<)
+	$(APPLY) $(SRC)/ffmpeg/remove-mjpeg-log.patch
+	$(APPLY) $(SRC)/ffmpeg/change-RTCP-ratio.patch
+	$(APPLY) $(SRC)/ffmpeg/rtp_ext_abs_send_time.patch
+	$(APPLY) $(SRC)/ffmpeg/libopusdec-enable-FEC.patch
+	$(APPLY) $(SRC)/ffmpeg/libopusenc-enable-FEC.patch
+	$(UPDATE_AUTOCONFIG)
+	$(MOVE)
+
+.ffmpeg: ffmpeg .sum-ffmpeg
+	cd $< && $(HOSTVARS) ./configure \
+		--extra-cflags="$(CFLAGS)" \
+		--extra-ldflags="$(LDFLAGS)" $(FFMPEGCONF) \
+		--prefix="$(PREFIX)" --enable-static --disable-shared \
+		--pkg-config-flags="--static"
+	cd $< && $(MAKE) install-libs install-headers
+	touch $@
diff --git a/GreenScreen/ffmpeg/windows-configure-make.sh b/GreenScreen/ffmpeg/windows-configure-make.sh
new file mode 100644
index 0000000..b6ec0d9
--- /dev/null
+++ b/GreenScreen/ffmpeg/windows-configure-make.sh
@@ -0,0 +1,200 @@
+#!/bin/bash
+set +x
+set +e
+DIR=$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )
+cd $DIR/../../build/ffmpeg
+FFMPEGCONF='
+            --toolchain=msvc
+            --target-os=win32'
+
+#disable everything
+FFMPEGCONF+='
+            --disable-everything
+            --disable-programs
+            --disable-d3d11va
+            --disable-dxva2
+            --disable-postproc
+            --disable-filters
+            --enable-zlib'
+
+FFMPEGCONF+='
+            --enable-cross-compile
+            --enable-gpl
+            --enable-swscale
+            --enable-protocols
+            --enable-bsfs'
+
+#enable muxers/demuxers
+FFMPEGCONF+='
+            --enable-demuxers
+            --enable-muxers'
+
+#enable parsers
+FFMPEGCONF+='
+            --enable-parser=h263
+            --enable-parser=h264
+            --enable-parser=hevc
+            --enable-parser=mpeg4video
+            --enable-parser=vp8
+            --enable-parser=vp9
+            --enable-parser=opus'
+
+#encoders/decoders
+FFMPEGCONF+='
+            --enable-libopus
+            --enable-encoder=libopus
+            --enable-decoder=libopus
+            --enable-encoder=adpcm_g722
+            --enable-decoder=adpcm_g722
+            --enable-encoder=pcm_alaw
+            --enable-decoder=pcm_alaw
+            --enable-encoder=pcm_mulaw
+            --enable-decoder=pcm_mulaw
+            --enable-libx264
+            --enable-encoder=libx264
+            --enable-decoder=h264
+            --enable-encoder=rawvideo
+            --enable-decoder=rawvideo
+            --enable-encoder=mpeg4
+            --enable-decoder=mpeg4
+            --enable-encoder=h263
+            --enable-encoder=h263p
+            --enable-decoder=h263
+            --enable-encoder=mjpeg
+            --enable-decoder=mjpeg
+            --enable-decoder=mjpegb'
+
+# decoders for ringtones and audio streaming
+FFMPEGCONF+='
+            --enable-decoder=flac
+            --enable-decoder=vorbis
+            --enable-decoder=aac
+            --enable-decoder=ac3
+            --enable-decoder=eac3
+            --enable-decoder=mp3
+            --enable-decoder=pcm_u24be
+            --enable-decoder=pcm_u24le
+            --enable-decoder=pcm_u32be
+            --enable-decoder=pcm_u32le
+            --enable-decoder=pcm_u8
+            --enable-decoder=pcm_f16le
+            --enable-decoder=pcm_f24le
+            --enable-decoder=pcm_f32be
+            --enable-decoder=pcm_f32le
+            --enable-decoder=pcm_f64be
+            --enable-decoder=pcm_f64le
+            --enable-decoder=pcm_s16be
+            --enable-decoder=pcm_s16be_planar
+            --enable-decoder=pcm_s16le
+            --enable-decoder=pcm_s16le_planar
+            --enable-decoder=pcm_s24be
+            --enable-decoder=pcm_s24le
+            --enable-decoder=pcm_s24le_planar
+            --enable-decoder=pcm_s32be
+            --enable-decoder=pcm_s32le
+            --enable-decoder=pcm_s32le_planar
+            --enable-decoder=pcm_s64be
+            --enable-decoder=pcm_s64le
+            --enable-decoder=pcm_s8
+            --enable-decoder=pcm_s8_planar
+            --enable-decoder=pcm_u16be
+            --enable-decoder=pcm_u16le'
+
+#encoders/decoders for images
+FFMPEGCONF+='
+            --enable-encoder=jpegls
+            --enable-decoder=jpegls
+            --enable-encoder=ljpeg
+            --enable-decoder=jpeg2000
+            --enable-encoder=png
+            --enable-decoder=png'
+
+#filters
+FFMPEGCONF+='
+            --enable-filter=scale
+            --enable-filter=overlay
+            --enable-filter=format
+            --enable-filter=fps
+            --enable-filter=transpose
+            --enable-filter=rotate
+            --enable-filter=negate
+            --enable-filter=lut
+            --enable-filter=alphamerge
+            --enable-filter=boxblur
+            --enable-filter=colorkey
+            --enable-filter=split'
+
+if [ "$1" == "uwp" ]; then
+    EXTRACFLAGS='-MD -DWINAPI_FAMILY=WINAPI_FAMILY_APP -D_WIN32_WINNT=0x0A00 -I../../../../../msvc/include -I../../../../../msvc/include/opus'
+    if [ "$2" == "x64" ]; then
+        echo "configure and make ffmpeg for UWP-x64..."
+            EXTRALDFLAGS='-APPCONTAINER WindowsApp.lib libopus.lib libx264.lib libzlib.lib -LIBPATH:../../../../../msvc/lib/x64'
+            FFMPEGCONF+=' --arch=x86_64'
+            PREFIX=../../../Build/Windows10/x64
+            OUTDIR=Output/Windows10/x64
+    elif [ "$2" == "x86" ]; then
+        echo "configure and make ffmpeg for UWP-x86..."
+            EXTRALDFLAGS='-APPCONTAINER WindowsApp.lib libopus.lib libx264.lib libzlib.lib -LIBPATH:../../../../../msvc/lib/x86'
+            FFMPEGCONF+=' --arch=x86'
+            PREFIX=../../../Build/Windows10/x86
+            OUTDIR=Output/Windows10/x86
+    fi
+elif [ "$1" == "win32" ]; then
+    EXTRACFLAGS='-MD -D_WINDLL -I../../../../../msvc/include -I../../../../../msvc/include/opus -I../../../../../msvc/include/vpx -I../../../../../msvc/include/ffnvcodec -I../../../../../msvc/include/mfx' 
+    FFMPEGCONF+='
+                --enable-libvpx
+                --enable-encoder=libvpx_vp8
+                --enable-decoder=vp8
+                --enable-decoder=vp9'
+    FFMPEGCONF+='
+                --enable-indev=dshow
+                --enable-indev=gdigrab
+                --enable-dxva2'
+    FFMPEGCONF+='
+                --enable-ffnvcodec
+                --enable-cuvid
+                --enable-nvdec
+                --enable-nvenc
+                --enable-hwaccel=h264_nvdec
+                --enable-hwaccel=hevc_nvdec
+                --enable-hwaccel=vp8_nvdec
+                --enable-hwaccel=mjpeg_nvdec
+                --enable-encoder=h264_nvenc
+                --enable-encoder=hevc_nvenc'
+    FFMPEGCONF+='
+                --enable-libmfx
+                --enable-encoder=h264_qsv
+                --enable-encoder=hevc_qsv
+                --enable-encoder=mjpeg_qsv
+                --enable-decoder=vp8_qsv
+                --enable-decoder=h264_qsv
+                --enable-decoder=hevc_qsv
+                --enable-decoder=mjpeg_qsv
+                --enable-decoder=vp9_qsv
+                --enable-filter=scale_qsv
+                --enable-filter=overlay_qsv'
+    if [ "$2" == "x64" ]; then
+        echo "configure and make ffmpeg for win32-x64..."
+        EXTRALDFLAGS='-APPCONTAINER:NO -MACHINE:x64 Ole32.lib Kernel32.lib Gdi32.lib User32.lib Strmiids.lib Advapi32.lib OleAut32.lib Shlwapi.lib Vfw32.lib Secur32.lib Advapi32.lib libopus.lib libx264.lib libvpx.lib libmfx.lib libzlib.lib -LIBPATH:../../../../../msvc/lib/x64'
+        FFMPEGCONF+=' --arch=x86_64'
+        PREFIX=../../../Build/win32/x64
+        OUTDIR=Output/win32/x64
+    elif [ "$2" == "x86" ]; then
+        echo "configure and make ffmpeg for win32-x86..."
+        EXTRALDFLAGS='-APPCONTAINER:NO -MACHINE:x86 Ole32.lib Kernel32.lib Gdi32.lib User32.lib Strmiids.lib OleAut32.lib Shlwapi.lib Vfw32.lib Secur32.lib Advapi32.lib libopus.lib libx264.lib libvpx.lib libmfx.lib libzlib.lib -LIBPATH:../../../../../msvc/lib/x86'
+        FFMPEGCONF+=' --arch=x86'
+        PREFIX=../../../Build/win32/x86
+        OUTDIR=Output/win32/x86
+    fi
+fi
+rm -rf $OUTDIR
+mkdir -p $OUTDIR
+cd $OUTDIR
+pwd
+FFMPEGCONF=$(echo $FFMPEGCONF | sed -e "s/[[:space:]]\+/ /g")
+set -x
+set -e
+../../../configure $FFMPEGCONF --extra-cflags="${EXTRACFLAGS}" --extra-ldflags="${EXTRALDFLAGS}" --prefix="${PREFIX}"
+make -j8 install
+cd ../../..
+
diff --git a/GreenScreen/main.cpp b/GreenScreen/main.cpp
index bfc1bc8..eef75af 100644
--- a/GreenScreen/main.cpp
+++ b/GreenScreen/main.cpp
@@ -32,9 +32,9 @@
 #define EXPORT_PLUGIN
 #endif
 
-#define GreenScreen_VERSION_MAJOR 1
+#define GreenScreen_VERSION_MAJOR 2
 #define GreenScreen_VERSION_MINOR 0
-#define GreenScreen_VERSION_PATCH 2
+#define GreenScreen_VERSION_PATCH 0
 
 extern "C" {
 void
@@ -44,9 +44,9 @@
 EXPORT_PLUGIN JAMI_PluginExitFunc
 JAMI_dynPluginInit(const JAMI_PluginAPI* api)
 {
-    std::cout << "**************************" << std::endl;
-    std::cout << "**  GREENSCREEN PLUGIN  **" << std::endl;
-    std::cout << "**************************" << std::endl << std::endl;
+    std::cout << "*******************" << std::endl;
+    std::cout << "**  GREENSCREEN  **" << std::endl;
+    std::cout << "*******************" << std::endl << std::endl;
     std::cout << "Version " << GreenScreen_VERSION_MAJOR << "." << GreenScreen_VERSION_MINOR << "."
               << GreenScreen_VERSION_PATCH << std::endl;
 
diff --git a/GreenScreen/manifest.json b/GreenScreen/manifest.json
index 5661ad2..0a35ec5 100644
--- a/GreenScreen/manifest.json
+++ b/GreenScreen/manifest.json
@@ -1,6 +1,6 @@
 {
     "name": "GreenScreen",
-    "description": "GreenScreen Plugin with onnx",
-    "version": "1.0.2",
+    "description": "This plugin hides your background during a call. Your banckground can be blured or changed with another image.",
+    "version": "2.0.0",
     "iconPath": "icon.svg"
-}
+}
\ No newline at end of file
diff --git a/GreenScreen/package.json b/GreenScreen/package.json
index 373f1b8..40949a7 100644
--- a/GreenScreen/package.json
+++ b/GreenScreen/package.json
@@ -1,6 +1,6 @@
 {
     "name": "GreenScreen",
-    "version": "1.0.2",
+    "version": "2.0.0",
     "extractLibs": false,
     "deps": [
         "ffmpeg",
diff --git a/GreenScreen/pluginMediaHandler.cpp b/GreenScreen/pluginMediaHandler.cpp
index 2643d6d..1bc9465 100644
--- a/GreenScreen/pluginMediaHandler.cpp
+++ b/GreenScreen/pluginMediaHandler.cpp
@@ -20,8 +20,8 @@
  */
 
 #include "pluginMediaHandler.h"
-// Logger
-#include "pluglog.h"
+
+#include <pluglog.h>
 #include <string_view>
 const char sep = separator();
 const std::string TAG = "FORESEG";
@@ -32,25 +32,24 @@
 
 PluginMediaHandler::PluginMediaHandler(std::map<std::string, std::string>&& preferences,
                                        std::string&& datapath)
-    : datapath_ {datapath}
+    : dataPath_ {datapath}
     , preferences_ {preferences}
 {
-    setId(datapath_);
+    setId(dataPath_);
 #ifdef __ANDROID__
-    mVS = std::make_shared<VideoSubscriber>(datapath_,
-                                            "mModel.ort",
-                                            preferences_.at("background"),
+    mVS = std::make_shared<VideoSubscriber>(dataPath_ + sep + "model/mModel.ort",
                                             preferences_.at("acceleration") == "1");
 #else
 #ifdef NVIDIA
-    mVS = std::make_shared<VideoSubscriber>(datapath_,
-                                            "mModel.onnx",
-                                            preferences_.at("background"),
+    mVS = std::make_shared<VideoSubscriber>(dataPath_ + sep + "model/mModel.onnx",
                                             preferences_.at("acceleration") == "1");
 #else
-    mVS = std::make_shared<VideoSubscriber>(datapath_, "mModel.onnx", preferences_.at("background"));
+    mVS = std::make_shared<VideoSubscriber>(dataPath_ + sep + "model/mModel.onnx");
 #endif // NVIDIA
 #endif // ANDROID
+    mVS->setBackground(preferences_.at("background"));
+    mVS->setBlur(preferences_.at("blur") == "1");
+    mVS->setBlurLevel(preferences_.at("blurlevel"));
 }
 
 void
@@ -68,12 +67,14 @@
     oss << "preferredStreamDirection " << preferredStreamDirection << std::endl;
     if (data.type == StreamType::video && !data.direction
         && data.direction == preferredStreamDirection) {
-        subject->attach(mVS.get()); // my image
+        detach();
+        subject->attachPriorityObserver(mVS); // my image
         oss << "got my sent image attached" << std::endl;
         attached_ = '1';
     } else if (data.type == StreamType::video && data.direction
                && data.direction == preferredStreamDirection) {
-        subject->attach(mVS.get()); // the image I receive from the others on the call
+        detach();
+        subject->attachPriorityObserver(mVS); // the image I receive from the others on the call
         oss << "got my received image attached" << std::endl;
         attached_ = '1';
     }
@@ -85,7 +86,7 @@
 PluginMediaHandler::getCallMediaHandlerDetails()
 {
     return {{"name", NAME},
-            {"iconPath", datapath_ + sep + "icon.svg"},
+            {"iconPath", dataPath_ + sep + "icon.svg"},
             {"pluginId", id()},
             {"attached", attached_},
             {"dataType", "1"}};
@@ -100,16 +101,19 @@
         if (key == "background") {
             mVS->setBackground(value);
         }
+        if (key == "blur") {
+            mVS->setBlur(value == "1");
+        }
+        if (key == "blurlevel") {
+            mVS->setBlurLevel(value);
+        }
     }
 }
 
 bool
 PluginMediaHandler::preferenceMapHasKey(const std::string& key)
 {
-    if (key == "background") {
-        return true;
-    }
-    return false;
+    return (key == "background" || key == "blur" || key == "blurlevel");
 }
 
 void
diff --git a/GreenScreen/pluginMediaHandler.h b/GreenScreen/pluginMediaHandler.h
index 3d2cc48..bc4a479 100644
--- a/GreenScreen/pluginMediaHandler.h
+++ b/GreenScreen/pluginMediaHandler.h
@@ -21,12 +21,10 @@
 
 #pragma once
 
-// Project
 #include "videoSubscriber.h"
 
-// Plugin
-#include "plugin/jamiplugin.h"
-#include "plugin/mediahandler.h"
+#include <plugin/jamiplugin.h>
+#include <plugin/mediahandler.h>
 
 using avSubjectPtr = std::weak_ptr<jami::Observable<AVFrame*>>;
 
@@ -48,7 +46,7 @@
     std::shared_ptr<VideoSubscriber> mVS;
 
 private:
-    const std::string datapath_;
+    const std::string dataPath_;
     std::map<std::string, std::string> preferences_;
     std::string attached_ {'0'};
 };
diff --git a/GreenScreen/pluginProcessor.cpp b/GreenScreen/pluginProcessor.cpp
index 62de879..ff4955b 100644
--- a/GreenScreen/pluginProcessor.cpp
+++ b/GreenScreen/pluginProcessor.cpp
@@ -20,202 +20,161 @@
  */
 
 #include "pluginProcessor.h"
-// System includes
-#include <algorithm>
-#include <cstring>
-// OpenCV headers
-#include <opencv2/core.hpp>
-#include <opencv2/imgcodecs.hpp>
-#include <opencv2/imgproc.hpp>
-// Logger
-#include <pluglog.h>
 
+#include <opencv2/imgproc.hpp>
 extern "C" {
 #include <libavutil/display.h>
 }
+#include <frameUtils.h>
+#include <pluglog.h>
+#ifdef WIN32
+#include <string_utils.h>
+#endif
 const char sep = separator();
 
 const std::string TAG = "FORESEG";
 
 namespace jami {
 
-PluginProcessor::PluginProcessor(const std::string& dataPath, const std::string& model, const std::string& backgroundImage, bool acc)
+PluginProcessor::PluginProcessor(const std::string& model, bool acc)
 {
-    activateAcc_ = acc;
-    initModel(dataPath+sep+"model/"+model);
-    setBackgroundImage(backgroundImage);
+    initModel(model, acc);
 }
 
 PluginProcessor::~PluginProcessor()
 {
+    mainFilter_.clean();
     Plog::log(Plog::LogPriority::INFO, TAG, "~pluginprocessor");
     if (session_)
         delete session_;
 }
 
 void
-PluginProcessor::setBackgroundImage(const std::string& backgroundPath)
-{
-    cv::Size size = cv::Size {0, 0};
-
-    if (!backgroundImage.empty())
-        size = backgroundImage.size();
-
-    cv::Mat newBackgroundImage = cv::imread(backgroundPath);
-    if (newBackgroundImage.cols == 0) {
-        Plog::log(Plog::LogPriority::ERR, TAG, "Background image not Loaded");
-    } else {
-        Plog::log(Plog::LogPriority::INFO, TAG, "Background image Loaded");
-        cv::cvtColor(newBackgroundImage, newBackgroundImage, cv::COLOR_BGR2RGB);
-        newBackgroundImage.convertTo(newBackgroundImage, CV_32FC3);
-        if (size.height) {
-            cv::resize(newBackgroundImage, newBackgroundImage, size);
-            backgroundRotation = 0;
-        }
-        backgroundImage = newBackgroundImage.clone();
-        newBackgroundImage.release();
-        hasBackground_ = true;
-    }
-}
-
-void
-PluginProcessor::initModel(const std::string& modelPath)
+PluginProcessor::initModel(const std::string& modelPath, bool activateAcc)
 {
     try {
         auto allocator_info = Ort::MemoryInfo::CreateCpu(OrtArenaAllocator, OrtMemTypeDefault);
-        input_tensor_ = Ort::Value::CreateTensor<float>(allocator_info, input_image_.data(), input_image_.size(), input_shape_.data(), input_shape_.size());
-        output_tensor_ = Ort::Value::CreateTensor<float>(allocator_info, results_.data(), results_.size(), output_shape_.data(), output_shape_.size());
-        sessOpt_ =  Ort::SessionOptions();
+        input_tensor_ = Ort::Value::CreateTensor<float>(allocator_info,
+                                                        input_image_.data(),
+                                                        input_image_.size(),
+                                                        input_shape_.data(),
+                                                        input_shape_.size());
+        output_tensor_ = Ort::Value::CreateTensor<float>(allocator_info,
+                                                         results_.data(),
+                                                         results_.size(),
+                                                         output_shape_.data(),
+                                                         output_shape_.size());
+        sessOpt_ = Ort::SessionOptions();
 
 #ifdef NVIDIA
-        if (activateAcc_)
+        if (activateAcc)
             Ort::ThrowOnError(OrtSessionOptionsAppendExecutionProvider_CUDA(sessOpt_, 0));
 #endif
-#ifdef ANDROID
-        if (activateAcc_)
+#ifdef __ANDROID__
+        if (activateAcc)
             Ort::ThrowOnError(OrtSessionOptionsAppendExecutionProvider_Nnapi(sessOpt_, 0));
 #endif
 
         sessOpt_.SetGraphOptimizationLevel(GraphOptimizationLevel::ORT_ENABLE_ALL);
 #ifdef WIN32
-        std::wstring wsTmp(modelPath.begin(), modelPath.end());
-        session_ = new Ort::Session(env, wsTmp.c_str(), sessOpt_);
+        session_ = new Ort::Session(env_, to_wstring(modelPath).c_str(), sessOpt_);
 #else
-        session_ = new Ort::Session(env, modelPath.c_str(), sessOpt_);
+        session_ = new Ort::Session(env_, modelPath.c_str(), sessOpt_);
 #endif
         isAllocated_ = true;
+        Plog::log(Plog::LogPriority::INFO, TAG, "Model is allocated");
     } catch (std::exception& e) {
         Plog::log(Plog::LogPriority::ERR, TAG, e.what());
     }
-    std::ostringstream oss;
-    oss << "Model is allocated " << isAllocated_;
-    Plog::log(Plog::LogPriority::INFO, TAG, oss.str());
-}
-
-bool
-PluginProcessor::isAllocated()
-{
-    return isAllocated_;
 }
 
 void
-PluginProcessor::feedInput(const cv::Mat& frame)
+PluginProcessor::feedInput(AVFrame* input)
 {
-    cv::Mat temp(frame.rows, frame.cols, CV_32FC3, input_image_.data());
-    frame.convertTo(temp, CV_32FC3);
-}
-
-int
-PluginProcessor::getBackgroundRotation()
-{
-    return backgroundRotation;
-}
-
-void
-PluginProcessor::setBackgroundRotation(int angle)
-{
-    if (backgroundRotation != angle && (backgroundRotation - angle) != 0) {
-        rotateFrame(backgroundRotation - angle, backgroundImage);
-        backgroundRotation = angle;
-    }
+    cv::Mat frame = cv::Mat {
+        input->height,
+        input->width,
+        CV_8UC3,
+        input->data[0],
+        static_cast<size_t>(
+            input->linesize[0])}; // not zero input->linesize[0] leads to non continuous data
+    cvFrame_ = frame.clone();     // this is done to have continuous data
+    cv::Mat temp(modelInputDimensions.first,
+                 modelInputDimensions.second,
+                 CV_32FC3,
+                 input_image_.data());
+    cvFrame_.convertTo(temp, CV_32FC3);
 }
 
 void
 PluginProcessor::computePredictions()
 {
-    if (count == 0) {
+    if (count_ == 0) {
         // Run the graph
-        session_->Run(Ort::RunOptions{nullptr}, input_names, &input_tensor_, 1, output_names, &output_tensor_, 1);
-        computedMask = std::vector(results_.begin(), results_.end());
+        session_->Run(Ort::RunOptions {nullptr},
+                      modelInputNames,
+                      &input_tensor_,
+                      1,
+                      modelOutputNames,
+                      &output_tensor_,
+                      1);
+        computedMask_ = std::vector(results_.begin(), results_.end());
     }
 }
 
 void
 PluginProcessor::printMask()
 {
-    for (size_t i = 0; i < computedMask.size(); i++) {
+    std::ostringstream oss;
+    for (size_t i = 0; i < computedMask_.size(); i++) {
         // Log the predictions
-        std::ostringstream oss;
-        oss << "\nclass: " << computedMask[i] << std::endl;
-        Plog::log(Plog::LogPriority::INFO, TAG, oss.str());
-    }
-}
-
-void
-PluginProcessor::resetInitValues(const cv::Size& modelInputSize)
-{
-    previousMasks[0] = cv::Mat(modelInputSize.height, modelInputSize.width, CV_32FC1, double(0.));
-    previousMasks[1] = cv::Mat(modelInputSize.height, modelInputSize.width, CV_32FC1, double(0.));
-    kSize = cv::Size(modelInputSize.width * kernelSize, modelInputSize.height * kernelSize);
-    if (kSize.height % 2 == 0) {
-        kSize.height -= 1;
-    }
-    if (kSize.width % 2 == 0) {
-        kSize.width -= 1;
-    }
-    count = 0;
-    grabCutMode = cv::GC_INIT_WITH_MASK;
-    grabCutIterations = 5;
-}
-
-void
-copyByLine(uchar* frameData, uchar* applyMaskData, const int lineSize, cv::Size size)
-{
-    if (3 * size.width == lineSize) {
-        std::memcpy(frameData, applyMaskData, size.height * size.width * 3);
-    } else {
-        int rows = size.height;
-        int offset = 0;
-        int maskoffset = 0;
-        for (int i = 0; i < rows; i++) {
-            std::memcpy(frameData + offset, applyMaskData + maskoffset, lineSize);
-            offset += lineSize;
-            maskoffset += 3 * size.width;
+        if (computedMask_[i] > 2) {
+            oss << computedMask_[i] << " " << std::endl;
         }
     }
+    Plog::log(Plog::LogPriority::INFO, TAG, oss.str());
 }
 
 void
-PluginProcessor::drawMaskOnFrame(
-    cv::Mat& frame, cv::Mat& frameReduced, std::vector<float> computedMask, int lineSize, int angle)
+PluginProcessor::resetInitValues()
 {
-    if (computedMask.empty()) {
-        return;
+    previousMasks_[0] = previousMasks_[1] = cv::Mat(modelInputDimensions.first,
+                                                    modelInputDimensions.second,
+                                                    CV_32FC1,
+                                                    double(0.));
+    kSize_ = cv::Size(modelInputDimensions.first * kernelSize_,
+                      modelInputDimensions.second * kernelSize_);
+    if (kSize_.height % 2 == 0) {
+        kSize_.height -= 1;
     }
+    if (kSize_.width % 2 == 0) {
+        kSize_.width -= 1;
+    }
+    count_ = 0;
+    grabCutMode_ = cv::GC_INIT_WITH_MASK;
+    grabCutIterations_ = 4;
+}
 
-    if (count == 0) {
-        int maskSize = static_cast<int>(std::sqrt(computedMask.size()));
-        cv::Mat maskImg(maskSize, maskSize, CV_32FC1, computedMask.data());
-        cv::Mat* applyMask = &frameReduced;
+void
+PluginProcessor::drawMaskOnFrame(AVFrame* frame, AVFrame* frameReduced, int angle)
+{
+    if (computedMask_.empty() || !mainFilter_.initialized_)
+        return;
 
-        rotateFrame(-angle, maskImg);
-        cv::resize(maskImg, maskImg, cv::Size(frameReduced.cols, frameReduced.rows));
+    if (count_ == 0) {
+        int maskSize = static_cast<int>(std::sqrt(computedMask_.size()));
+        cv::Mat maskImg(maskSize, maskSize, CV_32FC1, computedMask_.data());
+
+        cv::resize(maskImg,
+                   maskImg,
+                   cv::Size(modelInputDimensions.first, modelInputDimensions.second));
 
         double m, M;
         cv::minMaxLoc(maskImg, &m, &M);
-
-        if (M < 2) { // avoid detection if there is any one in frame
+        bool improveMask = !isBlur_;
+        if (M < 2) { // avoid detection if there isn't anyone in frame
             maskImg = 0. * maskImg;
+            improveMask = false;
         } else {
             for (int i = 0; i < maskImg.cols; i++) {
                 for (int j = 0; j < maskImg.rows; j++) {
@@ -224,9 +183,9 @@
                     if (maskImg.at<float>(j, i) < 0.4)
                         maskImg.at<float>(j, i) = 0.;
                     else if (maskImg.at<float>(j, i) < 0.7) {
-                        float value = maskImg.at<float>(j, i) * smoothFactors[0]
-                                      + previousMasks[0].at<float>(j, i) * smoothFactors[1]
-                                      + previousMasks[1].at<float>(j, i) * smoothFactors[2];
+                        float value = maskImg.at<float>(j, i) * smoothFactors_[0]
+                                      + previousMasks_[0].at<float>(j, i) * smoothFactors_[1]
+                                      + previousMasks_[1].at<float>(j, i) * smoothFactors_[2];
                         maskImg.at<float>(j, i) = 0.;
                         if (value > 0.7)
                             maskImg.at<float>(j, i) = 1.;
@@ -235,91 +194,230 @@
                 }
             }
         }
-        if (cv::countNonZero(maskImg) != 0) {
+
+        if (improveMask) {
             cv::Mat dilate;
             cv::dilate(maskImg,
-                        dilate,
-                        cv::getStructuringElement(cv::MORPH_ELLIPSE, kSize),
-                        cv::Point(-1, -1),
-                        2);
+                       dilate,
+                       cv::getStructuringElement(cv::MORPH_ELLIPSE, kSize_),
+                       cv::Point(-1, -1),
+                       2);
             cv::erode(maskImg,
-                        maskImg,
-                        cv::getStructuringElement(cv::MORPH_ELLIPSE, kSize),
-                        cv::Point(-1, -1),
-                        2);
+                      maskImg,
+                      cv::getStructuringElement(cv::MORPH_ELLIPSE, kSize_),
+                      cv::Point(-1, -1),
+                      2);
             for (int i = 0; i < maskImg.cols; i++) {
                 for (int j = 0; j < maskImg.rows; j++) {
                     if (dilate.at<float>(j, i) != maskImg.at<float>(j, i))
-                        maskImg.at<float>(j, i) = grabcutClass;
+                        maskImg.at<float>(j, i) = grabcutClass_;
                 }
             }
+            cv::Mat applyMask = cvFrame_.clone();
             maskImg.convertTo(maskImg, CV_8UC1);
-            applyMask->convertTo(*applyMask, CV_8UC1);
+            applyMask.convertTo(applyMask, CV_8UC1);
             cv::Rect rect(1, 1, maskImg.rows, maskImg.cols);
-            cv::grabCut(*applyMask,
+            cv::grabCut(applyMask,
                         maskImg,
                         rect,
-                        bgdModel,
-                        fgdModel,
-                        grabCutIterations,
-                        grabCutMode);
+                        bgdModel_,
+                        fgdModel_,
+                        grabCutIterations_,
+                        grabCutMode_);
 
-            grabCutMode = cv::GC_EVAL;
-            grabCutIterations = 1;
+            grabCutMode_ = cv::GC_EVAL;
+            grabCutIterations_ = 1;
 
             maskImg = maskImg & 1;
             maskImg.convertTo(maskImg, CV_32FC1);
             maskImg *= 255.;
-            GaussianBlur(maskImg, maskImg, cv::Size(7, 7), 0); // float mask from 0 to 255.
+            blur(maskImg, maskImg, cv::Size(7, 7)); // float mask from 0 to 255.
             maskImg = maskImg / 255.;
         }
-        previousMasks[1] = previousMasks[0].clone();
-        previousMasks[0] = maskImg.clone();
+
+        previousMasks_[1] = previousMasks_[0].clone();
+        previousMasks_[0] = maskImg.clone();
     }
 
-    cv::Mat roiMaskImg = previousMasks[0].clone();
-    cv::Mat roiMaskImgComplementary = 1. - roiMaskImg; // mask from 1. to 0
+    cv::Mat roiMaskImg = previousMasks_[0].clone() * 255.;
+    roiMaskImg.convertTo(roiMaskImg, CV_8UC1);
 
-    std::vector<cv::Mat> channels;
-    std::vector<cv::Mat> channelsComplementary;
+    gsFrame maskFrame = {av_frame_alloc(), frameFree};
+    maskFrame->format = AV_PIX_FMT_GRAY8;
+    maskFrame->width = roiMaskImg.cols;
+    maskFrame->height = roiMaskImg.rows;
+    maskFrame->linesize[0] = roiMaskImg.step;
+    if (av_frame_get_buffer(maskFrame.get(), 0) < 0)
+        return;
 
-    channels.emplace_back(roiMaskImg);
-    channels.emplace_back(roiMaskImg);
-    channels.emplace_back(roiMaskImg);
-    channelsComplementary.emplace_back(roiMaskImgComplementary);
-    channelsComplementary.emplace_back(roiMaskImgComplementary);
-    channelsComplementary.emplace_back(roiMaskImgComplementary);
+    maskFrame->data[0] = roiMaskImg.data;
+    maskFrame->pts = 1;
+    mainFilter_.feedInput(maskFrame.get(), "mask");
+    maskFrame.reset();
 
-    cv::merge(channels, roiMaskImg);
-    cv::merge(channelsComplementary, roiMaskImgComplementary);
+    if (isBlur_)
+        mainFilter_.feedInput(frameReduced, "input");
+    mainFilter_.feedInput(frame, "input2");
+    AVFrame* filteredFrame;
+    if ((filteredFrame = mainFilter_.readOutput())) {
+        moveFrom(frame, filteredFrame);
+        frameFree(filteredFrame);
+    }
+    count_++;
+    count_ = count_ % frameCount_;
+}
 
-    cv::Mat output;
-    frameReduced.convertTo(output, roiMaskImg.type());
-    output = output.mul(roiMaskImg);
-    output += backgroundImage.mul(roiMaskImgComplementary);
-    output.convertTo(output, frameReduced.type());
+MediaStream
+PluginProcessor::getbgAVFrameInfos()
+{
+    AVFormatContext* ctx = avformat_alloc_context();
+    // Open
+    if (avformat_open_input(&ctx, backgroundPath_.c_str(), NULL, NULL) != 0) {
+        avformat_free_context(ctx);
+        Plog::log(Plog::LogPriority::INFO, TAG, "Couldn't open input stream.");
+        return {};
+    }
+    pFormatCtx_.reset(ctx);
+    // Retrieve stream information
+    if (avformat_find_stream_info(pFormatCtx_.get(), NULL) < 0) {
+        Plog::log(Plog::LogPriority::INFO, TAG, "Couldn't find stream information.");
+        return {};
+    }
 
-    cv::resize(output, output, cv::Size(frame.cols, frame.rows));
+    // Dump valid information onto standard error
+    av_dump_format(pFormatCtx_.get(), 0, backgroundPath_.c_str(), false);
 
-    copyByLine(frame.data, output.data, lineSize, cv::Size(frame.cols, frame.rows));
-    count++;
-    count = count % frameCount;
+    // Find the video stream
+    for (int i = 0; i < static_cast<int>(pFormatCtx_->nb_streams); i++)
+        if (pFormatCtx_->streams[i]->codecpar->codec_type == AVMEDIA_TYPE_VIDEO) {
+            videoStream_ = i;
+            break;
+        }
+
+    if (videoStream_ == -1) {
+        Plog::log(Plog::LogPriority::INFO, TAG, "Didn't find a video stream.");
+        return {};
+    }
+
+    rational<int> fr = pFormatCtx_->streams[videoStream_]->r_frame_rate;
+    return MediaStream("background",
+                       pFormatCtx_->streams[videoStream_]->codecpar->format,
+                       1 / fr,
+                       pFormatCtx_->streams[videoStream_]->codecpar->width,
+                       pFormatCtx_->streams[videoStream_]->codecpar->height,
+                       0,
+                       fr);
 }
 
 void
-PluginProcessor::rotateFrame(int angle, cv::Mat& mat)
+PluginProcessor::loadBackground()
 {
-    if (angle == -90)
-        cv::rotate(mat, mat, cv::ROTATE_90_COUNTERCLOCKWISE);
-    else if (std::abs(angle) == 180)
-        cv::rotate(mat, mat, cv::ROTATE_180);
-    else if (angle == 90)
-        cv::rotate(mat, mat, cv::ROTATE_90_CLOCKWISE);
+    if (backgroundPath_.empty())
+        return;
+
+    auto bgStream_ = getbgAVFrameInfos();
+    if (mainFilter_.initialize(mainFilterDescription_, {maskms_, bgStream_, ims2_}) < 0)
+        return;
+
+    int got_frame;
+    AVCodecContext* pCodecCtx;
+    AVCodec* pCodec;
+    AVPacket* packet;
+
+    pCodecCtx = pFormatCtx_->streams[videoStream_]->codec;
+    pCodec = avcodec_find_decoder(pCodecCtx->codec_id);
+    if (pCodec == nullptr) {
+        mainFilter_.clean();
+        pFormatCtx_.reset();
+        Plog::log(Plog::LogPriority::INFO, TAG, "Codec not found.");
+        return;
+    }
+
+    // Open codec
+    if (avcodec_open2(pCodecCtx, pCodec, NULL) < 0) {
+        mainFilter_.clean();
+        pFormatCtx_.reset();
+        Plog::log(Plog::LogPriority::INFO, TAG, "Could not open codec.");
+        return;
+    }
+
+    packet = av_packet_alloc();
+    if (av_read_frame(pFormatCtx_.get(), packet) < 0) {
+        mainFilter_.clean();
+        avcodec_close(pCodecCtx);
+        av_packet_free(&packet);
+        pFormatCtx_.reset();
+        Plog::log(Plog::LogPriority::INFO, TAG, "Could not read packet from context.");
+        return;
+    }
+
+    AVFrame* bgImage = av_frame_alloc();
+    avcodec_decode_video2(pCodecCtx, bgImage, &got_frame, packet);
+    if (got_frame) {
+        mainFilter_.feedInput(bgImage, "background");
+        mainFilter_.feedEOF("background");
+    } else
+        mainFilter_.clean();
+
+    frameFree(bgImage);
+    avcodec_close(pCodecCtx);
+    av_packet_free(&packet);
+    pFormatCtx_.reset();
 }
 
-bool
-PluginProcessor::hasBackground() const
+void
+PluginProcessor::initFilters(const std::pair<int, int>& inputSize, int format, int angle)
 {
-    return hasBackground_;
+    resetInitValues();
+    mainFilter_.clean();
+
+    std::string rotateSides = "";
+    std::string scaleSize = std::to_string(inputSize.first) + ":"
+                            + std::to_string(inputSize.second);
+    Plog::log(Plog::LogPriority::INFO, TAG, scaleSize);
+    if (std::abs(angle) == 90) {
+        rotateSides = ":out_w=ih:out_h=iw";
+        scaleSize = std::to_string(inputSize.second) + ":" + std::to_string(inputSize.first);
+    }
+
+    rational<int> fr(1, 1);
+    ims_ = MediaStream("input",
+                       AV_PIX_FMT_RGB24,
+                       1 / fr,
+                       modelInputDimensions.first,
+                       modelInputDimensions.second,
+                       0,
+                       fr);
+    ims2_ = MediaStream("input2", format, 1 / fr, inputSize.first, inputSize.second, 0, fr);
+
+    maskms_ = MediaStream("mask",
+                          AV_PIX_FMT_GRAY8,
+                          1 / fr,
+                          modelInputDimensions.first,
+                          modelInputDimensions.second,
+                          0,
+                          fr);
+
+    if (isBlur_) {
+        mainFilterDescription_ = "[mask]negate[negated],[input][negated]alphamerge,boxblur="
+                                 + blurLevel_ + ",scale=" + scaleSize
+                                 + "[blured],[input2]format=rgb24,rotate=" + rotation[-angle]
+                                 + rotateSides
+                                 + "[input2formated],[input2formated][blured]overlay,rotate="
+                                 + rotation[angle] + rotateSides;
+        Plog::log(Plog::LogPriority::INFO, TAG, mainFilterDescription_);
+        mainFilter_.initialize(mainFilterDescription_, {maskms_, ims_, ims2_});
+    } else {
+        mainFilterDescription_ = "[mask]scale=" + scaleSize
+                                 + "[fgmask],[fgmask]split=2[bg][fg],[bg]negate[bgn],"
+                                 + "[background]scale=" + scaleSize + "[backgroundformated],"
+                                 + "[backgroundformated][bgn]alphamerge[background2],"
+                                 + "[input2]rotate=" + rotation[-angle] + rotateSides
+                                 + "[input2formated],[input2formated][fg]alphamerge[foreground],"
+                                 + "[foreground][background2]overlay," + "rotate=" + rotation[angle]
+                                 + rotateSides;
+        Plog::log(Plog::LogPriority::INFO, TAG, mainFilterDescription_);
+        loadBackground();
+    }
 }
 } // namespace jami
diff --git a/GreenScreen/pluginProcessor.h b/GreenScreen/pluginProcessor.h
index 0897527..36eaa78 100644
--- a/GreenScreen/pluginProcessor.h
+++ b/GreenScreen/pluginProcessor.h
@@ -20,46 +20,50 @@
  */
 
 #pragma once
-// STL
-#include <condition_variable>
-#include <cstdint>
+
 #include <map>
-#include <memory>
-#include <mutex>
-#include <thread>
 #include <vector>
-// AvFrame
 extern "C" {
 #include <libavutil/frame.h>
 }
-// Plugin
+
 #include <plugin/jamiplugin.h>
 #include <plugin/mediahandler.h>
 
-// Opencv processing
 #include <opencv2/core.hpp>
 #include <onnxruntime_cxx_api.h>
 #ifdef NVIDIA
 #include <cuda_provider_factory.h>
 #endif
-#ifdef ANDROID
+#ifdef __ANDROID__
 #include <nnapi_provider_factory.h>
 #endif
+
+#include <frameFilter.h>
+#include <frameUtils.h>
+#include <mediaStream.h>
+#include <functional>
+
 namespace jami {
 
+using gsFrame = std::unique_ptr<AVFrame, decltype(&frameFree)>;
+
+static const char* modelInputNames[8] = {"image:0"};
+static const char* modelOutputNames[11] = {"Identity:0"};
+
 class PluginProcessor
 {
 public:
-    PluginProcessor(const std::string& dataPath, const std::string& model, const std::string& backgroundImage, bool acc);
+    PluginProcessor(const std::string& model, bool acc);
     ~PluginProcessor();
 
-    void initModel(const std::string& modelPath);
+    void initModel(const std::string& modelPath, bool activateAcc);
     /**
      * @brief feedInput
      * Takes a frame and feeds it to the model storage for predictions
      * @param frame
      */
-    void feedInput(const cv::Mat& frame);
+    void feedInput(AVFrame* input);
 
     /**
      * @brief computePredictions
@@ -69,59 +73,66 @@
     void computePredictions();
 
     void printMask();
-    void drawMaskOnFrame(cv::Mat& frame,
-                         cv::Mat& frameReduced,
-                         std::vector<float> computedMask,
-                         int lineSize,
-                         int angle);
-    int getBackgroundRotation();
-    void setBackgroundRotation(int angle);
-    void setBackgroundImage(const std::string& backgroundPath);
-    void rotateFrame(int angle, cv::Mat& mat);
-    bool hasBackground() const;
-    void resetInitValues(const cv::Size& modelInputSize);
-    bool isAllocated();
+    void drawMaskOnFrame(AVFrame* frame, AVFrame* frameReduced, int angle);
+    bool isAllocated() { return isAllocated_; }
+    void setBlur(bool isBlur) { isBlur_ = isBlur; }
+    void setBlurLevel(const std::string& blurLevel) { blurLevel_ = blurLevel; }
+    void setBackgroundImage(const std::string& backgroundPath) { backgroundPath_ = backgroundPath; }
+    void initFilters(const std::pair<int, int>& inputSize, int format, int angle);
 
-    // Output predictions
-    std::vector<float> computedMask;
-
-    cv::Mat previousMasks[2];
-    cv::Mat backgroundImage;
-
-    cv::Size kSize;
-
-    std::string backgroundPath;
+    std::pair<int, int> modelInputDimensions {257, 257};
+    std::map<int, std::string> rotation = {{90, "-PI/2"},
+                                           {-90, "PI/2"},
+                                           {-180, "-PI"},
+                                           {180, "PI"},
+                                           {0, "0"}};
 
 private:
-    int count{0};
-    cv::Mat frame;
-    int backgroundRotation{0};
-    bool hasBackground_{false};
-    cv::Mat bgdModel, fgdModel;
-    int grabCutMode{1}; // cv::GC_INIT_WITH_MASK = 1;
-    int grabCutIterations{5};
-    int grabcutClass{3};
-    int frameCount{3};
-    float smoothFactors[3] = {0.6f, 0.3f, 0.1f};
-    float kernelSize{0.05f};
+    void resetInitValues();
+    void loadBackground();
+    MediaStream getbgAVFrameInfos();
 
-    bool isAllocated_{false};
-    Ort::Env env{ORT_LOGGING_LEVEL_WARNING, "test"};
-    Ort::Value input_tensor_{nullptr};
-    std::array<int64_t, 3> input_shape_{257, 257, 3};
+    bool isBlur_ {false};
+    std::string blurLevel_;
+    std::string backgroundPath_;
+    cv::Mat previousMasks_[2];
+    std::vector<float> computedMask_;
+    cv::Mat cvFrame_;
 
-    Ort::Value output_tensor_{nullptr};
-    std::array<int64_t, 4> output_shape_{1, 17, 17, 1};
+    // process variables
+    cv::Size kSize_;
+    int count_ {0};
+    cv::Mat bgdModel_, fgdModel_;
+    int grabCutMode_ {1}; // cv::GC_INIT_WITH_MASK = 1;
+    int grabCutIterations_ {4};
+    int grabcutClass_ {3};
+    int frameCount_ {5};
+    float smoothFactors_[3] = {0.6f, 0.3f, 0.1f};
+    float kernelSize_ {0.05f};
 
+    // filters
+    std::string mainFilterDescription_;
+    FrameFilter mainFilter_;
+    std::unique_ptr<AVFormatContext, std::function<void(AVFormatContext*)>> pFormatCtx_
+        = {avformat_alloc_context(), [](AVFormatContext* ptr) {
+               avformat_close_input(&ptr);
+               avformat_free_context(ptr);
+           }};
+    int videoStream_ {-1};
+    MediaStream ims_, ims2_, maskms_;
 
-    std::array<float, 257 * 257 * 3> input_image_{};
-    
-    std::array<float, 17 * 17> results_{};
-    Ort::Session* session_{};
-    const char* input_names[8] = {"image:0"};
-    const char* output_names[11] = {"Identity:0"};
+    // onnx related
+    bool isAllocated_ {false};
+    Ort::Env env_ {ORT_LOGGING_LEVEL_WARNING, "test"};
+    Ort::Session* session_ {};
     Ort::SessionOptions sessOpt_;
 
-    bool activateAcc_{false};
+    Ort::Value input_tensor_ {nullptr};
+    std::array<int64_t, 3> input_shape_ {257, 257, 3};
+    std::array<float, 257 * 257 * 3> input_image_ {};
+
+    Ort::Value output_tensor_ {nullptr};
+    std::array<int64_t, 4> output_shape_ {1, 17, 17, 1};
+    std::array<float, 17 * 17> results_ {};
 };
 } // namespace jami
diff --git a/GreenScreen/preferences-accel.json b/GreenScreen/preferences-accel.json
index 8f87311..af90f21 100644
--- a/GreenScreen/preferences-accel.json
+++ b/GreenScreen/preferences-accel.json
@@ -6,6 +6,15 @@
         "title": "Background image",
         "summary": "Select background image file",
         "defaultValue": "data/backgrounds/background2.jpeg",
+        "scope": "plugin,Foreground Segmentation",
+        "dependsOn": "!blur"
+    },
+    {
+        "type": "Switch",
+        "key": "blur",
+        "title": "Blur",
+        "summary": "Do you want to blur background?",
+        "defaultValue": "0",
         "scope": "plugin,Foreground Segmentation"
     },
     {
@@ -18,6 +27,17 @@
     },
     {
         "type": "List",
+        "key": "blurlevel",
+        "title": "Blur level",
+        "summary": "Select how much blur do you want.",
+        "defaultValue": "8",
+        "entries": ["1", "2", "3", "4", "5", "6", "7", "8", "9", "10"],
+        "entryValues": ["1", "2", "3", "4", "5", "6", "7", "8", "9", "10"],
+        "scope": "plugin,Foreground Segmentation",
+        "dependsOn": "blur"
+    },
+    {
+        "type": "List",
         "key": "streamslist",
         "title": "Video stream",
         "summary": "Select stream",
diff --git a/GreenScreen/preferences.json b/GreenScreen/preferences.json
index 94b6b8f..8ee350c 100644
--- a/GreenScreen/preferences.json
+++ b/GreenScreen/preferences.json
@@ -6,10 +6,30 @@
         "title": "Background image",
         "summary": "Select background image file",
         "defaultValue": "data/backgrounds/background2.jpeg",
+        "scope": "plugin,Foreground Segmentation",
+        "dependsOn": "!blur"
+    },
+    {
+        "type": "Switch",
+        "key": "blur",
+        "title": "Blur",
+        "summary": "Do you want to blur background?",
+        "defaultValue": "0",
         "scope": "plugin,Foreground Segmentation"
     },
     {
         "type": "List",
+        "key": "blurlevel",
+        "title": "Blur level",
+        "summary": "Select how much blur do you want.",
+        "defaultValue": "8",
+        "entries": ["1", "2", "3", "4", "5", "6", "7", "8", "9", "10"],
+        "entryValues": ["1", "2", "3", "4", "5", "6", "7", "8", "9", "10"],
+        "scope": "plugin,Foreground Segmentation",
+        "dependsOn": "blur"
+    },
+    {
+        "type": "List",
         "key": "streamslist",
         "title": "Video stream",
         "summary": "Select stream",
diff --git a/GreenScreen/videoSubscriber.cpp b/GreenScreen/videoSubscriber.cpp
index 583a5c5..92147c8 100644
--- a/GreenScreen/videoSubscriber.cpp
+++ b/GreenScreen/videoSubscriber.cpp
@@ -20,18 +20,12 @@
  */
 
 #include "videoSubscriber.h"
-// Use for display rotation matrix
+
 extern "C" {
 #include <libavutil/display.h>
 }
 #include <accel.h>
-#include <frameUtils.h>
-
-// Opencv processing
-#include <opencv2/imgcodecs.hpp>
-#include <opencv2/imgproc.hpp>
-
-// LOGGING
+#include <mediaStream.h>
 #include <pluglog.h>
 
 const std::string TAG = "FORESEG";
@@ -39,12 +33,8 @@
 
 namespace jami {
 
-VideoSubscriber::VideoSubscriber(const std::string& dataPath,
-                                 const std::string& model,
-                                 const std::string& backgroundImage,
-                                 bool acc)
-    : path_ {dataPath}
-    , pluginProcessor {dataPath, model, backgroundImage, acc}
+VideoSubscriber::VideoSubscriber(const std::string& model, bool acc)
+    : pluginProcessor {model, acc}
 {
     /**
      * Waits for new frames and then process them
@@ -58,7 +48,7 @@
                 break;
             }
 
-            pluginProcessor.feedInput(fcopy.resizedFrameRGB);
+            pluginProcessor.feedInput(inputFrame_.get());
             newFrame = false;
             /** Unclock the mutex, this way we let the other thread
              *  copy new data while we are processing the old one
@@ -71,123 +61,96 @@
 
 VideoSubscriber::~VideoSubscriber()
 {
-    std::ostringstream oss;
-    oss << "~MediaProcessor" << std::endl;
+    inputFilter_.clean();
+    detach();
     stop();
     processFrameThread.join();
-    Plog::log(Plog::LogPriority::INFO, TAG, oss.str());
+    Plog::log(Plog::LogPriority::INFO, TAG, "~MediaProcessor");
 }
 
 void
 VideoSubscriber::update(jami::Observable<AVFrame*>*, AVFrame* const& pluginFrame)
 {
-    if (!observable_ || !pluginProcessor.isAllocated() || !pluginProcessor.hasBackground()
-        || !pluginFrame)
+    if (!observable_ || !pluginProcessor.isAllocated() || !pluginFrame)
         return;
 
     //======================================================================================
     // GET FRAME ROTATION
     AVFrameSideData* side_data = av_frame_get_side_data(pluginFrame, AV_FRAME_DATA_DISPLAYMATRIX);
-
-    int angle {0};
+    int newAngle {0};
     if (side_data) {
         auto matrix_rotation = reinterpret_cast<int32_t*>(side_data->data);
-        angle = static_cast<int>(av_display_rotation_get(matrix_rotation));
+        newAngle = static_cast<int>(av_display_rotation_get(matrix_rotation));
+    }
+    if (newAngle != angle_) {
+        angle_ = newAngle;
+        firstRun = true;
     }
 
     //======================================================================================
     // GET RAW FRAME
-    // Use a non-const Frame
-    // Convert input frame to RGB
-    int inputHeight = pluginFrame->height;
-    int inputWidth = pluginFrame->width;
-
-    fcopy.originalSize = cv::Size {inputWidth, inputHeight};
-
-    AVFrame* temp = transferToMainMemory(pluginFrame, AV_PIX_FMT_NV12);
-    AVFrame* bgrFrame = scaler.convertFormat(temp, AV_PIX_FMT_RGB24);
-    av_frame_unref(temp);
-    av_frame_free(&temp);
-    if (!bgrFrame)
+    gsFrame rgbFrame = {transferToMainMemory(pluginFrame, AV_PIX_FMT_NV12), frameFree};
+    if (!rgbFrame.get())
         return;
-    cv::Mat frame = cv::Mat {bgrFrame->height,
-                             bgrFrame->width,
-                             CV_8UC3,
-                             bgrFrame->data[0],
-                             static_cast<size_t>(bgrFrame->linesize[0])};
-    // First clone the frame as the original one is unusable because of
-    // linespace
+    rgbFrame->pts = 1;
 
-    cv::Mat clone = frame.clone();
     //======================================================================================
-
-    pluginProcessor.setBackgroundRotation(angle);
-
+    // PROCESS
     if (firstRun) {
-        fcopy.resizedSize = cv::Size {257, 257};
-        pluginProcessor.resetInitValues(fcopy.resizedSize);
-
-        cv::resize(clone, fcopy.resizedFrameRGB, fcopy.resizedSize);
-        pluginProcessor.rotateFrame(angle, fcopy.resizedFrameRGB);
-
-        cv::resize(pluginProcessor.backgroundImage,
-                   pluginProcessor.backgroundImage,
-                   fcopy.resizedSize);
+        initFilters();
+        pluginProcessor.initFilters({rgbFrame->width, rgbFrame->height}, rgbFrame->format, angle_);
+        rational<int> fr(rgbFrame->pts, 1);
+        MediaStream pluginstream_ = MediaStream("input",
+                                                rgbFrame->format,
+                                                1 / fr,
+                                                rgbFrame->width,
+                                                rgbFrame->height,
+                                                0,
+                                                fr);
+        inputFilter_.initialize(inputFilterDescription_, {pluginstream_});
 
         firstRun = false;
     }
+    if (!inputFilter_.initialized_)
+        return;
+
+    AVFrame* filteredFrame;
+    if (inputFilter_.feedInput(rgbFrame.get(), "input") == 0) {
+        if ((filteredFrame = inputFilter_.readOutput()) == 0)
+            return;
+        else
+            filteredFrame->pts = 1;
+    } else
+        return;
 
     if (!newFrame) {
         std::lock_guard<std::mutex> l(inputLock);
-        cv::resize(clone, fcopy.resizedFrameRGB, fcopy.resizedSize);
-        pluginProcessor.rotateFrame(angle, fcopy.resizedFrameRGB);
+        inputFrame_.reset(av_frame_clone(filteredFrame));
         newFrame = true;
         inputCv.notify_all();
     }
 
-    fcopy.predictionsFrameRGB = frame;
-    fcopy.predictionsResizedFrameRGB = fcopy.resizedFrameRGB.clone();
-    pluginProcessor.rotateFrame(-angle, fcopy.predictionsResizedFrameRGB);
-    pluginProcessor.drawMaskOnFrame(fcopy.predictionsFrameRGB,
-                                    fcopy.predictionsResizedFrameRGB,
-                                    pluginProcessor.computedMask,
-                                    bgrFrame->linesize[0],
-                                    angle);
+    pluginProcessor.drawMaskOnFrame(rgbFrame.get(), filteredFrame, angle_);
+    frameFree(filteredFrame);
 
-    //======================================================================================
-    // REPLACE AVFRAME DATA WITH FRAME DATA
-    if (bgrFrame->data[0]) {
-        uint8_t* frameData = bgrFrame->data[0];
-        if (angle == 90 || angle == -90) {
-            std::memmove(frameData,
-                         fcopy.predictionsFrameRGB.data,
-                         static_cast<size_t>(pluginFrame->width * pluginFrame->height * 3)
-                             * sizeof(uint8_t));
-        }
-
-        moveFrom(pluginFrame, bgrFrame);
-    }
-    av_frame_unref(bgrFrame);
-    av_frame_free(&bgrFrame);
+    moveFrom(pluginFrame, rgbFrame.get());
 }
 
 void
 VideoSubscriber::attached(jami::Observable<AVFrame*>* observable)
 {
-    std::ostringstream oss;
-    oss << "::Attached ! " << std::endl;
-    Plog::log(Plog::LogPriority::INFO, TAG, oss.str());
     observable_ = observable;
+    Plog::log(Plog::LogPriority::INFO, TAG, "Attached!");
 }
 
 void
 VideoSubscriber::detached(jami::Observable<AVFrame*>*)
 {
+    inputFilter_.clean();
+    inputFrame_.reset();
     firstRun = true;
     observable_ = nullptr;
-    std::ostringstream oss;
-    oss << "::Detached()" << std::endl;
-    Plog::log(Plog::LogPriority::INFO, TAG, oss.str());
+    Plog::log(Plog::LogPriority::INFO, TAG, "Detached!");
 }
 
 void
@@ -195,10 +158,7 @@
 {
     if (observable_) {
         firstRun = true;
-        std::ostringstream oss;
-        oss << "::Calling detach()" << std::endl;
-        Plog::log(Plog::LogPriority::INFO, TAG, oss.str());
-        observable_->detach(this);
+        observable_->detachPriorityObserver(this);
     }
 }
 
@@ -213,5 +173,35 @@
 VideoSubscriber::setBackground(const std::string& backgroundPath)
 {
     pluginProcessor.setBackgroundImage(backgroundPath);
+    firstRun = true;
+}
+
+void
+VideoSubscriber::setBlur(bool isBlur)
+{
+    pluginProcessor.setBlur(isBlur);
+    firstRun = true;
+}
+
+void
+VideoSubscriber::setBlurLevel(const std::string& blurLevel)
+{
+    pluginProcessor.setBlurLevel(blurLevel);
+    firstRun = true;
+}
+
+void
+VideoSubscriber::initFilters()
+{
+    inputFilter_.clean();
+    std::string rotateSides = "";
+    if (std::abs(angle_) == 90)
+        rotateSides = ":out_w=ih:out_h=iw";
+    inputFilterDescription_ = "[input]scale="
+                              + std::to_string(pluginProcessor.modelInputDimensions.first) + ":"
+                              + std::to_string(pluginProcessor.modelInputDimensions.second)
+                              + ",rotate=" + pluginProcessor.rotation[-angle_] + rotateSides
+                              + ",format=rgb24";
+    Plog::log(Plog::LogPriority::INFO, TAG, inputFilterDescription_);
 }
 } // namespace jami
diff --git a/GreenScreen/videoSubscriber.h b/GreenScreen/videoSubscriber.h
index f23f02d..9841ec7 100644
--- a/GreenScreen/videoSubscriber.h
+++ b/GreenScreen/videoSubscriber.h
@@ -20,44 +20,23 @@
 
 #pragma once
 
-// AvFrame
+#include "pluginProcessor.h"
+
 extern "C" {
 #include <libavutil/frame.h>
 }
 #include <observer.h>
 
-// STl
-#include <map>
 #include <thread>
 #include <condition_variable>
-
-#include <opencv2/core.hpp>
-
-#include "pluginProcessor.h"
-#include <frameScaler.h>
+#include <frameFilter.h>
 
 namespace jami {
 
-class FrameCopy
-{
-public:
-    // This frame is a resized version of the original in RGB format
-    cv::Mat resizedFrameRGB;
-    cv::Size resizedSize;
-    // This frame is used to draw predictions into in RGB format
-    cv::Mat predictionsFrameRGB;
-    cv::Size originalSize;
-    // This frame is used to draw predictions into in RGB format on a resized frame
-    cv::Mat predictionsResizedFrameRGB;
-};
-
 class VideoSubscriber : public jami::Observer<AVFrame*>
 {
 public:
-    VideoSubscriber(const std::string& dataPath,
-                    const std::string& model,
-                    const std::string& backgroundImage,
-                    bool acc = false);
+    VideoSubscriber(const std::string& model, bool acc = false);
     ~VideoSubscriber();
 
     virtual void update(jami::Observable<AVFrame*>*, AVFrame* const&) override;
@@ -67,19 +46,17 @@
     void detach();
     void stop();
     void setBackground(const std::string& backgroundPath);
+    void setBlur(bool isBlur);
+    void setBlurLevel(const std::string& blurLevel);
+    void initFilters();
 
 private:
     // Observer pattern
     Observable<AVFrame*>* observable_ {};
-
-    // Data
-    std::string path_;
-
-    // Frame
-    FrameCopy fcopy;
-    cv::Mat frame;
-
-    FrameScaler scaler;
+    int angle_ {0};
+    gsFrame inputFrame_ = {av_frame_alloc(), frameFree};
+    FrameFilter inputFilter_;
+    std::string inputFilterDescription_;
 
     // Threading
     std::thread processFrameThread;
@@ -91,7 +68,6 @@
     bool running {true};
     bool newFrame {false};
 
-    // std::shared_ptr<PluginProcessor> pluginProcessor;
     PluginProcessor pluginProcessor;
 };
 } // namespace jami
diff --git a/GreenScreen/zlib/libzlib.vcxproj b/GreenScreen/zlib/libzlib.vcxproj
new file mode 100644
index 0000000..81f9634
--- /dev/null
+++ b/GreenScreen/zlib/libzlib.vcxproj
@@ -0,0 +1,918 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project DefaultTargets="Build" ToolsVersion="12.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+  <ItemGroup Label="ProjectConfigurations">
+    <ProjectConfiguration Include="DebugDLL|Win32">
+      <Configuration>DebugDLL</Configuration>
+      <Platform>Win32</Platform>
+    </ProjectConfiguration>
+    <ProjectConfiguration Include="DebugDLL|x64">
+      <Configuration>DebugDLL</Configuration>
+      <Platform>x64</Platform>
+    </ProjectConfiguration>
+    <ProjectConfiguration Include="Debug|Win32">
+      <Configuration>Debug</Configuration>
+      <Platform>Win32</Platform>
+    </ProjectConfiguration>
+    <ProjectConfiguration Include="Debug|x64">
+      <Configuration>Debug</Configuration>
+      <Platform>x64</Platform>
+    </ProjectConfiguration>
+    <ProjectConfiguration Include="ReleaseDLL|Win32">
+      <Configuration>ReleaseDLL</Configuration>
+      <Platform>Win32</Platform>
+    </ProjectConfiguration>
+    <ProjectConfiguration Include="ReleaseDLL|x64">
+      <Configuration>ReleaseDLL</Configuration>
+      <Platform>x64</Platform>
+    </ProjectConfiguration>
+    <ProjectConfiguration Include="ReleaseLTO|Win32">
+      <Configuration>ReleaseLTO</Configuration>
+      <Platform>Win32</Platform>
+    </ProjectConfiguration>
+    <ProjectConfiguration Include="ReleaseLTO|x64">
+      <Configuration>ReleaseLTO</Configuration>
+      <Platform>x64</Platform>
+    </ProjectConfiguration>
+    <ProjectConfiguration Include="Release|Win32">
+      <Configuration>Release</Configuration>
+      <Platform>Win32</Platform>
+    </ProjectConfiguration>
+    <ProjectConfiguration Include="Release|x64">
+      <Configuration>Release</Configuration>
+      <Platform>x64</Platform>
+    </ProjectConfiguration>
+  </ItemGroup>
+  <PropertyGroup Label="Globals">
+    <ProjectGuid>{CA9A4A38-CC63-4BDB-8CFB-E058965DDA32}</ProjectGuid>
+    <RootNamespace>libzlib</RootNamespace>
+  </PropertyGroup>
+  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
+    <ConfigurationType>StaticLibrary</ConfigurationType>
+    <UseDebugLibraries>true</UseDebugLibraries>
+    <PlatformToolset>v142</PlatformToolset>
+    <PlatformToolset>v142</PlatformToolset>
+    <PlatformToolset>v142</PlatformToolset>
+    <CharacterSet>Unicode</CharacterSet>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
+    <ConfigurationType>StaticLibrary</ConfigurationType>
+    <UseDebugLibraries>true</UseDebugLibraries>
+    <PlatformToolset>v142</PlatformToolset>
+    <PlatformToolset>v142</PlatformToolset>
+    <PlatformToolset>v142</PlatformToolset>
+    <CharacterSet>Unicode</CharacterSet>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='DebugDLL|Win32'" Label="Configuration">
+    <ConfigurationType>DynamicLibrary</ConfigurationType>
+    <UseDebugLibraries>true</UseDebugLibraries>
+    <PlatformToolset>v142</PlatformToolset>
+    <PlatformToolset>v142</PlatformToolset>
+    <PlatformToolset>v142</PlatformToolset>
+    <CharacterSet>Unicode</CharacterSet>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='DebugDLL|x64'" Label="Configuration">
+    <ConfigurationType>DynamicLibrary</ConfigurationType>
+    <UseDebugLibraries>true</UseDebugLibraries>
+    <PlatformToolset>v142</PlatformToolset>
+    <PlatformToolset>v142</PlatformToolset>
+    <PlatformToolset>v142</PlatformToolset>
+    <CharacterSet>Unicode</CharacterSet>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
+    <ConfigurationType>StaticLibrary</ConfigurationType>
+    <UseDebugLibraries>false</UseDebugLibraries>
+    <PlatformToolset>v142</PlatformToolset>
+    <PlatformToolset>v142</PlatformToolset>
+    <PlatformToolset>v142</PlatformToolset>
+    <CharacterSet>Unicode</CharacterSet>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseLTO|Win32'" Label="Configuration">
+    <ConfigurationType>StaticLibrary</ConfigurationType>
+    <UseDebugLibraries>false</UseDebugLibraries>
+    <PlatformToolset>v142</PlatformToolset>
+    <PlatformToolset>v142</PlatformToolset>
+    <PlatformToolset>v142</PlatformToolset>
+    <CharacterSet>Unicode</CharacterSet>
+    <WholeProgramOptimization>true</WholeProgramOptimization>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
+    <ConfigurationType>StaticLibrary</ConfigurationType>
+    <UseDebugLibraries>false</UseDebugLibraries>
+    <PlatformToolset>v142</PlatformToolset>
+    <PlatformToolset>v142</PlatformToolset>
+    <PlatformToolset>v142</PlatformToolset>
+    <CharacterSet>Unicode</CharacterSet>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseLTO|x64'" Label="Configuration">
+    <ConfigurationType>StaticLibrary</ConfigurationType>
+    <UseDebugLibraries>false</UseDebugLibraries>
+    <PlatformToolset>v142</PlatformToolset>
+    <PlatformToolset>v142</PlatformToolset>
+    <PlatformToolset>v142</PlatformToolset>
+    <CharacterSet>Unicode</CharacterSet>
+    <WholeProgramOptimization>true</WholeProgramOptimization>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|Win32'" Label="Configuration">
+    <ConfigurationType>DynamicLibrary</ConfigurationType>
+    <UseDebugLibraries>false</UseDebugLibraries>
+    <PlatformToolset>v142</PlatformToolset>
+    <PlatformToolset>v142</PlatformToolset>
+    <PlatformToolset>v142</PlatformToolset>
+    <CharacterSet>Unicode</CharacterSet>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|x64'" Label="Configuration">
+    <ConfigurationType>DynamicLibrary</ConfigurationType>
+    <UseDebugLibraries>false</UseDebugLibraries>
+    <PlatformToolset>v142</PlatformToolset>
+    <PlatformToolset>v142</PlatformToolset>
+    <PlatformToolset>v142</PlatformToolset>
+    <CharacterSet>Unicode</CharacterSet>
+  </PropertyGroup>
+  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
+  <ImportGroup Label="ExtensionSettings" />
+  <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+  </ImportGroup>
+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="PropertySheets">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+  </ImportGroup>
+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='DebugDLL|Win32'" Label="PropertySheets">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+  </ImportGroup>
+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='DebugDLL|x64'" Label="PropertySheets">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+  </ImportGroup>
+  <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+  </ImportGroup>
+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseLTO|Win32'" Label="PropertySheets">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+  </ImportGroup>
+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="PropertySheets">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+  </ImportGroup>
+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseLTO|x64'" Label="PropertySheets">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+  </ImportGroup>
+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|Win32'" Label="PropertySheets">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+  </ImportGroup>
+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|x64'" Label="PropertySheets">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+  </ImportGroup>
+  <PropertyGroup Label="UserMacros" />
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+    <OutDir>$(ProjectDir)..\..\..\msvc\</OutDir>
+    <IntDir>$(SolutionDir)obj\$(Configuration)\$(Platform)\$(ProjectName)\</IntDir>
+    <TargetName>libzlibd</TargetName>
+    <CustomBuildAfterTargets>Clean</CustomBuildAfterTargets>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+    <OutDir>$(ProjectDir)..\..\..\msvc\</OutDir>
+    <IntDir>$(SolutionDir)obj\$(Configuration)\$(Platform)\$(ProjectName)\</IntDir>
+    <TargetName>libzlib</TargetName>
+    <CustomBuildAfterTargets>Clean</CustomBuildAfterTargets>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseLTO|Win32'">
+    <OutDir>$(ProjectDir)..\..\..\msvc\</OutDir>
+    <IntDir>$(SolutionDir)obj\$(Configuration)\$(Platform)\$(ProjectName)\</IntDir>
+    <TargetName>libzlib</TargetName>
+    <CustomBuildAfterTargets>Clean</CustomBuildAfterTargets>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|Win32'">
+    <OutDir>$(ProjectDir)..\..\..\msvc\</OutDir>
+    <IntDir>$(SolutionDir)obj\$(Configuration)\$(Platform)\$(ProjectName)\</IntDir>
+    <TargetName>zlib</TargetName>
+    <CustomBuildAfterTargets>Clean</CustomBuildAfterTargets>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='DebugDLL|Win32'">
+    <OutDir>$(ProjectDir)..\..\..\msvc\</OutDir>
+    <IntDir>$(SolutionDir)obj\$(Configuration)\$(Platform)\$(ProjectName)\</IntDir>
+    <TargetName>zlibd</TargetName>
+    <CustomBuildAfterTargets>Clean</CustomBuildAfterTargets>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+    <OutDir>$(ProjectDir)..\..\..\msvc\</OutDir>
+    <IntDir>$(SolutionDir)obj\$(Configuration)\$(Platform)\$(ProjectName)\</IntDir>
+    <TargetName>libzlibd</TargetName>
+    <CustomBuildAfterTargets>Clean</CustomBuildAfterTargets>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+    <OutDir>$(ProjectDir)..\..\..\msvc\</OutDir>
+    <IntDir>$(SolutionDir)obj\$(Configuration)\$(Platform)\$(ProjectName)\</IntDir>
+    <TargetName>libzlib</TargetName>
+    <CustomBuildAfterTargets>Clean</CustomBuildAfterTargets>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseLTO|x64'">
+    <OutDir>$(ProjectDir)..\..\..\msvc\</OutDir>
+    <IntDir>$(SolutionDir)obj\$(Configuration)\$(Platform)\$(ProjectName)\</IntDir>
+    <TargetName>libzlib</TargetName>
+    <CustomBuildAfterTargets>Clean</CustomBuildAfterTargets>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|x64'">
+    <OutDir>$(ProjectDir)..\..\..\msvc\</OutDir>
+    <IntDir>$(SolutionDir)obj\$(Configuration)\$(Platform)\$(ProjectName)\</IntDir>
+    <TargetName>zlib</TargetName>
+    <CustomBuildAfterTargets>Clean</CustomBuildAfterTargets>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='DebugDLL|x64'">
+    <OutDir>$(ProjectDir)..\..\..\msvc\</OutDir>
+    <IntDir>$(SolutionDir)obj\$(Configuration)\$(Platform)\$(ProjectName)\</IntDir>
+    <TargetName>zlibd</TargetName>
+    <CustomBuildAfterTargets>Clean</CustomBuildAfterTargets>
+  </PropertyGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+    <ClCompile>
+      <WarningLevel>Level3</WarningLevel>
+      <Optimization>Disabled</Optimization>
+      <PreprocessorDefinitions>WIN32;_WIN32_WINNT=0x0502;_DEBUG;DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <MultiProcessorCompilation>true</MultiProcessorCompilation>
+      <AdditionalIncludeDirectories>.\;..\;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+      <DisableSpecificWarnings>4996;%(DisableSpecificWarnings)</DisableSpecificWarnings>
+      <ProgramDataBaseFileName>$(OutDir)\lib\x86\$(TargetName).pdb</ProgramDataBaseFileName>
+      <MinimalRebuild>false</MinimalRebuild>
+    </ClCompile>
+    <Link>
+      <GenerateDebugInformation>true</GenerateDebugInformation>
+    </Link>
+    <Lib>
+      <OutputFile>$(OutDir)\lib\x86\$(TargetName)$(TargetExt)</OutputFile>
+    </Lib>
+    <Lib>
+      <TargetMachine>MachineX86</TargetMachine>
+    </Lib>
+    <Lib>
+      <SubSystem>Windows</SubSystem>
+    </Lib>
+    <MASM>
+      <UseSafeExceptionHandlers>true</UseSafeExceptionHandlers>
+    </MASM>
+    <PostBuildEvent>
+      <Command>mkdir "$(OutDir)"\include
+copy ..\zlib.h "$(OutDir)"\include
+copy "$(OutDir)"\..\src\zlib\zconf.h "$(OutDir)"\include /Y
+copy "$(OutDir)"\lib\$(Platform)\libzlib.lib "$(OutDir)"\lib\$(Platform)\zlib.lib /Y
+mkdir $(OutDir)\licenses
+copy ..\README $(OutDir)\licenses\zlib.txt</Command>
+    </PostBuildEvent>
+    <PreBuildEvent>
+      <Command>if exist ..\zconf.h (
+del ..\zconf.h
+)
+if exist "$(OutDir)"\include\zlib.h (
+del "$(OutDir)"\include\zlib.h
+)
+if exist "$(OutDir)"\include\zconf.h (
+del "$(OutDir)"\include\zconf.h
+)</Command>
+    </PreBuildEvent>
+    <CustomBuildStep>
+      <Message>Custom Clean Step</Message>
+    </CustomBuildStep>
+    <CustomBuildStep>
+      <Outputs>force_clean</Outputs>
+      <Command>if exist "$(OutDir)"\include\zlib.h (
+del /f /q "$(OutDir)"\include\zlib.h
+)
+if exist "$(OutDir)"\include\zconf.h (
+del /f /q "$(OutDir)"\include\zconf.h
+)
+if exist $(OutDir)\licenses\zlib.txt (
+del /f /q $(OutDir)\licenses\zlib.txt
+)</Command>
+    </CustomBuildStep>
+  </ItemDefinitionGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+    <ClCompile>
+      <WarningLevel>Level3</WarningLevel>
+      <Optimization>Disabled</Optimization>
+      <PreprocessorDefinitions>WIN64;_WIN32_WINNT=0x0600;_DEBUG;DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <MultiProcessorCompilation>true</MultiProcessorCompilation>
+      <AdditionalIncludeDirectories>.\;..\;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+      <DisableSpecificWarnings>4996;%(DisableSpecificWarnings)</DisableSpecificWarnings>
+      <ProgramDataBaseFileName>$(OutDir)\lib\x64\$(TargetName).pdb</ProgramDataBaseFileName>
+      <MinimalRebuild>false</MinimalRebuild>
+    </ClCompile>
+    <Link>
+      <GenerateDebugInformation>true</GenerateDebugInformation>
+    </Link>
+    <Lib>
+      <SubSystem>Windows</SubSystem>
+      <OutputFile>$(OutDir)\lib\x64\$(TargetName)$(TargetExt)</OutputFile>
+    </Lib>
+    <MASM>
+      <UseSafeExceptionHandlers>true</UseSafeExceptionHandlers>
+    </MASM>
+    <PostBuildEvent>
+      <Command>mkdir "$(OutDir)"\include
+copy ..\zlib.h "$(OutDir)"\include
+copy "$(OutDir)"\..\src\zlib\zconf.h "$(OutDir)"\include /Y
+copy "$(OutDir)"\lib\$(Platform)\libzlib.lib "$(OutDir)"\lib\$(Platform)\zlib.lib /Y
+mkdir $(OutDir)\licenses
+copy ..\README $(OutDir)\licenses\zlib.txt</Command>
+    </PostBuildEvent>
+    <PreBuildEvent>
+      <Command>if exist ..\zconf.h (
+del ..\zconf.h
+)
+if exist "$(OutDir)"\include\zlib.h (
+del "$(OutDir)"\include\zlib.h
+)
+if exist "$(OutDir)"\include\zconf.h (
+del "$(OutDir)"\include\zconf.h
+)</Command>
+    </PreBuildEvent>
+    <CustomBuildStep>
+      <Message>Custom Clean Step</Message>
+    </CustomBuildStep>
+    <CustomBuildStep>
+      <Outputs>force_clean</Outputs>
+      <Command>if exist "$(OutDir)"\include\zlib.h (
+del /f /q "$(OutDir)"\include\zlib.h
+)
+if exist "$(OutDir)"\include\zconf.h (
+del /f /q "$(OutDir)"\include\zconf.h
+)
+if exist $(OutDir)\licenses\zlib.txt (
+del /f /q $(OutDir)\licenses\zlib.txt
+)</Command>
+    </CustomBuildStep>
+  </ItemDefinitionGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='DebugDLL|Win32'">
+    <ClCompile>
+      <WarningLevel>Level3</WarningLevel>
+      <Optimization>Disabled</Optimization>
+      <PreprocessorDefinitions>WIN32;_WIN32_WINNT=0x0502;_DEBUG;DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <MultiProcessorCompilation>true</MultiProcessorCompilation>
+      <AdditionalIncludeDirectories>.\;..\;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+      <DisableSpecificWarnings>4996;%(DisableSpecificWarnings)</DisableSpecificWarnings>
+      <ProgramDataBaseFileName>$(IntDir)$(TargetName).pdb</ProgramDataBaseFileName>
+      <MinimalRebuild>false</MinimalRebuild>
+    </ClCompile>
+    <Link>
+      <ImportLibrary>$(OutDir)\lib\x86\$(TargetName).lib</ImportLibrary>
+      <SubSystem>Windows</SubSystem>
+      <ProfileGuidedDatabase>$(IntDir)\$(TargetName).pgd</ProfileGuidedDatabase>
+      <ProgramDatabaseFile>$(OutDir)\lib\x86\$(TargetName).pdb</ProgramDatabaseFile>
+      <OutputFile>$(OutDir)\bin\x86\$(TargetName)$(TargetExt)</OutputFile>
+      <ModuleDefinitionFile>..\contrib\vstudio\vc11\zlibvc.def</ModuleDefinitionFile>
+      <LargeAddressAware>true</LargeAddressAware>
+      <GenerateDebugInformation>true</GenerateDebugInformation>
+      <MinimumRequiredVersion>5.1</MinimumRequiredVersion>
+    </Link>
+    <MASM>
+      <UseSafeExceptionHandlers>true</UseSafeExceptionHandlers>
+    </MASM>
+    <PostBuildEvent>
+      <Command>mkdir "$(OutDir)"\include
+copy ..\zlib.h "$(OutDir)"\include
+copy "$(OutDir)"\..\src\zlib\zconf.h "$(OutDir)"\include /Y
+copy "$(OutDir)"\lib\$(Platform)\libzlib.lib "$(OutDir)"\lib\$(Platform)\zlib.lib /Y
+mkdir $(OutDir)\licenses
+copy ..\README $(OutDir)\licenses\zlib.txt</Command>
+    </PostBuildEvent>
+    <PreBuildEvent>
+      <Command>if exist ..\zconf.h (
+del ..\zconf.h
+)
+if exist "$(OutDir)"\include\zlib.h (
+del "$(OutDir)"\include\zlib.h
+)
+if exist "$(OutDir)"\include\zconf.h (
+del "$(OutDir)"\include\zconf.h
+)</Command>
+    </PreBuildEvent>
+    <CustomBuildStep>
+      <Message>Custom Clean Step</Message>
+    </CustomBuildStep>
+    <CustomBuildStep>
+      <Outputs>force_clean</Outputs>
+      <Command>if exist "$(OutDir)"\include\zlib.h (
+del /f /q "$(OutDir)"\include\zlib.h
+)
+if exist "$(OutDir)"\include\zconf.h (
+del /f /q "$(OutDir)"\include\zconf.h
+)
+if exist $(OutDir)\licenses\zlib.txt (
+del /f /q $(OutDir)\licenses\zlib.txt
+)</Command>
+    </CustomBuildStep>
+  </ItemDefinitionGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='DebugDLL|x64'">
+    <ClCompile>
+      <WarningLevel>Level3</WarningLevel>
+      <Optimization>Disabled</Optimization>
+      <PreprocessorDefinitions>WIN64;_WIN32_WINNT=0x0600;_DEBUG;DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <MultiProcessorCompilation>true</MultiProcessorCompilation>
+      <AdditionalIncludeDirectories>.\;..\;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+      <DisableSpecificWarnings>4996;%(DisableSpecificWarnings)</DisableSpecificWarnings>
+      <ProgramDataBaseFileName>$(IntDir)$(TargetName).pdb</ProgramDataBaseFileName>
+      <MinimalRebuild>false</MinimalRebuild>
+    </ClCompile>
+    <Link>
+      <OutputFile>$(OutDir)\bin\x64\$(TargetName)$(TargetExt)</OutputFile>
+      <ProgramDatabaseFile>$(OutDir)\lib\x64\$(TargetName).pdb</ProgramDatabaseFile>
+      <SubSystem>Windows</SubSystem>
+      <ProfileGuidedDatabase>$(IntDir)\$(TargetName).pgd</ProfileGuidedDatabase>
+      <ImportLibrary>$(OutDir)\lib\x64\$(TargetName).lib</ImportLibrary>
+      <ModuleDefinitionFile>..\contrib\vstudio\vc11\zlibvc.def</ModuleDefinitionFile>
+      <GenerateDebugInformation>true</GenerateDebugInformation>
+      <MinimumRequiredVersion>6.0</MinimumRequiredVersion>
+    </Link>
+    <MASM>
+      <UseSafeExceptionHandlers>true</UseSafeExceptionHandlers>
+    </MASM>
+    <PostBuildEvent>
+      <Command>mkdir "$(OutDir)"\include
+copy ..\zlib.h "$(OutDir)"\include
+copy "$(OutDir)"\..\src\zlib\zconf.h "$(OutDir)"\include /Y
+copy "$(OutDir)"\lib\$(Platform)\libzlib.lib "$(OutDir)"\lib\$(Platform)\zlib.lib /Y
+mkdir $(OutDir)\licenses
+copy ..\README $(OutDir)\licenses\zlib.txt</Command>
+    </PostBuildEvent>
+    <PreBuildEvent>
+      <Command>if exist ..\zconf.h (
+del ..\zconf.h
+)
+if exist "$(OutDir)"\include\zlib.h (
+del "$(OutDir)"\include\zlib.h
+)
+if exist "$(OutDir)"\include\zconf.h (
+del "$(OutDir)"\include\zconf.h
+)</Command>
+    </PreBuildEvent>
+    <CustomBuildStep>
+      <Message>Custom Clean Step</Message>
+    </CustomBuildStep>
+    <CustomBuildStep>
+      <Outputs>force_clean</Outputs>
+      <Command>if exist "$(OutDir)"\include\zlib.h (
+del /f /q "$(OutDir)"\include\zlib.h
+)
+if exist "$(OutDir)"\include\zconf.h (
+del /f /q "$(OutDir)"\include\zconf.h
+)
+if exist $(OutDir)\licenses\zlib.txt (
+del /f /q $(OutDir)\licenses\zlib.txt
+)</Command>
+    </CustomBuildStep>
+  </ItemDefinitionGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+    <ClCompile>
+      <WarningLevel>Level3</WarningLevel>
+      <Optimization>MaxSpeed</Optimization>
+      <FunctionLevelLinking>true</FunctionLevelLinking>
+      <IntrinsicFunctions>true</IntrinsicFunctions>
+      <PreprocessorDefinitions>WIN32;_WIN32_WINNT=0x0502;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <MultiProcessorCompilation>true</MultiProcessorCompilation>
+      <InlineFunctionExpansion>AnySuitable</InlineFunctionExpansion>
+      <FavorSizeOrSpeed>Speed</FavorSizeOrSpeed>
+      <OmitFramePointers>true</OmitFramePointers>
+      <EnableFiberSafeOptimizations>true</EnableFiberSafeOptimizations>
+      <StringPooling>true</StringPooling>
+      <AdditionalIncludeDirectories>.\;..\;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+      <DisableSpecificWarnings>4996;%(DisableSpecificWarnings)</DisableSpecificWarnings>
+      <InterproceduralOptimization>SingleFile</InterproceduralOptimization>
+      <ProgramDataBaseFileName>$(OutDir)\lib\x86\$(TargetName).pdb</ProgramDataBaseFileName>
+    </ClCompile>
+    <Link>
+      <GenerateDebugInformation>true</GenerateDebugInformation>
+      <EnableCOMDATFolding>true</EnableCOMDATFolding>
+      <OptimizeReferences>true</OptimizeReferences>
+    </Link>
+    <Lib>
+      <OutputFile>$(OutDir)\lib\x86\$(TargetName)$(TargetExt)</OutputFile>
+    </Lib>
+    <Lib>
+      <TargetMachine>MachineX86</TargetMachine>
+    </Lib>
+    <Lib>
+      <SubSystem>Windows</SubSystem>
+    </Lib>
+    <MASM>
+      <UseSafeExceptionHandlers>true</UseSafeExceptionHandlers>
+    </MASM>
+    <PostBuildEvent>
+      <Command>mkdir "$(OutDir)"\include
+copy ..\zlib.h "$(OutDir)"\include
+copy "$(OutDir)"\..\src\zlib\zconf.h "$(OutDir)"\include /Y
+copy "$(OutDir)"\lib\$(Platform)\libzlib.lib "$(OutDir)"\lib\$(Platform)\zlib.lib /Y
+mkdir $(OutDir)\licenses
+copy ..\README $(OutDir)\licenses\zlib.txt</Command>
+    </PostBuildEvent>
+    <PreBuildEvent>
+      <Command>if exist ..\zconf.h (
+del ..\zconf.h
+)
+if exist "$(OutDir)"\include\zlib.h (
+del "$(OutDir)"\include\zlib.h
+)
+if exist "$(OutDir)"\include\zconf.h (
+del "$(OutDir)"\include\zconf.h
+)</Command>
+    </PreBuildEvent>
+    <CustomBuildStep>
+      <Message>Custom Clean Step</Message>
+    </CustomBuildStep>
+    <CustomBuildStep>
+      <Outputs>force_clean</Outputs>
+      <Command>if exist "$(OutDir)"\include\zlib.h (
+del /f /q "$(OutDir)"\include\zlib.h
+)
+if exist "$(OutDir)"\include\zconf.h (
+del /f /q "$(OutDir)"\include\zconf.h
+)
+if exist $(OutDir)\licenses\zlib.txt (
+del /f /q $(OutDir)\licenses\zlib.txt
+)</Command>
+    </CustomBuildStep>
+  </ItemDefinitionGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseLTO|Win32'">
+    <ClCompile>
+      <WarningLevel>Level3</WarningLevel>
+      <Optimization>MaxSpeed</Optimization>
+      <FunctionLevelLinking>true</FunctionLevelLinking>
+      <IntrinsicFunctions>true</IntrinsicFunctions>
+      <PreprocessorDefinitions>WIN32;_WIN32_WINNT=0x0502;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <MultiProcessorCompilation>true</MultiProcessorCompilation>
+      <InlineFunctionExpansion>AnySuitable</InlineFunctionExpansion>
+      <FavorSizeOrSpeed>Speed</FavorSizeOrSpeed>
+      <OmitFramePointers>true</OmitFramePointers>
+      <EnableFiberSafeOptimizations>true</EnableFiberSafeOptimizations>
+      <StringPooling>true</StringPooling>
+      <AdditionalIncludeDirectories>.\;..\;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+      <DisableSpecificWarnings>4996;%(DisableSpecificWarnings)</DisableSpecificWarnings>
+      <InterproceduralOptimization>SingleFile</InterproceduralOptimization>
+      <ProgramDataBaseFileName>$(OutDir)\lib\x86\$(TargetName).pdb</ProgramDataBaseFileName>
+    </ClCompile>
+    <Link>
+      <GenerateDebugInformation>true</GenerateDebugInformation>
+      <EnableCOMDATFolding>true</EnableCOMDATFolding>
+      <OptimizeReferences>true</OptimizeReferences>
+    </Link>
+    <Lib>
+      <OutputFile>$(OutDir)\lib\x86\$(TargetName)$(TargetExt)</OutputFile>
+    </Lib>
+    <Lib>
+      <TargetMachine>MachineX86</TargetMachine>
+    </Lib>
+    <Lib>
+      <SubSystem>Windows</SubSystem>
+    </Lib>
+    <MASM>
+      <UseSafeExceptionHandlers>true</UseSafeExceptionHandlers>
+    </MASM>
+    <PostBuildEvent>
+      <Command>mkdir "$(OutDir)"\include
+copy ..\zlib.h "$(OutDir)"\include
+copy "$(OutDir)"\..\src\zlib\zconf.h "$(OutDir)"\include /Y
+copy "$(OutDir)"\lib\$(Platform)\libzlib.lib "$(OutDir)"\lib\$(Platform)\zlib.lib /Y
+mkdir $(OutDir)\licenses
+copy ..\README $(OutDir)\licenses\zlib.txt</Command>
+    </PostBuildEvent>
+    <PreBuildEvent>
+      <Command>if exist ..\zconf.h (
+del ..\zconf.h
+)
+if exist "$(OutDir)"\include\zlib.h (
+del "$(OutDir)"\include\zlib.h
+)
+if exist "$(OutDir)"\include\zconf.h (
+del "$(OutDir)"\include\zconf.h
+)</Command>
+    </PreBuildEvent>
+    <CustomBuildStep>
+      <Message>Custom Clean Step</Message>
+    </CustomBuildStep>
+    <CustomBuildStep>
+      <Outputs>force_clean</Outputs>
+      <Command>if exist "$(OutDir)"\include\zlib.h (
+del /f /q "$(OutDir)"\include\zlib.h
+)
+if exist "$(OutDir)"\include\zconf.h (
+del /f /q "$(OutDir)"\include\zconf.h
+)
+if exist $(OutDir)\licenses\zlib.txt (
+del /f /q $(OutDir)\licenses\zlib.txt
+)</Command>
+    </CustomBuildStep>
+  </ItemDefinitionGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+    <ClCompile>
+      <WarningLevel>Level3</WarningLevel>
+      <Optimization>MaxSpeed</Optimization>
+      <FunctionLevelLinking>true</FunctionLevelLinking>
+      <IntrinsicFunctions>true</IntrinsicFunctions>
+      <PreprocessorDefinitions>WIN64;_WIN32_WINNT=0x0600;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <MultiProcessorCompilation>true</MultiProcessorCompilation>
+      <InlineFunctionExpansion>AnySuitable</InlineFunctionExpansion>
+      <FavorSizeOrSpeed>Speed</FavorSizeOrSpeed>
+      <OmitFramePointers>true</OmitFramePointers>
+      <EnableFiberSafeOptimizations>true</EnableFiberSafeOptimizations>
+      <StringPooling>true</StringPooling>
+      <AdditionalIncludeDirectories>.\;..\;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+      <DisableSpecificWarnings>4996;%(DisableSpecificWarnings)</DisableSpecificWarnings>
+      <InterproceduralOptimization>SingleFile</InterproceduralOptimization>
+      <ProgramDataBaseFileName>$(OutDir)\lib\x64\$(TargetName).pdb</ProgramDataBaseFileName>
+    </ClCompile>
+    <Link>
+      <GenerateDebugInformation>true</GenerateDebugInformation>
+      <EnableCOMDATFolding>true</EnableCOMDATFolding>
+      <OptimizeReferences>true</OptimizeReferences>
+    </Link>
+    <Lib>
+      <SubSystem>Windows</SubSystem>
+      <OutputFile>$(OutDir)\lib\x64\$(TargetName)$(TargetExt)</OutputFile>
+    </Lib>
+    <MASM>
+      <UseSafeExceptionHandlers>true</UseSafeExceptionHandlers>
+    </MASM>
+    <PostBuildEvent>
+      <Command>mkdir "$(OutDir)"\include
+copy ..\zlib.h "$(OutDir)"\include
+copy "$(OutDir)"\..\src\zlib\zconf.h "$(OutDir)"\include /Y
+copy "$(OutDir)"\lib\$(Platform)\libzlib.lib "$(OutDir)"\lib\$(Platform)\zlib.lib /Y
+mkdir $(OutDir)\licenses
+copy ..\README $(OutDir)\licenses\zlib.txt</Command>
+    </PostBuildEvent>
+    <PreBuildEvent>
+      <Command>if exist ..\zconf.h (
+del ..\zconf.h
+)
+if exist "$(OutDir)"\include\zlib.h (
+del "$(OutDir)"\include\zlib.h
+)
+if exist "$(OutDir)"\include\zconf.h (
+del "$(OutDir)"\include\zconf.h
+)</Command>
+    </PreBuildEvent>
+    <CustomBuildStep>
+      <Message>Custom Clean Step</Message>
+    </CustomBuildStep>
+    <CustomBuildStep>
+      <Outputs>force_clean</Outputs>
+      <Command>if exist "$(OutDir)"\include\zlib.h (
+del /f /q "$(OutDir)"\include\zlib.h
+)
+if exist "$(OutDir)"\include\zconf.h (
+del /f /q "$(OutDir)"\include\zconf.h
+)
+if exist $(OutDir)\licenses\zlib.txt (
+del /f /q $(OutDir)\licenses\zlib.txt
+)</Command>
+    </CustomBuildStep>
+  </ItemDefinitionGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseLTO|x64'">
+    <ClCompile>
+      <WarningLevel>Level3</WarningLevel>
+      <Optimization>MaxSpeed</Optimization>
+      <FunctionLevelLinking>true</FunctionLevelLinking>
+      <IntrinsicFunctions>true</IntrinsicFunctions>
+      <PreprocessorDefinitions>WIN64;_WIN32_WINNT=0x0600;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <MultiProcessorCompilation>true</MultiProcessorCompilation>
+      <InlineFunctionExpansion>AnySuitable</InlineFunctionExpansion>
+      <FavorSizeOrSpeed>Speed</FavorSizeOrSpeed>
+      <OmitFramePointers>true</OmitFramePointers>
+      <EnableFiberSafeOptimizations>true</EnableFiberSafeOptimizations>
+      <StringPooling>true</StringPooling>
+      <AdditionalIncludeDirectories>.\;..\;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+      <DisableSpecificWarnings>4996;%(DisableSpecificWarnings)</DisableSpecificWarnings>
+      <InterproceduralOptimization>SingleFile</InterproceduralOptimization>
+      <ProgramDataBaseFileName>$(OutDir)\lib\x64\$(TargetName).pdb</ProgramDataBaseFileName>
+    </ClCompile>
+    <Link>
+      <GenerateDebugInformation>true</GenerateDebugInformation>
+      <EnableCOMDATFolding>true</EnableCOMDATFolding>
+      <OptimizeReferences>true</OptimizeReferences>
+    </Link>
+    <Lib>
+      <SubSystem>Windows</SubSystem>
+      <OutputFile>$(OutDir)\lib\x64\$(TargetName)$(TargetExt)</OutputFile>
+    </Lib>
+    <MASM>
+      <UseSafeExceptionHandlers>true</UseSafeExceptionHandlers>
+    </MASM>
+    <PostBuildEvent>
+      <Command>mkdir "$(OutDir)"\include
+copy ..\zlib.h "$(OutDir)"\include
+copy "$(OutDir)"\..\src\zlib\zconf.h "$(OutDir)"\include /Y
+copy "$(OutDir)"\lib\$(Platform)\libzlib.lib "$(OutDir)"\lib\$(Platform)\zlib.lib /Y
+mkdir $(OutDir)\licenses
+copy ..\README $(OutDir)\licenses\zlib.txt</Command>
+    </PostBuildEvent>
+    <PreBuildEvent>
+      <Command>if exist ..\zconf.h (
+del ..\zconf.h
+)
+if exist "$(OutDir)"\include\zlib.h (
+del "$(OutDir)"\include\zlib.h
+)
+if exist "$(OutDir)"\include\zconf.h (
+del "$(OutDir)"\include\zconf.h
+)</Command>
+    </PreBuildEvent>
+    <CustomBuildStep>
+      <Message>Custom Clean Step</Message>
+    </CustomBuildStep>
+    <CustomBuildStep>
+      <Outputs>force_clean</Outputs>
+      <Command>if exist "$(OutDir)"\include\zlib.h (
+del /f /q "$(OutDir)"\include\zlib.h
+)
+if exist "$(OutDir)"\include\zconf.h (
+del /f /q "$(OutDir)"\include\zconf.h
+)
+if exist $(OutDir)\licenses\zlib.txt (
+del /f /q $(OutDir)\licenses\zlib.txt
+)</Command>
+    </CustomBuildStep>
+  </ItemDefinitionGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|Win32'">
+    <ClCompile>
+      <WarningLevel>Level3</WarningLevel>
+      <Optimization>MaxSpeed</Optimization>
+      <FunctionLevelLinking>true</FunctionLevelLinking>
+      <IntrinsicFunctions>true</IntrinsicFunctions>
+      <PreprocessorDefinitions>WIN32;_WIN32_WINNT=0x0502;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <MultiProcessorCompilation>true</MultiProcessorCompilation>
+      <InlineFunctionExpansion>AnySuitable</InlineFunctionExpansion>
+      <FavorSizeOrSpeed>Speed</FavorSizeOrSpeed>
+      <OmitFramePointers>true</OmitFramePointers>
+      <EnableFiberSafeOptimizations>true</EnableFiberSafeOptimizations>
+      <StringPooling>true</StringPooling>
+      <AdditionalIncludeDirectories>.\;..\;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+      <DisableSpecificWarnings>4996;%(DisableSpecificWarnings)</DisableSpecificWarnings>
+      <ProgramDataBaseFileName>$(IntDir)$(TargetName).pdb</ProgramDataBaseFileName>
+    </ClCompile>
+    <Link>
+      <EnableCOMDATFolding>true</EnableCOMDATFolding>
+      <OptimizeReferences>true</OptimizeReferences>
+      <ImportLibrary>$(OutDir)\lib\x86\$(TargetName).lib</ImportLibrary>
+      <SubSystem>Windows</SubSystem>
+      <ProfileGuidedDatabase>$(IntDir)\$(TargetName).pgd</ProfileGuidedDatabase>
+      <ProgramDatabaseFile>$(OutDir)\lib\x86\$(TargetName).pdb</ProgramDatabaseFile>
+      <OutputFile>$(OutDir)\bin\x86\$(TargetName)$(TargetExt)</OutputFile>
+      <ModuleDefinitionFile>..\contrib\vstudio\vc11\zlibvc.def</ModuleDefinitionFile>
+      <LargeAddressAware>true</LargeAddressAware>
+      <GenerateDebugInformation>true</GenerateDebugInformation>
+      <MinimumRequiredVersion>5.1</MinimumRequiredVersion>
+    </Link>
+    <MASM>
+      <UseSafeExceptionHandlers>true</UseSafeExceptionHandlers>
+    </MASM>
+    <PostBuildEvent>
+      <Command>mkdir "$(OutDir)"\include
+copy ..\zlib.h "$(OutDir)"\include
+copy "$(OutDir)"\..\src\zlib\zconf.h "$(OutDir)"\include /Y
+copy "$(OutDir)"\lib\$(Platform)\libzlib.lib "$(OutDir)"\lib\$(Platform)\zlib.lib /Y
+mkdir $(OutDir)\licenses
+copy ..\README $(OutDir)\licenses\zlib.txt</Command>
+    </PostBuildEvent>
+    <PreBuildEvent>
+      <Command>if exist ..\zconf.h (
+del ..\zconf.h
+)
+if exist "$(OutDir)"\include\zlib.h (
+del "$(OutDir)"\include\zlib.h
+)
+if exist "$(OutDir)"\include\zconf.h (
+del "$(OutDir)"\include\zconf.h
+)</Command>
+    </PreBuildEvent>
+    <CustomBuildStep>
+      <Message>Custom Clean Step</Message>
+    </CustomBuildStep>
+    <CustomBuildStep>
+      <Outputs>force_clean</Outputs>
+      <Command>if exist "$(OutDir)"\include\zlib.h (
+del /f /q "$(OutDir)"\include\zlib.h
+)
+if exist "$(OutDir)"\include\zconf.h (
+del /f /q "$(OutDir)"\include\zconf.h
+)
+if exist $(OutDir)\licenses\zlib.txt (
+del /f /q $(OutDir)\licenses\zlib.txt
+)</Command>
+    </CustomBuildStep>
+  </ItemDefinitionGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|x64'">
+    <ClCompile>
+      <WarningLevel>Level3</WarningLevel>
+      <Optimization>MaxSpeed</Optimization>
+      <FunctionLevelLinking>true</FunctionLevelLinking>
+      <IntrinsicFunctions>true</IntrinsicFunctions>
+      <PreprocessorDefinitions>WIN64;_WIN32_WINNT=0x0600;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <MultiProcessorCompilation>true</MultiProcessorCompilation>
+      <InlineFunctionExpansion>AnySuitable</InlineFunctionExpansion>
+      <FavorSizeOrSpeed>Speed</FavorSizeOrSpeed>
+      <OmitFramePointers>true</OmitFramePointers>
+      <EnableFiberSafeOptimizations>true</EnableFiberSafeOptimizations>
+      <StringPooling>true</StringPooling>
+      <AdditionalIncludeDirectories>.\;..\;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+      <DisableSpecificWarnings>4996;%(DisableSpecificWarnings)</DisableSpecificWarnings>
+      <ProgramDataBaseFileName>$(IntDir)$(TargetName).pdb</ProgramDataBaseFileName>
+    </ClCompile>
+    <Link>
+      <EnableCOMDATFolding>true</EnableCOMDATFolding>
+      <OptimizeReferences>true</OptimizeReferences>
+      <OutputFile>$(OutDir)\bin\x64\$(TargetName)$(TargetExt)</OutputFile>
+      <ProgramDatabaseFile>$(OutDir)\lib\x64\$(TargetName).pdb</ProgramDatabaseFile>
+      <SubSystem>Windows</SubSystem>
+      <ProfileGuidedDatabase>$(IntDir)\$(TargetName).pgd</ProfileGuidedDatabase>
+      <ImportLibrary>$(OutDir)\lib\x64\$(TargetName).lib</ImportLibrary>
+      <ModuleDefinitionFile>..\contrib\vstudio\vc11\zlibvc.def</ModuleDefinitionFile>
+      <GenerateDebugInformation>true</GenerateDebugInformation>
+      <MinimumRequiredVersion>6.0</MinimumRequiredVersion>
+    </Link>
+    <MASM>
+      <UseSafeExceptionHandlers>true</UseSafeExceptionHandlers>
+    </MASM>
+    <PostBuildEvent>
+      <Command>mkdir "$(OutDir)"\include
+copy ..\zlib.h "$(OutDir)"\include
+copy "$(OutDir)"\..\src\zlib\zconf.h "$(OutDir)"\include /Y
+copy "$(OutDir)"\lib\$(Platform)\libzlib.lib "$(OutDir)"\lib\$(Platform)\zlib.lib /Y
+mkdir $(OutDir)\licenses
+copy ..\README $(OutDir)\licenses\zlib.txt</Command>
+    </PostBuildEvent>
+    <PreBuildEvent>
+      <Command>if exist ..\zconf.h (
+del ..\zconf.h
+)
+if exist "$(OutDir)"\include\zlib.h (
+del "$(OutDir)"\include\zlib.h
+)
+if exist "$(OutDir)"\include\zconf.h (
+del "$(OutDir)"\include\zconf.h
+)</Command>
+    </PreBuildEvent>
+    <CustomBuildStep>
+      <Message>Custom Clean Step</Message>
+    </CustomBuildStep>
+    <CustomBuildStep>
+      <Outputs>force_clean</Outputs>
+      <Command>if exist "$(OutDir)"\include\zlib.h (
+del /f /q "$(OutDir)"\include\zlib.h
+)
+if exist "$(OutDir)"\include\zconf.h (
+del /f /q "$(OutDir)"\include\zconf.h
+)
+if exist $(OutDir)\licenses\zlib.txt (
+del /f /q $(OutDir)\licenses\zlib.txt
+)</Command>
+    </CustomBuildStep>
+  </ItemDefinitionGroup>
+  <ItemGroup>
+    <ClCompile Include="..\adler32.c" />
+    <ClCompile Include="..\compress.c" />
+    <ClCompile Include="..\crc32.c" />
+    <ClCompile Include="..\deflate.c" />
+    <ClCompile Include="..\gzclose.c" />
+    <ClCompile Include="..\gzlib.c" />
+    <ClCompile Include="..\gzread.c" />
+    <ClCompile Include="..\gzwrite.c" />
+    <ClCompile Include="..\infback.c" />
+    <ClCompile Include="..\inffast.c" />
+    <ClCompile Include="..\inflate.c" />
+    <ClCompile Include="..\inftrees.c" />
+    <ClCompile Include="..\trees.c" />
+    <ClCompile Include="..\uncompr.c" />
+    <ClCompile Include="..\zutil.c" />
+    <ClCompile Include="..\contrib\minizip\ioapi.c" />
+    <ClCompile Include="..\contrib\minizip\iowin32.c">
+      <ExcludedFromBuild Condition="'$(Configuration)'=='Debug'">true</ExcludedFromBuild>
+      <ExcludedFromBuild Condition="'$(Configuration)'=='Release'">true</ExcludedFromBuild>
+      <ExcludedFromBuild Condition="'$(Configuration)'=='ReleaseLTO'">true</ExcludedFromBuild>
+    </ClCompile>
+    <ClCompile Include="..\contrib\minizip\unzip.c" />
+    <ClCompile Include="..\contrib\minizip\zip.c" />
+  </ItemGroup>
+  <ItemGroup>
+    <ClInclude Include="..\crc32.h" />
+    <ClInclude Include="..\deflate.h" />
+    <ClInclude Include="..\inffast.h" />
+    <ClInclude Include="..\inffixed.h" />
+    <ClInclude Include="..\inflate.h" />
+    <ClInclude Include="..\inftrees.h" />
+    <ClInclude Include="..\trees.h" />
+    <ClInclude Include="..\zlib.h" />
+    <ClInclude Include="..\zutil.h" />
+    <ClInclude Include="..\contrib\minizip\ioapi.h" />
+    <ClInclude Include="..\contrib\minizip\unzip.h" />
+    <ClInclude Include="..\contrib\minizip\zip.h" />
+    <ClInclude Include="zconf.h" />
+  </ItemGroup>
+  <ItemGroup>
+    <ResourceCompile Include="..\contrib\vstudio\vc11\zlib.rc">
+      <ExcludedFromBuild Condition="'$(Configuration)'=='Debug'">true</ExcludedFromBuild>
+      <ExcludedFromBuild Condition="'$(Configuration)'=='Release'">true</ExcludedFromBuild>
+      <ExcludedFromBuild Condition="'$(Configuration)'=='ReleaseLTO'">true</ExcludedFromBuild>
+    </ResourceCompile>
+  </ItemGroup>
+  <ItemGroup>
+    <None Include="..\contrib\vstudio\vc11\zlibvc.def" />
+  </ItemGroup>
+  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
+  <ImportGroup Label="ExtensionTargets" />
+</Project>
diff --git a/GreenScreen/zlib/package.json b/GreenScreen/zlib/package.json
new file mode 100644
index 0000000..fdfec5e
--- /dev/null
+++ b/GreenScreen/zlib/package.json
@@ -0,0 +1,17 @@
+{
+    "name": "zlib",
+    "version": "8e4e3ead55cdd296130242d86b44b92fde3ea4d4",
+    "url": "https://github.com/ShiftMediaProject/zlib/archive/__VERSION__.tar.gz",
+    "deps": [],
+    "patches": [],
+    "win_patches": [],
+    "project_paths": [
+        "SMP/libzlib.vcxproj"
+    ],
+    "with_env" : "",
+    "custom_scripts": {
+        "pre_build": ["copy %cd%\\\\..\\\\..\\\\src\\\\zlib\\\\libzlib.vcxproj %cd%\\\\SMP\\\\libzlib.vcxproj /Y"],
+        "build": [],
+        "post_build": []
+    }
+}
diff --git a/GreenScreen/zlib/zconf.h b/GreenScreen/zlib/zconf.h
new file mode 100644
index 0000000..df47fef
--- /dev/null
+++ b/GreenScreen/zlib/zconf.h
@@ -0,0 +1,519 @@
+/* zconf.h -- configuration of the zlib compression library
+ * Copyright (C) 1995-2016 Jean-loup Gailly, Mark Adler
+ * For conditions of distribution and use, see copyright notice in zlib.h
+ */
+
+/* @(#) $Id$ */
+
+#ifndef ZCONF_H
+#define ZCONF_H
+
+/*
+ * If you *really* need a unique prefix for all types and library functions,
+ * compile with -DZ_PREFIX. The "standard" zlib should be compiled without it.
+ * Even better than compiling with -DZ_PREFIX would be to use configure to set
+ * this permanently in zconf.h using "./configure --zprefix".
+ */
+#ifdef Z_PREFIX /* may be set to #if 1 by ./configure */
+#define Z_PREFIX_SET
+
+/* all linked symbols and init macros */
+#define _dist_code        z__dist_code
+#define _length_code      z__length_code
+#define _tr_align         z__tr_align
+#define _tr_flush_bits    z__tr_flush_bits
+#define _tr_flush_block   z__tr_flush_block
+#define _tr_init          z__tr_init
+#define _tr_stored_block  z__tr_stored_block
+#define _tr_tally         z__tr_tally
+#define adler32           z_adler32
+#define adler32_combine   z_adler32_combine
+#define adler32_combine64 z_adler32_combine64
+#define adler32_z         z_adler32_z
+#ifndef Z_SOLO
+#define compress      z_compress
+#define compress2     z_compress2
+#define compressBound z_compressBound
+#endif
+#define crc32                z_crc32
+#define crc32_combine        z_crc32_combine
+#define crc32_combine64      z_crc32_combine64
+#define crc32_z              z_crc32_z
+#define deflate              z_deflate
+#define deflateBound         z_deflateBound
+#define deflateCopy          z_deflateCopy
+#define deflateEnd           z_deflateEnd
+#define deflateGetDictionary z_deflateGetDictionary
+#define deflateInit          z_deflateInit
+#define deflateInit2         z_deflateInit2
+#define deflateInit2_        z_deflateInit2_
+#define deflateInit_         z_deflateInit_
+#define deflateParams        z_deflateParams
+#define deflatePending       z_deflatePending
+#define deflatePrime         z_deflatePrime
+#define deflateReset         z_deflateReset
+#define deflateResetKeep     z_deflateResetKeep
+#define deflateSetDictionary z_deflateSetDictionary
+#define deflateSetHeader     z_deflateSetHeader
+#define deflateTune          z_deflateTune
+#define deflate_copyright    z_deflate_copyright
+#define get_crc_table        z_get_crc_table
+#ifndef Z_SOLO
+#define gz_error       z_gz_error
+#define gz_intmax      z_gz_intmax
+#define gz_strwinerror z_gz_strwinerror
+#define gzbuffer       z_gzbuffer
+#define gzclearerr     z_gzclearerr
+#define gzclose        z_gzclose
+#define gzclose_r      z_gzclose_r
+#define gzclose_w      z_gzclose_w
+#define gzdirect       z_gzdirect
+#define gzdopen        z_gzdopen
+#define gzeof          z_gzeof
+#define gzerror        z_gzerror
+#define gzflush        z_gzflush
+#define gzfread        z_gzfread
+#define gzfwrite       z_gzfwrite
+#define gzgetc         z_gzgetc
+#define gzgetc_        z_gzgetc_
+#define gzgets         z_gzgets
+#define gzoffset       z_gzoffset
+#define gzoffset64     z_gzoffset64
+#define gzopen         z_gzopen
+#define gzopen64       z_gzopen64
+#ifdef _WIN32
+#define gzopen_w z_gzopen_w
+#endif
+#define gzprintf    z_gzprintf
+#define gzputc      z_gzputc
+#define gzputs      z_gzputs
+#define gzread      z_gzread
+#define gzrewind    z_gzrewind
+#define gzseek      z_gzseek
+#define gzseek64    z_gzseek64
+#define gzsetparams z_gzsetparams
+#define gztell      z_gztell
+#define gztell64    z_gztell64
+#define gzungetc    z_gzungetc
+#define gzvprintf   z_gzvprintf
+#define gzwrite     z_gzwrite
+#endif
+#define inflate              z_inflate
+#define inflateBack          z_inflateBack
+#define inflateBackEnd       z_inflateBackEnd
+#define inflateBackInit      z_inflateBackInit
+#define inflateBackInit_     z_inflateBackInit_
+#define inflateCodesUsed     z_inflateCodesUsed
+#define inflateCopy          z_inflateCopy
+#define inflateEnd           z_inflateEnd
+#define inflateGetDictionary z_inflateGetDictionary
+#define inflateGetHeader     z_inflateGetHeader
+#define inflateInit          z_inflateInit
+#define inflateInit2         z_inflateInit2
+#define inflateInit2_        z_inflateInit2_
+#define inflateInit_         z_inflateInit_
+#define inflateMark          z_inflateMark
+#define inflatePrime         z_inflatePrime
+#define inflateReset         z_inflateReset
+#define inflateReset2        z_inflateReset2
+#define inflateResetKeep     z_inflateResetKeep
+#define inflateSetDictionary z_inflateSetDictionary
+#define inflateSync          z_inflateSync
+#define inflateSyncPoint     z_inflateSyncPoint
+#define inflateUndermine     z_inflateUndermine
+#define inflateValidate      z_inflateValidate
+#define inflate_copyright    z_inflate_copyright
+#define inflate_fast         z_inflate_fast
+#define inflate_table        z_inflate_table
+#ifndef Z_SOLO
+#define uncompress  z_uncompress
+#define uncompress2 z_uncompress2
+#endif
+#define zError z_zError
+#ifndef Z_SOLO
+#define zcalloc z_zcalloc
+#define zcfree  z_zcfree
+#endif
+#define zlibCompileFlags z_zlibCompileFlags
+#define zlibVersion      z_zlibVersion
+
+/* all zlib typedefs in zlib.h and zconf.h */
+#define Byte       z_Byte
+#define Bytef      z_Bytef
+#define alloc_func z_alloc_func
+#define charf      z_charf
+#define free_func  z_free_func
+#ifndef Z_SOLO
+#define gzFile z_gzFile
+#endif
+#define gz_header  z_gz_header
+#define gz_headerp z_gz_headerp
+#define in_func    z_in_func
+#define intf       z_intf
+#define out_func   z_out_func
+#define uInt       z_uInt
+#define uIntf      z_uIntf
+#define uLong      z_uLong
+#define uLongf     z_uLongf
+#define voidp      z_voidp
+#define voidpc     z_voidpc
+#define voidpf     z_voidpf
+
+/* all zlib structs in zlib.h and zconf.h */
+#define gz_header_s    z_gz_header_s
+#define internal_state z_internal_state
+
+#endif
+
+#if defined(__MSDOS__) && !defined(MSDOS)
+#define MSDOS
+#endif
+#if (defined(OS_2) || defined(__OS2__)) && !defined(OS2)
+#define OS2
+#endif
+#if defined(_WINDOWS) && !defined(WINDOWS)
+#define WINDOWS
+#endif
+#if defined(_WIN32) || defined(_WIN32_WCE) || defined(__WIN32__)
+#ifndef WIN32
+#define WIN32
+#endif
+#endif
+#if (defined(MSDOS) || defined(OS2) || defined(WINDOWS)) && !defined(WIN32)
+#if !defined(__GNUC__) && !defined(__FLAT__) && !defined(__386__)
+#ifndef SYS16BIT
+#define SYS16BIT
+#endif
+#endif
+#endif
+
+/*
+ * Compile with -DMAXSEG_64K if the alloc function cannot allocate more
+ * than 64k bytes at a time (needed on systems with 16-bit int).
+ */
+#ifdef SYS16BIT
+#define MAXSEG_64K
+#endif
+#ifdef MSDOS
+#define UNALIGNED_OK
+#endif
+
+#ifdef __STDC_VERSION__
+#ifndef STDC
+#define STDC
+#endif
+#if __STDC_VERSION__ >= 199901L
+#ifndef STDC99
+#define STDC99
+#endif
+#endif
+#endif
+#if !defined(STDC) && (defined(__STDC__) || defined(__cplusplus))
+#define STDC
+#endif
+#if !defined(STDC) && (defined(__GNUC__) || defined(__BORLANDC__))
+#define STDC
+#endif
+#if !defined(STDC) && (defined(MSDOS) || defined(WINDOWS) || defined(WIN32))
+#define STDC
+#endif
+#if !defined(STDC) && (defined(OS2) || defined(__HOS_AIX__))
+#define STDC
+#endif
+
+#if defined(__OS400__) && !defined(STDC) /* iSeries (formerly AS/400). */
+#define STDC
+#endif
+
+#ifndef STDC
+#ifndef const /* cannot use !defined(STDC) && !defined(const) on Mac */
+#define const /* note: need a more gentle solution here */
+#endif
+#endif
+
+#if defined(ZLIB_CONST) && !defined(z_const)
+#define z_const const
+#else
+#define z_const
+#endif
+
+#ifdef Z_SOLO
+typedef unsigned long z_size_t;
+#else
+#define z_longlong long long
+#if defined(NO_SIZE_T)
+typedef unsigned NO_SIZE_T z_size_t;
+#elif defined(STDC)
+#include <stddef.h>
+typedef size_t z_size_t;
+#else
+typedef unsigned long z_size_t;
+#endif
+#undef z_longlong
+#endif
+
+/* Maximum value for memLevel in deflateInit2 */
+#ifndef MAX_MEM_LEVEL
+#ifdef MAXSEG_64K
+#define MAX_MEM_LEVEL 8
+#else
+#define MAX_MEM_LEVEL 9
+#endif
+#endif
+
+/* Maximum value for windowBits in deflateInit2 and inflateInit2.
+ * WARNING: reducing MAX_WBITS makes minigzip unable to extract .gz files
+ * created by gzip. (Files created by minigzip can still be extracted by
+ * gzip.)
+ */
+#ifndef MAX_WBITS
+#define MAX_WBITS 15 /* 32K LZ77 window */
+#endif
+
+/* The memory requirements for deflate are (in bytes):
+            (1 << (windowBits+2)) +  (1 << (memLevel+9))
+ that is: 128K for windowBits=15  +  128K for memLevel = 8  (default values)
+ plus a few kilobytes for small objects. For example, if you want to reduce
+ the default memory requirements from 256K to 128K, compile with
+     make CFLAGS="-O -DMAX_WBITS=14 -DMAX_MEM_LEVEL=7"
+ Of course this will generally degrade compression (there's no free lunch).
+
+   The memory requirements for inflate are (in bytes) 1 << windowBits
+ that is, 32K for windowBits=15 (default value) plus about 7 kilobytes
+ for small objects.
+*/
+
+/* Type declarations */
+
+#ifndef OF /* function prototypes */
+#ifdef STDC
+#define OF(args) args
+#else
+#define OF(args) ()
+#endif
+#endif
+
+#ifndef Z_ARG /* function prototypes for stdarg */
+#if defined(STDC) || defined(Z_HAVE_STDARG_H)
+#define Z_ARG(args) args
+#else
+#define Z_ARG(args) ()
+#endif
+#endif
+
+/* The following definitions for FAR are needed only for MSDOS mixed
+ * model programming (small or medium model with some far allocations).
+ * This was tested only with MSC; for other MSDOS compilers you may have
+ * to define NO_MEMCPY in zutil.h.  If you don't need the mixed model,
+ * just define FAR to be empty.
+ */
+#ifdef SYS16BIT
+#if defined(M_I86SM) || defined(M_I86MM)
+/* MSC small or medium model */
+#define SMALL_MEDIUM
+#ifdef _MSC_VER
+#define FAR _far
+#else
+#define FAR far
+#endif
+#endif
+#if (defined(__SMALL__) || defined(__MEDIUM__))
+/* Turbo C small or medium model */
+#define SMALL_MEDIUM
+#ifdef __BORLANDC__
+#define FAR _far
+#else
+#define FAR far
+#endif
+#endif
+#endif
+
+#if defined(WINDOWS) || defined(WIN32)
+/* If building or using zlib as a DLL, define ZLIB_DLL.
+ * This is not mandatory, but it offers a little performance increase.
+ */
+#ifdef ZLIB_DLL
+#if defined(WIN32) && (!defined(__BORLANDC__) || (__BORLANDC__ >= 0x500))
+#ifdef ZLIB_INTERNAL
+#define ZEXTERN extern __declspec(dllexport)
+#else
+#define ZEXTERN extern __declspec(dllimport)
+#endif
+#endif
+#endif /* ZLIB_DLL */
+       /* If building or using zlib with the WINAPI/WINAPIV calling convention,
+        * define ZLIB_WINAPI.
+        * Caution: the standard ZLIB1.DLL is NOT compiled using ZLIB_WINAPI.
+        */
+#ifdef ZLIB_WINAPI
+#ifdef FAR
+#undef FAR
+#endif
+#include <windows.h>
+/* No need for _export, use ZLIB.DEF instead. */
+/* For complete Windows compatibility, use WINAPI, not __stdcall. */
+#define ZEXPORT WINAPI
+#ifdef WIN32
+#define ZEXPORTVA WINAPIV
+#else
+#define ZEXPORTVA FAR CDECL
+#endif
+#endif
+#endif
+
+#if defined(__BEOS__)
+#ifdef ZLIB_DLL
+#ifdef ZLIB_INTERNAL
+#define ZEXPORT   __declspec(dllexport)
+#define ZEXPORTVA __declspec(dllexport)
+#else
+#define ZEXPORT   __declspec(dllimport)
+#define ZEXPORTVA __declspec(dllimport)
+#endif
+#endif
+#endif
+
+#ifndef ZEXTERN
+#define ZEXTERN extern
+#endif
+#ifndef ZEXPORT
+#define ZEXPORT
+#endif
+#ifndef ZEXPORTVA
+#define ZEXPORTVA
+#endif
+
+#ifndef FAR
+#define FAR
+#endif
+
+#if !defined(__MACTYPES__)
+typedef unsigned char Byte; /* 8 bits */
+#endif
+typedef unsigned int uInt;   /* 16 bits or more */
+typedef unsigned long uLong; /* 32 bits or more */
+
+#ifdef SMALL_MEDIUM
+/* Borland C/C++ and some old MSC versions ignore FAR inside typedef */
+#define Bytef Byte FAR
+#else
+typedef Byte FAR Bytef;
+#endif
+typedef char FAR charf;
+typedef int FAR intf;
+typedef uInt FAR uIntf;
+typedef uLong FAR uLongf;
+
+#ifdef STDC
+typedef void const* voidpc;
+typedef void FAR* voidpf;
+typedef void* voidp;
+#else
+typedef Byte const* voidpc;
+typedef Byte FAR* voidpf;
+typedef Byte* voidp;
+#endif
+
+#if !defined(Z_U4) && !defined(Z_SOLO) && defined(STDC)
+#include <limits.h>
+#if (UINT_MAX == 0xffffffffUL)
+#define Z_U4 unsigned
+#elif (ULONG_MAX == 0xffffffffUL)
+#define Z_U4 unsigned long
+#elif (USHRT_MAX == 0xffffffffUL)
+#define Z_U4 unsigned short
+#endif
+#endif
+
+#ifdef Z_U4
+typedef Z_U4 z_crc_t;
+#else
+typedef unsigned long z_crc_t;
+#endif
+
+#ifdef HAVE_STDARG_H /* may be set to #if 1 by ./configure */
+#define Z_HAVE_STDARG_H
+#endif
+
+#ifdef STDC
+#ifndef Z_SOLO
+#include <sys/types.h> /* for off_t */
+#endif
+#endif
+
+#if defined(STDC) || defined(Z_HAVE_STDARG_H)
+#ifndef Z_SOLO
+#include <stdarg.h> /* for va_list */
+#endif
+#endif
+
+#ifdef _WIN32
+#ifndef Z_SOLO
+#include <stddef.h> /* for wchar_t */
+#endif
+#endif
+
+/* a little trick to accommodate both "#define _LARGEFILE64_SOURCE" and
+ * "#define _LARGEFILE64_SOURCE 1" as requesting 64-bit operations, (even
+ * though the former does not conform to the LFS document), but considering
+ * both "#undef _LARGEFILE64_SOURCE" and "#define _LARGEFILE64_SOURCE 0" as
+ * equivalently requesting no 64-bit operations
+ */
+#if defined(_LARGEFILE64_SOURCE) && -_LARGEFILE64_SOURCE - -1 == 1
+#undef _LARGEFILE64_SOURCE
+#endif
+
+#if defined(__WATCOMC__) && !defined(Z_HAVE_UNISTD_H)
+#define Z_HAVE_UNISTD_H
+#endif
+
+#if defined(_LFS64_LARGEFILE) && _LFS64_LARGEFILE - 0
+#define Z_LFS64
+#endif
+
+#if defined(_LARGEFILE64_SOURCE) && defined(Z_LFS64)
+#define Z_LARGE64
+#endif
+
+#if defined(_FILE_OFFSET_BITS) && _FILE_OFFSET_BITS - 0 == 64 && defined(Z_LFS64)
+#define Z_WANT64
+#endif
+
+#if !defined(SEEK_SET) && !defined(Z_SOLO)
+#define SEEK_SET 0 /* Seek from beginning of file.  */
+#define SEEK_CUR 1 /* Seek from current position.  */
+#define SEEK_END 2 /* Set file pointer to EOF plus "offset" */
+#endif
+
+#ifndef z_off_t
+#define z_off_t long
+#endif
+
+#if !defined(_WIN32) && defined(Z_LARGE64)
+#define z_off64_t off64_t
+#else
+#if defined(_WIN32) && !defined(__GNUC__) && !defined(Z_SOLO)
+#define z_off64_t __int64
+#else
+#define z_off64_t z_off_t
+#endif
+#endif
+
+/* MVS linker does not support external names larger than 8 bytes */
+#if defined(__MVS__)
+#pragma map(deflateInit_, "DEIN")
+#pragma map(deflateInit2_, "DEIN2")
+#pragma map(deflateEnd, "DEEND")
+#pragma map(deflateBound, "DEBND")
+#pragma map(inflateInit_, "ININ")
+#pragma map(inflateInit2_, "ININ2")
+#pragma map(inflateEnd, "INEND")
+#pragma map(inflateSync, "INSY")
+#pragma map(inflateSetDictionary, "INSEDI")
+#pragma map(compressBound, "CMBND")
+#pragma map(inflate_table, "INTABL")
+#pragma map(inflate_fast, "INFA")
+#pragma map(inflate_copyright, "INCOPY")
+#endif
+
+#endif /* ZCONF_H */