aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJan Beich <jbeich@FreeBSD.org>2023-03-17 18:58:47 +0000
committerJan Beich <jbeich@FreeBSD.org>2023-03-17 20:59:23 +0000
commitf0dadc529fe9c4ee69dd96db92e2d0572d2092aa (patch)
tree80091ad194c99a3a9f5a775d81ee866d5c7128ba
parent1d6031f987c94e323b9041709934fbf77a4be49b (diff)
downloadports-f0dadc529fe9c4ee69dd96db92e2d0572d2092aa.tar.gz
ports-f0dadc529fe9c4ee69dd96db92e2d0572d2092aa.zip
multimedia/ffmpeg: fork 4.* into a pinned port
Mainly for leaf consumers: applications but not plugins or libraries. Otherwise, indirectly mixing different versions of ffmpeg libraries at runtime can lead to crashes. To use simply add the following before <bsd.port.mk> or <bsd.port.pre.mk> .include "${.CURDIR:H:H}/multimedia/ffmpeg4/override.mk" PR: 261302 Inspired by: c717faa5c764
-rw-r--r--multimedia/Makefile1
-rw-r--r--multimedia/ffmpeg4/Makefile655
-rw-r--r--multimedia/ffmpeg4/distinfo9
-rw-r--r--multimedia/ffmpeg4/files/patch-configure26
-rw-r--r--multimedia/ffmpeg4/files/patch-doc-Makefile11
-rw-r--r--multimedia/ffmpeg4/files/patch-libavdevice_v4l2.c18
-rw-r--r--multimedia/ffmpeg4/files/patch-libavfilter_vf__lensfun.c51
-rw-r--r--multimedia/ffmpeg4/files/patch-libavformat_rtsp.c44
-rw-r--r--multimedia/ffmpeg4/files/patch-libavutil-common.h13
-rw-r--r--multimedia/ffmpeg4/files/patch-libavutil-x86-asm.h11
-rw-r--r--multimedia/ffmpeg4/files/patch-libavutil_hwcontext__drm.c24
-rw-r--r--multimedia/ffmpeg4/files/patch-libswscale_ppc_yuv2rgb__altivec.c15
-rw-r--r--multimedia/ffmpeg4/files/patch-svtav1437
-rw-r--r--multimedia/ffmpeg4/files/patch-vmaf951
-rw-r--r--multimedia/ffmpeg4/override.mk8
-rw-r--r--multimedia/ffmpeg4/pkg-descr3
-rw-r--r--multimedia/ffmpeg4/pkg-plist220
17 files changed, 2497 insertions, 0 deletions
diff --git a/multimedia/Makefile b/multimedia/Makefile
index 7875ba189f9b..c3103e9e153b 100644
--- a/multimedia/Makefile
+++ b/multimedia/Makefile
@@ -60,6 +60,7 @@
SUBDIR += ffaudioconverter
SUBDIR += ffdec
SUBDIR += ffmpeg
+ SUBDIR += ffmpeg4
SUBDIR += ffmpegthumbnailer
SUBDIR += ffms2
SUBDIR += ffnvcodec-headers
diff --git a/multimedia/ffmpeg4/Makefile b/multimedia/ffmpeg4/Makefile
new file mode 100644
index 000000000000..94be714a6010
--- /dev/null
+++ b/multimedia/ffmpeg4/Makefile
@@ -0,0 +1,655 @@
+PORTNAME= ffmpeg
+PORTVERSION= 4.4.3
+CATEGORIES= multimedia audio net
+MASTER_SITES= https://ffmpeg.org/releases/
+PKGNAMESUFFIX= 4
+
+MAINTAINER= multimedia@FreeBSD.org
+COMMENT= Realtime audio/video encoder/converter and streaming server (legacy 4.* series)
+WWW= https://ffmpeg.org/
+
+LICENSE= GPLv2+ LGPL21+
+LICENSE_COMB= multi
+
+BUILD_DEPENDS= ${BUILD_DEPENDS_${ARCH}}
+BUILD_DEPENDS_aarch64= as:devel/binutils
+BUILD_DEPENDS_amd64= nasm:devel/nasm
+BUILD_DEPENDS_armv6= as:devel/binutils
+BUILD_DEPENDS_armv7= as:devel/binutils
+BUILD_DEPENDS_i386= nasm:devel/nasm
+
+HAS_CONFIGURE= yes
+CONFIGURE_LOG= ffbuild/config.log
+USES= compiler:c11 cpe gmake localbase:ldflags perl5 \
+ pkgconfig shebangfix tar:xz
+USE_LDCONFIG= yes
+USE_PERL5= build
+SHEBANG_FILES= doc/texi2pod.pl
+NOPRECIOUSMAKEVARS= yes # ARCH
+
+.ifdef PKGNAMESUFFIX
+PORTSCOUT= limit:^4\.
+PREFIX= ${LOCALBASE}/${PKGBASE} # avoid conflict with the default
+.endif
+
+# Option CHROMAPRINT disabled, it cannot work and people are baffled.
+OPTIONS_DEFINE= ALSA AMR_NB AMR_WB AOM ARIBB24 ASM ASS BS2B CACA CDIO \
+ CODEC2 DAV1D DAVS2 DC1394 DEBUG DOCS DRM FDK_AAC FLITE \
+ FONTCONFIG FREETYPE FREI0R FRIBIDI GLSLANG GME GSM ICONV ILBC \
+ JACK KLVANC KVAZAAR LADSPA LAME LENSFUN LIBBLURAY LIBRSVG2 \
+ LIBXML2 LTO LV2 MODPLUG MYSOFA NETWORK NVENC OPENAL OPENCL OPENGL \
+ OPENH264 OPENJPEG OPENMPT OPENVINO OPTIMIZED_CFLAGS OPUS POCKETSPHINX \
+ PULSEAUDIO RAV1E RABBITMQ RIST RTCPU RUBBERBAND SDL SMB SNAPPY \
+ SNDIO SOXR SPEEX SRT SSH SVTAV1 SVTHEVC SVTVP9 TENSORFLOW \
+ TESSERACT THEORA TWOLAME UAVS3D V4L VAAPI VAPOURSYNTH VDPAU VIDSTAB \
+ VMAF VO_AMRWBENC VORBIS VPX VULKAN WEBP X264 X265 \
+ XAVS2 XCB XVID XVIDEO ZIMG ZMQ ZVBI
+# intel-media-sdk only for i386/amd64
+OPTIONS_DEFINE_amd64= MFX
+OPTIONS_DEFINE_i386= MFX
+
+OPTIONS_DEFAULT= AOM ASM ASS DAV1D DRM FONTCONFIG FREETYPE FREI0R GMP \
+ GNUTLS ICONV LAME LIBXML2 NETWORK OPTIMIZED_CFLAGS OPUS \
+ RTCPU SVTAV1 V4L VAAPI VDPAU VMAF VORBIS VPX WEBP X264 \
+ X265 XCB
+OPTIONS_DEFAULT_amd64= NVENC
+OPTIONS_DEFAULT_i386= NVENC
+
+# i386 is too register-starved for LTO (PR257124)
+OPTIONS_EXCLUDE_i386= LTO
+
+.if !exists(${.CURDIR:H:H}/multimedia/davs2)
+# https://git.ffmpeg.org/gitweb/ffmpeg.git/commitdiff/5985a1bf7233
+OPTIONS_EXCLUDE+= DAVS2
+.endif
+
+.if !exists(${.CURDIR:H:H}/multimedia/uavs3d)
+# https://git.ffmpeg.org/gitweb/ffmpeg.git/commitdiff/c952db9d68d3
+OPTIONS_EXCLUDE+= UAVS3D
+.endif
+
+.if !exists(${.CURDIR:H:H}/multimedia/xavs2)
+# https://git.ffmpeg.org/gitweb/ffmpeg.git/commitdiff/85a921f4618
+OPTIONS_EXCLUDE+= XAVS2
+.endif
+
+.if !exists(${.CURDIR:H:H}/multimedia/klvanc)
+# https://git.ffmpeg.org/gitweb/ffmpeg.git/commitdiff/8732dfa9954
+OPTIONS_EXCLUDE+= KLVANC
+.endif
+
+.if !exists(${.CURDIR:H:H}/science/openvino)
+# https://git.ffmpeg.org/gitweb/ffmpeg.git/commitdiff/ff37ebaf30e6
+OPTIONS_EXCLUDE+= OPENVINO
+.endif
+
+OPTIONS_RADIO= RTMP SSL
+OPTIONS_RADIO_RTMP= GCRYPT GMP LIBRTMP
+OPTIONS_RADIO_SSL= GNUTLS MBEDTLS OPENSSL
+OPTIONS_GROUP= LICENSE
+OPTIONS_GROUP_LICENSE= GPL3 NONFREE
+
+ASS_DESC= Subtitles rendering via libass
+AOM_DESC= AV1 video encoding/decoding via libaom
+ARIBB24_DESC= ARIB text and caption decoding via libaribb24
+BS2B_DESC= Bauer Stereophonic-to-Binaural filter
+CHROMAPRINT_DESC= Audio fingerprinting with chromaprint
+CODEC2_DESC= Codec 2 audio encoding/decoding via libcodec2
+DAV1D_DESC= AV1 video decoding via libdav1d
+DAVS2_DESC= AVS2 decoding via libdavs2
+DC1394_DESC= IIDC-1394 grabbing using libdc1394
+DRM_DESC= KMS grabbing using libdrm
+FDK_AAC_DESC= AAC audio encoding via Fraunhofer FDK
+FLITE_DESC= Voice synthesis support via libflite
+GLSLANG_DESC= GLSL->SPIRV compilation via libglslang
+GME_DESC= Game Music Emu demuxer
+GPL3_DESC= Allow (L)GPL version 3 code(cs)
+ILBC_DESC= Internet Low Bit Rate codec
+KLVANC_DESC= Kernel Labs VANC processing
+KVAZAAR_DESC= H.265 video codec support via Kvazaar
+LICENSE_DESC= Licensing options
+LV2_DESC= LV2 audio filtering
+MFX_DESC= Intel MediaSDK (aka Quick Sync Video)
+MYSOFA_DESC= SOFAlizer binaural filter
+NETWORK_DESC= Networking support
+NONFREE_DESC= Allow use of nonfree code
+NVENC_DESC= NVIDIA decoder/encoder with CUDA support
+OPENMPT_DESC= Decoding tracked files via libopenmpt
+OPENH264_DESC= H.264 video codec support via OpenH264
+OPENVINO_DESC= OpenVINO as a DNN module backend for DNN based filters like dnn_processing
+POCKETSPHINX_DESC= Automatic Speech Recognition via PocketSphinx
+RAV1E_DESC= AV1 encoding via librav1e
+RABBITMQ_DESC= AMQP 0-9-1 protocol via RabbitMQ
+RIST_DESC= Reliable Internet Stream Transport protocol via librist
+RUBBERBAND_DESC=Time-stretching and pitch-shifting with librubberband
+RTCPU_DESC= Detect CPU capabilities at runtime
+RTMP_DESC= RTMP(T)E protocol support
+SRT_DESC= Haivision SRT protocol via libsrt
+SVTAV1_DESC= AV1 encoding via SVT-AV1
+SVTHEVC_DESC= HEVC encoding via SVT-HEVC
+SVTVP9_DESC= VP9 encoding via SVT-VP9
+LIBRTMP_DESC= ${RTMP_DESC} via librtmp
+TENSORFLOW_DESC=TensorFlow as a DNN module backend for DNN based filters like sr
+TESSERACT_DESC= Optical Character Recognition via Tesseract
+THEORA_DESC= Encoding support for theora via libtheora
+UAVS3D_DESC= AVS3 decoding via libuavs3d
+VAPOURSYNTH_DESC= VapourSynth demuxer
+VIDSTAB_DESC= Video stabilization filter
+VMAF_DESC= VMAF filter via libvmaf
+VULKAN_DESC= Vulkan filters
+XAVS2_DESC= AVS2 encoding via libxavs2
+XCB_DESC= X11 grabbing using XCB
+XVID_DESC= Encoding support for MPEG-4 ASP via libxvid
+ZIMG_DESC= "z" library video scaling filter
+ZMQ_DESC= Message passing via libzmq${ZMQ_VERSION}
+ZVBI_DESC= Teletext support via libzvbi
+
+OPTIONS_SUB= yes
+
+# alsa
+ALSA_LIB_DEPENDS= libasound.so:audio/alsa-lib
+ALSA_CONFIGURE_ENABLE= alsa
+
+# Opencore AMR NB
+AMR_NB_LIB_DEPENDS= libopencore-amrnb.so:audio/opencore-amr
+AMR_NB_CONFIGURE_ENABLE= libopencore-amrnb
+AMR_NB_IMPLIES= GPL3
+
+# Opencore AMR WB
+AMR_WB_LIB_DEPENDS= libopencore-amrwb.so:audio/opencore-amr
+AMR_WB_CONFIGURE_ENABLE= libopencore-amrwb
+AMR_WB_IMPLIES= GPL3
+
+# aom
+AOM_LIB_DEPENDS= libaom.so:multimedia/aom
+AOM_CONFIGURE_ENABLE= libaom
+
+# arib
+ARIBB24_LIB_DEPENDS= libaribb24.so:multimedia/aribb24
+ARIBB24_CONFIGURE_ENABLE= libaribb24
+
+# asm support
+ASM_CONFIGURE_ENABLE= asm
+
+# ass
+ASS_LIB_DEPENDS= libass.so:multimedia/libass
+ASS_CONFIGURE_ENABLE= libass
+
+# bs2b
+BS2B_LIB_DEPENDS= libbs2b.so:audio/libbs2b
+BS2B_CONFIGURE_ENABLE= libbs2b
+
+# caca
+CACA_LIB_DEPENDS= libcaca.so:graphics/libcaca
+CACA_CONFIGURE_ENABLE= libcaca
+
+# cdio
+CDIO_LIB_DEPENDS= libcdio_paranoia.so:sysutils/libcdio-paranoia
+CDIO_CONFIGURE_ENABLE= libcdio
+
+# chromaprint
+CHROMAPRINT_BROKEN= Dependency loop
+CHROMAPRINT_LIB_DEPENDS= libchromaprint.so:audio/chromaprint
+CHROMAPRINT_CONFIGURE_ENABLE= chromaprint
+
+# codec2
+CODEC2_LIB_DEPENDS= libcodec2.so:audio/codec2
+CODEC2_CONFIGURE_ENABLE= libcodec2
+
+# dav1d
+DAV1D_LIB_DEPENDS= libdav1d.so:multimedia/dav1d
+DAV1D_CONFIGURE_ENABLE= libdav1d
+
+# davs2
+DAVS2_LIB_DEPENDS= libdavs2.so:multimedia/davs2
+DAVS2_CONFIGURE_ENABLE= libdavs2
+
+# dc1394
+DC1394_LIB_DEPENDS= libdc1394.so:multimedia/libdc1394
+DC1394_CONFIGURE_ENABLE= libdc1394
+
+# debugging
+DEBUG_CONFIGURE_ON= --disable-stripping
+DEBUG_CONFIGURE_OFF= --disable-debug
+
+# docs
+DOCS_BUILD_DEPENDS= texi2html:textproc/texi2html
+DOCS_CONFIGURE_ENABLE= htmlpages
+
+# drm
+DRM_LIB_DEPENDS= libdrm.so:graphics/libdrm
+DRM_CONFIGURE_ENABLE= libdrm
+
+# fdk_aac
+FDK_AAC_LIB_DEPENDS= libfdk-aac.so:audio/fdk-aac
+FDK_AAC_CONFIGURE_ENABLE= libfdk-aac
+FDK_AAC_IMPLIES= NONFREE
+
+# flite
+FLITE_LIB_DEPENDS= libflite.so:audio/flite
+FLITE_CONFIGURE_ENABLE= libflite
+
+# fontconfig
+FONTCONFIG_LIB_DEPENDS= libfontconfig.so:x11-fonts/fontconfig
+FONTCONFIG_CONFIGURE_ENABLE= fontconfig
+
+# freetype
+FREETYPE_LIB_DEPENDS= libfreetype.so:print/freetype2
+FREETYPE_CONFIGURE_ENABLE= libfreetype
+
+# frei0r
+FREI0R_BUILD_DEPENDS= ${LOCALBASE}/include/frei0r.h:graphics/frei0r
+FREI0R_CONFIGURE_ENABLE= frei0r
+
+# fribidi
+FRIBIDI_LIB_DEPENDS= libfribidi.so:converters/fribidi
+FRIBIDI_CONFIGURE_ENABLE= libfribidi
+
+# gcrypt
+GCRYPT_LIB_DEPENDS= libgcrypt.so:security/libgcrypt
+GCRYPT_CONFIGURE_ENABLE= gcrypt
+
+# glslang
+GLSLANG_BUILD_DEPENDS= glslang>0:graphics/glslang \
+ spirv-tools>0:graphics/spirv-tools
+GLSLANG_CONFIGURE_ENABLE= libglslang
+GLSLANG_LDFLAGS= -lm
+
+# gnutls
+GNUTLS_LIB_DEPENDS= libgnutls.so:security/gnutls
+GNUTLS_CONFIGURE_ENABLE= gnutls
+
+# gme
+GME_LIB_DEPENDS= libgme.so:audio/libgme
+GME_CONFIGURE_ENABLE= libgme
+
+# gmp
+GMP_LIB_DEPENDS= libgmp.so:math/gmp
+GMP_CONFIGURE_ENABLE= gmp
+GMP_IMPLIES= GPL3
+
+# gsm
+GSM_LIB_DEPENDS= libgsm.so:audio/gsm
+GSM_CONFIGURE_ENABLE= libgsm
+
+# iconv
+ICONV_USES= iconv
+ICONV_CONFIGURE_ENABLE= iconv
+
+# ilbc
+ILBC_LIB_DEPENDS= libilbc.so:net/libilbc
+ILBC_CONFIGURE_ENABLE= libilbc
+
+# jack
+JACK_LIB_DEPENDS= libjack.so:audio/jack
+JACK_CONFIGURE_ENABLE= libjack
+
+# klvanc
+KLVANC_LIB_DEPENDS= libklvanc.so:multimedia/libklvanc
+KLVANC_CONFIGURE_ENABLE= libklvanc
+
+# kvazaar
+KVAZAAR_LIB_DEPENDS= libkvazaar.so:multimedia/kvazaar
+KVAZAAR_CONFIGURE_ENABLE= libkvazaar
+
+# ladspa
+LADSPA_BUILD_DEPENDS= ${LOCALBASE}/include/ladspa.h:audio/ladspa
+LADSPA_RUN_DEPENDS= ${LOCALBASE}/lib/ladspa/amp.so:audio/ladspa
+LADSPA_CONFIGURE_ENABLE= ladspa
+
+# lame
+LAME_LIB_DEPENDS= libmp3lame.so:audio/lame
+LAME_CONFIGURE_ENABLE= libmp3lame
+
+# lensfun
+LENSFUN_LIB_DEPENDS= liblensfun.so:graphics/lensfun
+LENSFUN_CONFIGURE_ENABLE= liblensfun
+
+# libbluray
+LIBBLURAY_LIB_DEPENDS= libbluray.so:multimedia/libbluray
+LIBBLURAY_CONFIGURE_ENABLE= libbluray
+
+# librsvg
+LIBRSVG2_USES= gnome
+LIBRSVG2_USE= GNOME=cairo,librsvg2
+LIBRSVG2_CONFIGURE_ENABLE= librsvg
+
+# libxml
+LIBXML2_LIB_DEPENDS= libxml2.so:textproc/libxml2
+LIBXML2_CONFIGURE_ENABLE= libxml2
+
+# lto
+LTO_CONFIGURE_ENABLE= lto
+
+# lv2
+LV2_BUILD_DEPENDS= lv2>0:audio/lv2
+LV2_LIB_DEPENDS= liblilv-0.so:audio/lilv
+LV2_CONFIGURE_ENABLE= lv2
+
+# libv4l
+V4L_BUILD_DEPENDS= v4l_compat>0:multimedia/v4l_compat
+V4L_LIB_DEPENDS= libv4l2.so:multimedia/libv4l
+V4L_CONFIGURE_ENABLE= libv4l2
+V4L_CONFIGURE_OFF= --disable-indev=v4l2 \
+ --disable-outdev=v4l2
+
+# mbedtls
+MBEDTLS_LIB_DEPENDS= libmbedtls.so:security/mbedtls
+MBEDTLS_CONFIGURE_ENABLE= mbedtls
+
+# mfx
+MFX_LIB_DEPENDS= libmfx.so:multimedia/intel-media-sdk
+MFX_CONFIGURE_ENABLE= libmfx
+
+# modplug
+MODPLUG_LIB_DEPENDS= libmodplug.so:audio/libmodplug
+MODPLUG_CONFIGURE_ENABLE= libmodplug
+
+# mysofa
+MYSOFA_LIB_DEPENDS= libmysofa.so:audio/libmysofa
+MYSOFA_CONFIGURE_ENABLE= libmysofa
+
+# network
+NETWORK_CONFIGURE_ENABLE= network
+
+# nvenc
+NVENC_BUILD_DEPENDS= ${LOCALBASE}/include/ffnvcodec/nvEncodeAPI.h:multimedia/ffnvcodec-headers
+NVENC_CONFIGURE_ENABLE= nvenc
+
+# OpenAL
+OPENAL_LIB_DEPENDS= libopenal.so:audio/openal-soft
+OPENAL_CONFIGURE_ENABLE= openal
+
+# opencl
+OPENCL_BUILD_DEPENDS= ${LOCALBASE}/include/CL/opencl.h:devel/opencl
+OPENCL_LIB_DEPENDS= libOpenCL.so:devel/ocl-icd
+OPENCL_CONFIGURE_ENABLE= opencl
+
+# opengl
+OPENGL_USES= gl
+OPENGL_USE= GL=gl
+OPENGL_CONFIGURE_ENABLE= opengl
+
+# openh264
+OPENH264_LIB_DEPENDS= libopenh264.so:multimedia/openh264
+OPENH264_CONFIGURE_ENABLE= libopenh264
+
+# openjpeg
+OPENJPEG_LIB_DEPENDS= libopenjp2.so:graphics/openjpeg
+OPENJPEG_CONFIGURE_ENABLE= libopenjpeg
+
+# openmpt
+OPENMPT_LIB_DEPENDS= libopenmpt.so:audio/libopenmpt
+OPENMPT_CONFIGURE_ENABLE= libopenmpt
+
+# openssl/libtls
+OPENSSL_USES= ssl
+OPENSSL_CONFIGURE_ENABLE= ${"${SSL_DEFAULT:Mlibressl*}"!="":?libtls:openssl}
+OPENSSL_IMPLIES= NONFREE
+
+# openvino
+OPENVINO_LIB_DEPENDS= libinference_engine_c_api.so:science/openvino
+OPENVINO_CONFIGURE_ENABLE= libopenvino
+
+# optimizations
+OPTIMIZED_CFLAGS_CONFIGURE_ENABLE= optimizations
+
+# opus
+OPUS_LIB_DEPENDS= libopus.so:audio/opus
+OPUS_CONFIGURE_ENABLE= libopus
+
+# pocketsphinx
+POCKETSPHINX_LIB_DEPENDS= libpocketsphinx.so:audio/pocketsphinx
+POCKETSPHINX_CONFIGURE_ENABLE= pocketsphinx
+POCKETSPHINX_BROKEN= pocketsphinx < 5prealpha is not supported
+
+# pulseaudio
+PULSEAUDIO_LIB_DEPENDS= libpulse.so:audio/pulseaudio
+PULSEAUDIO_CONFIGURE_ENABLE= libpulse
+
+# rav1e
+RAV1E_LIB_DEPENDS= librav1e.so:multimedia/librav1e
+RAV1E_CONFIGURE_ENABLE= librav1e
+
+# rabbitmq
+RABBITMQ_LIB_DEPENDS= librabbitmq.so:net/rabbitmq-c
+RABBITMQ_CONFIGURE_ENABLE= librabbitmq
+
+# rist
+RIST_LIB_DEPENDS= librist.so:multimedia/librist
+RIST_CONFIGURE_ENABLE= librist
+
+# rubberband
+RUBBERBAND_LIB_DEPENDS= librubberband.so:audio/rubberband
+RUBBERBAND_CONFIGURE_ENABLE= librubberband
+
+# rtcpu
+RTCPU_CONFIGURE_ENABLE= runtime-cpudetect
+
+# rtmp
+LIBRTMP_LIB_DEPENDS= librtmp.so:multimedia/librtmp
+LIBRTMP_CONFIGURE_ENABLE= librtmp
+
+# sdl
+SDL_USES= sdl
+SDL_USE= SDL=sdl2
+SDL_CONFIGURE_ENABLE= sdl2
+
+# smbclient
+SMB_USES= samba:lib
+SMB_CONFIGURE_ENABLE= libsmbclient
+SMB_IMPLIES= GPL3
+
+# snappy
+SNAPPY_LIB_DEPENDS= libsnappy.so:archivers/snappy
+SNAPPY_CONFIGURE_ENABLE= libsnappy
+
+# sndio
+SNDIO_LIB_DEPENDS= libsndio.so:audio/sndio
+SNDIO_CONFIGURE_ENABLE= sndio
+
+# soxr
+SOXR_LIB_DEPENDS= libsoxr.so:audio/libsoxr
+SOXR_CONFIGURE_ENABLE= libsoxr
+
+# speex
+SPEEX_LIB_DEPENDS= libspeex.so:audio/speex
+SPEEX_CONFIGURE_ENABLE= libspeex
+
+# ssh
+SSH_LIB_DEPENDS= libssh.so:security/libssh
+SSH_CONFIGURE_ENABLE= libssh
+
+# srt
+SRT_LIB_DEPENDS= libsrt.so:www/srt
+SRT_CONFIGURE_ENABLE= libsrt
+
+# svt-av1
+SVTAV1_LIB_DEPENDS= libSvtAv1Enc.so:multimedia/svt-av1
+SVTAV1_CONFIGURE_ON= --enable-libsvtav1
+
+# svt-hevc
+SVTHEVC_LIB_DEPENDS= libSvtHevcEnc.so:multimedia/svt-hevc
+SVTHEVC_CONFIGURE_ON= --enable-libsvthevc
+SVTHEVC_PATCH_SITES= https://github.com/OpenVisualCloud/SVT-HEVC/raw/v1.5.0-3-g86b58f77/ffmpeg_plugin/:svthevc
+SVTHEVC_PATCHFILES= 0001-lavc-svt_hevc-add-libsvt-hevc-encoder-wrapper.patch:-p1:svthevc \
+ 0002-doc-Add-libsvt_hevc-encoder-docs.patch:-p1:svthevc
+.if make(makesum)
+.MAKEFLAGS: WITH+=SVTHEVC
+.endif
+
+# svt-vp9
+SVTVP9_LIB_DEPENDS= libSvtVp9Enc.so:multimedia/svt-vp9
+SVTVP9_CONFIGURE_ON= --enable-libsvtvp9
+SVTVP9_PATCH_SITES= https://github.com/OpenVisualCloud/SVT-VP9/raw/v0.3.0-4-gabd5c59/ffmpeg_plugin/:svtvp9
+SVTVP9_PATCHFILES= master-0001-Add-ability-for-ffmpeg-to-run-svt-vp9.patch:-p1:svtvp9
+.if make(makesum)
+.MAKEFLAGS: WITH+=SVTVP9
+.endif
+
+# tensorflow
+TENSORFLOW_LIB_DEPENDS= libtensorflow.so:science/py-tensorflow
+TENSORFLOW_CONFIGURE_ENABLE= libtensorflow
+
+# tesseract
+TESSERACT_LIB_DEPENDS= libtesseract.so:graphics/tesseract
+TESSERACT_CONFIGURE_ENABLE= libtesseract
+
+# theora
+THEORA_LIB_DEPENDS= libtheora.so:multimedia/libtheora
+THEORA_CONFIGURE_ENABLE= libtheora
+
+# twolame
+TWOLAME_LIB_DEPENDS= libtwolame.so:audio/twolame
+TWOLAME_CONFIGURE_ENABLE= libtwolame
+
+# uavs3d
+UAVS3D_LIB_DEPENDS= libuavs3d.so:multimedia/uavs3d
+UAVS3D_CONFIGURE_ENABLE= libuavs3d
+
+# vaapi
+VAAPI_LIB_DEPENDS= libva.so:multimedia/libva
+VAAPI_CONFIGURE_ENABLE= vaapi
+
+# vapoursynth
+VAPOURSYNTH_LIB_DEPENDS= libvapoursynth-script.so:multimedia/vapoursynth
+VAPOURSYNTH_CONFIGURE_ENABLE= vapoursynth
+
+# vdpau
+VDPAU_USES= xorg
+VDPAU_USE= XORG=x11
+VDPAU_LIB_DEPENDS= libvdpau.so:multimedia/libvdpau
+VDPAU_CONFIGURE_ENABLE= vdpau
+
+# vmaf
+VMAF_LIB_DEPENDS= libvmaf.so:multimedia/vmaf
+VMAF_CONFIGURE_ENABLE= libvmaf
+
+# vo-amrwbenc
+VO_AMRWBENC_LIB_DEPENDS= libvo-amrwbenc.so:audio/vo-amrwbenc
+VO_AMRWBENC_CONFIGURE_ENABLE= libvo-amrwbenc
+VO_AMRWBENC_IMPLIES= GPL3
+
+# vid.stab
+VIDSTAB_LIB_DEPENDS= libvidstab.so:multimedia/vid.stab
+VIDSTAB_CONFIGURE_ENABLE= libvidstab
+
+# vorbis
+VORBIS_LIB_DEPENDS= libvorbisenc.so:audio/libvorbis
+VORBIS_CONFIGURE_ENABLE= libvorbis
+
+# vp8
+VPX_LIB_DEPENDS= libvpx.so:multimedia/libvpx
+VPX_CONFIGURE_ENABLE= libvpx
+
+# vulkan
+VULKAN_BUILD_DEPENDS= vulkan-headers>0:graphics/vulkan-headers
+VULKAN_LIB_DEPENDS= libvulkan.so:graphics/vulkan-loader
+VULKAN_CONFIGURE_ENABLE= vulkan
+VULKAN_IMPLIES= GLSLANG
+
+# webp
+WEBP_LIB_DEPENDS= libwebp.so:graphics/webp
+WEBP_CONFIGURE_ENABLE= libwebp
+
+# x264
+X264_LIB_DEPENDS= libx264.so:multimedia/libx264
+X264_CONFIGURE_ENABLE= libx264
+
+# x265
+X265_LIB_DEPENDS= libx265.so:multimedia/x265
+X265_CONFIGURE_ENABLE= libx265
+
+# xavs2
+XAVS2_LIB_DEPENDS= libxavs2.so:multimedia/xavs2
+XAVS2_CONFIGURE_ENABLE= libxavs2
+
+# xcb
+XCB_USES= xorg
+XCB_USE= XORG=xcb
+XCB_CONFIGURE_ENABLE= libxcb
+
+# xvid
+XVID_LIB_DEPENDS= libxvidcore.so:multimedia/xvid
+XVID_CONFIGURE_ENABLE= libxvid
+
+# xv
+XVIDEO_USES= xorg
+XVIDEO_USE= XORG=x11,xext,xv
+XVIDEO_CONFIGURE_OFF= --disable-outdev=xv
+
+# zimg
+ZIMG_LIB_DEPENDS= libzimg.so:graphics/sekrit-twc-zimg
+ZIMG_CONFIGURE_ENABLE= libzimg
+
+# zmq
+ZMQ_LIB_DEPENDS= libzmq.so:net/libzmq${ZMQ_VERSION}
+ZMQ_CONFIGURE_ENABLE= libzmq
+ZMQ_VERSION?= 4
+
+# zvbi
+ZVBI_LIB_DEPENDS= libzvbi.so:devel/libzvbi
+ZVBI_CONFIGURE_ENABLE= libzvbi
+
+# License knobs
+GPL3_CONFIGURE_ENABLE= version3
+GPL3_VARS= LICENSE="GPLv3+ LGPL3+"
+LICENSE_FILE_GPLv3+ = ${WRKSRC}/COPYING.GPLv3
+LICENSE_FILE_LGPL3+ = ${WRKSRC}/COPYING.LGPLv3
+
+NONFREE_CONFIGURE_ENABLE=nonfree
+
+INSTALL_TARGET= install-progs install-doc install-data \
+ install-libs install-headers install-examples
+
+DATADIR= ${PREFIX}/share/${PORTNAME}${PKGNAMESUFFIX}
+DOCSDIR= ${PREFIX}/share/doc/${PORTNAME}${PKGNAMESUFFIX}
+MAKE_ENV+= V=1
+LDFLAGS_aarch64=-Wl,-z,notext
+LDFLAGS_armv6= -Wl,-z,notext
+LDFLAGS_armv7= -Wl,-z,notext
+LDFLAGS_i386= -Wl,-z,notext
+
+CONFIGURE_ARGS+=--prefix="${PREFIX}" \
+ --mandir="${PREFIX}/man" \
+ --datadir="${DATADIR}" \
+ --docdir="${DOCSDIR}" \
+ --pkgconfigdir="${PREFIX}/libdata/pkgconfig" \
+ --disable-static \
+ --disable-libcelt \
+ --enable-shared \
+ --enable-pic \
+ --enable-gpl \
+ --enable-avresample \
+ --cc="${CC}" \
+ --cxx="${CXX}"
+
+DOC_FILES= Changelog CREDITS INSTALL.md LICENSE.md MAINTAINERS \
+ README.md RELEASE_NOTES
+# under doc subdirectory
+DOC_DOCFILES= APIchanges *.txt
+PORTDOCS= *
+
+.include <bsd.port.options.mk>
+
+.if ${PORT_OPTIONS:MNONFREE}
+LICENSE+= NONFREE
+LICENSE_COMB= multi
+LICENSE_NAME_NONFREE= Non free code
+LICENSE_TEXT_NONFREE= enabling OPENSSL or FDK_AAC restricts redistribution
+LICENSE_PERMS_NONFREE= auto-accept
+.endif
+
+.include <bsd.port.pre.mk>
+
+.if ${ARCH} == powerpc64 && ${PORT_OPTIONS:MLTO} && ${CHOSEN_COMPILER_TYPE} == clang
+USE_GCC= yes
+.endif
+
+post-install:
+ (cd ${WRKSRC} && ${COPYTREE_SHARE} \
+ "${DOC_FILES}" ${STAGEDIR}${DOCSDIR})
+ (cd ${WRKSRC}/doc && ${COPYTREE_SHARE} \
+ "${DOC_DOCFILES}" ${STAGEDIR}${DOCSDIR})
+
+.include <bsd.port.post.mk>
diff --git a/multimedia/ffmpeg4/distinfo b/multimedia/ffmpeg4/distinfo
new file mode 100644
index 000000000000..da3325c05deb
--- /dev/null
+++ b/multimedia/ffmpeg4/distinfo
@@ -0,0 +1,9 @@
+TIMESTAMP = 1665342284
+SHA256 (ffmpeg-4.4.3.tar.xz) = 6c5b6c195e61534766a0b5fe16acc919170c883362612816d0a1c7f4f947006e
+SIZE (ffmpeg-4.4.3.tar.xz) = 9566020
+SHA256 (0001-lavc-svt_hevc-add-libsvt-hevc-encoder-wrapper.patch) = 376ea23e9d876390fbca936c80cb437bb9daa6232ff65df0ea91673e18b739ff
+SIZE (0001-lavc-svt_hevc-add-libsvt-hevc-encoder-wrapper.patch) = 24259
+SHA256 (0002-doc-Add-libsvt_hevc-encoder-docs.patch) = d16589efc4be2602a9f436e9938cfee0cc7b5ccd7a4a6b41c0c9a59ae0859fda
+SIZE (0002-doc-Add-libsvt_hevc-encoder-docs.patch) = 5336
+SHA256 (master-0001-Add-ability-for-ffmpeg-to-run-svt-vp9.patch) = b7d722dfce20b73e9d5c73d55ffe041bbdc92a3c4a5c5d766b6b3040671b4052
+SIZE (master-0001-Add-ability-for-ffmpeg-to-run-svt-vp9.patch) = 33497
diff --git a/multimedia/ffmpeg4/files/patch-configure b/multimedia/ffmpeg4/files/patch-configure
new file mode 100644
index 000000000000..760c50b8e912
--- /dev/null
+++ b/multimedia/ffmpeg4/files/patch-configure
@@ -0,0 +1,26 @@
+--- configure.orig 2022-10-09 19:04:43 UTC
++++ configure
+@@ -3784,13 +3784,7 @@ host_os=$target_os_default
+ host_os=$target_os_default
+
+ # machine
+-if test "$target_os_default" = aix; then
+- arch_default=$(uname -p)
+- strip_default="strip -X32_64"
+- nm_default="nm -g -X32_64"
+-else
+- arch_default=$(uname -m)
+-fi
++arch_default=$(uname -p)
+ cpu="generic"
+ intrinsics="none"
+
+@@ -6758,7 +6752,7 @@ if enabled x86; then
+
+ if enabled x86; then
+ case $target_os in
+- mingw32*|mingw64*|win32|win64|linux|cygwin*)
++ freebsd|mingw32*|mingw64*|win32|win64|linux|cygwin*)
+ ;;
+ *)
+ disable ffnvcodec cuvid nvdec nvenc
diff --git a/multimedia/ffmpeg4/files/patch-doc-Makefile b/multimedia/ffmpeg4/files/patch-doc-Makefile
new file mode 100644
index 000000000000..52ab4033ad98
--- /dev/null
+++ b/multimedia/ffmpeg4/files/patch-doc-Makefile
@@ -0,0 +1,11 @@
+--- doc/Makefile.orig 2015-06-19 20:44:35 UTC
++++ doc/Makefile
+@@ -145,7 +145,7 @@ install-html: $(HTMLPAGES)
+ endif
+
+ ifdef CONFIG_MANPAGES
+-install-progs-$(CONFIG_DOC): install-man
++#install-progs-$(CONFIG_DOC): install-man
+
+ install-man: $(MANPAGES)
+ $(Q)mkdir -p "$(MANDIR)/man1"
diff --git a/multimedia/ffmpeg4/files/patch-libavdevice_v4l2.c b/multimedia/ffmpeg4/files/patch-libavdevice_v4l2.c
new file mode 100644
index 000000000000..8518fadce3af
--- /dev/null
+++ b/multimedia/ffmpeg4/files/patch-libavdevice_v4l2.c
@@ -0,0 +1,18 @@
+- ioctl() prototype on BSDs follows Version 7 AT&T UNIX
+
+--- libavdevice/v4l2.c.orig 2019-04-21 04:37:17 UTC
++++ libavdevice/v4l2.c
+@@ -95,10 +95,10 @@ struct video_data {
+ int (*open_f)(const char *file, int oflag, ...);
+ int (*close_f)(int fd);
+ int (*dup_f)(int fd);
+-#ifdef __GLIBC__
+- int (*ioctl_f)(int fd, unsigned long int request, ...);
+-#else
++#if defined(__sun) || defined(__BIONIC__) || defined(__musl__) /* POSIX-like */
+ int (*ioctl_f)(int fd, int request, ...);
++#else
++ int (*ioctl_f)(int fd, unsigned long int request, ...);
+ #endif
+ ssize_t (*read_f)(int fd, void *buffer, size_t n);
+ void *(*mmap_f)(void *start, size_t length, int prot, int flags, int fd, int64_t offset);
diff --git a/multimedia/ffmpeg4/files/patch-libavfilter_vf__lensfun.c b/multimedia/ffmpeg4/files/patch-libavfilter_vf__lensfun.c
new file mode 100644
index 000000000000..805d07687521
--- /dev/null
+++ b/multimedia/ffmpeg4/files/patch-libavfilter_vf__lensfun.c
@@ -0,0 +1,51 @@
+Partially revert https://git.ffmpeg.org/gitweb/ffmpeg.git/commitdiff/8b78eb312de9
+until graphics/lensfun is updated to a version that contains
+https://github.com/lensfun/lensfun/commit/b135e05d729d
+
+--- libavfilter/vf_lensfun.c.orig 2021-04-08 21:28:40 UTC
++++ libavfilter/vf_lensfun.c
+@@ -222,20 +222,39 @@ static int config_props(AVFilterLink *inlink)
+
+ if (!lensfun->modifier) {
+ if (lensfun->camera && lensfun->lens) {
+- lensfun->modifier = lf_modifier_create(lensfun->lens,
++ lensfun->modifier = lf_modifier_create(
++#if (LF_VERSION > 0x35F00)
++ lensfun->lens,
+ lensfun->focal_length,
++#endif
+ lensfun->camera->CropFactor,
+ inlink->w,
+ inlink->h, LF_PF_U8, lensfun->reverse);
+ if (lensfun->mode & VIGNETTING)
+- lf_modifier_enable_vignetting_correction(lensfun->modifier, lensfun->aperture, lensfun->focus_distance);
++ lf_modifier_enable_vignetting_correction(lensfun->modifier,
++#if (LF_VERSION <= 0x35F00)
++ lensfun->lens, lensfun->focal_length,
++#endif
++ lensfun->aperture, lensfun->focus_distance);
+ if (lensfun->mode & GEOMETRY_DISTORTION) {
+- lf_modifier_enable_distortion_correction(lensfun->modifier);
+- lf_modifier_enable_projection_transform(lensfun->modifier, lensfun->target_geometry);
++ lf_modifier_enable_distortion_correction(lensfun->modifier,
++#if (LF_VERSION <= 0x35F00)
++ lensfun->lens, lensfun->focal_length
++#endif
++ );
++ lf_modifier_enable_projection_transform(lensfun->modifier,
++#if (LF_VERSION <= 0x35F00)
++ lensfun->lens, lensfun->focal_length,
++#endif
++ lensfun->target_geometry);
+ lf_modifier_enable_scaling(lensfun->modifier, lensfun->scale);
+ }
+ if (lensfun->mode & SUBPIXEL_DISTORTION)
+- lf_modifier_enable_tca_correction(lensfun->modifier);
++ lf_modifier_enable_tca_correction(lensfun->modifier,
++#if (LF_VERSION <= 0x35F00)
++ lensfun->lens, lensfun->focal_length
++#endif
++ );
+ } else {
+ // lensfun->camera and lensfun->lens should have been initialized
+ return AVERROR_BUG;
diff --git a/multimedia/ffmpeg4/files/patch-libavformat_rtsp.c b/multimedia/ffmpeg4/files/patch-libavformat_rtsp.c
new file mode 100644
index 000000000000..7cd751dbd79c
--- /dev/null
+++ b/multimedia/ffmpeg4/files/patch-libavformat_rtsp.c
@@ -0,0 +1,44 @@
+--- libavformat/rtsp.c.orig 2016-10-27 16:17:40 UTC
++++ libavformat/rtsp.c
+@@ -1614,7 +1614,12 @@ int ff_rtsp_make_setup_request(AVFormatC
+ }
+ if (ttl > 0)
+ snprintf(optbuf, sizeof(optbuf), "?ttl=%d", ttl);
+- getnameinfo((struct sockaddr*) &addr, sizeof(addr),
++ getnameinfo((struct sockaddr*) &addr,
++#if HAVE_STRUCT_SOCKADDR_SA_LEN
++ ((struct sockaddr*) &addr)->sa_len,
++#else
++ sizeof(addr),
++#endif
+ namebuf, sizeof(namebuf), NULL, 0, NI_NUMERICHOST);
+ ff_url_join(url, sizeof(url), "rtp", NULL, namebuf,
+ port, "%s", optbuf);
+@@ -1830,8 +1835,13 @@ redirect:
+ goto fail;
+ }
+ if (!getpeername(tcp_fd, (struct sockaddr*) &peer, &peer_len)) {
+- getnameinfo((struct sockaddr*) &peer, peer_len, host, sizeof(host),
+- NULL, 0, NI_NUMERICHOST);
++ getnameinfo((struct sockaddr*) &peer,
++#if HAVE_STRUCT_SOCKADDR_SA_LEN
++ ((struct sockaddr*) &peer)->sa_len,
++#else
++ peer_len,
++#endif
++ host, sizeof(host), NULL, 0, NI_NUMERICHOST);
+ }
+
+ /* request options supported by the server; this also detects server
+@@ -2310,7 +2320,11 @@ static int sdp_read_header(AVFormatConte
+ AVDictionary *opts = map_to_opts(rt);
+
+ err = getnameinfo((struct sockaddr*) &rtsp_st->sdp_ip,
++#if HAVE_STRUCT_SOCKADDR_SA_LEN
++ ((struct sockaddr*) &rtsp_st->sdp_ip)->sa_len,
++#else
+ sizeof(rtsp_st->sdp_ip),
++#endif
+ namebuf, sizeof(namebuf), NULL, 0, NI_NUMERICHOST);
+ if (err) {
+ av_log(s, AV_LOG_ERROR, "getnameinfo: %s\n", gai_strerror(err));
diff --git a/multimedia/ffmpeg4/files/patch-libavutil-common.h b/multimedia/ffmpeg4/files/patch-libavutil-common.h
new file mode 100644
index 000000000000..2c8c84e6d372
--- /dev/null
+++ b/multimedia/ffmpeg4/files/patch-libavutil-common.h
@@ -0,0 +1,13 @@
+--- libavutil/common.h.orig 2015-06-19 20:44:53 UTC
++++ libavutil/common.h
+@@ -49,6 +49,10 @@
+ # define AV_NE(be, le) (le)
+ #endif
+
++#ifndef UINT64_C
++#define UINT64_C(c) (c ## UL)
++#endif
++
+ //rounded division & shift
+ #define RSHIFT(a,b) ((a) > 0 ? ((a) + ((1<<(b))>>1))>>(b) : ((a) + ((1<<(b))>>1)-1)>>(b))
+ /* assume b>0 */
diff --git a/multimedia/ffmpeg4/files/patch-libavutil-x86-asm.h b/multimedia/ffmpeg4/files/patch-libavutil-x86-asm.h
new file mode 100644
index 000000000000..71e31a029955
--- /dev/null
+++ b/multimedia/ffmpeg4/files/patch-libavutil-x86-asm.h
@@ -0,0 +1,11 @@
+--- libavutil/x86/asm.h.orig 2015-06-19 20:44:54 UTC
++++ libavutil/x86/asm.h
+@@ -71,7 +71,7 @@ typedef int32_t x86_reg;
+ typedef int x86_reg;
+ #endif
+
+-#define HAVE_7REGS (ARCH_X86_64 || (HAVE_EBX_AVAILABLE && HAVE_EBP_AVAILABLE))
++#define HAVE_7REGS (ARCH_X86_64 || (HAVE_EBX_AVAILABLE && HAVE_EBP_AVAILABLE && !defined(__clang__)))
+ #define HAVE_6REGS (ARCH_X86_64 || (HAVE_EBX_AVAILABLE || HAVE_EBP_AVAILABLE))
+
+ #if ARCH_X86_64 && defined(PIC)
diff --git a/multimedia/ffmpeg4/files/patch-libavutil_hwcontext__drm.c b/multimedia/ffmpeg4/files/patch-libavutil_hwcontext__drm.c
new file mode 100644
index 000000000000..f5e186300975
--- /dev/null
+++ b/multimedia/ffmpeg4/files/patch-libavutil_hwcontext__drm.c
@@ -0,0 +1,24 @@
+drm-kmod doesn't expose uAPI yet, so bundle like Mesa
+
+--- libavutil/hwcontext_drm.c.orig 2022-07-22 17:58:39 UTC
++++ libavutil/hwcontext_drm.c
+@@ -28,6 +28,19 @@
+ #if HAVE_LINUX_DMA_BUF_H
+ #include <linux/dma-buf.h>
+ #include <sys/ioctl.h>
++#else // BSDs
++#undef HAVE_LINUX_DMA_BUF_H
++#define HAVE_LINUX_DMA_BUF_H 1
++#include <sys/ioctl.h>
++struct dma_buf_sync {
++ uint64_t flags;
++};
++#define DMA_BUF_BASE 'b'
++#define DMA_BUF_IOCTL_SYNC _IOW(DMA_BUF_BASE, 0, struct dma_buf_sync)
++#define DMA_BUF_SYNC_READ (1 << 0)
++#define DMA_BUF_SYNC_WRITE (2 << 0)
++#define DMA_BUF_SYNC_START (0 << 2)
++#define DMA_BUF_SYNC_END (1 << 2)
+ #endif
+
+ #include <drm.h>
diff --git a/multimedia/ffmpeg4/files/patch-libswscale_ppc_yuv2rgb__altivec.c b/multimedia/ffmpeg4/files/patch-libswscale_ppc_yuv2rgb__altivec.c
new file mode 100644
index 000000000000..38ff9087b842
--- /dev/null
+++ b/multimedia/ffmpeg4/files/patch-libswscale_ppc_yuv2rgb__altivec.c
@@ -0,0 +1,15 @@
+Error:
+libswscale/ppc/yuv2rgb_altivec.c:288:36: error: redeclaration of 'vec_xl' must have the 'overloadable' attribute
+static inline vector unsigned char vec_xl(signed long long offset, const ubyte *addr)
+
+--- libswscale/ppc/yuv2rgb_altivec.c.orig 2021-04-08 21:28:40 UTC
++++ libswscale/ppc/yuv2rgb_altivec.c
+@@ -284,7 +284,7 @@ static inline void cvtyuvtoRGB(SwsContext *c, vector s
+ * ------------------------------------------------------------------------------
+ */
+
+-#if !HAVE_VSX
++#if !HAVE_VSX && !defined(__clang__)
+ static inline vector unsigned char vec_xl(signed long long offset, const ubyte *addr)
+ {
+ const vector unsigned char *v_addr = (const vector unsigned char *) (addr + offset);
diff --git a/multimedia/ffmpeg4/files/patch-svtav1 b/multimedia/ffmpeg4/files/patch-svtav1
new file mode 100644
index 000000000000..5d8893a959fa
--- /dev/null
+++ b/multimedia/ffmpeg4/files/patch-svtav1
@@ -0,0 +1,437 @@
+https://git.ffmpeg.org/gitweb/ffmpeg.git/commitdiff/04b89e8ae33b
+https://git.ffmpeg.org/gitweb/ffmpeg.git/commitdiff/64e2fb3f9d89
+https://git.ffmpeg.org/gitweb/ffmpeg.git/commitdiff/0463f5d6d56d
+https://git.ffmpeg.org/gitweb/ffmpeg.git/commitdiff/c5f314309067
+https://git.ffmpeg.org/gitweb/ffmpeg.git/commitdiff/c33b4048859a
+https://git.ffmpeg.org/gitweb/ffmpeg.git/commitdiff/a2b090da7932
+https://git.ffmpeg.org/gitweb/ffmpeg.git/commitdiff/1dddb930aaf0
+https://git.ffmpeg.org/gitweb/ffmpeg.git/commitdiff/4e47ebf38b97
+https://git.ffmpeg.org/gitweb/ffmpeg.git/commitdiff/50bc87263576
+https://git.ffmpeg.org/gitweb/ffmpeg.git/commitdiff/d794b36a7788
+https://git.ffmpeg.org/gitweb/ffmpeg.git/commitdiff/51c0b9e829be
+https://git.ffmpeg.org/gitweb/ffmpeg.git/commitdiff/e3c4442b249a
+https://git.ffmpeg.org/gitweb/ffmpeg.git/commitdiff/6fd1533057ff
+https://git.ffmpeg.org/gitweb/ffmpeg.git/commitdiff/ded0334d214f
+https://git.ffmpeg.org/gitweb/ffmpeg.git/commitdiff/70887d44ffa3
+https://git.ffmpeg.org/gitweb/ffmpeg.git/commitdiff/fe100bc556d7
+https://git.ffmpeg.org/gitweb/ffmpeg.git/commitdiff/fb70e0611bd7
+
+--- configure.orig 2021-10-24 20:47:11 UTC
++++ configure
+@@ -6430,7 +6430,7 @@ enabled libsrt && require_pkg_config libsrt
+ enabled libssh && require_pkg_config libssh libssh libssh/sftp.h sftp_init
+ enabled libspeex && require_pkg_config libspeex speex speex/speex.h speex_decoder_init
+ enabled libsrt && require_pkg_config libsrt "srt >= 1.3.0" srt/srt.h srt_socket
+-enabled libsvtav1 && require_pkg_config libsvtav1 "SvtAv1Enc >= 0.8.4" EbSvtAv1Enc.h svt_av1_enc_init_handle
++enabled libsvtav1 && require_pkg_config libsvtav1 "SvtAv1Enc >= 0.9.0" EbSvtAv1Enc.h svt_av1_enc_init_handle
+ enabled libtensorflow && require libtensorflow tensorflow/c/c_api.h TF_Version -ltensorflow
+ enabled libtesseract && require_pkg_config libtesseract tesseract tesseract/capi.h TessBaseAPICreate
+ enabled libtheora && require libtheora theora/theoraenc.h th_info_init -ltheoraenc -ltheoradec -logg
+--- doc/encoders.texi.orig 2021-10-24 20:47:07 UTC
++++ doc/encoders.texi
+@@ -1754,28 +1754,15 @@ Set the operating point tier.
+ @item tier
+ Set the operating point tier.
+
+-@item rc
+-Set the rate control mode to use.
+-
+-Possible modes:
+-@table @option
+-@item cqp
+-Constant quantizer: use fixed values of qindex (dependent on the frame type)
+-throughout the stream. This mode is the default.
+-
+-@item vbr
+-Variable bitrate: use a target bitrate for the whole stream.
+-
+-@item cvbr
+-Constrained variable bitrate: use a target bitrate for each GOP.
+-@end table
+-
+ @item qmax
+ Set the maximum quantizer to use when using a bitrate mode.
+
+ @item qmin
+ Set the minimum quantizer to use when using a bitrate mode.
+
++@item crf
++Constant rate factor value used in crf rate control mode (0-63).
++
+ @item qp
+ Set the quantizer used in cqp rate control mode (0-63).
+
+@@ -1786,14 +1773,18 @@ Set number of frames to look ahead (0-120).
+ Set number of frames to look ahead (0-120).
+
+ @item preset
+-Set the quality-speed tradeoff, in the range 0 to 8. Higher values are
+-faster but lower quality. Defaults to 8 (highest speed).
++Set the quality-speed tradeoff, in the range 0 to 13. Higher values are
++faster but lower quality.
+
+ @item tile_rows
+ Set log2 of the number of rows of tiles to use (0-6).
+
+ @item tile_columns
+ Set log2 of the number of columns of tiles to use (0-4).
++
++@item svtav1-params
++Set SVT-AV1 options using a list of @var{key}=@var{value} pairs separated
++by ":". See the SVT-AV1 encoder user guide for a list of accepted parameters.
+
+ @end table
+
+--- libavcodec/libsvtav1.c.orig 2021-10-24 20:47:07 UTC
++++ libavcodec/libsvtav1.c
+@@ -60,17 +60,20 @@ typedef struct SvtContext {
+ EOS_STATUS eos_flag;
+
+ // User options.
++ AVDictionary *svtav1_opts;
++#if FF_API_SVTAV1_OPTS
+ int hierarchical_level;
+ int la_depth;
+- int enc_mode;
+- int rc_mode;
+ int scd;
+- int qp;
+
+ int tier;
+
+ int tile_columns;
+ int tile_rows;
++#endif
++ int enc_mode;
++ int crf;
++ int qp;
+ } SvtContext;
+
+ static const struct {
+@@ -151,11 +154,126 @@ static int config_enc_params(EbSvtAv1EncConfiguration
+ {
+ SvtContext *svt_enc = avctx->priv_data;
+ const AVPixFmtDescriptor *desc;
++ AVDictionaryEntry *en = NULL;
+
++ // Update param from options
++#if FF_API_SVTAV1_OPTS
++ param->hierarchical_levels = svt_enc->hierarchical_level;
++ param->tier = svt_enc->tier;
++ param->scene_change_detection = svt_enc->scd;
++ param->tile_columns = svt_enc->tile_columns;
++ param->tile_rows = svt_enc->tile_rows;
++
++ if (svt_enc->la_depth >= 0)
++ param->look_ahead_distance = svt_enc->la_depth;
++#endif
++
++ if (svt_enc->enc_mode >= 0)
++ param->enc_mode = svt_enc->enc_mode;
++
++ if (avctx->bit_rate) {
++ param->target_bit_rate = avctx->bit_rate;
++ if (avctx->rc_max_rate != avctx->bit_rate)
++ param->rate_control_mode = 1;
++ else
++ param->rate_control_mode = 2;
++
++ param->max_qp_allowed = avctx->qmax;
++ param->min_qp_allowed = avctx->qmin;
++ }
++ param->max_bit_rate = avctx->rc_max_rate;
++ param->vbv_bufsize = avctx->rc_buffer_size;
++
++ if (svt_enc->crf > 0) {
++ param->qp = svt_enc->crf;
++ param->rate_control_mode = 0;
++ } else if (svt_enc->qp > 0) {
++ param->qp = svt_enc->qp;
++ param->rate_control_mode = 0;
++ param->enable_adaptive_quantization = 0;
++ }
++
++ desc = av_pix_fmt_desc_get(avctx->pix_fmt);
++ param->color_primaries = avctx->color_primaries;
++ param->matrix_coefficients = (desc->flags & AV_PIX_FMT_FLAG_RGB) ?
++ AVCOL_SPC_RGB : avctx->colorspace;
++ param->transfer_characteristics = avctx->color_trc;
++
++ if (avctx->color_range != AVCOL_RANGE_UNSPECIFIED)
++ param->color_range = avctx->color_range == AVCOL_RANGE_JPEG;
++ else
++ param->color_range = !!(desc->flags & AV_PIX_FMT_FLAG_RGB);
++
++#if SVT_AV1_CHECK_VERSION(1, 0, 0)
++ if (avctx->chroma_sample_location != AVCHROMA_LOC_UNSPECIFIED) {
++ const char *name =
++ av_chroma_location_name(avctx->chroma_sample_location);
++
++ switch (avctx->chroma_sample_location) {
++ case AVCHROMA_LOC_LEFT:
++ param->chroma_sample_position = EB_CSP_VERTICAL;
++ break;
++ case AVCHROMA_LOC_TOPLEFT:
++ param->chroma_sample_position = EB_CSP_COLOCATED;
++ break;
++ default:
++ if (!name)
++ break;
++
++ av_log(avctx, AV_LOG_WARNING,
++ "Specified chroma sample location %s is unsupported "
++ "on the AV1 bit stream level. Usage of a container that "
++ "allows passing this information - such as Matroska - "
++ "is recommended.\n",
++ name);
++ break;
++ }
++ }
++#endif
++
++ if (avctx->profile != FF_PROFILE_UNKNOWN)
++ param->profile = avctx->profile;
++
++ if (avctx->level != FF_LEVEL_UNKNOWN)
++ param->level = avctx->level;
++
++ if (avctx->gop_size > 0)
++ param->intra_period_length = avctx->gop_size - 1;
++
++ if (avctx->framerate.num > 0 && avctx->framerate.den > 0) {
++ param->frame_rate_numerator = avctx->framerate.num;
++ param->frame_rate_denominator = avctx->framerate.den;
++ } else {
++ param->frame_rate_numerator = avctx->time_base.den;
++ param->frame_rate_denominator = avctx->time_base.num * avctx->ticks_per_frame;
++ }
++
++ /* 2 = IDR, closed GOP, 1 = CRA, open GOP */
++ param->intra_refresh_type = avctx->flags & AV_CODEC_FLAG_CLOSED_GOP ? 2 : 1;
++
++#if SVT_AV1_CHECK_VERSION(0, 9, 1)
++ while ((en = av_dict_get(svt_enc->svtav1_opts, "", en, AV_DICT_IGNORE_SUFFIX))) {
++ EbErrorType ret = svt_av1_enc_parse_parameter(param, en->key, en->value);
++ if (ret != EB_ErrorNone) {
++ int level = (avctx->err_recognition & AV_EF_EXPLODE) ? AV_LOG_ERROR : AV_LOG_WARNING;
++ av_log(avctx, level, "Error parsing option %s: %s.\n", en->key, en->value);
++ if (avctx->err_recognition & AV_EF_EXPLODE)
++ return AVERROR(EINVAL);
++ }
++ }
++#else
++ if ((en = av_dict_get(svt_enc->svtav1_opts, "", NULL, AV_DICT_IGNORE_SUFFIX))) {
++ int level = (avctx->err_recognition & AV_EF_EXPLODE) ? AV_LOG_ERROR : AV_LOG_WARNING;
++ av_log(avctx, level, "svt-params needs libavcodec to be compiled with SVT-AV1 "
++ "headers >= 0.9.1.\n");
++ if (avctx->err_recognition & AV_EF_EXPLODE)
++ return AVERROR(ENOSYS);
++ }
++#endif
++
+ param->source_width = avctx->width;
+ param->source_height = avctx->height;
+
+- desc = av_pix_fmt_desc_get(avctx->pix_fmt);
+ param->encoder_bit_depth = desc->comp[0].depth;
+
+ if (desc->log2_chroma_w == 1 && desc->log2_chroma_h == 1)
+@@ -169,12 +287,6 @@ static int config_enc_params(EbSvtAv1EncConfiguration
+ return AVERROR(EINVAL);
+ }
+
+- if (avctx->profile != FF_PROFILE_UNKNOWN)
+- param->profile = avctx->profile;
+-
+- if (avctx->level != FF_LEVEL_UNKNOWN)
+- param->level = avctx->level;
+-
+ if ((param->encoder_color_format == EB_YUV422 || param->encoder_bit_depth > 10)
+ && param->profile != FF_PROFILE_AV1_PROFESSIONAL ) {
+ av_log(avctx, AV_LOG_WARNING, "Forcing Professional profile\n");
+@@ -184,40 +296,21 @@ static int config_enc_params(EbSvtAv1EncConfiguration
+ param->profile = FF_PROFILE_AV1_HIGH;
+ }
+
+- // Update param from options
+- param->hierarchical_levels = svt_enc->hierarchical_level;
+- param->enc_mode = svt_enc->enc_mode;
+- param->tier = svt_enc->tier;
+- param->rate_control_mode = svt_enc->rc_mode;
+- param->scene_change_detection = svt_enc->scd;
+- param->qp = svt_enc->qp;
++ avctx->bit_rate = param->rate_control_mode > 0 ?
++ param->target_bit_rate : 0;
++ avctx->rc_max_rate = param->max_bit_rate;
++ avctx->rc_buffer_size = param->vbv_bufsize;
+
+- param->target_bit_rate = avctx->bit_rate;
++ if (avctx->bit_rate || avctx->rc_max_rate || avctx->rc_buffer_size) {
++ AVCPBProperties *cpb_props = ff_add_cpb_side_data(avctx);
++ if (!cpb_props)
++ return AVERROR(ENOMEM);
+
+- if (avctx->gop_size > 0)
+- param->intra_period_length = avctx->gop_size - 1;
+-
+- if (avctx->framerate.num > 0 && avctx->framerate.den > 0) {
+- param->frame_rate_numerator = avctx->framerate.num;
+- param->frame_rate_denominator = avctx->framerate.den;
+- } else {
+- param->frame_rate_numerator = avctx->time_base.den;
+- param->frame_rate_denominator = avctx->time_base.num * avctx->ticks_per_frame;
++ cpb_props->buffer_size = avctx->rc_buffer_size;
++ cpb_props->max_bitrate = avctx->rc_max_rate;
++ cpb_props->avg_bitrate = avctx->bit_rate;
+ }
+
+- if (param->rate_control_mode) {
+- param->max_qp_allowed = avctx->qmax;
+- param->min_qp_allowed = avctx->qmin;
+- }
+-
+- param->intra_refresh_type = 2; /* Real keyframes only */
+-
+- if (svt_enc->la_depth >= 0)
+- param->look_ahead_distance = svt_enc->la_depth;
+-
+- param->tile_columns = svt_enc->tile_columns;
+- param->tile_rows = svt_enc->tile_rows;
+-
+ return 0;
+ }
+
+@@ -330,11 +423,8 @@ static int eb_send_frame(AVCodecContext *avctx, const
+ if (svt_enc->eos_flag == EOS_SENT)
+ return 0;
+
+- headerPtrLast.n_alloc_len = 0;
+- headerPtrLast.n_filled_len = 0;
+- headerPtrLast.n_tick_count = 0;
+- headerPtrLast.p_app_private = NULL;
+- headerPtrLast.p_buffer = NULL;
++ memset(&headerPtrLast, 0, sizeof(headerPtrLast));
++ headerPtrLast.pic_type = EB_AV1_INVALID_PICTURE;
+ headerPtrLast.flags = EB_BUFFERFLAG_EOS;
+
+ svt_av1_enc_send_picture(svt_enc->svt_handle, &headerPtrLast);
+@@ -350,6 +440,16 @@ static int eb_send_frame(AVCodecContext *avctx, const
+ headerPtr->p_app_private = NULL;
+ headerPtr->pts = frame->pts;
+
++ switch (frame->pict_type) {
++ case AV_PICTURE_TYPE_I:
++ headerPtr->pic_type = EB_AV1_KEY_PICTURE;
++ break;
++ default:
++ // Actually means auto, or default.
++ headerPtr->pic_type = EB_AV1_INVALID_PICTURE;
++ break;
++ }
++
+ svt_av1_enc_send_picture(svt_enc->svt_handle, headerPtr);
+
+ return 0;
+@@ -472,21 +572,22 @@ static const AVOption options[] = {
+ #define OFFSET(x) offsetof(SvtContext, x)
+ #define VE AV_OPT_FLAG_VIDEO_PARAM | AV_OPT_FLAG_ENCODING_PARAM
+ static const AVOption options[] = {
+- { "hielevel", "Hierarchical prediction levels setting", OFFSET(hierarchical_level),
+- AV_OPT_TYPE_INT, { .i64 = 4 }, 3, 4, VE , "hielevel"},
++#if FF_API_SVTAV1_OPTS
++ { "hielevel", "Hierarchical prediction levels setting (Deprecated, use svtav1-params)", OFFSET(hierarchical_level),
++ AV_OPT_TYPE_INT, { .i64 = 4 }, 3, 4, VE | AV_OPT_FLAG_DEPRECATED , "hielevel"},
+ { "3level", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = 3 }, INT_MIN, INT_MAX, VE, "hielevel" },
+ { "4level", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = 4 }, INT_MIN, INT_MAX, VE, "hielevel" },
+
+- { "la_depth", "Look ahead distance [0, 120]", OFFSET(la_depth),
+- AV_OPT_TYPE_INT, { .i64 = -1 }, -1, 120, VE },
++ { "la_depth", "Look ahead distance [0, 120] (Deprecated, use svtav1-params)", OFFSET(la_depth),
++ AV_OPT_TYPE_INT, { .i64 = -1 }, -1, 120, VE | AV_OPT_FLAG_DEPRECATED },
+
+- { "preset", "Encoding preset [0, 8]",
+- OFFSET(enc_mode), AV_OPT_TYPE_INT, { .i64 = MAX_ENC_PRESET }, 0, MAX_ENC_PRESET, VE },
+-
+- { "tier", "Set operating point tier", OFFSET(tier),
+- AV_OPT_TYPE_INT, { .i64 = 0 }, 0, 1, VE, "tier" },
++ { "tier", "Set operating point tier (Deprecated, use svtav1-params)", OFFSET(tier),
++ AV_OPT_TYPE_INT, { .i64 = 0 }, 0, 1, VE | AV_OPT_FLAG_DEPRECATED, "tier" },
+ { "main", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = 0 }, 0, 0, VE, "tier" },
+ { "high", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = 1 }, 0, 0, VE, "tier" },
++#endif
++ { "preset", "Encoding preset",
++ OFFSET(enc_mode), AV_OPT_TYPE_INT, { .i64 = -1 }, -1, MAX_ENC_PRESET, VE },
+
+ FF_AV1_PROFILE_OPTS
+
+@@ -518,21 +619,20 @@ static const AVOption options[] = {
+ { LEVEL("7.3", 73) },
+ #undef LEVEL
+
+- { "rc", "Bit rate control mode", OFFSET(rc_mode),
+- AV_OPT_TYPE_INT, { .i64 = 0 }, 0, 3, VE , "rc"},
+- { "cqp", "Constant quantizer", 0, AV_OPT_TYPE_CONST, { .i64 = 0 }, INT_MIN, INT_MAX, VE, "rc" },
+- { "vbr", "Variable Bit Rate, use a target bitrate for the entire stream", 0, AV_OPT_TYPE_CONST, { .i64 = 1 }, INT_MIN, INT_MAX, VE, "rc" },
+- { "cvbr", "Constrained Variable Bit Rate, use a target bitrate for each GOP", 0, AV_OPT_TYPE_CONST,{ .i64 = 2 }, INT_MIN, INT_MAX, VE, "rc" },
++ { "crf", "Constant Rate Factor value", OFFSET(crf),
++ AV_OPT_TYPE_INT, { .i64 = 0 }, 0, 63, VE },
++ { "qp", "Initial Quantizer level value", OFFSET(qp),
++ AV_OPT_TYPE_INT, { .i64 = 0 }, 0, 63, VE },
++#if FF_API_SVTAV1_OPTS
++ { "sc_detection", "Scene change detection (Deprecated, use svtav1-params)", OFFSET(scd),
++ AV_OPT_TYPE_BOOL, { .i64 = 0 }, 0, 1, VE | AV_OPT_FLAG_DEPRECATED },
+
+- { "qp", "Quantizer to use with cqp rate control mode", OFFSET(qp),
+- AV_OPT_TYPE_INT, { .i64 = 50 }, 0, 63, VE },
++ { "tile_columns", "Log2 of number of tile columns to use (Deprecated, use svtav1-params)", OFFSET(tile_columns), AV_OPT_TYPE_INT, { .i64 = 0 }, 0, 4, VE | AV_OPT_FLAG_DEPRECATED },
++ { "tile_rows", "Log2 of number of tile rows to use (Deprecated, use svtav1-params)", OFFSET(tile_rows), AV_OPT_TYPE_INT, { .i64 = 0 }, 0, 6, VE | AV_OPT_FLAG_DEPRECATED },
++#endif
+
+- { "sc_detection", "Scene change detection", OFFSET(scd),
+- AV_OPT_TYPE_BOOL, { .i64 = 0 }, 0, 1, VE },
++ { "svtav1-params", "Set the SVT-AV1 configuration using a :-separated list of key=value parameters", OFFSET(svtav1_opts), AV_OPT_TYPE_DICT, { 0 }, 0, 0, VE },
+
+- { "tile_columns", "Log2 of number of tile columns to use", OFFSET(tile_columns), AV_OPT_TYPE_INT, {.i64 = 0}, 0, 4, VE},
+- { "tile_rows", "Log2 of number of tile rows to use", OFFSET(tile_rows), AV_OPT_TYPE_INT, {.i64 = 0}, 0, 6, VE},
+-
+ {NULL},
+ };
+
+@@ -544,9 +644,10 @@ static const AVCodecDefault eb_enc_defaults[] = {
+ };
+
+ static const AVCodecDefault eb_enc_defaults[] = {
+- { "b", "7M" },
++ { "b", "0" },
++ { "flags", "+cgop" },
+ { "g", "-1" },
+- { "qmin", "0" },
++ { "qmin", "1" },
+ { "qmax", "63" },
+ { NULL },
+ };
+@@ -561,12 +662,11 @@ AVCodec ff_libsvtav1_encoder = {
+ .receive_packet = eb_receive_packet,
+ .close = eb_enc_close,
+ .capabilities = AV_CODEC_CAP_DELAY | AV_CODEC_CAP_OTHER_THREADS,
+- .caps_internal = FF_CODEC_CAP_AUTO_THREADS,
++ .caps_internal = FF_CODEC_CAP_AUTO_THREADS | FF_CODEC_CAP_INIT_CLEANUP,
+ .pix_fmts = (const enum AVPixelFormat[]){ AV_PIX_FMT_YUV420P,
+ AV_PIX_FMT_YUV420P10,
+ AV_PIX_FMT_NONE },
+ .priv_class = &class,
+ .defaults = eb_enc_defaults,
+- .caps_internal = FF_CODEC_CAP_INIT_CLEANUP,
+ .wrapper_name = "libsvtav1",
+ };
+--- libavcodec/version.h.orig 2021-10-24 20:47:07 UTC
++++ libavcodec/version.h
+@@ -168,5 +168,8 @@
+ #ifndef FF_API_INIT_PACKET
+ #define FF_API_INIT_PACKET (LIBAVCODEC_VERSION_MAJOR < 60)
+ #endif
++#ifndef FF_API_SVTAV1_OPTS
++#define FF_API_SVTAV1_OPTS (LIBAVCODEC_VERSION_MAJOR < 60)
++#endif
+
+ #endif /* AVCODEC_VERSION_H */
diff --git a/multimedia/ffmpeg4/files/patch-vmaf b/multimedia/ffmpeg4/files/patch-vmaf
new file mode 100644
index 000000000000..abe772274d3c
--- /dev/null
+++ b/multimedia/ffmpeg4/files/patch-vmaf
@@ -0,0 +1,951 @@
+https://git.ffmpeg.org/gitweb/ffmpeg.git/commitdiff/3d29724c008d
+
+--- configure.orig 2021-10-24 20:47:11 UTC
++++ configure
+@@ -3663,7 +3663,7 @@ vidstabtransform_filter_deps="libvidstab"
+ vaguedenoiser_filter_deps="gpl"
+ vidstabdetect_filter_deps="libvidstab"
+ vidstabtransform_filter_deps="libvidstab"
+-libvmaf_filter_deps="libvmaf pthreads"
++libvmaf_filter_deps="libvmaf"
+ zmq_filter_deps="libzmq"
+ zoompan_filter_deps="swscale"
+ zscale_filter_deps="libzimg const_nan"
+@@ -6441,7 +6441,7 @@ enabled libvidstab && require_pkg_config libvid
+ enabled libuavs3d && require_pkg_config libuavs3d "uavs3d >= 1.1.41" uavs3d.h uavs3d_decode
+ enabled libv4l2 && require_pkg_config libv4l2 libv4l2 libv4l2.h v4l2_ioctl
+ enabled libvidstab && require_pkg_config libvidstab "vidstab >= 0.98" vid.stab/libvidstab.h vsMotionDetectInit
+-enabled libvmaf && require_pkg_config libvmaf "libvmaf >= 1.5.2" libvmaf.h compute_vmaf
++enabled libvmaf && require_pkg_config libvmaf "libvmaf >= 2.0.0" libvmaf.h vmaf_init
+ enabled libvo_amrwbenc && require libvo_amrwbenc vo-amrwbenc/enc_if.h E_IF_init -lvo-amrwbenc
+ enabled libvorbis && require_pkg_config libvorbis vorbis vorbis/codec.h vorbis_info_init &&
+ require_pkg_config libvorbisenc vorbisenc vorbis/vorbisenc.h vorbis_encode_init
+--- doc/filters.texi.orig 2021-10-24 20:47:07 UTC
++++ doc/filters.texi
+@@ -13867,66 +13867,58 @@ ffmpeg -i input.mov -vf lensfun=make=Canon:model="Cano
+
+ @section libvmaf
+
+-Obtain the VMAF (Video Multi-Method Assessment Fusion)
+-score between two input videos.
++Calulate the VMAF (Video Multi-Method Assessment Fusion) score for a
++reference/distorted pair of input videos.
+
+ The obtained VMAF score is printed through the logging system.
+
+ It requires Netflix's vmaf library (libvmaf) as a pre-requisite.
+ After installing the library it can be enabled using:
+ @code{./configure --enable-libvmaf}.
+-If no model path is specified it uses the default model: @code{vmaf_v0.6.1.pkl}.
+
+ The filter has following options:
+
+ @table @option
++@item model
++A `|` delimited list of vmaf models. Each model can be configured with a number of parameters.
++Default value: @code{"version=vmaf_v0.6.1"}
++
+ @item model_path
+-Set the model path which is to be used for SVM.
+-Default value: @code{"/usr/local/share/model/vmaf_v0.6.1.pkl"}
++Deprecated, use model='path=...'.
+
+-@item log_path
+-Set the file path to be used to store logs.
+-
+-@item log_fmt
+-Set the format of the log file (csv, json or xml).
+-
+ @item enable_transform
+-This option can enable/disable the @code{score_transform} applied to the final predicted VMAF score,
+-if you have specified score_transform option in the input parameter file passed to @code{run_vmaf_training.py}
+-Default value: @code{false}
++Deprecated, use model='enable_transform=true'.
+
+ @item phone_model
+-Invokes the phone model which will generate VMAF scores higher than in the
+-regular model, which is more suitable for laptop, TV, etc. viewing conditions.
+-Default value: @code{false}
++Deprecated, use model='enable_transform=true'.
+
++@item enable_conf_interval
++Deprecated, use model='enable_conf_interval=true'.
++
++@item feature
++A `|` delimited list of features. Each feature can be configured with a number of parameters.
++
+ @item psnr
+-Enables computing psnr along with vmaf.
+-Default value: @code{false}
++Deprecated, use feature='name=psnr'.
+
+ @item ssim
+-Enables computing ssim along with vmaf.
+-Default value: @code{false}
++Deprecated, use feature='name=ssim'.
+
+ @item ms_ssim
+-Enables computing ms_ssim along with vmaf.
+-Default value: @code{false}
++Deprecated, use feature='name=ms_ssim'.
+
+-@item pool
+-Set the pool method to be used for computing vmaf.
+-Options are @code{min}, @code{harmonic_mean} or @code{mean} (default).
++@item log_path
++Set the file path to be used to store log files.
+
++@item log_fmt
++Set the format of the log file (xml, json, csv, or sub).
++
+ @item n_threads
+-Set number of threads to be used when computing vmaf.
+-Default value: @code{0}, which makes use of all available logical processors.
++Set number of threads to be used when initializing libvmaf.
++Default value: @code{0}, no threads.
+
+ @item n_subsample
+-Set interval for frame subsampling used when computing vmaf.
+-Default value: @code{1}
+-
+-@item enable_conf_interval
+-Enables confidence interval.
+-Default value: @code{false}
++Set frame subsampling interval to be used.
+ @end table
+
+ This filter also supports the @ref{framesync} options.
+@@ -13934,23 +13926,31 @@ This filter also supports the @ref{framesync} options.
+ @subsection Examples
+ @itemize
+ @item
+-On the below examples the input file @file{main.mpg} being processed is
+-compared with the reference file @file{ref.mpg}.
++In the examples below, a distorted video @file{distorted.mpg} is
++compared with a reference file @file{reference.mpg}.
+
++@item
++Basic usage:
+ @example
+-ffmpeg -i main.mpg -i ref.mpg -lavfi libvmaf -f null -
++ffmpeg -i distorted.mpg -i reference.mpg -lavfi libvmaf=log_path=output.xml -f null -
+ @end example
+
+ @item
+-Example with options:
++Example with multiple models:
+ @example
+-ffmpeg -i main.mpg -i ref.mpg -lavfi libvmaf="psnr=1:log_fmt=json" -f null -
++ffmpeg -i distorted.mpg -i reference.mpg -lavfi libvmaf='model=version=vmaf_v0.6.1\\:name=vmaf|version=vmaf_v0.6.1neg\\:name=vmaf_neg' -f null -
+ @end example
+
+ @item
++Example with multiple addtional features:
++@example
++ffmpeg -i distorted.mpg -i reference.mpg -lavfi libvmaf='feature=name=psnr|name=ciede' -f null -
++@end example
++
++@item
+ Example with options and different containers:
+ @example
+-ffmpeg -i main.mpg -i ref.mkv -lavfi "[0:v]settb=AVTB,setpts=PTS-STARTPTS[main];[1:v]settb=AVTB,setpts=PTS-STARTPTS[ref];[main][ref]libvmaf=psnr=1:log_fmt=json" -f null -
++ffmpeg -i distorted.mpg -i reference.mkv -lavfi "[0:v]settb=AVTB,setpts=PTS-STARTPTS[main];[1:v]settb=AVTB,setpts=PTS-STARTPTS[ref];[main][ref]libvmaf=log_fmt=json:log_path=output.json" -f null -
+ @end example
+ @end itemize
+
+--- libavfilter/vf_libvmaf.c.orig 2021-10-24 20:47:07 UTC
++++ libavfilter/vf_libvmaf.c
+@@ -24,8 +24,8 @@
+ * Calculate the VMAF between two input videos.
+ */
+
+-#include <pthread.h>
+ #include <libvmaf.h>
++
+ #include "libavutil/avstring.h"
+ #include "libavutil/opt.h"
+ #include "libavutil/pixdesc.h"
+@@ -39,23 +39,9 @@ typedef struct LIBVMAFContext {
+ typedef struct LIBVMAFContext {
+ const AVClass *class;
+ FFFrameSync fs;
+- const AVPixFmtDescriptor *desc;
+- int width;
+- int height;
+- double vmaf_score;
+- int vmaf_thread_created;
+- pthread_t vmaf_thread;
+- pthread_mutex_t lock;
+- pthread_cond_t cond;
+- int eof;
+- AVFrame *gmain;
+- AVFrame *gref;
+- int frame_set;
+ char *model_path;
+ char *log_path;
+ char *log_fmt;
+- int disable_clip;
+- int disable_avx;
+ int enable_transform;
+ int phone_model;
+ int psnr;
+@@ -65,185 +51,488 @@ typedef struct LIBVMAFContext {
+ int n_threads;
+ int n_subsample;
+ int enable_conf_interval;
+- int error;
++ char *model_cfg;
++ char *feature_cfg;
++ VmafContext *vmaf;
++ VmafModel **model;
++ unsigned model_cnt;
++ unsigned frame_cnt;
++ unsigned bpc;
+ } LIBVMAFContext;
+
+ #define OFFSET(x) offsetof(LIBVMAFContext, x)
+ #define FLAGS AV_OPT_FLAG_FILTERING_PARAM|AV_OPT_FLAG_VIDEO_PARAM
+
+ static const AVOption libvmaf_options[] = {
+- {"model_path", "Set the model to be used for computing vmaf.", OFFSET(model_path), AV_OPT_TYPE_STRING, {.str="/usr/local/share/model/vmaf_v0.6.1.pkl"}, 0, 1, FLAGS},
+- {"log_path", "Set the file path to be used to store logs.", OFFSET(log_path), AV_OPT_TYPE_STRING, {.str=NULL}, 0, 1, FLAGS},
+- {"log_fmt", "Set the format of the log (csv, json or xml).", OFFSET(log_fmt), AV_OPT_TYPE_STRING, {.str=NULL}, 0, 1, FLAGS},
+- {"enable_transform", "Enables transform for computing vmaf.", OFFSET(enable_transform), AV_OPT_TYPE_BOOL, {.i64=0}, 0, 1, FLAGS},
+- {"phone_model", "Invokes the phone model that will generate higher VMAF scores.", OFFSET(phone_model), AV_OPT_TYPE_BOOL, {.i64=0}, 0, 1, FLAGS},
+- {"psnr", "Enables computing psnr along with vmaf.", OFFSET(psnr), AV_OPT_TYPE_BOOL, {.i64=0}, 0, 1, FLAGS},
+- {"ssim", "Enables computing ssim along with vmaf.", OFFSET(ssim), AV_OPT_TYPE_BOOL, {.i64=0}, 0, 1, FLAGS},
+- {"ms_ssim", "Enables computing ms-ssim along with vmaf.", OFFSET(ms_ssim), AV_OPT_TYPE_BOOL, {.i64=0}, 0, 1, FLAGS},
++ {"model_path", "use model='path=...'.", OFFSET(model_path), AV_OPT_TYPE_STRING, {.str=NULL}, 0, 1, FLAGS|AV_OPT_FLAG_DEPRECATED},
++ {"log_path", "Set the file path to be used to write log.", OFFSET(log_path), AV_OPT_TYPE_STRING, {.str=NULL}, 0, 1, FLAGS},
++ {"log_fmt", "Set the format of the log (csv, json, xml, or sub).", OFFSET(log_fmt), AV_OPT_TYPE_STRING, {.str="xml"}, 0, 1, FLAGS},
++ {"enable_transform", "use model='enable_transform=true'.", OFFSET(enable_transform), AV_OPT_TYPE_BOOL, {.i64=0}, 0, 1, FLAGS|AV_OPT_FLAG_DEPRECATED},
++ {"phone_model", "use model='enable_transform=true'.", OFFSET(phone_model), AV_OPT_TYPE_BOOL, {.i64=0}, 0, 1, FLAGS|AV_OPT_FLAG_DEPRECATED},
++ {"psnr", "use feature='name=psnr'.", OFFSET(psnr), AV_OPT_TYPE_BOOL, {.i64=0}, 0, 1, FLAGS|AV_OPT_FLAG_DEPRECATED},
++ {"ssim", "use feature='name=ssim'.", OFFSET(ssim), AV_OPT_TYPE_BOOL, {.i64=0}, 0, 1, FLAGS|AV_OPT_FLAG_DEPRECATED},
++ {"ms_ssim", "use feature='name=ms_ssim'.", OFFSET(ms_ssim), AV_OPT_TYPE_BOOL, {.i64=0}, 0, 1, FLAGS|AV_OPT_FLAG_DEPRECATED},
+ {"pool", "Set the pool method to be used for computing vmaf.", OFFSET(pool), AV_OPT_TYPE_STRING, {.str=NULL}, 0, 1, FLAGS},
+ {"n_threads", "Set number of threads to be used when computing vmaf.", OFFSET(n_threads), AV_OPT_TYPE_INT, {.i64=0}, 0, UINT_MAX, FLAGS},
+ {"n_subsample", "Set interval for frame subsampling used when computing vmaf.", OFFSET(n_subsample), AV_OPT_TYPE_INT, {.i64=1}, 1, UINT_MAX, FLAGS},
+- {"enable_conf_interval", "Enables confidence interval.", OFFSET(enable_conf_interval), AV_OPT_TYPE_BOOL, {.i64=0}, 0, 1, FLAGS},
++ {"enable_conf_interval", "model='enable_conf_interval=true'.", OFFSET(enable_conf_interval), AV_OPT_TYPE_BOOL, {.i64=0}, 0, 1, FLAGS|AV_OPT_FLAG_DEPRECATED},
++ {"model", "Set the model to be used for computing vmaf.", OFFSET(model_cfg), AV_OPT_TYPE_STRING, {.str="version=vmaf_v0.6.1"}, 0, 1, FLAGS},
++ {"feature", "Set the feature to be used for computing vmaf.", OFFSET(feature_cfg), AV_OPT_TYPE_STRING, {.str=NULL}, 0, 1, FLAGS},
+ { NULL }
+ };
+
+ FRAMESYNC_DEFINE_CLASS(libvmaf, LIBVMAFContext, fs);
+
+-#define read_frame_fn(type, bits) \
+- static int read_frame_##bits##bit(float *ref_data, float *main_data, \
+- float *temp_data, int stride, void *ctx) \
+-{ \
+- LIBVMAFContext *s = (LIBVMAFContext *) ctx; \
+- int ret; \
+- \
+- pthread_mutex_lock(&s->lock); \
+- \
+- while (!s->frame_set && !s->eof) { \
+- pthread_cond_wait(&s->cond, &s->lock); \
+- } \
+- \
+- if (s->frame_set) { \
+- int ref_stride = s->gref->linesize[0]; \
+- int main_stride = s->gmain->linesize[0]; \
+- \
+- const type *ref_ptr = (const type *) s->gref->data[0]; \
+- const type *main_ptr = (const type *) s->gmain->data[0]; \
+- \
+- float *ptr = ref_data; \
+- float factor = 1.f / (1 << (bits - 8)); \
+- \
+- int h = s->height; \
+- int w = s->width; \
+- \
+- int i,j; \
+- \
+- for (i = 0; i < h; i++) { \
+- for ( j = 0; j < w; j++) { \
+- ptr[j] = ref_ptr[j] * factor; \
+- } \
+- ref_ptr += ref_stride / sizeof(*ref_ptr); \
+- ptr += stride / sizeof(*ptr); \
+- } \
+- \
+- ptr = main_data; \
+- \
+- for (i = 0; i < h; i++) { \
+- for (j = 0; j < w; j++) { \
+- ptr[j] = main_ptr[j] * factor; \
+- } \
+- main_ptr += main_stride / sizeof(*main_ptr); \
+- ptr += stride / sizeof(*ptr); \
+- } \
+- } \
+- \
+- ret = !s->frame_set; \
+- \
+- av_frame_unref(s->gref); \
+- av_frame_unref(s->gmain); \
+- s->frame_set = 0; \
+- \
+- pthread_cond_signal(&s->cond); \
+- pthread_mutex_unlock(&s->lock); \
+- \
+- if (ret) { \
+- return 2; \
+- } \
+- \
+- return 0; \
++static enum VmafPixelFormat pix_fmt_map(enum AVPixelFormat av_pix_fmt)
++{
++ switch (av_pix_fmt) {
++ case AV_PIX_FMT_YUV420P:
++ case AV_PIX_FMT_YUV420P10LE:
++ case AV_PIX_FMT_YUV420P12LE:
++ case AV_PIX_FMT_YUV420P16LE:
++ return VMAF_PIX_FMT_YUV420P;
++ case AV_PIX_FMT_YUV422P:
++ case AV_PIX_FMT_YUV422P10LE:
++ case AV_PIX_FMT_YUV422P12LE:
++ case AV_PIX_FMT_YUV422P16LE:
++ return VMAF_PIX_FMT_YUV422P;
++ case AV_PIX_FMT_YUV444P:
++ case AV_PIX_FMT_YUV444P10LE:
++ case AV_PIX_FMT_YUV444P12LE:
++ case AV_PIX_FMT_YUV444P16LE:
++ return VMAF_PIX_FMT_YUV444P;
++ default:
++ return VMAF_PIX_FMT_UNKNOWN;
++ }
+ }
+
+-read_frame_fn(uint8_t, 8);
+-read_frame_fn(uint16_t, 10);
++static int copy_picture_data(AVFrame *src, VmafPicture *dst, unsigned bpc)
++{
++ int err = vmaf_picture_alloc(dst, pix_fmt_map(src->format), bpc,
++ src->width, src->height);
++ if (err)
++ return AVERROR(ENOMEM);
+
+-static void compute_vmaf_score(LIBVMAFContext *s)
++ for (unsigned i = 0; i < 3; i++) {
++ uint8_t *src_data = src->data[i];
++ uint8_t *dst_data = dst->data[i];
++ for (unsigned j = 0; j < dst->h[i]; j++) {
++ memcpy(dst_data, src_data, sizeof(*dst_data) * dst->w[i]);
++ src_data += src->linesize[i];
++ dst_data += dst->stride[i];
++ }
++ }
++
++ return 0;
++}
++
++static int do_vmaf(FFFrameSync *fs)
+ {
+- int (*read_frame)(float *ref_data, float *main_data, float *temp_data,
+- int stride, void *ctx);
+- char *format;
++ AVFilterContext *ctx = fs->parent;
++ LIBVMAFContext *s = ctx->priv;
++ VmafPicture pic_ref, pic_dist;
++ AVFrame *ref, *dist;
++ int err = 0;
+
+- if (s->desc->comp[0].depth <= 8) {
+- read_frame = read_frame_8bit;
+- } else {
+- read_frame = read_frame_10bit;
++ int ret = ff_framesync_dualinput_get(fs, &dist, &ref);
++ if (ret < 0)
++ return ret;
++ if (ctx->is_disabled || !ref)
++ return ff_filter_frame(ctx->outputs[0], dist);
++
++ err = copy_picture_data(ref, &pic_ref, s->bpc);
++ if (err) {
++ av_log(s, AV_LOG_ERROR, "problem during vmaf_picture_alloc.\n");
++ return AVERROR(ENOMEM);
+ }
+
+- format = (char *) s->desc->name;
++ err = copy_picture_data(dist, &pic_dist, s->bpc);
++ if (err) {
++ av_log(s, AV_LOG_ERROR, "problem during vmaf_picture_alloc.\n");
++ vmaf_picture_unref(&pic_ref);
++ return AVERROR(ENOMEM);
++ }
+
+- s->error = compute_vmaf(&s->vmaf_score, format, s->width, s->height,
+- read_frame, s, s->model_path, s->log_path,
+- s->log_fmt, 0, 0, s->enable_transform,
+- s->phone_model, s->psnr, s->ssim,
+- s->ms_ssim, s->pool,
+- s->n_threads, s->n_subsample, s->enable_conf_interval);
++ err = vmaf_read_pictures(s->vmaf, &pic_ref, &pic_dist, s->frame_cnt++);
++ if (err) {
++ av_log(s, AV_LOG_ERROR, "problem during vmaf_read_pictures.\n");
++ return AVERROR(EINVAL);
++ }
++
++ return ff_filter_frame(ctx->outputs[0], dist);
+ }
+
+-static void *call_vmaf(void *ctx)
++
++static AVDictionary **delimited_dict_parse(char *str, unsigned *cnt)
+ {
+- LIBVMAFContext *s = (LIBVMAFContext *) ctx;
+- compute_vmaf_score(s);
+- if (!s->error) {
+- av_log(ctx, AV_LOG_INFO, "VMAF score: %f\n",s->vmaf_score);
+- } else {
+- pthread_mutex_lock(&s->lock);
+- pthread_cond_signal(&s->cond);
+- pthread_mutex_unlock(&s->lock);
++ AVDictionary **dict = NULL;
++ char *str_copy = NULL;
++ char *saveptr = NULL;
++ unsigned cnt2;
++ int err = 0;
++
++ if (!str)
++ return NULL;
++
++ cnt2 = 1;
++ for (char *p = str; *p; p++) {
++ if (*p == '|')
++ cnt2++;
+ }
+- pthread_exit(NULL);
++
++ dict = av_calloc(cnt2, sizeof(*dict));
++ if (!dict)
++ goto fail;
++
++ str_copy = av_strdup(str);
++ if (!str_copy)
++ goto fail;
++
++ *cnt = 0;
++ for (unsigned i = 0; i < cnt2; i++) {
++ char *s = av_strtok(i == 0 ? str_copy : NULL, "|", &saveptr);
++ if (!s)
++ continue;
++ err = av_dict_parse_string(&dict[(*cnt)++], s, "=", ":", 0);
++ if (err)
++ goto fail;
++ }
++
++ av_free(str_copy);
++ return dict;
++
++fail:
++ if (dict) {
++ for (unsigned i = 0; i < *cnt; i++) {
++ if (dict[i])
++ av_dict_free(&dict[i]);
++ }
++ av_free(dict);
++ }
++
++ av_free(str_copy);
++ *cnt = 0;
+ return NULL;
+ }
+
+-static int do_vmaf(FFFrameSync *fs)
++static int parse_features(AVFilterContext *ctx)
+ {
+- AVFilterContext *ctx = fs->parent;
+ LIBVMAFContext *s = ctx->priv;
+- AVFrame *master, *ref;
+- int ret;
++ AVDictionary **dict = NULL;
++ unsigned dict_cnt;
++ int err = 0;
+
+- ret = ff_framesync_dualinput_get(fs, &master, &ref);
+- if (ret < 0)
+- return ret;
+- if (!ref)
+- return ff_filter_frame(ctx->outputs[0], master);
++ if (!s->feature_cfg)
++ return 0;
+
+- pthread_mutex_lock(&s->lock);
++ dict = delimited_dict_parse(s->feature_cfg, &dict_cnt);
++ if (!dict) {
++ av_log(ctx, AV_LOG_ERROR,
++ "could not parse feature config: %s\n", s->feature_cfg);
++ return AVERROR(EINVAL);
++ }
+
+- while (s->frame_set && !s->error) {
+- pthread_cond_wait(&s->cond, &s->lock);
++ for (unsigned i = 0; i < dict_cnt; i++) {
++ char *feature_name = NULL;
++ VmafFeatureDictionary *feature_opts_dict = NULL;
++ AVDictionaryEntry *e = NULL;
++
++ while (e = av_dict_get(dict[i], "", e, AV_DICT_IGNORE_SUFFIX)) {
++ if (av_stristr(e->key, "name")) {
++ feature_name = e->value;
++ continue;
++ }
++
++ err = vmaf_feature_dictionary_set(&feature_opts_dict, e->key,
++ e->value);
++ if (err) {
++ av_log(ctx, AV_LOG_ERROR,
++ "could not set feature option: %s.%s=%s\n",
++ feature_name, e->key, e->value);
++ goto exit;
++ }
++ }
++
++ err = vmaf_use_feature(s->vmaf, feature_name, feature_opts_dict);
++ if (err) {
++ av_log(ctx, AV_LOG_ERROR,
++ "problem during vmaf_use_feature: %s\n", feature_name);
++ goto exit;
++ }
+ }
+
+- if (s->error) {
++exit:
++ for (unsigned i = 0; i < dict_cnt; i++) {
++ if (dict[i])
++ av_dict_free(&dict[i]);
++ }
++ av_free(dict);
++ return err;
++}
++
++static int parse_models(AVFilterContext *ctx)
++{
++ LIBVMAFContext *s = ctx->priv;
++ AVDictionary **dict;
++ unsigned dict_cnt;
++ int err = 0;
++
++ if (!s->model_cfg) return 0;
++
++ dict_cnt = 0;
++ dict = delimited_dict_parse(s->model_cfg, &dict_cnt);
++ if (!dict) {
+ av_log(ctx, AV_LOG_ERROR,
+- "libvmaf encountered an error, check log for details\n");
+- pthread_mutex_unlock(&s->lock);
++ "could not parse model config: %s\n", s->model_cfg);
+ return AVERROR(EINVAL);
+ }
+
+- av_frame_ref(s->gref, ref);
+- av_frame_ref(s->gmain, master);
++ s->model_cnt = dict_cnt;
++ s->model = av_calloc(s->model_cnt, sizeof(*s->model));
++ if (!s->model)
++ return AVERROR(ENOMEM);
+
+- s->frame_set = 1;
++ for (unsigned i = 0; i < dict_cnt; i++) {
++ VmafModelConfig model_cfg = { 0 };
++ AVDictionaryEntry *e = NULL;
++ char *version = NULL;
++ char *path = NULL;
+
+- pthread_cond_signal(&s->cond);
+- pthread_mutex_unlock(&s->lock);
++ while (e = av_dict_get(dict[i], "", e, AV_DICT_IGNORE_SUFFIX)) {
++ if (av_stristr(e->key, "disable_clip")) {
++ model_cfg.flags |= av_stristr(e->value, "true") ?
++ VMAF_MODEL_FLAG_DISABLE_CLIP : 0;
++ continue;
++ }
+
+- return ff_filter_frame(ctx->outputs[0], master);
++ if (av_stristr(e->key, "enable_transform")) {
++ model_cfg.flags |= av_stristr(e->value, "true") ?
++ VMAF_MODEL_FLAG_ENABLE_TRANSFORM : 0;
++ continue;
++ }
++
++ if (av_stristr(e->key, "name")) {
++ model_cfg.name = e->value;
++ continue;
++ }
++
++ if (av_stristr(e->key, "version")) {
++ version = e->value;
++ continue;
++ }
++
++ if (av_stristr(e->key, "path")) {
++ path = e->value;
++ continue;
++ }
++ }
++
++ if (version) {
++ err = vmaf_model_load(&s->model[i], &model_cfg, version);
++ if (err) {
++ av_log(ctx, AV_LOG_ERROR,
++ "could not load libvmaf model with version: %s\n",
++ version);
++ goto exit;
++ }
++ }
++
++ if (path && !s->model[i]) {
++ err = vmaf_model_load_from_path(&s->model[i], &model_cfg, path);
++ if (err) {
++ av_log(ctx, AV_LOG_ERROR,
++ "could not load libvmaf model with path: %s\n",
++ path);
++ goto exit;
++ }
++ }
++
++ if (!s->model[i]) {
++ av_log(ctx, AV_LOG_ERROR,
++ "could not load libvmaf model with config: %s\n",
++ s->model_cfg);
++ goto exit;
++ }
++
++ while (e = av_dict_get(dict[i], "", e, AV_DICT_IGNORE_SUFFIX)) {
++ VmafFeatureDictionary *feature_opts_dict = NULL;
++ char *feature_opt = NULL;
++
++ char *feature_name = av_strtok(e->key, ".", &feature_opt);
++ if (!feature_opt)
++ continue;
++
++ err = vmaf_feature_dictionary_set(&feature_opts_dict,
++ feature_opt, e->value);
++ if (err) {
++ av_log(ctx, AV_LOG_ERROR,
++ "could not set feature option: %s.%s=%s\n",
++ feature_name, feature_opt, e->value);
++ err = AVERROR(EINVAL);
++ goto exit;
++ }
++
++ err = vmaf_model_feature_overload(s->model[i], feature_name,
++ feature_opts_dict);
++ if (err) {
++ av_log(ctx, AV_LOG_ERROR,
++ "could not overload feature: %s\n", feature_name);
++ err = AVERROR(EINVAL);
++ goto exit;
++ }
++ }
++ }
++
++ for (unsigned i = 0; i < s->model_cnt; i++) {
++ err = vmaf_use_features_from_model(s->vmaf, s->model[i]);
++ if (err) {
++ av_log(ctx, AV_LOG_ERROR,
++ "problem during vmaf_use_features_from_model\n");
++ err = AVERROR(EINVAL);
++ goto exit;
++ }
++ }
++
++exit:
++ for (unsigned i = 0; i < dict_cnt; i++) {
++ if (dict[i])
++ av_dict_free(&dict[i]);
++ }
++ av_free(dict);
++ return err;
+ }
+
++static enum VmafLogLevel log_level_map(int log_level)
++{
++ switch (log_level) {
++ case AV_LOG_QUIET:
++ return VMAF_LOG_LEVEL_NONE;
++ case AV_LOG_ERROR:
++ return VMAF_LOG_LEVEL_ERROR;
++ case AV_LOG_WARNING:
++ return VMAF_LOG_LEVEL_WARNING;
++ case AV_LOG_INFO:
++ return VMAF_LOG_LEVEL_INFO;
++ case AV_LOG_DEBUG:
++ return VMAF_LOG_LEVEL_DEBUG;
++ default:
++ return VMAF_LOG_LEVEL_INFO;
++ }
++}
++
++static int parse_deprecated_options(AVFilterContext *ctx)
++{
++ LIBVMAFContext *s = ctx->priv;
++ VmafModel *model = NULL;
++ VmafModelCollection *model_collection = NULL;
++ enum VmafModelFlags flags = VMAF_MODEL_FLAGS_DEFAULT;
++ int err = 0;
++
++ VmafModelConfig model_cfg = {
++ .name = "vmaf",
++ .flags = flags,
++ };
++
++ if (s->enable_transform || s->phone_model)
++ flags |= VMAF_MODEL_FLAG_ENABLE_TRANSFORM;
++
++ if (!s->model_path)
++ goto extra_metrics_only;
++
++ if (s->enable_conf_interval) {
++ err = vmaf_model_collection_load_from_path(&model, &model_collection,
++ &model_cfg, s->model_path);
++ if (err) {
++ av_log(ctx, AV_LOG_ERROR,
++ "problem loading model file: %s\n", s->model_path);
++ goto exit;
++ }
++
++ err = vmaf_use_features_from_model_collection(s->vmaf, model_collection);
++ if (err) {
++ av_log(ctx, AV_LOG_ERROR,
++ "problem loading feature extractors from model file: %s\n",
++ s->model_path);
++ goto exit;
++ }
++ } else {
++ err = vmaf_model_load_from_path(&model, &model_cfg, s->model_path);
++ if (err) {
++ av_log(ctx, AV_LOG_ERROR,
++ "problem loading model file: %s\n", s->model_path);
++ goto exit;
++ }
++ err = vmaf_use_features_from_model(s->vmaf, model);
++ if (err) {
++ av_log(ctx, AV_LOG_ERROR,
++ "problem loading feature extractors from model file: %s\n",
++ s->model_path);
++ goto exit;
++ }
++ }
++
++extra_metrics_only:
++ if (s->psnr) {
++ VmafFeatureDictionary *d = NULL;
++ vmaf_feature_dictionary_set(&d, "enable_chroma", "false");
++
++ err = vmaf_use_feature(s->vmaf, "psnr", d);
++ if (err) {
++ av_log(ctx, AV_LOG_ERROR,
++ "problem loading feature extractor: psnr\n");
++ goto exit;
++ }
++ }
++
++ if (s->ssim) {
++ err = vmaf_use_feature(s->vmaf, "float_ssim", NULL);
++ if (err) {
++ av_log(ctx, AV_LOG_ERROR,
++ "problem loading feature extractor: ssim\n");
++ goto exit;
++ }
++ }
++
++ if (s->ms_ssim) {
++ err = vmaf_use_feature(s->vmaf, "float_ms_ssim", NULL);
++ if (err) {
++ av_log(ctx, AV_LOG_ERROR,
++ "problem loading feature extractor: ms_ssim\n");
++ goto exit;
++ }
++ }
++
++exit:
++ return err;
++}
++
+ static av_cold int init(AVFilterContext *ctx)
+ {
+ LIBVMAFContext *s = ctx->priv;
++ int err = 0;
+
+- s->gref = av_frame_alloc();
+- s->gmain = av_frame_alloc();
+- if (!s->gref || !s->gmain)
+- return AVERROR(ENOMEM);
++ VmafConfiguration cfg = {
++ .log_level = log_level_map(av_log_get_level()),
++ .n_subsample = s->n_subsample,
++ .n_threads = s->n_threads,
++ };
+
+- s->error = 0;
++ err = vmaf_init(&s->vmaf, cfg);
++ if (err)
++ return AVERROR(EINVAL);
+
+- s->vmaf_thread_created = 0;
+- pthread_mutex_init(&s->lock, NULL);
+- pthread_cond_init (&s->cond, NULL);
++ err = parse_deprecated_options(ctx);
++ if (err)
++ return err;
+
++ err = parse_models(ctx);
++ if (err)
++ return err;
++
++ err = parse_features(ctx);
++ if (err)
++ return err;
++
+ s->fs.on_event = do_vmaf;
+ return 0;
+ }
+@@ -265,31 +554,36 @@ static int config_input_ref(AVFilterLink *inlink)
+
+ static int config_input_ref(AVFilterLink *inlink)
+ {
+- AVFilterContext *ctx = inlink->dst;
++ AVFilterContext *ctx = inlink->dst;
+ LIBVMAFContext *s = ctx->priv;
+- int th;
++ const AVPixFmtDescriptor *desc;
++ int err = 0;
+
+- if (ctx->inputs[0]->w != ctx->inputs[1]->w ||
+- ctx->inputs[0]->h != ctx->inputs[1]->h) {
+- av_log(ctx, AV_LOG_ERROR, "Width and height of input videos must be same.\n");
+- return AVERROR(EINVAL);
++ if (ctx->inputs[0]->w != ctx->inputs[1]->w) {
++ av_log(ctx, AV_LOG_ERROR, "input width must match.\n");
++ err |= AVERROR(EINVAL);
+ }
+ if (ctx->inputs[0]->format != ctx->inputs[1]->format) {
+ av_log(ctx, AV_LOG_ERROR, "Inputs must be of same pixel format.\n");
+ return AVERROR(EINVAL);
+ }
+
+- s->desc = av_pix_fmt_desc_get(inlink->format);
+- s->width = ctx->inputs[0]->w;
+- s->height = ctx->inputs[0]->h;
++ if (ctx->inputs[0]->h != ctx->inputs[1]->h) {
++ av_log(ctx, AV_LOG_ERROR, "input height must match.\n");
++ err |= AVERROR(EINVAL);
++ }
+
+- th = pthread_create(&s->vmaf_thread, NULL, call_vmaf, (void *) s);
+- if (th) {
+- av_log(ctx, AV_LOG_ERROR, "Thread creation failed.\n");
+- return AVERROR(EINVAL);
++ if (ctx->inputs[0]->format != ctx->inputs[1]->format) {
++ av_log(ctx, AV_LOG_ERROR, "input pix_fmt must match.\n");
++ err |= AVERROR(EINVAL);
+ }
+- s->vmaf_thread_created = 1;
+
++ if (err)
++ return err;
++
++ desc = av_pix_fmt_desc_get(inlink->format);
++ s->bpc = desc->comp[0].depth;
++
+ return 0;
+ }
+
+@@ -320,28 +614,80 @@ static int activate(AVFilterContext *ctx)
+ return ff_framesync_activate(&s->fs);
+ }
+
++static enum VmafOutputFormat log_fmt_map(const char *log_fmt)
++{
++ if (log_fmt) {
++ if (av_stristr(log_fmt, "xml"))
++ return VMAF_OUTPUT_FORMAT_XML;
++ if (av_stristr(log_fmt, "json"))
++ return VMAF_OUTPUT_FORMAT_JSON;
++ if (av_stristr(log_fmt, "csv"))
++ return VMAF_OUTPUT_FORMAT_CSV;
++ if (av_stristr(log_fmt, "sub"))
++ return VMAF_OUTPUT_FORMAT_SUB;
++ }
++
++ return VMAF_OUTPUT_FORMAT_XML;
++}
++
++static enum VmafPoolingMethod pool_method_map(const char *pool_method)
++{
++ if (pool_method) {
++ if (av_stristr(pool_method, "min"))
++ return VMAF_POOL_METHOD_MIN;
++ if (av_stristr(pool_method, "mean"))
++ return VMAF_POOL_METHOD_MEAN;
++ if (av_stristr(pool_method, "harmonic_mean"))
++ return VMAF_POOL_METHOD_HARMONIC_MEAN;
++ }
++
++ return VMAF_POOL_METHOD_MEAN;
++}
++
+ static av_cold void uninit(AVFilterContext *ctx)
+ {
+ LIBVMAFContext *s = ctx->priv;
++ int err = 0;
+
+ ff_framesync_uninit(&s->fs);
+
+- pthread_mutex_lock(&s->lock);
+- s->eof = 1;
+- pthread_cond_signal(&s->cond);
+- pthread_mutex_unlock(&s->lock);
++ if (!s->frame_cnt)
++ goto clean_up;
+
+- if (s->vmaf_thread_created)
+- {
+- pthread_join(s->vmaf_thread, NULL);
+- s->vmaf_thread_created = 0;
++ err = vmaf_read_pictures(s->vmaf, NULL, NULL, 0);
++ if (err) {
++ av_log(ctx, AV_LOG_ERROR,
++ "problem flushing libvmaf context.\n");
+ }
+
+- av_frame_free(&s->gref);
+- av_frame_free(&s->gmain);
++ for (unsigned i = 0; i < s->model_cnt; i++) {
++ double vmaf_score;
++ err = vmaf_score_pooled(s->vmaf, s->model[i], pool_method_map(s->pool),
++ &vmaf_score, 0, s->frame_cnt - 1);
++ if (err) {
++ av_log(ctx, AV_LOG_ERROR,
++ "problem getting pooled vmaf score.\n");
++ }
+
+- pthread_mutex_destroy(&s->lock);
+- pthread_cond_destroy(&s->cond);
++ av_log(ctx, AV_LOG_INFO, "VMAF score: %f\n", vmaf_score);
++ }
++
++ if (s->vmaf) {
++ if (s->log_path && !err)
++ vmaf_write_output(s->vmaf, s->log_path, log_fmt_map(s->log_fmt));
++ }
++
++clean_up:
++ if (s->model) {
++ for (unsigned i = 0; i < s->model_cnt; i++) {
++ if (s->model[i])
++ vmaf_model_destroy(s->model[i]);
++ }
++ av_free(s->model);
++ }
++
++ if (s->vmaf)
++ vmaf_close(s->vmaf);
+ }
+
+ static const AVFilterPad libvmaf_inputs[] = {
diff --git a/multimedia/ffmpeg4/override.mk b/multimedia/ffmpeg4/override.mk
new file mode 100644
index 000000000000..1c7df87e262a
--- /dev/null
+++ b/multimedia/ffmpeg4/override.mk
@@ -0,0 +1,8 @@
+FF_SUFFIX= 4
+
+BUILD_DEPENDS:= ${BUILD_DEPENDS:S/ffmpeg/&${FF_SUFFIX}/g}
+LIB_DEPENDS:= ${LIB_DEPENDS:S/ffmpeg$/&${FF_SUFFIX}/}
+
+USES+= localbase # -isystem
+CONFIGURE_ENV+= PKG_CONFIG_PATH="${LOCALBASE}/ffmpeg${FF_SUFFIX}/libdata/pkgconfig"
+MAKE_ENV+= PKG_CONFIG_PATH="${LOCALBASE}/ffmpeg${FF_SUFFIX}/libdata/pkgconfig"
diff --git a/multimedia/ffmpeg4/pkg-descr b/multimedia/ffmpeg4/pkg-descr
new file mode 100644
index 000000000000..c3e23a3fdc4e
--- /dev/null
+++ b/multimedia/ffmpeg4/pkg-descr
@@ -0,0 +1,3 @@
+FFmpeg is a complete, cross-platform solution to record, convert and stream
+audio and video. It includes libavcodec - the leading audio/video codec
+library.
diff --git a/multimedia/ffmpeg4/pkg-plist b/multimedia/ffmpeg4/pkg-plist
new file mode 100644
index 000000000000..6f5f8c0b8db6
--- /dev/null
+++ b/multimedia/ffmpeg4/pkg-plist
@@ -0,0 +1,220 @@
+bin/ffmpeg
+%%SDL%%bin/ffplay
+bin/ffprobe
+include/libavcodec/ac3_parser.h
+include/libavcodec/adts_parser.h
+include/libavcodec/avcodec.h
+include/libavcodec/avdct.h
+include/libavcodec/avfft.h
+include/libavcodec/bsf.h
+include/libavcodec/codec.h
+include/libavcodec/codec_desc.h
+include/libavcodec/codec_id.h
+include/libavcodec/codec_par.h
+include/libavcodec/d3d11va.h
+include/libavcodec/dirac.h
+include/libavcodec/dv_profile.h
+include/libavcodec/dxva2.h
+include/libavcodec/jni.h
+include/libavcodec/mediacodec.h
+include/libavcodec/packet.h
+include/libavcodec/qsv.h
+include/libavcodec/vaapi.h
+include/libavcodec/vdpau.h
+include/libavcodec/version.h
+include/libavcodec/videotoolbox.h
+include/libavcodec/vorbis_parser.h
+include/libavcodec/xvmc.h
+include/libavdevice/avdevice.h
+include/libavdevice/version.h
+include/libavfilter/avfilter.h
+include/libavfilter/buffersink.h
+include/libavfilter/buffersrc.h
+include/libavfilter/version.h
+include/libavformat/avformat.h
+include/libavformat/avio.h
+include/libavformat/version.h
+include/libavresample/avresample.h
+include/libavresample/version.h
+include/libavutil/adler32.h
+include/libavutil/aes.h
+include/libavutil/aes_ctr.h
+include/libavutil/attributes.h
+include/libavutil/audio_fifo.h
+include/libavutil/avassert.h
+include/libavutil/avconfig.h
+include/libavutil/avstring.h
+include/libavutil/avutil.h
+include/libavutil/base64.h
+include/libavutil/blowfish.h
+include/libavutil/bprint.h
+include/libavutil/bswap.h
+include/libavutil/buffer.h
+include/libavutil/camellia.h
+include/libavutil/cast5.h
+include/libavutil/channel_layout.h
+include/libavutil/common.h
+include/libavutil/cpu.h
+include/libavutil/crc.h
+include/libavutil/des.h
+include/libavutil/dict.h
+include/libavutil/display.h
+include/libavutil/dovi_meta.h
+include/libavutil/downmix_info.h
+include/libavutil/encryption_info.h
+include/libavutil/error.h
+include/libavutil/eval.h
+include/libavutil/ffversion.h
+include/libavutil/fifo.h
+include/libavutil/file.h
+include/libavutil/film_grain_params.h
+include/libavutil/frame.h
+include/libavutil/hash.h
+include/libavutil/hdr_dynamic_metadata.h
+include/libavutil/hmac.h
+include/libavutil/hwcontext.h
+include/libavutil/hwcontext_cuda.h
+include/libavutil/hwcontext_d3d11va.h
+include/libavutil/hwcontext_drm.h
+include/libavutil/hwcontext_dxva2.h
+include/libavutil/hwcontext_mediacodec.h
+include/libavutil/hwcontext_opencl.h
+include/libavutil/hwcontext_qsv.h
+include/libavutil/hwcontext_vaapi.h
+include/libavutil/hwcontext_vdpau.h
+include/libavutil/hwcontext_videotoolbox.h
+include/libavutil/hwcontext_vulkan.h
+include/libavutil/imgutils.h
+include/libavutil/intfloat.h
+include/libavutil/intreadwrite.h
+include/libavutil/lfg.h
+include/libavutil/log.h
+include/libavutil/lzo.h
+include/libavutil/macros.h
+include/libavutil/mastering_display_metadata.h
+include/libavutil/mathematics.h
+include/libavutil/md5.h
+include/libavutil/mem.h
+include/libavutil/motion_vector.h
+include/libavutil/murmur3.h
+include/libavutil/opt.h
+include/libavutil/parseutils.h
+include/libavutil/pixdesc.h
+include/libavutil/pixelutils.h
+include/libavutil/pixfmt.h
+include/libavutil/random_seed.h
+include/libavutil/rational.h
+include/libavutil/rc4.h
+include/libavutil/replaygain.h
+include/libavutil/ripemd.h
+include/libavutil/samplefmt.h
+include/libavutil/sha.h
+include/libavutil/sha512.h
+include/libavutil/spherical.h
+include/libavutil/stereo3d.h
+include/libavutil/tea.h
+include/libavutil/threadmessage.h
+include/libavutil/time.h
+include/libavutil/timecode.h
+include/libavutil/timestamp.h
+include/libavutil/tree.h
+include/libavutil/twofish.h
+include/libavutil/tx.h
+include/libavutil/version.h
+include/libavutil/video_enc_params.h
+include/libavutil/xtea.h
+include/libpostproc/postprocess.h
+include/libpostproc/version.h
+include/libswresample/swresample.h
+include/libswresample/version.h
+include/libswscale/swscale.h
+include/libswscale/version.h
+lib/libavcodec.so
+lib/libavcodec.so.58
+lib/libavcodec.so.58.134.100
+lib/libavdevice.so
+lib/libavdevice.so.58
+lib/libavdevice.so.58.13.100
+lib/libavfilter.so
+lib/libavfilter.so.7
+lib/libavfilter.so.7.110.100
+lib/libavformat.so
+lib/libavformat.so.58
+lib/libavformat.so.58.76.100
+lib/libavresample.so
+lib/libavresample.so.4
+lib/libavresample.so.4.0.0
+lib/libavutil.so
+lib/libavutil.so.56
+lib/libavutil.so.56.70.100
+lib/libpostproc.so
+lib/libpostproc.so.55
+lib/libpostproc.so.55.9.100
+lib/libswresample.so
+lib/libswresample.so.3
+lib/libswresample.so.3.9.100
+lib/libswscale.so
+lib/libswscale.so.5
+lib/libswscale.so.5.9.100
+libdata/pkgconfig/libavcodec.pc
+libdata/pkgconfig/libavdevice.pc
+libdata/pkgconfig/libavfilter.pc
+libdata/pkgconfig/libavformat.pc
+libdata/pkgconfig/libavresample.pc
+libdata/pkgconfig/libavutil.pc
+libdata/pkgconfig/libpostproc.pc
+libdata/pkgconfig/libswresample.pc
+libdata/pkgconfig/libswscale.pc
+man/man1/ffmpeg-all.1.gz
+man/man1/ffmpeg-bitstream-filters.1.gz
+man/man1/ffmpeg-codecs.1.gz
+man/man1/ffmpeg-devices.1.gz
+man/man1/ffmpeg-filters.1.gz
+man/man1/ffmpeg-formats.1.gz
+man/man1/ffmpeg-protocols.1.gz
+man/man1/ffmpeg-resampler.1.gz
+man/man1/ffmpeg-scaler.1.gz
+man/man1/ffmpeg-utils.1.gz
+man/man1/ffmpeg.1.gz
+%%SDL%%man/man1/ffplay-all.1.gz
+%%SDL%%man/man1/ffplay.1.gz
+man/man1/ffprobe-all.1.gz
+man/man1/ffprobe.1.gz
+man/man3/libavcodec.3.gz
+man/man3/libavdevice.3.gz
+man/man3/libavfilter.3.gz
+man/man3/libavformat.3.gz
+man/man3/libavutil.3.gz
+man/man3/libswresample.3.gz
+man/man3/libswscale.3.gz
+%%DATADIR%%/examples/Makefile
+%%DATADIR%%/examples/README
+%%DATADIR%%/examples/avio_list_dir.c
+%%DATADIR%%/examples/avio_reading.c
+%%DATADIR%%/examples/decode_audio.c
+%%DATADIR%%/examples/decode_video.c
+%%DATADIR%%/examples/demuxing_decoding.c
+%%DATADIR%%/examples/encode_audio.c
+%%DATADIR%%/examples/encode_video.c
+%%DATADIR%%/examples/extract_mvs.c
+%%DATADIR%%/examples/filter_audio.c
+%%DATADIR%%/examples/filtering_audio.c
+%%DATADIR%%/examples/filtering_video.c
+%%DATADIR%%/examples/http_multiclient.c
+%%DATADIR%%/examples/hw_decode.c
+%%DATADIR%%/examples/metadata.c
+%%DATADIR%%/examples/muxing.c
+%%DATADIR%%/examples/qsvdec.c
+%%DATADIR%%/examples/remuxing.c
+%%DATADIR%%/examples/resampling_audio.c
+%%DATADIR%%/examples/scaling_video.c
+%%DATADIR%%/examples/transcode_aac.c
+%%DATADIR%%/examples/transcoding.c
+%%DATADIR%%/examples/vaapi_encode.c
+%%DATADIR%%/examples/vaapi_transcode.c
+%%DATADIR%%/ffprobe.xsd
+%%DATADIR%%/libvpx-1080p.ffpreset
+%%DATADIR%%/libvpx-1080p50_60.ffpreset
+%%DATADIR%%/libvpx-360p.ffpreset
+%%DATADIR%%/libvpx-720p.ffpreset
+%%DATADIR%%/libvpx-720p50_60.ffpreset