summarylogtreecommitdiffstats
diff options
context:
space:
mode:
authorArley Henostroza2019-12-09 14:54:08 -0500
committerArley Henostroza2019-12-09 14:54:08 -0500
commit0014f5d3263c7021fd5527f1c0708c133452bea9 (patch)
tree36d90a7cb947228733db1ec22664b76284370b17
downloadaur-0014f5d3263c7021fd5527f1c0708c133452bea9.tar.gz
init commit
-rw-r--r--.SRCINFO142
-rw-r--r--LICENSE9
-rw-r--r--PKGBUILD218
-rw-r--r--ffmpeg-full-git-add-svt-av1-0.6.0.patch569
-rw-r--r--ffmpeg-full-git-add-svt-hevc-1.4.1.patch601
-rw-r--r--ffmpeg-full-git-add-svt-hevc-docs-1.4.1.patch198
-rw-r--r--ffmpeg-full-git-add-svt-vp9-gce24589.patch624
7 files changed, 2361 insertions, 0 deletions
diff --git a/.SRCINFO b/.SRCINFO
new file mode 100644
index 000000000000..51d8faa79a1a
--- /dev/null
+++ b/.SRCINFO
@@ -0,0 +1,142 @@
+pkgbase = ffmpeg-full-git
+ pkgdesc = Complete solution to record, convert and stream audio and video (all possible features including nvenc, qsv and libfdk-aac; git version)
+ pkgver = 4.3.r95713.g0e49560806
+ pkgrel = 1
+ url = https://www.ffmpeg.org/
+ arch = x86_64
+ license = custom: nonfree and unredistributable
+ makedepends = git
+ makedepends = nasm
+ makedepends = vmaf
+ makedepends = opencl-headers
+ makedepends = ffnvcodec-headers
+ makedepends = blackmagic-decklink-sdk
+ makedepends = amf-headers-git
+ depends = glibc
+ depends = alsa-lib
+ depends = jack
+ depends = libpng
+ depends = bzip2
+ depends = frei0r-plugins
+ depends = libgcrypt
+ depends = gmp
+ depends = gnutls
+ depends = ladspa
+ depends = libass
+ depends = aom
+ depends = aribb24
+ depends = libbluray
+ depends = libbs2b
+ depends = libcaca
+ depends = celt
+ depends = libcdio-paranoia
+ depends = codec2
+ depends = dav1d
+ depends = libdc1394
+ depends = libavc1394
+ depends = libfdk-aac
+ depends = fontconfig
+ depends = freetype2
+ depends = fribidi
+ depends = libgme
+ depends = gsm
+ depends = libilbc
+ depends = libiec61883
+ depends = kvazaar
+ depends = lensfun
+ depends = libmodplug
+ depends = lame
+ depends = opencore-amr
+ depends = openjpeg2
+ depends = opus
+ depends = pulseaudio
+ depends = librsvg
+ depends = rubberband
+ depends = rtmpdump
+ depends = snappy
+ depends = libsoxr
+ depends = speex
+ depends = srt
+ depends = libssh
+ depends = tensorflow
+ depends = tesseract
+ depends = libtheora
+ depends = twolame
+ depends = v4l-utils
+ depends = vid.stab
+ depends = libvorbis
+ depends = libvpx
+ depends = wavpack
+ depends = libwebp
+ depends = libx264.so
+ depends = x265
+ depends = libxcb
+ depends = xvidcore
+ depends = libxml2
+ depends = zimg
+ depends = zeromq
+ depends = zvbi
+ depends = lv2
+ depends = lilv
+ depends = xz
+ depends = libmysofa
+ depends = openal
+ depends = ocl-icd
+ depends = libgl
+ depends = sndio
+ depends = sdl2
+ depends = vapoursynth
+ depends = libxv
+ depends = libx11
+ depends = libxext
+ depends = zlib
+ depends = cuda
+ depends = libomxil-bellagio
+ depends = libdrm
+ depends = intel-media-sdk
+ depends = libva
+ depends = libvdpau
+ depends = svt-hevc
+ depends = svt-av1
+ depends = chromaprint-fftw
+ depends = davs2
+ depends = flite1-patched
+ depends = libklvanc-git
+ depends = openh264
+ depends = libopenmpt-svn
+ depends = rav1e
+ depends = shine
+ depends = vo-amrwbenc
+ depends = xavs
+ depends = xavs2
+ depends = pocketsphinx
+ depends = rockchip-mpp
+ depends = svt-vp9-git
+ provides = libavcodec.so
+ provides = libavdevice.so
+ provides = libavfilter.so
+ provides = libavformat.so
+ provides = libavutil.so
+ provides = libpostproc.so
+ provides = libavresample.so
+ provides = libswscale.so
+ provides = libswresample.so
+ provides = ffmpeg
+ provides = ffmpeg-full
+ provides = ffmpeg-git
+ conflicts = ffmpeg
+ source = git+https://git.ffmpeg.org/ffmpeg.git
+ source = ffmpeg-full-git-add-svt-hevc-1.4.1.patch::https://raw.githubusercontent.com/OpenVisualCloud/SVT-HEVC/v1.4.1/ffmpeg_plugin/0001-lavc-svt_hevc-add-libsvt-hevc-encoder-wrapper.patch
+ source = ffmpeg-full-git-add-svt-hevc-docs-1.4.1.patch::https://raw.githubusercontent.com/OpenVisualCloud/SVT-HEVC/v1.4.1/ffmpeg_plugin/0002-doc-Add-libsvt_hevc-encoder-docs.patch
+ source = ffmpeg-full-git-add-svt-av1-0.6.0.patch::https://raw.githubusercontent.com/OpenVisualCloud/SVT-AV1/v0.6.0/ffmpeg_plugin/0001-Add-ability-for-ffmpeg-to-run-svt-av1-with-svt-hevc.patch
+ source = ffmpeg-full-git-add-svt-vp9-gce24589.patch::https://raw.githubusercontent.com/OpenVisualCloud/SVT-VP9/ce245894c6fc1c5d1439c41a7dda8d6dc61784c4/ffmpeg_plugin/0001-Add-ability-for-ffmpeg-to-run-svt-vp9-with-svt-hevc-av1.patch
+ source = LICENSE
+ sha256sums = SKIP
+ sha256sums = d2db0acbdb0773f3883746cd25996905ff0a3f539d9b434fe314f883856ad883
+ sha256sums = 1499e419dda72b1604dc5e3959668f3843292ff56bfba78734e31510ba576de0
+ sha256sums = 102a70c5c453875f5806ce02cc83fdc74e53c078cf5be2657f3dd1dd4438868c
+ sha256sums = 7690a4f6bdc4a57e35c7ff5b6e87f2fe6d056d452eff9e767eaccff41832f4d7
+ sha256sums = 04a7176400907fd7db0d69116b99de49e582a6e176b3bfb36a03e50a4cb26a36
+
+pkgname = ffmpeg-full-git
+
diff --git a/LICENSE b/LICENSE
new file mode 100644
index 000000000000..b0bb658ca78c
--- /dev/null
+++ b/LICENSE
@@ -0,0 +1,9 @@
+This software is nonfree and unredistributable.
+
+The end-user must compile this software for himself in order to be allowed to use it.
+
+This software cannot be redistributed.
+
+This software cannot be used commercially.
+
+Due to the libraries used to compile this software, the resulting binaries and libraries are under a complex and restrictive license mix.
diff --git a/PKGBUILD b/PKGBUILD
new file mode 100644
index 000000000000..33261ac9b474
--- /dev/null
+++ b/PKGBUILD
@@ -0,0 +1,218 @@
+# Maintainer: Arley Henostroza < arllk at gmail dot com >
+# Contributor: Daniel Bermond < gmail-com: danielbermond >
+
+_svt_hevc_ver='1.4.1'
+_svt_av1_ver='0.6.0'
+_svt_vp9_ver='ce245894c6fc1c5d1439c41a7dda8d6dc61784c4'
+
+pkgname=ffmpeg-intel-full-git
+pkgver=4.3.r95997.g9f7b2b37e3
+pkgrel=1
+pkgdesc='Complete solution to record, convert and stream audio and video (all possible features for intel; git version)'
+arch=('x86_64')
+url='https://www.ffmpeg.org/'
+license=('custom: nonfree and unredistributable')
+depends=(
+ # official repositories:
+ 'glibc' 'alsa-lib' 'jack' 'libpng'
+ 'bzip2' 'frei0r-plugins' 'libgcrypt' 'gmp' 'gnutls' 'ladspa' 'libass' 'aom'
+ 'aribb24' 'libbluray' 'libbs2b' 'libcaca' 'celt' 'libcdio-paranoia' 'codec2'
+ 'dav1d' 'libdc1394' 'libavc1394' 'libfdk-aac' 'fontconfig' 'freetype2' 'fribidi'
+ 'libgme' 'gsm' 'libilbc' 'libiec61883' 'kvazaar' 'lensfun' 'libmodplug' 'lame'
+ 'opencore-amr' 'openjpeg2' 'opus' 'pulseaudio' 'librsvg' 'rubberband' 'rtmpdump'
+ 'snappy' 'libsoxr' 'speex' 'srt' 'libssh' 'tensorflow' 'tesseract' 'libtheora'
+ 'twolame' 'v4l-utils' 'vid.stab' 'libvorbis' 'libvpx' 'wavpack' 'libwebp'
+ 'libx264.so' 'x265' 'libxcb' 'xvidcore' 'libxml2' 'zimg' 'zeromq' 'zvbi' 'lv2'
+ 'lilv' 'xz' 'libmysofa' 'openal' 'ocl-icd' 'libgl' 'sndio' 'sdl2' 'vapoursynth'
+ 'libxv' 'libx11' 'libxext' 'zlib' 'libomxil-bellagio' 'libdrm'
+ 'intel-media-sdk' 'libva' 'libvdpau' 'svt-hevc' 'svt-av1'
+ # AUR:
+ 'chromaprint-fftw' 'davs2' 'flite1-patched' 'libklvanc-git' 'openh264'
+ 'libopenmpt-svn' 'rav1e' 'shine' 'vo-amrwbenc' 'xavs' 'xavs2' 'pocketsphinx'
+ 'svt-vp9-git'
+)
+makedepends=(
+ # official repositories:
+ 'git' 'nasm' 'vmaf' 'opencl-headers'
+ # AUR:
+ 'blackmagic-decklink-sdk'
+)
+provides=('libavcodec.so' 'libavdevice.so' 'libavfilter.so' 'libavformat.so'
+ 'libavutil.so' 'libpostproc.so' 'libavresample.so' 'libswscale.so'
+ 'libswresample.so' 'ffmpeg' 'ffmpeg-full' 'ffmpeg-git' 'ffmpeg-intel')
+conflicts=('ffmpeg')
+source=('git+https://git.ffmpeg.org/ffmpeg.git'
+ "ffmpeg-full-git-add-svt-hevc-${_svt_hevc_ver}.patch"::"https://raw.githubusercontent.com/OpenVisualCloud/SVT-HEVC/v${_svt_hevc_ver}/ffmpeg_plugin/0001-lavc-svt_hevc-add-libsvt-hevc-encoder-wrapper.patch"
+ "ffmpeg-full-git-add-svt-hevc-docs-${_svt_hevc_ver}.patch"::"https://raw.githubusercontent.com/OpenVisualCloud/SVT-HEVC/v${_svt_hevc_ver}/ffmpeg_plugin/0002-doc-Add-libsvt_hevc-encoder-docs.patch"
+ "ffmpeg-full-git-add-svt-av1-${_svt_av1_ver}.patch"::"https://raw.githubusercontent.com/OpenVisualCloud/SVT-AV1/v${_svt_av1_ver}/ffmpeg_plugin/0001-Add-ability-for-ffmpeg-to-run-svt-av1-with-svt-hevc.patch"
+ "ffmpeg-full-git-add-svt-vp9-g${_svt_vp9_ver:0:7}.patch"::"https://raw.githubusercontent.com/OpenVisualCloud/SVT-VP9/${_svt_vp9_ver}/ffmpeg_plugin/0001-Add-ability-for-ffmpeg-to-run-svt-vp9-with-svt-hevc-av1.patch"
+ 'LICENSE')
+sha256sums=('SKIP'
+ 'd2db0acbdb0773f3883746cd25996905ff0a3f539d9b434fe314f883856ad883'
+ '1499e419dda72b1604dc5e3959668f3843292ff56bfba78734e31510ba576de0'
+ '102a70c5c453875f5806ce02cc83fdc74e53c078cf5be2657f3dd1dd4438868c'
+ '7690a4f6bdc4a57e35c7ff5b6e87f2fe6d056d452eff9e767eaccff41832f4d7'
+ '04a7176400907fd7db0d69116b99de49e582a6e176b3bfb36a03e50a4cb26a36')
+
+prepare() {
+ cd ffmpeg
+
+ # add svt codec support for hevc, av1 and vp9
+ git apply --index "${srcdir}/ffmpeg-full-git-add-svt-hevc-${_svt_hevc_ver}.patch"
+ patch -Np1 -i "${srcdir}/ffmpeg-full-git-add-svt-hevc-docs-${_svt_hevc_ver}.patch"
+ git apply --index "${srcdir}/ffmpeg-full-git-add-svt-av1-${_svt_av1_ver}.patch"
+ git apply --index "${srcdir}/ffmpeg-full-git-add-svt-vp9-g${_svt_vp9_ver:0:7}.patch"
+}
+
+pkgver() {
+ cd ffmpeg
+
+ local _version
+ local _revision
+ local _shorthash
+
+ _version="$( git describe --tags --long | awk -F'-' '{ sub(/^n/, "", $1); print $1 }')"
+ _revision="$( git describe --tags --match 'N' | awk -F'-' '{ print $2 }')"
+ _shorthash="$(git rev-parse --short HEAD)"
+
+ printf '%s.r%s.g%s' "$_version" "$_revision" "$_shorthash"
+}
+
+build() {
+ cd ffmpeg
+
+ export PKG_CONFIG_PATH="${PKG_CONFIG_PATH:+${PKG_CONFIG_PATH}:}/opt/intel/mediasdk/lib/pkgconfig"
+
+ printf '%s\n' ' -> Running ffmpeg configure script...'
+
+ ./configure \
+ --prefix='/usr' \
+ --extra-cflags='-I/usr/include/tensorflow' \
+ \
+ --disable-rpath \
+ --enable-gpl \
+ --enable-version3 \
+ --enable-nonfree \
+ --enable-shared \
+ --disable-static \
+ --disable-stripping \
+ --enable-gray \
+ --enable-avresample \
+ \
+ --enable-alsa \
+ --enable-avisynth \
+ --enable-bzlib \
+ --enable-chromaprint \
+ --enable-frei0r \
+ --enable-gcrypt \
+ --enable-gmp \
+ --enable-gnutls \
+ --enable-iconv \
+ --enable-ladspa \
+ --enable-libaom \
+ --enable-libaribb24 \
+ --enable-libass \
+ --enable-libbluray \
+ --enable-libbs2b \
+ --enable-libcaca \
+ --enable-libcelt \
+ --enable-libcdio \
+ --enable-libcodec2 \
+ --enable-libdav1d \
+ --enable-libdavs2 \
+ --enable-libdc1394 \
+ --enable-libfdk-aac \
+ --enable-libflite \
+ --enable-fontconfig \
+ --enable-libfreetype \
+ --enable-libfribidi \
+ --enable-libgme \
+ --enable-libgsm \
+ --enable-libiec61883 \
+ --enable-libilbc \
+ --enable-libjack \
+ --enable-libklvanc \
+ --enable-libkvazaar \
+ --enable-liblensfun \
+ --enable-libmodplug \
+ --enable-libmp3lame \
+ --enable-libopencore-amrnb \
+ --enable-libopencore-amrwb \
+ --disable-libopencv \
+ --enable-libopenh264 \
+ --enable-libopenjpeg \
+ --enable-libopenmpt \
+ --enable-libopus \
+ --enable-libpulse \
+ --enable-librav1e \
+ --enable-librsvg \
+ --enable-librubberband \
+ --enable-librtmp \
+ --enable-libshine \
+ --disable-libsmbclient \
+ --enable-libsnappy \
+ --enable-libsoxr \
+ --enable-libspeex \
+ --enable-libsrt \
+ --enable-libssh \
+ --enable-libsvthevc \
+ --enable-libsvtav1 \
+ --enable-libsvtvp9 \
+ --enable-libtensorflow \
+ --enable-libtesseract \
+ --enable-libtheora \
+ --disable-libtls \
+ --enable-libtwolame \
+ --enable-libv4l2 \
+ --enable-libvidstab \
+ --enable-libvmaf \
+ --enable-libvo-amrwbenc \
+ --enable-libvorbis \
+ --enable-libvpx \
+ --enable-libwavpack \
+ --enable-libwebp \
+ --enable-libx264 \
+ --enable-libx265 \
+ --enable-libxavs \
+ --enable-libxavs2 \
+ --enable-libxcb \
+ --enable-libxcb-shm \
+ --enable-libxcb-xfixes \
+ --enable-libxcb-shape \
+ --enable-libxvid \
+ --enable-libxml2 \
+ --enable-libzimg \
+ --enable-libzmq \
+ --enable-libzvbi \
+ --enable-lv2 \
+ --enable-lzma \
+ --enable-decklink \
+ --disable-mbedtls \
+ --enable-libmysofa \
+ --enable-openal \
+ --enable-opencl \
+ --enable-opengl \
+ --disable-openssl \
+ --enable-pocketsphinx \
+ --enable-sndio \
+ --enable-sdl2 \
+ --enable-vapoursynth \
+ --enable-xlib \
+ --enable-zlib \
+ \
+ --enable-libdrm \
+ --enable-libmfx \
+ --enable-omx \
+ --enable-v4l2-m2m \
+ --enable-vaapi \
+ --enable-vdpau
+
+ make
+ make tools/qt-faststart
+}
+
+package() {
+ make -C ffmpeg DESTDIR="$pkgdir" install
+ install -D -m755 ffmpeg/tools/qt-faststart -t "${pkgdir}/usr/bin"
+ install -D -m644 LICENSE -t "${pkgdir}/usr/share/licenses/${pkgname}"
+}
diff --git a/ffmpeg-full-git-add-svt-av1-0.6.0.patch b/ffmpeg-full-git-add-svt-av1-0.6.0.patch
new file mode 100644
index 000000000000..35b47610ce18
--- /dev/null
+++ b/ffmpeg-full-git-add-svt-av1-0.6.0.patch
@@ -0,0 +1,569 @@
+From 64932c76e3dd36f010b1643a70abcceae7fdfca8 Mon Sep 17 00:00:00 2001
+From: Daryl Seah <daryl.seah@intel.com>
+Date: Fri, 18 Jan 2019 02:11:38 +0000
+Subject: [PATCH] Add ability for ffmpeg to run svt-av1 with svt-hevc
+
+Change-Id: I37ee5414fdd99e0b3f112a6e5ede166f3e48d819
+Signed-off-by: Daryl Seah <daryl.seah@intel.com>
+Signed-off-by: Jing SUN <jing.a.sun@intel.com>
+---
+ configure | 4 +
+ libavcodec/Makefile | 1 +
+ libavcodec/allcodecs.c | 1 +
+ libavcodec/libsvt_av1.c | 484 ++++++++++++++++++++++++++++++++++++++++
+ 4 files changed, 490 insertions(+)
+ create mode 100644 libavcodec/libsvt_av1.c
+
+diff --git a/configure b/configure
+index 2f61c8296e..87e6696523 100755
+--- a/configure
++++ b/configure
+@@ -263,6 +263,7 @@ External library support:
+ --enable-libsrt enable Haivision SRT protocol via libsrt [no]
+ --enable-libssh enable SFTP protocol via libssh [no]
+ --enable-libsvthevc enable HEVC encoding via svt [no]
++ --enable-libsvtav1 enable AV1 encoding via svt [no]
+ --enable-libtensorflow enable TensorFlow as a DNN module backend
+ for DNN based filters like sr [no]
+ --enable-libtesseract enable Tesseract, needed for ocr filter [no]
+@@ -1745,6 +1746,7 @@ EXTERNAL_LIBRARY_LIST="
+ libsrt
+ libssh
+ libsvthevc
++ libsvtav1
+ libtensorflow
+ libtesseract
+ libtheora
+@@ -3128,6 +3130,7 @@ libspeex_decoder_deps="libspeex"
+ libspeex_encoder_deps="libspeex"
+ libspeex_encoder_select="audio_frame_queue"
+ libsvt_hevc_encoder_deps="libsvthevc"
++libsvt_av1_encoder_deps="libsvtav1"
+ libtheora_encoder_deps="libtheora"
+ libtwolame_encoder_deps="libtwolame"
+ libvo_amrwbenc_encoder_deps="libvo_amrwbenc"
+@@ -6139,6 +6142,7 @@ enabled libssh && require_pkg_config libssh libssh libssh/sftp.h sftp
+ 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 libsvthevc && require_pkg_config libsvthevc SvtHevcEnc EbApi.h EbInitHandle
++enabled libsvtav1 && require_pkg_config libsvtav1 SvtAv1Enc EbSvtAv1Enc.h eb_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
+diff --git a/libavcodec/Makefile b/libavcodec/Makefile
+index 728503be9c..a524f34d9c 100644
+--- a/libavcodec/Makefile
++++ b/libavcodec/Makefile
+@@ -982,6 +982,7 @@ OBJS-$(CONFIG_LIBSHINE_ENCODER) += libshine.o
+ OBJS-$(CONFIG_LIBSPEEX_DECODER) += libspeexdec.o
+ OBJS-$(CONFIG_LIBSPEEX_ENCODER) += libspeexenc.o
+ OBJS-$(CONFIG_LIBSVT_HEVC_ENCODER) += libsvt_hevc.o
++OBJS-$(CONFIG_LIBSVT_AV1_ENCODER) += libsvt_av1.o
+ OBJS-$(CONFIG_LIBTHEORA_ENCODER) += libtheoraenc.o
+ OBJS-$(CONFIG_LIBTWOLAME_ENCODER) += libtwolame.o
+ OBJS-$(CONFIG_LIBVO_AMRWBENC_ENCODER) += libvo-amrwbenc.o
+diff --git a/libavcodec/allcodecs.c b/libavcodec/allcodecs.c
+index 5739d53329..98f0c99883 100644
+--- a/libavcodec/allcodecs.c
++++ b/libavcodec/allcodecs.c
+@@ -698,6 +698,7 @@ extern AVCodec ff_libshine_encoder;
+ extern AVCodec ff_libspeex_encoder;
+ extern AVCodec ff_libspeex_decoder;
+ extern AVCodec ff_libsvt_hevc_encoder;
++extern AVCodec ff_libsvt_av1_encoder;
+ extern AVCodec ff_libtheora_encoder;
+ extern AVCodec ff_libtwolame_encoder;
+ extern AVCodec ff_libvo_amrwbenc_encoder;
+diff --git a/libavcodec/libsvt_av1.c b/libavcodec/libsvt_av1.c
+new file mode 100644
+index 0000000000..a044c1eac5
+--- /dev/null
++++ b/libavcodec/libsvt_av1.c
+@@ -0,0 +1,484 @@
++/*
++* Scalable Video Technology for AV1 encoder library plugin
++*
++* Copyright (c) 2018 Intel Corporation
++*
++* This file is part of FFmpeg.
++*
++* FFmpeg is free software; you can redistribute it and/or
++* modify it under the terms of the GNU Lesser General Public
++* License as published by the Free Software Foundation; either
++* version 2.1 of the License, or (at your option) any later version.
++*
++* FFmpeg is distributed in the hope that it will be useful,
++* but WITHOUT ANY WARRANTY; without even the implied warranty of
++* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
++* Lesser General Public License for more details.
++*
++* You should have received a copy of the GNU Lesser General Public
++* License along with this program; if not, write to the Free Software
++* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
++*/
++
++#include <stdint.h>
++#include "EbSvtAv1ErrorCodes.h"
++#include "EbSvtAv1Enc.h"
++
++#include "libavutil/common.h"
++#include "libavutil/frame.h"
++#include "libavutil/opt.h"
++
++#include "internal.h"
++#include "avcodec.h"
++
++typedef struct SvtContext {
++ AVClass *class;
++
++ EbSvtAv1EncConfiguration enc_params;
++ EbComponentType *svt_handle;
++
++ EbBufferHeaderType *in_buf;
++ int raw_size;
++
++ int eos_flag;
++
++ // User options.
++ int hierarchical_level;
++ int la_depth;
++ int enc_mode;
++ int rc_mode;
++ int scd;
++ int qp;
++
++ int forced_idr;
++
++ int aud;
++
++ int tier;
++ int level;
++
++ int base_layer_switch_mode;
++} SvtContext;
++
++static int error_mapping(EbErrorType svt_ret)
++{
++ int err;
++
++ switch (svt_ret) {
++ case EB_ErrorInsufficientResources:
++ err = AVERROR(ENOMEM);
++ break;
++
++ case EB_ErrorUndefined:
++ case EB_ErrorInvalidComponent:
++ case EB_ErrorBadParameter:
++ err = AVERROR(EINVAL);
++ break;
++
++ case EB_ErrorDestroyThreadFailed:
++ case EB_ErrorSemaphoreUnresponsive:
++ case EB_ErrorDestroySemaphoreFailed:
++ case EB_ErrorCreateMutexFailed:
++ case EB_ErrorMutexUnresponsive:
++ case EB_ErrorDestroyMutexFailed:
++ err = AVERROR_EXTERNAL;
++ break;
++
++ case EB_NoErrorEmptyQueue:
++ err = AVERROR(EAGAIN);
++
++ case EB_ErrorNone:
++ err = 0;
++ break;
++
++ default:
++ err = AVERROR_UNKNOWN;
++ }
++
++ return err;
++}
++
++static void free_buffer(SvtContext *svt_enc)
++{
++ if (svt_enc->in_buf) {
++ EbSvtIOFormat *in_data = (EbSvtIOFormat *)svt_enc->in_buf->p_buffer;
++ av_freep(&in_data);
++ av_freep(&svt_enc->in_buf);
++ }
++}
++
++static int alloc_buffer(EbSvtAv1EncConfiguration *config, SvtContext *svt_enc)
++{
++ const int pack_mode_10bit =
++ (config->encoder_bit_depth > 8) && (config->compressed_ten_bit_format == 0) ? 1 : 0;
++ const size_t luma_size_8bit =
++ config->source_width * config->source_height * (1 << pack_mode_10bit);
++ const size_t luma_size_10bit =
++ (config->encoder_bit_depth > 8 && pack_mode_10bit == 0) ? luma_size_8bit : 0;
++
++ EbSvtIOFormat *in_data;
++
++ svt_enc->raw_size = (luma_size_8bit + luma_size_10bit) * 3 / 2;
++
++ // allocate buffer for in and out
++ svt_enc->in_buf = av_mallocz(sizeof(*svt_enc->in_buf));
++ if (!svt_enc->in_buf)
++ goto failed;
++
++ in_data = av_mallocz(sizeof(*in_data));
++ if (!in_data)
++ goto failed;
++ svt_enc->in_buf->p_buffer = (unsigned char *)in_data;
++
++ svt_enc->in_buf->size = sizeof(*svt_enc->in_buf);
++ svt_enc->in_buf->p_app_private = NULL;
++
++ return 0;
++
++failed:
++ free_buffer(svt_enc);
++ return AVERROR(ENOMEM);
++}
++
++static int config_enc_params(EbSvtAv1EncConfiguration *param,
++ AVCodecContext *avctx)
++{
++ SvtContext *svt_enc = avctx->priv_data;
++ int ret;
++ int ten_bits = 0;
++
++ param->source_width = avctx->width;
++ param->source_height = avctx->height;
++
++ if (avctx->pix_fmt == AV_PIX_FMT_YUV420P10LE) {
++ av_log(avctx, AV_LOG_DEBUG , "Encoder 10 bits depth input\n");
++ // Disable Compressed 10-bit format default
++ //
++ // SVT-AV1 support a compressed 10-bit format allowing the
++ // software to achieve a higher speed and channel density levels.
++ // The conversion between the 10-bit yuv420p10le and the compressed
++ // 10-bit format is a lossless operation. But in FFmpeg, we usually
++ // didn't use this format
++ param->compressed_ten_bit_format = 0;
++ ten_bits = 1;
++ }
++
++ // Update param from options
++ param->hierarchical_levels = svt_enc->hierarchical_level;
++ param->enc_mode = svt_enc->enc_mode;
++ param->tier = svt_enc->tier;
++ param->level = svt_enc->level;
++ param->rate_control_mode = svt_enc->rc_mode;
++ param->scene_change_detection = svt_enc->scd;
++ param->base_layer_switch_mode = svt_enc->base_layer_switch_mode;
++ param->qp = svt_enc->qp;
++
++
++ param->target_bit_rate = avctx->bit_rate;
++ 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 * avctx->ticks_per_frame;
++ } else {
++ param->frame_rate_numerator = avctx->time_base.den;
++ param->frame_rate_denominator = avctx->time_base.num * avctx->ticks_per_frame;
++ }
++
++ if (param->rate_control_mode) {
++ param->max_qp_allowed = avctx->qmax;
++ param->min_qp_allowed = avctx->qmin;
++ }
++
++ param->intra_refresh_type =
++ !!(avctx->flags & AV_CODEC_FLAG_CLOSED_GOP) + 1;
++
++ if (svt_enc->la_depth != -1)
++ param->look_ahead_distance = svt_enc->la_depth;
++
++ if (ten_bits) {
++ param->encoder_bit_depth = 10;
++ }
++
++ ret = alloc_buffer(param, svt_enc);
++
++ return ret;
++}
++
++static void read_in_data(EbSvtAv1EncConfiguration *config,
++ const AVFrame *frame,
++ EbBufferHeaderType *headerPtr)
++{
++ uint8_t is16bit = config->encoder_bit_depth > 8;
++ uint64_t luma_size =
++ (uint64_t)config->source_width * config->source_height<< is16bit;
++ EbSvtIOFormat *in_data = (EbSvtIOFormat *)headerPtr->p_buffer;
++
++ // support yuv420p and yuv420p010
++ in_data->luma = frame->data[0];
++ in_data->cb = frame->data[1];
++ in_data->cr = frame->data[2];
++
++ // stride info
++ in_data->y_stride = frame->linesize[0] >> is16bit;
++ in_data->cb_stride = frame->linesize[1] >> is16bit;
++ in_data->cr_stride = frame->linesize[2] >> is16bit;
++
++ headerPtr->n_filled_len += luma_size * 3/2u;
++}
++
++static av_cold int eb_enc_init(AVCodecContext *avctx)
++{
++ SvtContext *svt_enc = avctx->priv_data;
++ EbErrorType svt_ret;
++
++ svt_enc->eos_flag = 0;
++
++ svt_ret = eb_init_handle(&svt_enc->svt_handle, svt_enc, &svt_enc->enc_params);
++ if (svt_ret != EB_ErrorNone) {
++ av_log(avctx, AV_LOG_ERROR, "Error init encoder handle\n");
++ goto failed;
++ }
++
++ svt_ret = config_enc_params(&svt_enc->enc_params, avctx);
++ if (svt_ret != EB_ErrorNone) {
++ av_log(avctx, AV_LOG_ERROR, "Error configure encoder parameters\n");
++ goto failed_init_handle;
++ }
++
++ svt_ret = eb_svt_enc_set_parameter(svt_enc->svt_handle, &svt_enc->enc_params);
++ if (svt_ret != EB_ErrorNone) {
++ av_log(avctx, AV_LOG_ERROR, "Error setting encoder parameters\n");
++ goto failed_init_handle;
++ }
++
++ svt_ret = eb_init_encoder(svt_enc->svt_handle);
++ if (svt_ret != EB_ErrorNone) {
++ av_log(avctx, AV_LOG_ERROR, "Error init encoder\n");
++ goto failed_init_handle;
++ }
++
++ if (avctx->flags & AV_CODEC_FLAG_GLOBAL_HEADER) {
++ EbBufferHeaderType *headerPtr = NULL;
++
++ svt_ret = eb_svt_enc_stream_header(svt_enc->svt_handle, &headerPtr);
++ if (svt_ret != EB_ErrorNone) {
++ av_log(avctx, AV_LOG_ERROR, "Error when build stream header.\n");
++ goto failed_init_enc;
++ }
++
++ avctx->extradata_size = headerPtr->n_filled_len;
++ avctx->extradata = av_mallocz(avctx->extradata_size + AV_INPUT_BUFFER_PADDING_SIZE);
++ if (!avctx->extradata) {
++ av_log(avctx, AV_LOG_ERROR,
++ "Cannot allocate AV1 header of size %d.\n", avctx->extradata_size);
++ svt_ret = EB_ErrorInsufficientResources;
++ goto failed_init_enc;
++ }
++
++ memcpy(avctx->extradata, headerPtr->p_buffer, avctx->extradata_size);
++
++ svt_ret = eb_svt_release_enc_stream_header(headerPtr);
++ if (svt_ret != EB_ErrorNone) {
++ av_log(avctx, AV_LOG_ERROR, "Error when destroy stream header.\n");
++ goto failed_init_enc;
++ }
++ }
++
++ return 0;
++
++failed_init_enc:
++ eb_deinit_encoder(svt_enc->svt_handle);
++failed_init_handle:
++ eb_deinit_handle(svt_enc->svt_handle);
++failed:
++ free_buffer(svt_enc);
++ return error_mapping(svt_ret);
++}
++
++static int eb_send_frame(AVCodecContext *avctx, const AVFrame *frame)
++{
++ SvtContext *svt_enc = avctx->priv_data;
++ EbBufferHeaderType *headerPtr = svt_enc->in_buf;
++
++ if (!frame) {
++ EbBufferHeaderType headerPtrLast;
++ headerPtrLast.n_alloc_len = 0;
++ headerPtrLast.n_filled_len = 0;
++ headerPtrLast.n_tick_count = 0;
++ headerPtrLast.p_app_private = NULL;
++ headerPtrLast.p_buffer = NULL;
++ headerPtrLast.flags = EB_BUFFERFLAG_EOS;
++
++ eb_svt_enc_send_picture(svt_enc->svt_handle, &headerPtrLast);
++ svt_enc->eos_flag = 1;
++ av_log(avctx, AV_LOG_DEBUG, "Finish sending frames!!!\n");
++ return 0;
++ }
++
++ read_in_data(&svt_enc->enc_params, frame, headerPtr);
++
++ headerPtr->flags = 0;
++ headerPtr->p_app_private = NULL;
++ headerPtr->pts = frame->pts;
++ switch (frame->pict_type) {
++ case AV_PICTURE_TYPE_I:
++ headerPtr->pic_type = svt_enc->forced_idr > 0 ? EB_AV1_KEY_PICTURE : EB_AV1_INTRA_ONLY_PICTURE;
++ break;
++ case AV_PICTURE_TYPE_P:
++ headerPtr->pic_type = EB_AV1_ALT_REF_PICTURE;
++ break;
++ case AV_PICTURE_TYPE_B:
++ headerPtr->pic_type = EB_AV1_INTER_PICTURE;
++ break;
++ default:
++ headerPtr->pic_type = EB_AV1_INVALID_PICTURE;
++ break;
++ }
++ eb_svt_enc_send_picture(svt_enc->svt_handle, headerPtr);
++
++ return 0;
++}
++
++static int eb_receive_packet(AVCodecContext *avctx, AVPacket *pkt)
++{
++ SvtContext *svt_enc = avctx->priv_data;
++ EbBufferHeaderType *headerPtr;
++ EbErrorType svt_ret;
++ int ret;
++
++ if ((ret = ff_alloc_packet2(avctx, pkt, svt_enc->raw_size, 0)) < 0) {
++ av_log(avctx, AV_LOG_ERROR, "Failed to allocate output packet.\n");
++ return ret;
++ }
++ svt_ret = eb_svt_get_packet(svt_enc->svt_handle, &headerPtr, svt_enc->eos_flag);
++ if (svt_ret == EB_NoErrorEmptyQueue)
++ return AVERROR(EAGAIN);
++
++ memcpy(pkt->data, headerPtr->p_buffer, headerPtr->n_filled_len);
++ pkt->size = headerPtr->n_filled_len;
++ pkt->pts = headerPtr->pts;
++ pkt->dts = headerPtr->dts;
++ if (headerPtr->pic_type == EB_AV1_KEY_PICTURE)
++ pkt->flags |= AV_PKT_FLAG_KEY;
++ if (headerPtr->pic_type == EB_AV1_NON_REF_PICTURE)
++ pkt->flags |= AV_PKT_FLAG_DISPOSABLE;
++
++ ret = (headerPtr->flags & EB_BUFFERFLAG_EOS) ? AVERROR_EOF : 0;
++
++ eb_svt_release_out_buffer(&headerPtr);
++
++ return ret;
++}
++
++static av_cold int eb_enc_close(AVCodecContext *avctx)
++{
++ SvtContext *svt_enc = avctx->priv_data;
++
++ eb_deinit_encoder(svt_enc->svt_handle);
++ eb_deinit_handle(svt_enc->svt_handle);
++
++ free_buffer(svt_enc);
++
++ return 0;
++}
++
++#define OFFSET(x) offsetof(SvtContext, x)
++#define VE AV_OPT_FLAG_VIDEO_PARAM | AV_OPT_FLAG_ENCODING_PARAM
++static const AVOption options[] = {
++ { "aud", "Include AUD", OFFSET(aud),
++ AV_OPT_TYPE_BOOL, { .i64 = 0 }, 0, 1, VE },
++
++ { "hielevel", "Hierarchical prediction levels setting", OFFSET(hierarchical_level),
++ AV_OPT_TYPE_INT, { .i64 = 4 }, 3, 4, VE , "hielevel"},
++ { "flat", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = 1 }, INT_MIN, INT_MAX, VE, "hielevel" },
++ { "2level", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = 2 }, INT_MIN, INT_MAX, VE, "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, 256]", OFFSET(la_depth),
++ AV_OPT_TYPE_INT, { .i64 = -1 }, -1, 256, VE },
++
++ { "preset", "Encoding preset [0, 7]",
++ OFFSET(enc_mode), AV_OPT_TYPE_INT, { .i64 = MAX_ENC_PRESET }, 0, MAX_ENC_PRESET, VE },
++
++ { "tier", "Set tier (general_tier_flag)", OFFSET(tier),
++ AV_OPT_TYPE_INT, { .i64 = 0 }, 0, 1, VE, "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" },
++
++ { "level", "Set level (level_idc)", OFFSET(level),
++ AV_OPT_TYPE_INT, { .i64 = 0 }, 0, 0xff, VE, "level" },
++
++#define LEVEL(name, value) name, NULL, 0, AV_OPT_TYPE_CONST, \
++ { .i64 = value }, 0, 0, VE, "level"
++ { LEVEL("1", 10) },
++ { LEVEL("2", 20) },
++ { LEVEL("2.1", 21) },
++ { LEVEL("3", 30) },
++ { LEVEL("3.1", 31) },
++ { LEVEL("4", 40) },
++ { LEVEL("4.1", 41) },
++ { LEVEL("5", 50) },
++ { LEVEL("5.1", 51) },
++ { LEVEL("5.2", 52) },
++ { LEVEL("6", 60) },
++ { LEVEL("6.1", 61) },
++ { LEVEL("6.2", 62) },
++#undef LEVEL
++
++ { "rc", "Bit rate control mode", OFFSET(rc_mode),
++ AV_OPT_TYPE_INT, { .i64 = 0 }, 0, 1, VE , "rc"},
++ { "cqp", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = 0 }, INT_MIN, INT_MAX, VE, "rc" },
++ { "vbr", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = 1 }, INT_MIN, INT_MAX, VE, "rc" },
++
++ { "qp", "QP value for intra frames", OFFSET(qp),
++ AV_OPT_TYPE_INT, { .i64 = 50 }, 0, 63, VE },
++
++ { "sc_detection", "Scene change detection", OFFSET(scd),
++ AV_OPT_TYPE_BOOL, { .i64 = 0 }, 0, 1, VE },
++
++ { "bl_mode", "Random Access Prediction Structure type setting", OFFSET(base_layer_switch_mode),
++ AV_OPT_TYPE_BOOL, { .i64 = 0 }, 0, 1, VE },
++
++ { "forced-idr", "If forcing keyframes, force them as IDR frames.", OFFSET(forced_idr),
++ AV_OPT_TYPE_BOOL, { .i64 = 0 }, -1, 1, VE },
++
++ {NULL},
++};
++
++static const AVClass class = {
++ .class_name = "libsvt_av1",
++ .item_name = av_default_item_name,
++ .option = options,
++ .version = LIBAVUTIL_VERSION_INT,
++};
++
++static const AVCodecDefault eb_enc_defaults[] = {
++ { "b", "7M" },
++ { "g", "-2" },
++ { "flags", "-cgop" },
++ { "qmin", "0" },
++ { "qmax", "63" },
++ { NULL },
++};
++
++AVCodec ff_libsvt_av1_encoder = {
++ .name = "libsvt_av1",
++ .long_name = NULL_IF_CONFIG_SMALL("SVT-AV1(Scalable Video Technology for AV1) encoder"),
++ .priv_data_size = sizeof(SvtContext),
++ .type = AVMEDIA_TYPE_VIDEO,
++ .id = AV_CODEC_ID_AV1,
++ .init = eb_enc_init,
++ .send_frame = eb_send_frame,
++ .receive_packet = eb_receive_packet,
++ .close = eb_enc_close,
++ .capabilities = AV_CODEC_CAP_DELAY | AV_CODEC_CAP_AUTO_THREADS,
++ .pix_fmts = (const enum AVPixelFormat[]){ AV_PIX_FMT_YUV420P,
++ AV_PIX_FMT_NONE },
++ .priv_class = &class,
++ .defaults = eb_enc_defaults,
++ .caps_internal = FF_CODEC_CAP_INIT_CLEANUP,
++ .wrapper_name = "libsvt_av1",
++};
+--
+2.20.1
+
diff --git a/ffmpeg-full-git-add-svt-hevc-1.4.1.patch b/ffmpeg-full-git-add-svt-hevc-1.4.1.patch
new file mode 100644
index 000000000000..ec55044854f2
--- /dev/null
+++ b/ffmpeg-full-git-add-svt-hevc-1.4.1.patch
@@ -0,0 +1,601 @@
+From 3248aee7fc94304cd5f41afa8dc502d92ae080ef Mon Sep 17 00:00:00 2001
+From: Jing Sun <jing.a.sun@intel.com>
+Date: Wed, 21 Nov 2018 11:33:04 +0800
+Subject: [PATCH 1/1] lavc/svt_hevc: add libsvt hevc encoder wrapper
+
+Signed-off-by: Zhengxu Huang <zhengxu.huang@intel.com>
+Signed-off-by: Hassene Tmar <hassene.tmar@intel.com>
+Signed-off-by: Jun Zhao <jun.zhao@intel.com>
+Signed-off-by: Jing Sun <jing.a.sun@intel.com>
+---
+ configure | 4 +
+ libavcodec/Makefile | 1 +
+ libavcodec/allcodecs.c | 1 +
+ libavcodec/libsvt_hevc.c | 515 +++++++++++++++++++++++++++++++++++++++++++++++
+ 4 files changed, 521 insertions(+)
+ create mode 100644 libavcodec/libsvt_hevc.c
+
+diff --git a/configure b/configure
+index c09c842..648ea80 100755
+--- a/configure
++++ b/configure
+@@ -264,6 +264,7 @@ External library support:
+ --enable-libspeex enable Speex de/encoding via libspeex [no]
+ --enable-libsrt enable Haivision SRT protocol via libsrt [no]
+ --enable-libssh enable SFTP protocol via libssh [no]
++ --enable-libsvthevc enable HEVC encoding via svt [no]
+ --enable-libtensorflow enable TensorFlow as a DNN module backend
+ for DNN based filters like sr [no]
+ --enable-libtesseract enable Tesseract, needed for ocr filter [no]
+@@ -1793,6 +1794,7 @@ EXTERNAL_LIBRARY_LIST="
+ libspeex
+ libsrt
+ libssh
++ libsvthevc
+ libtensorflow
+ libtesseract
+ libtheora
+@@ -3194,6 +3196,7 @@ libshine_encoder_select="audio_frame_queue"
+ libspeex_decoder_deps="libspeex"
+ libspeex_encoder_deps="libspeex"
+ libspeex_encoder_select="audio_frame_queue"
++libsvt_hevc_encoder_deps="libsvthevc"
+ libtheora_encoder_deps="libtheora"
+ libtwolame_encoder_deps="libtwolame"
+ libvo_amrwbenc_encoder_deps="libvo_amrwbenc"
+@@ -6269,6 +6272,7 @@ enabled libsoxr && require libsoxr soxr.h soxr_create -lsoxr
+ 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 libsvthevc && require_pkg_config libsvthevc SvtHevcEnc EbApi.h EbInitHandle
+ 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
+diff --git a/libavcodec/Makefile b/libavcodec/Makefile
+index 3cd73fb..d39f568 100644
+--- a/libavcodec/Makefile
++++ b/libavcodec/Makefile
+@@ -991,6 +991,7 @@ OBJS-$(CONFIG_LIBOPUS_ENCODER) += libopusenc.o libopus.o \
+ OBJS-$(CONFIG_LIBSHINE_ENCODER) += libshine.o
+ OBJS-$(CONFIG_LIBSPEEX_DECODER) += libspeexdec.o
+ OBJS-$(CONFIG_LIBSPEEX_ENCODER) += libspeexenc.o
++OBJS-$(CONFIG_LIBSVT_HEVC_ENCODER) += libsvt_hevc.o
+ OBJS-$(CONFIG_LIBTHEORA_ENCODER) += libtheoraenc.o
+ OBJS-$(CONFIG_LIBTWOLAME_ENCODER) += libtwolame.o
+ OBJS-$(CONFIG_LIBVO_AMRWBENC_ENCODER) += libvo-amrwbenc.o
+diff --git a/libavcodec/allcodecs.c b/libavcodec/allcodecs.c
+index d2f9a39..d8788a7 100644
+--- a/libavcodec/allcodecs.c
++++ b/libavcodec/allcodecs.c
+@@ -707,6 +707,7 @@ extern AVCodec ff_librsvg_decoder;
+ extern AVCodec ff_libshine_encoder;
+ extern AVCodec ff_libspeex_encoder;
+ extern AVCodec ff_libspeex_decoder;
++extern AVCodec ff_libsvt_hevc_encoder;
+ extern AVCodec ff_libtheora_encoder;
+ extern AVCodec ff_libtwolame_encoder;
+ extern AVCodec ff_libvo_amrwbenc_encoder;
+diff --git a/libavcodec/libsvt_hevc.c b/libavcodec/libsvt_hevc.c
+new file mode 100644
+index 0000000..77eae48
+--- /dev/null
++++ b/libavcodec/libsvt_hevc.c
+@@ -0,0 +1,515 @@
++/*
++* Scalable Video Technology for HEVC encoder library plugin
++*
++* Copyright (c) 2019 Intel Corporation
++*
++* This file is part of FFmpeg.
++*
++* FFmpeg is free software; you can redistribute it and/or
++* modify it under the terms of the GNU Lesser General Public
++* License as published by the Free Software Foundation; either
++* version 2.1 of the License, or (at your option) any later version.
++*
++* FFmpeg is distributed in the hope that it will be useful,
++* but WITHOUT ANY WARRANTY; without even the implied warranty of
++* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
++* Lesser General Public License for more details.
++*
++* You should have received a copy of the GNU Lesser General Public
++* License along with this program; if not, write to the Free Software
++* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
++*/
++
++#include "EbApi.h"
++
++#include "libavutil/common.h"
++#include "libavutil/frame.h"
++#include "libavutil/opt.h"
++
++#include "internal.h"
++#include "avcodec.h"
++
++typedef enum eos_status {
++ EOS_NOT_REACHED = 0,
++ EOS_SENT,
++ EOS_RECEIVED
++}EOS_STATUS;
++
++typedef struct SvtContext {
++ AVClass *class;
++
++ EB_H265_ENC_CONFIGURATION enc_params;
++ EB_COMPONENTTYPE *svt_handle;
++ EB_BUFFERHEADERTYPE in_buf;
++ uint8_t *in_data;
++ EOS_STATUS eos_flag;
++
++ // User options.
++ int profile;
++ int hierarchical_level;
++ int enc_mode;
++ int tier;
++ int level;
++ int rc_mode;
++ int scd;
++ int tune;
++ int base_layer_switch_mode;
++ int qp;
++ int aud;
++ int asm_type;
++ int forced_idr;
++ int la_depth;
++ int thread_count;
++} SvtContext;
++
++static int error_mapping(EB_ERRORTYPE svt_ret)
++{
++ switch (svt_ret) {
++ case EB_ErrorInsufficientResources:
++ return AVERROR(ENOMEM);
++
++ case EB_ErrorUndefined:
++ case EB_ErrorInvalidComponent:
++ case EB_ErrorBadParameter:
++ return AVERROR(EINVAL);
++
++ case EB_ErrorDestroyThreadFailed:
++ case EB_ErrorSemaphoreUnresponsive:
++ case EB_ErrorDestroySemaphoreFailed:
++ case EB_ErrorCreateMutexFailed:
++ case EB_ErrorMutexUnresponsive:
++ case EB_ErrorDestroyMutexFailed:
++ return AVERROR_EXTERNAL;
++
++ case EB_NoErrorEmptyQueue:
++ return AVERROR(EAGAIN);
++
++ case EB_ErrorNone:
++ return 0;
++
++ default:
++ return AVERROR_UNKNOWN;
++ }
++}
++
++static void free_buffer(SvtContext *svt_enc)
++{
++ if (svt_enc && svt_enc->in_data) {
++ av_freep(&svt_enc->in_data);
++ svt_enc->in_data = NULL;
++ }
++}
++
++static EB_ERRORTYPE alloc_buffer(SvtContext *svt_enc)
++{
++ EB_BUFFERHEADERTYPE *in_buf = &svt_enc->in_buf;
++ EB_H265_ENC_INPUT *in_data = NULL;
++
++ memset(in_buf, 0, sizeof(*in_buf));
++ in_buf->nSize = sizeof(*in_buf);
++ in_buf->sliceType = EB_INVALID_PICTURE;
++
++ in_data = (EB_H265_ENC_INPUT *)av_mallocz(sizeof(*in_data));
++ if (in_data) {
++ svt_enc->in_data = in_buf->pBuffer = (uint8_t *)in_data;
++ return EB_ErrorNone;
++ } else {
++ return EB_ErrorInsufficientResources;
++ }
++}
++
++static int config_enc_params(EB_H265_ENC_CONFIGURATION *param,
++ AVCodecContext *avctx)
++{
++ SvtContext *svt_enc = avctx->priv_data;
++
++ param->sourceWidth = avctx->width;
++ param->sourceHeight = avctx->height;
++
++ if ((avctx->pix_fmt == AV_PIX_FMT_YUV420P10) ||
++ (avctx->pix_fmt == AV_PIX_FMT_YUV422P10) ||
++ (avctx->pix_fmt == AV_PIX_FMT_YUV444P10)) {
++ av_log(avctx, AV_LOG_DEBUG, "Set 10 bits depth input\n");
++ param->encoderBitDepth = 10;
++ } else {
++ av_log(avctx, AV_LOG_DEBUG, "Set 8 bits depth input\n");
++ param->encoderBitDepth = 8;
++ }
++
++ if ((avctx->pix_fmt == AV_PIX_FMT_YUV420P) ||
++ (avctx->pix_fmt == AV_PIX_FMT_YUV420P10))
++ param->encoderColorFormat = EB_YUV420;
++ else if ((avctx->pix_fmt == AV_PIX_FMT_YUV422P) ||
++ (avctx->pix_fmt == AV_PIX_FMT_YUV422P10))
++ param->encoderColorFormat = EB_YUV422;
++ else
++ param->encoderColorFormat = EB_YUV444;
++
++ param->profile = svt_enc->profile;
++
++ if (FF_PROFILE_HEVC_MAIN_STILL_PICTURE == param->profile) {
++ av_log(avctx, AV_LOG_ERROR, "Main Still Picture Profile not supported\n");
++ return EB_ErrorBadParameter;
++ }
++
++ if ((param->encoderColorFormat >= EB_YUV422) &&
++ (param->profile != FF_PROFILE_HEVC_REXT)) {
++ av_log(avctx, AV_LOG_WARNING, "Rext Profile forced for 422 or 444\n");
++ param->profile = FF_PROFILE_HEVC_REXT;
++ }
++
++ if ((FF_PROFILE_HEVC_MAIN == param->profile) &&
++ (param->encoderBitDepth > 8)) {
++ av_log(avctx, AV_LOG_WARNING, "Main10 Profile forced for 10 bits\n");
++ param->profile = FF_PROFILE_HEVC_MAIN_10;
++ }
++
++ param->targetBitRate = avctx->bit_rate;
++
++ if (avctx->gop_size > 0)
++ param->intraPeriodLength = avctx->gop_size - 1;
++
++ if ((avctx->framerate.num > 0) && (avctx->framerate.den > 0)) {
++ param->frameRateNumerator = avctx->framerate.num;
++ param->frameRateDenominator =
++ avctx->framerate.den * avctx->ticks_per_frame;
++ } else {
++ param->frameRateNumerator = avctx->time_base.den;
++ param->frameRateDenominator =
++ avctx->time_base.num * avctx->ticks_per_frame;
++ }
++
++ param->hierarchicalLevels = svt_enc->hierarchical_level;
++ param->encMode = svt_enc->enc_mode;
++ param->tier = svt_enc->tier;
++ param->level = svt_enc->level;
++ param->rateControlMode = svt_enc->rc_mode;
++ param->sceneChangeDetection = svt_enc->scd;
++ param->tune = svt_enc->tune;
++ param->baseLayerSwitchMode = svt_enc->base_layer_switch_mode;
++ param->qp = svt_enc->qp;
++ param->accessUnitDelimiter = svt_enc->aud;
++ param->asmType = svt_enc->asm_type;
++ param->intraRefreshType = svt_enc->forced_idr;
++
++ if (param->rateControlMode) {
++ param->maxQpAllowed = avctx->qmax;
++ param->minQpAllowed = avctx->qmin;
++ }
++
++ if (svt_enc->la_depth != -1)
++ param->lookAheadDistance = svt_enc->la_depth;
++
++ if ((svt_enc->thread_count > 0) &&
++ (svt_enc->thread_count < (EB_THREAD_COUNT_MIN_CORE * EB_THREAD_COUNT_FACTOR))) {
++ param->threadCount = EB_THREAD_COUNT_MIN_CORE * EB_THREAD_COUNT_FACTOR;
++ av_log(avctx, AV_LOG_WARNING, "Thread count is set too small, forced to %"PRId32"\n",
++ param->threadCount);
++ } else if (svt_enc->thread_count % EB_THREAD_COUNT_MIN_CORE) {
++ param->threadCount = (svt_enc->thread_count + EB_THREAD_COUNT_MIN_CORE - 1)
++ / EB_THREAD_COUNT_MIN_CORE * EB_THREAD_COUNT_MIN_CORE;
++ av_log(avctx, AV_LOG_DEBUG, "Thread count is rounded to %"PRId32"\n",
++ param->threadCount);
++ } else {
++ param->threadCount = svt_enc->thread_count;
++ }
++
++ if (avctx->flags & AV_CODEC_FLAG_GLOBAL_HEADER)
++ param->codeVpsSpsPps = 0;
++ else
++ param->codeVpsSpsPps = 1;
++
++ param->codeEosNal = 1;
++
++ return EB_ErrorNone;
++}
++
++static void read_in_data(EB_H265_ENC_CONFIGURATION *config,
++ const AVFrame *frame,
++ EB_BUFFERHEADERTYPE *header_ptr)
++{
++ uint8_t is16bit;
++ uint64_t frame_size;
++ EB_H265_ENC_INPUT *in_data = (EB_H265_ENC_INPUT *)header_ptr->pBuffer;
++
++ is16bit = config->encoderBitDepth > 8;
++ frame_size = (uint64_t)(config->sourceWidth * config->sourceHeight) << is16bit;
++
++ in_data->luma = frame->data[0];
++ in_data->cb = frame->data[1];
++ in_data->cr = frame->data[2];
++
++ in_data->yStride = frame->linesize[0] >> is16bit;
++ in_data->cbStride = frame->linesize[1] >> is16bit;
++ in_data->crStride = frame->linesize[2] >> is16bit;
++
++ if (config->encoderColorFormat == EB_YUV420)
++ frame_size *= 3/2u;
++ else if (config->encoderColorFormat == EB_YUV422)
++ frame_size *= 2u;
++ else
++ frame_size *= 3u;
++
++ header_ptr->nFilledLen += frame_size;
++}
++
++static av_cold int eb_enc_init(AVCodecContext *avctx)
++{
++ SvtContext *svt_enc = avctx->priv_data;
++ EB_ERRORTYPE svt_ret;
++
++ svt_enc->eos_flag = EOS_NOT_REACHED;
++
++ svt_ret = EbInitHandle(&svt_enc->svt_handle, svt_enc, &svt_enc->enc_params);
++ if (svt_ret != EB_ErrorNone) {
++ av_log(avctx, AV_LOG_ERROR, "Failed to init handle\n");
++ return error_mapping(svt_ret);
++ }
++
++ svt_ret = config_enc_params(&svt_enc->enc_params, avctx);
++ if (svt_ret != EB_ErrorNone) {
++ av_log(avctx, AV_LOG_ERROR, "Failed to config parameters\n");
++ goto failed_init_handle;
++ }
++
++ svt_ret = EbH265EncSetParameter(svt_enc->svt_handle, &svt_enc->enc_params);
++ if (svt_ret != EB_ErrorNone) {
++ av_log(avctx, AV_LOG_ERROR, "Failed to set parameters\n");
++ goto failed_init_handle;
++ }
++
++ svt_ret = EbInitEncoder(svt_enc->svt_handle);
++ if (svt_ret != EB_ErrorNone) {
++ av_log(avctx, AV_LOG_ERROR, "Failed to init encoder\n");
++ goto failed_init_handle;
++ }
++
++ if (avctx->flags & AV_CODEC_FLAG_GLOBAL_HEADER) {
++ EB_BUFFERHEADERTYPE *header_ptr = NULL;
++
++ svt_ret = EbH265EncStreamHeader(svt_enc->svt_handle, &header_ptr);
++ if (svt_ret != EB_ErrorNone) {
++ av_log(avctx, AV_LOG_ERROR, "Failed to build stream header\n");
++ goto failed_init_encoder;
++ }
++
++ avctx->extradata_size = header_ptr->nFilledLen;
++ avctx->extradata = av_malloc(avctx->extradata_size + AV_INPUT_BUFFER_PADDING_SIZE);
++ if (!avctx->extradata) {
++ av_log(avctx, AV_LOG_ERROR, "Failed to allocate extradata\n");
++ svt_ret = EB_ErrorInsufficientResources;
++ goto failed_init_encoder;
++ }
++ memcpy(avctx->extradata, header_ptr->pBuffer, avctx->extradata_size);
++ memset(avctx->extradata+avctx->extradata_size, 0, AV_INPUT_BUFFER_PADDING_SIZE);
++ }
++
++ svt_ret = alloc_buffer(svt_enc);
++ if (svt_ret != EB_ErrorNone) {
++ av_log(avctx, AV_LOG_ERROR, "Failed to alloc data buffer\n");
++ goto failed_init_encoder;
++ }
++ return 0;
++
++failed_init_encoder:
++ EbDeinitEncoder(svt_enc->svt_handle);
++failed_init_handle:
++ EbDeinitHandle(svt_enc->svt_handle);
++ svt_enc->svt_handle = NULL;
++ svt_enc = NULL;
++ return error_mapping(svt_ret);
++}
++
++static int eb_encode_frame(AVCodecContext *avctx, AVPacket *pkt,
++ const AVFrame *frame, int *got_packet)
++{
++ SvtContext *svt_enc = avctx->priv_data;
++ EB_BUFFERHEADERTYPE *header_ptr = &svt_enc->in_buf;
++ EB_ERRORTYPE svt_ret;
++ int av_ret;
++
++ if (EOS_RECEIVED == svt_enc->eos_flag) {
++ *got_packet = 0;
++ return 0;
++ }
++
++ if (!frame) {
++ if (!svt_enc->eos_flag) {
++ svt_enc->eos_flag = EOS_SENT;
++
++ header_ptr->nAllocLen = 0;
++ header_ptr->nFilledLen = 0;
++ header_ptr->nTickCount = 0;
++ header_ptr->nFlags = EB_BUFFERFLAG_EOS;
++ header_ptr->pBuffer = NULL;
++
++ EbH265EncSendPicture(svt_enc->svt_handle, header_ptr);
++
++ av_log(avctx, AV_LOG_DEBUG, "Sent EOS\n");
++ }
++ } else {
++ read_in_data(&svt_enc->enc_params, frame, header_ptr);
++ header_ptr->pts = frame->pts;
++
++ EbH265EncSendPicture(svt_enc->svt_handle, header_ptr);
++
++ av_log(avctx, AV_LOG_DEBUG, "Sent PTS %"PRId64"\n", header_ptr->pts);
++ }
++
++ header_ptr = NULL;
++ svt_ret = EbH265GetPacket(svt_enc->svt_handle, &header_ptr, svt_enc->eos_flag);
++
++ if (svt_ret == EB_NoErrorEmptyQueue) {
++ *got_packet = 0;
++ av_log(avctx, AV_LOG_DEBUG, "Received none\n");
++ return 0;
++ }
++
++ av_log(avctx, AV_LOG_DEBUG, "Received PTS %"PRId64" packet\n", header_ptr->pts);
++
++ av_ret = ff_alloc_packet2(avctx, pkt, header_ptr->nFilledLen, 0);
++ if (av_ret) {
++ av_log(avctx, AV_LOG_ERROR, "Failed to allocate a packet\n");
++ EbH265ReleaseOutBuffer(&header_ptr);
++ return av_ret;
++ }
++
++ memcpy(pkt->data, header_ptr->pBuffer, header_ptr->nFilledLen);
++ pkt->size = header_ptr->nFilledLen;
++ pkt->pts = header_ptr->pts;
++ pkt->dts = header_ptr->dts;
++
++ if ((header_ptr->sliceType == EB_IDR_PICTURE) ||
++ (header_ptr->sliceType == EB_I_PICTURE))
++ pkt->flags |= AV_PKT_FLAG_KEY;
++ if (header_ptr->sliceType == EB_NON_REF_PICTURE)
++ pkt->flags |= AV_PKT_FLAG_DISPOSABLE;
++
++ EbH265ReleaseOutBuffer(&header_ptr);
++
++ *got_packet = 1;
++
++ if (EB_BUFFERFLAG_EOS == header_ptr->nFlags)
++ svt_enc->eos_flag = EOS_RECEIVED;
++
++ return 0;
++}
++
++static av_cold int eb_enc_close(AVCodecContext *avctx)
++{
++ SvtContext *svt_enc = avctx->priv_data;
++
++ if (svt_enc) {
++ free_buffer(svt_enc);
++
++ if (svt_enc->svt_handle) {
++ EbDeinitEncoder(svt_enc->svt_handle);
++ EbDeinitHandle(svt_enc->svt_handle);
++ svt_enc->svt_handle = NULL;
++ }
++ }
++
++ return 0;
++}
++
++#define OFFSET(x) offsetof(SvtContext, x)
++#define VE AV_OPT_FLAG_VIDEO_PARAM | AV_OPT_FLAG_ENCODING_PARAM
++static const AVOption options[] = {
++ { "asm_type", "Assembly instruction set type [0: C Only, 1: Auto]", OFFSET(asm_type),
++ AV_OPT_TYPE_BOOL, { .i64 = 1 }, 0, 1, VE },
++
++ { "aud", "Include Access Unit Delimiter", OFFSET(aud),
++ AV_OPT_TYPE_BOOL, { .i64 = 0 }, 0, 1, VE },
++
++ { "bl_mode", "Random Access Prediction Structure type setting", OFFSET(base_layer_switch_mode),
++ AV_OPT_TYPE_BOOL, { .i64 = 0 }, 0, 1, VE },
++
++ { "forced-idr", "If forcing keyframes, force them as IDR frames.", OFFSET(forced_idr),
++ AV_OPT_TYPE_INT, { .i64 = -1 }, -1, INT_MAX, VE },
++
++ { "hielevel", "Hierarchical prediction levels setting", OFFSET(hierarchical_level),
++ AV_OPT_TYPE_INT, { .i64 = 3 }, 0, 3, VE , "hielevel"},
++ { "flat", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = 0 }, INT_MIN, INT_MAX, VE, "hielevel" },
++ { "1 level", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = 1 }, INT_MIN, INT_MAX, VE, "hielevel" },
++ { "2 level", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = 2 }, INT_MIN, INT_MAX, VE, "hielevel" },
++ { "3 level", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = 3 }, INT_MIN, INT_MAX, VE, "hielevel" },
++
++ { "la_depth", "Look ahead distance [0, 256]", OFFSET(la_depth),
++ AV_OPT_TYPE_INT, { .i64 = -1 }, -1, 256, VE },
++
++ { "level", "Set level (level_idc)", OFFSET(level),
++ AV_OPT_TYPE_INT, { .i64 = 0 }, 0, 0xff, VE, "level" },
++
++ { "preset", "Encoding preset [0, 12]",
++ OFFSET(enc_mode), AV_OPT_TYPE_INT, { .i64 = 7 }, 0, 12, VE },
++
++ { "profile", "Profile setting, Main Still Picture Profile not supported", OFFSET(profile),
++ AV_OPT_TYPE_INT, { .i64 = FF_PROFILE_HEVC_MAIN }, FF_PROFILE_HEVC_MAIN, FF_PROFILE_HEVC_REXT, VE, "profile"},
++
++ { "qp", "QP value for intra frames", OFFSET(qp),
++ AV_OPT_TYPE_INT, { .i64 = 32 }, 0, 51, VE },
++
++ { "rc", "Bit rate control mode", OFFSET(rc_mode),
++ AV_OPT_TYPE_INT, { .i64 = 0 }, 0, 1, VE , "rc"},
++ { "cqp", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = 0 }, INT_MIN, INT_MAX, VE, "rc" },
++ { "vbr", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = 1 }, INT_MIN, INT_MAX, VE, "rc" },
++
++ { "sc_detection", "Scene change detection", OFFSET(scd),
++ AV_OPT_TYPE_BOOL, { .i64 = 1 }, 0, 1, VE },
++
++ { "thread_count", "Number of threads [0: Auto, 96: Min]", OFFSET(thread_count),
++ AV_OPT_TYPE_INT, {.i64 = 0}, 0, INT_MAX, VE },
++
++ { "tier", "Set tier (general_tier_flag)", OFFSET(tier),
++ AV_OPT_TYPE_INT, { .i64 = 0 }, 0, 1, VE, "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" },
++
++ { "tune", "Quality tuning mode", OFFSET(tune), AV_OPT_TYPE_INT, { .i64 = 1 }, 0, 2, VE, "tune" },
++ { "sq", "Visually optimized mode", 0,
++ AV_OPT_TYPE_CONST, { .i64 = 0 }, INT_MIN, INT_MAX, VE, "tune" },
++ { "oq", "PSNR / SSIM optimized mode", 0,
++ AV_OPT_TYPE_CONST, { .i64 = 1 }, INT_MIN, INT_MAX, VE, "tune" },
++ { "vmaf", "VMAF optimized mode", 0,
++ AV_OPT_TYPE_CONST, { .i64 = 2 }, INT_MIN, INT_MAX, VE, "tune" },
++
++ {NULL},
++};
++
++static const AVClass class = {
++ .class_name = "libsvt_hevc",
++ .item_name = av_default_item_name,
++ .option = options,
++ .version = LIBAVUTIL_VERSION_INT,
++};
++
++static const AVCodecDefault eb_enc_defaults[] = {
++ { "b", "7M" },
++ { "qmin", "10" },
++ { "qmax", "48" },
++ { "g", "-2" },
++ { NULL },
++};
++
++AVCodec ff_libsvt_hevc_encoder = {
++ .name = "libsvt_hevc",
++ .long_name = NULL_IF_CONFIG_SMALL("SVT-HEVC(Scalable Video Technology for HEVC) encoder"),
++ .priv_data_size = sizeof(SvtContext),
++ .type = AVMEDIA_TYPE_VIDEO,
++ .id = AV_CODEC_ID_HEVC,
++ .init = eb_enc_init,
++ .encode2 = eb_encode_frame,
++ .close = eb_enc_close,
++ .capabilities = AV_CODEC_CAP_DELAY,
++ .pix_fmts = (const enum AVPixelFormat[]){ AV_PIX_FMT_YUV420P,
++ AV_PIX_FMT_YUV420P10,
++ AV_PIX_FMT_YUV422P,
++ AV_PIX_FMT_YUV422P10,
++ AV_PIX_FMT_YUV444P,
++ AV_PIX_FMT_YUV444P10,
++ AV_PIX_FMT_NONE },
++ .priv_class = &class,
++ .defaults = eb_enc_defaults,
++ .caps_internal = FF_CODEC_CAP_INIT_CLEANUP,
++ .wrapper_name = "libsvt_hevc",
++};
+--
+1.8.3.1
+
diff --git a/ffmpeg-full-git-add-svt-hevc-docs-1.4.1.patch b/ffmpeg-full-git-add-svt-hevc-docs-1.4.1.patch
new file mode 100644
index 000000000000..b1e14880b9af
--- /dev/null
+++ b/ffmpeg-full-git-add-svt-hevc-docs-1.4.1.patch
@@ -0,0 +1,198 @@
+From 6b0a4fd63454e3c2185efe741e50e80df5c9a4a4 Mon Sep 17 00:00:00 2001
+From: Jing Sun <jing.a.sun@intel.com>
+Date: Tue, 5 Mar 2019 15:04:58 +0800
+Subject: [PATCH 2/2] doc: Add libsvt_hevc encoder docs
+
+Add docs for libsvt_hevc encoder in encoders.texi and general.texi
+
+Signed-off-by: Jun Zhao <jun.zhao@intel.com>
+Signed-off-by: Zhengxu Huang <zhengxu.huang@intel.com>
+Signed-off-by: Hassene Tmar <hassene.tmar@intel.com>
+Signed-off-by: Jing Sun <jing.a.sun@intel.com>
+---
+ doc/encoders.texi | 149 ++++++++++++++++++++++++++++++++++++++++++++++++++++++
+ doc/general.texi | 8 +++
+ 2 files changed, 157 insertions(+)
+
+diff --git a/doc/encoders.texi b/doc/encoders.texi
+index eefd124..81debda 100644
+--- a/doc/encoders.texi
++++ b/doc/encoders.texi
+@@ -1640,6 +1640,155 @@ Set maximum NAL size in bytes.
+ Allow skipping frames to hit the target bitrate if set to 1.
+ @end table
+
++@section libsvt_hevc
++
++Scalable Video Technology for HEVC (SVT-HEVC) encoder wrapper.
++
++This encoder requires the presence of the headers and
++library during configuration. You need to explicitly configure the
++build with @code{--enable-libsvthevc}. The library is detected using
++@command{pkg-config}.
++
++For more information about the library see
++@url{https://github.com/intel/SVT-HEVC.git}.
++
++@subsection Options
++
++The following FFmpeg global options affect the configurations of the
++libsvt_hevc encoder:
++
++@table @option
++@item b (@emph{bitrate})
++Set the bitrate (as a number of bits per second). Default is 7M.
++
++@item g / @option{gop_size}
++Set the GOP size. Default is -2 (unspecified).
++
++@item flags +cgop
++Enable closed GOP.
++
++@item qmin (@emph{min-q})
++Default is 10
++
++@item qmax (@emph{max-q})
++Default is 48
++
++Set minimum/maximum quantisation values. Valid range is from 0 to 51
++(Only used when bit rate control mode @option{rc} is set to 1(vbr) mode.
++It is required that qmax >= qmin).
++
++@item profile (@emph{profile})
++Set profile restrictions. Can assume one of the following possible values:
++
++@table @samp
++@item main
++main profile
++@item main10
++main10 profile
++@item rext
++rext profile
++@end table
++
++Default is 1 (main).
++
++@item level (@emph{level})
++
++@option{level} sets the value of @emph{level}.
++Set level (level_idc). Default is 0 (to be determined by the encoder).
++
++@end table
++
++The encoder also has its own specific options:
++
++@table @option
++@item aud (@emph{aud})
++Enable use of access unit delimiters when set to 1. Default is 0 (Off).
++
++@item hielevel
++Set hierarchical levels. Can assume one of the following possible values:
++
++@table @samp
++@item flat
++flat more
++@item 1 level
++Minigop size is 2^1
++@item 2 level
++Minigop size is 2^2
++@item 3 level
++Minigop size is 2^3
++@end table
++
++Default is 3 level.
++
++@item la_depth
++Set look-ahead depth, depending on @option{rc}: for @var{vbr}, it's recommended
++to unset it and use the default value (the intra period); for @var{cqp}, better
++specify the look-ahead depth.
++
++The range is @var{-1-256}. Default is -1 (unset and the default value to be used).
++
++@item preset
++Set the quality vs density tradeoff point at which the encoding is to be performed.
++Higher perset value, higher density and lower quality.
++
++The range is @var{0-12}. Default is 9.
++
++@item tier
++Set @emph{general_tier_flag}. This may affect the level chosen for the stream
++if it is not explicitly specified. Can assume one of the following possible values:
++
++@table @samp
++@item main
++main tier
++@item high
++high tier
++@end table
++
++Default is 1 (main).
++
++@item rc
++Set bit rate control mode. Can assume one of the following possible values:
++
++@table @samp
++@item cqp
++Constant QP (CQP) mode
++@item vbr
++Variable Bit Rate (VBR) mode
++@end table
++
++Default is 0 (cqp).
++
++@item forced_idr
++Force keyframes to be IDR if set to >=0 (the value sets headers insertion interval). Default is -1 (CRA).
++
++@item asm_type
++Auto select highest supported asm if set to 1 or C only if 0. Default is 1.
++
++@item qp
++Initial quantization parameter for the intra pictures used when
++@option{rc} is cqp mode. The range is from @var{0-51}. Default is 32.
++
++@item sc_detection
++Enables or disables the scene change detection algorithm. Default is 0 (disabled).
++
++@item tune
++Set quality tuning mode. Can assume one of the following possible values:
++
++@table @samp
++@item sq
++Visually optimized mode
++@item oq
++PSNR / SSIM optimized mode
++@item vmaf
++VMAF optimized mode
++@end table
++
++Default is 1 (oq).
++
++@item bl_mode
++Enables or disables Random Access Prediction. Default is 0 (disabled).
++@end table
++
+ @section libtheora
+
+ libtheora Theora encoder wrapper.
+diff --git a/doc/general.texi b/doc/general.texi
+index 3c0c803..fa9cd31 100644
+--- a/doc/general.texi
++++ b/doc/general.texi
+@@ -243,6 +243,14 @@ FFmpeg can use the OpenJPEG libraries for decoding/encoding J2K videos. Go to
+ instructions. To enable using OpenJPEG in FFmpeg, pass @code{--enable-libopenjpeg} to
+ @file{./configure}.
+
++@section Scalable Video Technology for HEVC
++
++FFmpeg can make use of the SVT-HEVC library for HEVC encoding.
++
++Go to @url{https://github.com/intel/SVT-HEVC.git} and follow the instructions
++for installing the library. Pass @code{--enable-libsvthevc} to configure to
++enable it.
++
+ @section TwoLAME
+
+ FFmpeg can make use of the TwoLAME library for MP2 encoding.
+--
+1.8.3.1
+
diff --git a/ffmpeg-full-git-add-svt-vp9-gce24589.patch b/ffmpeg-full-git-add-svt-vp9-gce24589.patch
new file mode 100644
index 000000000000..cddcd43737c8
--- /dev/null
+++ b/ffmpeg-full-git-add-svt-vp9-gce24589.patch
@@ -0,0 +1,624 @@
+From 7876bb6fa6f782dc283633d00d49cccc436ab89d Mon Sep 17 00:00:00 2001
+From: Jing Sun <jing.a.sun@intel.com>
+Date: Mon, 1 Apr 2019 17:17:00 +0800
+Subject: [PATCH 1/1] Add ability for ffmpeg to run svt vp9 with hevc & av1
+
+Signed-off-by: hassene <hassene.tmar@intel.com>
+Signed-off-by: Jing Sun <jing.a.sun@intel.com>
+---
+ configure | 4 +
+ libavcodec/Makefile | 1 +
+ libavcodec/allcodecs.c | 1 +
+ libavcodec/avcodec.h | 2 +
+ libavcodec/libsvt_vp9.c | 474 ++++++++++++++++++++++++++++++++++++++++++++++++
+ libavformat/ivfenc.c | 34 +++-
+ 6 files changed, 513 insertions(+), 3 deletions(-)
+ create mode 100644 libavcodec/libsvt_vp9.c
+
+diff --git a/configure b/configure
+index 5a54eb4..45f250a 100755
+--- a/configure
++++ b/configure
+@@ -266,6 +266,7 @@ External library support:
+ --enable-libssh enable SFTP protocol via libssh [no]
+ --enable-libsvthevc enable HEVC encoding via svt [no]
+ --enable-libsvtav1 enable AV1 encoding via svt [no]
++ --enable-libsvtvp9 enable VP9 encoding via svt [no]
+ --enable-libtensorflow enable TensorFlow as a DNN module backend
+ for DNN based filters like sr [no]
+ --enable-libtesseract enable Tesseract, needed for ocr filter [no]
+@@ -1788,6 +1789,7 @@ EXTERNAL_LIBRARY_LIST="
+ libssh
+ libsvthevc
+ libsvtav1
++ libsvtvp9
+ libtensorflow
+ libtesseract
+ libtheora
+@@ -3179,6 +3181,7 @@ libspeex_encoder_deps="libspeex"
+ libspeex_encoder_select="audio_frame_queue"
+ libsvt_hevc_encoder_deps="libsvthevc"
+ libsvt_av1_encoder_deps="libsvtav1"
++libsvt_vp9_encoder_deps="libsvtvp9"
+ libtheora_encoder_deps="libtheora"
+ libtwolame_encoder_deps="libtwolame"
+ libvo_amrwbenc_encoder_deps="libvo_amrwbenc"
+@@ -6217,6 +6220,7 @@ enabled libspeex && require_pkg_config libspeex speex speex/speex.h spe
+ enabled libsrt && require_pkg_config libsrt "srt >= 1.3.0" srt/srt.h srt_socket
+ enabled libsvthevc && require_pkg_config libsvthevc SvtHevcEnc EbApi.h EbInitHandle
+ enabled libsvtav1 && require_pkg_config libsvtav1 SvtAv1Enc EbSvtAv1Enc.h eb_init_handle
++enabled libsvtvp9 && require_pkg_config libsvtvp9 SvtVp9Enc EbSvtVp9Enc.h eb_vp9_svt_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
+diff --git a/libavcodec/Makefile b/libavcodec/Makefile
+index dd1b848..cfcd6f0 100644
+--- a/libavcodec/Makefile
++++ b/libavcodec/Makefile
+@@ -989,6 +989,7 @@ OBJS-$(CONFIG_LIBSPEEX_DECODER) += libspeexdec.o
+ OBJS-$(CONFIG_LIBSPEEX_ENCODER) += libspeexenc.o
+ OBJS-$(CONFIG_LIBSVT_HEVC_ENCODER) += libsvt_hevc.o
+ OBJS-$(CONFIG_LIBSVT_AV1_ENCODER) += libsvt_av1.o
++OBJS-$(CONFIG_LIBSVT_VP9_ENCODER) += libsvt_vp9.o
+ OBJS-$(CONFIG_LIBTHEORA_ENCODER) += libtheoraenc.o
+ OBJS-$(CONFIG_LIBTWOLAME_ENCODER) += libtwolame.o
+ OBJS-$(CONFIG_LIBVO_AMRWBENC_ENCODER) += libvo-amrwbenc.o
+diff --git a/libavcodec/allcodecs.c b/libavcodec/allcodecs.c
+index c6c203e..3d20d9c 100644
+--- a/libavcodec/allcodecs.c
++++ b/libavcodec/allcodecs.c
+@@ -705,6 +705,7 @@ extern AVCodec ff_libspeex_encoder;
+ extern AVCodec ff_libspeex_decoder;
+ extern AVCodec ff_libsvt_hevc_encoder;
+ extern AVCodec ff_libsvt_av1_encoder;
++extern AVCodec ff_libsvt_vp9_encoder;
+ extern AVCodec ff_libtheora_encoder;
+ extern AVCodec ff_libtwolame_encoder;
+ extern AVCodec ff_libvo_amrwbenc_encoder;
+diff --git a/libavcodec/avcodec.h b/libavcodec/avcodec.h
+index b749946..1f504af 100644
+--- a/libavcodec/avcodec.h
++++ b/libavcodec/avcodec.h
+@@ -1526,6 +1526,8 @@ typedef struct AVPacket {
+ */
+ #define AV_PKT_FLAG_DISPOSABLE 0x0010
+
++#define AV_PKT_FLAG_SVT_VP9_EXT_ON 0x10000 // Indicating SVT VP9 frame header ext on
++#define AV_PKT_FLAG_SVT_VP9_EXT_OFF 0x20000 // Indicating SVT VP9 frame header ext off
+
+ enum AVSideDataParamChangeFlags {
+ AV_SIDE_DATA_PARAM_CHANGE_CHANNEL_COUNT = 0x0001,
+diff --git a/libavcodec/libsvt_vp9.c b/libavcodec/libsvt_vp9.c
+new file mode 100644
+index 0000000..f7e3bc3
+--- /dev/null
++++ b/libavcodec/libsvt_vp9.c
+@@ -0,0 +1,474 @@
++/*
++* Scalable Video Technology for VP9 encoder library plugin
++*
++* Copyright (c) 2018 Intel Corporation
++*
++* This file is part of FFmpeg.
++*
++* FFmpeg is free software; you can redistribute it and/or
++* modify it under the terms of the GNU Lesser General Public
++* License as published by the Free Software Foundation; either
++* version 2.1 of the License, or (at your option) any later version.
++*
++* FFmpeg is distributed in the hope that it will be useful,
++* but WITHOUT ANY WARRANTY; without even the implied warranty of
++* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
++* Lesser General Public License for more details.
++*
++* You should have received a copy of the GNU Lesser General Public
++* License along with this program; if not, write to the Free Software
++* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
++*/
++
++#include <stdint.h>
++#include "EbSvtVp9ErrorCodes.h"
++#include "EbSvtVp9Time.h"
++#include "EbSvtVp9Enc.h"
++
++#include "libavutil/common.h"
++#include "libavutil/frame.h"
++#include "libavutil/opt.h"
++
++#include "internal.h"
++#include "avcodec.h"
++
++typedef enum eos_status {
++ EOS_NOT_REACHED = 0,
++ EOS_REACHED,
++ EOS_TOTRIGGER
++}EOS_STATUS;
++
++typedef struct SvtContext {
++ AVClass *class;
++
++ EbSvtVp9EncConfiguration enc_params;
++ EbComponentType *svt_handle;
++
++ EbBufferHeaderType *in_buf;
++ int raw_size;
++
++ EOS_STATUS eos_flag;
++
++ // User options.
++ int enc_mode;
++ int rc_mode;
++ int tune;
++ int qp;
++
++ int forced_idr;
++
++ int level;
++
++ int base_layer_switch_mode;
++} SvtContext;
++
++static int error_mapping(EbErrorType svt_ret)
++{
++ int err;
++
++ switch (svt_ret) {
++ case EB_ErrorInsufficientResources:
++ err = AVERROR(ENOMEM);
++ break;
++
++ case EB_ErrorUndefined:
++ case EB_ErrorInvalidComponent:
++ case EB_ErrorBadParameter:
++ err = AVERROR(EINVAL);
++ break;
++
++ case EB_ErrorDestroyThreadFailed:
++ case EB_ErrorSemaphoreUnresponsive:
++ case EB_ErrorDestroySemaphoreFailed:
++ case EB_ErrorCreateMutexFailed:
++ case EB_ErrorMutexUnresponsive:
++ case EB_ErrorDestroyMutexFailed:
++ err = AVERROR_EXTERNAL;
++ break;
++
++ case EB_NoErrorEmptyQueue:
++ err = AVERROR(EAGAIN);
++
++ case EB_ErrorNone:
++ err = 0;
++ break;
++
++ default:
++ err = AVERROR_UNKNOWN;
++ }
++
++ return err;
++}
++
++static void free_buffer(SvtContext *svt_enc)
++{
++ if (svt_enc->in_buf) {
++ EbSvtEncInput *in_data = (EbSvtEncInput *)svt_enc->in_buf->p_buffer;
++ av_freep(&in_data);
++ av_freep(&svt_enc->in_buf);
++ }
++}
++
++static int alloc_buffer(EbSvtVp9EncConfiguration *config, SvtContext *svt_enc)
++{
++ const size_t luma_size_8bit =
++ config->source_width * config->source_height;
++ const size_t luma_size_10bit =
++ (config->encoder_bit_depth > 8) ? luma_size_8bit : 0;
++
++ EbSvtEncInput *in_data;
++
++ svt_enc->raw_size = (luma_size_8bit + luma_size_10bit) * 3 / 2;
++
++ // allocate buffer for in and out
++ svt_enc->in_buf = av_mallocz(sizeof(*svt_enc->in_buf));
++ if (!svt_enc->in_buf)
++ goto failed;
++
++ in_data = av_mallocz(sizeof(*in_data));
++ if (!in_data)
++ goto failed;
++ svt_enc->in_buf->p_buffer = (unsigned char *)in_data;
++
++ svt_enc->in_buf->size = sizeof(*svt_enc->in_buf);
++ svt_enc->in_buf->p_app_private = NULL;
++
++ return 0;
++
++failed:
++ free_buffer(svt_enc);
++ return AVERROR(ENOMEM);
++}
++
++static int config_enc_params(EbSvtVp9EncConfiguration *param,
++ AVCodecContext *avctx)
++{
++ SvtContext *svt_enc = avctx->priv_data;
++ int ret;
++ int ten_bits = 0;
++
++ param->source_width = avctx->width;
++ param->source_height = avctx->height;
++
++ if (avctx->pix_fmt == AV_PIX_FMT_YUV420P10LE) {
++ av_log(avctx, AV_LOG_DEBUG , "Encoder 10 bits depth input\n");
++ // Disable Compressed 10-bit format default
++ ten_bits = 1;
++ }
++
++ // Update param from options
++ param->enc_mode = svt_enc->enc_mode;
++ param->level = svt_enc->level;
++ param->rate_control_mode = svt_enc->rc_mode;
++ param->tune = svt_enc->tune;
++ param->base_layer_switch_mode = svt_enc->base_layer_switch_mode;
++ param->qp = svt_enc->qp;
++
++ param->target_bit_rate = avctx->bit_rate;
++ if (avctx->gop_size > 0)
++ param->intra_period = 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 * avctx->ticks_per_frame;
++ } else {
++ param->frame_rate_numerator = avctx->time_base.den;
++ param->frame_rate_denominator = avctx->time_base.num * avctx->ticks_per_frame;
++ }
++
++ if (param->rate_control_mode) {
++ param->max_qp_allowed = avctx->qmax;
++ param->min_qp_allowed = avctx->qmin;
++ }
++
++ param->intra_refresh_type =
++ !!(avctx->flags & AV_CODEC_FLAG_CLOSED_GOP) + 1;
++
++ if (ten_bits) {
++ param->encoder_bit_depth = 10;
++ }
++
++ ret = alloc_buffer(param, svt_enc);
++
++ return ret;
++}
++
++static void read_in_data(EbSvtVp9EncConfiguration *config,
++ const AVFrame *frame,
++ EbBufferHeaderType *headerPtr)
++{
++ uint8_t is16bit = config->encoder_bit_depth > 8;
++ uint64_t luma_size =
++ (uint64_t)config->source_width * config->source_height<< is16bit;
++ EbSvtEncInput *in_data = (EbSvtEncInput *)headerPtr->p_buffer;
++
++ // support yuv420p and yuv420p010
++ in_data->luma = frame->data[0];
++ in_data->cb = frame->data[1];
++ in_data->cr = frame->data[2];
++
++ // stride info
++ in_data->y_stride = frame->linesize[0] >> is16bit;
++ in_data->cb_stride = frame->linesize[1] >> is16bit;
++ in_data->cr_stride = frame->linesize[2] >> is16bit;
++
++ headerPtr->n_filled_len += luma_size * 3/2u;
++}
++
++static av_cold int eb_enc_init(AVCodecContext *avctx)
++{
++ SvtContext *svt_enc = avctx->priv_data;
++ EbErrorType svt_ret;
++
++ svt_enc->eos_flag = EOS_NOT_REACHED;
++
++ svt_ret = eb_vp9_svt_init_handle(&svt_enc->svt_handle, svt_enc, &svt_enc->enc_params);
++ if (svt_ret != EB_ErrorNone) {
++ av_log(avctx, AV_LOG_ERROR, "Error init encoder handle\n");
++ goto failed;
++ }
++
++ svt_ret = config_enc_params(&svt_enc->enc_params, avctx);
++ if (svt_ret != EB_ErrorNone) {
++ av_log(avctx, AV_LOG_ERROR, "Error configure encoder parameters\n");
++ goto failed_init_handle;
++ }
++
++ svt_ret = eb_vp9_svt_enc_set_parameter(svt_enc->svt_handle, &svt_enc->enc_params);
++ if (svt_ret != EB_ErrorNone) {
++ av_log(avctx, AV_LOG_ERROR, "Error setting encoder parameters\n");
++ goto failed_init_handle;
++ }
++
++ svt_ret = eb_vp9_init_encoder(svt_enc->svt_handle);
++ if (svt_ret != EB_ErrorNone) {
++ av_log(avctx, AV_LOG_ERROR, "Error init encoder\n");
++ goto failed_init_handle;
++ }
++
++ // if (avctx->flags & AV_CODEC_FLAG_GLOBAL_HEADER) {
++ // EbBufferHeaderType* headerPtr;
++ // headerPtr->size = sizeof(headerPtr);
++ // headerPtr->n_filled_len = 0; /* in/out */
++ // headerPtr->p_buffer = av_malloc(10 * 1024 * 1024);
++ // headerPtr->n_alloc_len = (10 * 1024 * 1024);
++ //
++ // if (!headerPtr->p_buffer) {
++ // av_log(avctx, AV_LOG_ERROR,
++ // "Cannot allocate buffer size %d.\n", headerPtr->n_alloc_len);
++ // svt_ret = EB_ErrorInsufficientResources;
++ // goto failed_init_enc;
++ // }
++ //
++ // svt_ret = eb_svt_enc_stream_header(svt_enc->svt_handle, &headerPtr);
++ // if (svt_ret != EB_ErrorNone) {
++ // av_log(avctx, AV_LOG_ERROR, "Error when build stream header.\n");
++ // av_freep(&headerPtr->p_buffer);
++ // goto failed_init_enc;
++ // }
++ //
++ // avctx->extradata_size = headerPtr->n_filled_len;
++ // avctx->extradata = av_mallocz(avctx->extradata_size + AV_INPUT_BUFFER_PADDING_SIZE);
++ // if (!avctx->extradata) {
++ // av_log(avctx, AV_LOG_ERROR,
++ // "Cannot allocate VP9 header of size %d.\n", avctx->extradata_size);
++ // av_freep(&headerPtr->p_buffer);
++ // svt_ret = EB_ErrorInsufficientResources;
++ // goto failed_init_enc;
++ // }
++ // memcpy(avctx->extradata, headerPtr->p_buffer, avctx->extradata_size);
++ //
++ // av_freep(&headerPtr->p_buffer);
++ // }
++ return 0;
++
++//failed_init_enc:
++// eb_deinit_encoder(svt_enc->svt_handle);
++failed_init_handle:
++ eb_vp9_deinit_handle(svt_enc->svt_handle);
++failed:
++ free_buffer(svt_enc);
++ return error_mapping(svt_ret);
++}
++
++static int eb_send_frame(AVCodecContext *avctx, const AVFrame *frame)
++{
++ SvtContext *svt_enc = avctx->priv_data;
++ EbBufferHeaderType *headerPtr = svt_enc->in_buf;
++
++ if (!frame) {
++ EbBufferHeaderType headerPtrLast;
++ headerPtrLast.n_alloc_len = 0;
++ headerPtrLast.n_filled_len = 0;
++ headerPtrLast.n_tick_count = 0;
++ headerPtrLast.p_app_private = NULL;
++ headerPtrLast.p_buffer = NULL;
++ headerPtrLast.flags = EB_BUFFERFLAG_EOS;
++
++ eb_vp9_svt_enc_send_picture(svt_enc->svt_handle, &headerPtrLast);
++ svt_enc->eos_flag = EOS_REACHED;
++ av_log(avctx, AV_LOG_DEBUG, "Finish sending frames!!!\n");
++ return 0;
++ }
++
++ read_in_data(&svt_enc->enc_params, frame, headerPtr);
++
++ headerPtr->flags = 0;
++ headerPtr->p_app_private = NULL;
++ headerPtr->pts = frame->pts;
++ switch (frame->pict_type) {
++ case AV_PICTURE_TYPE_I:
++ headerPtr->pic_type = svt_enc->forced_idr > 0 ? EB_IDR_PICTURE : EB_I_PICTURE;
++ break;
++ case AV_PICTURE_TYPE_P:
++ headerPtr->pic_type = EB_P_PICTURE;
++ break;
++ case AV_PICTURE_TYPE_B:
++ headerPtr->pic_type = EB_B_PICTURE;
++ break;
++ default:
++ headerPtr->pic_type = EB_INVALID_PICTURE;
++ break;
++ }
++ eb_vp9_svt_enc_send_picture(svt_enc->svt_handle, headerPtr);
++
++ return 0;
++}
++
++static int eb_receive_packet(AVCodecContext *avctx, AVPacket *pkt)
++{
++ SvtContext *svt_enc = avctx->priv_data;
++ EbBufferHeaderType *headerPtr;
++ EbErrorType svt_ret;
++ int ret;
++
++ if (EOS_TOTRIGGER == svt_enc->eos_flag) {
++ pkt = NULL;
++ return AVERROR_EOF;
++ }
++
++ svt_ret = eb_vp9_svt_get_packet(svt_enc->svt_handle, &headerPtr, svt_enc->eos_flag);
++ if (svt_ret == EB_NoErrorEmptyQueue)
++ return AVERROR(EAGAIN);
++
++ if ((ret = ff_alloc_packet2(avctx, pkt, headerPtr->n_filled_len, 0)) < 0) {
++ av_log(avctx, AV_LOG_ERROR, "Failed to allocate output packet.\n");
++ return ret;
++ }
++
++ memcpy(pkt->data, headerPtr->p_buffer, headerPtr->n_filled_len);
++ pkt->size = headerPtr->n_filled_len;
++ pkt->pts = headerPtr->pts;
++ pkt->dts = headerPtr->dts;
++ if (headerPtr->pic_type == EB_IDR_PICTURE)
++ pkt->flags |= AV_PKT_FLAG_KEY;
++ if (headerPtr->pic_type == EB_NON_REF_PICTURE)
++ pkt->flags |= AV_PKT_FLAG_DISPOSABLE;
++
++ if (headerPtr->flags & EB_BUFFERFLAG_SHOW_EXT)
++ pkt->flags |= AV_PKT_FLAG_SVT_VP9_EXT_ON;
++ else
++ pkt->flags |= AV_PKT_FLAG_SVT_VP9_EXT_OFF;
++
++ if (EB_BUFFERFLAG_EOS == headerPtr->flags)
++ svt_enc->eos_flag = EOS_TOTRIGGER;
++
++ eb_vp9_svt_release_out_buffer(&headerPtr);
++ return 0;
++}
++
++static av_cold int eb_enc_close(AVCodecContext *avctx)
++{
++ SvtContext *svt_enc = avctx->priv_data;
++
++ eb_vp9_deinit_encoder(svt_enc->svt_handle);
++ eb_vp9_deinit_handle(svt_enc->svt_handle);
++
++ free_buffer(svt_enc);
++
++ return 0;
++}
++
++#define OFFSET(x) offsetof(SvtContext, x)
++#define VE AV_OPT_FLAG_VIDEO_PARAM | AV_OPT_FLAG_ENCODING_PARAM
++static const AVOption options[] = {
++ { "preset", "Encoding preset [1, 1]",
++ OFFSET(enc_mode), AV_OPT_TYPE_INT, { .i64 = 9 }, 0, 9, VE },
++
++ { "level", "Set level (level_idc)", OFFSET(level),
++ AV_OPT_TYPE_INT, { .i64 = 0 }, 0, 0xff, VE, "level" },
++
++#define LEVEL(name, value) name, NULL, 0, AV_OPT_TYPE_CONST, \
++ { .i64 = value }, 0, 0, VE, "level"
++ { LEVEL("1", 10) },
++ { LEVEL("2", 20) },
++ { LEVEL("2.1", 21) },
++ { LEVEL("3", 30) },
++ { LEVEL("3.1", 31) },
++ { LEVEL("4", 40) },
++ { LEVEL("4.1", 41) },
++ { LEVEL("5", 50) },
++ { LEVEL("5.1", 51) },
++ { LEVEL("5.2", 52) },
++ { LEVEL("6", 60) },
++ { LEVEL("6.1", 61) },
++ { LEVEL("6.2", 62) },
++#undef LEVEL
++
++ { "tune", "Tune mode", OFFSET(tune),
++ AV_OPT_TYPE_INT, { .i64 = 0 }, 0, 2, VE , "tune"},
++ { "vq", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = 0 }, INT_MIN, INT_MAX, VE, "tune" },
++ { "ssim", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = 1 }, INT_MIN, INT_MAX, VE, "tune" },
++ { "vmaf", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = 2 }, INT_MIN, INT_MAX, VE, "tune" },
++
++ { "rc", "Bit rate control mode", OFFSET(rc_mode),
++ AV_OPT_TYPE_INT, { .i64 = 0 }, 0, 2, VE , "rc"},
++ { "cqp", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = 0 }, INT_MIN, INT_MAX, VE, "rc" },
++ { "vbr", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = 1 }, INT_MIN, INT_MAX, VE, "rc" },
++ { "cbr", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = 2 }, INT_MIN, INT_MAX, VE, "rc" },
++
++ { "qp", "QP value for intra frames", OFFSET(qp),
++ AV_OPT_TYPE_INT, { .i64 = 32 }, 0, 51, VE },
++
++ { "bl_mode", "Random Access Prediction Structure type setting", OFFSET(base_layer_switch_mode),
++ AV_OPT_TYPE_BOOL, { .i64 = 0 }, 0, 1, VE },
++
++ { "forced-idr", "If forcing keyframes, force them as IDR frames.", OFFSET(forced_idr),
++ AV_OPT_TYPE_BOOL, { .i64 = 0 }, -1, 1, VE },
++
++ {NULL},
++};
++
++static const AVClass class = {
++ .class_name = "libsvt_vp9",
++ .item_name = av_default_item_name,
++ .option = options,
++ .version = LIBAVUTIL_VERSION_INT,
++};
++
++static const AVCodecDefault eb_enc_defaults[] = {
++ { "b", "7M" },
++ { "flags", "-cgop" },
++ { "qmin", "10" },
++ { "qmax", "48" },
++ { NULL },
++};
++
++AVCodec ff_libsvt_vp9_encoder = {
++ .name = "libsvt_vp9",
++ .long_name = NULL_IF_CONFIG_SMALL("SVT-VP9(Scalable Video Technology for VP9) encoder"),
++ .priv_data_size = sizeof(SvtContext),
++ .type = AVMEDIA_TYPE_VIDEO,
++ .id = AV_CODEC_ID_VP9,
++ .init = eb_enc_init,
++ .send_frame = eb_send_frame,
++ .receive_packet = eb_receive_packet,
++ .close = eb_enc_close,
++ .capabilities = AV_CODEC_CAP_DELAY | AV_CODEC_CAP_AUTO_THREADS,
++ .pix_fmts = (const enum AVPixelFormat[]){ AV_PIX_FMT_YUV420P,
++ AV_PIX_FMT_NONE },
++ .priv_class = &class,
++ .defaults = eb_enc_defaults,
++ .caps_internal = FF_CODEC_CAP_INIT_CLEANUP,
++ .wrapper_name = "libsvt_vp9",
++};
+diff --git a/libavformat/ivfenc.c b/libavformat/ivfenc.c
+index adf7211..05f0813 100644
+--- a/libavformat/ivfenc.c
++++ b/libavformat/ivfenc.c
+@@ -63,9 +63,33 @@ static int ivf_write_packet(AVFormatContext *s, AVPacket *pkt)
+ AVIOContext *pb = s->pb;
+ IVFEncContext *ctx = s->priv_data;
+
+- avio_wl32(pb, pkt->size);
+- avio_wl64(pb, pkt->pts);
+- avio_write(pb, pkt->data, pkt->size);
++ if (pkt->flags & AV_PKT_FLAG_SVT_VP9_EXT_ON) {
++ avio_wl32(pb, pkt->size - 4);
++ avio_wl64(pb, pkt->pts);
++ avio_write(pb, pkt->data, pkt->size - 4);
++
++ avio_wl32(pb, 1);
++ avio_wl64(pb, pkt->pts - 2);
++ avio_write(pb, pkt->data + pkt->size - 4, 1);
++
++ avio_wl32(pb, 1);
++ avio_wl64(pb, pkt->pts - 1);
++ avio_write(pb, pkt->data + pkt->size - 3, 1);
++
++ avio_wl32(pb, 1);
++ avio_wl64(pb, pkt->pts);
++ avio_write(pb, pkt->data + pkt->size - 2, 1);
++
++ avio_wl32(pb, 1);
++ avio_wl64(pb, pkt->pts + 1);
++ avio_write(pb, pkt->data + pkt->size - 1, 1);
++ }
++ else {
++ avio_wl32(pb, pkt->size);
++ avio_wl64(pb, pkt->pts);
++ avio_write(pb, pkt->data, pkt->size);
++ }
++
+ if (ctx->frame_cnt)
+ ctx->sum_delta_pts += pkt->pts - ctx->last_pts;
+ ctx->frame_cnt++;
+@@ -95,6 +119,10 @@ static int ivf_check_bitstream(struct AVFormatContext *s, const AVPacket *pkt)
+ int ret = 1;
+ AVStream *st = s->streams[pkt->stream_index];
+
++ if ((pkt->flags & AV_PKT_FLAG_SVT_VP9_EXT_ON) ||
++ (pkt->flags & AV_PKT_FLAG_SVT_VP9_EXT_OFF))
++ return 0;
++
+ if (st->codecpar->codec_id == AV_CODEC_ID_VP9)
+ ret = ff_stream_add_bitstream_filter(st, "vp9_superframe", NULL);
+ else if (st->codecpar->codec_id == AV_CODEC_ID_AV1)
+--
+1.8.3.1