Compare commits

...

18 Commits

Author SHA1 Message Date
Michael Fabian 'Xaymar' Dirks 4c09db4eac ci: Add patch for updated AMF 2022-01-13 00:16:44 +01:00
Michael Fabian 'Xaymar' Dirks e13759d272 ci: Use hidden .env file to store environmental updates 2022-01-10 01:29:48 +01:00
Michael Fabian 'Xaymar' Dirks a2e7cca590 ci: Figure out why scripts aren't working right 2022-01-10 01:12:45 +01:00
Michael Fabian 'Xaymar' Dirks f2e7cd16c5 ci: Add AOM 2022-01-10 00:52:47 +01:00
Michael Fabian 'Xaymar' Dirks 9a0470f317 ci: Add libx264 2022-01-10 00:42:01 +01:00
Michael Fabian 'Xaymar' Dirks d99e9e9c74 ci: Add zLib 2022-01-10 00:41:44 +01:00
Michael Fabian 'Xaymar' Dirks ba8761110f ci: Always use twice the "ideal" amount of threads 2022-01-10 00:31:30 +01:00
Michael Fabian 'Xaymar' Dirks 8adf994e36 ci: Don't limit parallel builds 2022-01-10 00:31:30 +01:00
Michael Fabian 'Xaymar' Dirks be09d8675e ci: Add NVIDIA NVENC 2022-01-10 00:31:30 +01:00
Michael Fabian 'Xaymar' Dirks 8aa7731030 ci: Fix uploaded file names 2022-01-10 00:31:30 +01:00
Michael Fabian 'Xaymar' Dirks e357430b22 ci: Add AMD AMF v1.4.23 2022-01-10 00:31:19 +01:00
Michael Fabian 'Xaymar' Dirks 5c9a68281a ci: Move to a script based system for easier local repro
Also limit parallel execution of automation commands so they don't break each other randomly.
2022-01-10 00:31:19 +01:00
Michael Fabian 'Xaymar' Dirks aef6bb2532 ci: Let FFmpeg figure things out by itself 2022-01-10 00:29:26 +01:00
Michael Fabian 'Xaymar' Dirks c8a19476c0 patches: Remove incompatible patch from master 2022-01-10 00:29:23 +01:00
Michael Fabian 'Xaymar' Dirks 1394ca0edb ci: Add AOM and improve some dependencies 2022-01-10 00:29:23 +01:00
Michael Fabian 'Xaymar' Dirks 64daba4a66 ci: x264 0.161.3049 -> 0.163.3060 2021-09-07 18:29:38 +02:00
Michael Fabian 'Xaymar' Dirks 3cfe4b67a2 ci: Use matrix instead of parameter for patches
The matrix build type can take care of most if not all optional configurations, so there is no point in having this as an argument. In any case we'd want both normal and patched builds anyway.
2021-05-23 22:28:20 +02:00
Michael Fabian 'Xaymar' Dirks 8a11745d31 ci: Prefer pre-built zlib-ng 2021-05-23 22:24:11 +02:00
24 changed files with 1233 additions and 389 deletions
+62 -222
View File
@@ -6,137 +6,48 @@ on:
description: 'Branch, Tag or Commit to build' description: 'Branch, Tag or Commit to build'
required: false required: false
default: 'master' default: 'master'
apply_patches:
description: 'Apply custom patches (Boolean)'
required: false
default: false
env: env:
X264_VERSION: "0.161.3049" AMDAMF_VERSION: "v1.4.23"
FFNVCODEC_VERSION: "n11.0.10.0" AOM_VERSION: "v3.1.2.115"
AMF_VERSION: "v1.4.18" MINGW_VERSION: "v9.0.0"
ZLIB_NG_VERSION: "2.0.3" NVIDIANVENC_VERSION: "n11.0.10.0"
X264_VERSION: "0.163.3060"
ZLIB_VERSION: "2.0.3"
jobs: jobs:
cc: cc:
runs-on: ubuntu-20.04 runs-on: ubuntu-20.04
strategy: strategy:
matrix: matrix:
license_version: [ 3, 2 ] license: [ "LGPL", "GPL" ]
license: [ "GPL", "LGPL" ] license_version: [ 2, 3 ]
type: [ "shared" ] type: [ "shared" ]
bits: [ 64 ] bits: [ 64 ]
name: "Windows (${{ matrix.bits }}bit, ${{ matrix.type }}, ${{ matrix.license }}v${{ matrix.license_version}})" patches: [ false, true ]
name: "Windows (${{ matrix.bits }}bit, ${{ matrix.type }}, ${{ matrix.license }}v${{ matrix.license_version}}, patched=${{ matrix.patches }})"
env:
BUILD_TYPE: ${{ matrix.type }}
BUILD_BITS: ${{ matrix.bits }}
LICENSE: ${{ matrix.license }}
LICENSE_VERSION: ${{ matrix.license_version }}
SCRIPTROOT: "/tmp"
steps: steps:
- name: "automation: Check out" - name: "automation: Check-out"
uses: actions/checkout@v2 uses: actions/checkout@v2
with: with:
submodules: "recursive" submodules: "recursive"
fetch-depth: 0 fetch-depth: 1
- name: "automation: Copy patches to safe directory" - name: "automation: Copy things to safety"
if: ${{ github.event.inputs.apply_patches == 'true' }}
shell: bash shell: bash
run: | run: |
if [[ -d ./patches ]]; then # Copy important scripts to "safe" directory".
cp -a ./patches /tmp/ cp -R -f ./patches ${SCRIPTROOT}/patches
fi cp -R -f ./scripts ${SCRIPTROOT}/scripts
chmod +x ${SCRIPTROOT}/scripts/*.sh
- name: "automation: Gather Information" cp -R -f ./addons ${SCRIPTROOT}/addons
id: data chmod +x ${SCRIPTROOT}/addons/*.sh
shell: bash
run: |
# Bitness
if [ "${{ matrix.bits }}" == "32" ]; then
echo "::set-output name=arch::i686"
echo "::set-output name=target_os::mingw32"
echo "::set-output name=cross_prefix::i686-w64-mingw32"
else
echo "::set-output name=arch::x86_64"
echo "::set-output name=target_os::mingw64"
echo "::set-output name=cross_prefix::x86_64-w64-mingw32"
fi
# License (GPL vs LGPL, v2 vs v3)
if [ "${{ matrix.license }}" == "GPL" ]; then
echo "::set-output name=flags_license::--enable-gpl"
fi
if [ "${{ matrix.license_version }}" == "3" ]; then
echo "::set-output name=flags_license_version::--enable-version3"
fi
# Build Type
if [ "${{ matrix.type }}" == "static" ]; then
echo "::set-output name=flags_type::--enable-static --disable-shared"
else
echo "::set-output name=flags_type::--disable-static --enable-shared"
fi
- name: "ffmpeg: Check out ${{ github.event.inputs.ref }}"
uses: actions/checkout@v2
with:
ref: "${{ github.event.inputs.ref }}"
submodules: "recursive"
fetch-depth: 0
- name: "automation: Detect version (and apply patches if necessary)"
id: version
shell: bash
run: |
# Detect Major.Minor.Patch version
VERSION=( $(cat RELEASE | sed -E 's/\./ /gi') )
VERSION_MAJOR=${VERSION[0]}
VERSION_MINOR=${VERSION[1]}
if (( ${#VERSION[@]} == 3 )); then
VERSION_PATCH=${VERSION[2]}
else
VERSION_PATCH=0
fi
COMMIT="$(git rev-parse --short=8 HEAD)"
echo "FFmpeg v${VERSION_MAJOR}.${VERSION_MINOR}.${VERSION_PATCH}-${COMMIT}"
# Apply available patches
if [[ "${{ github.event.inputs.apply_patches}}" == "true" ]]; then
echo "Applying custom patches:"
declare -a PATCHES
if [[ "${{ github.event.inputs.ref }}" == "master" ]]; then
PATCHES[${#PATCHES[@]}]="master"
else
PATCHES[${#PATCHES[@]}]="${VERSION_MAJOR}.${VERSION_MINOR}.${VERSION_PATCH}"
PATCHES[${#PATCHES[@]}]="${VERSION_MAJOR}.${VERSION_MINOR}"
PATCHES[${#PATCHES[@]}]="${VERSION_MAJOR}"
fi
for p in ${PATCHES[@]}; do
if [[ -d "/tmp/patches/${p}" ]]; then
echo " Found patches for ${p}:"
for f in /tmp/patches/${p}/*.patch; do
echo " ${f}..."
[ -e "$f" ] || continue
git apply "$f"
done
else
echo " No patches for ${p}."
fi
done
VERSION_PATCH="${VERSION_PATCH}.patched"
fi
# Set Outputs
echo "::set-output name=major::${VERSION_MAJOR}"
echo "::set-output name=minor::${VERSION_MINOR}"
echo "::set-output name=patch::${VERSION_PATCH}"
echo "::set-output name=commit::${COMMIT}"
# Create distrib directory
mkdir distrib
mkdir distrib/bin
mkdir distrib/lib
mkdir distrib/include
mkdir distrib/share
- name: "dependency: cmake, make, pkg-config, mingw, nasm" - name: "dependency: cmake, make, pkg-config, mingw, nasm"
shell: bash shell: bash
@@ -147,124 +58,53 @@ jobs:
cmake make ninja-build \ cmake make ninja-build \
pkg-config \ pkg-config \
mingw-w64 mingw-w64-tools gcc-mingw-w64 g++-mingw-w64 \ mingw-w64 mingw-w64-tools gcc-mingw-w64 g++-mingw-w64 \
nasm nasm
# zlib-ng - name: "ffmpeg: Check out '${{ github.event.inputs.ref }}'"
- name: "dependency: zlib (zlib-ng v${{ env.ZLIB_NG_VERSION }}, Zlib license, shared)" uses: actions/checkout@v2
id: zlib with:
ref: "${{ github.event.inputs.ref }}"
submodules: "recursive"
fetch-depth: 0
- name: "automation: Bootstrap"
id: bootstrap
shell: bash shell: bash
run: | run: |
git clone --depth 1 --branch ${ZLIB_NG_VERSION} "https://github.com/zlib-ng/zlib-ng" /tmp/zlib-ng . ${SCRIPTROOT}/addons/bootstrap.sh
pushd "/tmp/zlib-ng" > /dev/null echo "FFmpeg v${VERSION_MAJOR}.${VERSION_MINOR}.${VERSION_PATCH}.${VERSION_TWEAK}-${COMMIT}"
cmake -H. -Bbuild/build \
-DCMAKE_TOOLCHAIN_FILE=./cmake/toolchain-mingw-${{ steps.data.outputs.arch }}.cmake \
-DCMAKE_BUILD_TYPE=RELEASE -DZLIB_COMPAT=ON -DZLIB_ENABLE_TESTS=OFF -DBUILD_SHARED_LIBS=ON \
-DCMAKE_INSTALL_PREFIX=./build/distrib/
cmake --build build/build --target install
pushd "./build/distrib" > /dev/null
# Fix ZLIB_COMPAT=ON still adding a suffix.
cp ./lib/libzlib.dll.a ./lib/libz.dll.a
# Generate MSVC compatible .lib file - name: "automation: Apply Patches"
gendef - ./bin/libzlib1.dll > ./lib/libzlib.def if: ${{ (matrix.patches == true) }}
${{ steps.data.outputs.cross_prefix }}-dlltool -d ./lib/libzlib.def -l ./lib/libzlib.lib id: patch
cp ./lib/libzlib.lib ./lib/libz.lib env:
popd > /dev/null VERSION_MAJOR: ${{ steps.bootstrap.outputs.VERSION_MAJOR }}
popd > /dev/null VERSION_MINOR: ${{ steps.bootstrap.outputs.VERSION_MINOR }}
sudo cp -a /tmp/zlib-ng/build/distrib/. /usr/${{ steps.data.outputs.cross_prefix }} VERSION_PATCH: ${{ steps.bootstrap.outputs.VERSION_PATCH }}
cp -a /tmp/zlib-ng/build/distrib/bin/*.dll ./distrib/bin/ VERSION_TWEAK: ${{ steps.bootstrap.outputs.VERSION_TWEAK }}
COMMIT: ${{ steps.bootstrap.outputs.COMMIT }}
# libx264 (FFmpeg 0.5 and up, arbitrarily limited to 1.0 because I'm lazy)
- name: "dependency: x264 v${{ env.X264_VERSION }} (GPLv2, shared)"
if: ${{ (steps.version.outputs.major >= 1) && startsWith(matrix.license, 'GPL') }}
id: x264
shell: bash shell: bash
run: | run: |
curl -L -o "/tmp/x264.zip" "https://github.com/Xaymar/x264/releases/download/${X264_VERSION}/x264-${{ matrix.bits }}-shared-GPLv2.zip" . ${SCRIPTROOT}/addons/patch.sh
7z x -o/tmp/x264/ "/tmp/x264.zip" echo "::set-output name=name::-patched"
sudo cp -a /tmp/x264/. /usr/${{ steps.data.outputs.cross_prefix }}/
cp -a /tmp/x264/bin/*.dll ./distrib/bin/
echo "::set-output name=flags::--enable-libx264"
# NVIDIA Codec Headers (FFmpeg 3.0 and up) - name: "automation: Run scripts"
- name: "dependency: NVIDIA Codec Headers v${{ env.FFNVCODEC_VERSION }} (MIT, shared)" env:
if: ${{ steps.version.outputs.major >= 3 }} VERSION_MAJOR: ${{ steps.bootstrap.outputs.VERSION_MAJOR }}
id: ffnvcodec VERSION_MINOR: ${{ steps.bootstrap.outputs.VERSION_MINOR }}
VERSION_PATCH: ${{ steps.bootstrap.outputs.VERSION_PATCH }}
VERSION_TWEAK: ${{ steps.bootstrap.outputs.VERSION_TWEAK }}
COMMIT: ${{ steps.bootstrap.outputs.COMMIT }}
BUILD_ARCH: ${{ steps.bootstrap.outputs.BUILD_ARCH }}
BUILD_TARGET: ${{ steps.bootstrap.outputs.BUILD_TARGET }}
BUILD_PREFIX: ${{ steps.bootstrap.outputs.BUILD_PREFIX }}
BUILD_FLAGS: ${{ steps.bootstrap.outputs.BUILD_FLAGS }}
shell: bash shell: bash
run: | run: |
git clone --depth 1 --branch ${FFNVCODEC_VERSION} "https://git.videolan.org/git/ffmpeg/nv-codec-headers.git" /tmp/nv-codec-headers . ${SCRIPTROOT}/addons/run.sh
pushd "/tmp/nv-codec-headers" > /dev/null
make PREFIX=/usr/${{ steps.data.outputs.cross_prefix }}
sudo make PREFIX=/usr/${{ steps.data.outputs.cross_prefix }} install
popd > /dev/null
if (( "${{ steps.version.outputs.major }}" >= 4 )); then
echo "::set-output name=flags::--enable-ffnvcodec --enable-nvdec --enable-cuvid --enable-nvenc"
elif (( "${{ steps.version.outputs.major }}" >= 3 )); then
if (( "${{ steps.version.outputs.minor }}" >= 2 )); then
# 3.2+ has cuda, cuvid, nvenc
echo "::set-output name=flags::--enable-cuvid --enable-nvenc"
elif (( "${{ steps.version.outputs.minor }}" >= 1 )); then
# 3.1 has cuda, nvenc
echo "::set-output name=flags::--enable-nvenc"
elif (( "${{ steps.version.outputs.minor }}" >= 0 )); then
# 3.0 has nvenc
echo "::set-output name=flags::--enable-nvenc"
fi
fi
# AMD AMF (FFmpeg 4.0 and up)
- name: "dependency: AMD AMF (v${{ env.AMF_VERSION }}, MIT, shared)"
if: ${{ steps.version.outputs.major >= 4 }}
id: amf
shell: bash
run: |
git clone --depth 1 --branch ${AMF_VERSION} "https://github.com/GPUOpen-LibrariesAndSDKs/AMF.git" /tmp/amd-amf
pushd "/tmp/amd-amf"
sudo cp -R amf/public/include/ /usr/${{ steps.data.outputs.cross_prefix }}/include/AMF
popd
if (( "${{ steps.version.outputs.major }}" >= 4 )); then
echo "::set-output name=flags::--enable-amf"
fi
# Configure FFmpeg
- name: "ffmpeg: Configure"
shell: bash
run: |
export PKG_CONFIG_PATH=/usr/${{ steps.data.outputs.cross_prefix }}/lib/pkgconfig:${PKG_CONFIG_PATH}
./configure \
--arch=${{ steps.data.outputs.arch }} \
--target-os=${{ steps.data.outputs.target_os }} \
--cross-prefix=${{ steps.data.outputs.cross_prefix }}- \
--prefix="${{ github.workspace }}/distrib" \
--bindir="${{ github.workspace }}/distrib/bin" \
--libdir="${{ github.workspace }}/distrib/lib" \
--shlibdir="${{ github.workspace }}/distrib/bin" \
--pkg-config=pkg-config \
--extra-cflags=-O3 --extra-cflags=-mmmx --extra-cflags=-msse --extra-cflags=-msse2 --extra-cflags=-msse3 --extra-cflags=-mssse3 \
--extra-cflags=-msse4.1 --extra-cflags=-msse4.2 --extra-cflags=-mavx --extra-cflags=-maes --extra-cflags=-mpclmul \
--pkg-config=pkg-config \
${{ steps.data.outputs.flags_license }} ${{ steps.data.outputs.flags_license_version }} \
${{ steps.data.outputs.flags_type }} \
${{ steps.x264.outputs.flags }} \
${{ steps.ffnvcodec.outputs.flags }} \
${{ steps.amf.outputs.flags }}
- name: "ffmpeg: Compile"
shell: bash
run: |
make -j 4
- name: "ffmpeg: Install"
shell: bash
run: |
make install
# Move .lib files which are in the wrong place.
mv ./distrib/bin/*.lib ./distrib/lib/
- name: "automation: Upload Artifacts" - name: "automation: Upload Artifacts"
uses: actions/upload-artifact@v1 uses: actions/upload-artifact@v1
with: with:
name: ffmpeg-${{ matrix.bits }}-${{ matrix.type }}-${{ matrix.license }}v${{ matrix.license_version }}-${{ steps.version.outputs.major }}.${{ steps.version.outputs.minor }}.${{ steps.version.outputs.patch }}-${{ steps.version.outputs.commit }} name: "ffmpeg-${{ matrix.license }}v${{ matrix.license_version }}-${{ matrix.bits}}-${{ matrix.type }}-${{ steps.bootstrap.outputs.VERSION_MAJOR }}.${{ steps.bootstrap.outputs.VERSION_MINOR }}.${{ steps.bootstrap.outputs.VERSION_PATCH }}.${{ steps.bootstrap.outputs.VERSION_TWEAK }}-${{ steps.bootstrap.outputs.COMMIT }}${{ steps.patch.outputs.name }}"
path: distrib path: distrib
+4 -19
View File
@@ -7,6 +7,10 @@ on:
- 'automation' - 'automation'
- 'automation-test' - 'automation-test'
concurrency:
group: "refresh"
cancel-in-progress: false
jobs: jobs:
update: update:
runs-on: ubuntu-latest runs-on: ubuntu-latest
@@ -81,22 +85,12 @@ jobs:
if ${BRANCH_REQUIRES_UPDATE}; then if ${BRANCH_REQUIRES_UPDATE}; then
git push --follow-tags --set-upstream origin ${d} git push --follow-tags --set-upstream origin ${d}
# Trigger build without custom patches
curl -s --show-error \ curl -s --show-error \
-X POST \ -X POST \
-H "Authorization: token ${{ secrets.WORKFLOW_TOKEN }}" \ -H "Authorization: token ${{ secrets.WORKFLOW_TOKEN }}" \
-H "Accept: application/vnd.github.v3+json" \ -H "Accept: application/vnd.github.v3+json" \
-d "{\"ref\":\"${{ github.ref }}\",\"inputs\":{\"ref\":\"${d}\"}}" \ -d "{\"ref\":\"${{ github.ref }}\",\"inputs\":{\"ref\":\"${d}\"}}" \
"https://api.github.com/repos/${{ github.repository }}/actions/workflows/build.yml/dispatches" "https://api.github.com/repos/${{ github.repository }}/actions/workflows/build.yml/dispatches"
# Trigger build with custom patches
curl -s --show-error \
-X POST \
-H "Authorization: token ${{ secrets.WORKFLOW_TOKEN }}" \
-H "Accept: application/vnd.github.v3+json" \
-d "{\"ref\":\"${{ github.ref }}\",\"inputs\":{\"ref\":\"${d}\",\"apply_patches\":\"true\"}}" \
"https://api.github.com/repos/${{ github.repository }}/actions/workflows/build.yml/dispatches"
fi fi
done done
- name: "Only trigger build on manual push" - name: "Only trigger build on manual push"
@@ -107,19 +101,10 @@ jobs:
BRANCHES[${#BRANCHES[@]}]="master" BRANCHES[${#BRANCHES[@]}]="master"
for d in ${BRANCHES[@]}; do for d in ${BRANCHES[@]}; do
# Trigger build without custom patches
curl -s --show-error \ curl -s --show-error \
-X POST \ -X POST \
-H "Authorization: token ${{ secrets.WORKFLOW_TOKEN }}" \ -H "Authorization: token ${{ secrets.WORKFLOW_TOKEN }}" \
-H "Accept: application/vnd.github.v3+json" \ -H "Accept: application/vnd.github.v3+json" \
-d "{\"ref\":\"${{ github.ref }}\",\"inputs\":{\"ref\":\"${d}\"}}" \ -d "{\"ref\":\"${{ github.ref }}\",\"inputs\":{\"ref\":\"${d}\"}}" \
"https://api.github.com/repos/${{ github.repository }}/actions/workflows/build.yml/dispatches" "https://api.github.com/repos/${{ github.repository }}/actions/workflows/build.yml/dispatches"
# Trigger build with custom patches
curl -s --show-error \
-X POST \
-H "Authorization: token ${{ secrets.WORKFLOW_TOKEN }}" \
-H "Accept: application/vnd.github.v3+json" \
-d "{\"ref\":\"${{ github.ref }}\",\"inputs\":{\"ref\":\"${d}\",\"apply_patches\":\"true\"}}" \
"https://api.github.com/repos/${{ github.repository }}/actions/workflows/build.yml/dispatches"
done done
+66
View File
@@ -0,0 +1,66 @@
# Ask git for a description of the current commit.
DESCRIPTION=`git describe --long HEAD`
if [ "${DESCRIPTION:0:1}" == "n" ] || [ "${DESCRIPTION:0:1}" == "v" ]; then
DESCRIPTION=${DESCRIPTION:1}
fi
#echo "echo FFmpeg v${DESCRIPTION}"
# Extract version information from description.
VERSION=${DESCRIPTION//./ }
VERSION=${VERSION//-/ }
VERSION=( ${VERSION} )
VERSION_MAJOR=${VERSION[0]}
VERSION_MINOR=${VERSION[1]}
VERSION_PATCH=${VERSION[2]}
VERSION_TWEAK=${VERSION[3]}
COMMIT=${VERSION[4]:1}
#echo "echo FFmpeg v${VERSION_MAJOR}.${VERSION_MINOR}.${VERSION_PATCH}.${VERSION_TWEAK}-${COMMIT}"
. ${SCRIPTROOT}/addons/export.sh VERSION_MAJOR "${VERSION_MAJOR}"
. ${SCRIPTROOT}/addons/export.sh VERSION_MINOR "${VERSION_MINOR}"
. ${SCRIPTROOT}/addons/export.sh VERSION_PATCH "${VERSION_PATCH}"
. ${SCRIPTROOT}/addons/export.sh VERSION_TWEAK "${VERSION_TWEAK}"
. ${SCRIPTROOT}/addons/export.sh COMMIT "${COMMIT}"
# Set up some baseline directories
if [ ! -d distrib ]; then mkdir distrib; fi
if [ ! -d distrib/bin ]; then mkdir distrib/bin; fi
if [ ! -d distrib/lib ]; then mkdir distrib/lib; fi
if [ ! -d distrib/include ]; then mkdir distrib/include; fi
if [ ! -d distrib/share ]; then mkdir distrib/share; fi
# Target Architecture
if [ "${BUILD_BITS}" == "32" ]; then
BUILD_ARCH="i686"
BUILD_TARGET="mingw32"
BUILD_PREFIX="i686-w64-mingw32"
else
BUILD_ARCH="x86_64"
BUILD_TARGET="mingw64"
BUILD_PREFIX="x86_64-w64-mingw32"
fi
. ${SCRIPTROOT}/addons/export.sh BUILD_ARCH "${BUILD_ARCH}"
. ${SCRIPTROOT}/addons/export.sh BUILD_TARGET "${BUILD_TARGET}"
. ${SCRIPTROOT}/addons/export.sh BUILD_PREFIX "${BUILD_PREFIX}"
# License (GPL vs LGPL, v2 vs v3)
declare -a BUILD_FLAGS
if [ "${LICENSE}" == "GPL" ]; then
#echo "::set-output name=flags_license::--enable-gpl"
BUILD_FLAGS+=("--enable-gpl")
fi
if [ "${LICENSE_VERSION}" == "3" ]; then
#echo "::set-output name=flags_license_version::--enable-version3"
BUILD_FLAGS+=("--enable-version3")
fi
# Build Type
if [ "${BUILD_TYPE}" == "static" ]; then
#echo "::set-output name=flags_type::--enable-static --disable-shared"
BUILD_FLAGS+=("--enable-static")
BUILD_FLAGS+=("--disable-shared")
else
#echo "::set-output name=flags_type::--disable-static --enable-shared"
BUILD_FLAGS+=("--disable-static")
BUILD_FLAGS+=("--enable-shared")
fi
. ${SCRIPTROOT}/addons/export.sh BUILD_FLAGS "`echo ${BUILD_FLAGS[@]}`"
+5
View File
@@ -0,0 +1,5 @@
export $1="$2"
if [[ "${CI}" == "true" ]]; then
echo "::set-output name=$1::$2"
fi
echo "export $1=\"$2\"" >> ${SCRIPTROOT}/.env
+18
View File
@@ -0,0 +1,18 @@
echo "Applying custom patches..."
declare -a PATCHES
PATCHES[${#PATCHES[@]}]="${VERSION_MAJOR}.${VERSION_MINOR}.${VERSION_TWEAK}"
PATCHES[${#PATCHES[@]}]="${VERSION_MAJOR}.${VERSION_MINOR}"
PATCHES[${#PATCHES[@]}]="${VERSION_MAJOR}"
for patchset in ${PATCHES[@]}; do
if [[ -d "${SCRIPTROOT}/patches/${patchset}" ]]; then
echo " Found ${patchset}..."
for file in ${SCRIPTROOT}/patches/${patchset}/*.patch; do
# Skip files that don't actually exist.
[ -e "${file}" ] || continue
echo " Applying '${file}'..."
git apply "${file}"
done
fi
done
+9
View File
@@ -0,0 +1,9 @@
for file in ${SCRIPTROOT}/scripts/*.sh; do
[ -e "${file}" ] || continue
echo "================================================================================"
echo ">> ${file}"
echo "================================================================================"
. ${SCRIPTROOT}/.env
${file}
if [[ $? -ne 0 ]]; then exit 1; fi
done
@@ -0,0 +1,30 @@
From a440dce6b5c8b90e80660641d632c60a4cc1c1bd Mon Sep 17 00:00:00 2001
Message-Id: <a440dce6b5c8b90e80660641d632c60a4cc1c1bd.1642029358.git.info@xaymar.com>
From: Michael Fabian 'Xaymar' Dirks <michael.dirks@xaymar.com>
Date: Mon, 10 Jan 2022 03:08:48 +0100
Subject: [PATCH 1/5] avcodec: Require AMF SDK v1.4.23 or newer
Increasing the minimum AMF SDK version allows us to support
more recent hardware and drivers, which is necessary to fix
some of the discrepancies between older and newer drivers on
AMD hardware with FFmpeg.
---
configure | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/configure b/configure
index 1413122d87..515ec1a50f 100755
--- a/configure
+++ b/configure
@@ -6969,7 +6969,7 @@ fi
enabled amf &&
check_cpp_condition amf "AMF/core/Version.h" \
- "(AMF_VERSION_MAJOR << 48 | AMF_VERSION_MINOR << 32 | AMF_VERSION_RELEASE << 16 | AMF_VERSION_BUILD_NUM) >= 0x0001000400090000"
+ "AMF_FULL_VERSION >= AMF_MAKE_FULL_VERSION(1, 4, 23, 0)"
# Funny iconv installations are not unusual, so check it after all flags have been set
if enabled libc_iconv; then
--
2.34.1.windows.1
@@ -0,0 +1,177 @@
From d6a48f863ffe0ae2968aa487b571a1a68412522d Mon Sep 17 00:00:00 2001
Message-Id: <d6a48f863ffe0ae2968aa487b571a1a68412522d.1642029358.git.info@xaymar.com>
In-Reply-To: <a440dce6b5c8b90e80660641d632c60a4cc1c1bd.1642029358.git.info@xaymar.com>
References: <a440dce6b5c8b90e80660641d632c60a4cc1c1bd.1642029358.git.info@xaymar.com>
From: Michael Fabian 'Xaymar' Dirks <michael.dirks@xaymar.com>
Date: Tue, 11 Jan 2022 08:15:59 +0100
Subject: [PATCH 2/5] avcodec/amfenc: Set all color metadata for AMF
Fixes the color information in the output from the AMD encoder
being wrong, which led to weird transcoding results. This
problem appeared out of thin air, and I've been unable to tie
it to a specific driver that supports my hardware. Unfortunately
this requires AMF SDK version 1.4.23 or later, but it should
still work fine on older drivers.
Theoretical support for HDR encoding is also now possible,
although the implementation is not complete. I have no clear
idea on how to generate AMFs HDR metadata structure, or where
to even take this information from.
---
libavcodec/amfenc.h | 1 +
libavcodec/amfenc_h264.c | 48 +++++++++++++++++++++++++++++++++++++-
libavcodec/amfenc_hevc.c | 50 ++++++++++++++++++++++++++++++++++++++++
3 files changed, 98 insertions(+), 1 deletion(-)
diff --git a/libavcodec/amfenc.h b/libavcodec/amfenc.h
index 358b2ef778..951e529362 100644
--- a/libavcodec/amfenc.h
+++ b/libavcodec/amfenc.h
@@ -21,6 +21,7 @@
#include <AMF/core/Factory.h>
+#include <AMF/components/ColorSpace.h>
#include <AMF/components/VideoEncoderVCE.h>
#include <AMF/components/VideoEncoderHEVC.h>
diff --git a/libavcodec/amfenc_h264.c b/libavcodec/amfenc_h264.c
index aeca99f7c6..009378e9f1 100644
--- a/libavcodec/amfenc_h264.c
+++ b/libavcodec/amfenc_h264.c
@@ -137,6 +137,8 @@ static av_cold int amf_encode_init_h264(AVCodecContext *avctx)
AMFRate framerate;
AMFSize framesize = AMFConstructSize(avctx->width, avctx->height);
int deblocking_filter = (avctx->flags & AV_CODEC_FLAG_LOOP_FILTER) ? 1 : 0;
+ amf_int64 color_depth;
+ amf_int64 color_profile;
if (avctx->framerate.num > 0 && avctx->framerate.den > 0) {
framerate = AMFConstructRate(avctx->framerate.num, avctx->framerate.den);
@@ -194,10 +196,54 @@ static av_cold int amf_encode_init_h264(AVCodecContext *avctx)
AMF_ASSIGN_PROPERTY_RATIO(res, ctx->encoder, AMF_VIDEO_ENCODER_ASPECT_RATIO, ratio);
}
- /// Color Range (Partial/TV/MPEG or Full/PC/JPEG)
+ // Color Metadata
+ /// Color Range (Support for older Drivers)
if (avctx->color_range == AVCOL_RANGE_JPEG) {
AMF_ASSIGN_PROPERTY_BOOL(res, ctx->encoder, AMF_VIDEO_ENCODER_FULL_RANGE_COLOR, 1);
+ } else {
+ AMF_ASSIGN_PROPERTY_BOOL(res, ctx->encoder, AMF_VIDEO_ENCODER_FULL_RANGE_COLOR, 0);
+ }
+ /// Color Space & Depth
+ color_depth = AMF_COLOR_BIT_DEPTH_8;
+ color_profile = AMF_VIDEO_CONVERTER_COLOR_PROFILE_UNKNOWN;
+ switch (avctx->colorspace) {
+ case AVCOL_SPC_SMPTE170M:
+ if (avctx->color_range == AVCOL_RANGE_JPEG) {
+ color_profile = AMF_VIDEO_CONVERTER_COLOR_PROFILE_FULL_601;
+ } else {
+ color_profile = AMF_VIDEO_CONVERTER_COLOR_PROFILE_601;
+ }
+ break;
+ case AVCOL_SPC_BT709:
+ if (avctx->color_range == AVCOL_RANGE_JPEG) {
+ color_profile = AMF_VIDEO_CONVERTER_COLOR_PROFILE_FULL_709;
+ } else {
+ color_profile = AMF_VIDEO_CONVERTER_COLOR_PROFILE_709;
+ }
+ break;
+ case AVCOL_SPC_BT2020_NCL:
+ case AVCOL_SPC_BT2020_CL:
+ // !FIXME: Verify that this is correct on Hardware supporting it.
+ // !FIXME: Figure out how to decide on bit depth.
+ if (avctx->color_range == AVCOL_RANGE_JPEG) {
+ color_profile = AMF_VIDEO_CONVERTER_COLOR_PROFILE_FULL_2020;
+ color_depth = AMF_COLOR_BIT_DEPTH_10;
+ } else {
+ color_profile = AMF_VIDEO_CONVERTER_COLOR_PROFILE_2020;
+ color_depth = AMF_COLOR_BIT_DEPTH_10;
+ }
+ break;
}
+ AMF_ASSIGN_PROPERTY_INT64(res, ctx->encoder, AMF_VIDEO_ENCODER_COLOR_BIT_DEPTH, color_depth);
+ AMF_ASSIGN_PROPERTY_INT64(res, ctx->encoder, AMF_VIDEO_ENCODER_INPUT_COLOR_PROFILE, color_profile);
+ AMF_ASSIGN_PROPERTY_INT64(res, ctx->encoder, AMF_VIDEO_ENCODER_OUTPUT_COLOR_PROFILE, color_profile);
+ /// Color Transfer Characteristics (AMF matches ISO/IEC)
+ AMF_ASSIGN_PROPERTY_INT64(res, ctx->encoder, AMF_VIDEO_ENCODER_INPUT_TRANSFER_CHARACTERISTIC, (amf_int64)avctx->color_trc);
+ AMF_ASSIGN_PROPERTY_INT64(res, ctx->encoder, AMF_VIDEO_ENCODER_OUTPUT_TRANSFER_CHARACTERISTIC, (amf_int64)avctx->color_trc);
+ /// Color Primaries (AMF matches ISO/IEC)
+ AMF_ASSIGN_PROPERTY_INT64(res, ctx->encoder, AMF_VIDEO_ENCODER_INPUT_COLOR_PRIMARIES, (amf_int64)avctx->color_primaries);
+ AMF_ASSIGN_PROPERTY_INT64(res, ctx->encoder, AMF_VIDEO_ENCODER_OUTPUT_COLOR_PRIMARIES, (amf_int64)avctx->color_primaries);
+ /// !TODO: AMF HDR Metadata generation
// autodetect rate control method
if (ctx->rate_control_mode == AMF_VIDEO_ENCODER_RATE_CONTROL_METHOD_UNKNOWN) {
diff --git a/libavcodec/amfenc_hevc.c b/libavcodec/amfenc_hevc.c
index 79541b9b2f..900e1482b4 100644
--- a/libavcodec/amfenc_hevc.c
+++ b/libavcodec/amfenc_hevc.c
@@ -104,6 +104,8 @@ static av_cold int amf_encode_init_hevc(AVCodecContext *avctx)
AMFRate framerate;
AMFSize framesize = AMFConstructSize(avctx->width, avctx->height);
int deblocking_filter = (avctx->flags & AV_CODEC_FLAG_LOOP_FILTER) ? 1 : 0;
+ amf_int64 color_depth;
+ amf_int64 color_profile;
if (avctx->framerate.num > 0 && avctx->framerate.den > 0) {
framerate = AMFConstructRate(avctx->framerate.num, avctx->framerate.den);
@@ -152,6 +154,54 @@ static av_cold int amf_encode_init_hevc(AVCodecContext *avctx)
AMFRatio ratio = AMFConstructRatio(avctx->sample_aspect_ratio.num, avctx->sample_aspect_ratio.den);
AMF_ASSIGN_PROPERTY_RATIO(res, ctx->encoder, AMF_VIDEO_ENCODER_HEVC_ASPECT_RATIO, ratio);
}
+
+ // Color Metadata
+ /// Color Range (Support for older Drivers)
+ if (avctx->color_range == AVCOL_RANGE_JPEG) {
+ AMF_ASSIGN_PROPERTY_BOOL(res, ctx->encoder, AMF_VIDEO_ENCODER_HEVC_NOMINAL_RANGE, 1);
+ } else {
+ AMF_ASSIGN_PROPERTY_BOOL(res, ctx->encoder, AMF_VIDEO_ENCODER_HEVC_NOMINAL_RANGE, 0);
+ }
+ /// Color Space & Depth
+ color_depth = AMF_COLOR_BIT_DEPTH_8;
+ color_profile = AMF_VIDEO_CONVERTER_COLOR_PROFILE_UNKNOWN;
+ switch (avctx->colorspace) {
+ case AVCOL_SPC_SMPTE170M:
+ if (avctx->color_range == AVCOL_RANGE_JPEG) {
+ color_profile = AMF_VIDEO_CONVERTER_COLOR_PROFILE_FULL_601;
+ } else {
+ color_profile = AMF_VIDEO_CONVERTER_COLOR_PROFILE_601;
+ }
+ break;
+ case AVCOL_SPC_BT709:
+ if (avctx->color_range == AVCOL_RANGE_JPEG) {
+ color_profile = AMF_VIDEO_CONVERTER_COLOR_PROFILE_FULL_709;
+ } else {
+ color_profile = AMF_VIDEO_CONVERTER_COLOR_PROFILE_709;
+ }
+ break;
+ case AVCOL_SPC_BT2020_NCL:
+ case AVCOL_SPC_BT2020_CL:
+ // !FIXME: Verify that this is correct on Hardware supporting it.
+ // !FIXME: Figure out how to decide on bit depth.
+ if (avctx->color_range == AVCOL_RANGE_JPEG) {
+ color_profile = AMF_VIDEO_CONVERTER_COLOR_PROFILE_FULL_2020;
+ color_depth = AMF_COLOR_BIT_DEPTH_10;
+ } else {
+ color_profile = AMF_VIDEO_CONVERTER_COLOR_PROFILE_2020;
+ color_depth = AMF_COLOR_BIT_DEPTH_10;
+ }
+ break;
+ }
+ AMF_ASSIGN_PROPERTY_INT64(res, ctx->encoder, AMF_VIDEO_ENCODER_HEVC_COLOR_BIT_DEPTH, color_depth);
+ AMF_ASSIGN_PROPERTY_INT64(res, ctx->encoder, AMF_VIDEO_ENCODER_HEVC_INPUT_COLOR_PROFILE, color_profile);
+ AMF_ASSIGN_PROPERTY_INT64(res, ctx->encoder, AMF_VIDEO_ENCODER_HEVC_OUTPUT_COLOR_PROFILE, color_profile);
+ /// Color Transfer Characteristics (AMF matches ISO/IEC)
+ AMF_ASSIGN_PROPERTY_INT64(res, ctx->encoder, AMF_VIDEO_ENCODER_HEVC_INPUT_TRANSFER_CHARACTERISTIC, (amf_int64)avctx->color_trc);
+ AMF_ASSIGN_PROPERTY_INT64(res, ctx->encoder, AMF_VIDEO_ENCODER_HEVC_OUTPUT_TRANSFER_CHARACTERISTIC, (amf_int64)avctx->color_trc);
+ /// Color Primaries (AMF matches ISO/IEC)
+ AMF_ASSIGN_PROPERTY_INT64(res, ctx->encoder, AMF_VIDEO_ENCODER_HEVC_INPUT_COLOR_PRIMARIES, (amf_int64)avctx->color_primaries);
+ AMF_ASSIGN_PROPERTY_INT64(res, ctx->encoder, AMF_VIDEO_ENCODER_HEVC_OUTPUT_COLOR_PRIMARIES, (amf_int64)avctx->color_primaries);
// Picture control properties
AMF_ASSIGN_PROPERTY_INT64(res, ctx->encoder, AMF_VIDEO_ENCODER_HEVC_NUM_GOPS_PER_IDR, ctx->gops_per_idr);
--
2.34.1.windows.1
@@ -0,0 +1,61 @@
From d622fed60be525e5ff814f1eb703c67d3be0ed0e Mon Sep 17 00:00:00 2001
Message-Id: <d622fed60be525e5ff814f1eb703c67d3be0ed0e.1642029358.git.info@xaymar.com>
In-Reply-To: <a440dce6b5c8b90e80660641d632c60a4cc1c1bd.1642029358.git.info@xaymar.com>
References: <a440dce6b5c8b90e80660641d632c60a4cc1c1bd.1642029358.git.info@xaymar.com>
From: Michael Fabian 'Xaymar' Dirks <michael.dirks@xaymar.com>
Date: Tue, 11 Jan 2022 08:22:16 +0100
Subject: [PATCH 3/5] avcodec/amfenc: Add the new usage presets
These enable some new features that otherwise require another
AMF component to be loaded. Requires AMF SDK 1.4.23 or newer.
---
libavcodec/amfenc_h264.c | 12 +++++++-----
libavcodec/amfenc_hevc.c | 6 ++++--
2 files changed, 11 insertions(+), 7 deletions(-)
diff --git a/libavcodec/amfenc_h264.c b/libavcodec/amfenc_h264.c
index 009378e9f1..afac97a968 100644
--- a/libavcodec/amfenc_h264.c
+++ b/libavcodec/amfenc_h264.c
@@ -28,11 +28,13 @@
static const AVOption options[] = {
// Static
/// Usage
- { "usage", "Encoder Usage", OFFSET(usage), AV_OPT_TYPE_INT, { .i64 = AMF_VIDEO_ENCODER_USAGE_TRANSCONDING }, AMF_VIDEO_ENCODER_USAGE_TRANSCONDING, AMF_VIDEO_ENCODER_USAGE_WEBCAM, VE, "usage" },
- { "transcoding", "Generic Transcoding", 0, AV_OPT_TYPE_CONST, { .i64 = AMF_VIDEO_ENCODER_USAGE_TRANSCONDING }, 0, 0, VE, "usage" },
- { "ultralowlatency","", 0, AV_OPT_TYPE_CONST, { .i64 = AMF_VIDEO_ENCODER_USAGE_ULTRA_LOW_LATENCY }, 0, 0, VE, "usage" },
- { "lowlatency", "", 0, AV_OPT_TYPE_CONST, { .i64 = AMF_VIDEO_ENCODER_USAGE_LOW_LATENCY }, 0, 0, VE, "usage" },
- { "webcam", "Webcam", 0, AV_OPT_TYPE_CONST, { .i64 = AMF_VIDEO_ENCODER_USAGE_WEBCAM }, 0, 0, VE, "usage" },
+ { "usage", "Encoder Usage", OFFSET(usage), AV_OPT_TYPE_INT, { .i64 = AMF_VIDEO_ENCODER_USAGE_TRANSCODING }, AMF_VIDEO_ENCODER_USAGE_TRANSCODING, AMF_VIDEO_ENCODER_USAGE_LOW_LATENCY_HIGH_QUALITY, VE, "usage" },
+ { "transcoding", "Generic Transcoding", 0, AV_OPT_TYPE_CONST, { .i64 = AMF_VIDEO_ENCODER_USAGE_TRANSCODING }, 0, 0, VE, "usage" },
+ { "ultralowlatency", "", 0, AV_OPT_TYPE_CONST, { .i64 = AMF_VIDEO_ENCODER_USAGE_ULTRA_LOW_LATENCY }, 0, 0, VE, "usage" },
+ { "lowlatency", "", 0, AV_OPT_TYPE_CONST, { .i64 = AMF_VIDEO_ENCODER_USAGE_LOW_LATENCY }, 0, 0, VE, "usage" },
+ { "webcam", "Webcam", 0, AV_OPT_TYPE_CONST, { .i64 = AMF_VIDEO_ENCODER_USAGE_WEBCAM }, 0, 0, VE, "usage" },
+ { "highquality", "", 0, AV_OPT_TYPE_CONST, { .i64 = AMF_VIDEO_ENCODER_USAGE_HIGH_QUALITY }, 0, 0, VE, "usage" },
+ { "lowlatency_highqquality", "", 0, AV_OPT_TYPE_CONST, { .i64 = AMF_VIDEO_ENCODER_USAGE_LOW_LATENCY_HIGH_QUALITY }, 0, 0, VE, "usage" },
/// Profile,
{ "profile", "Profile", OFFSET(profile),AV_OPT_TYPE_INT, { .i64 = AMF_VIDEO_ENCODER_PROFILE_MAIN }, AMF_VIDEO_ENCODER_PROFILE_BASELINE, AMF_VIDEO_ENCODER_PROFILE_CONSTRAINED_HIGH, VE, "profile" },
diff --git a/libavcodec/amfenc_hevc.c b/libavcodec/amfenc_hevc.c
index 900e1482b4..b7fee950f6 100644
--- a/libavcodec/amfenc_hevc.c
+++ b/libavcodec/amfenc_hevc.c
@@ -24,11 +24,13 @@
#define OFFSET(x) offsetof(AmfContext, x)
#define VE AV_OPT_FLAG_VIDEO_PARAM | AV_OPT_FLAG_ENCODING_PARAM
static const AVOption options[] = {
- { "usage", "Set the encoding usage", OFFSET(usage), AV_OPT_TYPE_INT, { .i64 = AMF_VIDEO_ENCODER_HEVC_USAGE_TRANSCONDING }, AMF_VIDEO_ENCODER_HEVC_USAGE_TRANSCONDING, AMF_VIDEO_ENCODER_HEVC_USAGE_WEBCAM, VE, "usage" },
- { "transcoding", "", 0, AV_OPT_TYPE_CONST, { .i64 = AMF_VIDEO_ENCODER_HEVC_USAGE_TRANSCONDING }, 0, 0, VE, "usage" },
+ { "usage", "Set the encoding usage", OFFSET(usage), AV_OPT_TYPE_INT, { .i64 = AMF_VIDEO_ENCODER_HEVC_USAGE_TRANSCODING }, AMF_VIDEO_ENCODER_HEVC_USAGE_TRANSCODING, AMF_VIDEO_ENCODER_HEVC_USAGE_LOW_LATENCY_HIGH_QUALITY, VE, "usage" },
+ { "transcoding", "", 0, AV_OPT_TYPE_CONST, { .i64 = AMF_VIDEO_ENCODER_HEVC_USAGE_TRANSCODING }, 0, 0, VE, "usage" },
{ "ultralowlatency","", 0, AV_OPT_TYPE_CONST, { .i64 = AMF_VIDEO_ENCODER_HEVC_USAGE_ULTRA_LOW_LATENCY }, 0, 0, VE, "usage" },
{ "lowlatency", "", 0, AV_OPT_TYPE_CONST, { .i64 = AMF_VIDEO_ENCODER_HEVC_USAGE_LOW_LATENCY }, 0, 0, VE, "usage" },
{ "webcam", "", 0, AV_OPT_TYPE_CONST, { .i64 = AMF_VIDEO_ENCODER_HEVC_USAGE_WEBCAM }, 0, 0, VE, "usage" },
+ { "highquality", "", 0, AV_OPT_TYPE_CONST, { .i64 = AMF_VIDEO_ENCODER_HEVC_USAGE_HIGH_QUALITY }, 0, 0, VE, "usage" },
+ { "lowlatency_highqquality", "", 0, AV_OPT_TYPE_CONST, { .i64 = AMF_VIDEO_ENCODER_HEVC_USAGE_LOW_LATENCY_HIGH_QUALITY }, 0, 0, VE, "usage" },
{ "profile", "Set the profile (default main)", OFFSET(profile), AV_OPT_TYPE_INT,{ .i64 = AMF_VIDEO_ENCODER_HEVC_PROFILE_MAIN }, AMF_VIDEO_ENCODER_HEVC_PROFILE_MAIN, AMF_VIDEO_ENCODER_HEVC_PROFILE_MAIN, VE, "profile" },
{ "main", "", 0, AV_OPT_TYPE_CONST,{ .i64 = AMF_VIDEO_ENCODER_HEVC_PROFILE_MAIN }, 0, 0, VE, "profile" },
--
2.34.1.windows.1
@@ -0,0 +1,80 @@
From 9cbaf2a700356682713bd01b2a6df3bc8d85c228 Mon Sep 17 00:00:00 2001
Message-Id: <9cbaf2a700356682713bd01b2a6df3bc8d85c228.1642029358.git.info@xaymar.com>
In-Reply-To: <a440dce6b5c8b90e80660641d632c60a4cc1c1bd.1642029358.git.info@xaymar.com>
References: <a440dce6b5c8b90e80660641d632c60a4cc1c1bd.1642029358.git.info@xaymar.com>
From: Michael Fabian 'Xaymar' Dirks <michael.dirks@xaymar.com>
Date: Tue, 11 Jan 2022 08:23:37 +0100
Subject: [PATCH 4/5] avcodec/amfenc: Add "High Motion Quality Boost" option
This option was missing from amfenc, and is now available.
---
libavcodec/amfenc.h | 3 +++
libavcodec/amfenc_h264.c | 2 ++
libavcodec/amfenc_hevc.c | 3 ++-
3 files changed, 7 insertions(+), 1 deletion(-)
diff --git a/libavcodec/amfenc.h b/libavcodec/amfenc.h
index 951e529362..f47e6a1200 100644
--- a/libavcodec/amfenc.h
+++ b/libavcodec/amfenc.h
@@ -108,6 +108,9 @@ typedef struct AmfContext {
int me_quarter_pel;
int aud;
+ // Unclear options, have different behavior based on codec.
+ int hmqb;
+
// HEVC - specific options
int gops_per_idr;
diff --git a/libavcodec/amfenc_h264.c b/libavcodec/amfenc_h264.c
index afac97a968..87a3bb6a73 100644
--- a/libavcodec/amfenc_h264.c
+++ b/libavcodec/amfenc_h264.c
@@ -86,6 +86,7 @@ static const AVOption options[] = {
{ "filler_data", "Filler Data Enable", OFFSET(filler_data), AV_OPT_TYPE_BOOL, { .i64 = 0 }, 0, 1, VE },
{ "vbaq", "Enable VBAQ", OFFSET(enable_vbaq), AV_OPT_TYPE_BOOL, { .i64 = 0 }, 0, 1, VE },
{ "frame_skipping", "Rate Control Based Frame Skip", OFFSET(skip_frame), AV_OPT_TYPE_BOOL, { .i64 = 0 }, 0, 1, VE },
+ { "hmqb", "High Motion Quality Boost", OFFSET(hmqb), AV_OPT_TYPE_BOOL, { .i64 = 0 }, 0, 1, VE },
/// QP Values
{ "qp_i", "Quantization Parameter for I-Frame", OFFSET(qp_i), AV_OPT_TYPE_INT, { .i64 = -1 }, -1, 51, VE },
@@ -331,6 +332,7 @@ static av_cold int amf_encode_init_h264(AVCodecContext *avctx)
AMF_ASSIGN_PROPERTY_BOOL(res, ctx->encoder, AMF_VIDEO_ENCODER_ENFORCE_HRD, !!ctx->enforce_hrd);
AMF_ASSIGN_PROPERTY_BOOL(res, ctx->encoder, AMF_VIDEO_ENCODER_FILLER_DATA_ENABLE, !!ctx->filler_data);
AMF_ASSIGN_PROPERTY_BOOL(res, ctx->encoder, AMF_VIDEO_ENCODER_RATE_CONTROL_SKIP_FRAME_ENABLE, !!ctx->skip_frame);
+ AMF_ASSIGN_PROPERTY_BOOL(res, ctx->encoder, AMF_VIDEO_ENCODER_HIGH_MOTION_QUALITY_BOOST_ENABLE, !!ctx->hmqb);
if (ctx->rate_control_mode == AMF_VIDEO_ENCODER_RATE_CONTROL_METHOD_CONSTANT_QP) {
AMF_ASSIGN_PROPERTY_BOOL(res, ctx->encoder, AMF_VIDEO_ENCODER_ENABLE_VBAQ, 0);
if (ctx->enable_vbaq)
diff --git a/libavcodec/amfenc_hevc.c b/libavcodec/amfenc_hevc.c
index b7fee950f6..565be9bad9 100644
--- a/libavcodec/amfenc_hevc.c
+++ b/libavcodec/amfenc_hevc.c
@@ -74,6 +74,7 @@ static const AVOption options[] = {
{ "gops_per_idr", "GOPs per IDR 0-no IDR will be inserted", OFFSET(gops_per_idr), AV_OPT_TYPE_INT, { .i64 = 1 }, 0, INT_MAX, VE },
{ "preanalysis", "Enable preanalysis", OFFSET(preanalysis), AV_OPT_TYPE_BOOL, { .i64 = 0 }, 0, 1, VE},
{ "vbaq", "Enable VBAQ", OFFSET(enable_vbaq), AV_OPT_TYPE_BOOL, { .i64 = 0 }, 0, 1, VE},
+ { "hmqb", "High Motion Quality Boost", OFFSET(hmqb), AV_OPT_TYPE_BOOL, { .i64 = 0 }, 0, 1, VE },
{ "enforce_hrd", "Enforce HRD", OFFSET(enforce_hrd), AV_OPT_TYPE_BOOL, { .i64 = 0 }, 0, 1, VE},
{ "filler_data", "Filler Data Enable", OFFSET(filler_data), AV_OPT_TYPE_BOOL, { .i64 = 0 }, 0, 1, VE},
{ "max_au_size", "Maximum Access Unit Size for rate control (in bits)", OFFSET(max_au_size), AV_OPT_TYPE_INT,{ .i64 = 0 }, 0, INT_MAX, VE},
@@ -231,7 +232,6 @@ static av_cold int amf_encode_init_hevc(AVCodecContext *avctx)
}
}
-
AMF_ASSIGN_PROPERTY_INT64(res, ctx->encoder, AMF_VIDEO_ENCODER_HEVC_RATE_CONTROL_METHOD, ctx->rate_control_mode);
if (avctx->rc_buffer_size) {
AMF_ASSIGN_PROPERTY_INT64(res, ctx->encoder, AMF_VIDEO_ENCODER_HEVC_VBV_BUFFER_SIZE, avctx->rc_buffer_size);
@@ -253,6 +253,7 @@ static av_cold int amf_encode_init_hevc(AVCodecContext *avctx)
} else {
AMF_ASSIGN_PROPERTY_BOOL(res, ctx->encoder, AMF_VIDEO_ENCODER_HEVC_ENABLE_VBAQ, !!ctx->enable_vbaq);
}
+ AMF_ASSIGN_PROPERTY_BOOL(res, ctx->encoder, AMF_VIDEO_ENCODER_HEVC_HIGH_MOTION_QUALITY_BOOST_ENABLE, !!ctx->hmqb);
AMF_ASSIGN_PROPERTY_BOOL(res, ctx->encoder, AMF_VIDEO_ENCODER_HEVC_MOTION_HALF_PIXEL, ctx->me_half_pel);
AMF_ASSIGN_PROPERTY_BOOL(res, ctx->encoder, AMF_VIDEO_ENCODER_HEVC_MOTION_QUARTERPIXEL, ctx->me_quarter_pel);
--
2.34.1.windows.1
@@ -0,0 +1,52 @@
From ebf6229908e96c3f8d6144b19fc42f5346e3b628 Mon Sep 17 00:00:00 2001
Message-Id: <ebf6229908e96c3f8d6144b19fc42f5346e3b628.1642029358.git.info@xaymar.com>
In-Reply-To: <a440dce6b5c8b90e80660641d632c60a4cc1c1bd.1642029358.git.info@xaymar.com>
References: <a440dce6b5c8b90e80660641d632c60a4cc1c1bd.1642029358.git.info@xaymar.com>
From: Michael Fabian 'Xaymar' Dirks <michael.dirks@xaymar.com>
Date: Tue, 11 Jan 2022 08:24:11 +0100
Subject: [PATCH 5/5] avcodec/amfenc: Add missing profiles
Adds the missing profiles to the '-help encoder=xxx_amf' list,
even if the user may never need these.
---
libavcodec/amfenc_h264.c | 11 ++++++-----
libavcodec/amfenc_hevc.c | 1 +
2 files changed, 7 insertions(+), 5 deletions(-)
diff --git a/libavcodec/amfenc_h264.c b/libavcodec/amfenc_h264.c
index 87a3bb6a73..ae21c60357 100644
--- a/libavcodec/amfenc_h264.c
+++ b/libavcodec/amfenc_h264.c
@@ -37,11 +37,12 @@ static const AVOption options[] = {
{ "lowlatency_highqquality", "", 0, AV_OPT_TYPE_CONST, { .i64 = AMF_VIDEO_ENCODER_USAGE_LOW_LATENCY_HIGH_QUALITY }, 0, 0, VE, "usage" },
/// Profile,
- { "profile", "Profile", OFFSET(profile),AV_OPT_TYPE_INT, { .i64 = AMF_VIDEO_ENCODER_PROFILE_MAIN }, AMF_VIDEO_ENCODER_PROFILE_BASELINE, AMF_VIDEO_ENCODER_PROFILE_CONSTRAINED_HIGH, VE, "profile" },
- { "main", "", 0, AV_OPT_TYPE_CONST, { .i64 = AMF_VIDEO_ENCODER_PROFILE_MAIN }, 0, 0, VE, "profile" },
- { "high", "", 0, AV_OPT_TYPE_CONST, { .i64 = AMF_VIDEO_ENCODER_PROFILE_HIGH }, 0, 0, VE, "profile" },
- { "constrained_baseline", "", 0, AV_OPT_TYPE_CONST, { .i64 = AMF_VIDEO_ENCODER_PROFILE_CONSTRAINED_BASELINE }, 0, 0, VE, "profile" },
- { "constrained_high", "", 0, AV_OPT_TYPE_CONST, { .i64 = AMF_VIDEO_ENCODER_PROFILE_CONSTRAINED_HIGH }, 0, 0, VE, "profile" },
+ { "profile", "Profile", OFFSET(profile), AV_OPT_TYPE_INT, { .i64 = AMF_VIDEO_ENCODER_PROFILE_MAIN }, AMF_VIDEO_ENCODER_PROFILE_BASELINE, AMF_VIDEO_ENCODER_PROFILE_CONSTRAINED_HIGH, VE, "profile" },
+ { "baseline", "", 0, AV_OPT_TYPE_CONST, { .i64 = AMF_VIDEO_ENCODER_PROFILE_BASELINE }, 0, 0, VE, "profile" },
+ { "main", "", 0, AV_OPT_TYPE_CONST, { .i64 = AMF_VIDEO_ENCODER_PROFILE_MAIN }, 0, 0, VE, "profile" },
+ { "high", "", 0, AV_OPT_TYPE_CONST, { .i64 = AMF_VIDEO_ENCODER_PROFILE_HIGH }, 0, 0, VE, "profile" },
+ { "constrained_baseline", "", 0, AV_OPT_TYPE_CONST, { .i64 = AMF_VIDEO_ENCODER_PROFILE_CONSTRAINED_BASELINE }, 0, 0, VE, "profile" },
+ { "constrained_high", "", 0, AV_OPT_TYPE_CONST, { .i64 = AMF_VIDEO_ENCODER_PROFILE_CONSTRAINED_HIGH }, 0, 0, VE, "profile" },
/// Profile Level
{ "level", "Profile Level", OFFSET(level), AV_OPT_TYPE_INT, { .i64 = 0 }, 0, 62, VE, "level" },
diff --git a/libavcodec/amfenc_hevc.c b/libavcodec/amfenc_hevc.c
index 565be9bad9..a69f37e7b1 100644
--- a/libavcodec/amfenc_hevc.c
+++ b/libavcodec/amfenc_hevc.c
@@ -34,6 +34,7 @@ static const AVOption options[] = {
{ "profile", "Set the profile (default main)", OFFSET(profile), AV_OPT_TYPE_INT,{ .i64 = AMF_VIDEO_ENCODER_HEVC_PROFILE_MAIN }, AMF_VIDEO_ENCODER_HEVC_PROFILE_MAIN, AMF_VIDEO_ENCODER_HEVC_PROFILE_MAIN, VE, "profile" },
{ "main", "", 0, AV_OPT_TYPE_CONST,{ .i64 = AMF_VIDEO_ENCODER_HEVC_PROFILE_MAIN }, 0, 0, VE, "profile" },
+ { "main10", "", 0, AV_OPT_TYPE_CONST,{ .i64 = AMF_VIDEO_ENCODER_HEVC_PROFILE_MAIN_10 }, 0, 0, VE, "profile" },
{ "profile_tier", "Set the profile tier (default main)", OFFSET(tier), AV_OPT_TYPE_INT,{ .i64 = AMF_VIDEO_ENCODER_HEVC_TIER_MAIN }, AMF_VIDEO_ENCODER_HEVC_TIER_MAIN, AMF_VIDEO_ENCODER_HEVC_TIER_HIGH, VE, "tier" },
{ "main", "", 0, AV_OPT_TYPE_CONST, { .i64 = AMF_VIDEO_ENCODER_HEVC_TIER_MAIN }, 0, 0, VE, "tier" },
--
2.34.1.windows.1
@@ -0,0 +1,30 @@
From a440dce6b5c8b90e80660641d632c60a4cc1c1bd Mon Sep 17 00:00:00 2001
Message-Id: <a440dce6b5c8b90e80660641d632c60a4cc1c1bd.1642029358.git.info@xaymar.com>
From: Michael Fabian 'Xaymar' Dirks <michael.dirks@xaymar.com>
Date: Mon, 10 Jan 2022 03:08:48 +0100
Subject: [PATCH 1/5] avcodec: Require AMF SDK v1.4.23 or newer
Increasing the minimum AMF SDK version allows us to support
more recent hardware and drivers, which is necessary to fix
some of the discrepancies between older and newer drivers on
AMD hardware with FFmpeg.
---
configure | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/configure b/configure
index 1413122d87..515ec1a50f 100755
--- a/configure
+++ b/configure
@@ -6969,7 +6969,7 @@ fi
enabled amf &&
check_cpp_condition amf "AMF/core/Version.h" \
- "(AMF_VERSION_MAJOR << 48 | AMF_VERSION_MINOR << 32 | AMF_VERSION_RELEASE << 16 | AMF_VERSION_BUILD_NUM) >= 0x0001000400090000"
+ "AMF_FULL_VERSION >= AMF_MAKE_FULL_VERSION(1, 4, 23, 0)"
# Funny iconv installations are not unusual, so check it after all flags have been set
if enabled libc_iconv; then
--
2.34.1.windows.1
@@ -0,0 +1,177 @@
From d6a48f863ffe0ae2968aa487b571a1a68412522d Mon Sep 17 00:00:00 2001
Message-Id: <d6a48f863ffe0ae2968aa487b571a1a68412522d.1642029358.git.info@xaymar.com>
In-Reply-To: <a440dce6b5c8b90e80660641d632c60a4cc1c1bd.1642029358.git.info@xaymar.com>
References: <a440dce6b5c8b90e80660641d632c60a4cc1c1bd.1642029358.git.info@xaymar.com>
From: Michael Fabian 'Xaymar' Dirks <michael.dirks@xaymar.com>
Date: Tue, 11 Jan 2022 08:15:59 +0100
Subject: [PATCH 2/5] avcodec/amfenc: Set all color metadata for AMF
Fixes the color information in the output from the AMD encoder
being wrong, which led to weird transcoding results. This
problem appeared out of thin air, and I've been unable to tie
it to a specific driver that supports my hardware. Unfortunately
this requires AMF SDK version 1.4.23 or later, but it should
still work fine on older drivers.
Theoretical support for HDR encoding is also now possible,
although the implementation is not complete. I have no clear
idea on how to generate AMFs HDR metadata structure, or where
to even take this information from.
---
libavcodec/amfenc.h | 1 +
libavcodec/amfenc_h264.c | 48 +++++++++++++++++++++++++++++++++++++-
libavcodec/amfenc_hevc.c | 50 ++++++++++++++++++++++++++++++++++++++++
3 files changed, 98 insertions(+), 1 deletion(-)
diff --git a/libavcodec/amfenc.h b/libavcodec/amfenc.h
index 358b2ef778..951e529362 100644
--- a/libavcodec/amfenc.h
+++ b/libavcodec/amfenc.h
@@ -21,6 +21,7 @@
#include <AMF/core/Factory.h>
+#include <AMF/components/ColorSpace.h>
#include <AMF/components/VideoEncoderVCE.h>
#include <AMF/components/VideoEncoderHEVC.h>
diff --git a/libavcodec/amfenc_h264.c b/libavcodec/amfenc_h264.c
index aeca99f7c6..009378e9f1 100644
--- a/libavcodec/amfenc_h264.c
+++ b/libavcodec/amfenc_h264.c
@@ -137,6 +137,8 @@ static av_cold int amf_encode_init_h264(AVCodecContext *avctx)
AMFRate framerate;
AMFSize framesize = AMFConstructSize(avctx->width, avctx->height);
int deblocking_filter = (avctx->flags & AV_CODEC_FLAG_LOOP_FILTER) ? 1 : 0;
+ amf_int64 color_depth;
+ amf_int64 color_profile;
if (avctx->framerate.num > 0 && avctx->framerate.den > 0) {
framerate = AMFConstructRate(avctx->framerate.num, avctx->framerate.den);
@@ -194,10 +196,54 @@ static av_cold int amf_encode_init_h264(AVCodecContext *avctx)
AMF_ASSIGN_PROPERTY_RATIO(res, ctx->encoder, AMF_VIDEO_ENCODER_ASPECT_RATIO, ratio);
}
- /// Color Range (Partial/TV/MPEG or Full/PC/JPEG)
+ // Color Metadata
+ /// Color Range (Support for older Drivers)
if (avctx->color_range == AVCOL_RANGE_JPEG) {
AMF_ASSIGN_PROPERTY_BOOL(res, ctx->encoder, AMF_VIDEO_ENCODER_FULL_RANGE_COLOR, 1);
+ } else {
+ AMF_ASSIGN_PROPERTY_BOOL(res, ctx->encoder, AMF_VIDEO_ENCODER_FULL_RANGE_COLOR, 0);
+ }
+ /// Color Space & Depth
+ color_depth = AMF_COLOR_BIT_DEPTH_8;
+ color_profile = AMF_VIDEO_CONVERTER_COLOR_PROFILE_UNKNOWN;
+ switch (avctx->colorspace) {
+ case AVCOL_SPC_SMPTE170M:
+ if (avctx->color_range == AVCOL_RANGE_JPEG) {
+ color_profile = AMF_VIDEO_CONVERTER_COLOR_PROFILE_FULL_601;
+ } else {
+ color_profile = AMF_VIDEO_CONVERTER_COLOR_PROFILE_601;
+ }
+ break;
+ case AVCOL_SPC_BT709:
+ if (avctx->color_range == AVCOL_RANGE_JPEG) {
+ color_profile = AMF_VIDEO_CONVERTER_COLOR_PROFILE_FULL_709;
+ } else {
+ color_profile = AMF_VIDEO_CONVERTER_COLOR_PROFILE_709;
+ }
+ break;
+ case AVCOL_SPC_BT2020_NCL:
+ case AVCOL_SPC_BT2020_CL:
+ // !FIXME: Verify that this is correct on Hardware supporting it.
+ // !FIXME: Figure out how to decide on bit depth.
+ if (avctx->color_range == AVCOL_RANGE_JPEG) {
+ color_profile = AMF_VIDEO_CONVERTER_COLOR_PROFILE_FULL_2020;
+ color_depth = AMF_COLOR_BIT_DEPTH_10;
+ } else {
+ color_profile = AMF_VIDEO_CONVERTER_COLOR_PROFILE_2020;
+ color_depth = AMF_COLOR_BIT_DEPTH_10;
+ }
+ break;
}
+ AMF_ASSIGN_PROPERTY_INT64(res, ctx->encoder, AMF_VIDEO_ENCODER_COLOR_BIT_DEPTH, color_depth);
+ AMF_ASSIGN_PROPERTY_INT64(res, ctx->encoder, AMF_VIDEO_ENCODER_INPUT_COLOR_PROFILE, color_profile);
+ AMF_ASSIGN_PROPERTY_INT64(res, ctx->encoder, AMF_VIDEO_ENCODER_OUTPUT_COLOR_PROFILE, color_profile);
+ /// Color Transfer Characteristics (AMF matches ISO/IEC)
+ AMF_ASSIGN_PROPERTY_INT64(res, ctx->encoder, AMF_VIDEO_ENCODER_INPUT_TRANSFER_CHARACTERISTIC, (amf_int64)avctx->color_trc);
+ AMF_ASSIGN_PROPERTY_INT64(res, ctx->encoder, AMF_VIDEO_ENCODER_OUTPUT_TRANSFER_CHARACTERISTIC, (amf_int64)avctx->color_trc);
+ /// Color Primaries (AMF matches ISO/IEC)
+ AMF_ASSIGN_PROPERTY_INT64(res, ctx->encoder, AMF_VIDEO_ENCODER_INPUT_COLOR_PRIMARIES, (amf_int64)avctx->color_primaries);
+ AMF_ASSIGN_PROPERTY_INT64(res, ctx->encoder, AMF_VIDEO_ENCODER_OUTPUT_COLOR_PRIMARIES, (amf_int64)avctx->color_primaries);
+ /// !TODO: AMF HDR Metadata generation
// autodetect rate control method
if (ctx->rate_control_mode == AMF_VIDEO_ENCODER_RATE_CONTROL_METHOD_UNKNOWN) {
diff --git a/libavcodec/amfenc_hevc.c b/libavcodec/amfenc_hevc.c
index 79541b9b2f..900e1482b4 100644
--- a/libavcodec/amfenc_hevc.c
+++ b/libavcodec/amfenc_hevc.c
@@ -104,6 +104,8 @@ static av_cold int amf_encode_init_hevc(AVCodecContext *avctx)
AMFRate framerate;
AMFSize framesize = AMFConstructSize(avctx->width, avctx->height);
int deblocking_filter = (avctx->flags & AV_CODEC_FLAG_LOOP_FILTER) ? 1 : 0;
+ amf_int64 color_depth;
+ amf_int64 color_profile;
if (avctx->framerate.num > 0 && avctx->framerate.den > 0) {
framerate = AMFConstructRate(avctx->framerate.num, avctx->framerate.den);
@@ -152,6 +154,54 @@ static av_cold int amf_encode_init_hevc(AVCodecContext *avctx)
AMFRatio ratio = AMFConstructRatio(avctx->sample_aspect_ratio.num, avctx->sample_aspect_ratio.den);
AMF_ASSIGN_PROPERTY_RATIO(res, ctx->encoder, AMF_VIDEO_ENCODER_HEVC_ASPECT_RATIO, ratio);
}
+
+ // Color Metadata
+ /// Color Range (Support for older Drivers)
+ if (avctx->color_range == AVCOL_RANGE_JPEG) {
+ AMF_ASSIGN_PROPERTY_BOOL(res, ctx->encoder, AMF_VIDEO_ENCODER_HEVC_NOMINAL_RANGE, 1);
+ } else {
+ AMF_ASSIGN_PROPERTY_BOOL(res, ctx->encoder, AMF_VIDEO_ENCODER_HEVC_NOMINAL_RANGE, 0);
+ }
+ /// Color Space & Depth
+ color_depth = AMF_COLOR_BIT_DEPTH_8;
+ color_profile = AMF_VIDEO_CONVERTER_COLOR_PROFILE_UNKNOWN;
+ switch (avctx->colorspace) {
+ case AVCOL_SPC_SMPTE170M:
+ if (avctx->color_range == AVCOL_RANGE_JPEG) {
+ color_profile = AMF_VIDEO_CONVERTER_COLOR_PROFILE_FULL_601;
+ } else {
+ color_profile = AMF_VIDEO_CONVERTER_COLOR_PROFILE_601;
+ }
+ break;
+ case AVCOL_SPC_BT709:
+ if (avctx->color_range == AVCOL_RANGE_JPEG) {
+ color_profile = AMF_VIDEO_CONVERTER_COLOR_PROFILE_FULL_709;
+ } else {
+ color_profile = AMF_VIDEO_CONVERTER_COLOR_PROFILE_709;
+ }
+ break;
+ case AVCOL_SPC_BT2020_NCL:
+ case AVCOL_SPC_BT2020_CL:
+ // !FIXME: Verify that this is correct on Hardware supporting it.
+ // !FIXME: Figure out how to decide on bit depth.
+ if (avctx->color_range == AVCOL_RANGE_JPEG) {
+ color_profile = AMF_VIDEO_CONVERTER_COLOR_PROFILE_FULL_2020;
+ color_depth = AMF_COLOR_BIT_DEPTH_10;
+ } else {
+ color_profile = AMF_VIDEO_CONVERTER_COLOR_PROFILE_2020;
+ color_depth = AMF_COLOR_BIT_DEPTH_10;
+ }
+ break;
+ }
+ AMF_ASSIGN_PROPERTY_INT64(res, ctx->encoder, AMF_VIDEO_ENCODER_HEVC_COLOR_BIT_DEPTH, color_depth);
+ AMF_ASSIGN_PROPERTY_INT64(res, ctx->encoder, AMF_VIDEO_ENCODER_HEVC_INPUT_COLOR_PROFILE, color_profile);
+ AMF_ASSIGN_PROPERTY_INT64(res, ctx->encoder, AMF_VIDEO_ENCODER_HEVC_OUTPUT_COLOR_PROFILE, color_profile);
+ /// Color Transfer Characteristics (AMF matches ISO/IEC)
+ AMF_ASSIGN_PROPERTY_INT64(res, ctx->encoder, AMF_VIDEO_ENCODER_HEVC_INPUT_TRANSFER_CHARACTERISTIC, (amf_int64)avctx->color_trc);
+ AMF_ASSIGN_PROPERTY_INT64(res, ctx->encoder, AMF_VIDEO_ENCODER_HEVC_OUTPUT_TRANSFER_CHARACTERISTIC, (amf_int64)avctx->color_trc);
+ /// Color Primaries (AMF matches ISO/IEC)
+ AMF_ASSIGN_PROPERTY_INT64(res, ctx->encoder, AMF_VIDEO_ENCODER_HEVC_INPUT_COLOR_PRIMARIES, (amf_int64)avctx->color_primaries);
+ AMF_ASSIGN_PROPERTY_INT64(res, ctx->encoder, AMF_VIDEO_ENCODER_HEVC_OUTPUT_COLOR_PRIMARIES, (amf_int64)avctx->color_primaries);
// Picture control properties
AMF_ASSIGN_PROPERTY_INT64(res, ctx->encoder, AMF_VIDEO_ENCODER_HEVC_NUM_GOPS_PER_IDR, ctx->gops_per_idr);
--
2.34.1.windows.1
@@ -0,0 +1,61 @@
From d622fed60be525e5ff814f1eb703c67d3be0ed0e Mon Sep 17 00:00:00 2001
Message-Id: <d622fed60be525e5ff814f1eb703c67d3be0ed0e.1642029358.git.info@xaymar.com>
In-Reply-To: <a440dce6b5c8b90e80660641d632c60a4cc1c1bd.1642029358.git.info@xaymar.com>
References: <a440dce6b5c8b90e80660641d632c60a4cc1c1bd.1642029358.git.info@xaymar.com>
From: Michael Fabian 'Xaymar' Dirks <michael.dirks@xaymar.com>
Date: Tue, 11 Jan 2022 08:22:16 +0100
Subject: [PATCH 3/5] avcodec/amfenc: Add the new usage presets
These enable some new features that otherwise require another
AMF component to be loaded. Requires AMF SDK 1.4.23 or newer.
---
libavcodec/amfenc_h264.c | 12 +++++++-----
libavcodec/amfenc_hevc.c | 6 ++++--
2 files changed, 11 insertions(+), 7 deletions(-)
diff --git a/libavcodec/amfenc_h264.c b/libavcodec/amfenc_h264.c
index 009378e9f1..afac97a968 100644
--- a/libavcodec/amfenc_h264.c
+++ b/libavcodec/amfenc_h264.c
@@ -28,11 +28,13 @@
static const AVOption options[] = {
// Static
/// Usage
- { "usage", "Encoder Usage", OFFSET(usage), AV_OPT_TYPE_INT, { .i64 = AMF_VIDEO_ENCODER_USAGE_TRANSCONDING }, AMF_VIDEO_ENCODER_USAGE_TRANSCONDING, AMF_VIDEO_ENCODER_USAGE_WEBCAM, VE, "usage" },
- { "transcoding", "Generic Transcoding", 0, AV_OPT_TYPE_CONST, { .i64 = AMF_VIDEO_ENCODER_USAGE_TRANSCONDING }, 0, 0, VE, "usage" },
- { "ultralowlatency","", 0, AV_OPT_TYPE_CONST, { .i64 = AMF_VIDEO_ENCODER_USAGE_ULTRA_LOW_LATENCY }, 0, 0, VE, "usage" },
- { "lowlatency", "", 0, AV_OPT_TYPE_CONST, { .i64 = AMF_VIDEO_ENCODER_USAGE_LOW_LATENCY }, 0, 0, VE, "usage" },
- { "webcam", "Webcam", 0, AV_OPT_TYPE_CONST, { .i64 = AMF_VIDEO_ENCODER_USAGE_WEBCAM }, 0, 0, VE, "usage" },
+ { "usage", "Encoder Usage", OFFSET(usage), AV_OPT_TYPE_INT, { .i64 = AMF_VIDEO_ENCODER_USAGE_TRANSCODING }, AMF_VIDEO_ENCODER_USAGE_TRANSCODING, AMF_VIDEO_ENCODER_USAGE_LOW_LATENCY_HIGH_QUALITY, VE, "usage" },
+ { "transcoding", "Generic Transcoding", 0, AV_OPT_TYPE_CONST, { .i64 = AMF_VIDEO_ENCODER_USAGE_TRANSCODING }, 0, 0, VE, "usage" },
+ { "ultralowlatency", "", 0, AV_OPT_TYPE_CONST, { .i64 = AMF_VIDEO_ENCODER_USAGE_ULTRA_LOW_LATENCY }, 0, 0, VE, "usage" },
+ { "lowlatency", "", 0, AV_OPT_TYPE_CONST, { .i64 = AMF_VIDEO_ENCODER_USAGE_LOW_LATENCY }, 0, 0, VE, "usage" },
+ { "webcam", "Webcam", 0, AV_OPT_TYPE_CONST, { .i64 = AMF_VIDEO_ENCODER_USAGE_WEBCAM }, 0, 0, VE, "usage" },
+ { "highquality", "", 0, AV_OPT_TYPE_CONST, { .i64 = AMF_VIDEO_ENCODER_USAGE_HIGH_QUALITY }, 0, 0, VE, "usage" },
+ { "lowlatency_highqquality", "", 0, AV_OPT_TYPE_CONST, { .i64 = AMF_VIDEO_ENCODER_USAGE_LOW_LATENCY_HIGH_QUALITY }, 0, 0, VE, "usage" },
/// Profile,
{ "profile", "Profile", OFFSET(profile),AV_OPT_TYPE_INT, { .i64 = AMF_VIDEO_ENCODER_PROFILE_MAIN }, AMF_VIDEO_ENCODER_PROFILE_BASELINE, AMF_VIDEO_ENCODER_PROFILE_CONSTRAINED_HIGH, VE, "profile" },
diff --git a/libavcodec/amfenc_hevc.c b/libavcodec/amfenc_hevc.c
index 900e1482b4..b7fee950f6 100644
--- a/libavcodec/amfenc_hevc.c
+++ b/libavcodec/amfenc_hevc.c
@@ -24,11 +24,13 @@
#define OFFSET(x) offsetof(AmfContext, x)
#define VE AV_OPT_FLAG_VIDEO_PARAM | AV_OPT_FLAG_ENCODING_PARAM
static const AVOption options[] = {
- { "usage", "Set the encoding usage", OFFSET(usage), AV_OPT_TYPE_INT, { .i64 = AMF_VIDEO_ENCODER_HEVC_USAGE_TRANSCONDING }, AMF_VIDEO_ENCODER_HEVC_USAGE_TRANSCONDING, AMF_VIDEO_ENCODER_HEVC_USAGE_WEBCAM, VE, "usage" },
- { "transcoding", "", 0, AV_OPT_TYPE_CONST, { .i64 = AMF_VIDEO_ENCODER_HEVC_USAGE_TRANSCONDING }, 0, 0, VE, "usage" },
+ { "usage", "Set the encoding usage", OFFSET(usage), AV_OPT_TYPE_INT, { .i64 = AMF_VIDEO_ENCODER_HEVC_USAGE_TRANSCODING }, AMF_VIDEO_ENCODER_HEVC_USAGE_TRANSCODING, AMF_VIDEO_ENCODER_HEVC_USAGE_LOW_LATENCY_HIGH_QUALITY, VE, "usage" },
+ { "transcoding", "", 0, AV_OPT_TYPE_CONST, { .i64 = AMF_VIDEO_ENCODER_HEVC_USAGE_TRANSCODING }, 0, 0, VE, "usage" },
{ "ultralowlatency","", 0, AV_OPT_TYPE_CONST, { .i64 = AMF_VIDEO_ENCODER_HEVC_USAGE_ULTRA_LOW_LATENCY }, 0, 0, VE, "usage" },
{ "lowlatency", "", 0, AV_OPT_TYPE_CONST, { .i64 = AMF_VIDEO_ENCODER_HEVC_USAGE_LOW_LATENCY }, 0, 0, VE, "usage" },
{ "webcam", "", 0, AV_OPT_TYPE_CONST, { .i64 = AMF_VIDEO_ENCODER_HEVC_USAGE_WEBCAM }, 0, 0, VE, "usage" },
+ { "highquality", "", 0, AV_OPT_TYPE_CONST, { .i64 = AMF_VIDEO_ENCODER_HEVC_USAGE_HIGH_QUALITY }, 0, 0, VE, "usage" },
+ { "lowlatency_highqquality", "", 0, AV_OPT_TYPE_CONST, { .i64 = AMF_VIDEO_ENCODER_HEVC_USAGE_LOW_LATENCY_HIGH_QUALITY }, 0, 0, VE, "usage" },
{ "profile", "Set the profile (default main)", OFFSET(profile), AV_OPT_TYPE_INT,{ .i64 = AMF_VIDEO_ENCODER_HEVC_PROFILE_MAIN }, AMF_VIDEO_ENCODER_HEVC_PROFILE_MAIN, AMF_VIDEO_ENCODER_HEVC_PROFILE_MAIN, VE, "profile" },
{ "main", "", 0, AV_OPT_TYPE_CONST,{ .i64 = AMF_VIDEO_ENCODER_HEVC_PROFILE_MAIN }, 0, 0, VE, "profile" },
--
2.34.1.windows.1
@@ -0,0 +1,80 @@
From 9cbaf2a700356682713bd01b2a6df3bc8d85c228 Mon Sep 17 00:00:00 2001
Message-Id: <9cbaf2a700356682713bd01b2a6df3bc8d85c228.1642029358.git.info@xaymar.com>
In-Reply-To: <a440dce6b5c8b90e80660641d632c60a4cc1c1bd.1642029358.git.info@xaymar.com>
References: <a440dce6b5c8b90e80660641d632c60a4cc1c1bd.1642029358.git.info@xaymar.com>
From: Michael Fabian 'Xaymar' Dirks <michael.dirks@xaymar.com>
Date: Tue, 11 Jan 2022 08:23:37 +0100
Subject: [PATCH 4/5] avcodec/amfenc: Add "High Motion Quality Boost" option
This option was missing from amfenc, and is now available.
---
libavcodec/amfenc.h | 3 +++
libavcodec/amfenc_h264.c | 2 ++
libavcodec/amfenc_hevc.c | 3 ++-
3 files changed, 7 insertions(+), 1 deletion(-)
diff --git a/libavcodec/amfenc.h b/libavcodec/amfenc.h
index 951e529362..f47e6a1200 100644
--- a/libavcodec/amfenc.h
+++ b/libavcodec/amfenc.h
@@ -108,6 +108,9 @@ typedef struct AmfContext {
int me_quarter_pel;
int aud;
+ // Unclear options, have different behavior based on codec.
+ int hmqb;
+
// HEVC - specific options
int gops_per_idr;
diff --git a/libavcodec/amfenc_h264.c b/libavcodec/amfenc_h264.c
index afac97a968..87a3bb6a73 100644
--- a/libavcodec/amfenc_h264.c
+++ b/libavcodec/amfenc_h264.c
@@ -86,6 +86,7 @@ static const AVOption options[] = {
{ "filler_data", "Filler Data Enable", OFFSET(filler_data), AV_OPT_TYPE_BOOL, { .i64 = 0 }, 0, 1, VE },
{ "vbaq", "Enable VBAQ", OFFSET(enable_vbaq), AV_OPT_TYPE_BOOL, { .i64 = 0 }, 0, 1, VE },
{ "frame_skipping", "Rate Control Based Frame Skip", OFFSET(skip_frame), AV_OPT_TYPE_BOOL, { .i64 = 0 }, 0, 1, VE },
+ { "hmqb", "High Motion Quality Boost", OFFSET(hmqb), AV_OPT_TYPE_BOOL, { .i64 = 0 }, 0, 1, VE },
/// QP Values
{ "qp_i", "Quantization Parameter for I-Frame", OFFSET(qp_i), AV_OPT_TYPE_INT, { .i64 = -1 }, -1, 51, VE },
@@ -331,6 +332,7 @@ static av_cold int amf_encode_init_h264(AVCodecContext *avctx)
AMF_ASSIGN_PROPERTY_BOOL(res, ctx->encoder, AMF_VIDEO_ENCODER_ENFORCE_HRD, !!ctx->enforce_hrd);
AMF_ASSIGN_PROPERTY_BOOL(res, ctx->encoder, AMF_VIDEO_ENCODER_FILLER_DATA_ENABLE, !!ctx->filler_data);
AMF_ASSIGN_PROPERTY_BOOL(res, ctx->encoder, AMF_VIDEO_ENCODER_RATE_CONTROL_SKIP_FRAME_ENABLE, !!ctx->skip_frame);
+ AMF_ASSIGN_PROPERTY_BOOL(res, ctx->encoder, AMF_VIDEO_ENCODER_HIGH_MOTION_QUALITY_BOOST_ENABLE, !!ctx->hmqb);
if (ctx->rate_control_mode == AMF_VIDEO_ENCODER_RATE_CONTROL_METHOD_CONSTANT_QP) {
AMF_ASSIGN_PROPERTY_BOOL(res, ctx->encoder, AMF_VIDEO_ENCODER_ENABLE_VBAQ, 0);
if (ctx->enable_vbaq)
diff --git a/libavcodec/amfenc_hevc.c b/libavcodec/amfenc_hevc.c
index b7fee950f6..565be9bad9 100644
--- a/libavcodec/amfenc_hevc.c
+++ b/libavcodec/amfenc_hevc.c
@@ -74,6 +74,7 @@ static const AVOption options[] = {
{ "gops_per_idr", "GOPs per IDR 0-no IDR will be inserted", OFFSET(gops_per_idr), AV_OPT_TYPE_INT, { .i64 = 1 }, 0, INT_MAX, VE },
{ "preanalysis", "Enable preanalysis", OFFSET(preanalysis), AV_OPT_TYPE_BOOL, { .i64 = 0 }, 0, 1, VE},
{ "vbaq", "Enable VBAQ", OFFSET(enable_vbaq), AV_OPT_TYPE_BOOL, { .i64 = 0 }, 0, 1, VE},
+ { "hmqb", "High Motion Quality Boost", OFFSET(hmqb), AV_OPT_TYPE_BOOL, { .i64 = 0 }, 0, 1, VE },
{ "enforce_hrd", "Enforce HRD", OFFSET(enforce_hrd), AV_OPT_TYPE_BOOL, { .i64 = 0 }, 0, 1, VE},
{ "filler_data", "Filler Data Enable", OFFSET(filler_data), AV_OPT_TYPE_BOOL, { .i64 = 0 }, 0, 1, VE},
{ "max_au_size", "Maximum Access Unit Size for rate control (in bits)", OFFSET(max_au_size), AV_OPT_TYPE_INT,{ .i64 = 0 }, 0, INT_MAX, VE},
@@ -231,7 +232,6 @@ static av_cold int amf_encode_init_hevc(AVCodecContext *avctx)
}
}
-
AMF_ASSIGN_PROPERTY_INT64(res, ctx->encoder, AMF_VIDEO_ENCODER_HEVC_RATE_CONTROL_METHOD, ctx->rate_control_mode);
if (avctx->rc_buffer_size) {
AMF_ASSIGN_PROPERTY_INT64(res, ctx->encoder, AMF_VIDEO_ENCODER_HEVC_VBV_BUFFER_SIZE, avctx->rc_buffer_size);
@@ -253,6 +253,7 @@ static av_cold int amf_encode_init_hevc(AVCodecContext *avctx)
} else {
AMF_ASSIGN_PROPERTY_BOOL(res, ctx->encoder, AMF_VIDEO_ENCODER_HEVC_ENABLE_VBAQ, !!ctx->enable_vbaq);
}
+ AMF_ASSIGN_PROPERTY_BOOL(res, ctx->encoder, AMF_VIDEO_ENCODER_HEVC_HIGH_MOTION_QUALITY_BOOST_ENABLE, !!ctx->hmqb);
AMF_ASSIGN_PROPERTY_BOOL(res, ctx->encoder, AMF_VIDEO_ENCODER_HEVC_MOTION_HALF_PIXEL, ctx->me_half_pel);
AMF_ASSIGN_PROPERTY_BOOL(res, ctx->encoder, AMF_VIDEO_ENCODER_HEVC_MOTION_QUARTERPIXEL, ctx->me_quarter_pel);
--
2.34.1.windows.1
@@ -0,0 +1,52 @@
From ebf6229908e96c3f8d6144b19fc42f5346e3b628 Mon Sep 17 00:00:00 2001
Message-Id: <ebf6229908e96c3f8d6144b19fc42f5346e3b628.1642029358.git.info@xaymar.com>
In-Reply-To: <a440dce6b5c8b90e80660641d632c60a4cc1c1bd.1642029358.git.info@xaymar.com>
References: <a440dce6b5c8b90e80660641d632c60a4cc1c1bd.1642029358.git.info@xaymar.com>
From: Michael Fabian 'Xaymar' Dirks <michael.dirks@xaymar.com>
Date: Tue, 11 Jan 2022 08:24:11 +0100
Subject: [PATCH 5/5] avcodec/amfenc: Add missing profiles
Adds the missing profiles to the '-help encoder=xxx_amf' list,
even if the user may never need these.
---
libavcodec/amfenc_h264.c | 11 ++++++-----
libavcodec/amfenc_hevc.c | 1 +
2 files changed, 7 insertions(+), 5 deletions(-)
diff --git a/libavcodec/amfenc_h264.c b/libavcodec/amfenc_h264.c
index 87a3bb6a73..ae21c60357 100644
--- a/libavcodec/amfenc_h264.c
+++ b/libavcodec/amfenc_h264.c
@@ -37,11 +37,12 @@ static const AVOption options[] = {
{ "lowlatency_highqquality", "", 0, AV_OPT_TYPE_CONST, { .i64 = AMF_VIDEO_ENCODER_USAGE_LOW_LATENCY_HIGH_QUALITY }, 0, 0, VE, "usage" },
/// Profile,
- { "profile", "Profile", OFFSET(profile),AV_OPT_TYPE_INT, { .i64 = AMF_VIDEO_ENCODER_PROFILE_MAIN }, AMF_VIDEO_ENCODER_PROFILE_BASELINE, AMF_VIDEO_ENCODER_PROFILE_CONSTRAINED_HIGH, VE, "profile" },
- { "main", "", 0, AV_OPT_TYPE_CONST, { .i64 = AMF_VIDEO_ENCODER_PROFILE_MAIN }, 0, 0, VE, "profile" },
- { "high", "", 0, AV_OPT_TYPE_CONST, { .i64 = AMF_VIDEO_ENCODER_PROFILE_HIGH }, 0, 0, VE, "profile" },
- { "constrained_baseline", "", 0, AV_OPT_TYPE_CONST, { .i64 = AMF_VIDEO_ENCODER_PROFILE_CONSTRAINED_BASELINE }, 0, 0, VE, "profile" },
- { "constrained_high", "", 0, AV_OPT_TYPE_CONST, { .i64 = AMF_VIDEO_ENCODER_PROFILE_CONSTRAINED_HIGH }, 0, 0, VE, "profile" },
+ { "profile", "Profile", OFFSET(profile), AV_OPT_TYPE_INT, { .i64 = AMF_VIDEO_ENCODER_PROFILE_MAIN }, AMF_VIDEO_ENCODER_PROFILE_BASELINE, AMF_VIDEO_ENCODER_PROFILE_CONSTRAINED_HIGH, VE, "profile" },
+ { "baseline", "", 0, AV_OPT_TYPE_CONST, { .i64 = AMF_VIDEO_ENCODER_PROFILE_BASELINE }, 0, 0, VE, "profile" },
+ { "main", "", 0, AV_OPT_TYPE_CONST, { .i64 = AMF_VIDEO_ENCODER_PROFILE_MAIN }, 0, 0, VE, "profile" },
+ { "high", "", 0, AV_OPT_TYPE_CONST, { .i64 = AMF_VIDEO_ENCODER_PROFILE_HIGH }, 0, 0, VE, "profile" },
+ { "constrained_baseline", "", 0, AV_OPT_TYPE_CONST, { .i64 = AMF_VIDEO_ENCODER_PROFILE_CONSTRAINED_BASELINE }, 0, 0, VE, "profile" },
+ { "constrained_high", "", 0, AV_OPT_TYPE_CONST, { .i64 = AMF_VIDEO_ENCODER_PROFILE_CONSTRAINED_HIGH }, 0, 0, VE, "profile" },
/// Profile Level
{ "level", "Profile Level", OFFSET(level), AV_OPT_TYPE_INT, { .i64 = 0 }, 0, 62, VE, "level" },
diff --git a/libavcodec/amfenc_hevc.c b/libavcodec/amfenc_hevc.c
index 565be9bad9..a69f37e7b1 100644
--- a/libavcodec/amfenc_hevc.c
+++ b/libavcodec/amfenc_hevc.c
@@ -34,6 +34,7 @@ static const AVOption options[] = {
{ "profile", "Set the profile (default main)", OFFSET(profile), AV_OPT_TYPE_INT,{ .i64 = AMF_VIDEO_ENCODER_HEVC_PROFILE_MAIN }, AMF_VIDEO_ENCODER_HEVC_PROFILE_MAIN, AMF_VIDEO_ENCODER_HEVC_PROFILE_MAIN, VE, "profile" },
{ "main", "", 0, AV_OPT_TYPE_CONST,{ .i64 = AMF_VIDEO_ENCODER_HEVC_PROFILE_MAIN }, 0, 0, VE, "profile" },
+ { "main10", "", 0, AV_OPT_TYPE_CONST,{ .i64 = AMF_VIDEO_ENCODER_HEVC_PROFILE_MAIN_10 }, 0, 0, VE, "profile" },
{ "profile_tier", "Set the profile tier (default main)", OFFSET(tier), AV_OPT_TYPE_INT,{ .i64 = AMF_VIDEO_ENCODER_HEVC_TIER_MAIN }, AMF_VIDEO_ENCODER_HEVC_TIER_MAIN, AMF_VIDEO_ENCODER_HEVC_TIER_HIGH, VE, "tier" },
{ "main", "", 0, AV_OPT_TYPE_CONST, { .i64 = AMF_VIDEO_ENCODER_HEVC_TIER_MAIN }, 0, 0, VE, "tier" },
--
2.34.1.windows.1
@@ -1,148 +0,0 @@
From 9b88662cdf8d38b7d747b1c0eec85662f8eab2ec Mon Sep 17 00:00:00 2001
From: Michael Fabian 'Xaymar' Dirks <michael.dirks@xaymar.com>
Date: Wed, 19 May 2021 01:39:54 +0200
Subject: [PATCH] avformat/matroskaenc: Allow changing the time stamp precision
via option
Adds "timestamp_precision" to the available options for Matroska muxing.
The option enables users and developers to change the precision of the
time stamps in the Matroska container up to 1 nanosecond, which can aid
with the proper detection of constant and variable rate content.
Work-around fix for: 259, 6406, 7927, 8909 and 9124.
Signed-off-by: Michael Fabian 'Xaymar' Dirks <michael.dirks@xaymar.com>
---
doc/muxers.texi | 8 ++++++++
libavformat/matroskaenc.c | 33 ++++++++++++++++++++++++++-------
2 files changed, 34 insertions(+), 7 deletions(-)
diff --git a/doc/muxers.texi b/doc/muxers.texi
index e1c6ad0829..8655be94ff 100644
--- a/doc/muxers.texi
+++ b/doc/muxers.texi
@@ -1583,6 +1583,14 @@ bitmap is stored bottom-up. Note that this option does not flip the bitmap
which has to be done manually beforehand, e.g. by using the vflip filter.
Default is @var{false} and indicates bitmap is stored top down.
+@item timestamp_precision
+Sets the timestamp precision up to 1 nanosecond for Matroska/WebM, which can
+improve detection of constant rate content in demuxers. Note that some poorly
+implemented demuxers may require a timestamp precision of 1 millisecond, so
+increasing it past that point may result in playback issues. Higher precision
+also reduces the maximum possible timestamp significantly.
+Default is @var{1/1000} (1 millisecond).
+
@end table
@anchor{md5}
diff --git a/libavformat/matroskaenc.c b/libavformat/matroskaenc.c
index 186a25d920..1b911a648c 100644
--- a/libavformat/matroskaenc.c
+++ b/libavformat/matroskaenc.c
@@ -158,6 +158,8 @@ typedef struct MatroskaMuxContext {
int default_mode;
uint32_t segment_uid[4];
+
+ AVRational time_base;
} MatroskaMuxContext;
/** 2 bytes * 7 for EBML IDs, 7 1-byte EBML lengths, 6 1-byte uint,
@@ -1814,6 +1816,7 @@ static int mkv_write_header(AVFormatContext *s)
const AVDictionaryEntry *tag;
int ret, i, version = 2;
int64_t creation_time;
+ int64_t time_base = 1;
if (mkv->mode != MODE_WEBM ||
av_dict_get(s->metadata, "stereo_mode", NULL, 0) ||
@@ -1850,7 +1853,10 @@ static int mkv_write_header(AVFormatContext *s)
return ret;
pb = mkv->info.bc;
- put_ebml_uint(pb, MATROSKA_ID_TIMECODESCALE, 1000000);
+ time_base = av_rescale_q(time_base, mkv->time_base, (AVRational){1, 1000000000});
+ av_log(s, AV_LOG_DEBUG, "TimestampScale is: %" PRId64 " ns\n", time_base);
+ put_ebml_uint(pb, MATROSKA_ID_TIMECODESCALE, time_base);
+
if ((tag = av_dict_get(s->metadata, "title", NULL, 0)))
put_ebml_string(pb, MATROSKA_ID_TITLE, tag->value);
if (!(s->flags & AVFMT_FLAG_BITEXACT)) {
@@ -1883,11 +1889,11 @@ static int mkv_write_header(AVFormatContext *s)
int64_t metadata_duration = get_metadata_duration(s);
if (s->duration > 0) {
- int64_t scaledDuration = av_rescale(s->duration, 1000, AV_TIME_BASE);
+ int64_t scaledDuration = av_rescale_q(s->duration, AV_TIME_BASE_Q, mkv->time_base);
put_ebml_float(pb, MATROSKA_ID_DURATION, scaledDuration);
av_log(s, AV_LOG_DEBUG, "Write early duration from recording time = %" PRIu64 "\n", scaledDuration);
} else if (metadata_duration > 0) {
- int64_t scaledDuration = av_rescale(metadata_duration, 1000, AV_TIME_BASE);
+ int64_t scaledDuration = av_rescale_q(metadata_duration, AV_TIME_BASE_Q, mkv->time_base);
put_ebml_float(pb, MATROSKA_ID_DURATION, scaledDuration);
av_log(s, AV_LOG_DEBUG, "Write early duration from metadata = %" PRIu64 "\n", scaledDuration);
} else if (s->pb->seekable & AVIO_SEEKABLE_NORMAL) {
@@ -1948,12 +1954,12 @@ static int mkv_write_header(AVFormatContext *s)
// after 4k and on a keyframe
if (IS_SEEKABLE(pb, mkv)) {
if (mkv->cluster_time_limit < 0)
- mkv->cluster_time_limit = 5000;
+ mkv->cluster_time_limit = av_rescale_q(5000, (AVRational){1, 1000}, mkv->time_base);
if (mkv->cluster_size_limit < 0)
mkv->cluster_size_limit = 5 * 1024 * 1024;
} else {
if (mkv->cluster_time_limit < 0)
- mkv->cluster_time_limit = 1000;
+ mkv->cluster_time_limit = av_rescale_q(1000, (AVRational){1, 1000}, mkv->time_base);
if (mkv->cluster_size_limit < 0)
mkv->cluster_size_limit = 32 * 1024;
}
@@ -2713,6 +2719,14 @@ static int mkv_init(struct AVFormatContext *s)
} else
mkv->mode = MODE_MATROSKAv2;
+ // WebM requires a timestamp precision of 1ms.
+ if (mkv->mode == MODE_WEBM) {
+ if (av_cmp_q(mkv->time_base, (AVRational){1, 1000}) != 0) {
+ av_log(s, AV_LOG_ERROR, "WebM requires 1ms timestamp precision\n");
+ return AVERROR(EINVAL);
+ }
+ }
+
mkv->cur_audio_pkt = av_packet_alloc();
if (!mkv->cur_audio_pkt)
return AVERROR(ENOMEM);
@@ -2738,8 +2752,8 @@ static int mkv_init(struct AVFormatContext *s)
track->uid = mkv_get_uid(mkv->tracks, i, &c);
}
- // ms precision is the de-facto standard timescale for mkv files
- avpriv_set_pts_info(st, 64, 1, 1000);
+ // Use user-defined timescale.
+ avpriv_set_pts_info(st, 64, mkv->time_base.num, mkv->time_base.den);
if (st->codecpar->codec_type == AVMEDIA_TYPE_ATTACHMENT) {
if (mkv->mode == MODE_WEBM) {
@@ -2759,6 +2773,10 @@ static int mkv_init(struct AVFormatContext *s)
track->track_num_size = ebml_num_size(track->track_num);
}
+ // Scale the configured cluster_time_limit.
+ if (mkv->cluster_time_limit >= 0)
+ mkv->cluster_time_limit = av_rescale_q(mkv->cluster_time_limit, (AVRational){1, 1000}, mkv->time_base);
+
if (mkv->is_dash && nb_tracks != 1)
return AVERROR(EINVAL);
@@ -2826,6 +2844,7 @@ static const AVOption options[] = {
{ "infer", "For each track type, mark the first track of disposition default as default; if none exists, mark the first track as default.", 0, AV_OPT_TYPE_CONST, { .i64 = DEFAULT_MODE_INFER }, 0, 0, FLAGS, "default_mode" },
{ "infer_no_subs", "For each track type, mark the first track of disposition default as default; for audio and video: if none exists, mark the first track as default.", 0, AV_OPT_TYPE_CONST, { .i64 = DEFAULT_MODE_INFER_NO_SUBS }, 0, 0, FLAGS, "default_mode" },
{ "passthrough", "Use the disposition flag as-is", 0, AV_OPT_TYPE_CONST, { .i64 = DEFAULT_MODE_PASSTHROUGH }, 0, 0, FLAGS, "default_mode" },
+ { "timestamp_precision", "Timestamp precision to use for the entire container", OFFSET(time_base), AV_OPT_TYPE_RATIONAL, { .dbl = 0.001 }, 0.000000001, INT_MAX, FLAGS},
{ NULL },
};
--
2.31.1.windows.1
+141
View File
@@ -0,0 +1,141 @@
#!/bin/bash
REPOSITORY="https://github.com/mirror/mingw-w64.git"
GCC_SYSROOT="`${BUILD_PREFIX}-gcc -print-sysroot`"
mingw_clone() {
if [ ! -d /tmp/mingw ]; then
git clone -b "${MINGW_VERSION}" --depth 1 "${REPOSITORY}" /tmp/mingw
if [[ $? -ne 0 ]]; then return 1; fi
else
pushd /tmp/mingw > /dev/null
git fetch --all
if [[ $? -ne 0 ]]; then return 1; fi
git reset --hard "${MINGW_VERSION}"
if [[ $? -ne 0 ]]; then return 1; fi
popd > /dev/null
fi
}
mingw_build_crt() {
pushd /tmp/mingw/mingw-w64-crt > /dev/null
# Clear potentially passed flags.
unset CFLAGS
unset CXXFLAGS
unset LDFLAGS
unset PKG_CONFIG_LIBDIR
# Configure MinGW
local mingw_configure=(
--prefix="${GCC_SYSROOT}/usr/${BUILD_PREFIX}"
# --host=`gcc -dumpmachine`
--host="${BUILD_PREFIX}"
--enable-lib32
--enable-lib64
)
./configure ${mingw_configure[@]}
if [[ $? -ne 0 ]]; then return 1; fi
# Build MinGW
make -j`nproc`
if [[ $? -ne 0 ]]; then return 1; fi
# Install MinGW
sudo make install
if [[ $? -ne 0 ]]; then return 1; fi
popd > /dev/null
}
mingw_build_headers() {
pushd /tmp/mingw/mingw-w64-headers > /dev/null
# Clear potentially passed flags.
unset CFLAGS
unset CXXFLAGS
unset LDFLAGS
unset PKG_CONFIG_LIBDIR
# Configure MinGW
local mingw_configure=(
--prefix="${GCC_SYSROOT}/usr/${BUILD_PREFIX}"
# --host=`gcc -dumpmachine`
--host="${BUILD_PREFIX}"
--with-default-win32-winnt="0x0601"
--enable-idl
)
./configure ${mingw_configure[@]}
if [[ $? -ne 0 ]]; then return 1; fi
# Build MinGW
make -j`nproc`
if [[ $? -ne 0 ]]; then return 1; fi
# Install MinGW
sudo make install
if [[ $? -ne 0 ]]; then return 1; fi
popd > /dev/null
}
mingw_build_library_winpthreads() {
pushd /tmp/mingw/mingw-w64-libraries/winpthreads > /dev/null
# Clear potentially passed flags.
unset CFLAGS
unset CXXFLAGS
unset LDFLAGS
unset PKG_CONFIG_LIBDIR
# Configure MinGW
local mingw_configure=(
--prefix="${GCC_SYSROOT}/usr/${BUILD_PREFIX}"
--host="${BUILD_PREFIX}"
--disable-shared
--enable-static
--with-pic
)
./configure ${mingw_configure[@]}
if [[ $? -ne 0 ]]; then return 1; fi
# Build MinGW
make -j`nproc`
if [[ $? -ne 0 ]]; then return 1; fi
# Install MinGW
sudo make install
if [[ $? -ne 0 ]]; then return 1; fi
popd > /dev/null
}
mingw_build_libraries() {
mingw_build_library_winpthreads
if [[ $? -ne 0 ]]; then return 1; fi
}
mingw_build() {
pushd /tmp/mingw > /dev/null
# Clear potentially passed flags.
unset CFLAGS
unset CXXFLAGS
unset LDFLAGS
unset PKG_CONFIG_LIBDIR
#mingw_build_crt
#if [[ $? -ne 0 ]]; then return 1; fi
#mingw_build_headers
#if [[ $? -ne 0 ]]; then return 1; fi
#mingw_build_libraries
#if [[ $? -ne 0 ]]; then return 1; fi
popd > /dev/null
}
mingw_clone
if [[ $? -ne 0 ]]; then exit 1; fi
mingw_build
if [[ $? -ne 0 ]]; then exit 1; fi
+19
View File
@@ -0,0 +1,19 @@
REPOSITORY="https://github.com/GPUOpen-LibrariesAndSDKs/AMF.git"
function amd_amf() {
if [[ ${VERSION_MAJOR} -lt 4 ]]; then
return 0
fi
git clone --depth 1 --branch "${AMDAMF_VERSION}" "${REPOSITORY}" /tmp/amd-amf
if [[ $? -ne 0 ]]; then return 1; fi
pushd /tmp/amd-amf > /dev/null
if [[ $? -ne 0 ]]; then return 1; fi
sudo cp -R amf/public/include/ /usr/${BUILD_PREFIX}/include/AMF
if [[ $? -ne 0 ]]; then return 1; fi
popd > /dev/null
if [[ $? -ne 0 ]]; then return 1; fi
}
amd_amf
if [[ $? -ne 0 ]]; then exit 1; fi
+21
View File
@@ -0,0 +1,21 @@
REPOSITORY="https://git.videolan.org/git/ffmpeg/nv-codec-headers.git"
function nvidia_nvenc() {
if [[ ${VERSION_MAJOR} -lt 3 ]]; then
return 0
fi
git clone --depth 1 --branch "${NVIDIANVENC_VERSION}" "${REPOSITORY}" /tmp/nvidia-nvenc
if [[ $? -ne 0 ]]; then return 1; fi
pushd "/tmp/nvidia-nvenc" > /dev/null
if [[ $? -ne 0 ]]; then return 1; fi
make PREFIX=/usr/${BUILD_PREFIX}
if [[ $? -ne 0 ]]; then return 1; fi
sudo make PREFIX=/usr/${BUILD_PREFIX} install
if [[ $? -ne 0 ]]; then return 1; fi
popd > /dev/null
if [[ $? -ne 0 ]]; then return 1; fi
}
nvidia_nvenc
if [[ $? -ne 0 ]]; then exit 1; fi
+13
View File
@@ -0,0 +1,13 @@
function install_zlib() {
curl -L -o "/tmp/zlib.zip" "https://github.com/Xaymar/zlib-ng/releases/download/${ZLIB_VERSION}/zlib-ng-${BUILD_BITS}.zip"
if [[ $? -ne 0 ]]; then return 1; fi
7z x -o/tmp/zlib/ "/tmp/zlib.zip"
if [[ $? -ne 0 ]]; then return 1; fi
sudo cp -a /tmp/zlib/. /usr/${BUILD_PREFIX}/
if [[ $? -ne 0 ]]; then return 1; fi
cp -a /tmp/zlib/bin/*.dll ./distrib/bin/
if [[ $? -ne 0 ]]; then return 1; fi
}
install_zlib
if [[ $? -ne 0 ]]; then exit 1; fi
+21
View File
@@ -0,0 +1,21 @@
function install_aom() {
if [[ ${VERSION_MAJOR} -lt 4 ]]; then
return 0
fi
curl -L -o "/tmp/aom.7z" "https://github.com/Xaymar/aom/releases/download/${AOM_VERSION}/aom-windows-${BUILD_BITS}-shared.7z"
if [[ $? -ne 0 ]]; then return 1; fi
7z x -o/tmp/aom "/tmp/aom.7z"
if [[ $? -ne 0 ]]; then return 1; fi
sed -i -E "s/^prefix=.*$/prefix=\/usr\/${BUILD_PREFIX}/g" /tmp/aom/lib/pkgconfig/aom.pc
if [[ $? -ne 0 ]]; then return 1; fi
cp /tmp/aom/lib/pkgconfig/aom.pc /tmp/aom/lib/pkgconfig/libaom.pc
if [[ $? -ne 0 ]]; then return 1; fi
sudo cp -a /tmp/aom/. /usr/${BUILD_PREFIX}/
if [[ $? -ne 0 ]]; then return 1; fi
cp -a /tmp/aom/bin/*.dll ./distrib/bin/
if [[ $? -ne 0 ]]; then return 1; fi
}
install_aom
if [[ $? -ne 0 ]]; then exit 1; fi
+20
View File
@@ -0,0 +1,20 @@
function install_libx264() {
if [[ ${VERSION_MAJOR} -lt 1 ]]; then
return 0
fi
if [[ "${LICENSE}" != "GPL" ]]; then
return 0
fi
curl -L -o "/tmp/x264.zip" "https://github.com/Xaymar/x264/releases/download/${X264_VERSION}/x264-${BUILD_BITS}-shared-GPLv2.zip"
if [[ $? -ne 0 ]]; then return 1; fi
7z x -o/tmp/x264/ "/tmp/x264.zip"
if [[ $? -ne 0 ]]; then return 1; fi
sudo cp -a /tmp/x264/. /usr/${BUILD_PREFIX}/
if [[ $? -ne 0 ]]; then return 1; fi
cp -a /tmp/x264/bin/*.dll ./distrib/bin/
if [[ $? -ne 0 ]]; then return 1; fi
}
install_libx264
if [[ $? -ne 0 ]]; then exit 1; fi
+34
View File
@@ -0,0 +1,34 @@
function install_ffmpeg() {
export PKG_CONFIG_PATH=/usr/${BUILD_PREFIX}/lib/pkgconfig:${PKG_CONFIG_PATH}
# Configure FFmpeg
./configure \
--arch="${BUILD_ARCH}" \
--target-os="${BUILD_TARGET}" \
--cross-prefix="${BUILD_PREFIX}-" \
--prefix="${PWD}/distrib" \
--bindir="${PWD}/distrib/bin" \
--libdir="${PWD}/distrib/lib" \
--shlibdir="${PWD}/distrib/bin" \
--pkg-config=pkg-config \
--extra-cflags=-O3 --extra-cflags=-mmmx --extra-cflags=-msse --extra-cflags=-msse2 --extra-cflags=-msse3 --extra-cflags=-mssse3 \
--extra-cflags=-msse4.1 --extra-cflags=-msse4.2 --extra-cflags=-mavx --extra-cflags=-maes --extra-cflags=-mpclmul \
--pkg-config=pkg-config \
${BUILD_FLAGS}
if [[ $? -ne 0 ]]; then return 1; fi
# Compile FFmpeg
make -j$((`nproc` * 2))
if [[ $? -ne 0 ]]; then return 1; fi
# Install FFmpeg
sudo make install
if [[ $? -ne 0 ]]; then return 1; fi
# Move .lib files which are in the wrong place.
mv ./distrib/bin/*.lib ./distrib/lib/
if [[ $? -ne 0 ]]; then return 1; fi
}
install_ffmpeg
if [[ $? -ne 0 ]]; then exit 1; fi