mirror of
https://repo.dactyloidae.xyz/Dactyloidae/UXP.git
synced 2026-08-15 08:53:07 +09:00
Vendor dav1d 1.5.3
This commit is contained in:
parent
a852c0a86a
commit
ee30135ecc
390 changed files with 325535 additions and 0 deletions
5
media/libdav1d/README_MCP
Normal file
5
media/libdav1d/README_MCP
Normal file
|
|
@ -0,0 +1,5 @@
|
|||
This directory contains dav1d 1.5.3 from VideoLAN:
|
||||
https://code.videolan.org/videolan/dav1d/-/tags/1.5.3
|
||||
|
||||
Upstream source is stored in src/. Mozilla-specific build configuration lives
|
||||
in moz.build, config/, and moz/.
|
||||
85
media/libdav1d/config/config.h
Normal file
85
media/libdav1d/config/config.h
Normal file
|
|
@ -0,0 +1,85 @@
|
|||
/* Mozilla build configuration for bundled dav1d. */
|
||||
#ifndef MOZ_DAV1D_CONFIG_H
|
||||
#define MOZ_DAV1D_CONFIG_H
|
||||
|
||||
#if defined(__x86_64__) || defined(_M_X64)
|
||||
# define ARCH_X86 1
|
||||
# define ARCH_X86_64 1
|
||||
# define ARCH_X86_32 0
|
||||
#elif defined(__i386__) || defined(_M_IX86)
|
||||
# define ARCH_X86 1
|
||||
# define ARCH_X86_64 0
|
||||
# define ARCH_X86_32 1
|
||||
#else
|
||||
# define ARCH_X86 0
|
||||
# define ARCH_X86_64 0
|
||||
# define ARCH_X86_32 0
|
||||
#endif
|
||||
|
||||
#if defined(__aarch64__) || defined(_M_ARM64)
|
||||
# define ARCH_AARCH64 1
|
||||
#else
|
||||
# define ARCH_AARCH64 0
|
||||
#endif
|
||||
|
||||
#if defined(__arm__) || defined(_M_ARM)
|
||||
# define ARCH_ARM 1
|
||||
#else
|
||||
# define ARCH_ARM 0
|
||||
#endif
|
||||
|
||||
#if defined(__loongarch64)
|
||||
# define ARCH_LOONGARCH 1
|
||||
# define ARCH_LOONGARCH64 1
|
||||
#else
|
||||
# define ARCH_LOONGARCH 0
|
||||
# define ARCH_LOONGARCH64 0
|
||||
#endif
|
||||
|
||||
#if defined(__powerpc64__) && defined(_LITTLE_ENDIAN)
|
||||
# define ARCH_PPC64LE 1
|
||||
#else
|
||||
# define ARCH_PPC64LE 0
|
||||
#endif
|
||||
|
||||
#if defined(__riscv)
|
||||
# define ARCH_RISCV 1
|
||||
#else
|
||||
# define ARCH_RISCV 0
|
||||
#endif
|
||||
|
||||
#if defined(IS_BIG_ENDIAN) || defined(__BIG_ENDIAN__)
|
||||
# define ENDIANNESS_BIG 1
|
||||
#else
|
||||
# define ENDIANNESS_BIG 0
|
||||
#endif
|
||||
|
||||
#define CONFIG_8BPC 1
|
||||
#define CONFIG_16BPC 1
|
||||
#define CONFIG_LOG 0
|
||||
#define CONFIG_MACOS_KPERF 0
|
||||
#define HAVE_ASM 0
|
||||
#define TRIM_DSP_FUNCTIONS 0
|
||||
|
||||
#define HAVE_ALIGNED_ALLOC 0
|
||||
#define HAVE_DLSYM 0
|
||||
#define HAVE_ELF_AUX_INFO 0
|
||||
#define HAVE_GETAUXVAL 0
|
||||
#define HAVE_MEMALIGN 0
|
||||
#define HAVE_POSIX_MEMALIGN 0
|
||||
#define HAVE_PTHREAD_GETAFFINITY_NP 0
|
||||
#define HAVE_PTHREAD_NP_H 0
|
||||
#define HAVE_PTHREAD_SETNAME_NP 0
|
||||
#define HAVE_PTHREAD_SET_NAME_NP 0
|
||||
|
||||
#ifdef _WIN32
|
||||
# define HAVE_IO_H 1
|
||||
# define HAVE_SYS_TYPES_H 1
|
||||
# define HAVE_UNISTD_H 0
|
||||
#else
|
||||
# define HAVE_IO_H 0
|
||||
# define HAVE_SYS_TYPES_H 1
|
||||
# define HAVE_UNISTD_H 1
|
||||
#endif
|
||||
|
||||
#endif /* MOZ_DAV1D_CONFIG_H */
|
||||
1
media/libdav1d/config/vcs_version.h
Normal file
1
media/libdav1d/config/vcs_version.h
Normal file
|
|
@ -0,0 +1 @@
|
|||
#define DAV1D_VERSION "1.5.3"
|
||||
109
media/libdav1d/moz.build
Normal file
109
media/libdav1d/moz.build
Normal file
|
|
@ -0,0 +1,109 @@
|
|||
# -*- Mode: python; indent-tabs-mode: nil; tab-width: 40 -*-
|
||||
# This Source Code Form is subject to the terms of the Mozilla Public
|
||||
# License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
|
||||
with Files('*'):
|
||||
BUG_COMPONENT = ('Core', 'Audio/Video')
|
||||
|
||||
common_sources = [
|
||||
'/media/libdav1d/src/src/cdf.c',
|
||||
'/media/libdav1d/src/src/cpu.c',
|
||||
'/media/libdav1d/src/src/ctx.c',
|
||||
'/media/libdav1d/src/src/data.c',
|
||||
'/media/libdav1d/src/src/decode.c',
|
||||
'/media/libdav1d/src/src/dequant_tables.c',
|
||||
'/media/libdav1d/src/src/getbits.c',
|
||||
'/media/libdav1d/src/src/intra_edge.c',
|
||||
'/media/libdav1d/src/src/itx_1d.c',
|
||||
'/media/libdav1d/src/src/lf_mask.c',
|
||||
'/media/libdav1d/src/src/lib.c',
|
||||
'/media/libdav1d/src/src/log.c',
|
||||
'/media/libdav1d/src/src/mem.c',
|
||||
'/media/libdav1d/src/src/msac.c',
|
||||
'/media/libdav1d/src/src/obu.c',
|
||||
'/media/libdav1d/src/src/pal.c',
|
||||
'/media/libdav1d/src/src/picture.c',
|
||||
'/media/libdav1d/src/src/qm.c',
|
||||
'/media/libdav1d/src/src/ref.c',
|
||||
'/media/libdav1d/src/src/refmvs.c',
|
||||
'/media/libdav1d/src/src/scan.c',
|
||||
'/media/libdav1d/src/src/tables.c',
|
||||
'/media/libdav1d/src/src/thread_task.c',
|
||||
'/media/libdav1d/src/src/warpmv.c',
|
||||
'/media/libdav1d/src/src/wedge.c',
|
||||
]
|
||||
|
||||
bitdepth_sources = [
|
||||
'/media/libdav1d/moz/cdef_16bpc.c',
|
||||
'/media/libdav1d/moz/cdef_8bpc.c',
|
||||
'/media/libdav1d/moz/cdef_apply_16bpc.c',
|
||||
'/media/libdav1d/moz/cdef_apply_8bpc.c',
|
||||
'/media/libdav1d/moz/fg_apply_16bpc.c',
|
||||
'/media/libdav1d/moz/fg_apply_8bpc.c',
|
||||
'/media/libdav1d/moz/filmgrain_16bpc.c',
|
||||
'/media/libdav1d/moz/filmgrain_8bpc.c',
|
||||
'/media/libdav1d/moz/ipred_16bpc.c',
|
||||
'/media/libdav1d/moz/ipred_8bpc.c',
|
||||
'/media/libdav1d/moz/ipred_prepare_16bpc.c',
|
||||
'/media/libdav1d/moz/ipred_prepare_8bpc.c',
|
||||
'/media/libdav1d/moz/itx_16bpc.c',
|
||||
'/media/libdav1d/moz/itx_8bpc.c',
|
||||
'/media/libdav1d/moz/lf_apply_16bpc.c',
|
||||
'/media/libdav1d/moz/lf_apply_8bpc.c',
|
||||
'/media/libdav1d/moz/loopfilter_16bpc.c',
|
||||
'/media/libdav1d/moz/loopfilter_8bpc.c',
|
||||
'/media/libdav1d/moz/looprestoration_16bpc.c',
|
||||
'/media/libdav1d/moz/looprestoration_8bpc.c',
|
||||
'/media/libdav1d/moz/lr_apply_16bpc.c',
|
||||
'/media/libdav1d/moz/lr_apply_8bpc.c',
|
||||
'/media/libdav1d/moz/mc_16bpc.c',
|
||||
'/media/libdav1d/moz/mc_8bpc.c',
|
||||
'/media/libdav1d/moz/recon_16bpc.c',
|
||||
'/media/libdav1d/moz/recon_8bpc.c',
|
||||
]
|
||||
|
||||
SOURCES += common_sources
|
||||
SOURCES += bitdepth_sources
|
||||
|
||||
if CONFIG['OS_TARGET'] == 'WINNT':
|
||||
SOURCES += [
|
||||
'/media/libdav1d/src/src/win32/thread.c',
|
||||
]
|
||||
else:
|
||||
DEFINES['_GNU_SOURCE'] = True
|
||||
|
||||
EXPORTS.dav1d += [
|
||||
'/media/libdav1d/src/include/dav1d/common.h',
|
||||
'/media/libdav1d/src/include/dav1d/data.h',
|
||||
'/media/libdav1d/src/include/dav1d/dav1d.h',
|
||||
'/media/libdav1d/src/include/dav1d/headers.h',
|
||||
'/media/libdav1d/src/include/dav1d/picture.h',
|
||||
'/media/libdav1d/src/include/dav1d/version.h',
|
||||
]
|
||||
|
||||
LOCAL_INCLUDES += [
|
||||
'/media/libdav1d/config',
|
||||
'/media/libdav1d/src',
|
||||
'/media/libdav1d/src/include',
|
||||
'/media/libdav1d/src/include/dav1d',
|
||||
]
|
||||
|
||||
FINAL_LIBRARY = 'gkmedias'
|
||||
|
||||
# We allow warnings for third-party code that can be updated from upstream.
|
||||
ALLOW_COMPILER_WARNINGS = True
|
||||
|
||||
if CONFIG['GNU_CC'] or CONFIG['CLANG_CL']:
|
||||
CFLAGS += [
|
||||
'-Wno-missing-field-initializers',
|
||||
'-Wno-sign-compare',
|
||||
'-Wno-unused-function',
|
||||
'-Wno-unused-parameter',
|
||||
]
|
||||
|
||||
if CONFIG['CLANG_CXX'] or CONFIG['CLANG_CL']:
|
||||
CFLAGS += [
|
||||
'-Wno-shorten-64-to-32',
|
||||
'-Wno-unreachable-code',
|
||||
]
|
||||
2
media/libdav1d/moz/cdef_16bpc.c
Normal file
2
media/libdav1d/moz/cdef_16bpc.c
Normal file
|
|
@ -0,0 +1,2 @@
|
|||
#define BITDEPTH 16
|
||||
#include "../src/src/cdef_tmpl.c"
|
||||
2
media/libdav1d/moz/cdef_8bpc.c
Normal file
2
media/libdav1d/moz/cdef_8bpc.c
Normal file
|
|
@ -0,0 +1,2 @@
|
|||
#define BITDEPTH 8
|
||||
#include "../src/src/cdef_tmpl.c"
|
||||
2
media/libdav1d/moz/cdef_apply_16bpc.c
Normal file
2
media/libdav1d/moz/cdef_apply_16bpc.c
Normal file
|
|
@ -0,0 +1,2 @@
|
|||
#define BITDEPTH 16
|
||||
#include "../src/src/cdef_apply_tmpl.c"
|
||||
2
media/libdav1d/moz/cdef_apply_8bpc.c
Normal file
2
media/libdav1d/moz/cdef_apply_8bpc.c
Normal file
|
|
@ -0,0 +1,2 @@
|
|||
#define BITDEPTH 8
|
||||
#include "../src/src/cdef_apply_tmpl.c"
|
||||
2
media/libdav1d/moz/fg_apply_16bpc.c
Normal file
2
media/libdav1d/moz/fg_apply_16bpc.c
Normal file
|
|
@ -0,0 +1,2 @@
|
|||
#define BITDEPTH 16
|
||||
#include "../src/src/fg_apply_tmpl.c"
|
||||
2
media/libdav1d/moz/fg_apply_8bpc.c
Normal file
2
media/libdav1d/moz/fg_apply_8bpc.c
Normal file
|
|
@ -0,0 +1,2 @@
|
|||
#define BITDEPTH 8
|
||||
#include "../src/src/fg_apply_tmpl.c"
|
||||
2
media/libdav1d/moz/filmgrain_16bpc.c
Normal file
2
media/libdav1d/moz/filmgrain_16bpc.c
Normal file
|
|
@ -0,0 +1,2 @@
|
|||
#define BITDEPTH 16
|
||||
#include "../src/src/filmgrain_tmpl.c"
|
||||
2
media/libdav1d/moz/filmgrain_8bpc.c
Normal file
2
media/libdav1d/moz/filmgrain_8bpc.c
Normal file
|
|
@ -0,0 +1,2 @@
|
|||
#define BITDEPTH 8
|
||||
#include "../src/src/filmgrain_tmpl.c"
|
||||
2
media/libdav1d/moz/ipred_16bpc.c
Normal file
2
media/libdav1d/moz/ipred_16bpc.c
Normal file
|
|
@ -0,0 +1,2 @@
|
|||
#define BITDEPTH 16
|
||||
#include "../src/src/ipred_tmpl.c"
|
||||
2
media/libdav1d/moz/ipred_8bpc.c
Normal file
2
media/libdav1d/moz/ipred_8bpc.c
Normal file
|
|
@ -0,0 +1,2 @@
|
|||
#define BITDEPTH 8
|
||||
#include "../src/src/ipred_tmpl.c"
|
||||
2
media/libdav1d/moz/ipred_prepare_16bpc.c
Normal file
2
media/libdav1d/moz/ipred_prepare_16bpc.c
Normal file
|
|
@ -0,0 +1,2 @@
|
|||
#define BITDEPTH 16
|
||||
#include "../src/src/ipred_prepare_tmpl.c"
|
||||
2
media/libdav1d/moz/ipred_prepare_8bpc.c
Normal file
2
media/libdav1d/moz/ipred_prepare_8bpc.c
Normal file
|
|
@ -0,0 +1,2 @@
|
|||
#define BITDEPTH 8
|
||||
#include "../src/src/ipred_prepare_tmpl.c"
|
||||
2
media/libdav1d/moz/itx_16bpc.c
Normal file
2
media/libdav1d/moz/itx_16bpc.c
Normal file
|
|
@ -0,0 +1,2 @@
|
|||
#define BITDEPTH 16
|
||||
#include "../src/src/itx_tmpl.c"
|
||||
2
media/libdav1d/moz/itx_8bpc.c
Normal file
2
media/libdav1d/moz/itx_8bpc.c
Normal file
|
|
@ -0,0 +1,2 @@
|
|||
#define BITDEPTH 8
|
||||
#include "../src/src/itx_tmpl.c"
|
||||
2
media/libdav1d/moz/lf_apply_16bpc.c
Normal file
2
media/libdav1d/moz/lf_apply_16bpc.c
Normal file
|
|
@ -0,0 +1,2 @@
|
|||
#define BITDEPTH 16
|
||||
#include "../src/src/lf_apply_tmpl.c"
|
||||
2
media/libdav1d/moz/lf_apply_8bpc.c
Normal file
2
media/libdav1d/moz/lf_apply_8bpc.c
Normal file
|
|
@ -0,0 +1,2 @@
|
|||
#define BITDEPTH 8
|
||||
#include "../src/src/lf_apply_tmpl.c"
|
||||
2
media/libdav1d/moz/loopfilter_16bpc.c
Normal file
2
media/libdav1d/moz/loopfilter_16bpc.c
Normal file
|
|
@ -0,0 +1,2 @@
|
|||
#define BITDEPTH 16
|
||||
#include "../src/src/loopfilter_tmpl.c"
|
||||
2
media/libdav1d/moz/loopfilter_8bpc.c
Normal file
2
media/libdav1d/moz/loopfilter_8bpc.c
Normal file
|
|
@ -0,0 +1,2 @@
|
|||
#define BITDEPTH 8
|
||||
#include "../src/src/loopfilter_tmpl.c"
|
||||
2
media/libdav1d/moz/looprestoration_16bpc.c
Normal file
2
media/libdav1d/moz/looprestoration_16bpc.c
Normal file
|
|
@ -0,0 +1,2 @@
|
|||
#define BITDEPTH 16
|
||||
#include "../src/src/looprestoration_tmpl.c"
|
||||
2
media/libdav1d/moz/looprestoration_8bpc.c
Normal file
2
media/libdav1d/moz/looprestoration_8bpc.c
Normal file
|
|
@ -0,0 +1,2 @@
|
|||
#define BITDEPTH 8
|
||||
#include "../src/src/looprestoration_tmpl.c"
|
||||
2
media/libdav1d/moz/lr_apply_16bpc.c
Normal file
2
media/libdav1d/moz/lr_apply_16bpc.c
Normal file
|
|
@ -0,0 +1,2 @@
|
|||
#define BITDEPTH 16
|
||||
#include "../src/src/lr_apply_tmpl.c"
|
||||
2
media/libdav1d/moz/lr_apply_8bpc.c
Normal file
2
media/libdav1d/moz/lr_apply_8bpc.c
Normal file
|
|
@ -0,0 +1,2 @@
|
|||
#define BITDEPTH 8
|
||||
#include "../src/src/lr_apply_tmpl.c"
|
||||
2
media/libdav1d/moz/mc_16bpc.c
Normal file
2
media/libdav1d/moz/mc_16bpc.c
Normal file
|
|
@ -0,0 +1,2 @@
|
|||
#define BITDEPTH 16
|
||||
#include "../src/src/mc_tmpl.c"
|
||||
2
media/libdav1d/moz/mc_8bpc.c
Normal file
2
media/libdav1d/moz/mc_8bpc.c
Normal file
|
|
@ -0,0 +1,2 @@
|
|||
#define BITDEPTH 8
|
||||
#include "../src/src/mc_tmpl.c"
|
||||
2
media/libdav1d/moz/recon_16bpc.c
Normal file
2
media/libdav1d/moz/recon_16bpc.c
Normal file
|
|
@ -0,0 +1,2 @@
|
|||
#define BITDEPTH 16
|
||||
#include "../src/src/recon_tmpl.c"
|
||||
2
media/libdav1d/moz/recon_8bpc.c
Normal file
2
media/libdav1d/moz/recon_8bpc.c
Normal file
|
|
@ -0,0 +1,2 @@
|
|||
#define BITDEPTH 8
|
||||
#include "../src/src/recon_tmpl.c"
|
||||
10
media/libdav1d/src/.gitignore
vendored
Normal file
10
media/libdav1d/src/.gitignore
vendored
Normal file
|
|
@ -0,0 +1,10 @@
|
|||
/build*
|
||||
/Session.vim
|
||||
[._]*.swp
|
||||
*~
|
||||
tags
|
||||
.DS_Store
|
||||
/tests/argon
|
||||
/tests/dav1d-test-data
|
||||
*.snap
|
||||
/tools/output/xxhash.h
|
||||
930
media/libdav1d/src/.gitlab-ci.yml
Normal file
930
media/libdav1d/src/.gitlab-ci.yml
Normal file
|
|
@ -0,0 +1,930 @@
|
|||
stages:
|
||||
- style
|
||||
- build
|
||||
- test
|
||||
|
||||
.debian-amd64-common:
|
||||
image: registry.videolan.org/dav1d-debian-unstable:20250207200301
|
||||
stage: build
|
||||
tags:
|
||||
- docker
|
||||
- amd64
|
||||
|
||||
.debian-amd64-minimum:
|
||||
image: registry.videolan.org/dav1d-debian-minimum:20250207200301
|
||||
stage: build
|
||||
tags:
|
||||
- docker
|
||||
- amd64
|
||||
|
||||
.debian-llvm-mingw-common:
|
||||
image: registry.videolan.org/vlc-debian-llvm-msvcrt:20250305204125
|
||||
stage: build
|
||||
tags:
|
||||
- docker
|
||||
- amd64
|
||||
|
||||
.debian-aarch64-common:
|
||||
image: registry.videolan.org/dav1d-debian-bookworm-aarch64:20250215002814
|
||||
stage: build
|
||||
tags:
|
||||
- docker
|
||||
- aarch64
|
||||
|
||||
.debian-armv7-common:
|
||||
image: registry.videolan.org/dav1d-debian-bookworm-armv7:20250215014239
|
||||
stage: build
|
||||
tags:
|
||||
- docker
|
||||
- armv7
|
||||
|
||||
.debian-ppc64le-common:
|
||||
image: registry.videolan.org/dav1d-debian-unstable-ppc64le:20250215003029
|
||||
stage: build
|
||||
tags:
|
||||
- docker
|
||||
- ppc64le
|
||||
|
||||
.android-common:
|
||||
image: registry.videolan.org/vlc-debian-android:20241118101328
|
||||
stage: build
|
||||
tags:
|
||||
- docker
|
||||
- amd64
|
||||
|
||||
.debian-wasm-emscripten-common:
|
||||
image: registry.videolan.org/vlc-debian-wasm-emscripten:20250207201514
|
||||
stage: build
|
||||
tags:
|
||||
- docker
|
||||
- amd64
|
||||
|
||||
|
||||
style-check:
|
||||
extends: .debian-amd64-common
|
||||
stage: style
|
||||
script:
|
||||
- git grep -I -n -P "\t|\r| $" -- . ':(exclude)*/compat/*' && echo "Trailing whitespace" && exit 1
|
||||
- git grep -I -n -i -e 'david' --and --not -e 'copyright' -- . ':(exclude)THANKS.md' ':(exclude).gitlab-ci.yml' && echo "Misspelled dav1d" && exit 1
|
||||
- git grep -I -l -z "" -- . ':(exclude)*/compat/*' | while IFS= read -r -d '' i; do
|
||||
if [ -n "$(tail -c 1 "$i")" ]; then
|
||||
echo "No newline at end of $i";
|
||||
exit 1;
|
||||
fi;
|
||||
done
|
||||
- rg '[\u061c\u2000-\u200f\u2028-\u202f\u205f-\u206f]' ./ && echo "Invisible Unicode characters" && exit 1
|
||||
- git remote rm upstream 2> /dev/null || true
|
||||
- git remote add upstream https://code.videolan.org/videolan/dav1d.git
|
||||
- git fetch -q upstream master
|
||||
- for i in $(git rev-list HEAD ^upstream/master); do
|
||||
echo "Checking commit message of $i";
|
||||
msg="$(git log --format=%B -n 1 $i)";
|
||||
if [ -n "$(echo "$msg" | awk "NR==2")" ]; then
|
||||
echo "Malformed commit message in $i, second line must be empty";
|
||||
exit 1;
|
||||
fi;
|
||||
if echo "$msg" | head -1 | grep -q '\.$'; then
|
||||
echo "Malformed commit message in $i, trailing period in subject line";
|
||||
exit 1;
|
||||
fi;
|
||||
done
|
||||
|
||||
x86inc-check:
|
||||
extends: .debian-amd64-common
|
||||
stage: style
|
||||
script:
|
||||
- git remote rm x86inc 2> /dev/null || true
|
||||
- git remote add x86inc https://code.videolan.org/videolan/x86inc.asm.git
|
||||
- git fetch -q x86inc master
|
||||
- git diff --exit-code x86inc/master:x86inc.asm src/ext/x86/x86inc.asm
|
||||
allow_failure: true
|
||||
|
||||
|
||||
build-debian:
|
||||
extends: .debian-amd64-common
|
||||
tags:
|
||||
- docker
|
||||
- avx2
|
||||
- amd64
|
||||
script:
|
||||
- meson setup build --buildtype release
|
||||
-Dtrim_dsp=false
|
||||
--werror
|
||||
- ninja -C build
|
||||
- cd build && meson test -v
|
||||
artifacts:
|
||||
paths:
|
||||
- build/
|
||||
expire_in: 1 day
|
||||
|
||||
build-debian-static:
|
||||
extends: .debian-amd64-common
|
||||
script:
|
||||
- meson setup build --buildtype release
|
||||
--default-library static
|
||||
--werror
|
||||
- ninja -C build
|
||||
- cd build && meson test -v
|
||||
- nm -A -g src/libdav1d.a | grep " [ABCDGRST] " | (! grep -v " _*dav1d_")
|
||||
|
||||
build-debian-illegal-instructions:
|
||||
extends: .debian-amd64-common
|
||||
tags:
|
||||
- docker
|
||||
- avx2
|
||||
- amd64
|
||||
script:
|
||||
- meson setup build --buildtype debug
|
||||
- ninja -C build
|
||||
- cd build
|
||||
- exit_code=0
|
||||
- time meson test -v --suite checkasm --wrapper 'qemu-x86_64 -cpu Conroe' || exit_code=$((exit_code + $?))
|
||||
- time meson test -v --suite checkasm --wrapper 'qemu-x86_64 -cpu Penryn' || exit_code=$((exit_code + $?))
|
||||
- if [ $exit_code -ne 0 ]; then exit $exit_code; fi
|
||||
|
||||
build-debian32:
|
||||
extends: .debian-amd64-common
|
||||
script:
|
||||
- meson setup build --buildtype release
|
||||
-Dtrim_dsp=false
|
||||
--werror
|
||||
--cross-file package/crossfiles/i686-linux32.meson
|
||||
- ninja -C build
|
||||
- cd build && meson test -v
|
||||
artifacts:
|
||||
paths:
|
||||
- build/
|
||||
expire_in: 1 day
|
||||
|
||||
build-debian-examples:
|
||||
extends: .debian-amd64-common
|
||||
script:
|
||||
- meson setup build --buildtype release
|
||||
--werror
|
||||
-Denable_examples=true
|
||||
- ninja -C build
|
||||
|
||||
build-debian-no-tools:
|
||||
extends: .debian-amd64-common
|
||||
script:
|
||||
- meson setup build --buildtype release
|
||||
--werror
|
||||
-Denable_tools=false
|
||||
- ninja -C build
|
||||
|
||||
build-debian-bitdepth:
|
||||
extends: .debian-amd64-common
|
||||
script:
|
||||
- meson setup build --buildtype release
|
||||
--werror
|
||||
-Dbitdepths=$DEPTH
|
||||
- ninja -C build
|
||||
parallel:
|
||||
matrix:
|
||||
- DEPTH: [8, 16]
|
||||
|
||||
build-debian-avx:
|
||||
extends: .debian-amd64-common
|
||||
tags:
|
||||
- docker
|
||||
- avx2
|
||||
- amd64
|
||||
variables:
|
||||
CFLAGS: '-mavx'
|
||||
script:
|
||||
- meson setup build --buildtype debugoptimized
|
||||
--werror
|
||||
- ninja -C build
|
||||
- cd build
|
||||
- time meson test -v --suite checkasm
|
||||
|
||||
build-debian-minimum:
|
||||
extends: .debian-amd64-minimum
|
||||
script:
|
||||
- meson setup build --buildtype release
|
||||
--werror
|
||||
-Dtrim_dsp=false
|
||||
- ninja -C build
|
||||
- cd build && meson test -v
|
||||
|
||||
build-debian-avx512:
|
||||
extends: .debian-amd64-common
|
||||
tags:
|
||||
- docker
|
||||
- amd64-avx512
|
||||
variables:
|
||||
CFLAGS: '-mavx'
|
||||
script:
|
||||
- meson setup build --buildtype debugoptimized
|
||||
--werror
|
||||
- ninja -C build
|
||||
- cd build
|
||||
- time meson test -v --suite checkasm
|
||||
|
||||
build-debian-clang:
|
||||
extends: .debian-amd64-common
|
||||
variables:
|
||||
CC: clang
|
||||
CC_LD: mold
|
||||
script:
|
||||
- meson setup build --buildtype release
|
||||
--werror
|
||||
-Dtrim_dsp=false
|
||||
- ninja -C build
|
||||
- cd build && meson test -v
|
||||
|
||||
build-win:
|
||||
extends: .debian-amd64-common
|
||||
script:
|
||||
- wineserver -p && wine wineboot
|
||||
- meson setup build --buildtype release
|
||||
--werror
|
||||
--libdir lib
|
||||
--prefix "$(pwd)/build/dav1d_install"
|
||||
--cross-file package/crossfiles/${CROSSFILE}.meson
|
||||
-Ddefault_library=both
|
||||
-Dtrim_dsp=false
|
||||
- ninja -C build
|
||||
- ninja -C build install
|
||||
- cd build && meson test -v
|
||||
- ${CROSSFILE}-nm -A -g src/libdav1d.a | grep " [ABCDGRST] " | (! grep -E -v " \.| _*dav1d_")
|
||||
artifacts:
|
||||
name: "$CI_JOB_NAME-$CI_COMMIT_REF_SLUG"
|
||||
paths:
|
||||
- build/dav1d_install/
|
||||
expire_in: 1 week
|
||||
parallel:
|
||||
matrix:
|
||||
- CROSSFILE: [i686-w64-mingw32, x86_64-w64-mingw32]
|
||||
|
||||
build-win32-unaligned-stack:
|
||||
extends: .debian-llvm-mingw-common
|
||||
script:
|
||||
- wineserver -p && wine wineboot
|
||||
- meson setup build --buildtype release
|
||||
--werror
|
||||
--cross-file package/crossfiles/i686-w64-mingw32.meson
|
||||
-Dstack_alignment=4
|
||||
-Dtrim_dsp=false
|
||||
- ninja -C build
|
||||
- cd build && meson test -v
|
||||
|
||||
build-win-arm:
|
||||
extends: .debian-llvm-mingw-common
|
||||
script:
|
||||
- meson setup build --buildtype release
|
||||
--werror
|
||||
--libdir lib
|
||||
--prefix "$(pwd)/build/dav1d_install"
|
||||
--cross-file package/crossfiles/${CROSSFILE}.meson
|
||||
-Ddefault_library=both
|
||||
-Dtrim_dsp=false
|
||||
- ninja -C build
|
||||
- ninja -C build install
|
||||
- ${CROSSFILE}-nm -A -g build/src/libdav1d.a | grep " [ABCDGRST] " | (! grep -E -v " \.| _*dav1d_")
|
||||
artifacts:
|
||||
name: "$CI_JOB_NAME-$CI_COMMIT_REF_SLUG"
|
||||
paths:
|
||||
- build/dav1d_install/
|
||||
expire_in: 1 week
|
||||
parallel:
|
||||
matrix:
|
||||
- CROSSFILE: [armv7-w64-mingw32, aarch64-w64-mingw32]
|
||||
|
||||
.build-android-common:
|
||||
extends: .android-common
|
||||
script:
|
||||
- meson setup build --buildtype release
|
||||
--werror
|
||||
--libdir lib
|
||||
--prefix "$(pwd)/build/dav1d_install"
|
||||
--cross-file $CROSSFILE
|
||||
-Ddefault_library=both
|
||||
-Dtrim_dsp=false
|
||||
- ninja -C build
|
||||
- ninja -C build install
|
||||
|
||||
build-android-armv7:
|
||||
extends: .build-android-common
|
||||
variables:
|
||||
CROSSFILE: package/crossfiles/arm-android.meson
|
||||
rules:
|
||||
- if: '$CI_COMMIT_BRANCH'
|
||||
|
||||
build-android-aarch64:
|
||||
extends: .build-android-common
|
||||
variables:
|
||||
CROSSFILE: package/crossfiles/aarch64-android.meson
|
||||
rules:
|
||||
- if: '$CI_COMMIT_BRANCH'
|
||||
|
||||
build-android-armv7-release:
|
||||
extends: build-android-armv7
|
||||
rules:
|
||||
- if: '$CI_COMMIT_TAG && $CI_PROJECT_PATH == "videolan/dav1d"'
|
||||
artifacts:
|
||||
name: "$CI_JOB_NAME-$CI_COMMIT_REF_SLUG"
|
||||
paths:
|
||||
- build/dav1d_install/
|
||||
expire_in: 1 week
|
||||
|
||||
build-android-aarch64-release:
|
||||
extends: build-android-aarch64
|
||||
rules:
|
||||
- if: '$CI_COMMIT_TAG && $CI_PROJECT_PATH == "videolan/dav1d"'
|
||||
artifacts:
|
||||
name: "$CI_JOB_NAME-$CI_COMMIT_REF_SLUG"
|
||||
paths:
|
||||
- build/dav1d_install/
|
||||
expire_in: 1 week
|
||||
|
||||
build-debian-aarch64:
|
||||
extends: .debian-aarch64-common
|
||||
script:
|
||||
- meson setup build --buildtype debugoptimized
|
||||
--werror
|
||||
- ninja -C build
|
||||
- cd build && meson test -v
|
||||
|
||||
build-debian-aarch64-clang-5:
|
||||
extends: .debian-aarch64-common
|
||||
variables:
|
||||
CC: clang-5.0
|
||||
CFLAGS: '-integrated-as'
|
||||
script:
|
||||
- meson setup build --buildtype release
|
||||
- ninja -C build
|
||||
- cd build && meson test -v
|
||||
|
||||
build-debian-aarch64-clang-18:
|
||||
extends: .debian-amd64-common
|
||||
variables:
|
||||
QEMU_LD_PREFIX: /usr/aarch64-linux-gnu/
|
||||
script:
|
||||
- meson setup build --buildtype release
|
||||
-Dtrim_dsp=false
|
||||
--werror
|
||||
--cross-file package/crossfiles/aarch64-linux-clang.meson
|
||||
- ninja -C build
|
||||
- cd build && meson test -v
|
||||
|
||||
build-macos:
|
||||
stage: build
|
||||
tags:
|
||||
- amd64
|
||||
- macos
|
||||
script:
|
||||
- meson setup build --buildtype release
|
||||
-Ddefault_library=both
|
||||
-Dtrim_dsp=false
|
||||
--werror
|
||||
- ninja -C build
|
||||
- cd build && meson test -v
|
||||
|
||||
build-debian-werror:
|
||||
extends: .debian-aarch64-common
|
||||
variables:
|
||||
CC: clang
|
||||
script:
|
||||
- meson setup build --buildtype debug
|
||||
--werror
|
||||
- ninja -C build
|
||||
|
||||
build-debian-armv7:
|
||||
extends: .debian-armv7-common
|
||||
script:
|
||||
- linux32 meson setup build --buildtype debugoptimized
|
||||
--werror
|
||||
- ninja -C build
|
||||
- cd build && meson test -v
|
||||
|
||||
build-debian-armv7-clang-5:
|
||||
extends: .debian-armv7-common
|
||||
variables:
|
||||
CC: clang-5.0
|
||||
CFLAGS: '-integrated-as'
|
||||
script:
|
||||
- linux32 meson setup build --buildtype release
|
||||
- ninja -C build
|
||||
- cd build && meson test -v
|
||||
|
||||
build-debian-ppc64le:
|
||||
extends: .debian-ppc64le-common
|
||||
variables:
|
||||
CC: gcc-13
|
||||
script:
|
||||
- meson setup build --buildtype release
|
||||
-Dtrim_dsp=false
|
||||
--werror
|
||||
- ninja -C build
|
||||
- cd build && meson test -v
|
||||
|
||||
build-debian-wasm:
|
||||
extends: .debian-wasm-emscripten-common
|
||||
script:
|
||||
- source $EMSCRIPTEN_SDK/emsdk_env.sh
|
||||
- meson setup build --buildtype release
|
||||
--werror
|
||||
--default-library static
|
||||
--cross-file package/crossfiles/${CROSSFILE}.meson
|
||||
- ninja -C build
|
||||
- cd build && meson test -v
|
||||
parallel:
|
||||
matrix:
|
||||
- CROSSFILE: [wasm32, wasm64]
|
||||
|
||||
build-debian-riscv64:
|
||||
extends: .debian-amd64-common
|
||||
variables:
|
||||
QEMU_CPU: rv64,v=true,vext_spec=v1.0,vlen=256,elen=64
|
||||
QEMU_LD_PREFIX: /usr/riscv64-linux-gnu/
|
||||
script:
|
||||
- meson setup build --buildtype release
|
||||
-Dtrim_dsp=false
|
||||
--werror
|
||||
--cross-file package/crossfiles/${CROSSFILE}.meson
|
||||
- ninja -C build
|
||||
- cd build && meson test -v
|
||||
parallel:
|
||||
matrix:
|
||||
- CROSSFILE: [riscv64-linux, riscv64-linux-clang]
|
||||
|
||||
build-debian-loongarch64:
|
||||
extends: .debian-amd64-common
|
||||
variables:
|
||||
QEMU_CPU: max-loongarch-cpu
|
||||
QEMU_LD_PREFIX: /opt/cross-tools/target/
|
||||
script:
|
||||
- meson setup build --buildtype release
|
||||
-Dtrim_dsp=false
|
||||
--werror
|
||||
--cross-file package/crossfiles/loongarch64-linux.meson
|
||||
- ninja -C build
|
||||
- cd build && meson test -v
|
||||
|
||||
|
||||
.test-common:
|
||||
stage: test
|
||||
cache:
|
||||
key: testdata.git-20190215
|
||||
paths:
|
||||
- cache/dav1d-test-data.git/
|
||||
before_script:
|
||||
- test -d cache || mkdir cache
|
||||
- test -d cache/dav1d-test-data.git && GIT_DIR=cache/dav1d-test-data.git git fetch --refmap=refs/heads/master:refs/heads/master origin master
|
||||
- test -d cache/dav1d-test-data.git || git clone --bare https://code.videolan.org/videolan/dav1d-test-data.git cache/dav1d-test-data.git
|
||||
- git clone cache/dav1d-test-data.git tests/dav1d-test-data
|
||||
- git -C tests/dav1d-test-data describe --always --long
|
||||
dependencies: []
|
||||
artifacts:
|
||||
when: always
|
||||
reports:
|
||||
junit: build/meson-logs/testlog.junit.xml
|
||||
|
||||
.test-asm-common:
|
||||
extends:
|
||||
- .debian-amd64-common
|
||||
- .test-common
|
||||
tags:
|
||||
- docker
|
||||
- amd64
|
||||
- avx2
|
||||
script:
|
||||
- meson configure build -Dtestdata_tests=true
|
||||
- ninja -C build
|
||||
- cd build
|
||||
- exit_code=0
|
||||
- time meson test -q --suite testdata --test-args "--cpumask 0" || exit_code=$((exit_code + $?))
|
||||
- time meson test -q --suite testdata --test-args "--cpumask sse2" || exit_code=$((exit_code + $?))
|
||||
- time meson test -q --suite testdata --test-args "--cpumask ssse3" || exit_code=$((exit_code + $?))
|
||||
- time meson test -q --suite testdata --test-args "--cpumask sse41" || exit_code=$((exit_code + $?))
|
||||
- time meson test -q --suite testdata --test-args "--cpumask avx2" || exit_code=$((exit_code + $?))
|
||||
- if [ $exit_code -ne 0 ]; then exit $exit_code; fi
|
||||
|
||||
.test-argon:
|
||||
stage: test
|
||||
cache:
|
||||
key: argon-20230512
|
||||
paths:
|
||||
- cache/argon/
|
||||
variables:
|
||||
ARGON_URL: https://streams.videolan.org/argon/argon.tar.zst
|
||||
before_script:
|
||||
- test -d cache/argon || mkdir -p cache/argon
|
||||
- test -f cache/argon/argon.tar.zst ||
|
||||
(cd cache/argon && curl --remote-name "${ARGON_URL}" --remote-name "${ARGON_URL}.sha512sum" &&
|
||||
sha512sum --check argon.tar.zst.sha512sum )
|
||||
- tar -xf cache/argon/argon.tar.zst -C tests
|
||||
dependencies: []
|
||||
allow_failure: true
|
||||
rules:
|
||||
- if: '$CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH'
|
||||
|
||||
test-debian:
|
||||
extends:
|
||||
- .debian-amd64-common
|
||||
- .test-common
|
||||
needs: ["build-debian"]
|
||||
script:
|
||||
- meson setup build --buildtype release
|
||||
-Dtestdata_tests=true
|
||||
-Denable_seek_stress=true
|
||||
-Dlogging=false
|
||||
-Db_coverage=true
|
||||
-Dtrim_dsp=false
|
||||
- ninja -C build
|
||||
- cd build && time meson test -v
|
||||
- ninja coverage-html
|
||||
- mv meson-logs/coveragereport ../coverage
|
||||
- ninja coverage-xml
|
||||
- grep -Eo 'line-rate="[^"]+"' meson-logs/coverage.xml | head -n 1 |
|
||||
grep -Eo '[0-9.]+' | awk '{ print "coverage:", $1 * 100 } '
|
||||
- time meson test -v --suite testdata_seek-stress --test-args "--threads 2 --framedelay 1"
|
||||
- time meson test -v --suite testdata_seek-stress --test-args "--threads 2 --framedelay 2"
|
||||
- time meson test -v --suite testdata --test-args "--threads=1 --negstride"
|
||||
coverage: '/^coverage: (\d+.\d+)$/'
|
||||
artifacts:
|
||||
expose_as: 'Coverage HTML report'
|
||||
paths:
|
||||
- coverage/
|
||||
reports:
|
||||
coverage_report:
|
||||
coverage_format: cobertura
|
||||
path: build/meson-logs/coverage.xml
|
||||
|
||||
test-debian-asm:
|
||||
extends:
|
||||
- .test-asm-common
|
||||
needs: ["build-debian"]
|
||||
dependencies: ["build-debian"]
|
||||
|
||||
test-debian32-asm:
|
||||
extends:
|
||||
- .test-asm-common
|
||||
needs: ["build-debian32"]
|
||||
dependencies: ["build-debian32"]
|
||||
|
||||
test-debian-avx512:
|
||||
extends:
|
||||
- .debian-amd64-common
|
||||
- .test-common
|
||||
tags:
|
||||
- docker
|
||||
- amd64-avx512
|
||||
variables:
|
||||
CFLAGS: '-mavx'
|
||||
needs: ["build-debian-avx512"]
|
||||
script:
|
||||
- meson setup build --buildtype release
|
||||
-Dtestdata_tests=true
|
||||
-Dtrim_dsp=false
|
||||
- ninja -C build
|
||||
- cd build && time meson test --suite testdata --test-args "--cpumask avx512icl"
|
||||
- time meson test --suite testdata --test-args "--threads 2 --framedelay 2 --cpumask avx512icl"
|
||||
|
||||
test-debian-unaligned-stack:
|
||||
extends:
|
||||
- .debian-amd64-common
|
||||
- .test-common
|
||||
needs: ["build-debian"]
|
||||
tags:
|
||||
- docker
|
||||
- avx2
|
||||
- amd64
|
||||
script:
|
||||
- meson setup build --buildtype release
|
||||
-Dtestdata_tests=true
|
||||
-Denable_seek_stress=true
|
||||
-Dlogging=false
|
||||
-Dstack_alignment=16
|
||||
-Dtrim_dsp=false
|
||||
- ninja -C build
|
||||
- cd build && time meson test -v
|
||||
|
||||
test-debian-asan:
|
||||
extends:
|
||||
- .debian-amd64-common
|
||||
- .test-common
|
||||
needs: ["build-debian"]
|
||||
variables:
|
||||
ASAN_OPTIONS: 'detect_leaks=0'
|
||||
script:
|
||||
- meson setup build --buildtype debugoptimized
|
||||
-Dtestdata_tests=true
|
||||
-Dlogging=false
|
||||
-Db_sanitize=address
|
||||
- ninja -C build
|
||||
- cd build
|
||||
- exit_code=0
|
||||
- time meson test -v --setup=sanitizer --suite checkasm || exit_code=$((exit_code + $?))
|
||||
- time meson test -v --setup=sanitizer --suite testdata --test-args "--cpumask 0" || exit_code=$((exit_code + $?))
|
||||
- time meson test -v --setup=sanitizer --suite testdata --test-args "--cpumask 0xff" || exit_code=$((exit_code + $?))
|
||||
- if [ $exit_code -ne 0 ]; then exit $exit_code; fi
|
||||
|
||||
test-debian-msan:
|
||||
extends:
|
||||
- .debian-amd64-common
|
||||
- .test-common
|
||||
needs: ["build-debian"]
|
||||
variables:
|
||||
MSAN_OPTIONS: 'exitcode=1'
|
||||
CC: clang
|
||||
script:
|
||||
- meson setup build --buildtype debugoptimized
|
||||
-Dtestdata_tests=true
|
||||
-Denable_seek_stress=true
|
||||
-Dlogging=false
|
||||
-Db_sanitize=memory
|
||||
-Db_lundef=false
|
||||
-Denable_asm=false
|
||||
- ninja -C build
|
||||
- cd build
|
||||
- exit_code=0
|
||||
- time meson test -v --setup=sanitizer || exit_code=$((exit_code + $?))
|
||||
- time meson test -v --setup=sanitizer --suite testdata --test-args "--frametimes /dev/null" || exit_code=$((exit_code + $?))
|
||||
- if [ $exit_code -ne 0 ]; then exit $exit_code; fi
|
||||
|
||||
test-debian-ubsan:
|
||||
extends:
|
||||
- .debian-amd64-common
|
||||
- .test-common
|
||||
needs: ["build-debian"]
|
||||
variables:
|
||||
UBSAN_OPTIONS: 'print_stacktrace=1:halt_on_error=1'
|
||||
CC: clang
|
||||
script:
|
||||
- meson setup build --buildtype debugoptimized
|
||||
-Dtestdata_tests=true
|
||||
-Denable_seek_stress=true
|
||||
-Dlogging=false
|
||||
-Db_sanitize=undefined
|
||||
-Db_lundef=false
|
||||
-Denable_asm=false
|
||||
- ninja -C build
|
||||
- cd build && time meson test -v --setup=sanitizer
|
||||
|
||||
test-debian-tsan:
|
||||
extends:
|
||||
- .debian-amd64-common
|
||||
- .test-common
|
||||
needs: ["build-debian"]
|
||||
variables:
|
||||
TSAN_OPTIONS: 'halt_on_error=1'
|
||||
CC: clang
|
||||
script:
|
||||
- meson setup build --buildtype debugoptimized
|
||||
-Dtestdata_tests=true
|
||||
-Denable_seek_stress=true
|
||||
-Dlogging=false
|
||||
-Db_sanitize=thread
|
||||
-Db_lundef=false
|
||||
- ninja -C build
|
||||
- cd build
|
||||
- exit_code=0
|
||||
- time meson test -v --setup=sanitizer --suite testdata --test-args "--threads 2 --framedelay 1" || exit_code=$((exit_code + $?))
|
||||
- time meson test -v --setup=sanitizer --suite testdata --test-args "--threads 2 --framedelay 2" || exit_code=$((exit_code + $?))
|
||||
- time meson test -v --setup=sanitizer --suite testdata --test-args "--threads 2 --framedelay 2 --negstride" || exit_code=$((exit_code + $?))
|
||||
- time meson test -v --setup=sanitizer --suite testdata_seek-stress --test-args "--threads 2 --framedelay 1" || exit_code=$((exit_code + $?))
|
||||
- time meson test -v --setup=sanitizer --suite testdata_seek-stress --test-args "--threads 2 --framedelay 2" || exit_code=$((exit_code + $?))
|
||||
- time meson test -v --setup=sanitizer --suite oss-fuzz-asan --suite oss-fuzz-msan --suite oss-fuzz-ubsan || exit_code=$((exit_code + $?))
|
||||
- if [ $exit_code -ne 0 ]; then exit $exit_code; fi
|
||||
|
||||
test-win64:
|
||||
extends:
|
||||
- .debian-amd64-common
|
||||
- .test-common
|
||||
needs: ["build-win: [x86_64-w64-mingw32]"]
|
||||
tags:
|
||||
- docker
|
||||
- avx2
|
||||
- amd64
|
||||
script:
|
||||
- wineserver -p && wine wineboot
|
||||
- meson setup build --buildtype release
|
||||
-Dtestdata_tests=true
|
||||
-Dlogging=false
|
||||
-Dtrim_dsp=false
|
||||
--cross-file package/crossfiles/x86_64-w64-mingw32.meson
|
||||
- ninja -C build
|
||||
- cd build && time meson test -v
|
||||
|
||||
test-debian-aarch64:
|
||||
extends:
|
||||
- .debian-aarch64-common
|
||||
- .test-common
|
||||
needs: ["build-debian-aarch64"]
|
||||
script:
|
||||
- meson setup build --buildtype release
|
||||
-Dtestdata_tests=true
|
||||
-Dlogging=false
|
||||
-Dtrim_dsp=false
|
||||
- ninja -C build
|
||||
- cd build && time meson test -v
|
||||
|
||||
test-debian-ppc64le:
|
||||
extends:
|
||||
- .debian-ppc64le-common
|
||||
- .test-common
|
||||
variables:
|
||||
CC: gcc-13
|
||||
needs: ["build-debian-ppc64le"]
|
||||
script:
|
||||
- meson setup build --buildtype release
|
||||
-Dtestdata_tests=true
|
||||
-Dlogging=false
|
||||
-Dtrim_dsp=false
|
||||
- ninja -C build
|
||||
- cd build && time meson test -v
|
||||
|
||||
test-debian-riscv64:
|
||||
extends:
|
||||
- .debian-amd64-common
|
||||
- .test-common
|
||||
needs: ["build-debian-riscv64"]
|
||||
script:
|
||||
- meson setup build --buildtype release
|
||||
-Dtestdata_tests=true
|
||||
-Dlogging=false
|
||||
-Dtrim_dsp=false
|
||||
--cross-file package/crossfiles/riscv64-linux.meson
|
||||
- ninja -C build
|
||||
- cd build && time meson test -v --timeout-multiplier 10
|
||||
variables:
|
||||
QEMU_LD_PREFIX: /usr/riscv64-linux-gnu/
|
||||
parallel:
|
||||
matrix:
|
||||
- QEMU_CPU: [ "rv64,v=true,vext_spec=v1.0,vlen=128,elen=64",
|
||||
"rv64,v=true,vext_spec=v1.0,vlen=256,elen=64",
|
||||
"rv64,v=true,vext_spec=v1.0,vlen=512,elen=64",
|
||||
"rv64,v=true,vext_spec=v1.0,vlen=1024,elen=64" ]
|
||||
|
||||
test-debian-aarch64-qemu:
|
||||
extends:
|
||||
- .debian-amd64-common
|
||||
- .test-common
|
||||
needs: ["build-debian-aarch64"]
|
||||
script:
|
||||
- meson setup build --buildtype release
|
||||
-Dtestdata_tests=true
|
||||
-Dlogging=false
|
||||
-Dtrim_dsp=false
|
||||
--cross-file package/crossfiles/aarch64-linux.meson
|
||||
- ninja -C build
|
||||
- cd build && time meson test -v --timeout-multiplier 10
|
||||
variables:
|
||||
QEMU_LD_PREFIX: /usr/aarch64-linux-gnu/
|
||||
parallel:
|
||||
matrix:
|
||||
# sve-default-vector-length sets the max vector length in bytes;
|
||||
# the default is 64, allowing up to 512 bit vectors. Testing 1024
|
||||
# and 2048 bit vectors requires raising this limit. The sve<n>
|
||||
# option sets the active vector length in bits.
|
||||
- QEMU_CPU: [ "max,sve-default-vector-length=256,sve128=on",
|
||||
"max,sve-default-vector-length=256,sve256=on",
|
||||
"max,sve-default-vector-length=256,sve512=on",
|
||||
"max,sve-default-vector-length=256,sve1024=on",
|
||||
"max,sve-default-vector-length=256,sve2048=on" ]
|
||||
|
||||
test-debian-armv7-clang-5:
|
||||
extends:
|
||||
- .debian-armv7-common
|
||||
- .test-common
|
||||
needs: ["build-debian-armv7-clang-5"]
|
||||
variables:
|
||||
CC: clang-5.0
|
||||
CFLAGS: '-integrated-as'
|
||||
script:
|
||||
- linux32 meson setup build --buildtype release
|
||||
-Dtestdata_tests=true
|
||||
-Dlogging=false
|
||||
-Dtrim_dsp=false
|
||||
- ninja -C build
|
||||
- cd build && time meson test -v
|
||||
|
||||
test-debian-loongarch64:
|
||||
extends:
|
||||
- .debian-amd64-common
|
||||
- .test-common
|
||||
needs: ["build-debian-loongarch64"]
|
||||
variables:
|
||||
QEMU_CPU: max-loongarch-cpu
|
||||
QEMU_LD_PREFIX: /opt/cross-tools/target/
|
||||
script:
|
||||
- meson setup build --buildtype release
|
||||
-Dtestdata_tests=true
|
||||
-Dlogging=false
|
||||
-Dtrim_dsp=false
|
||||
--cross-file package/crossfiles/loongarch64-linux.meson
|
||||
- ninja -C build
|
||||
- cd build && time meson test -v --timeout-multiplier 10
|
||||
|
||||
.test-argon-script: &test-argon-script
|
||||
- meson setup build --buildtype release
|
||||
-Dlogging=false
|
||||
-Dtrim_dsp=false
|
||||
- cd build && ninja
|
||||
- exit_code=0
|
||||
|
||||
test-debian-argon:
|
||||
extends:
|
||||
- .debian-amd64-common
|
||||
- .test-argon
|
||||
needs: ["build-debian"]
|
||||
tags:
|
||||
- docker
|
||||
- amd64
|
||||
- avx2
|
||||
script:
|
||||
- *test-argon-script
|
||||
- ../tests/dav1d_argon.bash -t 1 -c 0 || exit_code=$((exit_code + $?))
|
||||
- ../tests/dav1d_argon.bash -t 2 -c sse2 -g 0 || exit_code=$((exit_code + $?))
|
||||
- ../tests/dav1d_argon.bash -t 3 -c ssse3 || exit_code=$((exit_code + $?))
|
||||
- ../tests/dav1d_argon.bash -t 4 -c sse41 || exit_code=$((exit_code + $?))
|
||||
- ../tests/dav1d_argon.bash -t 5 -c avx2 || exit_code=$((exit_code + $?))
|
||||
- if [ $exit_code -ne 0 ]; then exit $exit_code; fi
|
||||
|
||||
test-debian32-argon:
|
||||
extends:
|
||||
- .debian-amd64-common
|
||||
- .test-argon
|
||||
needs: ["build-debian32"]
|
||||
script:
|
||||
- meson setup build --buildtype release
|
||||
-Dlogging=false
|
||||
-Dtrim_dsp=false
|
||||
--cross-file package/crossfiles/i686-linux32.meson
|
||||
- cd build && ninja
|
||||
- exit_code=0
|
||||
- ../tests/dav1d_argon.bash -t 2 -c sse2 || exit_code=$((exit_code + $?))
|
||||
- ../tests/dav1d_argon.bash -t 2 -c ssse3 || exit_code=$((exit_code + $?))
|
||||
- ../tests/dav1d_argon.bash -t 2 -c sse41 -g 0 || exit_code=$((exit_code + $?))
|
||||
- if [ $exit_code -ne 0 ]; then exit $exit_code; fi
|
||||
|
||||
test-debian-argon-avx512:
|
||||
extends:
|
||||
- .debian-amd64-common
|
||||
- .test-argon
|
||||
needs: ["build-debian-avx512"]
|
||||
tags:
|
||||
- docker
|
||||
- amd64-avx512
|
||||
script:
|
||||
- *test-argon-script
|
||||
- ../tests/dav1d_argon.bash -t 2 -c avx512icl || exit_code=$((exit_code + $?))
|
||||
- if [ $exit_code -ne 0 ]; then exit $exit_code; fi
|
||||
|
||||
test-debian-armv7-argon:
|
||||
extends:
|
||||
- .debian-armv7-common
|
||||
- .test-argon
|
||||
needs: ["build-debian-armv7"]
|
||||
script:
|
||||
- *test-argon-script
|
||||
- ../tests/dav1d_argon.bash -t 3 -c 0 || exit_code=$((exit_code + $?))
|
||||
- ../tests/dav1d_argon.bash -t 2 -c neon || exit_code=$((exit_code + $?))
|
||||
- ../tests/dav1d_argon.bash -t 1 -c neon -g 0 || exit_code=$((exit_code + $?))
|
||||
- if [ $exit_code -ne 0 ]; then exit $exit_code; fi
|
||||
|
||||
test-debian-aarch64-argon:
|
||||
extends:
|
||||
- .debian-aarch64-common
|
||||
- .test-argon
|
||||
needs: ["build-debian-aarch64"]
|
||||
tags:
|
||||
- docker
|
||||
- aarch64
|
||||
- dotprod
|
||||
script:
|
||||
- *test-argon-script
|
||||
- ../tests/dav1d_argon.bash -t 2 -c 0 || exit_code=$((exit_code + $?))
|
||||
- ../tests/dav1d_argon.bash -t 3 -c neon || exit_code=$((exit_code + $?))
|
||||
- ../tests/dav1d_argon.bash -t 1 -c neon -g 0 || exit_code=$((exit_code + $?))
|
||||
- ../tests/dav1d_argon.bash -t 4 -c dotprod || exit_code=$((exit_code + $?))
|
||||
- if [ $exit_code -ne 0 ]; then exit $exit_code; fi
|
||||
|
||||
|
||||
.pages-common:
|
||||
extends: .debian-amd64-common
|
||||
script:
|
||||
- meson setup build --buildtype release
|
||||
--werror
|
||||
-Denable_docs=true
|
||||
- ninja -C build doc/html
|
||||
- mv build/doc/html public
|
||||
artifacts:
|
||||
paths:
|
||||
- public
|
||||
|
||||
build-pages:
|
||||
extends: .pages-common
|
||||
rules:
|
||||
- if: '$CI_COMMIT_BRANCH && $CI_COMMIT_BRANCH != $CI_DEFAULT_BRANCH'
|
||||
|
||||
pages:
|
||||
extends: .pages-common
|
||||
rules:
|
||||
- if: '$CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH'
|
||||
changes:
|
||||
- include/dav1d/*
|
||||
- doc/meson.build
|
||||
- doc/Doxyfile.in.in
|
||||
56
media/libdav1d/src/CONTRIBUTING.md
Normal file
56
media/libdav1d/src/CONTRIBUTING.md
Normal file
|
|
@ -0,0 +1,56 @@
|
|||
# dav1d contribution guide
|
||||
|
||||
## CoC
|
||||
The [VideoLAN Code of Conduct](https://wiki.videolan.org/CoC) applies fully to this project.
|
||||
|
||||
## ToDo
|
||||
|
||||
The todo list can be found [on the wiki](https://code.videolan.org/videolan/dav1d/wikis/task-list).
|
||||
|
||||
## Codebase language
|
||||
|
||||
The codebase is developed with the following assumptions:
|
||||
|
||||
For the library:
|
||||
- C language with C99 version, without the VLA or the Complex (*\_\_STDC_NO_COMPLEX__*) features, and without compiler extensions. Anonymous structures and unions are the only allowed compiler extensions for internal code.
|
||||
- x86 asm in .asm files, using the NASM syntax,
|
||||
- arm/arm64 in .S files, using the GAS syntax limited to subset llvm 5.0's internal assembler supports,
|
||||
- no C++ is allowed, whatever the version.
|
||||
|
||||
For the tools and utils:
|
||||
- C *(see above for restrictions)*
|
||||
- Rust
|
||||
- C++ is only allowed for the MFT.
|
||||
|
||||
If you want to use *Threads* or *Atomic* features, please conform to the **C11**/**POSIX** semantic and use a wrapper for older compilers/platforms *(like done in VLC)*.
|
||||
|
||||
Please use modern standard POSIX functions *(strscpy, asprintf, tdestroy)*, and provide a compatibility fallback *(like done in VLC)*.
|
||||
|
||||
We will make reasonable efforts for compilers that are a bit older, but we won't support gcc 3 or MSVC 2012.
|
||||
|
||||
## Authorship
|
||||
|
||||
Please provide a correct authorship for your commit logs, with a name and a valid email.
|
||||
|
||||
We will reject anonymous contributions for now. As an exception, known pseudonyms from the multimedia community are accepted.
|
||||
|
||||
This project is respecting **Copyright** and **Droit d'auteur**. There is no copyright attribution or CLA.
|
||||
|
||||
## Commit logs
|
||||
|
||||
Please read [How to Write a Git Commit Message](https://chris.beams.io/posts/git-commit/).
|
||||
|
||||
## Submit requests (WIP)
|
||||
|
||||
- Code,
|
||||
- [Compile](https://xkcd.com/303/),
|
||||
- Check your [code style](https://code.videolan.org/videolan/dav1d/wikis/Coding-style),
|
||||
- Test,
|
||||
- Try,
|
||||
- Submit patches through merge requests,
|
||||
- Check that this passes the CI.
|
||||
|
||||
## Patent license
|
||||
|
||||
You need to read, understand, and agree to the [AV1 patents license](doc/PATENTS), before committing.
|
||||
|
||||
23
media/libdav1d/src/COPYING
Normal file
23
media/libdav1d/src/COPYING
Normal file
|
|
@ -0,0 +1,23 @@
|
|||
Copyright © 2018-2025, VideoLAN and dav1d authors
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
|
||||
1. Redistributions of source code must retain the above copyright notice, this
|
||||
list of conditions and the following disclaimer.
|
||||
|
||||
2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
this list of conditions and the following disclaimer in the documentation
|
||||
and/or other materials provided with the distribution.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
|
||||
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
460
media/libdav1d/src/NEWS
Normal file
460
media/libdav1d/src/NEWS
Normal file
|
|
@ -0,0 +1,460 @@
|
|||
Changes for 1.5.3 'Sonic':
|
||||
--------------------------
|
||||
|
||||
1.5.3 is a minor release of dav1d, focused on RISC-V and maintenance:
|
||||
- Misc small optimizations
|
||||
- RISC-V assembly optimizations for ipred, emu_edge and w_mask,
|
||||
and VLEN 512 for blend functions
|
||||
- Fix issue with ivf files with 0 frames in tools
|
||||
|
||||
|
||||
Changes for 1.5.2 'Sonic':
|
||||
--------------------------
|
||||
|
||||
1.5.2 is a minor release of dav1d, focused on maintenance:
|
||||
- minor speed improvement in recon
|
||||
- improvements on loongarch symboles visibility and asm
|
||||
- mark C globals with small code model
|
||||
- reduce the code size of the frame header parsing (OBU)
|
||||
- minor fixes on tools and CI
|
||||
- fix compilation with nasm 3.00
|
||||
|
||||
|
||||
Changes for 1.5.1 'Sonic':
|
||||
--------------------------
|
||||
|
||||
1.5.1 is a minor release of dav1d, focusing on optimizations and stack reduction:
|
||||
|
||||
- Rewrite of the looprestoration (SGR, wiener) to reduce stack usage
|
||||
- Rewrite of {put,prep}_scaled functions
|
||||
|
||||
Now, the required stack space for dav1d should be: 62 KB on x86_64 and
|
||||
58KB on arm and aarch64.
|
||||
|
||||
- Improvements on the SSSE3 SGR
|
||||
- Improvements on ARM32/ARM64 looprestoration optimizations
|
||||
- RISC-V: blend optimizations for high bitdepth
|
||||
- Power9: blend optimizations for 8bpc
|
||||
- Port RISC-V to POSIX/non-Linux OS
|
||||
- AArch64: Add Neon implementation of load_tmvs
|
||||
- Fix a rare, but possible deadlock, in flush()
|
||||
|
||||
|
||||
Changes for 1.5.0 'Sonic':
|
||||
--------------------------
|
||||
|
||||
1.5.0 is a major release of dav1d, that:
|
||||
- WARNING: we removed some of the SSE2 optimizations, so if you care about
|
||||
systems without SSSE3, you should be careful when updating!
|
||||
- Add Arm OpenBSD run-time CPU feature
|
||||
- Optimize index offset calculations for decode_coefs
|
||||
- picture: copy HDR10+ and T35 metadata only to visible frames
|
||||
- SSSE3 new optimizations for 6-tap (8bit and hbd)
|
||||
- AArch64/SVE: Add HBD subpel filters using 128-bit SVE2
|
||||
- AArch64: Add USMMLA Implementation for 6-tap H/HV
|
||||
- AArch64: Optimize Armv8.0 NEON for HBD horizontal filters and 6-tap filters
|
||||
- Power9: Optimized ITX till 16x4.
|
||||
- Loongarch: numerous optimizations
|
||||
- RISC-V optimizations for pal, cdef_filter, ipred, mc_blend, mc_bdir, itx
|
||||
- Allow playing videos in full-screen mode in dav1dplay
|
||||
|
||||
|
||||
Changes for 1.4.3 'Road Runner':
|
||||
--------------------------------
|
||||
|
||||
1.4.3 is a small release focused on security issues
|
||||
- AArch64: Fix potential out of bounds access in DotProd H/HV filters
|
||||
- cli: Prevent buffer over-read
|
||||
|
||||
|
||||
Changes for 1.4.2 'Road Runner':
|
||||
--------------------------------
|
||||
|
||||
1.4.2 is a small release of dav1d, improving notably ARM, AVX-512 and PowerPC
|
||||
- AVX2 optimizations for 8-tap and new variants for 6-tap
|
||||
- AVX-512 optimizations for 8-tap and new variants for 6-tap
|
||||
- Improve entropy decoding on ARM64
|
||||
- New ARM64 optimizations for convolutions based on DotProd extension
|
||||
- New ARM64 optimizations for convolutions based on i8mm extension
|
||||
- New ARM64 optimizations for subpel and prep filters for i8mm
|
||||
- Misc improvements on existing ARM64 optimizations, notably for put/prep
|
||||
- New PowerPC9 optimizations for loopfilter
|
||||
- Support for macOS kperf API for benchmarking
|
||||
|
||||
|
||||
Changes for 1.4.1 'Road Runner':
|
||||
--------------------------------
|
||||
|
||||
1.4.1 is a small release of dav1d, improving notably ARM and RISC-V speed
|
||||
|
||||
- Optimizations for 6tap filters for NEON (ARM)
|
||||
- More RISC-V optimizations for itx (4x8, 8x4, 4x16, 16x4, 8x16, 16x8)
|
||||
- Reduction of binary size on ARM64, ARM32 and RISC-V
|
||||
- Fix out-of-bounds read in 8bpc SSE2/SSSE3 wiener_filter
|
||||
- Msac optimizations
|
||||
|
||||
|
||||
Changes for 1.4.0 'Road Runner':
|
||||
--------------------------------
|
||||
|
||||
1.4.0 is a medium release of dav1d, focusing on new architecture support and optimizations
|
||||
|
||||
- AVX-512 optimizations for z1, z2, z3 in 8bit and high-bitdepth
|
||||
- New architecture supported: loongarch
|
||||
- Loongarch optimizations for 8bit
|
||||
- New architecture supported: RISC-V
|
||||
- RISC-V optimizations for itx
|
||||
- Misc improvements in threading and in reducing binary size
|
||||
- Fix potential integer overflow with extremely large frame sizes (CVE-2024-1580)
|
||||
|
||||
|
||||
Changes for 1.3.0 'Tundra Peregrine Falcon (Calidus)':
|
||||
------------------------------------------------------
|
||||
|
||||
1.3.0 is a medium release of dav1d, focus on new APIs and memory usage reduction.
|
||||
|
||||
- Reduce memory usage in numerous places
|
||||
- ABI break in Dav1dSequenceHeader, Dav1dFrameHeader, Dav1dContentLightLevel structures
|
||||
- new API function to check the API version: dav1d_version_api()
|
||||
- Rewrite of the SGR functions for ARM64 to be faster
|
||||
- NEON implemetation of save_tmvs for ARM32 and ARM64
|
||||
- x86 palette DSP for pal_idx_finish function
|
||||
|
||||
|
||||
Changes for 1.2.1 'Arctic Peregrine Falcon':
|
||||
--------------------------------------------
|
||||
|
||||
1.2.1 is a small release of dav1d, adding more SIMD and fixes
|
||||
|
||||
- Fix a threading race on task_thread.init_done
|
||||
- NEON z2 8bpc and high bit-depth optimizations
|
||||
- SSSE3 z2 high bit-depth optimziations
|
||||
- Fix a desynced luma/chroma planes issue with Film Grain
|
||||
- Reduce memory consumption
|
||||
- Improve dav1d_parse_sequence_header() speed
|
||||
- OBU: Improve header parsing and fix potential overflows
|
||||
- OBU: Improve ITU-T T.35 parsing speed
|
||||
- Misc buildsystems, CI and headers fixes
|
||||
|
||||
|
||||
Changes for 1.2.0 'Arctic Peregrine Falcon':
|
||||
--------------------------------------------
|
||||
|
||||
1.2.0 is a small release of dav1d, adding more SIMD and fixes
|
||||
|
||||
- Improvements on attachments of props and T.35 entries on output pictures
|
||||
- NEON z1/z3 high bit-depth optimizations and improvements for 8bpc
|
||||
- SSSE3 z2/z3 8bpc and SSSE3 z1/z3 high bit-depth optimziations
|
||||
- refmvs.save_tmvs optimizations in SSSE3/AVX2/AVX-512
|
||||
- AVX-512 optimizations for high bit-depth itx (16x64, 32x64, 64x16, 64x32, 64x64)
|
||||
- AVX2 optimizations for 12bpc for 16x32, 32x16, 32x32 itx
|
||||
|
||||
|
||||
Changes for 1.1.0 'Arctic Peregrine Falcon':
|
||||
--------------------------------------------
|
||||
|
||||
1.1.0 is an important release of dav1d, fixing numerous bugs, and adding SIMD
|
||||
|
||||
- New function dav1d_get_frame_delay to query the decoder frame delay
|
||||
- Numerous fixes for strict conformity to the specs and samples
|
||||
- NEON and AVX-512 misc fixes and improvements
|
||||
- Partial AVX2 12bpc transform implementations
|
||||
- AVX-512 high bit-depth cdef_filter, loopfilter, itx
|
||||
- NEON z1/z3 optimization for 8bpc
|
||||
- SSSE3 z1 optimization for 8bpc
|
||||
|
||||
"From VideoLAN with love"
|
||||
|
||||
|
||||
Changes for 1.0.0 'Peregrine Falcon':
|
||||
-------------------------------------
|
||||
|
||||
1.0.0 is a major release of dav1d, adding important features and bug fixes.
|
||||
|
||||
It notably changes, in an important way, the way threading works, by adding
|
||||
an automatic thread management.
|
||||
|
||||
It also adds support for AVX-512 acceleration, and adds speedups to existing x86
|
||||
code (from SSE2 to AVX2).
|
||||
|
||||
1.0.0 adds new grain API to ease acceleration on the GPU, and adds an API call
|
||||
to get information of which frame failed to decode, in error cases.
|
||||
|
||||
Finally, 1.0.0 fixes numerous small bugs that were reported since the beginning
|
||||
of the project to have a proper release.
|
||||
|
||||
.''.
|
||||
.''. . *''* :_\/_: .
|
||||
:_\/_: _\(/_ .:.*_\/_* : /\ : .'.:.'.
|
||||
.''.: /\ : ./)\ ':'* /\ * : '..'. -=:o:=-
|
||||
:_\/_:'.:::. ' *''* * '.\'/.' _\(/_'.':'.'
|
||||
: /\ : ::::: *_\/_* -= o =- /)\ ' *
|
||||
'..' ':::' * /\ * .'/.\'. '
|
||||
* *..* :
|
||||
* :
|
||||
* 1.0.0
|
||||
|
||||
|
||||
|
||||
Changes for 0.9.2 'Golden Eagle':
|
||||
---------------------------------
|
||||
|
||||
0.9.2 is a small update of dav1d on the 0.9.x branch:
|
||||
- x86: SSE4 optimizations of inverse transforms for 10bit for all sizes
|
||||
- x86: mc.resize optimizations with AVX2/SSSE3 for 10/12b
|
||||
- x86: SSSE3 optimizations for cdef_filter in 10/12b and mc_w_mask_422/444 in 8b
|
||||
- ARM NEON optimizations for FilmGrain Gen_grain functions
|
||||
- Optimizations for splat_mv in SSE2/AVX2 and NEON
|
||||
- x86: SGR improvements for SSSE3 CPUs
|
||||
- x86: AVX2 optimizations for cfl_ac
|
||||
|
||||
|
||||
Changes for 0.9.1 'Golden Eagle':
|
||||
---------------------------------
|
||||
|
||||
0.9.1 is a middle-size revision of dav1d, adding notably 10b acceleration for SSSE3:
|
||||
- 10/12b SSSE3 optimizations for mc (avg, w_avg, mask, w_mask, emu_edge),
|
||||
prep/put_bilin, prep/put_8tap, ipred (dc/h/v, paeth, smooth, pal, filter), wiener,
|
||||
sgr (10b), warp8x8, deblock, film_grain, cfl_ac/pred for 32bit and 64bit x86 processors
|
||||
- Film grain NEON for fguv 10/12b, fgy/fguv 8b and fgy/fguv 10/12 arm32
|
||||
- Fixes for filmgrain on ARM
|
||||
- itx 10bit optimizations for 4x4/x8/x16, 8x4/x8/x16 for SSE4
|
||||
- Misc improvements on SSE2, SSE4
|
||||
|
||||
|
||||
Changes for 0.9.0 'Golden Eagle':
|
||||
---------------------------------
|
||||
|
||||
0.9.0 is a major version of dav1d, adding notably 10b acceleration on x64.
|
||||
|
||||
Details:
|
||||
- x86 (64bit) AVX2 implementation of most 10b/12b functions, which should provide
|
||||
a large boost for high-bitdepth decoding on modern x86 computers and servers.
|
||||
- ARM64 neon implementation of FilmGrain (4:2:0/4:2:2/4:4:4 8bit)
|
||||
- New API to signal events happening during the decoding process
|
||||
|
||||
|
||||
Changes for 0.8.2 'Eurasian Hobby':
|
||||
-----------------------------------
|
||||
|
||||
0.8.2 is a middle-size update of the 0.8.0 branch:
|
||||
- ARM32 optimizations for ipred and itx in 10/12bits,
|
||||
completing the 10b/12b work on ARM64 and ARM32
|
||||
- Give the post-filters their own threads
|
||||
- ARM64: rewrite the wiener functions
|
||||
- Speed up coefficient decoding, 0.5%-3% global decoding gain
|
||||
- x86 optimizations for CDEF_filter and wiener in 10/12bit
|
||||
- x86: rewrite the SGR AVX2 asm
|
||||
- x86: improve msac speed on SSE2+ machines
|
||||
- ARM32: improve speed of ipred and warp
|
||||
- ARM64: improve speed of ipred, cdef_dir, cdef_filter, warp_motion and itx16
|
||||
- ARM32/64: improve speed of looprestoration
|
||||
- Add seeking, pausing to the player
|
||||
- Update the player for rendering of 10b/12b
|
||||
- Misc speed improvements and fixes on all platforms
|
||||
- Add a xxh3 muxer in the dav1d application
|
||||
|
||||
|
||||
Changes for 0.8.1 'Eurasian Hobby':
|
||||
-----------------------------------
|
||||
|
||||
0.8.1 is a minor update on 0.8.0:
|
||||
- Keep references to buffers valid after dav1d_close(). Fixes a regression
|
||||
caused by the picture buffer pool added in 0.8.0.
|
||||
- ARM32 optimizations for 10bit bitdepth for SGR
|
||||
- ARM32 optimizations for 16bit bitdepth for blend/w_masl/emu_edge
|
||||
- ARM64 optimizations for 10bit bitdepth for SGR
|
||||
- x86 optimizations for wiener in SSE2/SSSE3/AVX2
|
||||
|
||||
|
||||
Changes for 0.8.0 'Eurasian Hobby':
|
||||
-----------------------------------
|
||||
|
||||
0.8.0 is a major update for dav1d:
|
||||
- Improve the performance by using a picture buffer pool;
|
||||
The improvements can reach 10% on some cases on Windows.
|
||||
- Support for Apple ARM Silicon
|
||||
- ARM32 optimizations for 8bit bitdepth for ipred paeth, smooth, cfl
|
||||
- ARM32 optimizations for 10/12/16bit bitdepth for mc_avg/mask/w_avg,
|
||||
put/prep 8tap/bilin, wiener and CDEF filters
|
||||
- ARM64 optimizations for cfl_ac 444 for all bitdepths
|
||||
- x86 optimizations for MC 8-tap, mc_scaled in AVX2
|
||||
- x86 optimizations for CDEF in SSE and {put/prep}_{8tap/bilin} in SSSE3
|
||||
|
||||
|
||||
Changes for 0.7.1 'Frigatebird':
|
||||
------------------------------
|
||||
|
||||
0.7.1 is a minor update on 0.7.0:
|
||||
- ARM32 NEON optimizations for itxfm, which can give up to 28% speedup, and MSAC
|
||||
- SSE2 optimizations for prep_bilin and prep_8tap
|
||||
- AVX2 optimizations for MC scaled
|
||||
- Fix a clamping issue in motion vector projection
|
||||
- Fix an issue on some specific Haswell CPU on ipred_z AVX2 functions
|
||||
- Improvements on the dav1dplay utility player to support resizing
|
||||
|
||||
|
||||
Changes for 0.7.0 'Frigatebird':
|
||||
------------------------------
|
||||
|
||||
0.7.0 is a major release for dav1d:
|
||||
- Faster refmv implementation gaining up to 12% speed while -25% of RAM (Single Thread)
|
||||
- 10b/12b ARM64 optimizations are mostly complete:
|
||||
- ipred (paeth, smooth, dc, pal, filter, cfl)
|
||||
- itxfm (only 10b)
|
||||
- AVX2/SSSE3 for non-4:2:0 film grain and for mc.resize
|
||||
- AVX2 for cfl4:4:4
|
||||
- AVX-512 CDEF filter
|
||||
- ARM64 8b improvements for cfl_ac and itxfm
|
||||
- ARM64 implementation for emu_edge in 8b/10b/12b
|
||||
- ARM32 implementation for emu_edge in 8b
|
||||
- Improvements on the dav1dplay utility player to support 10 bit,
|
||||
non-4:2:0 pixel formats and film grain on the GPU
|
||||
|
||||
|
||||
Changes for 0.6.0 'Gyrfalcon':
|
||||
------------------------------
|
||||
|
||||
0.6.0 is a major release for dav1d:
|
||||
- New ARM64 optimizations for the 10/12bit depth:
|
||||
- mc_avg, mc_w_avg, mc_mask
|
||||
- mc_put/mc_prep 8tap/bilin
|
||||
- mc_warp_8x8
|
||||
- mc_w_mask
|
||||
- mc_blend
|
||||
- wiener
|
||||
- SGR
|
||||
- loopfilter
|
||||
- cdef
|
||||
- New AVX-512 optimizations for prep_bilin, prep_8tap, cdef_filter, mc_avg/w_avg/mask
|
||||
- New SSSE3 optimizations for film grain
|
||||
- New AVX2 optimizations for msac_adapt16
|
||||
- Fix rare mismatches against the reference decoder, notably because of clipping
|
||||
- Improvements on ARM64 on msac, cdef, mc_blend_v and looprestoration optimizations
|
||||
- Improvements on AVX2 optimizations for cdef_filter
|
||||
- Improvements in the C version for itxfm, cdef_filter
|
||||
|
||||
|
||||
Changes for 0.5.2 'Asiatic Cheetah':
|
||||
------------------------------------
|
||||
|
||||
0.5.2 is a small release improving speed for ARM32 and adding minor features:
|
||||
- ARM32 optimizations for loopfilter, ipred_dc|h|v
|
||||
- Add section-5 raw OBU demuxer
|
||||
- Improve the speed by reducing the L2 cache collisions
|
||||
- Fix minor issues
|
||||
|
||||
|
||||
Changes for 0.5.1 'Asiatic Cheetah':
|
||||
------------------------------------
|
||||
|
||||
0.5.1 is a small release improving speeds and fixing minor issues
|
||||
compared to 0.5.0:
|
||||
- SSE2 optimizations for CDEF, wiener and warp_affine
|
||||
- NEON optimizations for SGR on ARM32
|
||||
- Fix mismatch issue in x86 asm in inverse identity transforms
|
||||
- Fix build issue in ARM64 assembly if debug info was enabled
|
||||
- Add a workaround for Xcode 11 -fstack-check bug
|
||||
|
||||
|
||||
Changes for 0.5.0 'Asiatic Cheetah':
|
||||
------------------------------------
|
||||
|
||||
0.5.0 is a medium release fixing regressions and minor issues,
|
||||
and improving speed significantly:
|
||||
- Export ITU T.35 metadata
|
||||
- Speed improvements on blend_ on ARM
|
||||
- Speed improvements on decode_coef and MSAC
|
||||
- NEON optimizations for blend*, w_mask_, ipred functions for ARM64
|
||||
- NEON optimizations for CDEF and warp on ARM32
|
||||
- SSE2 optimizations for MSAC hi_tok decoding
|
||||
- SSSE3 optimizations for deblocking loopfilters and warp_affine
|
||||
- AVX2 optimizations for film grain and ipred_z2
|
||||
- SSE4 optimizations for warp_affine
|
||||
- VSX optimizations for wiener
|
||||
- Fix inverse transform overflows in x86 and NEON asm
|
||||
- Fix integer overflows with large frames
|
||||
- Improve film grain generation to match reference code
|
||||
- Improve compatibility with older binutils for ARM
|
||||
- More advanced Player example in tools
|
||||
|
||||
|
||||
Changes for 0.4.0 'Cheetah':
|
||||
----------------------------
|
||||
|
||||
- Fix playback with unknown OBUs
|
||||
- Add an option to limit the maximum frame size
|
||||
- SSE2 and ARM64 optimizations for MSAC
|
||||
- Improve speed on 32bits systems
|
||||
- Optimization in obmc blend
|
||||
- Reduce RAM usage significantly
|
||||
- The initial PPC SIMD code, cdef_filter
|
||||
- NEON optimizations for blend functions on ARM
|
||||
- NEON optimizations for w_mask functions on ARM
|
||||
- NEON optimizations for inverse transforms on ARM64
|
||||
- VSX optimizations for CDEF filter
|
||||
- Improve handling of malloc failures
|
||||
- Simple Player example in tools
|
||||
|
||||
|
||||
Changes for 0.3.1 'Sailfish':
|
||||
------------------------------
|
||||
|
||||
- Fix a buffer overflow in frame-threading mode on SSSE3 CPUs
|
||||
- Reduce binary size, notably on Windows
|
||||
- SSSE3 optimizations for ipred_filter
|
||||
- ARM optimizations for MSAC
|
||||
|
||||
|
||||
Changes for 0.3.0 'Sailfish':
|
||||
------------------------------
|
||||
|
||||
This is the final release for the numerous speed improvements of 0.3.0-rc.
|
||||
It mostly:
|
||||
- Fixes an annoying crash on SSSE3 that happened in the itx functions
|
||||
|
||||
|
||||
Changes for 0.2.2 (0.3.0-rc) 'Antelope':
|
||||
-----------------------------
|
||||
|
||||
- Large improvement on MSAC decoding with SSE, bringing 4-6% speed increase
|
||||
The impact is important on SSSE3, SSE4 and AVX2 cpus
|
||||
- SSSE3 optimizations for all blocks size in itx
|
||||
- SSSE3 optimizations for ipred_paeth and ipred_cfl (420, 422 and 444)
|
||||
- Speed improvements on CDEF for SSE4 CPUs
|
||||
- NEON optimizations for SGR and loop filter
|
||||
- Minor crashes, improvements and build changes
|
||||
|
||||
|
||||
Changes for 0.2.1 'Antelope':
|
||||
----------------------------
|
||||
|
||||
- SSSE3 optimization for cdef_dir
|
||||
- AVX2 improvements of the existing CDEF optimizations
|
||||
- NEON improvements of the existing CDEF and wiener optimizations
|
||||
- Clarification about the numbering/versionning scheme
|
||||
|
||||
|
||||
Changes for 0.2.0 'Antelope':
|
||||
----------------------------
|
||||
|
||||
- ARM64 and ARM optimizations using NEON instructions
|
||||
- SSSE3 optimizations for both 32 and 64bits
|
||||
- More AVX2 assembly, reaching almost completion
|
||||
- Fix installation of includes
|
||||
- Rewrite inverse transforms to avoid overflows
|
||||
- Snap packaging for Linux
|
||||
- Updated API (ABI and API break)
|
||||
- Fixes for un-decodable samples
|
||||
|
||||
|
||||
Changes for 0.1.0 'Gazelle':
|
||||
----------------------------
|
||||
|
||||
Initial release of dav1d, the fast and small AV1 decoder.
|
||||
- Support for all features of the AV1 bitstream
|
||||
- Support for all bitdepth, 8, 10 and 12bits
|
||||
- Support for all chroma subsamplings 4:2:0, 4:2:2, 4:4:4 *and* grayscale
|
||||
- Full acceleration for AVX2 64bits processors, making it the fastest decoder
|
||||
- Partial acceleration for SSSE3 processors
|
||||
- Partial acceleration for NEON processors
|
||||
168
media/libdav1d/src/README.md
Normal file
168
media/libdav1d/src/README.md
Normal file
|
|
@ -0,0 +1,168 @@
|
|||

|
||||
|
||||
# dav1d
|
||||
|
||||
**dav1d** is an **AV1** cross-platform **d**ecoder, open-source, and focused on speed and correctness.
|
||||
|
||||
It is now battle-tested and production-ready and can be used everywhere.
|
||||
|
||||
The canonical repository URL for this repo is https://code.videolan.org/videolan/dav1d
|
||||
|
||||
This project was partially funded by the *Alliance for Open Media*/**AOM**.
|
||||
|
||||
## Goal and Features
|
||||
|
||||
The goal of this project is to provide a decoder for **most platforms**, and achieve the **highest speed** possible to overcome the temporary lack of AV1 hardware decoder.
|
||||
|
||||
It supports all features from AV1, including all subsampling and bit-depth parameters.
|
||||
|
||||
In the future, this project will host simple tools or simple wrappings *(like, for example, an MFT transform)*.
|
||||
|
||||
## License
|
||||
|
||||
**dav1d** is released under a very liberal license, a contrario from the other VideoLAN projects, so that it can be embedded anywhere, including non-open-source software; or even drivers, to allow the creation of hybrid decoders.
|
||||
|
||||
The reasoning behind this decision is the same as for libvorbis, see [RMS on vorbis](https://lwn.net/2001/0301/a/rms-ov-license.php3).
|
||||
|
||||
# Roadmap
|
||||
|
||||
The plan is the following:
|
||||
|
||||
### Reached
|
||||
1. Complete C implementation of the decoder,
|
||||
2. Provide a usable API,
|
||||
3. Port to most platforms,
|
||||
4. Make it fast on desktop, by writing asm for AVX2 chips.
|
||||
5. Make it fast on mobile, by writing asm for ARMv8 chips,
|
||||
6. Make it fast on older desktop, by writing asm for SSSE3+ chips,
|
||||
7. Make high bit-depth fast on mobile, by writing asm for ARMv8 chips.
|
||||
8. Make it fast on older mobile, by writing asm for ARMv7 chips,
|
||||
9. Make high bit-depth fast on older mobile, by writing asm for ARMv7 chips,
|
||||
10. Make high bit-depth fast on desktop, by writing asm for AVX2 chips,
|
||||
11. Make high bit-depth fast on older desktop, by writing asm for SSSE3+ chips,
|
||||
12. Improve threading.
|
||||
|
||||
### On-going
|
||||
13. Improve C code base with [various tweaks](https://code.videolan.org/videolan/dav1d/wikis/task-list),
|
||||
14. Accelerate for less common architectures, like PPC, SSE2, RISC-V or AVX-512.
|
||||
|
||||
### After
|
||||
15. Use more GPU decoding, when possible.
|
||||
|
||||
# Contribute
|
||||
|
||||
Currently, we are looking for help from:
|
||||
- C developers,
|
||||
- asm developers,
|
||||
- platform-specific developers,
|
||||
- GPGPU developers,
|
||||
- testers.
|
||||
|
||||
Our contributions guidelines are quite strict. We want to build a coherent codebase to simplify maintenance and achieve the highest possible speed.
|
||||
|
||||
Notably, the codebase is in pure C and asm.
|
||||
|
||||
We are on IRC, on the **#dav1d** channel on [*Libera.chat*](http://libera.chat/). If you do not have an IRC Client at hand, use [IRC Web Interface](https://web.libera.chat/#dav1d).
|
||||
|
||||
See the [contributions document](CONTRIBUTING.md).
|
||||
|
||||
## CLA
|
||||
|
||||
There is no CLA.
|
||||
|
||||
People will keep their copyright and their authorship rights, while adhering to the BSD 2-clause license.
|
||||
|
||||
VideoLAN will only have the collective work rights.
|
||||
|
||||
## CoC
|
||||
|
||||
The [VideoLAN Code of Conduct](https://wiki.videolan.org/CoC) applies to this project.
|
||||
|
||||
# Compile
|
||||
## General compilation steps
|
||||
|
||||
1. Install [Meson](https://mesonbuild.com/) (0.49 or higher), [Ninja](https://ninja-build.org/), and, for x86\* targets, [nasm](https://nasm.us/) (2.14 or higher)
|
||||
2. Run `mkdir build && cd build` to create a build directory and enter it
|
||||
3. Run `meson setup ..` to configure meson, add `--default-library=static` if static linking is desired
|
||||
4. Run `ninja` to compile
|
||||
|
||||
Following are modification of step 3 and 4, for specific purpose.
|
||||
|
||||
## Cross-Compilation for 32- or 64-bit Windows, 32-bit Linux
|
||||
|
||||
If you're on a linux build machine trying to compile .exe for a Windows target/host machine, configure meson like this
|
||||
|
||||
```
|
||||
meson setup .. --cross-file=../package/crossfiles/x86_64-w64-mingw32.meson
|
||||
```
|
||||
|
||||
or, for 32-bit:
|
||||
|
||||
```
|
||||
meson setup .. --cross-file=../package/crossfiles/i686-w64-mingw32.meson
|
||||
```
|
||||
|
||||
`mingw-w64` is a pre-requisite and should be installed on your linux machine via your preferred method or package manager. Note the binary name formats may differ between distributions. Verify the names, and use `alias` if certain binaries cannot be found.
|
||||
|
||||
For 32-bit linux, run
|
||||
|
||||
```
|
||||
meson setup .. --cross-file=../package/crossfiles/i686-linux32.meson
|
||||
```
|
||||
|
||||
## Build documentation
|
||||
|
||||
1. Make sure [doxygen](https://www.doxygen.nl/) and [graphviz](https://www.graphviz.org/) are installed.
|
||||
2. Run `meson setup .. -Denable_docs=true` to configure meson to generate docs from the build directory.
|
||||
3. Run `ninja doc/html` to build the docs
|
||||
|
||||
The result can be found in `build/doc/html/`. An online version built from master can be found [here](https://videolan.videolan.me/dav1d/).
|
||||
|
||||
# Run tests
|
||||
|
||||
1. In the root directory, run `git clone https://code.videolan.org/videolan/dav1d-test-data.git tests/dav1d-test-data` to fetch the test data repository
|
||||
2. During meson configuration, specify `-Dtestdata_tests=true`
|
||||
3. Run `meson test -v` after compiling
|
||||
|
||||
## Decoder conformance tests (optional but encouraged)
|
||||
|
||||
1. Download the argon conformance bitstreams from https://streams.videolan.org/argon/
|
||||
2. Extract into dav1d directory by running `tar -xvf argon.tar.zst`
|
||||
3. Execute tests with `tests/dav1d_argon.bash -d build/tools/dav1d -a argon`
|
||||
4. Expected outcome is `2763 files successfully verified in XXmYYs (dav1d 1.x.y-zz-gHHHHHHH filmgrain=1 cpumask=-1)`
|
||||
|
||||
# Support
|
||||
|
||||
This project is partially funded by the *Alliance for Open Media*/**AOM** and is supported by TwoOrioles and VideoLabs.
|
||||
|
||||
These companies can provide support and integration help, should you need it.
|
||||
|
||||
|
||||
# FAQ
|
||||
|
||||
## Why do you not improve libaom rather than starting a new project?
|
||||
|
||||
- We believe that libaom is a very good library. It was however developed for research purposes during AV1 design.
|
||||
We think that an implementation written from scratch can achieve faster decoding, in the same way that *ffvp9* was faster than *libvpx*.
|
||||
|
||||
## Is dav1d a recursive acronym?
|
||||
|
||||
- Yes.
|
||||
|
||||
## Can I help?
|
||||
|
||||
- Yes. See the [contributions document](CONTRIBUTING.md).
|
||||
|
||||
## I am not a developer. Can I help?
|
||||
|
||||
- Yes. We need testers, bug reporters and documentation writers.
|
||||
|
||||
## What about the AV1 patent license?
|
||||
|
||||
- This project is an implementation of a decoder. It gives you no special rights on the AV1 patents.
|
||||
|
||||
Please read the [AV1 patent license](doc/PATENTS) that applies to the AV1 specification and codec.
|
||||
|
||||
## Will you care about <my_arch>? <my_os>?
|
||||
|
||||
- We do, but we don't have either the time or the knowledge. Therefore, patches and contributions welcome.
|
||||
35
media/libdav1d/src/THANKS.md
Normal file
35
media/libdav1d/src/THANKS.md
Normal file
|
|
@ -0,0 +1,35 @@
|
|||
# The dav1d project and VideoLAN association would like to thank
|
||||
|
||||
## AOM
|
||||
The Alliance for Open Media (AOM) for partially funding this project.
|
||||
|
||||
## Companies
|
||||
* Two Orioles LLC, for important coding effort
|
||||
* VideoLabs SAS
|
||||
|
||||
## Projects
|
||||
* VideoLAN
|
||||
* FFmpeg
|
||||
* libplacebo
|
||||
|
||||
## Individual
|
||||
|
||||
And all the dav1d Authors (git shortlog -sn), including:
|
||||
|
||||
Henrik Gramner, Martin Storsjö, Ronald S. Bultje, Janne Grunau, James Almer,
|
||||
Victorien Le Couviour--Tuffet, Matthias Dressel, Nathan E. Egge,
|
||||
Jean-Baptiste Kempf, Marvin Scholz, Luc Trudeau, Niklas Haas,
|
||||
Hugo Beauzée-Luyssen, Konstantin Pavlov, David Michael Barr, Steve Lhomme,
|
||||
yuanhecai, Luca Barbato, Wan-Teh Chang, Kyle Siefring, B Krishnan Iyer,
|
||||
Francois Cartegnie, Liwei Wang, David Conrad, Derek Buitenhuis, Jan Beich,
|
||||
Michael Bradshaw, Raphaël Zumer, Xuefeng Jiang, Arpad Panyik, Christophe Gisquet,
|
||||
Justin Bull, Boyuan Xiao, Dale Curtis, Emmanuel Gil Peyrot, Raphael Zumer,
|
||||
Rupert Swarbrick, Thierry Foucu, Thomas Daede, jinbo, André Kempe, Colin Lee,
|
||||
Jonathan Wright, Lynne, Michail Alvanos, Nico Weber, Salome Thirot, SmilingWolf,
|
||||
Tristan Laurent, Tristan Matthews, Vittorio Giovara, Yannis Guyon,
|
||||
Andrey Semashev, Anisse Astier, Anton Mitrofanov, Charlie Hayden, Dmitriy Sychov,
|
||||
Ewout ter Hoeven, Fred Barbier, Hao Chen, Jean-Yves Avenard, Joe Drago,
|
||||
Mark Shuttleworth, Matthieu Bouron, Mehdi Sabwat, Nicolas Frattaroli,
|
||||
Pablo Stebler, Rostislav Pehlivanov, Sebastian Dröge, Shiz, Steinar Midtskogen,
|
||||
Sylvain BERTRAND, Sylvestre Ledru, Timo Gurr, Vibhoothi,
|
||||
Vignesh Venkatasubramanian, Xavier Claessens, Xu Guangxin, kossh1 and skal.
|
||||
23
media/libdav1d/src/doc/Doxyfile.in.in
Normal file
23
media/libdav1d/src/doc/Doxyfile.in.in
Normal file
|
|
@ -0,0 +1,23 @@
|
|||
PROJECT_NAME = dav1d
|
||||
PROJECT_NUMBER = \@VCS_TAG\@
|
||||
PROJECT_BRIEF = dav1d is an AV1 decoder
|
||||
OUTPUT_DIRECTORY = @DOXYGEN_OUTPUT@
|
||||
STRIP_FROM_PATH = @DOXYGEN_STRIP@
|
||||
OUTPUT_LANGUAGE = English
|
||||
TAB_SIZE = 4
|
||||
EXTRACT_ALL = YES
|
||||
OPTIMIZE_OUTPUT_FOR_C = YES
|
||||
DOXYFILE_ENCODING = UTF-8
|
||||
TYPEDEF_HIDES_STRUCT = YES
|
||||
HAVE_DOT = YES
|
||||
|
||||
QUIET = YES
|
||||
WARNINGS = YES
|
||||
WARN_IF_UNDOCUMENTED = YES
|
||||
WARN_AS_ERROR = FAIL_ON_WARNINGS
|
||||
|
||||
INPUT = @DOXYGEN_INPUT@
|
||||
FILE_PATTERNS = *.h
|
||||
|
||||
GENERATE_HTML = YES
|
||||
GENERATE_LATEX = NO
|
||||
108
media/libdav1d/src/doc/PATENTS
Normal file
108
media/libdav1d/src/doc/PATENTS
Normal file
|
|
@ -0,0 +1,108 @@
|
|||
Alliance for Open Media Patent License 1.0
|
||||
|
||||
1. License Terms.
|
||||
|
||||
1.1. Patent License. Subject to the terms and conditions of this License, each
|
||||
Licensor, on behalf of itself and successors in interest and assigns,
|
||||
grants Licensee a non-sublicensable, perpetual, worldwide, non-exclusive,
|
||||
no-charge, royalty-free, irrevocable (except as expressly stated in this
|
||||
License) patent license to its Necessary Claims to make, use, sell, offer
|
||||
for sale, import or distribute any Implementation.
|
||||
|
||||
1.2. Conditions.
|
||||
|
||||
1.2.1. Availability. As a condition to the grant of rights to Licensee to make,
|
||||
sell, offer for sale, import or distribute an Implementation under
|
||||
Section 1.1, Licensee must make its Necessary Claims available under
|
||||
this License, and must reproduce this License with any Implementation
|
||||
as follows:
|
||||
|
||||
a. For distribution in source code, by including this License in the
|
||||
root directory of the source code with its Implementation.
|
||||
|
||||
b. For distribution in any other form (including binary, object form,
|
||||
and/or hardware description code (e.g., HDL, RTL, Gate Level Netlist,
|
||||
GDSII, etc.)), by including this License in the documentation, legal
|
||||
notices, and/or other written materials provided with the
|
||||
Implementation.
|
||||
|
||||
1.2.2. Additional Conditions. This license is directly from Licensor to
|
||||
Licensee. Licensee acknowledges as a condition of benefiting from it
|
||||
that no rights from Licensor are received from suppliers, distributors,
|
||||
or otherwise in connection with this License.
|
||||
|
||||
1.3. Defensive Termination. If any Licensee, its Affiliates, or its agents
|
||||
initiates patent litigation or files, maintains, or voluntarily
|
||||
participates in a lawsuit against another entity or any person asserting
|
||||
that any Implementation infringes Necessary Claims, any patent licenses
|
||||
granted under this License directly to the Licensee are immediately
|
||||
terminated as of the date of the initiation of action unless 1) that suit
|
||||
was in response to a corresponding suit regarding an Implementation first
|
||||
brought against an initiating entity, or 2) that suit was brought to
|
||||
enforce the terms of this License (including intervention in a third-party
|
||||
action by a Licensee).
|
||||
|
||||
1.4. Disclaimers. The Reference Implementation and Specification are provided
|
||||
"AS IS" and without warranty. The entire risk as to implementing or
|
||||
otherwise using the Reference Implementation or Specification is assumed
|
||||
by the implementer and user. Licensor expressly disclaims any warranties
|
||||
(express, implied, or otherwise), including implied warranties of
|
||||
merchantability, non-infringement, fitness for a particular purpose, or
|
||||
title, related to the material. IN NO EVENT WILL LICENSOR BE LIABLE TO
|
||||
ANY OTHER PARTY FOR LOST PROFITS OR ANY FORM OF INDIRECT, SPECIAL,
|
||||
INCIDENTAL, OR CONSEQUENTIAL DAMAGES OF ANY CHARACTER FROM ANY CAUSES OF
|
||||
ACTION OF ANY KIND WITH RESPECT TO THIS LICENSE, WHETHER BASED ON BREACH
|
||||
OF CONTRACT, TORT (INCLUDING NEGLIGENCE), OR OTHERWISE, AND WHETHER OR
|
||||
NOT THE OTHER PARTRY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
2. Definitions.
|
||||
|
||||
2.1. Affiliate. “Affiliate” means an entity that directly or indirectly
|
||||
Controls, is Controlled by, or is under common Control of that party.
|
||||
|
||||
2.2. Control. “Control” means direct or indirect control of more than 50% of
|
||||
the voting power to elect directors of that corporation, or for any other
|
||||
entity, the power to direct management of such entity.
|
||||
|
||||
2.3. Decoder. "Decoder" means any decoder that conforms fully with all
|
||||
non-optional portions of the Specification.
|
||||
|
||||
2.4. Encoder. "Encoder" means any encoder that produces a bitstream that can
|
||||
be decoded by a Decoder only to the extent it produces such a bitstream.
|
||||
|
||||
2.5. Final Deliverable. “Final Deliverable” means the final version of a
|
||||
deliverable approved by the Alliance for Open Media as a Final
|
||||
Deliverable.
|
||||
|
||||
2.6. Implementation. "Implementation" means any implementation, including the
|
||||
Reference Implementation, that is an Encoder and/or a Decoder. An
|
||||
Implementation also includes components of an Implementation only to the
|
||||
extent they are used as part of an Implementation.
|
||||
|
||||
2.7. License. “License” means this license.
|
||||
|
||||
2.8. Licensee. “Licensee” means any person or entity who exercises patent
|
||||
rights granted under this License.
|
||||
|
||||
2.9. Licensor. "Licensor" means (i) any Licensee that makes, sells, offers
|
||||
for sale, imports or distributes any Implementation, or (ii) a person
|
||||
or entity that has a licensing obligation to the Implementation as a
|
||||
result of its membership and/or participation in the Alliance for Open
|
||||
Media working group that developed the Specification.
|
||||
|
||||
2.10. Necessary Claims. "Necessary Claims" means all claims of patents or
|
||||
patent applications, (a) that currently or at any time in the future,
|
||||
are owned or controlled by the Licensor, and (b) (i) would be an
|
||||
Essential Claim as defined by the W3C Policy as of February 5, 2004
|
||||
(https://www.w3.org/Consortium/Patent-Policy-20040205/#def-essential)
|
||||
as if the Specification was a W3C Recommendation; or (ii) are infringed
|
||||
by the Reference Implementation.
|
||||
|
||||
2.11. Reference Implementation. “Reference Implementation” means an Encoder
|
||||
and/or Decoder released by the Alliance for Open Media as a Final
|
||||
Deliverable.
|
||||
|
||||
2.12. Specification. “Specification” means the specification designated by
|
||||
the Alliance for Open Media as a Final Deliverable for which this
|
||||
License was issued.
|
||||
|
||||
BIN
media/libdav1d/src/doc/dav1d_logo.png
Normal file
BIN
media/libdav1d/src/doc/dav1d_logo.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 19 KiB |
1
media/libdav1d/src/doc/dav1d_logo.svg
Normal file
1
media/libdav1d/src/doc/dav1d_logo.svg
Normal file
File diff suppressed because one or more lines are too long
|
After Width: | Height: | Size: 5.3 KiB |
51
media/libdav1d/src/doc/meson.build
Normal file
51
media/libdav1d/src/doc/meson.build
Normal file
|
|
@ -0,0 +1,51 @@
|
|||
# Copyright © 2018-2022, VideoLAN and dav1d authors
|
||||
# All rights reserved.
|
||||
#
|
||||
# Redistribution and use in source and binary forms, with or without
|
||||
# modification, are permitted provided that the following conditions are met:
|
||||
#
|
||||
# 1. Redistributions of source code must retain the above copyright notice, this
|
||||
# list of conditions and the following disclaimer.
|
||||
#
|
||||
# 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
# this list of conditions and the following disclaimer in the documentation
|
||||
# and/or other materials provided with the distribution.
|
||||
#
|
||||
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
# DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
|
||||
# ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
# (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
# ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
if not get_option('enable_docs')
|
||||
subdir_done()
|
||||
endif
|
||||
|
||||
doxygen = find_program('doxygen')
|
||||
dot = find_program('dot')
|
||||
|
||||
conf_data = configuration_data()
|
||||
conf_data.set('DOXYGEN_INPUT', dav1d_src_root / 'include/dav1d')
|
||||
conf_data.set('DOXYGEN_STRIP', dav1d_src_root / 'include')
|
||||
conf_data.set('DOXYGEN_OUTPUT', meson.current_build_dir())
|
||||
doxyfile = configure_file(input: 'Doxyfile.in.in',
|
||||
output: 'Doxyfile.in',
|
||||
configuration: conf_data)
|
||||
|
||||
doxyfile_rev_target = vcs_tag(command: [
|
||||
'git', '--git-dir', dav1d_git_dir, 'describe', '--long', '--always'
|
||||
],
|
||||
input: doxyfile,
|
||||
output: 'Doxyfile'
|
||||
)
|
||||
|
||||
custom_target('doc',
|
||||
build_by_default: false,
|
||||
command: [doxygen, doxyfile_rev_target],
|
||||
output: ['html']
|
||||
)
|
||||
792
media/libdav1d/src/examples/dav1dplay.c
Normal file
792
media/libdav1d/src/examples/dav1dplay.c
Normal file
|
|
@ -0,0 +1,792 @@
|
|||
/*
|
||||
* Copyright © 2019, VideoLAN and dav1d authors
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
#include "vcs_version.h"
|
||||
|
||||
#include <getopt.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
#include <SDL.h>
|
||||
|
||||
#include "dav1d/dav1d.h"
|
||||
|
||||
#include "common/attributes.h"
|
||||
#include "tools/input/input.h"
|
||||
#include "dp_fifo.h"
|
||||
#include "dp_renderer.h"
|
||||
|
||||
#define FRAME_OFFSET_TO_PTS(foff) \
|
||||
(uint64_t)(((foff) * rd_ctx->spf) * 1000000000.0 + .5)
|
||||
#define TS_TO_PTS(ts) \
|
||||
(uint64_t)(((ts) * rd_ctx->timebase) * 1000000000.0 + .5)
|
||||
|
||||
// Selected renderer callbacks and cookie
|
||||
static const Dav1dPlayRenderInfo *renderer_info = { NULL };
|
||||
|
||||
/**
|
||||
* Render context structure
|
||||
* This structure contains informations necessary
|
||||
* to be shared between the decoder and the renderer
|
||||
* threads.
|
||||
*/
|
||||
typedef struct render_context
|
||||
{
|
||||
Dav1dPlaySettings settings;
|
||||
Dav1dSettings lib_settings;
|
||||
|
||||
// Renderer private data (passed to callbacks)
|
||||
void *rd_priv;
|
||||
|
||||
// Lock to protect access to the context structure
|
||||
SDL_mutex *lock;
|
||||
|
||||
// Timestamp of last displayed frame (in timebase unit)
|
||||
int64_t last_ts;
|
||||
// Timestamp of last decoded frame (in timebase unit)
|
||||
int64_t current_ts;
|
||||
// Ticks when last frame was received
|
||||
uint32_t last_ticks;
|
||||
// PTS time base
|
||||
double timebase;
|
||||
// Seconds per frame
|
||||
double spf;
|
||||
// Number of frames
|
||||
uint32_t total;
|
||||
|
||||
// Fifo
|
||||
Dav1dPlayPtrFifo *fifo;
|
||||
|
||||
// Custom SDL2 event types
|
||||
uint32_t event_types;
|
||||
|
||||
// User pause state
|
||||
uint8_t user_paused;
|
||||
// Internal pause state
|
||||
uint8_t paused;
|
||||
// Start of internal pause state
|
||||
uint32_t pause_start;
|
||||
// Duration of internal pause state
|
||||
uint32_t pause_time;
|
||||
|
||||
// Seek accumulator
|
||||
int seek;
|
||||
|
||||
// Indicates if termination of the decoder thread was requested
|
||||
uint8_t dec_should_terminate;
|
||||
} Dav1dPlayRenderContext;
|
||||
|
||||
static void dp_settings_print_usage(const char *const app,
|
||||
const char *const reason, ...)
|
||||
{
|
||||
if (reason) {
|
||||
va_list args;
|
||||
|
||||
va_start(args, reason);
|
||||
vfprintf(stderr, reason, args);
|
||||
va_end(args);
|
||||
fprintf(stderr, "\n\n");
|
||||
}
|
||||
fprintf(stderr, "Usage: %s [options]\n\n", app);
|
||||
fprintf(stderr, "Supported options:\n"
|
||||
" --input/-i $file: input file\n"
|
||||
" --untimed/-u: ignore PTS, render as fast as possible\n"
|
||||
" --threads $num: number of threads (default: 0)\n"
|
||||
" --framedelay $num: maximum frame delay, capped at $threads (default: 0);\n"
|
||||
" set to 1 for low-latency decoding\n"
|
||||
" --highquality: enable high quality rendering\n"
|
||||
" --zerocopy/-z: enable zero copy upload path\n"
|
||||
" --gpugrain/-g: enable GPU grain synthesis\n"
|
||||
" --fullscreen/-f: enable full screen mode\n"
|
||||
" --version/-v: print version and exit\n"
|
||||
" --renderer/-r: select renderer backend (default: auto)\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
static unsigned parse_unsigned(const char *const optarg, const int option,
|
||||
const char *const app)
|
||||
{
|
||||
char *end;
|
||||
const unsigned res = (unsigned) strtoul(optarg, &end, 0);
|
||||
if (*end || end == optarg)
|
||||
dp_settings_print_usage(app, "Invalid argument \"%s\" for option %s; should be an integer",
|
||||
optarg, option);
|
||||
return res;
|
||||
}
|
||||
|
||||
static void dp_rd_ctx_parse_args(Dav1dPlayRenderContext *rd_ctx,
|
||||
const int argc, char *const *const argv)
|
||||
{
|
||||
int o;
|
||||
Dav1dPlaySettings *settings = &rd_ctx->settings;
|
||||
Dav1dSettings *lib_settings = &rd_ctx->lib_settings;
|
||||
|
||||
// Short options
|
||||
static const char short_opts[] = "i:vuzgfr:";
|
||||
|
||||
enum {
|
||||
ARG_THREADS = 256,
|
||||
ARG_FRAME_DELAY,
|
||||
ARG_HIGH_QUALITY,
|
||||
};
|
||||
|
||||
// Long options
|
||||
static const struct option long_opts[] = {
|
||||
{ "input", 1, NULL, 'i' },
|
||||
{ "version", 0, NULL, 'v' },
|
||||
{ "untimed", 0, NULL, 'u' },
|
||||
{ "threads", 1, NULL, ARG_THREADS },
|
||||
{ "framedelay", 1, NULL, ARG_FRAME_DELAY },
|
||||
{ "highquality", 0, NULL, ARG_HIGH_QUALITY },
|
||||
{ "zerocopy", 0, NULL, 'z' },
|
||||
{ "gpugrain", 0, NULL, 'g' },
|
||||
{ "fullscreen", 0, NULL, 'f'},
|
||||
{ "renderer", 0, NULL, 'r'},
|
||||
{ NULL, 0, NULL, 0 },
|
||||
};
|
||||
|
||||
while ((o = getopt_long(argc, argv, short_opts, long_opts, NULL)) != -1) {
|
||||
switch (o) {
|
||||
case 'i':
|
||||
settings->inputfile = optarg;
|
||||
break;
|
||||
case 'v':
|
||||
fprintf(stderr, "%s\n", dav1d_version());
|
||||
exit(0);
|
||||
case 'u':
|
||||
settings->untimed = true;
|
||||
break;
|
||||
case ARG_HIGH_QUALITY:
|
||||
settings->highquality = true;
|
||||
break;
|
||||
case 'z':
|
||||
settings->zerocopy = true;
|
||||
break;
|
||||
case 'g':
|
||||
settings->gpugrain = true;
|
||||
break;
|
||||
case 'f':
|
||||
settings->fullscreen = true;
|
||||
break;
|
||||
case 'r':
|
||||
settings->renderer_name = optarg;
|
||||
break;
|
||||
case ARG_THREADS:
|
||||
lib_settings->n_threads =
|
||||
parse_unsigned(optarg, ARG_THREADS, argv[0]);
|
||||
break;
|
||||
case ARG_FRAME_DELAY:
|
||||
lib_settings->max_frame_delay =
|
||||
parse_unsigned(optarg, ARG_FRAME_DELAY, argv[0]);
|
||||
break;
|
||||
default:
|
||||
dp_settings_print_usage(argv[0], NULL);
|
||||
}
|
||||
}
|
||||
|
||||
if (optind < argc)
|
||||
dp_settings_print_usage(argv[0],
|
||||
"Extra/unused arguments found, e.g. '%s'\n", argv[optind]);
|
||||
if (!settings->inputfile)
|
||||
dp_settings_print_usage(argv[0], "Input file (-i/--input) is required");
|
||||
if (settings->renderer_name && strcmp(settings->renderer_name, "auto") == 0)
|
||||
settings->renderer_name = NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
* Destroy a Dav1dPlayRenderContext
|
||||
*/
|
||||
static void dp_rd_ctx_destroy(Dav1dPlayRenderContext *rd_ctx)
|
||||
{
|
||||
assert(rd_ctx != NULL);
|
||||
|
||||
renderer_info->destroy_renderer(rd_ctx->rd_priv);
|
||||
dp_fifo_destroy(rd_ctx->fifo);
|
||||
SDL_DestroyMutex(rd_ctx->lock);
|
||||
free(rd_ctx);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a Dav1dPlayRenderContext
|
||||
*
|
||||
* \note The Dav1dPlayRenderContext must be destroyed
|
||||
* again by using dp_rd_ctx_destroy.
|
||||
*/
|
||||
static Dav1dPlayRenderContext *dp_rd_ctx_create(int argc, char **argv)
|
||||
{
|
||||
Dav1dPlayRenderContext *rd_ctx;
|
||||
|
||||
// Alloc
|
||||
rd_ctx = calloc(1, sizeof(Dav1dPlayRenderContext));
|
||||
if (rd_ctx == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// Parse and validate arguments
|
||||
dav1d_default_settings(&rd_ctx->lib_settings);
|
||||
memset(&rd_ctx->settings, 0, sizeof(rd_ctx->settings));
|
||||
dp_rd_ctx_parse_args(rd_ctx, argc, argv);
|
||||
|
||||
// Init SDL2 library
|
||||
if (SDL_Init(SDL_INIT_VIDEO | SDL_INIT_TIMER) < 0) {
|
||||
fprintf(stderr, "SDL_Init failed: %s\n", SDL_GetError());
|
||||
goto fail;
|
||||
}
|
||||
|
||||
// Register a custom event to notify our SDL main thread
|
||||
// about new frames
|
||||
rd_ctx->event_types = SDL_RegisterEvents(3);
|
||||
if (rd_ctx->event_types == UINT32_MAX) {
|
||||
fprintf(stderr, "Failure to create custom SDL event types!\n");
|
||||
goto fail;
|
||||
}
|
||||
|
||||
rd_ctx->fifo = dp_fifo_create(5);
|
||||
if (rd_ctx->fifo == NULL) {
|
||||
fprintf(stderr, "Failed to create FIFO for output pictures!\n");
|
||||
goto fail;
|
||||
}
|
||||
|
||||
rd_ctx->lock = SDL_CreateMutex();
|
||||
if (rd_ctx->lock == NULL) {
|
||||
fprintf(stderr, "SDL_CreateMutex failed: %s\n", SDL_GetError());
|
||||
goto fail;
|
||||
}
|
||||
|
||||
// Select renderer
|
||||
renderer_info = dp_get_renderer(rd_ctx->settings.renderer_name);
|
||||
|
||||
if (renderer_info == NULL) {
|
||||
printf("No suitable renderer matching %s found.\n",
|
||||
(rd_ctx->settings.renderer_name) ? rd_ctx->settings.renderer_name : "auto");
|
||||
} else {
|
||||
printf("Using %s renderer\n", renderer_info->name);
|
||||
}
|
||||
|
||||
rd_ctx->rd_priv = (renderer_info) ? renderer_info->create_renderer(&rd_ctx->settings) : NULL;
|
||||
if (rd_ctx->rd_priv == NULL) {
|
||||
goto fail;
|
||||
}
|
||||
|
||||
return rd_ctx;
|
||||
|
||||
fail:
|
||||
if (rd_ctx->lock)
|
||||
SDL_DestroyMutex(rd_ctx->lock);
|
||||
if (rd_ctx->fifo)
|
||||
dp_fifo_destroy(rd_ctx->fifo);
|
||||
free(rd_ctx);
|
||||
SDL_Quit();
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
* Notify about new event
|
||||
*/
|
||||
static void dp_rd_ctx_post_event(Dav1dPlayRenderContext *rd_ctx, uint32_t type)
|
||||
{
|
||||
SDL_Event event;
|
||||
SDL_zero(event);
|
||||
event.type = type;
|
||||
SDL_PushEvent(&event);
|
||||
}
|
||||
|
||||
/**
|
||||
* Update the decoder context with a new dav1d picture
|
||||
*
|
||||
* Once the decoder decoded a new picture, this call can be used
|
||||
* to update the internal texture of the render context with the
|
||||
* new picture.
|
||||
*/
|
||||
static void dp_rd_ctx_update_with_dav1d_picture(Dav1dPlayRenderContext *rd_ctx,
|
||||
Dav1dPicture *dav1d_pic)
|
||||
{
|
||||
rd_ctx->current_ts = dav1d_pic->m.timestamp;
|
||||
renderer_info->update_frame(rd_ctx->rd_priv, dav1d_pic, &rd_ctx->settings);
|
||||
}
|
||||
|
||||
/**
|
||||
* Toggle pause state
|
||||
*/
|
||||
static void dp_rd_ctx_toggle_pause(Dav1dPlayRenderContext *rd_ctx)
|
||||
{
|
||||
SDL_LockMutex(rd_ctx->lock);
|
||||
rd_ctx->user_paused = !rd_ctx->user_paused;
|
||||
if (rd_ctx->seek)
|
||||
goto out;
|
||||
rd_ctx->paused = rd_ctx->user_paused;
|
||||
uint32_t now = SDL_GetTicks();
|
||||
if (rd_ctx->paused)
|
||||
rd_ctx->pause_start = now;
|
||||
else {
|
||||
rd_ctx->pause_time += now - rd_ctx->pause_start;
|
||||
rd_ctx->pause_start = 0;
|
||||
rd_ctx->last_ticks = now;
|
||||
}
|
||||
out:
|
||||
SDL_UnlockMutex(rd_ctx->lock);
|
||||
}
|
||||
|
||||
/**
|
||||
* Query pause state
|
||||
*/
|
||||
static int dp_rd_ctx_is_paused(Dav1dPlayRenderContext *rd_ctx)
|
||||
{
|
||||
int ret;
|
||||
SDL_LockMutex(rd_ctx->lock);
|
||||
ret = rd_ctx->paused;
|
||||
SDL_UnlockMutex(rd_ctx->lock);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* Request seeking, in seconds
|
||||
*/
|
||||
static void dp_rd_ctx_seek(Dav1dPlayRenderContext *rd_ctx, int sec)
|
||||
{
|
||||
SDL_LockMutex(rd_ctx->lock);
|
||||
rd_ctx->seek += sec;
|
||||
if (!rd_ctx->paused)
|
||||
rd_ctx->pause_start = SDL_GetTicks();
|
||||
rd_ctx->paused = 1;
|
||||
SDL_UnlockMutex(rd_ctx->lock);
|
||||
}
|
||||
|
||||
static int decode_frame(Dav1dPicture **p, Dav1dContext *c,
|
||||
Dav1dData *data, DemuxerContext *in_ctx);
|
||||
static inline void destroy_pic(void *a);
|
||||
|
||||
/**
|
||||
* Seek the stream, if requested
|
||||
*/
|
||||
static int dp_rd_ctx_handle_seek(Dav1dPlayRenderContext *rd_ctx,
|
||||
DemuxerContext *in_ctx,
|
||||
Dav1dContext *c, Dav1dData *data)
|
||||
{
|
||||
int res = 0;
|
||||
SDL_LockMutex(rd_ctx->lock);
|
||||
if (!rd_ctx->seek)
|
||||
goto out;
|
||||
int64_t seek = rd_ctx->seek * 1000000000ULL;
|
||||
uint64_t pts = TS_TO_PTS(rd_ctx->current_ts);
|
||||
pts = ((int64_t)pts > -seek) ? pts + seek : 0;
|
||||
int end = pts >= FRAME_OFFSET_TO_PTS(rd_ctx->total);
|
||||
if (end)
|
||||
pts = FRAME_OFFSET_TO_PTS(rd_ctx->total - 1);
|
||||
uint64_t target_pts = pts;
|
||||
dav1d_flush(c);
|
||||
uint64_t shift = FRAME_OFFSET_TO_PTS(5);
|
||||
while (1) {
|
||||
if (shift > pts)
|
||||
shift = pts;
|
||||
if ((res = input_seek(in_ctx, pts - shift)))
|
||||
goto out;
|
||||
Dav1dSequenceHeader seq;
|
||||
uint64_t cur_pts;
|
||||
do {
|
||||
if ((res = input_read(in_ctx, data)))
|
||||
break;
|
||||
cur_pts = TS_TO_PTS(data->m.timestamp);
|
||||
res = dav1d_parse_sequence_header(&seq, data->data, data->sz);
|
||||
} while (res && cur_pts < pts);
|
||||
if (!res && cur_pts <= pts)
|
||||
break;
|
||||
if (shift > pts)
|
||||
shift = pts;
|
||||
pts -= shift;
|
||||
}
|
||||
if (!res) {
|
||||
pts = TS_TO_PTS(data->m.timestamp);
|
||||
while (pts < target_pts) {
|
||||
Dav1dPicture *p;
|
||||
if ((res = decode_frame(&p, c, data, in_ctx)))
|
||||
break;
|
||||
if (p) {
|
||||
pts = TS_TO_PTS(p->m.timestamp);
|
||||
if (pts < target_pts)
|
||||
destroy_pic(p);
|
||||
else {
|
||||
dp_fifo_push(rd_ctx->fifo, p);
|
||||
uint32_t type = rd_ctx->event_types + DAV1D_EVENT_SEEK_FRAME;
|
||||
dp_rd_ctx_post_event(rd_ctx, type);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!res) {
|
||||
rd_ctx->last_ts = data->m.timestamp - rd_ctx->spf / rd_ctx->timebase;
|
||||
rd_ctx->current_ts = data->m.timestamp;
|
||||
}
|
||||
}
|
||||
out:
|
||||
rd_ctx->paused = rd_ctx->user_paused;
|
||||
if (!rd_ctx->paused && rd_ctx->seek) {
|
||||
uint32_t now = SDL_GetTicks();
|
||||
rd_ctx->pause_time += now - rd_ctx->pause_start;
|
||||
rd_ctx->pause_start = 0;
|
||||
rd_ctx->last_ticks = now;
|
||||
}
|
||||
rd_ctx->seek = 0;
|
||||
SDL_UnlockMutex(rd_ctx->lock);
|
||||
if (res)
|
||||
fprintf(stderr, "Error seeking, aborting\n");
|
||||
return res;
|
||||
}
|
||||
|
||||
/**
|
||||
* Terminate decoder thread (async)
|
||||
*/
|
||||
static void dp_rd_ctx_request_shutdown(Dav1dPlayRenderContext *rd_ctx)
|
||||
{
|
||||
SDL_LockMutex(rd_ctx->lock);
|
||||
rd_ctx->dec_should_terminate = 1;
|
||||
SDL_UnlockMutex(rd_ctx->lock);
|
||||
}
|
||||
|
||||
/**
|
||||
* Query state of decoder shutdown request
|
||||
*/
|
||||
static int dp_rd_ctx_should_terminate(Dav1dPlayRenderContext *rd_ctx)
|
||||
{
|
||||
int ret = 0;
|
||||
SDL_LockMutex(rd_ctx->lock);
|
||||
ret = rd_ctx->dec_should_terminate;
|
||||
SDL_UnlockMutex(rd_ctx->lock);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* Render the currently available texture
|
||||
*
|
||||
* Renders the currently available texture, if any.
|
||||
*/
|
||||
static void dp_rd_ctx_render(Dav1dPlayRenderContext *rd_ctx)
|
||||
{
|
||||
SDL_LockMutex(rd_ctx->lock);
|
||||
// Calculate time since last frame was received
|
||||
uint32_t ticks_now = SDL_GetTicks();
|
||||
uint32_t ticks_diff = (rd_ctx->last_ticks != 0) ? ticks_now - rd_ctx->last_ticks : 0;
|
||||
|
||||
// Calculate when to display the frame
|
||||
int64_t ts_diff = rd_ctx->current_ts - rd_ctx->last_ts;
|
||||
int32_t pts_diff = (ts_diff * rd_ctx->timebase) * 1000.0 + .5;
|
||||
int32_t wait_time = pts_diff - ticks_diff;
|
||||
|
||||
// In untimed mode, simply don't wait
|
||||
if (rd_ctx->settings.untimed)
|
||||
wait_time = 0;
|
||||
|
||||
// This way of timing the playback is not accurate, as there is no guarantee
|
||||
// that SDL_Delay will wait for exactly the requested amount of time so in a
|
||||
// accurate player this would need to be done in a better way.
|
||||
if (wait_time > 0) {
|
||||
SDL_Delay(wait_time);
|
||||
} else if (wait_time < -10 && !rd_ctx->paused) { // Do not warn for minor time drifts
|
||||
fprintf(stderr, "Frame displayed %f seconds too late\n", wait_time / 1000.0);
|
||||
}
|
||||
|
||||
renderer_info->render(rd_ctx->rd_priv, &rd_ctx->settings);
|
||||
|
||||
rd_ctx->last_ts = rd_ctx->current_ts;
|
||||
rd_ctx->last_ticks = SDL_GetTicks();
|
||||
|
||||
SDL_UnlockMutex(rd_ctx->lock);
|
||||
}
|
||||
|
||||
static int decode_frame(Dav1dPicture **p, Dav1dContext *c,
|
||||
Dav1dData *data, DemuxerContext *in_ctx)
|
||||
{
|
||||
int res;
|
||||
// Send data packets we got from the demuxer to dav1d
|
||||
if ((res = dav1d_send_data(c, data)) < 0) {
|
||||
// On EAGAIN, dav1d can not consume more data and
|
||||
// dav1d_get_picture needs to be called first, which
|
||||
// will happen below, so just keep going in that case
|
||||
// and do not error out.
|
||||
if (res != DAV1D_ERR(EAGAIN)) {
|
||||
dav1d_data_unref(data);
|
||||
goto err;
|
||||
}
|
||||
}
|
||||
*p = calloc(1, sizeof(**p));
|
||||
// Try to get a decoded frame
|
||||
if ((res = dav1d_get_picture(c, *p)) < 0) {
|
||||
// In all error cases, even EAGAIN, p needs to be freed as
|
||||
// it is never added to the queue and would leak.
|
||||
free(*p);
|
||||
*p = NULL;
|
||||
// On EAGAIN, it means dav1d has not enough data to decode
|
||||
// therefore this is not a decoding error but just means
|
||||
// we need to feed it more data, which happens in the next
|
||||
// run of the decoder loop.
|
||||
if (res != DAV1D_ERR(EAGAIN))
|
||||
goto err;
|
||||
}
|
||||
return data->sz == 0 ? input_read(in_ctx, data) : 0;
|
||||
err:
|
||||
fprintf(stderr, "Error decoding frame: %s\n",
|
||||
strerror(-res));
|
||||
return res;
|
||||
}
|
||||
|
||||
static inline void destroy_pic(void *a)
|
||||
{
|
||||
Dav1dPicture *p = (Dav1dPicture *)a;
|
||||
dav1d_picture_unref(p);
|
||||
free(p);
|
||||
}
|
||||
|
||||
/* Decoder thread "main" function */
|
||||
static int decoder_thread_main(void *cookie)
|
||||
{
|
||||
Dav1dPlayRenderContext *rd_ctx = cookie;
|
||||
|
||||
Dav1dPicture *p;
|
||||
Dav1dContext *c = NULL;
|
||||
Dav1dData data;
|
||||
DemuxerContext *in_ctx = NULL;
|
||||
int res = 0;
|
||||
unsigned total, timebase[2], fps[2];
|
||||
|
||||
Dav1dPlaySettings settings = rd_ctx->settings;
|
||||
|
||||
if ((res = input_open(&in_ctx, "ivf",
|
||||
settings.inputfile,
|
||||
fps, &total, timebase)) < 0)
|
||||
{
|
||||
fprintf(stderr, "Failed to open demuxer\n");
|
||||
res = 1;
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
rd_ctx->timebase = (double)timebase[1] / timebase[0];
|
||||
rd_ctx->spf = (double)fps[1] / fps[0];
|
||||
rd_ctx->total = total;
|
||||
|
||||
if ((res = dav1d_open(&c, &rd_ctx->lib_settings))) {
|
||||
fprintf(stderr, "Failed opening dav1d decoder\n");
|
||||
res = 1;
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
if ((res = input_read(in_ctx, &data)) < 0) {
|
||||
fprintf(stderr, "Failed demuxing input\n");
|
||||
res = 1;
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
// Decoder loop
|
||||
while (1) {
|
||||
if (dp_rd_ctx_should_terminate(rd_ctx) ||
|
||||
(res = dp_rd_ctx_handle_seek(rd_ctx, in_ctx, c, &data)) ||
|
||||
(res = decode_frame(&p, c, &data, in_ctx)))
|
||||
{
|
||||
break;
|
||||
}
|
||||
else if (p) {
|
||||
// Queue frame
|
||||
SDL_LockMutex(rd_ctx->lock);
|
||||
int seek = rd_ctx->seek;
|
||||
SDL_UnlockMutex(rd_ctx->lock);
|
||||
if (!seek) {
|
||||
dp_fifo_push(rd_ctx->fifo, p);
|
||||
uint32_t type = rd_ctx->event_types + DAV1D_EVENT_NEW_FRAME;
|
||||
dp_rd_ctx_post_event(rd_ctx, type);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Release remaining data
|
||||
if (data.sz > 0)
|
||||
dav1d_data_unref(&data);
|
||||
// Do not drain in case an error occured and caused us to leave the
|
||||
// decoding loop early.
|
||||
if (res < 0)
|
||||
goto cleanup;
|
||||
|
||||
// Drain decoder
|
||||
// When there is no more data to feed to the decoder, for example
|
||||
// because the file ended, we still need to request pictures, as
|
||||
// even though we do not have more data, there can be frames decoded
|
||||
// from data we sent before. So we need to call dav1d_get_picture until
|
||||
// we get an EAGAIN error.
|
||||
do {
|
||||
if (dp_rd_ctx_should_terminate(rd_ctx))
|
||||
break;
|
||||
p = calloc(1, sizeof(*p));
|
||||
res = dav1d_get_picture(c, p);
|
||||
if (res < 0) {
|
||||
free(p);
|
||||
if (res != DAV1D_ERR(EAGAIN)) {
|
||||
fprintf(stderr, "Error decoding frame: %s\n",
|
||||
strerror(-res));
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
// Queue frame
|
||||
dp_fifo_push(rd_ctx->fifo, p);
|
||||
uint32_t type = rd_ctx->event_types + DAV1D_EVENT_NEW_FRAME;
|
||||
dp_rd_ctx_post_event(rd_ctx, type);
|
||||
}
|
||||
} while (res != DAV1D_ERR(EAGAIN));
|
||||
|
||||
cleanup:
|
||||
dp_rd_ctx_post_event(rd_ctx, rd_ctx->event_types + DAV1D_EVENT_DEC_QUIT);
|
||||
|
||||
if (in_ctx)
|
||||
input_close(in_ctx);
|
||||
if (c)
|
||||
dav1d_close(&c);
|
||||
|
||||
return (res != DAV1D_ERR(EAGAIN) && res < 0);
|
||||
}
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
SDL_Thread *decoder_thread;
|
||||
|
||||
// Check for version mismatch between library and tool
|
||||
const char *version = dav1d_version();
|
||||
if (strcmp(version, DAV1D_VERSION)) {
|
||||
fprintf(stderr, "Version mismatch (library: %s, executable: %s)\n",
|
||||
version, DAV1D_VERSION);
|
||||
return 1;
|
||||
}
|
||||
|
||||
// Create render context
|
||||
Dav1dPlayRenderContext *rd_ctx = dp_rd_ctx_create(argc, argv);
|
||||
if (rd_ctx == NULL) {
|
||||
fprintf(stderr, "Failed creating render context\n");
|
||||
return 5;
|
||||
}
|
||||
|
||||
if (rd_ctx->settings.zerocopy) {
|
||||
if (renderer_info->alloc_pic) {
|
||||
rd_ctx->lib_settings.allocator = (Dav1dPicAllocator) {
|
||||
.cookie = rd_ctx->rd_priv,
|
||||
.alloc_picture_callback = renderer_info->alloc_pic,
|
||||
.release_picture_callback = renderer_info->release_pic,
|
||||
};
|
||||
} else {
|
||||
fprintf(stderr, "--zerocopy unsupported by selected renderer\n");
|
||||
}
|
||||
}
|
||||
|
||||
if (rd_ctx->settings.gpugrain) {
|
||||
if (renderer_info->supports_gpu_grain) {
|
||||
rd_ctx->lib_settings.apply_grain = 0;
|
||||
} else {
|
||||
fprintf(stderr, "--gpugrain unsupported by selected renderer\n");
|
||||
}
|
||||
}
|
||||
|
||||
// Start decoder thread
|
||||
decoder_thread = SDL_CreateThread(decoder_thread_main, "Decoder thread", rd_ctx);
|
||||
|
||||
// Main loop
|
||||
#define NUM_MAX_EVENTS 8
|
||||
SDL_Event events[NUM_MAX_EVENTS];
|
||||
int num_frame_events = 0;
|
||||
uint32_t start_time = 0, n_out = 0;
|
||||
while (1) {
|
||||
int num_events = 0;
|
||||
SDL_WaitEvent(NULL);
|
||||
while (num_events < NUM_MAX_EVENTS && SDL_PollEvent(&events[num_events++]))
|
||||
break;
|
||||
for (int i = 0; i < num_events; ++i) {
|
||||
SDL_Event *e = &events[i];
|
||||
if (e->type == SDL_QUIT) {
|
||||
dp_rd_ctx_request_shutdown(rd_ctx);
|
||||
dp_fifo_flush(rd_ctx->fifo, destroy_pic);
|
||||
goto out;
|
||||
} else if (e->type == SDL_WINDOWEVENT) {
|
||||
if (e->window.event == SDL_WINDOWEVENT_SIZE_CHANGED) {
|
||||
// TODO: Handle window resizes
|
||||
} else if(e->window.event == SDL_WINDOWEVENT_EXPOSED) {
|
||||
dp_rd_ctx_render(rd_ctx);
|
||||
}
|
||||
} else if (e->type == SDL_KEYDOWN) {
|
||||
SDL_KeyboardEvent *kbde = (SDL_KeyboardEvent *)e;
|
||||
if (kbde->keysym.sym == SDLK_SPACE) {
|
||||
dp_rd_ctx_toggle_pause(rd_ctx);
|
||||
} else if (kbde->keysym.sym == SDLK_ESCAPE) {
|
||||
dp_rd_ctx_request_shutdown(rd_ctx);
|
||||
dp_fifo_flush(rd_ctx->fifo, destroy_pic);
|
||||
goto out;
|
||||
} else if (kbde->keysym.sym == SDLK_LEFT ||
|
||||
kbde->keysym.sym == SDLK_RIGHT)
|
||||
{
|
||||
if (kbde->keysym.sym == SDLK_LEFT)
|
||||
dp_rd_ctx_seek(rd_ctx, -5);
|
||||
else if (kbde->keysym.sym == SDLK_RIGHT)
|
||||
dp_rd_ctx_seek(rd_ctx, +5);
|
||||
dp_fifo_flush(rd_ctx->fifo, destroy_pic);
|
||||
SDL_FlushEvent(rd_ctx->event_types + DAV1D_EVENT_NEW_FRAME);
|
||||
num_frame_events = 0;
|
||||
}
|
||||
} else if (e->type == rd_ctx->event_types + DAV1D_EVENT_NEW_FRAME) {
|
||||
num_frame_events++;
|
||||
// Store current ticks for stats calculation
|
||||
if (start_time == 0)
|
||||
start_time = SDL_GetTicks();
|
||||
} else if (e->type == rd_ctx->event_types + DAV1D_EVENT_SEEK_FRAME) {
|
||||
// Dequeue frame and update the render context with it
|
||||
Dav1dPicture *p = dp_fifo_shift(rd_ctx->fifo);
|
||||
// Do not update textures during termination
|
||||
if (!dp_rd_ctx_should_terminate(rd_ctx)) {
|
||||
dp_rd_ctx_update_with_dav1d_picture(rd_ctx, p);
|
||||
n_out++;
|
||||
}
|
||||
destroy_pic(p);
|
||||
} else if (e->type == rd_ctx->event_types + DAV1D_EVENT_DEC_QUIT) {
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
if (num_frame_events && !dp_rd_ctx_is_paused(rd_ctx)) {
|
||||
// Dequeue frame and update the render context with it
|
||||
Dav1dPicture *p = dp_fifo_shift(rd_ctx->fifo);
|
||||
// Do not update textures during termination
|
||||
if (!dp_rd_ctx_should_terminate(rd_ctx)) {
|
||||
dp_rd_ctx_update_with_dav1d_picture(rd_ctx, p);
|
||||
dp_rd_ctx_render(rd_ctx);
|
||||
n_out++;
|
||||
}
|
||||
destroy_pic(p);
|
||||
num_frame_events--;
|
||||
}
|
||||
}
|
||||
|
||||
out:;
|
||||
// Print stats
|
||||
uint32_t time_ms = SDL_GetTicks() - start_time - rd_ctx->pause_time;
|
||||
printf("Decoded %u frames in %d seconds, avg %.02f fps\n",
|
||||
n_out, time_ms / 1000, n_out/ (time_ms / 1000.0));
|
||||
|
||||
int decoder_ret = 0;
|
||||
SDL_WaitThread(decoder_thread, &decoder_ret);
|
||||
dp_rd_ctx_destroy(rd_ctx);
|
||||
SDL_Quit();
|
||||
return decoder_ret;
|
||||
}
|
||||
147
media/libdav1d/src/examples/dp_fifo.c
Normal file
147
media/libdav1d/src/examples/dp_fifo.c
Normal file
|
|
@ -0,0 +1,147 @@
|
|||
/*
|
||||
* Copyright © 2019, VideoLAN and dav1d authors
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include <SDL.h>
|
||||
#include <assert.h>
|
||||
|
||||
#include "dp_fifo.h"
|
||||
|
||||
// FIFO structure
|
||||
struct dp_fifo
|
||||
{
|
||||
SDL_mutex *lock;
|
||||
SDL_cond *cond_change;
|
||||
size_t capacity;
|
||||
size_t count;
|
||||
void **entries;
|
||||
int push_wait;
|
||||
int flush;
|
||||
};
|
||||
|
||||
|
||||
Dav1dPlayPtrFifo *dp_fifo_create(size_t capacity)
|
||||
{
|
||||
Dav1dPlayPtrFifo *fifo;
|
||||
|
||||
assert(capacity > 0);
|
||||
if (capacity <= 0)
|
||||
return NULL;
|
||||
|
||||
fifo = malloc(sizeof(*fifo));
|
||||
if (fifo == NULL)
|
||||
return NULL;
|
||||
|
||||
fifo->capacity = capacity;
|
||||
fifo->count = 0;
|
||||
fifo->push_wait = 0;
|
||||
fifo->flush = 0;
|
||||
|
||||
fifo->lock = SDL_CreateMutex();
|
||||
if (fifo->lock == NULL) {
|
||||
free(fifo);
|
||||
return NULL;
|
||||
}
|
||||
fifo->cond_change = SDL_CreateCond();
|
||||
if (fifo->cond_change == NULL) {
|
||||
SDL_DestroyMutex(fifo->lock);
|
||||
free(fifo);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
fifo->entries = calloc(capacity, sizeof(void*));
|
||||
if (fifo->entries == NULL) {
|
||||
dp_fifo_destroy(fifo);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return fifo;
|
||||
}
|
||||
|
||||
// Destroy FIFO
|
||||
void dp_fifo_destroy(Dav1dPlayPtrFifo *fifo)
|
||||
{
|
||||
assert(fifo->count == 0);
|
||||
SDL_DestroyMutex(fifo->lock);
|
||||
SDL_DestroyCond(fifo->cond_change);
|
||||
free(fifo->entries);
|
||||
free(fifo);
|
||||
}
|
||||
|
||||
// Push to FIFO
|
||||
void dp_fifo_push(Dav1dPlayPtrFifo *fifo, void *element)
|
||||
{
|
||||
SDL_LockMutex(fifo->lock);
|
||||
while (fifo->count == fifo->capacity) {
|
||||
fifo->push_wait = 1;
|
||||
SDL_CondWait(fifo->cond_change, fifo->lock);
|
||||
fifo->push_wait = 0;
|
||||
if (fifo->flush) {
|
||||
SDL_CondSignal(fifo->cond_change);
|
||||
SDL_UnlockMutex(fifo->lock);
|
||||
return;
|
||||
}
|
||||
}
|
||||
fifo->entries[fifo->count++] = element;
|
||||
if (fifo->count == 1)
|
||||
SDL_CondSignal(fifo->cond_change);
|
||||
SDL_UnlockMutex(fifo->lock);
|
||||
}
|
||||
|
||||
// Helper that shifts the FIFO array
|
||||
static void *dp_fifo_array_shift(void **arr, size_t len)
|
||||
{
|
||||
void *shifted_element = arr[0];
|
||||
for (size_t i = 1; i < len; ++i)
|
||||
arr[i-1] = arr[i];
|
||||
return shifted_element;
|
||||
}
|
||||
|
||||
// Get item from FIFO
|
||||
void *dp_fifo_shift(Dav1dPlayPtrFifo *fifo)
|
||||
{
|
||||
SDL_LockMutex(fifo->lock);
|
||||
while (fifo->count == 0)
|
||||
SDL_CondWait(fifo->cond_change, fifo->lock);
|
||||
void *res = dp_fifo_array_shift(fifo->entries, fifo->count--);
|
||||
if (fifo->count == fifo->capacity - 1)
|
||||
SDL_CondSignal(fifo->cond_change);
|
||||
SDL_UnlockMutex(fifo->lock);
|
||||
return res;
|
||||
}
|
||||
|
||||
void dp_fifo_flush(Dav1dPlayPtrFifo *fifo, void (*destroy_elem)(void *))
|
||||
{
|
||||
SDL_LockMutex(fifo->lock);
|
||||
fifo->flush = 1;
|
||||
if (fifo->push_wait) {
|
||||
SDL_CondSignal(fifo->cond_change);
|
||||
SDL_CondWait(fifo->cond_change, fifo->lock);
|
||||
}
|
||||
while (fifo->count)
|
||||
destroy_elem(fifo->entries[--fifo->count]);
|
||||
fifo->flush = 0;
|
||||
SDL_UnlockMutex(fifo->lock);
|
||||
}
|
||||
63
media/libdav1d/src/examples/dp_fifo.h
Normal file
63
media/libdav1d/src/examples/dp_fifo.h
Normal file
|
|
@ -0,0 +1,63 @@
|
|||
/*
|
||||
* Copyright © 2019, VideoLAN and dav1d authors
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Dav1dPlay FIFO helper
|
||||
*/
|
||||
|
||||
typedef struct dp_fifo Dav1dPlayPtrFifo;
|
||||
|
||||
/* Create a FIFO
|
||||
*
|
||||
* Creates a FIFO with the given capacity.
|
||||
* If the capacity is reached, new inserts into the FIFO
|
||||
* will block until enough space is available again.
|
||||
*/
|
||||
Dav1dPlayPtrFifo *dp_fifo_create(size_t capacity);
|
||||
|
||||
/* Destroy a FIFO
|
||||
*
|
||||
* The FIFO must be empty before it is destroyed!
|
||||
*/
|
||||
void dp_fifo_destroy(Dav1dPlayPtrFifo *fifo);
|
||||
|
||||
/* Shift FIFO
|
||||
*
|
||||
* Return the first item from the FIFO, thereby removing it from
|
||||
* the FIFO and making room for new entries.
|
||||
*/
|
||||
void *dp_fifo_shift(Dav1dPlayPtrFifo *fifo);
|
||||
|
||||
/* Push to FIFO
|
||||
*
|
||||
* Add an item to the end of the FIFO.
|
||||
* If the FIFO is full, this call will block until there is again enough
|
||||
* space in the FIFO, so calling this from the "consumer" thread if no
|
||||
* other thread will call dp_fifo_shift will lead to a deadlock.
|
||||
*/
|
||||
void dp_fifo_push(Dav1dPlayPtrFifo *fifo, void *element);
|
||||
|
||||
void dp_fifo_flush(Dav1dPlayPtrFifo *fifo, void (*destroy_elem)(void *));
|
||||
149
media/libdav1d/src/examples/dp_renderer.h
Normal file
149
media/libdav1d/src/examples/dp_renderer.h
Normal file
|
|
@ -0,0 +1,149 @@
|
|||
/*
|
||||
* Copyright © 2020, VideoLAN and dav1d authors
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include <inttypes.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "dav1d/dav1d.h"
|
||||
|
||||
#include <SDL.h>
|
||||
#if HAVE_PLACEBO
|
||||
# include <libplacebo/config.h>
|
||||
#endif
|
||||
|
||||
// Check libplacebo Vulkan rendering
|
||||
#if HAVE_VULKAN && defined(SDL_VIDEO_VULKAN)
|
||||
# if defined(PL_HAVE_VULKAN) && PL_HAVE_VULKAN
|
||||
# define HAVE_RENDERER_PLACEBO 1
|
||||
# define HAVE_PLACEBO_VULKAN 1
|
||||
# endif
|
||||
#endif
|
||||
|
||||
// Check libplacebo OpenGL rendering
|
||||
#if defined(PL_HAVE_OPENGL) && PL_HAVE_OPENGL
|
||||
# define HAVE_RENDERER_PLACEBO 1
|
||||
# define HAVE_PLACEBO_OPENGL 1
|
||||
#endif
|
||||
|
||||
#ifndef HAVE_RENDERER_PLACEBO
|
||||
#define HAVE_RENDERER_PLACEBO 0
|
||||
#endif
|
||||
#ifndef HAVE_PLACEBO_VULKAN
|
||||
#define HAVE_PLACEBO_VULKAN 0
|
||||
#endif
|
||||
#ifndef HAVE_PLACEBO_OPENGL
|
||||
#define HAVE_PLACEBO_OPENGL 0
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Settings structure
|
||||
* Hold all settings available for the player,
|
||||
* this is usually filled by parsing arguments
|
||||
* from the console.
|
||||
*/
|
||||
typedef struct {
|
||||
const char *inputfile;
|
||||
const char *renderer_name;
|
||||
int highquality;
|
||||
int untimed;
|
||||
int zerocopy;
|
||||
int gpugrain;
|
||||
int fullscreen;
|
||||
} Dav1dPlaySettings;
|
||||
|
||||
#define WINDOW_WIDTH 910
|
||||
#define WINDOW_HEIGHT 512
|
||||
|
||||
enum {
|
||||
DAV1D_EVENT_NEW_FRAME,
|
||||
DAV1D_EVENT_SEEK_FRAME,
|
||||
DAV1D_EVENT_DEC_QUIT
|
||||
};
|
||||
|
||||
/**
|
||||
* Renderer info
|
||||
*/
|
||||
typedef struct rdr_info
|
||||
{
|
||||
// Renderer name
|
||||
const char *name;
|
||||
// Cookie passed to the renderer implementation callbacks
|
||||
void *cookie;
|
||||
// Callback to create the renderer
|
||||
void* (*create_renderer)(const Dav1dPlaySettings *settings);
|
||||
// Callback to destroy the renderer
|
||||
void (*destroy_renderer)(void *cookie);
|
||||
// Callback to the render function that renders a prevously sent frame
|
||||
void (*render)(void *cookie, const Dav1dPlaySettings *settings);
|
||||
// Callback to the send frame function, _may_ also unref dav1d_pic!
|
||||
int (*update_frame)(void *cookie, Dav1dPicture *dav1d_pic,
|
||||
const Dav1dPlaySettings *settings);
|
||||
// Callback for alloc/release pictures (optional)
|
||||
int (*alloc_pic)(Dav1dPicture *pic, void *cookie);
|
||||
void (*release_pic)(Dav1dPicture *pic, void *cookie);
|
||||
// Whether or not this renderer can apply on-GPU film grain synthesis
|
||||
int supports_gpu_grain;
|
||||
} Dav1dPlayRenderInfo;
|
||||
|
||||
extern const Dav1dPlayRenderInfo rdr_placebo_vk;
|
||||
extern const Dav1dPlayRenderInfo rdr_placebo_gl;
|
||||
extern const Dav1dPlayRenderInfo rdr_sdl;
|
||||
|
||||
// Available renderes ordered by priority
|
||||
static const Dav1dPlayRenderInfo* const dp_renderers[] = {
|
||||
&rdr_placebo_vk,
|
||||
&rdr_placebo_gl,
|
||||
&rdr_sdl,
|
||||
};
|
||||
|
||||
static inline const Dav1dPlayRenderInfo *dp_get_renderer(const char *name)
|
||||
{
|
||||
for (size_t i = 0; i < (sizeof(dp_renderers)/sizeof(*dp_renderers)); ++i)
|
||||
{
|
||||
if (dp_renderers[i]->name == NULL)
|
||||
continue;
|
||||
|
||||
if (name == NULL || strcmp(name, dp_renderers[i]->name) == 0) {
|
||||
return dp_renderers[i];
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static inline SDL_Window *dp_create_sdl_window(int window_flags)
|
||||
{
|
||||
SDL_Window *win;
|
||||
window_flags |= SDL_WINDOW_SHOWN | SDL_WINDOW_ALLOW_HIGHDPI;
|
||||
|
||||
win = SDL_CreateWindow("Dav1dPlay", SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED,
|
||||
WINDOW_WIDTH, WINDOW_HEIGHT, window_flags);
|
||||
if (!win)
|
||||
return NULL;
|
||||
|
||||
SDL_SetWindowResizable(win, SDL_TRUE);
|
||||
|
||||
return win;
|
||||
}
|
||||
437
media/libdav1d/src/examples/dp_renderer_placebo.c
Normal file
437
media/libdav1d/src/examples/dp_renderer_placebo.c
Normal file
|
|
@ -0,0 +1,437 @@
|
|||
/*
|
||||
* Copyright © 2020, VideoLAN and dav1d authors
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include "dp_renderer.h"
|
||||
|
||||
#if HAVE_RENDERER_PLACEBO
|
||||
#include <assert.h>
|
||||
|
||||
#include <libplacebo/renderer.h>
|
||||
#include <libplacebo/utils/dav1d.h>
|
||||
|
||||
#if HAVE_PLACEBO_VULKAN
|
||||
# include <libplacebo/vulkan.h>
|
||||
# include <SDL_vulkan.h>
|
||||
#endif
|
||||
#if HAVE_PLACEBO_OPENGL
|
||||
# include <libplacebo/opengl.h>
|
||||
# include <SDL_opengl.h>
|
||||
#endif
|
||||
|
||||
|
||||
/**
|
||||
* Renderer context for libplacebo
|
||||
*/
|
||||
typedef struct renderer_priv_ctx
|
||||
{
|
||||
// SDL window
|
||||
SDL_Window *win;
|
||||
// Placebo log
|
||||
pl_log log;
|
||||
// Placebo renderer
|
||||
pl_renderer renderer;
|
||||
#if HAVE_PLACEBO_VULKAN
|
||||
// Placebo Vulkan handle
|
||||
pl_vulkan vk;
|
||||
// Placebo Vulkan instance
|
||||
pl_vk_inst vk_inst;
|
||||
// Vulkan surface
|
||||
VkSurfaceKHR surf;
|
||||
#endif
|
||||
#if HAVE_PLACEBO_OPENGL
|
||||
// Placebo OpenGL handle
|
||||
pl_opengl gl;
|
||||
// SDL OpenGL context
|
||||
SDL_GLContext gl_context;
|
||||
#endif
|
||||
// Placebo GPU
|
||||
pl_gpu gpu;
|
||||
// Placebo swapchain
|
||||
pl_swapchain swapchain;
|
||||
// Lock protecting access to the texture
|
||||
SDL_mutex *lock;
|
||||
// Image to render, and planes backing them
|
||||
struct pl_frame image;
|
||||
pl_tex plane_tex[3];
|
||||
} Dav1dPlayRendererPrivateContext;
|
||||
|
||||
static Dav1dPlayRendererPrivateContext*
|
||||
placebo_renderer_create_common(const Dav1dPlaySettings *settings, int window_flags)
|
||||
{
|
||||
if (settings->fullscreen)
|
||||
window_flags |= SDL_WINDOW_FULLSCREEN_DESKTOP;
|
||||
|
||||
// Create Window
|
||||
SDL_Window *sdlwin = dp_create_sdl_window(window_flags | SDL_WINDOW_RESIZABLE);
|
||||
if (sdlwin == NULL) {
|
||||
fprintf(stderr, "Creating SDL window failed: %s\n", SDL_GetError());
|
||||
return NULL;
|
||||
}
|
||||
|
||||
SDL_ShowCursor(0);
|
||||
|
||||
// Alloc
|
||||
Dav1dPlayRendererPrivateContext *const rd_priv_ctx =
|
||||
calloc(1, sizeof(Dav1dPlayRendererPrivateContext));
|
||||
if (rd_priv_ctx == NULL) {
|
||||
fprintf(stderr, "Out of memory!\n");
|
||||
return NULL;
|
||||
}
|
||||
rd_priv_ctx->win = sdlwin;
|
||||
|
||||
// Init libplacebo
|
||||
rd_priv_ctx->log = pl_log_create(PL_API_VER, pl_log_params(
|
||||
.log_cb = pl_log_color,
|
||||
#ifndef NDEBUG
|
||||
.log_level = PL_LOG_DEBUG,
|
||||
#else
|
||||
.log_level = PL_LOG_WARN,
|
||||
#endif
|
||||
));
|
||||
if (rd_priv_ctx->log == NULL) {
|
||||
fprintf(stderr, "pl_log_create failed!\n");
|
||||
free(rd_priv_ctx);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// Create Mutex
|
||||
rd_priv_ctx->lock = SDL_CreateMutex();
|
||||
if (rd_priv_ctx->lock == NULL) {
|
||||
fprintf(stderr, "SDL_CreateMutex failed: %s\n", SDL_GetError());
|
||||
pl_log_destroy(&rd_priv_ctx->log);
|
||||
free(rd_priv_ctx);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return rd_priv_ctx;
|
||||
}
|
||||
|
||||
#if HAVE_PLACEBO_OPENGL
|
||||
static void *placebo_renderer_create_gl(const Dav1dPlaySettings *settings)
|
||||
{
|
||||
SDL_Window *sdlwin = NULL;
|
||||
SDL_GL_SetAttribute(SDL_GL_CONTEXT_FLAGS, SDL_GL_CONTEXT_DEBUG_FLAG);
|
||||
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 3);
|
||||
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 0);
|
||||
SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_CORE);
|
||||
|
||||
// Common init
|
||||
Dav1dPlayRendererPrivateContext *rd_priv_ctx =
|
||||
placebo_renderer_create_common(settings, SDL_WINDOW_OPENGL);
|
||||
|
||||
if (rd_priv_ctx == NULL)
|
||||
return NULL;
|
||||
sdlwin = rd_priv_ctx->win;
|
||||
|
||||
rd_priv_ctx->gl_context = SDL_GL_CreateContext(sdlwin);
|
||||
if (!rd_priv_ctx->gl_context) {
|
||||
fprintf(stderr, "Failed creating opengl context: %s\n", SDL_GetError());
|
||||
exit(2);
|
||||
}
|
||||
SDL_GL_MakeCurrent(sdlwin, rd_priv_ctx->gl_context);
|
||||
|
||||
rd_priv_ctx->gl = pl_opengl_create(rd_priv_ctx->log, pl_opengl_params(
|
||||
.allow_software = true,
|
||||
#ifndef NDEBUG
|
||||
.debug = true,
|
||||
#endif
|
||||
));
|
||||
if (!rd_priv_ctx->gl) {
|
||||
fprintf(stderr, "Failed creating opengl device!\n");
|
||||
exit(2);
|
||||
}
|
||||
|
||||
rd_priv_ctx->swapchain = pl_opengl_create_swapchain(rd_priv_ctx->gl,
|
||||
pl_opengl_swapchain_params(
|
||||
.swap_buffers = (void (*)(void *)) SDL_GL_SwapWindow,
|
||||
.priv = sdlwin,
|
||||
));
|
||||
|
||||
if (!rd_priv_ctx->swapchain) {
|
||||
fprintf(stderr, "Failed creating opengl swapchain!\n");
|
||||
exit(2);
|
||||
}
|
||||
|
||||
int w = WINDOW_WIDTH, h = WINDOW_HEIGHT;
|
||||
SDL_GL_GetDrawableSize(sdlwin, &w, &h);
|
||||
|
||||
if (!pl_swapchain_resize(rd_priv_ctx->swapchain, &w, &h)) {
|
||||
fprintf(stderr, "Failed resizing vulkan swapchain!\n");
|
||||
exit(2);
|
||||
}
|
||||
|
||||
rd_priv_ctx->gpu = rd_priv_ctx->gl->gpu;
|
||||
|
||||
if (w != WINDOW_WIDTH || h != WINDOW_HEIGHT)
|
||||
printf("Note: window dimensions differ (got %dx%d)\n", w, h);
|
||||
|
||||
return rd_priv_ctx;
|
||||
}
|
||||
#endif
|
||||
|
||||
#if HAVE_PLACEBO_VULKAN
|
||||
static void *placebo_renderer_create_vk(const Dav1dPlaySettings *settings)
|
||||
{
|
||||
SDL_Window *sdlwin = NULL;
|
||||
|
||||
// Common init
|
||||
Dav1dPlayRendererPrivateContext *rd_priv_ctx =
|
||||
placebo_renderer_create_common(settings, SDL_WINDOW_VULKAN);
|
||||
|
||||
if (rd_priv_ctx == NULL)
|
||||
return NULL;
|
||||
sdlwin = rd_priv_ctx->win;
|
||||
|
||||
// Init Vulkan
|
||||
unsigned num = 0;
|
||||
if (!SDL_Vulkan_GetInstanceExtensions(sdlwin, &num, NULL)) {
|
||||
fprintf(stderr, "Failed enumerating Vulkan extensions: %s\n", SDL_GetError());
|
||||
exit(1);
|
||||
}
|
||||
|
||||
const char **extensions = malloc(num * sizeof(const char *));
|
||||
assert(extensions);
|
||||
|
||||
SDL_bool ok = SDL_Vulkan_GetInstanceExtensions(sdlwin, &num, extensions);
|
||||
if (!ok) {
|
||||
fprintf(stderr, "Failed getting Vk instance extensions\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
if (num > 0) {
|
||||
printf("Requesting %d additional Vulkan extensions:\n", num);
|
||||
for (unsigned i = 0; i < num; i++)
|
||||
printf(" %s\n", extensions[i]);
|
||||
}
|
||||
|
||||
rd_priv_ctx->vk_inst = pl_vk_inst_create(rd_priv_ctx->log, pl_vk_inst_params(
|
||||
.extensions = extensions,
|
||||
.num_extensions = num,
|
||||
));
|
||||
if (!rd_priv_ctx->vk_inst) {
|
||||
fprintf(stderr, "Failed creating Vulkan instance!\n");
|
||||
exit(1);
|
||||
}
|
||||
free(extensions);
|
||||
|
||||
if (!SDL_Vulkan_CreateSurface(sdlwin, rd_priv_ctx->vk_inst->instance, &rd_priv_ctx->surf)) {
|
||||
fprintf(stderr, "Failed creating vulkan surface: %s\n", SDL_GetError());
|
||||
exit(1);
|
||||
}
|
||||
|
||||
rd_priv_ctx->vk = pl_vulkan_create(rd_priv_ctx->log, pl_vulkan_params(
|
||||
.instance = rd_priv_ctx->vk_inst->instance,
|
||||
.surface = rd_priv_ctx->surf,
|
||||
.allow_software = true,
|
||||
));
|
||||
if (!rd_priv_ctx->vk) {
|
||||
fprintf(stderr, "Failed creating vulkan device!\n");
|
||||
exit(2);
|
||||
}
|
||||
|
||||
// Create swapchain
|
||||
rd_priv_ctx->swapchain = pl_vulkan_create_swapchain(rd_priv_ctx->vk,
|
||||
pl_vulkan_swapchain_params(
|
||||
.surface = rd_priv_ctx->surf,
|
||||
.present_mode = VK_PRESENT_MODE_IMMEDIATE_KHR,
|
||||
));
|
||||
|
||||
if (!rd_priv_ctx->swapchain) {
|
||||
fprintf(stderr, "Failed creating vulkan swapchain!\n");
|
||||
exit(2);
|
||||
}
|
||||
|
||||
int w = WINDOW_WIDTH, h = WINDOW_HEIGHT;
|
||||
if (!pl_swapchain_resize(rd_priv_ctx->swapchain, &w, &h)) {
|
||||
fprintf(stderr, "Failed resizing vulkan swapchain!\n");
|
||||
exit(2);
|
||||
}
|
||||
|
||||
rd_priv_ctx->gpu = rd_priv_ctx->vk->gpu;
|
||||
|
||||
if (w != WINDOW_WIDTH || h != WINDOW_HEIGHT)
|
||||
printf("Note: window dimensions differ (got %dx%d)\n", w, h);
|
||||
|
||||
return rd_priv_ctx;
|
||||
}
|
||||
#endif
|
||||
|
||||
static void placebo_renderer_destroy(void *cookie)
|
||||
{
|
||||
Dav1dPlayRendererPrivateContext *rd_priv_ctx = cookie;
|
||||
assert(rd_priv_ctx != NULL);
|
||||
|
||||
pl_renderer_destroy(&(rd_priv_ctx->renderer));
|
||||
pl_swapchain_destroy(&(rd_priv_ctx->swapchain));
|
||||
for (int i = 0; i < 3; i++)
|
||||
pl_tex_destroy(rd_priv_ctx->gpu, &(rd_priv_ctx->plane_tex[i]));
|
||||
|
||||
#if HAVE_PLACEBO_VULKAN
|
||||
if (rd_priv_ctx->vk) {
|
||||
pl_vulkan_destroy(&(rd_priv_ctx->vk));
|
||||
vkDestroySurfaceKHR(rd_priv_ctx->vk_inst->instance, rd_priv_ctx->surf, NULL);
|
||||
pl_vk_inst_destroy(&(rd_priv_ctx->vk_inst));
|
||||
}
|
||||
#endif
|
||||
#if HAVE_PLACEBO_OPENGL
|
||||
if (rd_priv_ctx->gl)
|
||||
pl_opengl_destroy(&(rd_priv_ctx->gl));
|
||||
if (rd_priv_ctx->gl_context)
|
||||
SDL_GL_DeleteContext(rd_priv_ctx->gl_context);
|
||||
#endif
|
||||
|
||||
SDL_DestroyWindow(rd_priv_ctx->win);
|
||||
|
||||
pl_log_destroy(&rd_priv_ctx->log);
|
||||
}
|
||||
|
||||
static void placebo_render(void *cookie, const Dav1dPlaySettings *settings)
|
||||
{
|
||||
Dav1dPlayRendererPrivateContext *rd_priv_ctx = cookie;
|
||||
assert(rd_priv_ctx != NULL);
|
||||
|
||||
SDL_LockMutex(rd_priv_ctx->lock);
|
||||
if (!rd_priv_ctx->image.num_planes) {
|
||||
SDL_UnlockMutex(rd_priv_ctx->lock);
|
||||
return;
|
||||
}
|
||||
|
||||
// Prepare rendering
|
||||
if (rd_priv_ctx->renderer == NULL) {
|
||||
rd_priv_ctx->renderer = pl_renderer_create(rd_priv_ctx->log, rd_priv_ctx->gpu);
|
||||
}
|
||||
|
||||
struct pl_swapchain_frame frame;
|
||||
bool ok = pl_swapchain_start_frame(rd_priv_ctx->swapchain, &frame);
|
||||
if (!ok) {
|
||||
SDL_UnlockMutex(rd_priv_ctx->lock);
|
||||
return;
|
||||
}
|
||||
|
||||
struct pl_frame target;
|
||||
pl_frame_from_swapchain(&target, &frame);
|
||||
pl_rect2df_aspect_copy(&target.crop, &rd_priv_ctx->image.crop, 0.0);
|
||||
if (pl_frame_is_cropped(&target))
|
||||
pl_tex_clear(rd_priv_ctx->gpu, frame.fbo, (float[4]){ 0.0 });
|
||||
|
||||
if (!pl_render_image(rd_priv_ctx->renderer, &rd_priv_ctx->image, &target,
|
||||
settings->highquality ? &pl_render_default_params
|
||||
: &pl_render_fast_params))
|
||||
{
|
||||
fprintf(stderr, "Failed rendering frame!\n");
|
||||
pl_tex_clear(rd_priv_ctx->gpu, frame.fbo, (float[4]){ 1.0 });
|
||||
}
|
||||
|
||||
ok = pl_swapchain_submit_frame(rd_priv_ctx->swapchain);
|
||||
if (!ok) {
|
||||
fprintf(stderr, "Failed submitting frame!\n");
|
||||
SDL_UnlockMutex(rd_priv_ctx->lock);
|
||||
return;
|
||||
}
|
||||
|
||||
pl_swapchain_swap_buffers(rd_priv_ctx->swapchain);
|
||||
SDL_UnlockMutex(rd_priv_ctx->lock);
|
||||
}
|
||||
|
||||
static int placebo_upload_image(void *cookie, Dav1dPicture *dav1d_pic,
|
||||
const Dav1dPlaySettings *settings)
|
||||
{
|
||||
Dav1dPlayRendererPrivateContext *p = cookie;
|
||||
assert(p != NULL);
|
||||
int ret = 0;
|
||||
|
||||
if (!dav1d_pic)
|
||||
return ret;
|
||||
|
||||
SDL_LockMutex(p->lock);
|
||||
if (!pl_upload_dav1dpicture(p->gpu, &p->image, p->plane_tex, pl_dav1d_upload_params(
|
||||
.picture = dav1d_pic,
|
||||
.film_grain = settings->gpugrain,
|
||||
.gpu_allocated = settings->zerocopy,
|
||||
.asynchronous = true,
|
||||
)))
|
||||
{
|
||||
fprintf(stderr, "Failed uploading planes!\n");
|
||||
p->image = (struct pl_frame) {0};
|
||||
ret = -1;
|
||||
}
|
||||
SDL_UnlockMutex(p->lock);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int placebo_alloc_pic(Dav1dPicture *const pic, void *cookie)
|
||||
{
|
||||
Dav1dPlayRendererPrivateContext *rd_priv_ctx = cookie;
|
||||
assert(rd_priv_ctx != NULL);
|
||||
|
||||
SDL_LockMutex(rd_priv_ctx->lock);
|
||||
int ret = pl_allocate_dav1dpicture(pic, (void *) rd_priv_ctx->gpu);
|
||||
SDL_UnlockMutex(rd_priv_ctx->lock);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void placebo_release_pic(Dav1dPicture *pic, void *cookie)
|
||||
{
|
||||
Dav1dPlayRendererPrivateContext *rd_priv_ctx = cookie;
|
||||
assert(rd_priv_ctx != NULL);
|
||||
|
||||
SDL_LockMutex(rd_priv_ctx->lock);
|
||||
pl_release_dav1dpicture(pic, (void *) rd_priv_ctx->gpu);
|
||||
SDL_UnlockMutex(rd_priv_ctx->lock);
|
||||
}
|
||||
|
||||
#if HAVE_PLACEBO_VULKAN
|
||||
const Dav1dPlayRenderInfo rdr_placebo_vk = {
|
||||
.name = "placebo-vk",
|
||||
.create_renderer = placebo_renderer_create_vk,
|
||||
.destroy_renderer = placebo_renderer_destroy,
|
||||
.render = placebo_render,
|
||||
.update_frame = placebo_upload_image,
|
||||
.alloc_pic = placebo_alloc_pic,
|
||||
.release_pic = placebo_release_pic,
|
||||
.supports_gpu_grain = 1,
|
||||
};
|
||||
#else
|
||||
const Dav1dPlayRenderInfo rdr_placebo_vk = { NULL };
|
||||
#endif
|
||||
|
||||
#if HAVE_PLACEBO_OPENGL
|
||||
const Dav1dPlayRenderInfo rdr_placebo_gl = {
|
||||
.name = "placebo-gl",
|
||||
.create_renderer = placebo_renderer_create_gl,
|
||||
.destroy_renderer = placebo_renderer_destroy,
|
||||
.render = placebo_render,
|
||||
.update_frame = placebo_upload_image,
|
||||
.supports_gpu_grain = 1,
|
||||
};
|
||||
#else
|
||||
const Dav1dPlayRenderInfo rdr_placebo_gl = { NULL };
|
||||
#endif
|
||||
|
||||
#else
|
||||
const Dav1dPlayRenderInfo rdr_placebo_vk = { NULL };
|
||||
const Dav1dPlayRenderInfo rdr_placebo_gl = { NULL };
|
||||
#endif
|
||||
175
media/libdav1d/src/examples/dp_renderer_sdl.c
Normal file
175
media/libdav1d/src/examples/dp_renderer_sdl.c
Normal file
|
|
@ -0,0 +1,175 @@
|
|||
/*
|
||||
* Copyright © 2020, VideoLAN and dav1d authors
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include "dp_renderer.h"
|
||||
|
||||
#include <assert.h>
|
||||
|
||||
/**
|
||||
* Renderer context for SDL
|
||||
*/
|
||||
typedef struct renderer_priv_ctx
|
||||
{
|
||||
// SDL window
|
||||
SDL_Window *win;
|
||||
// SDL renderer
|
||||
SDL_Renderer *renderer;
|
||||
// Lock protecting access to the texture
|
||||
SDL_mutex *lock;
|
||||
// Texture to render
|
||||
SDL_Texture *tex;
|
||||
} Dav1dPlayRendererPrivateContext;
|
||||
|
||||
static void *sdl_renderer_create(const Dav1dPlaySettings *settings)
|
||||
{
|
||||
int window_flags = 0;
|
||||
if (settings->fullscreen)
|
||||
window_flags |= SDL_WINDOW_FULLSCREEN_DESKTOP;
|
||||
|
||||
SDL_Window *win = dp_create_sdl_window(window_flags);
|
||||
if (win == NULL) {
|
||||
fprintf(stderr, "Creating SDL window failed: %s\n", SDL_GetError());
|
||||
return NULL;
|
||||
}
|
||||
SDL_ShowCursor(0);
|
||||
|
||||
// Alloc
|
||||
Dav1dPlayRendererPrivateContext *rd_priv_ctx = malloc(sizeof(Dav1dPlayRendererPrivateContext));
|
||||
if (rd_priv_ctx == NULL) {
|
||||
fprintf(stderr, "Out of memory!\n");
|
||||
return NULL;
|
||||
}
|
||||
rd_priv_ctx->win = win;
|
||||
|
||||
// Create renderer
|
||||
rd_priv_ctx->renderer = SDL_CreateRenderer(win, -1, SDL_RENDERER_ACCELERATED);
|
||||
// Set scale quality
|
||||
SDL_SetHint(SDL_HINT_RENDER_SCALE_QUALITY, "linear");
|
||||
|
||||
// Create Mutex
|
||||
rd_priv_ctx->lock = SDL_CreateMutex();
|
||||
if (rd_priv_ctx->lock == NULL) {
|
||||
fprintf(stderr, "SDL_CreateMutex failed: %s\n", SDL_GetError());
|
||||
free(rd_priv_ctx);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
rd_priv_ctx->tex = NULL;
|
||||
|
||||
return rd_priv_ctx;
|
||||
}
|
||||
|
||||
static void sdl_renderer_destroy(void *cookie)
|
||||
{
|
||||
Dav1dPlayRendererPrivateContext *rd_priv_ctx = cookie;
|
||||
assert(rd_priv_ctx != NULL);
|
||||
|
||||
SDL_DestroyTexture(rd_priv_ctx->tex);
|
||||
SDL_DestroyRenderer(rd_priv_ctx->renderer);
|
||||
SDL_DestroyWindow(rd_priv_ctx->win);
|
||||
SDL_DestroyMutex(rd_priv_ctx->lock);
|
||||
free(rd_priv_ctx);
|
||||
}
|
||||
|
||||
static void sdl_render(void *cookie, const Dav1dPlaySettings *settings)
|
||||
{
|
||||
Dav1dPlayRendererPrivateContext *rd_priv_ctx = cookie;
|
||||
assert(rd_priv_ctx != NULL);
|
||||
|
||||
SDL_LockMutex(rd_priv_ctx->lock);
|
||||
|
||||
if (rd_priv_ctx->tex == NULL) {
|
||||
SDL_UnlockMutex(rd_priv_ctx->lock);
|
||||
return;
|
||||
}
|
||||
|
||||
// Display the frame
|
||||
SDL_RenderClear(rd_priv_ctx->renderer);
|
||||
SDL_RenderCopy(rd_priv_ctx->renderer, rd_priv_ctx->tex, NULL, NULL);
|
||||
SDL_RenderPresent(rd_priv_ctx->renderer);
|
||||
|
||||
SDL_UnlockMutex(rd_priv_ctx->lock);
|
||||
}
|
||||
|
||||
static int sdl_update_texture(void *cookie, Dav1dPicture *dav1d_pic,
|
||||
const Dav1dPlaySettings *settings)
|
||||
{
|
||||
Dav1dPlayRendererPrivateContext *rd_priv_ctx = cookie;
|
||||
assert(rd_priv_ctx != NULL);
|
||||
|
||||
SDL_LockMutex(rd_priv_ctx->lock);
|
||||
|
||||
if (dav1d_pic == NULL) {
|
||||
rd_priv_ctx->tex = NULL;
|
||||
SDL_UnlockMutex(rd_priv_ctx->lock);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int width = dav1d_pic->p.w;
|
||||
int height = dav1d_pic->p.h;
|
||||
int tex_w = width;
|
||||
int tex_h = height;
|
||||
|
||||
enum Dav1dPixelLayout dav1d_layout = dav1d_pic->p.layout;
|
||||
|
||||
if (DAV1D_PIXEL_LAYOUT_I420 != dav1d_layout || dav1d_pic->p.bpc != 8) {
|
||||
fprintf(stderr, "Unsupported pixel format, only 8bit 420 supported so far.\n");
|
||||
exit(50);
|
||||
}
|
||||
|
||||
SDL_Texture *texture = rd_priv_ctx->tex;
|
||||
if (texture != NULL) {
|
||||
SDL_QueryTexture(texture, NULL, NULL, &tex_w, &tex_h);
|
||||
if (tex_w != width || tex_h != height) {
|
||||
SDL_DestroyTexture(texture);
|
||||
texture = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
if (texture == NULL) {
|
||||
texture = SDL_CreateTexture(rd_priv_ctx->renderer, SDL_PIXELFORMAT_IYUV,
|
||||
SDL_TEXTUREACCESS_STREAMING, width, height);
|
||||
SDL_RenderSetLogicalSize(rd_priv_ctx->renderer, width, height);
|
||||
}
|
||||
|
||||
SDL_UpdateYUVTexture(texture, NULL,
|
||||
dav1d_pic->data[0], (int)dav1d_pic->stride[0], // Y
|
||||
dav1d_pic->data[1], (int)dav1d_pic->stride[1], // U
|
||||
dav1d_pic->data[2], (int)dav1d_pic->stride[1] // V
|
||||
);
|
||||
|
||||
rd_priv_ctx->tex = texture;
|
||||
SDL_UnlockMutex(rd_priv_ctx->lock);
|
||||
return 0;
|
||||
}
|
||||
|
||||
const Dav1dPlayRenderInfo rdr_sdl = {
|
||||
.name = "sdl",
|
||||
.create_renderer = sdl_renderer_create,
|
||||
.destroy_renderer = sdl_renderer_destroy,
|
||||
.render = sdl_render,
|
||||
.update_frame = sdl_update_texture
|
||||
};
|
||||
78
media/libdav1d/src/examples/meson.build
Normal file
78
media/libdav1d/src/examples/meson.build
Normal file
|
|
@ -0,0 +1,78 @@
|
|||
# Copyright © 2018, VideoLAN and dav1d authors
|
||||
# All rights reserved.
|
||||
#
|
||||
# Redistribution and use in source and binary forms, with or without
|
||||
# modification, are permitted provided that the following conditions are met:
|
||||
#
|
||||
# 1. Redistributions of source code must retain the above copyright notice, this
|
||||
# list of conditions and the following disclaimer.
|
||||
#
|
||||
# 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
# this list of conditions and the following disclaimer in the documentation
|
||||
# and/or other materials provided with the distribution.
|
||||
#
|
||||
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
# DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
|
||||
# ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
# (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
# ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
#
|
||||
# Build definition for the dav1d examples
|
||||
#
|
||||
|
||||
# Leave subdir if examples are disabled
|
||||
if not get_option('enable_examples')
|
||||
subdir_done()
|
||||
endif
|
||||
|
||||
|
||||
# dav1d player sources
|
||||
dav1dplay_sources = files(
|
||||
'dav1dplay.c',
|
||||
'dp_fifo.c',
|
||||
'dp_renderer_placebo.c',
|
||||
'dp_renderer_sdl.c',
|
||||
)
|
||||
|
||||
sdl2_dependency = dependency('sdl2', version: '>= 2.0.1', required: true)
|
||||
|
||||
if sdl2_dependency.found()
|
||||
dav1dplay_deps = [sdl2_dependency, libm_dependency]
|
||||
dav1dplay_cflags = []
|
||||
|
||||
placebo_dependency = dependency('libplacebo', version: '>= 4.160.0', required: false)
|
||||
|
||||
have_vulkan = false
|
||||
have_placebo = placebo_dependency.found()
|
||||
if have_placebo
|
||||
dav1dplay_deps += placebo_dependency
|
||||
|
||||
# If libplacebo is found, we might be able to use Vulkan
|
||||
# with it, in which case we need the Vulkan library too.
|
||||
vulkan_dependency = dependency('vulkan', required: false)
|
||||
if vulkan_dependency.found()
|
||||
dav1dplay_deps += vulkan_dependency
|
||||
have_vulkan = true
|
||||
endif
|
||||
endif
|
||||
|
||||
dav1dplay_cflags += '-DHAVE_PLACEBO=' + (have_placebo ? '1' : '0')
|
||||
dav1dplay_cflags += '-DHAVE_VULKAN=' + (have_vulkan ? '1' : '0')
|
||||
|
||||
dav1dplay = executable('dav1dplay',
|
||||
dav1dplay_sources,
|
||||
rev_target,
|
||||
|
||||
link_with : [libdav1d, dav1d_input_objs],
|
||||
include_directories : [dav1d_inc_dirs],
|
||||
dependencies : [getopt_dependency, dav1dplay_deps],
|
||||
install : true,
|
||||
c_args : dav1dplay_cflags,
|
||||
)
|
||||
endif
|
||||
4
media/libdav1d/src/gcovr.cfg
Normal file
4
media/libdav1d/src/gcovr.cfg
Normal file
|
|
@ -0,0 +1,4 @@
|
|||
exclude = .*/tests/.*
|
||||
exclude = .*/tools/.*
|
||||
exclude = .*/include/common/dump.h
|
||||
gcov-ignore-parse-errors = negative_hits.warn
|
||||
213
media/libdav1d/src/include/common/attributes.h
Normal file
213
media/libdav1d/src/include/common/attributes.h
Normal file
|
|
@ -0,0 +1,213 @@
|
|||
/*
|
||||
* Copyright © 2018, VideoLAN and dav1d authors
|
||||
* Copyright © 2018, Two Orioles, LLC
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef DAV1D_COMMON_ATTRIBUTES_H
|
||||
#define DAV1D_COMMON_ATTRIBUTES_H
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include <stddef.h>
|
||||
#include <assert.h>
|
||||
|
||||
#ifndef __has_attribute
|
||||
#define __has_attribute(x) 0
|
||||
#endif
|
||||
|
||||
#ifndef __has_feature
|
||||
#define __has_feature(x) 0
|
||||
#endif
|
||||
|
||||
#ifdef __GNUC__
|
||||
#define ATTR_ALIAS __attribute__((may_alias))
|
||||
#if defined(__MINGW32__) && !defined(__clang__)
|
||||
#define ATTR_FORMAT_PRINTF(fmt, attr) __attribute__((__format__(__gnu_printf__, fmt, attr)))
|
||||
#else
|
||||
#define ATTR_FORMAT_PRINTF(fmt, attr) __attribute__((__format__(__printf__, fmt, attr)))
|
||||
#endif
|
||||
#define COLD __attribute__((cold))
|
||||
#else
|
||||
#define ATTR_ALIAS
|
||||
#define ATTR_FORMAT_PRINTF(fmt, attr)
|
||||
#define COLD
|
||||
#endif
|
||||
|
||||
#if ARCH_X86_64
|
||||
/* x86-64 needs 32- and 64-byte alignment for AVX2 and AVX-512. */
|
||||
#define ALIGN_64_VAL 64
|
||||
#define ALIGN_32_VAL 32
|
||||
#define ALIGN_16_VAL 16
|
||||
#elif ARCH_AARCH64 || ARCH_ARM || ARCH_LOONGARCH || ARCH_PPC64LE || ARCH_X86_32
|
||||
/* ARM doesn't benefit from anything more than 16-byte alignment. */
|
||||
#define ALIGN_64_VAL 16
|
||||
#define ALIGN_32_VAL 16
|
||||
#define ALIGN_16_VAL 16
|
||||
#else
|
||||
/* No need for extra alignment on platforms without assembly. */
|
||||
#define ALIGN_64_VAL 8
|
||||
#define ALIGN_32_VAL 8
|
||||
#define ALIGN_16_VAL 8
|
||||
#endif
|
||||
|
||||
/*
|
||||
* API for variables, struct members (ALIGN()) like:
|
||||
* uint8_t var[1][2][3][4]
|
||||
* becomes:
|
||||
* ALIGN(uint8_t var[1][2][3][4], alignment).
|
||||
*/
|
||||
#ifdef _MSC_VER
|
||||
#define ALIGN(ll, a) \
|
||||
__declspec(align(a)) ll
|
||||
#else
|
||||
#define ALIGN(line, align) \
|
||||
line __attribute__((aligned(align)))
|
||||
#endif
|
||||
|
||||
/*
|
||||
* API for stack alignment (ALIGN_STK_$align()) of variables like:
|
||||
* uint8_t var[1][2][3][4]
|
||||
* becomes:
|
||||
* ALIGN_STK_$align(uint8_t, var, 1, [2][3][4])
|
||||
*/
|
||||
#define ALIGN_STK_64(type, var, sz1d, sznd) \
|
||||
ALIGN(type var[sz1d]sznd, ALIGN_64_VAL)
|
||||
#define ALIGN_STK_32(type, var, sz1d, sznd) \
|
||||
ALIGN(type var[sz1d]sznd, ALIGN_32_VAL)
|
||||
#define ALIGN_STK_16(type, var, sz1d, sznd) \
|
||||
ALIGN(type var[sz1d]sznd, ALIGN_16_VAL)
|
||||
|
||||
/*
|
||||
* Forbid inlining of a function:
|
||||
* static NOINLINE void func() {}
|
||||
*/
|
||||
#ifdef _MSC_VER
|
||||
#define NOINLINE __declspec(noinline)
|
||||
#elif __has_attribute(noclone)
|
||||
#define NOINLINE __attribute__((noinline, noclone))
|
||||
#else
|
||||
#define NOINLINE __attribute__((noinline))
|
||||
#endif
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#define ALWAYS_INLINE __forceinline
|
||||
#else
|
||||
#define ALWAYS_INLINE __attribute__((always_inline)) inline
|
||||
#endif
|
||||
|
||||
#if (defined(__ELF__) || defined(__MACH__) || (defined(_WIN32) && defined(__clang__))) && __has_attribute(visibility)
|
||||
#define EXTERN extern __attribute__((visibility("hidden")))
|
||||
#else
|
||||
#define EXTERN extern
|
||||
#endif
|
||||
|
||||
#if ARCH_X86_64 && __has_attribute(model)
|
||||
#define ATTR_MCMODEL_SMALL __attribute__((model("small")))
|
||||
#else
|
||||
#define ATTR_MCMODEL_SMALL
|
||||
#endif
|
||||
|
||||
#ifdef __clang__
|
||||
#define NO_SANITIZE(x) __attribute__((no_sanitize(x)))
|
||||
#else
|
||||
#define NO_SANITIZE(x)
|
||||
#endif
|
||||
|
||||
#if defined(NDEBUG) && (defined(__GNUC__) || defined(__clang__))
|
||||
#undef assert
|
||||
#define assert(x) do { if (!(x)) __builtin_unreachable(); } while (0)
|
||||
#elif defined(NDEBUG) && defined(_MSC_VER)
|
||||
#undef assert
|
||||
#define assert __assume
|
||||
#endif
|
||||
|
||||
#if defined(__GNUC__) && !defined(__INTEL_COMPILER) && !defined(__clang__)
|
||||
# define dav1d_uninit(x) x=x
|
||||
#else
|
||||
# define dav1d_uninit(x) x
|
||||
#endif
|
||||
|
||||
#if defined(_MSC_VER) && !defined(__clang__)
|
||||
#include <intrin.h>
|
||||
|
||||
static inline int ctz(const unsigned int mask) {
|
||||
unsigned long idx;
|
||||
_BitScanForward(&idx, mask);
|
||||
return idx;
|
||||
}
|
||||
|
||||
static inline int clz(const unsigned int mask) {
|
||||
unsigned long leading_zero = 0;
|
||||
_BitScanReverse(&leading_zero, mask);
|
||||
return (31 - leading_zero);
|
||||
}
|
||||
|
||||
#ifdef _WIN64
|
||||
static inline int clzll(const unsigned long long mask) {
|
||||
unsigned long leading_zero = 0;
|
||||
_BitScanReverse64(&leading_zero, mask);
|
||||
return (63 - leading_zero);
|
||||
}
|
||||
#else /* _WIN64 */
|
||||
static inline int clzll(const unsigned long long mask) {
|
||||
if (mask >> 32)
|
||||
return clz((unsigned)(mask >> 32));
|
||||
else
|
||||
return clz((unsigned)mask) + 32;
|
||||
}
|
||||
#endif /* _WIN64 */
|
||||
#else /* !_MSC_VER */
|
||||
static inline int ctz(const unsigned int mask) {
|
||||
return __builtin_ctz(mask);
|
||||
}
|
||||
|
||||
static inline int clz(const unsigned int mask) {
|
||||
return __builtin_clz(mask);
|
||||
}
|
||||
|
||||
static inline int clzll(const unsigned long long mask) {
|
||||
return __builtin_clzll(mask);
|
||||
}
|
||||
#endif /* !_MSC_VER */
|
||||
|
||||
#ifndef static_assert
|
||||
#define CHECK_OFFSET(type, field, name) \
|
||||
struct check_##type##_##field { int x[(name == offsetof(type, field)) ? 1 : -1]; }
|
||||
#define CHECK_SIZE(type, size) \
|
||||
struct check_##type##_size { int x[(size == sizeof(type)) ? 1 : -1]; }
|
||||
#else
|
||||
#define CHECK_OFFSET(type, field, name) \
|
||||
static_assert(name == offsetof(type, field), #field)
|
||||
#define CHECK_SIZE(type, size) \
|
||||
static_assert(size == sizeof(type), #type)
|
||||
#endif
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#define PACKED(...) __pragma(pack(push, 1)) __VA_ARGS__ __pragma(pack(pop))
|
||||
#else
|
||||
#define PACKED(...) __VA_ARGS__ __attribute__((__packed__))
|
||||
#endif
|
||||
|
||||
#endif /* DAV1D_COMMON_ATTRIBUTES_H */
|
||||
93
media/libdav1d/src/include/common/bitdepth.h
Normal file
93
media/libdav1d/src/include/common/bitdepth.h
Normal file
|
|
@ -0,0 +1,93 @@
|
|||
/*
|
||||
* Copyright © 2018, VideoLAN and dav1d authors
|
||||
* Copyright © 2018, Two Orioles, LLC
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef DAV1D_COMMON_BITDEPTH_H
|
||||
#define DAV1D_COMMON_BITDEPTH_H
|
||||
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "common/attributes.h"
|
||||
|
||||
#if !defined(BITDEPTH)
|
||||
typedef uint8_t pixel; /* can't be void due to pointer-to-array usage */
|
||||
typedef void coef;
|
||||
#define HIGHBD_DECL_SUFFIX /* nothing */
|
||||
#define HIGHBD_CALL_SUFFIX /* nothing */
|
||||
#define HIGHBD_TAIL_SUFFIX /* nothing */
|
||||
#elif BITDEPTH == 8
|
||||
typedef uint8_t pixel;
|
||||
typedef int16_t coef;
|
||||
#define PIXEL_TYPE uint8_t
|
||||
#define COEF_TYPE int16_t
|
||||
#define pixel_copy memcpy
|
||||
#define pixel_set memset
|
||||
#define iclip_pixel iclip_u8
|
||||
#define PIX_HEX_FMT "%02x"
|
||||
#define bitfn(x) x##_8bpc
|
||||
#define BF(x, suffix) x##_8bpc_##suffix
|
||||
#define PXSTRIDE(x) (x)
|
||||
#define highbd_only(x)
|
||||
#define HIGHBD_DECL_SUFFIX /* nothing */
|
||||
#define HIGHBD_CALL_SUFFIX /* nothing */
|
||||
#define HIGHBD_TAIL_SUFFIX /* nothing */
|
||||
#define bitdepth_from_max(x) 8
|
||||
#define BITDEPTH_MAX 0xff
|
||||
#elif BITDEPTH == 16
|
||||
typedef uint16_t pixel;
|
||||
typedef int32_t coef;
|
||||
#define PIXEL_TYPE uint16_t
|
||||
#define COEF_TYPE int32_t
|
||||
#define pixel_copy(a, b, c) memcpy(a, b, (c) << 1)
|
||||
static inline void pixel_set(pixel *const dst, const int val, const int num) {
|
||||
for (int n = 0; n < num; n++)
|
||||
dst[n] = val;
|
||||
}
|
||||
#define PIX_HEX_FMT "%03x"
|
||||
#define iclip_pixel(x) iclip(x, 0, bitdepth_max)
|
||||
#define HIGHBD_DECL_SUFFIX , const int bitdepth_max
|
||||
#define HIGHBD_CALL_SUFFIX , f->bitdepth_max
|
||||
#define HIGHBD_TAIL_SUFFIX , bitdepth_max
|
||||
#define bitdepth_from_max(bitdepth_max) (32 - clz(bitdepth_max))
|
||||
#define BITDEPTH_MAX bitdepth_max
|
||||
#define bitfn(x) x##_16bpc
|
||||
#define BF(x, suffix) x##_16bpc_##suffix
|
||||
static inline ptrdiff_t PXSTRIDE(const ptrdiff_t x) {
|
||||
assert(!(x & 1));
|
||||
return x >> 1;
|
||||
}
|
||||
#define highbd_only(x) x
|
||||
#else
|
||||
#error invalid value for bitdepth
|
||||
#endif
|
||||
#define bytefn(x) bitfn(x)
|
||||
|
||||
#define bitfn_decls(name, ...) \
|
||||
name##_8bpc(__VA_ARGS__); \
|
||||
name##_16bpc(__VA_ARGS__)
|
||||
|
||||
#endif /* DAV1D_COMMON_BITDEPTH_H */
|
||||
92
media/libdav1d/src/include/common/dump.h
Normal file
92
media/libdav1d/src/include/common/dump.h
Normal file
|
|
@ -0,0 +1,92 @@
|
|||
/*
|
||||
* Copyright © 2018, VideoLAN and dav1d authors
|
||||
* Copyright © 2018, Two Orioles, LLC
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef DAV1D_COMMON_DUMP_H
|
||||
#define DAV1D_COMMON_DUMP_H
|
||||
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#include "common/bitdepth.h"
|
||||
|
||||
static inline void append_plane_to_file(const pixel *buf, ptrdiff_t stride,
|
||||
int w, int h, const char *const file)
|
||||
{
|
||||
FILE *const f = fopen(file, "ab");
|
||||
while (h--) {
|
||||
fwrite(buf, w * sizeof(pixel), 1, f);
|
||||
buf += PXSTRIDE(stride);
|
||||
}
|
||||
fclose(f);
|
||||
}
|
||||
|
||||
static inline void hex_fdump(FILE *out, const pixel *buf, ptrdiff_t stride,
|
||||
int w, int h, const char *what)
|
||||
{
|
||||
fprintf(out, "%s\n", what);
|
||||
while (h--) {
|
||||
int x;
|
||||
for (x = 0; x < w; x++)
|
||||
fprintf(out, " " PIX_HEX_FMT, buf[x]);
|
||||
buf += PXSTRIDE(stride);
|
||||
fprintf(out, "\n");
|
||||
}
|
||||
}
|
||||
|
||||
static inline void hex_dump(const pixel *buf, ptrdiff_t stride,
|
||||
int w, int h, const char *what)
|
||||
{
|
||||
hex_fdump(stdout, buf, stride, w, h, what);
|
||||
}
|
||||
|
||||
static inline void coef_dump(const coef *buf, const int w, const int h,
|
||||
const int len, const char *what)
|
||||
{
|
||||
int y;
|
||||
printf("%s\n", what);
|
||||
for (y = 0; y < h; y++) {
|
||||
int x;
|
||||
for (x = 0; x < w; x++)
|
||||
printf(" %*d", len, buf[x]);
|
||||
buf += w;
|
||||
printf("\n");
|
||||
}
|
||||
}
|
||||
|
||||
static inline void ac_dump(const int16_t *buf, int w, int h, const char *what)
|
||||
{
|
||||
printf("%s\n", what);
|
||||
while (h--) {
|
||||
for (int x = 0; x < w; x++)
|
||||
printf(" %03d", buf[x]);
|
||||
buf += w;
|
||||
printf("\n");
|
||||
}
|
||||
}
|
||||
|
||||
#endif /* DAV1D_COMMON_DUMP_H */
|
||||
45
media/libdav1d/src/include/common/frame.h
Normal file
45
media/libdav1d/src/include/common/frame.h
Normal file
|
|
@ -0,0 +1,45 @@
|
|||
/*
|
||||
* Copyright © 2021, VideoLAN and dav1d authors
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef DAV1D_COMMON_FRAME_H
|
||||
#define DAV1D_COMMON_FRAME_H
|
||||
|
||||
/*
|
||||
* Checks whether Dav1dFrameType == INTER || == SWITCH
|
||||
* Both are defined as odd numbers {1, 3} and therefore have the LSB set.
|
||||
* See also: AV1 spec 6.8.2
|
||||
*/
|
||||
#define IS_INTER_OR_SWITCH(frame_header) \
|
||||
((frame_header)->frame_type & 1)
|
||||
|
||||
/*
|
||||
* Checks whether Dav1dFrameType == KEY || == INTRA
|
||||
* See also: AV1 spec 6.8.2
|
||||
*/
|
||||
#define IS_KEY_OR_INTRA(frame_header) \
|
||||
(!IS_INTER_OR_SWITCH(frame_header))
|
||||
|
||||
#endif /* DAV1D_COMMON_FRAME_H */
|
||||
84
media/libdav1d/src/include/common/intops.h
Normal file
84
media/libdav1d/src/include/common/intops.h
Normal file
|
|
@ -0,0 +1,84 @@
|
|||
/*
|
||||
* Copyright © 2018, VideoLAN and dav1d authors
|
||||
* Copyright © 2018, Two Orioles, LLC
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef DAV1D_COMMON_INTOPS_H
|
||||
#define DAV1D_COMMON_INTOPS_H
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#include "common/attributes.h"
|
||||
|
||||
static inline int imax(const int a, const int b) {
|
||||
return a > b ? a : b;
|
||||
}
|
||||
|
||||
static inline int imin(const int a, const int b) {
|
||||
return a < b ? a : b;
|
||||
}
|
||||
|
||||
static inline unsigned umax(const unsigned a, const unsigned b) {
|
||||
return a > b ? a : b;
|
||||
}
|
||||
|
||||
static inline unsigned umin(const unsigned a, const unsigned b) {
|
||||
return a < b ? a : b;
|
||||
}
|
||||
|
||||
static inline int iclip(const int v, const int min, const int max) {
|
||||
return v < min ? min : v > max ? max : v;
|
||||
}
|
||||
|
||||
static inline int iclip_u8(const int v) {
|
||||
return iclip(v, 0, 255);
|
||||
}
|
||||
|
||||
static inline int apply_sign(const int v, const int s) {
|
||||
return s < 0 ? -v : v;
|
||||
}
|
||||
|
||||
static inline int apply_sign64(const int v, const int64_t s) {
|
||||
return s < 0 ? -v : v;
|
||||
}
|
||||
|
||||
static inline int ulog2(const unsigned v) {
|
||||
return 31 ^ clz(v);
|
||||
}
|
||||
|
||||
static inline int u64log2(const uint64_t v) {
|
||||
return 63 ^ clzll(v);
|
||||
}
|
||||
|
||||
static inline unsigned inv_recenter(const unsigned r, const unsigned v) {
|
||||
if (v > (r << 1))
|
||||
return v;
|
||||
else if ((v & 1) == 0)
|
||||
return (v >> 1) + r;
|
||||
else
|
||||
return r - ((v + 1) >> 1);
|
||||
}
|
||||
|
||||
#endif /* DAV1D_COMMON_INTOPS_H */
|
||||
61
media/libdav1d/src/include/common/validate.h
Normal file
61
media/libdav1d/src/include/common/validate.h
Normal file
|
|
@ -0,0 +1,61 @@
|
|||
/*
|
||||
* Copyright © 2018, VideoLAN and dav1d authors
|
||||
* Copyright © 2018, Two Orioles, LLC
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef DAV1D_COMMON_VALIDATE_H
|
||||
#define DAV1D_COMMON_VALIDATE_H
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#if defined(NDEBUG)
|
||||
#define debug_print(...) do {} while (0)
|
||||
#define debug_abort() do {} while (0)
|
||||
#else
|
||||
#define debug_print(...) fprintf(stderr, __VA_ARGS__)
|
||||
#define debug_abort abort
|
||||
#endif
|
||||
|
||||
#define validate_input_or_ret_with_msg(x, r, ...) \
|
||||
if (!(x)) { \
|
||||
debug_print("Input validation check \'%s\' failed in %s!\n", \
|
||||
#x, __func__); \
|
||||
debug_print(__VA_ARGS__); \
|
||||
debug_abort(); \
|
||||
return r; \
|
||||
}
|
||||
|
||||
#define validate_input_or_ret(x, r) \
|
||||
if (!(x)) { \
|
||||
debug_print("Input validation check \'%s\' failed in %s!\n", \
|
||||
#x, __func__); \
|
||||
debug_abort(); \
|
||||
return r; \
|
||||
}
|
||||
|
||||
#define validate_input(x) validate_input_or_ret(x, )
|
||||
|
||||
#endif /* DAV1D_COMMON_VALIDATE_H */
|
||||
51
media/libdav1d/src/include/compat/gcc/stdatomic.h
Normal file
51
media/libdav1d/src/include/compat/gcc/stdatomic.h
Normal file
|
|
@ -0,0 +1,51 @@
|
|||
/*
|
||||
* Copyright © 2018, VideoLAN and dav1d authors
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef GCCVER_STDATOMIC_H_
|
||||
#define GCCVER_STDATOMIC_H_
|
||||
|
||||
#if !defined(__cplusplus)
|
||||
|
||||
typedef int atomic_int;
|
||||
typedef unsigned int atomic_uint;
|
||||
|
||||
#define memory_order_relaxed __ATOMIC_RELAXED
|
||||
#define memory_order_acquire __ATOMIC_ACQUIRE
|
||||
|
||||
#define atomic_init(p_a, v) do { *(p_a) = (v); } while(0)
|
||||
#define atomic_store(p_a, v) __atomic_store_n(p_a, v, __ATOMIC_SEQ_CST)
|
||||
#define atomic_load(p_a) __atomic_load_n(p_a, __ATOMIC_SEQ_CST)
|
||||
#define atomic_load_explicit(p_a, mo) __atomic_load_n(p_a, mo)
|
||||
#define atomic_fetch_add(p_a, inc) __atomic_fetch_add(p_a, inc, __ATOMIC_SEQ_CST)
|
||||
#define atomic_fetch_add_explicit(p_a, inc, mo) __atomic_fetch_add(p_a, inc, mo)
|
||||
#define atomic_fetch_sub(p_a, dec) __atomic_fetch_sub(p_a, dec, __ATOMIC_SEQ_CST)
|
||||
#define atomic_exchange(p_a, v) __atomic_exchange_n(p_a, v, __ATOMIC_SEQ_CST)
|
||||
#define atomic_fetch_or(p_a, v) __atomic_fetch_or(p_a, v, __ATOMIC_SEQ_CST)
|
||||
#define atomic_compare_exchange_strong(p_a, expected, desired) __atomic_compare_exchange_n(p_a, expected, desired, 0, __ATOMIC_SEQ_CST, __ATOMIC_SEQ_CST)
|
||||
|
||||
#endif /* !defined(__cplusplus) */
|
||||
|
||||
#endif /* GCCVER_STDATOMIC_H_ */
|
||||
97
media/libdav1d/src/include/compat/getopt.h
Normal file
97
media/libdav1d/src/include/compat/getopt.h
Normal file
|
|
@ -0,0 +1,97 @@
|
|||
#ifndef __GETOPT_H__
|
||||
/**
|
||||
* DISCLAIMER
|
||||
* This file has no copyright assigned and is placed in the Public Domain.
|
||||
* This file is part of the mingw-w64 runtime package.
|
||||
*
|
||||
* The mingw-w64 runtime package and its code is distributed in the hope that it
|
||||
* will be useful but WITHOUT ANY WARRANTY. ALL WARRANTIES, EXPRESSED OR
|
||||
* IMPLIED ARE HEREBY DISCLAIMED. This includes but is not limited to
|
||||
* warranties of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
*/
|
||||
|
||||
#define __GETOPT_H__
|
||||
|
||||
/* All the headers include this file. */
|
||||
#ifdef _WIN32
|
||||
#include <crtdefs.h>
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
extern int optind; /* index of first non-option in argv */
|
||||
extern int optopt; /* single option character, as parsed */
|
||||
extern int opterr; /* flag to enable built-in diagnostics... */
|
||||
/* (user may set to zero, to suppress) */
|
||||
|
||||
extern char *optarg; /* pointer to argument of current option */
|
||||
|
||||
extern int getopt(int nargc, char * const *nargv, const char *options);
|
||||
|
||||
#ifdef _BSD_SOURCE
|
||||
/*
|
||||
* BSD adds the non-standard `optreset' feature, for reinitialisation
|
||||
* of `getopt' parsing. We support this feature, for applications which
|
||||
* proclaim their BSD heritage, before including this header; however,
|
||||
* to maintain portability, developers are advised to avoid it.
|
||||
*/
|
||||
# define optreset __mingw_optreset
|
||||
extern int optreset;
|
||||
#endif
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
/*
|
||||
* POSIX requires the `getopt' API to be specified in `unistd.h';
|
||||
* thus, `unistd.h' includes this header. However, we do not want
|
||||
* to expose the `getopt_long' or `getopt_long_only' APIs, when
|
||||
* included in this manner. Thus, close the standard __GETOPT_H__
|
||||
* declarations block, and open an additional __GETOPT_LONG_H__
|
||||
* specific block, only when *not* __UNISTD_H_SOURCED__, in which
|
||||
* to declare the extended API.
|
||||
*/
|
||||
#if !defined(__UNISTD_H_SOURCED__) && !defined(__GETOPT_LONG_H__)
|
||||
#define __GETOPT_LONG_H__
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
struct option /* specification for a long form option... */
|
||||
{
|
||||
const char *name; /* option name, without leading hyphens */
|
||||
int has_arg; /* does it take an argument? */
|
||||
int *flag; /* where to save its status, or NULL */
|
||||
int val; /* its associated status value */
|
||||
};
|
||||
|
||||
enum /* permitted values for its `has_arg' field... */
|
||||
{
|
||||
no_argument = 0, /* option never takes an argument */
|
||||
required_argument, /* option always requires an argument */
|
||||
optional_argument /* option may take an argument */
|
||||
};
|
||||
|
||||
extern int getopt_long(int nargc, char * const *nargv, const char *options,
|
||||
const struct option *long_options, int *idx);
|
||||
extern int getopt_long_only(int nargc, char * const *nargv, const char *options,
|
||||
const struct option *long_options, int *idx);
|
||||
/*
|
||||
* Previous MinGW implementation had...
|
||||
*/
|
||||
#ifndef HAVE_DECL_GETOPT
|
||||
/*
|
||||
* ...for the long form API only; keep this for compatibility.
|
||||
*/
|
||||
# define HAVE_DECL_GETOPT 1
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* !defined(__UNISTD_H_SOURCED__) && !defined(__GETOPT_LONG_H__) */
|
||||
|
||||
#endif /* !defined(__GETOPT_H__) */
|
||||
82
media/libdav1d/src/include/compat/msvc/stdatomic.h
Normal file
82
media/libdav1d/src/include/compat/msvc/stdatomic.h
Normal file
|
|
@ -0,0 +1,82 @@
|
|||
/*
|
||||
* Copyright © 2018, VideoLAN and dav1d authors
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef MSCVER_STDATOMIC_H_
|
||||
#define MSCVER_STDATOMIC_H_
|
||||
|
||||
#if !defined(__cplusplus) && defined(_MSC_VER)
|
||||
|
||||
#pragma warning(push)
|
||||
#pragma warning(disable:4067) /* newline for __has_include_next */
|
||||
|
||||
#if defined(__clang__) && __has_include_next(<stdatomic.h>)
|
||||
/* use the clang stdatomic.h with clang-cl*/
|
||||
# include_next <stdatomic.h>
|
||||
#else /* ! stdatomic.h */
|
||||
|
||||
#include <windows.h>
|
||||
|
||||
#include "common/attributes.h"
|
||||
|
||||
typedef volatile LONG atomic_int;
|
||||
typedef volatile ULONG atomic_uint;
|
||||
|
||||
typedef enum {
|
||||
memory_order_relaxed,
|
||||
memory_order_acquire
|
||||
} msvc_atomic_memory_order;
|
||||
|
||||
#define atomic_init(p_a, v) do { *(p_a) = (v); } while(0)
|
||||
#define atomic_store(p_a, v) InterlockedExchange((LONG*)p_a, v)
|
||||
#define atomic_load(p_a) InterlockedCompareExchange((LONG*)p_a, 0, 0)
|
||||
#define atomic_exchange(p_a, v) InterlockedExchange(p_a, v)
|
||||
#define atomic_load_explicit(p_a, mo) atomic_load(p_a)
|
||||
|
||||
static inline int atomic_compare_exchange_strong_int(LONG *obj, LONG *expected,
|
||||
LONG desired)
|
||||
{
|
||||
LONG orig = *expected;
|
||||
*expected = InterlockedCompareExchange(obj, desired, orig);
|
||||
return *expected == orig;
|
||||
}
|
||||
#define atomic_compare_exchange_strong(p_a, expected, desired) atomic_compare_exchange_strong_int((LONG *)p_a, (LONG *)expected, (LONG)desired)
|
||||
|
||||
/*
|
||||
* TODO use a special call to increment/decrement
|
||||
* using InterlockedIncrement/InterlockedDecrement
|
||||
*/
|
||||
#define atomic_fetch_add(p_a, inc) InterlockedExchangeAdd(p_a, inc)
|
||||
#define atomic_fetch_sub(p_a, dec) InterlockedExchangeAdd(p_a, -(dec))
|
||||
#define atomic_fetch_or(p_a, v) InterlockedOr(p_a, v)
|
||||
#define atomic_fetch_add_explicit(p_a, inc, mo) atomic_fetch_add(p_a, inc)
|
||||
|
||||
#endif /* ! stdatomic.h */
|
||||
|
||||
#pragma warning(pop)
|
||||
|
||||
#endif /* !defined(__cplusplus) && defined(_MSC_VER) */
|
||||
|
||||
#endif /* MSCVER_STDATOMIC_H_ */
|
||||
94
media/libdav1d/src/include/dav1d/common.h
Normal file
94
media/libdav1d/src/include/dav1d/common.h
Normal file
|
|
@ -0,0 +1,94 @@
|
|||
/*
|
||||
* Copyright © 2018, VideoLAN and dav1d authors
|
||||
* Copyright © 2018, Two Orioles, LLC
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef DAV1D_COMMON_H
|
||||
#define DAV1D_COMMON_H
|
||||
|
||||
#include <errno.h>
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#ifndef DAV1D_API
|
||||
#if defined _WIN32
|
||||
#if defined DAV1D_BUILDING_DLL
|
||||
#define DAV1D_API __declspec(dllexport)
|
||||
#else
|
||||
#define DAV1D_API
|
||||
#endif
|
||||
#else
|
||||
#if __GNUC__ >= 4
|
||||
#define DAV1D_API __attribute__ ((visibility ("default")))
|
||||
#else
|
||||
#define DAV1D_API
|
||||
#endif
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if EPERM > 0
|
||||
#define DAV1D_ERR(e) (-(e)) ///< Negate POSIX error code.
|
||||
#else
|
||||
#define DAV1D_ERR(e) (e)
|
||||
#endif
|
||||
|
||||
/**
|
||||
* A reference-counted object wrapper for a user-configurable pointer.
|
||||
*/
|
||||
typedef struct Dav1dUserData {
|
||||
const uint8_t *data; ///< data pointer
|
||||
struct Dav1dRef *ref; ///< allocation origin
|
||||
} Dav1dUserData;
|
||||
|
||||
/**
|
||||
* Input packet metadata which are copied from the input data used to
|
||||
* decode each image into the matching structure of the output image
|
||||
* returned back to the user. Since these are metadata fields, they
|
||||
* can be used for other purposes than the documented ones, they will
|
||||
* still be passed from input data to output picture without being
|
||||
* used internally.
|
||||
*/
|
||||
typedef struct Dav1dDataProps {
|
||||
int64_t timestamp; ///< container timestamp of input data, INT64_MIN if unknown (default)
|
||||
int64_t duration; ///< container duration of input data, 0 if unknown (default)
|
||||
int64_t offset; ///< stream offset of input data, -1 if unknown (default)
|
||||
size_t size; ///< packet size, default Dav1dData.sz
|
||||
struct Dav1dUserData user_data; ///< user-configurable data, default NULL members
|
||||
} Dav1dDataProps;
|
||||
|
||||
/**
|
||||
* Release reference to a Dav1dDataProps.
|
||||
*/
|
||||
DAV1D_API void dav1d_data_props_unref(Dav1dDataProps *props);
|
||||
|
||||
#ifdef __cplusplus
|
||||
} /* extern "C" */
|
||||
#endif
|
||||
|
||||
#endif /* DAV1D_COMMON_H */
|
||||
117
media/libdav1d/src/include/dav1d/data.h
Normal file
117
media/libdav1d/src/include/dav1d/data.h
Normal file
|
|
@ -0,0 +1,117 @@
|
|||
/*
|
||||
* Copyright © 2018, VideoLAN and dav1d authors
|
||||
* Copyright © 2018, Two Orioles, LLC
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef DAV1D_DATA_H
|
||||
#define DAV1D_DATA_H
|
||||
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#include "common.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
typedef struct Dav1dData {
|
||||
const uint8_t *data; ///< data pointer
|
||||
size_t sz; ///< data size
|
||||
struct Dav1dRef *ref; ///< allocation origin
|
||||
Dav1dDataProps m; ///< user provided metadata passed to the output picture
|
||||
} Dav1dData;
|
||||
|
||||
/**
|
||||
* Allocate data.
|
||||
*
|
||||
* @param data Input context.
|
||||
* @param sz Size of the data that should be allocated.
|
||||
*
|
||||
* @return Pointer to the allocated buffer on success. NULL on error.
|
||||
*/
|
||||
DAV1D_API uint8_t * dav1d_data_create(Dav1dData *data, size_t sz);
|
||||
|
||||
/**
|
||||
* Wrap an existing data array.
|
||||
*
|
||||
* @param data Input context.
|
||||
* @param buf The data to be wrapped.
|
||||
* @param sz Size of the data.
|
||||
* @param free_callback Function to be called when we release our last
|
||||
* reference to this data. In this callback, $buf will be
|
||||
* the $buf argument to this function, and $cookie will
|
||||
* be the $cookie input argument to this function.
|
||||
* @param cookie Opaque parameter passed to free_callback().
|
||||
*
|
||||
* @return 0 on success. A negative DAV1D_ERR value on error.
|
||||
*/
|
||||
DAV1D_API int dav1d_data_wrap(Dav1dData *data, const uint8_t *buf, size_t sz,
|
||||
void (*free_callback)(const uint8_t *buf, void *cookie),
|
||||
void *cookie);
|
||||
|
||||
/**
|
||||
* Wrap a user-provided data pointer into a reference counted object.
|
||||
*
|
||||
* data->m.user_data field will initialized to wrap the provided $user_data
|
||||
* pointer.
|
||||
*
|
||||
* $free_callback will be called on the same thread that released the last
|
||||
* reference. If frame threading is used, make sure $free_callback is
|
||||
* thread-safe.
|
||||
*
|
||||
* @param data Input context.
|
||||
* @param user_data The user data to be wrapped.
|
||||
* @param free_callback Function to be called when we release our last
|
||||
* reference to this data. In this callback, $user_data
|
||||
* will be the $user_data argument to this function, and
|
||||
* $cookie will be the $cookie input argument to this
|
||||
* function.
|
||||
* @param cookie Opaque parameter passed to $free_callback.
|
||||
*
|
||||
* @return 0 on success. A negative DAV1D_ERR value on error.
|
||||
*/
|
||||
DAV1D_API int dav1d_data_wrap_user_data(Dav1dData *data,
|
||||
const uint8_t *user_data,
|
||||
void (*free_callback)(const uint8_t *user_data,
|
||||
void *cookie),
|
||||
void *cookie);
|
||||
|
||||
/**
|
||||
* Free the data reference.
|
||||
*
|
||||
* The reference count for data->m.user_data will be decremented (if it has been
|
||||
* initialized with dav1d_data_wrap_user_data). The $data object will be memset
|
||||
* to 0.
|
||||
*
|
||||
* @param data Input context.
|
||||
*/
|
||||
DAV1D_API void dav1d_data_unref(Dav1dData *data);
|
||||
|
||||
#ifdef __cplusplus
|
||||
} /* extern "C" */
|
||||
#endif
|
||||
|
||||
#endif /* DAV1D_DATA_H */
|
||||
329
media/libdav1d/src/include/dav1d/dav1d.h
Normal file
329
media/libdav1d/src/include/dav1d/dav1d.h
Normal file
|
|
@ -0,0 +1,329 @@
|
|||
/*
|
||||
* Copyright © 2018-2021, VideoLAN and dav1d authors
|
||||
* Copyright © 2018, Two Orioles, LLC
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef DAV1D_H
|
||||
#define DAV1D_H
|
||||
|
||||
#include <errno.h>
|
||||
#include <stdarg.h>
|
||||
|
||||
#include "common.h"
|
||||
#include "picture.h"
|
||||
#include "data.h"
|
||||
#include "version.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
typedef struct Dav1dContext Dav1dContext;
|
||||
typedef struct Dav1dRef Dav1dRef;
|
||||
|
||||
#define DAV1D_MAX_THREADS 256
|
||||
#define DAV1D_MAX_FRAME_DELAY 256
|
||||
|
||||
typedef struct Dav1dLogger {
|
||||
void *cookie; ///< Custom data to pass to the callback.
|
||||
/**
|
||||
* Logger callback. May be NULL to disable logging.
|
||||
*
|
||||
* @param cookie Custom pointer passed to all calls.
|
||||
* @param format The vprintf compatible format string.
|
||||
* @param ap List of arguments referenced by the format string.
|
||||
*/
|
||||
void (*callback)(void *cookie, const char *format, va_list ap);
|
||||
} Dav1dLogger;
|
||||
|
||||
enum Dav1dInloopFilterType {
|
||||
DAV1D_INLOOPFILTER_NONE = 0,
|
||||
DAV1D_INLOOPFILTER_DEBLOCK = 1 << 0,
|
||||
DAV1D_INLOOPFILTER_CDEF = 1 << 1,
|
||||
DAV1D_INLOOPFILTER_RESTORATION = 1 << 2,
|
||||
DAV1D_INLOOPFILTER_ALL = DAV1D_INLOOPFILTER_DEBLOCK |
|
||||
DAV1D_INLOOPFILTER_CDEF |
|
||||
DAV1D_INLOOPFILTER_RESTORATION,
|
||||
};
|
||||
|
||||
enum Dav1dDecodeFrameType {
|
||||
DAV1D_DECODEFRAMETYPE_ALL = 0, ///< decode and return all frames
|
||||
DAV1D_DECODEFRAMETYPE_REFERENCE = 1,///< decode and return frames referenced by other frames only
|
||||
DAV1D_DECODEFRAMETYPE_INTRA = 2, ///< decode and return intra frames only (includes keyframes)
|
||||
DAV1D_DECODEFRAMETYPE_KEY = 3, ///< decode and return keyframes only
|
||||
};
|
||||
|
||||
typedef struct Dav1dSettings {
|
||||
int n_threads; ///< number of threads (0 = number of logical cores in host system, default 0)
|
||||
int max_frame_delay; ///< Set to 1 for low-latency decoding (0 = ceil(sqrt(n_threads)), default 0)
|
||||
int apply_grain; ///< whether to apply film grain on output frames (default 1)
|
||||
int operating_point; ///< select an operating point for scalable AV1 bitstreams (0 - 31, default 0)
|
||||
int all_layers; ///< output all spatial layers of a scalable AV1 biststream (default 1)
|
||||
unsigned frame_size_limit; ///< maximum frame size, in pixels (0 = unlimited, default 0)
|
||||
Dav1dPicAllocator allocator; ///< Picture allocator callback.
|
||||
Dav1dLogger logger; ///< Logger callback.
|
||||
int strict_std_compliance; ///< whether to abort decoding on standard compliance violations
|
||||
///< that don't affect actual bitstream decoding (e.g. inconsistent
|
||||
///< or invalid metadata, default 0)
|
||||
int output_invisible_frames; ///< output invisibly coded frames (in coding order) in addition
|
||||
///< to all visible frames. Because of show-existing-frame, this
|
||||
///< means some frames may appear twice (once when coded,
|
||||
///< once when shown, default 0)
|
||||
enum Dav1dInloopFilterType inloop_filters; ///< postfilters to enable during decoding (default
|
||||
///< DAV1D_INLOOPFILTER_ALL)
|
||||
enum Dav1dDecodeFrameType decode_frame_type; ///< frame types to decode (default
|
||||
///< DAV1D_DECODEFRAMETYPE_ALL)
|
||||
uint8_t reserved[16]; ///< reserved for future use
|
||||
} Dav1dSettings;
|
||||
|
||||
/**
|
||||
* Get library version.
|
||||
*/
|
||||
DAV1D_API const char *dav1d_version(void);
|
||||
|
||||
/**
|
||||
* Get library API version.
|
||||
*
|
||||
* @return A value in the format 0x00XXYYZZ, where XX is the major version,
|
||||
* YY the minor version, and ZZ the patch version.
|
||||
* @see DAV1D_API_MAJOR, DAV1D_API_MINOR, DAV1D_API_PATCH
|
||||
*/
|
||||
DAV1D_API unsigned dav1d_version_api(void);
|
||||
|
||||
/**
|
||||
* Initialize settings to default values.
|
||||
*
|
||||
* @param s Input settings context.
|
||||
*/
|
||||
DAV1D_API void dav1d_default_settings(Dav1dSettings *s);
|
||||
|
||||
/**
|
||||
* Allocate and open a decoder instance.
|
||||
*
|
||||
* @param c_out The decoder instance to open. *c_out will be set to the
|
||||
* allocated context.
|
||||
* @param s Input settings context.
|
||||
*
|
||||
* @note The context must be freed using dav1d_close() when decoding is
|
||||
* finished.
|
||||
*
|
||||
* @return 0 on success, or < 0 (a negative DAV1D_ERR code) on error.
|
||||
*/
|
||||
DAV1D_API int dav1d_open(Dav1dContext **c_out, const Dav1dSettings *s);
|
||||
|
||||
/**
|
||||
* Parse a Sequence Header OBU from bitstream data.
|
||||
*
|
||||
* @param out Output Sequence Header.
|
||||
* @param buf The data to be parser.
|
||||
* @param sz Size of the data.
|
||||
*
|
||||
* @return
|
||||
* 0: Success, and out is filled with the parsed Sequence Header
|
||||
* OBU parameters.
|
||||
* DAV1D_ERR(ENOENT): No Sequence Header OBUs were found in the buffer.
|
||||
* Other negative DAV1D_ERR codes: Invalid data in the buffer, invalid passed-in
|
||||
* arguments, and other errors during parsing.
|
||||
*
|
||||
* @note It is safe to feed this function data containing other OBUs than a
|
||||
* Sequence Header, as they will simply be ignored. If there is more than
|
||||
* one Sequence Header OBU present, only the last will be returned.
|
||||
*/
|
||||
DAV1D_API int dav1d_parse_sequence_header(Dav1dSequenceHeader *out,
|
||||
const uint8_t *buf, const size_t sz);
|
||||
|
||||
/**
|
||||
* Feed bitstream data to the decoder, in the form of one or multiple AV1
|
||||
* Open Bitstream Units (OBUs).
|
||||
*
|
||||
* @param c Input decoder instance.
|
||||
* @param in Input bitstream data. On success, ownership of the reference is
|
||||
* passed to the library.
|
||||
*
|
||||
* @return
|
||||
* 0: Success, and the data was consumed.
|
||||
* DAV1D_ERR(EAGAIN): The data can't be consumed. dav1d_get_picture() should
|
||||
* be called to get one or more frames before the function
|
||||
* can consume new data.
|
||||
* Other negative DAV1D_ERR codes: Error during decoding or because of invalid
|
||||
* passed-in arguments. The reference remains
|
||||
* owned by the caller.
|
||||
*/
|
||||
DAV1D_API int dav1d_send_data(Dav1dContext *c, Dav1dData *in);
|
||||
|
||||
/**
|
||||
* Return a decoded picture.
|
||||
*
|
||||
* @param c Input decoder instance.
|
||||
* @param out Output frame. The caller assumes ownership of the returned
|
||||
* reference.
|
||||
*
|
||||
* @return
|
||||
* 0: Success, and a frame is returned.
|
||||
* DAV1D_ERR(EAGAIN): Not enough data to output a frame. dav1d_send_data()
|
||||
* should be called with new input.
|
||||
* Other negative DAV1D_ERR codes: Error during decoding or because of invalid
|
||||
* passed-in arguments.
|
||||
*
|
||||
* @note To drain buffered frames from the decoder (i.e. on end of stream),
|
||||
* call this function until it returns DAV1D_ERR(EAGAIN).
|
||||
*
|
||||
* @code{.c}
|
||||
* Dav1dData data = { 0 };
|
||||
* Dav1dPicture p = { 0 };
|
||||
* int res;
|
||||
*
|
||||
* read_data(&data);
|
||||
* do {
|
||||
* res = dav1d_send_data(c, &data);
|
||||
* // Keep going even if the function can't consume the current data
|
||||
* packet. It eventually will after one or more frames have been
|
||||
* returned in this loop.
|
||||
* if (res < 0 && res != DAV1D_ERR(EAGAIN))
|
||||
* free_and_abort();
|
||||
* res = dav1d_get_picture(c, &p);
|
||||
* if (res < 0) {
|
||||
* if (res != DAV1D_ERR(EAGAIN))
|
||||
* free_and_abort();
|
||||
* } else
|
||||
* output_and_unref_picture(&p);
|
||||
* // Stay in the loop as long as there's data to consume.
|
||||
* } while (data.sz || read_data(&data) == SUCCESS);
|
||||
*
|
||||
* // Handle EOS by draining all buffered frames.
|
||||
* do {
|
||||
* res = dav1d_get_picture(c, &p);
|
||||
* if (res < 0) {
|
||||
* if (res != DAV1D_ERR(EAGAIN))
|
||||
* free_and_abort();
|
||||
* } else
|
||||
* output_and_unref_picture(&p);
|
||||
* } while (res == 0);
|
||||
* @endcode
|
||||
*/
|
||||
DAV1D_API int dav1d_get_picture(Dav1dContext *c, Dav1dPicture *out);
|
||||
|
||||
/**
|
||||
* Apply film grain to a previously decoded picture. If the picture contains no
|
||||
* film grain metadata, then this function merely returns a new reference.
|
||||
*
|
||||
* @param c Input decoder instance.
|
||||
* @param out Output frame. The caller assumes ownership of the returned
|
||||
* reference.
|
||||
* @param in Input frame. No ownership is transferred.
|
||||
*
|
||||
* @return
|
||||
* 0: Success, and a frame is returned.
|
||||
* Other negative DAV1D_ERR codes: Error due to lack of memory or because of
|
||||
* invalid passed-in arguments.
|
||||
*
|
||||
* @note If `Dav1dSettings.apply_grain` is true, film grain was already applied
|
||||
* by `dav1d_get_picture`, and so calling this function leads to double
|
||||
* application of film grain. Users should only call this when needed.
|
||||
*/
|
||||
DAV1D_API int dav1d_apply_grain(Dav1dContext *c, Dav1dPicture *out,
|
||||
const Dav1dPicture *in);
|
||||
|
||||
/**
|
||||
* Close a decoder instance and free all associated memory.
|
||||
*
|
||||
* @param c_out The decoder instance to close. *c_out will be set to NULL.
|
||||
*/
|
||||
DAV1D_API void dav1d_close(Dav1dContext **c_out);
|
||||
|
||||
/**
|
||||
* Flush all delayed frames in decoder and clear internal decoder state,
|
||||
* to be used when seeking.
|
||||
*
|
||||
* @param c Input decoder instance.
|
||||
*
|
||||
* @note Decoding will start only after a valid sequence header OBU is
|
||||
* delivered to dav1d_send_data().
|
||||
*
|
||||
*/
|
||||
DAV1D_API void dav1d_flush(Dav1dContext *c);
|
||||
|
||||
enum Dav1dEventFlags {
|
||||
/**
|
||||
* The last returned picture contains a reference to a new Sequence Header,
|
||||
* either because it's the start of a new coded sequence, or the decoder was
|
||||
* flushed before it was generated.
|
||||
*/
|
||||
DAV1D_EVENT_FLAG_NEW_SEQUENCE = 1 << 0,
|
||||
/**
|
||||
* The last returned picture contains a reference to a Sequence Header with
|
||||
* new operating parameters information for the current coded sequence.
|
||||
*/
|
||||
DAV1D_EVENT_FLAG_NEW_OP_PARAMS_INFO = 1 << 1,
|
||||
};
|
||||
|
||||
/**
|
||||
* Fetch a combination of DAV1D_EVENT_FLAG_* event flags generated by the decoding
|
||||
* process.
|
||||
*
|
||||
* @param c Input decoder instance.
|
||||
* @param flags Where to write the flags.
|
||||
*
|
||||
* @return 0 on success, or < 0 (a negative DAV1D_ERR code) on error.
|
||||
*
|
||||
* @note Calling this function will clear all the event flags currently stored in
|
||||
* the decoder.
|
||||
*
|
||||
*/
|
||||
DAV1D_API int dav1d_get_event_flags(Dav1dContext *c, enum Dav1dEventFlags *flags);
|
||||
|
||||
/**
|
||||
* Retrieve the user-provided metadata associated with the input data packet
|
||||
* for the last decoding error reported to the user, i.e. a negative return
|
||||
* value (not EAGAIN) from dav1d_send_data() or dav1d_get_picture().
|
||||
*
|
||||
* @param c Input decoder instance.
|
||||
* @param out Output Dav1dDataProps. On success, the caller assumes ownership of
|
||||
* the returned reference.
|
||||
*
|
||||
* @return 0 on success, or < 0 (a negative DAV1D_ERR code) on error.
|
||||
*/
|
||||
DAV1D_API int dav1d_get_decode_error_data_props(Dav1dContext *c, Dav1dDataProps *out);
|
||||
|
||||
/**
|
||||
* Get the decoder delay, which is the number of internally buffered frames, not
|
||||
* including reference frames.
|
||||
* This value is guaranteed to be >= 1 and <= max_frame_delay.
|
||||
*
|
||||
* @param s Input settings context.
|
||||
*
|
||||
* @return Decoder frame delay on success, or < 0 (a negative DAV1D_ERR code) on
|
||||
* error.
|
||||
*
|
||||
* @note The returned delay is valid only for a Dav1dContext initialized with the
|
||||
* provided Dav1dSettings.
|
||||
*/
|
||||
DAV1D_API int dav1d_get_frame_delay(const Dav1dSettings *s);
|
||||
|
||||
#ifdef __cplusplus
|
||||
} /* extern "C" */
|
||||
#endif
|
||||
|
||||
#endif /* DAV1D_H */
|
||||
440
media/libdav1d/src/include/dav1d/headers.h
Normal file
440
media/libdav1d/src/include/dav1d/headers.h
Normal file
|
|
@ -0,0 +1,440 @@
|
|||
/*
|
||||
* Copyright © 2018-2020, VideoLAN and dav1d authors
|
||||
* Copyright © 2018, Two Orioles, LLC
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef DAV1D_HEADERS_H
|
||||
#define DAV1D_HEADERS_H
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stddef.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
// Constants from Section 3. "Symbols and abbreviated terms"
|
||||
#define DAV1D_MAX_CDEF_STRENGTHS 8
|
||||
#define DAV1D_MAX_OPERATING_POINTS 32
|
||||
#define DAV1D_MAX_TILE_COLS 64
|
||||
#define DAV1D_MAX_TILE_ROWS 64
|
||||
#define DAV1D_MAX_SEGMENTS 8
|
||||
#define DAV1D_NUM_REF_FRAMES 8
|
||||
#define DAV1D_PRIMARY_REF_NONE 7
|
||||
#define DAV1D_REFS_PER_FRAME 7
|
||||
#define DAV1D_TOTAL_REFS_PER_FRAME (DAV1D_REFS_PER_FRAME + 1)
|
||||
|
||||
enum Dav1dObuType {
|
||||
DAV1D_OBU_SEQ_HDR = 1,
|
||||
DAV1D_OBU_TD = 2,
|
||||
DAV1D_OBU_FRAME_HDR = 3,
|
||||
DAV1D_OBU_TILE_GRP = 4,
|
||||
DAV1D_OBU_METADATA = 5,
|
||||
DAV1D_OBU_FRAME = 6,
|
||||
DAV1D_OBU_REDUNDANT_FRAME_HDR = 7,
|
||||
DAV1D_OBU_PADDING = 15,
|
||||
};
|
||||
|
||||
enum Dav1dTxfmMode {
|
||||
DAV1D_TX_4X4_ONLY,
|
||||
DAV1D_TX_LARGEST,
|
||||
DAV1D_TX_SWITCHABLE,
|
||||
DAV1D_N_TX_MODES,
|
||||
};
|
||||
|
||||
enum Dav1dFilterMode {
|
||||
DAV1D_FILTER_8TAP_REGULAR,
|
||||
DAV1D_FILTER_8TAP_SMOOTH,
|
||||
DAV1D_FILTER_8TAP_SHARP,
|
||||
DAV1D_N_SWITCHABLE_FILTERS,
|
||||
DAV1D_FILTER_BILINEAR = DAV1D_N_SWITCHABLE_FILTERS,
|
||||
DAV1D_N_FILTERS,
|
||||
DAV1D_FILTER_SWITCHABLE = DAV1D_N_FILTERS,
|
||||
};
|
||||
|
||||
enum Dav1dAdaptiveBoolean {
|
||||
DAV1D_OFF = 0,
|
||||
DAV1D_ON = 1,
|
||||
DAV1D_ADAPTIVE = 2,
|
||||
};
|
||||
|
||||
enum Dav1dRestorationType {
|
||||
DAV1D_RESTORATION_NONE,
|
||||
DAV1D_RESTORATION_SWITCHABLE,
|
||||
DAV1D_RESTORATION_WIENER,
|
||||
DAV1D_RESTORATION_SGRPROJ,
|
||||
};
|
||||
|
||||
enum Dav1dWarpedMotionType {
|
||||
DAV1D_WM_TYPE_IDENTITY,
|
||||
DAV1D_WM_TYPE_TRANSLATION,
|
||||
DAV1D_WM_TYPE_ROT_ZOOM,
|
||||
DAV1D_WM_TYPE_AFFINE,
|
||||
};
|
||||
|
||||
typedef struct Dav1dWarpedMotionParams {
|
||||
enum Dav1dWarpedMotionType type;
|
||||
int32_t matrix[6];
|
||||
union {
|
||||
struct {
|
||||
int16_t alpha, beta, gamma, delta;
|
||||
} p;
|
||||
int16_t abcd[4];
|
||||
} u;
|
||||
} Dav1dWarpedMotionParams;
|
||||
|
||||
enum Dav1dPixelLayout {
|
||||
DAV1D_PIXEL_LAYOUT_I400, ///< monochrome
|
||||
DAV1D_PIXEL_LAYOUT_I420, ///< 4:2:0 planar
|
||||
DAV1D_PIXEL_LAYOUT_I422, ///< 4:2:2 planar
|
||||
DAV1D_PIXEL_LAYOUT_I444, ///< 4:4:4 planar
|
||||
};
|
||||
|
||||
enum Dav1dFrameType {
|
||||
DAV1D_FRAME_TYPE_KEY = 0, ///< Key Intra frame
|
||||
DAV1D_FRAME_TYPE_INTER = 1, ///< Inter frame
|
||||
DAV1D_FRAME_TYPE_INTRA = 2, ///< Non key Intra frame
|
||||
DAV1D_FRAME_TYPE_SWITCH = 3, ///< Switch Inter frame
|
||||
};
|
||||
|
||||
enum Dav1dColorPrimaries {
|
||||
DAV1D_COLOR_PRI_BT709 = 1,
|
||||
DAV1D_COLOR_PRI_UNKNOWN = 2,
|
||||
DAV1D_COLOR_PRI_BT470M = 4,
|
||||
DAV1D_COLOR_PRI_BT470BG = 5,
|
||||
DAV1D_COLOR_PRI_BT601 = 6,
|
||||
DAV1D_COLOR_PRI_SMPTE240 = 7,
|
||||
DAV1D_COLOR_PRI_FILM = 8,
|
||||
DAV1D_COLOR_PRI_BT2020 = 9,
|
||||
DAV1D_COLOR_PRI_XYZ = 10,
|
||||
DAV1D_COLOR_PRI_SMPTE431 = 11,
|
||||
DAV1D_COLOR_PRI_SMPTE432 = 12,
|
||||
DAV1D_COLOR_PRI_EBU3213 = 22,
|
||||
DAV1D_COLOR_PRI_RESERVED = 255,
|
||||
};
|
||||
|
||||
enum Dav1dTransferCharacteristics {
|
||||
DAV1D_TRC_BT709 = 1,
|
||||
DAV1D_TRC_UNKNOWN = 2,
|
||||
DAV1D_TRC_BT470M = 4,
|
||||
DAV1D_TRC_BT470BG = 5,
|
||||
DAV1D_TRC_BT601 = 6,
|
||||
DAV1D_TRC_SMPTE240 = 7,
|
||||
DAV1D_TRC_LINEAR = 8,
|
||||
DAV1D_TRC_LOG100 = 9, ///< logarithmic (100:1 range)
|
||||
DAV1D_TRC_LOG100_SQRT10 = 10, ///< lograithmic (100*sqrt(10):1 range)
|
||||
DAV1D_TRC_IEC61966 = 11,
|
||||
DAV1D_TRC_BT1361 = 12,
|
||||
DAV1D_TRC_SRGB = 13,
|
||||
DAV1D_TRC_BT2020_10BIT = 14,
|
||||
DAV1D_TRC_BT2020_12BIT = 15,
|
||||
DAV1D_TRC_SMPTE2084 = 16, ///< PQ
|
||||
DAV1D_TRC_SMPTE428 = 17,
|
||||
DAV1D_TRC_HLG = 18, ///< hybrid log/gamma (BT.2100 / ARIB STD-B67)
|
||||
DAV1D_TRC_RESERVED = 255,
|
||||
};
|
||||
|
||||
enum Dav1dMatrixCoefficients {
|
||||
DAV1D_MC_IDENTITY = 0,
|
||||
DAV1D_MC_BT709 = 1,
|
||||
DAV1D_MC_UNKNOWN = 2,
|
||||
DAV1D_MC_FCC = 4,
|
||||
DAV1D_MC_BT470BG = 5,
|
||||
DAV1D_MC_BT601 = 6,
|
||||
DAV1D_MC_SMPTE240 = 7,
|
||||
DAV1D_MC_SMPTE_YCGCO = 8,
|
||||
DAV1D_MC_BT2020_NCL = 9,
|
||||
DAV1D_MC_BT2020_CL = 10,
|
||||
DAV1D_MC_SMPTE2085 = 11,
|
||||
DAV1D_MC_CHROMAT_NCL = 12, ///< Chromaticity-derived
|
||||
DAV1D_MC_CHROMAT_CL = 13,
|
||||
DAV1D_MC_ICTCP = 14,
|
||||
DAV1D_MC_RESERVED = 255,
|
||||
};
|
||||
|
||||
enum Dav1dChromaSamplePosition {
|
||||
DAV1D_CHR_UNKNOWN = 0,
|
||||
DAV1D_CHR_VERTICAL = 1, ///< Horizontally co-located with luma(0, 0)
|
||||
///< sample, between two vertical samples
|
||||
DAV1D_CHR_COLOCATED = 2, ///< Co-located with luma(0, 0) sample
|
||||
};
|
||||
|
||||
typedef struct Dav1dContentLightLevel {
|
||||
uint16_t max_content_light_level;
|
||||
uint16_t max_frame_average_light_level;
|
||||
} Dav1dContentLightLevel;
|
||||
|
||||
typedef struct Dav1dMasteringDisplay {
|
||||
uint16_t primaries[3][2]; ///< 0.16 fixed point
|
||||
uint16_t white_point[2]; ///< 0.16 fixed point
|
||||
uint32_t max_luminance; ///< 24.8 fixed point
|
||||
uint32_t min_luminance; ///< 18.14 fixed point
|
||||
} Dav1dMasteringDisplay;
|
||||
|
||||
typedef struct Dav1dITUTT35 {
|
||||
uint8_t country_code;
|
||||
uint8_t country_code_extension_byte;
|
||||
size_t payload_size;
|
||||
uint8_t *payload;
|
||||
} Dav1dITUTT35;
|
||||
|
||||
typedef struct Dav1dSequenceHeader {
|
||||
/**
|
||||
* Stream profile, 0 for 8-10 bits/component 4:2:0 or monochrome;
|
||||
* 1 for 8-10 bits/component 4:4:4; 2 for 4:2:2 at any bits/component,
|
||||
* or 12 bits/component at any chroma subsampling.
|
||||
*/
|
||||
uint8_t profile;
|
||||
/**
|
||||
* Maximum dimensions for this stream. In non-scalable streams, these
|
||||
* are often the actual dimensions of the stream, although that is not
|
||||
* a normative requirement.
|
||||
*/
|
||||
int max_width, max_height;
|
||||
enum Dav1dPixelLayout layout; ///< format of the picture
|
||||
enum Dav1dColorPrimaries pri; ///< color primaries (av1)
|
||||
enum Dav1dTransferCharacteristics trc; ///< transfer characteristics (av1)
|
||||
enum Dav1dMatrixCoefficients mtrx; ///< matrix coefficients (av1)
|
||||
enum Dav1dChromaSamplePosition chr; ///< chroma sample position (av1)
|
||||
/**
|
||||
* 0, 1 and 2 mean 8, 10 or 12 bits/component, respectively. This is not
|
||||
* exactly the same as 'hbd' from the spec; the spec's hbd distinguishes
|
||||
* between 8 (0) and 10-12 (1) bits/component, and another element
|
||||
* (twelve_bit) to distinguish between 10 and 12 bits/component. To get
|
||||
* the spec's hbd, use !!our_hbd, and to get twelve_bit, use hbd == 2.
|
||||
*/
|
||||
uint8_t hbd;
|
||||
/**
|
||||
* Pixel data uses JPEG pixel range ([0,255] for 8bits) instead of
|
||||
* MPEG pixel range ([16,235] for 8bits luma, [16,240] for 8bits chroma).
|
||||
*/
|
||||
uint8_t color_range;
|
||||
|
||||
uint8_t num_operating_points;
|
||||
struct Dav1dSequenceHeaderOperatingPoint {
|
||||
uint8_t major_level, minor_level;
|
||||
uint8_t initial_display_delay;
|
||||
uint16_t idc;
|
||||
uint8_t tier;
|
||||
uint8_t decoder_model_param_present;
|
||||
uint8_t display_model_param_present;
|
||||
} operating_points[DAV1D_MAX_OPERATING_POINTS];
|
||||
|
||||
uint8_t still_picture;
|
||||
uint8_t reduced_still_picture_header;
|
||||
uint8_t timing_info_present;
|
||||
uint32_t num_units_in_tick;
|
||||
uint32_t time_scale;
|
||||
uint8_t equal_picture_interval;
|
||||
uint32_t num_ticks_per_picture;
|
||||
uint8_t decoder_model_info_present;
|
||||
uint8_t encoder_decoder_buffer_delay_length;
|
||||
uint32_t num_units_in_decoding_tick;
|
||||
uint8_t buffer_removal_delay_length;
|
||||
uint8_t frame_presentation_delay_length;
|
||||
uint8_t display_model_info_present;
|
||||
uint8_t width_n_bits, height_n_bits;
|
||||
uint8_t frame_id_numbers_present;
|
||||
uint8_t delta_frame_id_n_bits;
|
||||
uint8_t frame_id_n_bits;
|
||||
uint8_t sb128;
|
||||
uint8_t filter_intra;
|
||||
uint8_t intra_edge_filter;
|
||||
uint8_t inter_intra;
|
||||
uint8_t masked_compound;
|
||||
uint8_t warped_motion;
|
||||
uint8_t dual_filter;
|
||||
uint8_t order_hint;
|
||||
uint8_t jnt_comp;
|
||||
uint8_t ref_frame_mvs;
|
||||
enum Dav1dAdaptiveBoolean screen_content_tools;
|
||||
enum Dav1dAdaptiveBoolean force_integer_mv;
|
||||
uint8_t order_hint_n_bits;
|
||||
uint8_t super_res;
|
||||
uint8_t cdef;
|
||||
uint8_t restoration;
|
||||
uint8_t ss_hor, ss_ver, monochrome;
|
||||
uint8_t color_description_present;
|
||||
uint8_t separate_uv_delta_q;
|
||||
uint8_t film_grain_present;
|
||||
|
||||
// Dav1dSequenceHeaders of the same sequence are required to be
|
||||
// bit-identical until this offset. See 7.5 "Ordering of OBUs":
|
||||
// Within a particular coded video sequence, the contents of
|
||||
// sequence_header_obu must be bit-identical each time the
|
||||
// sequence header appears except for the contents of
|
||||
// operating_parameters_info.
|
||||
struct Dav1dSequenceHeaderOperatingParameterInfo {
|
||||
uint32_t decoder_buffer_delay;
|
||||
uint32_t encoder_buffer_delay;
|
||||
uint8_t low_delay_mode;
|
||||
} operating_parameter_info[DAV1D_MAX_OPERATING_POINTS];
|
||||
} Dav1dSequenceHeader;
|
||||
|
||||
typedef struct Dav1dSegmentationData {
|
||||
int16_t delta_q;
|
||||
int8_t delta_lf_y_v, delta_lf_y_h, delta_lf_u, delta_lf_v;
|
||||
int8_t ref;
|
||||
uint8_t skip;
|
||||
uint8_t globalmv;
|
||||
} Dav1dSegmentationData;
|
||||
|
||||
typedef struct Dav1dSegmentationDataSet {
|
||||
Dav1dSegmentationData d[DAV1D_MAX_SEGMENTS];
|
||||
uint8_t preskip;
|
||||
int8_t last_active_segid;
|
||||
} Dav1dSegmentationDataSet;
|
||||
|
||||
typedef struct Dav1dLoopfilterModeRefDeltas {
|
||||
int8_t mode_delta[2 /* is_zeromv */];
|
||||
int8_t ref_delta[DAV1D_TOTAL_REFS_PER_FRAME];
|
||||
} Dav1dLoopfilterModeRefDeltas;
|
||||
|
||||
typedef struct Dav1dFilmGrainData {
|
||||
unsigned seed;
|
||||
int num_y_points;
|
||||
uint8_t y_points[14][2 /* value, scaling */];
|
||||
int chroma_scaling_from_luma;
|
||||
int num_uv_points[2];
|
||||
uint8_t uv_points[2][10][2 /* value, scaling */];
|
||||
int scaling_shift;
|
||||
int ar_coeff_lag;
|
||||
int8_t ar_coeffs_y[24];
|
||||
int8_t ar_coeffs_uv[2][25 + 3 /* padding for alignment purposes */];
|
||||
uint64_t ar_coeff_shift;
|
||||
int grain_scale_shift;
|
||||
int uv_mult[2];
|
||||
int uv_luma_mult[2];
|
||||
int uv_offset[2];
|
||||
int overlap_flag;
|
||||
int clip_to_restricted_range;
|
||||
} Dav1dFilmGrainData;
|
||||
|
||||
typedef struct Dav1dFrameHeader {
|
||||
struct {
|
||||
Dav1dFilmGrainData data;
|
||||
uint8_t present, update;
|
||||
} film_grain; ///< film grain parameters
|
||||
enum Dav1dFrameType frame_type; ///< type of the picture
|
||||
int width[2 /* { coded_width, superresolution_upscaled_width } */], height;
|
||||
uint8_t frame_offset; ///< frame number
|
||||
uint8_t temporal_id; ///< temporal id of the frame for SVC
|
||||
uint8_t spatial_id; ///< spatial id of the frame for SVC
|
||||
|
||||
uint8_t show_existing_frame;
|
||||
uint8_t existing_frame_idx;
|
||||
uint32_t frame_id;
|
||||
uint32_t frame_presentation_delay;
|
||||
uint8_t show_frame;
|
||||
uint8_t showable_frame;
|
||||
uint8_t error_resilient_mode;
|
||||
uint8_t disable_cdf_update;
|
||||
uint8_t allow_screen_content_tools;
|
||||
uint8_t force_integer_mv;
|
||||
uint8_t frame_size_override;
|
||||
uint8_t primary_ref_frame;
|
||||
uint8_t buffer_removal_time_present;
|
||||
struct Dav1dFrameHeaderOperatingPoint {
|
||||
uint32_t buffer_removal_time;
|
||||
} operating_points[DAV1D_MAX_OPERATING_POINTS];
|
||||
uint8_t refresh_frame_flags;
|
||||
int render_width, render_height;
|
||||
struct {
|
||||
uint8_t width_scale_denominator;
|
||||
uint8_t enabled;
|
||||
} super_res;
|
||||
uint8_t have_render_size;
|
||||
uint8_t allow_intrabc;
|
||||
uint8_t frame_ref_short_signaling;
|
||||
int8_t refidx[DAV1D_REFS_PER_FRAME];
|
||||
uint8_t hp;
|
||||
enum Dav1dFilterMode subpel_filter_mode;
|
||||
uint8_t switchable_motion_mode;
|
||||
uint8_t use_ref_frame_mvs;
|
||||
uint8_t refresh_context;
|
||||
struct {
|
||||
uint8_t uniform;
|
||||
uint8_t n_bytes;
|
||||
uint8_t min_log2_cols, max_log2_cols, log2_cols, cols;
|
||||
uint8_t min_log2_rows, max_log2_rows, log2_rows, rows;
|
||||
uint16_t col_start_sb[DAV1D_MAX_TILE_COLS + 1];
|
||||
uint16_t row_start_sb[DAV1D_MAX_TILE_ROWS + 1];
|
||||
uint16_t update;
|
||||
} tiling;
|
||||
struct {
|
||||
uint8_t yac;
|
||||
int8_t ydc_delta;
|
||||
int8_t udc_delta, uac_delta, vdc_delta, vac_delta;
|
||||
uint8_t qm, qm_y, qm_u, qm_v;
|
||||
} quant;
|
||||
struct {
|
||||
uint8_t enabled, update_map, temporal, update_data;
|
||||
Dav1dSegmentationDataSet seg_data;
|
||||
uint8_t lossless[DAV1D_MAX_SEGMENTS], qidx[DAV1D_MAX_SEGMENTS];
|
||||
} segmentation;
|
||||
struct {
|
||||
struct {
|
||||
uint8_t present;
|
||||
uint8_t res_log2;
|
||||
} q;
|
||||
struct {
|
||||
uint8_t present;
|
||||
uint8_t res_log2;
|
||||
uint8_t multi;
|
||||
} lf;
|
||||
} delta;
|
||||
uint8_t all_lossless;
|
||||
struct {
|
||||
uint8_t level_y[2 /* dir */];
|
||||
uint8_t level_u, level_v;
|
||||
uint8_t mode_ref_delta_enabled;
|
||||
uint8_t mode_ref_delta_update;
|
||||
Dav1dLoopfilterModeRefDeltas mode_ref_deltas;
|
||||
uint8_t sharpness;
|
||||
} loopfilter;
|
||||
struct {
|
||||
uint8_t damping;
|
||||
uint8_t n_bits;
|
||||
uint8_t y_strength[DAV1D_MAX_CDEF_STRENGTHS];
|
||||
uint8_t uv_strength[DAV1D_MAX_CDEF_STRENGTHS];
|
||||
} cdef;
|
||||
struct {
|
||||
enum Dav1dRestorationType type[3 /* plane */];
|
||||
uint8_t unit_size[2 /* y, uv */];
|
||||
} restoration;
|
||||
enum Dav1dTxfmMode txfm_mode;
|
||||
uint8_t switchable_comp_refs;
|
||||
uint8_t skip_mode_allowed, skip_mode_enabled;
|
||||
int8_t skip_mode_refs[2];
|
||||
uint8_t warp_motion;
|
||||
uint8_t reduced_txtp_set;
|
||||
Dav1dWarpedMotionParams gmv[DAV1D_REFS_PER_FRAME];
|
||||
} Dav1dFrameHeader;
|
||||
|
||||
#ifdef __cplusplus
|
||||
} /* extern "C" */
|
||||
#endif
|
||||
|
||||
#endif /* DAV1D_HEADERS_H */
|
||||
36
media/libdav1d/src/include/dav1d/meson.build
Normal file
36
media/libdav1d/src/include/dav1d/meson.build
Normal file
|
|
@ -0,0 +1,36 @@
|
|||
# Copyright © 2019, VideoLAN and dav1d authors
|
||||
# All rights reserved.
|
||||
#
|
||||
# Redistribution and use in source and binary forms, with or without
|
||||
# modification, are permitted provided that the following conditions are met:
|
||||
#
|
||||
# 1. Redistributions of source code must retain the above copyright notice, this
|
||||
# list of conditions and the following disclaimer.
|
||||
#
|
||||
# 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
# this list of conditions and the following disclaimer in the documentation
|
||||
# and/or other materials provided with the distribution.
|
||||
#
|
||||
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
# DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
|
||||
# ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
# (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
# ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
dav1d_api_headers = [
|
||||
'common.h',
|
||||
'data.h',
|
||||
'dav1d.h',
|
||||
'headers.h',
|
||||
'picture.h',
|
||||
'version.h',
|
||||
]
|
||||
|
||||
# install headers
|
||||
install_headers(dav1d_api_headers,
|
||||
subdir : 'dav1d')
|
||||
157
media/libdav1d/src/include/dav1d/picture.h
Normal file
157
media/libdav1d/src/include/dav1d/picture.h
Normal file
|
|
@ -0,0 +1,157 @@
|
|||
/*
|
||||
* Copyright © 2018-2020, VideoLAN and dav1d authors
|
||||
* Copyright © 2018, Two Orioles, LLC
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef DAV1D_PICTURE_H
|
||||
#define DAV1D_PICTURE_H
|
||||
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#include "common.h"
|
||||
#include "headers.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* Number of bytes to align AND pad picture memory buffers by, so that SIMD
|
||||
* implementations can over-read by a few bytes, and use aligned read/write
|
||||
* instructions. */
|
||||
#define DAV1D_PICTURE_ALIGNMENT 64
|
||||
|
||||
typedef struct Dav1dPictureParameters {
|
||||
int w; ///< width (in pixels)
|
||||
int h; ///< height (in pixels)
|
||||
enum Dav1dPixelLayout layout; ///< format of the picture
|
||||
int bpc; ///< bits per pixel component (8 or 10)
|
||||
} Dav1dPictureParameters;
|
||||
|
||||
typedef struct Dav1dPicture {
|
||||
Dav1dSequenceHeader *seq_hdr;
|
||||
Dav1dFrameHeader *frame_hdr;
|
||||
|
||||
/**
|
||||
* Pointers to planar image data (Y is [0], U is [1], V is [2]). The data
|
||||
* should be bytes (for 8 bpc) or words (for 10 bpc). In case of words
|
||||
* containing 10 bpc image data, the pixels should be located in the LSB
|
||||
* bits, so that values range between [0, 1023]; the upper bits should be
|
||||
* zero'ed out.
|
||||
*/
|
||||
void *data[3];
|
||||
|
||||
/**
|
||||
* Number of bytes between 2 lines in data[] for luma [0] or chroma [1].
|
||||
*/
|
||||
ptrdiff_t stride[2];
|
||||
|
||||
Dav1dPictureParameters p;
|
||||
Dav1dDataProps m;
|
||||
|
||||
/**
|
||||
* High Dynamic Range Content Light Level metadata applying to this picture,
|
||||
* as defined in section 5.8.3 and 6.7.3
|
||||
*/
|
||||
Dav1dContentLightLevel *content_light;
|
||||
/**
|
||||
* High Dynamic Range Mastering Display Color Volume metadata applying to
|
||||
* this picture, as defined in section 5.8.4 and 6.7.4
|
||||
*/
|
||||
Dav1dMasteringDisplay *mastering_display;
|
||||
/**
|
||||
* Array of ITU-T T.35 metadata as defined in section 5.8.2 and 6.7.2
|
||||
*/
|
||||
Dav1dITUTT35 *itut_t35;
|
||||
|
||||
/**
|
||||
* Number of ITU-T T35 metadata entries in the array
|
||||
*/
|
||||
size_t n_itut_t35;
|
||||
|
||||
uintptr_t reserved[4]; ///< reserved for future use
|
||||
|
||||
struct Dav1dRef *frame_hdr_ref; ///< Dav1dFrameHeader allocation origin
|
||||
struct Dav1dRef *seq_hdr_ref; ///< Dav1dSequenceHeader allocation origin
|
||||
struct Dav1dRef *content_light_ref; ///< Dav1dContentLightLevel allocation origin
|
||||
struct Dav1dRef *mastering_display_ref; ///< Dav1dMasteringDisplay allocation origin
|
||||
struct Dav1dRef *itut_t35_ref; ///< Dav1dITUTT35 allocation origin
|
||||
uintptr_t reserved_ref[4]; ///< reserved for future use
|
||||
struct Dav1dRef *ref; ///< Frame data allocation origin
|
||||
|
||||
void *allocator_data; ///< pointer managed by the allocator
|
||||
} Dav1dPicture;
|
||||
|
||||
typedef struct Dav1dPicAllocator {
|
||||
void *cookie; ///< custom data to pass to the allocator callbacks.
|
||||
/**
|
||||
* Allocate the picture buffer based on the Dav1dPictureParameters.
|
||||
*
|
||||
* The data[0], data[1] and data[2] must be DAV1D_PICTURE_ALIGNMENT byte
|
||||
* aligned and with a pixel width/height multiple of 128 pixels. Any
|
||||
* allocated memory area should also be padded by DAV1D_PICTURE_ALIGNMENT
|
||||
* bytes.
|
||||
* data[1] and data[2] must share the same stride[1].
|
||||
*
|
||||
* This function will be called on the main thread (the thread which calls
|
||||
* dav1d_get_picture()).
|
||||
*
|
||||
* @param pic The picture to allocate the buffer for. The callback needs to
|
||||
* fill the picture data[0], data[1], data[2], stride[0] and
|
||||
* stride[1].
|
||||
* The allocator can fill the pic allocator_data pointer with
|
||||
* a custom pointer that will be passed to
|
||||
* release_picture_callback().
|
||||
* @param cookie Custom pointer passed to all calls.
|
||||
*
|
||||
* @note No fields other than data, stride and allocator_data must be filled
|
||||
* by this callback.
|
||||
* @return 0 on success. A negative DAV1D_ERR value on error.
|
||||
*/
|
||||
int (*alloc_picture_callback)(Dav1dPicture *pic, void *cookie);
|
||||
/**
|
||||
* Release the picture buffer.
|
||||
*
|
||||
* If frame threading is used, this function may be called by the main
|
||||
* thread (the thread which calls dav1d_get_picture()) or any of the frame
|
||||
* threads and thus must be thread-safe. If frame threading is not used,
|
||||
* this function will only be called on the main thread.
|
||||
*
|
||||
* @param pic The picture that was filled by alloc_picture_callback().
|
||||
* @param cookie Custom pointer passed to all calls.
|
||||
*/
|
||||
void (*release_picture_callback)(Dav1dPicture *pic, void *cookie);
|
||||
} Dav1dPicAllocator;
|
||||
|
||||
/**
|
||||
* Release reference to a picture.
|
||||
*/
|
||||
DAV1D_API void dav1d_picture_unref(Dav1dPicture *p);
|
||||
|
||||
#ifdef __cplusplus
|
||||
} /* extern "C" */
|
||||
#endif
|
||||
|
||||
#endif /* DAV1D_PICTURE_H */
|
||||
50
media/libdav1d/src/include/dav1d/version.h
Normal file
50
media/libdav1d/src/include/dav1d/version.h
Normal file
|
|
@ -0,0 +1,50 @@
|
|||
/*
|
||||
* Copyright © 2019-2024, VideoLAN and dav1d authors
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef DAV1D_VERSION_H
|
||||
#define DAV1D_VERSION_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#define DAV1D_API_VERSION_MAJOR 7
|
||||
#define DAV1D_API_VERSION_MINOR 0
|
||||
#define DAV1D_API_VERSION_PATCH 0
|
||||
|
||||
/**
|
||||
* Extract version components from the value returned by
|
||||
* dav1d_version_int()
|
||||
*/
|
||||
#define DAV1D_API_MAJOR(v) (((v) >> 16) & 0xFF)
|
||||
#define DAV1D_API_MINOR(v) (((v) >> 8) & 0xFF)
|
||||
#define DAV1D_API_PATCH(v) (((v) >> 0) & 0xFF)
|
||||
|
||||
#ifdef __cplusplus
|
||||
} /* extern "C" */
|
||||
#endif
|
||||
|
||||
#endif /* DAV1D_VERSION_H */
|
||||
34
media/libdav1d/src/include/meson.build
Normal file
34
media/libdav1d/src/include/meson.build
Normal file
|
|
@ -0,0 +1,34 @@
|
|||
# Copyright © 2018, VideoLAN and dav1d authors
|
||||
# All rights reserved.
|
||||
#
|
||||
# Redistribution and use in source and binary forms, with or without
|
||||
# modification, are permitted provided that the following conditions are met:
|
||||
#
|
||||
# 1. Redistributions of source code must retain the above copyright notice, this
|
||||
# list of conditions and the following disclaimer.
|
||||
#
|
||||
# 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
# this list of conditions and the following disclaimer in the documentation
|
||||
# and/or other materials provided with the distribution.
|
||||
#
|
||||
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
# DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
|
||||
# ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
# (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
# ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
# Revision file (vcs_version.h) generation
|
||||
dav1d_git_dir = join_paths(dav1d_src_root, '.git')
|
||||
rev_target = vcs_tag(command: [
|
||||
'git', '--git-dir', dav1d_git_dir, 'describe', '--long', '--always'
|
||||
],
|
||||
input: 'vcs_version.h.in',
|
||||
output: 'vcs_version.h'
|
||||
)
|
||||
|
||||
subdir('dav1d')
|
||||
2
media/libdav1d/src/include/vcs_version.h.in
Normal file
2
media/libdav1d/src/include/vcs_version.h.in
Normal file
|
|
@ -0,0 +1,2 @@
|
|||
/* auto-generated, do not edit */
|
||||
#define DAV1D_VERSION "@VCS_TAG@"
|
||||
610
media/libdav1d/src/meson.build
Normal file
610
media/libdav1d/src/meson.build
Normal file
|
|
@ -0,0 +1,610 @@
|
|||
# Copyright © 2018-2024, VideoLAN and dav1d authors
|
||||
# All rights reserved.
|
||||
#
|
||||
# Redistribution and use in source and binary forms, with or without
|
||||
# modification, are permitted provided that the following conditions are met:
|
||||
#
|
||||
# 1. Redistributions of source code must retain the above copyright notice, this
|
||||
# list of conditions and the following disclaimer.
|
||||
#
|
||||
# 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
# this list of conditions and the following disclaimer in the documentation
|
||||
# and/or other materials provided with the distribution.
|
||||
#
|
||||
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
# DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
|
||||
# ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
# (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
# ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
project('dav1d', ['c'],
|
||||
version: '1.5.3',
|
||||
default_options: ['c_std=c99',
|
||||
'warning_level=2',
|
||||
'buildtype=release',
|
||||
'b_ndebug=if-release'],
|
||||
meson_version: '>= 0.49.0')
|
||||
|
||||
dav1d_src_root = meson.current_source_dir()
|
||||
cc = meson.get_compiler('c')
|
||||
|
||||
# Configuratin data for config.h
|
||||
cdata = configuration_data()
|
||||
|
||||
# Configuration data for config.asm
|
||||
cdata_asm = configuration_data()
|
||||
|
||||
# Include directories
|
||||
dav1d_inc_dirs = include_directories(['.', 'include/dav1d', 'include'])
|
||||
|
||||
dav1d_api_version_major = cc.get_define('DAV1D_API_VERSION_MAJOR',
|
||||
prefix: '#include "dav1d/version.h"',
|
||||
include_directories: dav1d_inc_dirs).strip()
|
||||
dav1d_api_version_minor = cc.get_define('DAV1D_API_VERSION_MINOR',
|
||||
prefix: '#include "dav1d/version.h"',
|
||||
include_directories: dav1d_inc_dirs).strip()
|
||||
dav1d_api_version_revision = cc.get_define('DAV1D_API_VERSION_PATCH',
|
||||
prefix: '#include "dav1d/version.h"',
|
||||
include_directories: dav1d_inc_dirs).strip()
|
||||
dav1d_soname_version = '@0@.@1@.@2@'.format(dav1d_api_version_major,
|
||||
dav1d_api_version_minor,
|
||||
dav1d_api_version_revision)
|
||||
|
||||
#
|
||||
# Option handling
|
||||
#
|
||||
|
||||
# Bitdepth option
|
||||
dav1d_bitdepths = get_option('bitdepths')
|
||||
foreach bitdepth : ['8', '16']
|
||||
cdata.set10('CONFIG_@0@BPC'.format(bitdepth), dav1d_bitdepths.contains(bitdepth))
|
||||
endforeach
|
||||
|
||||
# ASM option
|
||||
is_asm_enabled = (get_option('enable_asm') == true and
|
||||
(host_machine.cpu_family() == 'aarch64' or
|
||||
host_machine.cpu_family().startswith('arm') or
|
||||
host_machine.cpu() == 'ppc64le' or
|
||||
host_machine.cpu_family().startswith('riscv') or
|
||||
host_machine.cpu_family().startswith('loongarch') or
|
||||
host_machine.cpu_family() == 'x86' or
|
||||
(host_machine.cpu_family() == 'x86_64' and cc.get_define('__ILP32__').strip() == '')))
|
||||
cdata.set10('HAVE_ASM', is_asm_enabled)
|
||||
|
||||
if is_asm_enabled and get_option('b_sanitize') == 'memory'
|
||||
error('asm causes false positive with memory sanitizer. Use \'-Denable_asm=false\'.')
|
||||
endif
|
||||
|
||||
cdata.set10('TRIM_DSP_FUNCTIONS', get_option('trim_dsp') == 'true' or
|
||||
(get_option('trim_dsp') == 'if-release' and get_option('buildtype') == 'release'))
|
||||
|
||||
# Logging option
|
||||
cdata.set10('CONFIG_LOG', get_option('logging'))
|
||||
|
||||
cdata.set10('CONFIG_MACOS_KPERF', get_option('macos_kperf'))
|
||||
|
||||
#
|
||||
# OS/Compiler checks and defines
|
||||
#
|
||||
|
||||
# Arguments in test_args will be used even on feature tests
|
||||
test_args = []
|
||||
|
||||
optional_arguments = []
|
||||
optional_link_arguments = []
|
||||
|
||||
if host_machine.system() in ['linux', 'gnu', 'emscripten']
|
||||
test_args += '-D_GNU_SOURCE'
|
||||
add_project_arguments('-D_GNU_SOURCE', language: 'c')
|
||||
endif
|
||||
|
||||
have_clock_gettime = false
|
||||
have_posix_memalign = false
|
||||
have_memalign = false
|
||||
have_aligned_alloc = false
|
||||
if host_machine.system() == 'windows'
|
||||
cdata.set('_WIN32_WINNT', '0x0601')
|
||||
cdata.set('UNICODE', 1) # Define to 1 for Unicode (Wide Chars) APIs
|
||||
cdata.set('_UNICODE', 1) # Define to 1 for Unicode (Wide Chars) APIs
|
||||
cdata.set('__USE_MINGW_ANSI_STDIO', 1) # Define to force use of MinGW printf
|
||||
cdata.set('_CRT_DECLARE_NONSTDC_NAMES', 1) # Define to get off_t from sys/types.h on MSVC
|
||||
if cc.has_function('fseeko', prefix : '#include <stdio.h>', args : test_args)
|
||||
cdata.set('_FILE_OFFSET_BITS', 64) # Not set by default by Meson on Windows
|
||||
else
|
||||
cdata.set('fseeko', '_fseeki64')
|
||||
cdata.set('ftello', '_ftelli64')
|
||||
endif
|
||||
|
||||
if host_machine.cpu_family() == 'x86_64'
|
||||
if cc.get_argument_syntax() != 'msvc'
|
||||
optional_link_arguments += '-Wl,--dynamicbase,--nxcompat,--tsaware,--high-entropy-va'
|
||||
endif
|
||||
elif host_machine.cpu_family() == 'x86' or host_machine.cpu_family() == 'arm'
|
||||
if cc.get_argument_syntax() == 'msvc'
|
||||
optional_link_arguments += '/largeaddressaware'
|
||||
else
|
||||
optional_link_arguments += '-Wl,--dynamicbase,--nxcompat,--tsaware,--large-address-aware'
|
||||
endif
|
||||
endif
|
||||
|
||||
# On Windows, we use a compatibility layer to emulate pthread
|
||||
thread_dependency = []
|
||||
thread_compat_dep = declare_dependency(sources : files('src/win32/thread.c'))
|
||||
|
||||
rt_dependency = []
|
||||
|
||||
rc_version_array = meson.project_version().split('.')
|
||||
winmod = import('windows')
|
||||
rc_data = configuration_data()
|
||||
rc_data.set('PROJECT_VERSION_MAJOR', rc_version_array[0])
|
||||
rc_data.set('PROJECT_VERSION_MINOR', rc_version_array[1])
|
||||
rc_data.set('PROJECT_VERSION_REVISION', rc_version_array[2])
|
||||
rc_data.set('API_VERSION_MAJOR', dav1d_api_version_major)
|
||||
rc_data.set('API_VERSION_MINOR', dav1d_api_version_minor)
|
||||
rc_data.set('API_VERSION_REVISION', dav1d_api_version_revision)
|
||||
rc_data.set('COPYRIGHT_YEARS', '2018-2025')
|
||||
else
|
||||
thread_dependency = dependency('threads')
|
||||
thread_compat_dep = []
|
||||
|
||||
rt_dependency = []
|
||||
if cc.has_function('clock_gettime', prefix : '#include <time.h>', args : test_args)
|
||||
have_clock_gettime = true
|
||||
elif host_machine.system() not in ['darwin', 'ios', 'tvos']
|
||||
rt_dependency = cc.find_library('rt', required: false)
|
||||
if not cc.has_function('clock_gettime', prefix : '#include <time.h>', args : test_args, dependencies : rt_dependency)
|
||||
error('clock_gettime not found')
|
||||
endif
|
||||
have_clock_gettime = true
|
||||
endif
|
||||
|
||||
have_posix_memalign = cc.has_function('posix_memalign', prefix : '#include <stdlib.h>', args : test_args)
|
||||
have_memalign = cc.has_function('memalign', prefix : '#include <malloc.h>', args : test_args)
|
||||
have_aligned_alloc = cc.has_function('aligned_alloc', prefix : '#include <stdlib.h>', args : test_args)
|
||||
endif
|
||||
|
||||
cdata.set10('HAVE_CLOCK_GETTIME', have_clock_gettime)
|
||||
cdata.set10('HAVE_POSIX_MEMALIGN', have_posix_memalign)
|
||||
cdata.set10('HAVE_MEMALIGN', have_memalign)
|
||||
cdata.set10('HAVE_ALIGNED_ALLOC', have_aligned_alloc)
|
||||
|
||||
# check for fseeko on android. It is not always available if _FILE_OFFSET_BITS is defined to 64
|
||||
have_fseeko = true
|
||||
if host_machine.system() == 'android'
|
||||
if not cc.has_function('fseeko', prefix : '#include <stdio.h>', args : test_args)
|
||||
if cc.has_function('fseeko', prefix : '#include <stdio.h>', args : test_args + ['-U_FILE_OFFSET_BITS'])
|
||||
warning('Files larger than 2 gigabytes might not be supported in the dav1d CLI tool.')
|
||||
add_project_arguments('-U_FILE_OFFSET_BITS', language: 'c')
|
||||
elif get_option('enable_tools')
|
||||
error('dav1d CLI tool needs fseeko()')
|
||||
else
|
||||
have_fseeko = false
|
||||
endif
|
||||
endif
|
||||
endif
|
||||
|
||||
libdl_dependency = []
|
||||
have_dlsym = false
|
||||
if host_machine.system() == 'linux'
|
||||
libdl_dependency = cc.find_library('dl', required : false)
|
||||
have_dlsym = cc.has_function('dlsym', prefix : '#include <dlfcn.h>', args : test_args, dependencies : libdl_dependency)
|
||||
endif
|
||||
cdata.set10('HAVE_DLSYM', have_dlsym)
|
||||
|
||||
libm_dependency = cc.find_library('m', required: false)
|
||||
|
||||
|
||||
# Header checks
|
||||
|
||||
stdatomic_dependencies = []
|
||||
if not cc.check_header('stdatomic.h')
|
||||
if cc.get_id() == 'msvc'
|
||||
# we have a custom replacement for MSVC
|
||||
stdatomic_dependencies += declare_dependency(
|
||||
include_directories : include_directories('include/compat/msvc'),
|
||||
)
|
||||
elif cc.compiles('''int main() { int v = 0; return __atomic_fetch_add(&v, 1, __ATOMIC_SEQ_CST); }''',
|
||||
name : 'GCC-style atomics', args : test_args)
|
||||
stdatomic_dependencies += declare_dependency(
|
||||
include_directories : include_directories('include/compat/gcc'),
|
||||
)
|
||||
else
|
||||
error('Atomics not supported')
|
||||
endif
|
||||
endif
|
||||
|
||||
if host_machine.cpu_family().startswith('wasm')
|
||||
# enable atomics + bulk-memory features
|
||||
stdatomic_dependencies += thread_dependency.partial_dependency(compile_args: true)
|
||||
endif
|
||||
|
||||
cdata.set10('HAVE_SYS_TYPES_H', cc.check_header('sys/types.h'))
|
||||
cdata.set10('HAVE_UNISTD_H', cc.check_header('unistd.h'))
|
||||
cdata.set10('HAVE_IO_H', cc.check_header('io.h'))
|
||||
|
||||
have_pthread_np = cc.check_header('pthread_np.h')
|
||||
cdata.set10('HAVE_PTHREAD_NP_H', have_pthread_np)
|
||||
test_args += '-DHAVE_PTHREAD_NP_H=' + (have_pthread_np ? '1' : '0')
|
||||
|
||||
# Function checks
|
||||
|
||||
if not cc.has_function('getopt_long', prefix : '#include <getopt.h>', args : test_args)
|
||||
getopt_dependency = declare_dependency(
|
||||
sources: files('tools/compat/getopt.c'),
|
||||
include_directories : include_directories('include/compat'),
|
||||
)
|
||||
else
|
||||
getopt_dependency = []
|
||||
endif
|
||||
|
||||
have_getauxval = false
|
||||
have_elf_aux_info = false
|
||||
if (host_machine.cpu_family() == 'aarch64' or
|
||||
host_machine.cpu_family().startswith('arm') or
|
||||
host_machine.cpu_family().startswith('loongarch') or
|
||||
host_machine.cpu() == 'ppc64le' or
|
||||
host_machine.cpu_family().startswith('riscv'))
|
||||
have_getauxval = cc.has_function('getauxval', prefix : '#include <sys/auxv.h>', args : test_args)
|
||||
have_elf_aux_info = cc.has_function('elf_aux_info', prefix : '#include <sys/auxv.h>', args : test_args)
|
||||
endif
|
||||
|
||||
cdata.set10('HAVE_GETAUXVAL', have_getauxval)
|
||||
cdata.set10('HAVE_ELF_AUX_INFO', have_elf_aux_info)
|
||||
|
||||
pthread_np_prefix = '''
|
||||
#include <pthread.h>
|
||||
#if HAVE_PTHREAD_NP_H
|
||||
#include <pthread_np.h>
|
||||
#endif
|
||||
'''
|
||||
cdata.set10('HAVE_PTHREAD_GETAFFINITY_NP', cc.has_function('pthread_getaffinity_np', prefix : pthread_np_prefix, args : test_args, dependencies : thread_dependency))
|
||||
cdata.set10('HAVE_PTHREAD_SETAFFINITY_NP', cc.has_function('pthread_setaffinity_np', prefix : pthread_np_prefix, args : test_args, dependencies : thread_dependency))
|
||||
cdata.set10('HAVE_PTHREAD_SETNAME_NP', cc.has_function('pthread_setname_np', prefix : pthread_np_prefix, args : test_args, dependencies : thread_dependency))
|
||||
cdata.set10('HAVE_PTHREAD_SET_NAME_NP', cc.has_function('pthread_set_name_np', prefix : pthread_np_prefix, args : test_args, dependencies : thread_dependency))
|
||||
|
||||
cdata.set10('HAVE_C11_GENERIC', cc.compiles('int x = _Generic(0, default: 0);', name: '_Generic', args: test_args))
|
||||
|
||||
# Compiler flag tests
|
||||
|
||||
if cc.has_argument('-fvisibility=hidden')
|
||||
add_project_arguments('-fvisibility=hidden', language: 'c')
|
||||
else
|
||||
warning('Compiler does not support -fvisibility=hidden, all symbols will be public!')
|
||||
endif
|
||||
|
||||
# Compiler flags that should be set
|
||||
# But when the compiler does not supports them
|
||||
# it is not an error and silently tolerated
|
||||
if cc.get_argument_syntax() != 'msvc'
|
||||
optional_arguments += [
|
||||
'-Wundef',
|
||||
'-Werror=vla',
|
||||
'-Wno-maybe-uninitialized',
|
||||
'-Wno-missing-field-initializers',
|
||||
'-Wno-unused-parameter',
|
||||
'-Wstrict-prototypes',
|
||||
'-Werror=missing-prototypes',
|
||||
'-Wshorten-64-to-32',
|
||||
]
|
||||
if host_machine.cpu_family() == 'x86'
|
||||
optional_arguments += [
|
||||
'-msse2',
|
||||
'-mfpmath=sse',
|
||||
]
|
||||
endif
|
||||
else
|
||||
optional_arguments += [
|
||||
'-wd4028', # parameter different from declaration
|
||||
'-wd4090', # broken with arrays of pointers
|
||||
'-wd4996' # use of POSIX functions
|
||||
]
|
||||
endif
|
||||
|
||||
if (get_option('buildtype') != 'debug' and get_option('buildtype') != 'plain')
|
||||
optional_arguments += '-fomit-frame-pointer'
|
||||
optional_arguments += '-ffast-math'
|
||||
endif
|
||||
|
||||
if (host_machine.system() in ['darwin', 'ios', 'tvos'] and cc.get_id() == 'clang' and
|
||||
cc.version().startswith('11'))
|
||||
# Workaround for Xcode 11 -fstack-check bug, see #301
|
||||
optional_arguments += '-fno-stack-check'
|
||||
endif
|
||||
|
||||
if (host_machine.cpu_family() == 'aarch64' or host_machine.cpu_family().startswith('arm'))
|
||||
optional_arguments += '-fno-align-functions'
|
||||
endif
|
||||
|
||||
add_project_arguments(cc.get_supported_arguments(optional_arguments), language : 'c')
|
||||
add_project_link_arguments(cc.get_supported_link_arguments(optional_link_arguments), language : 'c')
|
||||
|
||||
# libFuzzer related things
|
||||
fuzzing_engine = get_option('fuzzing_engine')
|
||||
if fuzzing_engine == 'libfuzzer'
|
||||
if not cc.has_argument('-fsanitize=fuzzer')
|
||||
error('fuzzing_engine libfuzzer requires "-fsanitize=fuzzer"')
|
||||
endif
|
||||
fuzzer_args = ['-fsanitize=fuzzer-no-link', '-fsanitize=fuzzer']
|
||||
add_project_arguments(cc.first_supported_argument(fuzzer_args), language : 'c')
|
||||
endif
|
||||
|
||||
cdata.set10('ENDIANNESS_BIG', host_machine.endian() == 'big')
|
||||
|
||||
if host_machine.cpu_family().startswith('x86')
|
||||
if get_option('stack_alignment') > 0
|
||||
stack_alignment = get_option('stack_alignment')
|
||||
elif host_machine.cpu_family() == 'x86_64' or host_machine.system() in ['linux', 'darwin', 'ios', 'tvos']
|
||||
stack_alignment = 16
|
||||
else
|
||||
stack_alignment = 4
|
||||
endif
|
||||
cdata_asm.set('STACK_ALIGNMENT', stack_alignment)
|
||||
endif
|
||||
|
||||
#
|
||||
# ASM specific stuff
|
||||
#
|
||||
|
||||
use_gaspp = false
|
||||
if (is_asm_enabled and
|
||||
(host_machine.cpu_family() == 'aarch64' or
|
||||
host_machine.cpu_family().startswith('arm')) and
|
||||
cc.get_argument_syntax() == 'msvc' and
|
||||
(cc.get_id() != 'clang-cl' or meson.version().version_compare('<0.58.0')))
|
||||
gaspp = find_program('gas-preprocessor.pl')
|
||||
use_gaspp = true
|
||||
gaspp_args = [
|
||||
'-as-type', 'armasm',
|
||||
'-arch', host_machine.cpu_family(),
|
||||
'--',
|
||||
host_machine.cpu_family() == 'aarch64' ? 'armasm64' : 'armasm',
|
||||
'-nologo',
|
||||
'-I@0@'.format(dav1d_src_root),
|
||||
'-I@0@/'.format(meson.current_build_dir()),
|
||||
]
|
||||
gaspp_gen = generator(gaspp,
|
||||
output: '@BASENAME@.obj',
|
||||
arguments: gaspp_args + [
|
||||
'@INPUT@',
|
||||
'-c',
|
||||
'-o', '@OUTPUT@'
|
||||
])
|
||||
endif
|
||||
|
||||
cdata.set10('ARCH_AARCH64', host_machine.cpu_family() == 'aarch64' or host_machine.cpu() == 'arm64')
|
||||
cdata.set10('ARCH_ARM', host_machine.cpu_family().startswith('arm') and host_machine.cpu() != 'arm64')
|
||||
|
||||
have_as_func = false
|
||||
have_as_arch = false
|
||||
aarch64_extensions = {
|
||||
'dotprod': 'udot v0.4s, v0.16b, v0.16b',
|
||||
'i8mm': 'usdot v0.4s, v0.16b, v0.16b',
|
||||
'sve': 'whilelt p0.s, x0, x1',
|
||||
'sve2': 'sqrdmulh z0.s, z0.s, z0.s',
|
||||
}
|
||||
supported_aarch64_archexts = []
|
||||
supported_aarch64_instructions = []
|
||||
if (is_asm_enabled and
|
||||
(host_machine.cpu_family() == 'aarch64' or
|
||||
host_machine.cpu_family().startswith('arm')))
|
||||
|
||||
as_func_code = '''__asm__ (
|
||||
".func meson_test"
|
||||
".endfunc"
|
||||
);
|
||||
'''
|
||||
have_as_func = cc.compiles(as_func_code)
|
||||
|
||||
# fedora package build infrastructure uses a gcc specs file to enable
|
||||
# '-fPIE' by default. The chosen way only adds '-fPIE' to the C compiler
|
||||
# with integrated preprocessor. It is not added to the standalone
|
||||
# preprocessor or the preprocessing stage of '.S' files. So we have to
|
||||
# compile code to check if we have to define PIC for the arm asm to
|
||||
# avoid absolute relocations when building for example checkasm.
|
||||
check_pic_code = '''
|
||||
#if defined(PIC)
|
||||
#error "PIC already defined"
|
||||
#elif !(defined(__PIC__) || defined(__pic__))
|
||||
#error "no pic"
|
||||
#endif
|
||||
'''
|
||||
if cc.compiles(check_pic_code)
|
||||
cdata.set('PIC', '3')
|
||||
endif
|
||||
|
||||
if host_machine.cpu_family() == 'aarch64'
|
||||
have_as_arch = cc.compiles('''__asm__ (".arch armv8-a");''')
|
||||
as_arch_str = ''
|
||||
if have_as_arch
|
||||
as_arch_level = 'armv8-a'
|
||||
# Check what .arch levels are supported. In principle, we only
|
||||
# want to detect up to armv8.2-a here (binutils requires that
|
||||
# in order to enable i8mm). However, older Clang versions
|
||||
# (before Clang 17, and Xcode versions up to and including 15.0)
|
||||
# didn't support controlling dotprod/i8mm extensions via
|
||||
# .arch_extension, therefore try to enable a high enough .arch
|
||||
# level as well, to implicitly make them available via that.
|
||||
foreach arch : ['armv8.2-a', 'armv8.4-a', 'armv8.6-a']
|
||||
if cc.compiles('__asm__ (".arch ' + arch + '\\n");')
|
||||
as_arch_level = arch
|
||||
endif
|
||||
endforeach
|
||||
# Clang versions before 17 also had a bug
|
||||
# (https://github.com/llvm/llvm-project/issues/32220)
|
||||
# causing a plain ".arch <level>" to not have any effect unless it
|
||||
# had an extra "+<feature>" included - but it was activated on the
|
||||
# next ".arch_extension" directive instead. Check if we can include
|
||||
# "+crc" as dummy feature to make the .arch directive behave as
|
||||
# expected and take effect right away.
|
||||
if cc.compiles('__asm__ (".arch ' + as_arch_level + '+crc\\n");')
|
||||
as_arch_level = as_arch_level + '+crc'
|
||||
endif
|
||||
cdata.set('AS_ARCH_LEVEL', as_arch_level)
|
||||
as_arch_str = '".arch ' + as_arch_level + '\\n"'
|
||||
endif
|
||||
if use_gaspp
|
||||
python3 = import('python').find_installation()
|
||||
endif
|
||||
foreach name, instr : aarch64_extensions
|
||||
if use_gaspp
|
||||
f = configure_file(
|
||||
command: [python3, '-c', 'import sys; print(sys.argv[1])', '@0@'.format(instr)],
|
||||
output: 'test-@0@.S'.format(name),
|
||||
capture: true)
|
||||
r = run_command(gaspp, gaspp_args, f, '-c', '-o', meson.current_build_dir() / 'test-' + name + '.obj', check: false)
|
||||
message('Checking for gaspp/armasm64 ' + name.to_upper() + ': ' + (r.returncode() == 0 ? 'YES' : 'NO'))
|
||||
if r.returncode() == 0
|
||||
supported_aarch64_instructions += name
|
||||
endif
|
||||
else
|
||||
# Test for support for the various extensions. First test if
|
||||
# the assembler supports the .arch_extension directive for
|
||||
# enabling/disabling the extension, then separately check whether
|
||||
# the instructions themselves are supported. Even if .arch_extension
|
||||
# isn't supported, we may be able to assemble the instructions
|
||||
# if the .arch level includes support for them.
|
||||
code = '__asm__ (' + as_arch_str
|
||||
code += '".arch_extension ' + name + '\\n"'
|
||||
code += ');'
|
||||
supports_archext = cc.compiles(code)
|
||||
code = '__asm__ (' + as_arch_str
|
||||
if supports_archext
|
||||
supported_aarch64_archexts += name
|
||||
code += '".arch_extension ' + name + '\\n"'
|
||||
endif
|
||||
code += '"' + instr + '\\n"'
|
||||
code += ');'
|
||||
if cc.compiles(code, name: name.to_upper())
|
||||
supported_aarch64_instructions += name
|
||||
endif
|
||||
endif
|
||||
endforeach
|
||||
endif
|
||||
endif
|
||||
|
||||
cdata.set10('HAVE_AS_FUNC', have_as_func)
|
||||
cdata.set10('HAVE_AS_ARCH_DIRECTIVE', have_as_arch)
|
||||
foreach name, _ : aarch64_extensions
|
||||
cdata.set10('HAVE_AS_ARCHEXT_' + name.to_upper() + '_DIRECTIVE', name in supported_aarch64_archexts)
|
||||
cdata.set10('HAVE_' + name.to_upper(), name in supported_aarch64_instructions)
|
||||
endforeach
|
||||
|
||||
cdata.set10('ARCH_X86', host_machine.cpu_family().startswith('x86'))
|
||||
cdata.set10('ARCH_X86_64', host_machine.cpu_family() == 'x86_64')
|
||||
cdata.set10('ARCH_X86_32', host_machine.cpu_family() == 'x86')
|
||||
|
||||
if host_machine.cpu_family().startswith('x86')
|
||||
cdata_asm.set('private_prefix', 'dav1d')
|
||||
cdata_asm.set10('ARCH_X86_64', host_machine.cpu_family() == 'x86_64')
|
||||
cdata_asm.set10('ARCH_X86_32', host_machine.cpu_family() == 'x86')
|
||||
cdata_asm.set10('PIC', true)
|
||||
|
||||
# Convert SSE asm into (128-bit) AVX when compiler flags are set to use AVX instructions
|
||||
cdata_asm.set10('FORCE_VEX_ENCODING', cc.get_define('__AVX__').strip() != '')
|
||||
endif
|
||||
|
||||
cdata.set10('ARCH_PPC64LE', host_machine.cpu() == 'ppc64le')
|
||||
|
||||
cdata.set10('ARCH_RISCV', host_machine.cpu_family().startswith('riscv'))
|
||||
cdata.set10('ARCH_RV32', host_machine.cpu_family() == 'riscv32')
|
||||
cdata.set10('ARCH_RV64', host_machine.cpu_family() == 'riscv64')
|
||||
|
||||
cdata.set10('ARCH_LOONGARCH', host_machine.cpu_family().startswith('loongarch'))
|
||||
cdata.set10('ARCH_LOONGARCH32', host_machine.cpu_family() == 'loongarch32')
|
||||
cdata.set10('ARCH_LOONGARCH64', host_machine.cpu_family() == 'loongarch64')
|
||||
|
||||
# meson's cc.symbols_have_underscore_prefix() is unfortunately unrelieably
|
||||
# when additional flags like '-fprofile-instr-generate' are passed via CFLAGS
|
||||
# see following meson issue https://github.com/mesonbuild/meson/issues/5482
|
||||
if (host_machine.system() in ['darwin', 'ios', 'tvos'] or
|
||||
(host_machine.system() == 'windows' and host_machine.cpu_family() == 'x86'))
|
||||
cdata.set10('PREFIX', true)
|
||||
cdata_asm.set10('PREFIX', true)
|
||||
endif
|
||||
|
||||
if is_asm_enabled and host_machine.cpu_family().startswith('x86')
|
||||
|
||||
# NASM compiler support
|
||||
|
||||
nasm = find_program('nasm')
|
||||
|
||||
# check NASM version
|
||||
if nasm.found()
|
||||
nasm_r = run_command(nasm, '-v', check: true)
|
||||
|
||||
out = nasm_r.stdout().strip().split()
|
||||
if out[1].to_lower() == 'version'
|
||||
if out[2].version_compare('<2.14')
|
||||
error('nasm 2.14 or later is required, found nasm @0@'.format(out[2]))
|
||||
endif
|
||||
else
|
||||
error('unexpected nasm version string: @0@'.format(nasm_r.stdout()))
|
||||
endif
|
||||
endif
|
||||
|
||||
# Generate config.asm
|
||||
config_asm_target = configure_file(output: 'config.asm', output_format: 'nasm', configuration: cdata_asm)
|
||||
|
||||
if host_machine.system() == 'windows'
|
||||
nasm_format = 'win'
|
||||
elif host_machine.system() in ['darwin', 'ios', 'tvos']
|
||||
nasm_format = 'macho'
|
||||
else
|
||||
nasm_format = 'elf'
|
||||
endif
|
||||
if host_machine.cpu_family() == 'x86_64'
|
||||
nasm_format += '64'
|
||||
else
|
||||
nasm_format += '32'
|
||||
endif
|
||||
|
||||
nasm_gen = generator(nasm,
|
||||
output: '@BASENAME@.obj',
|
||||
depfile: '@BASENAME@.obj.ndep',
|
||||
arguments: [
|
||||
'-f', nasm_format,
|
||||
'-I', '@0@/src/'.format(dav1d_src_root),
|
||||
'-I', '@0@/'.format(meson.current_build_dir()),
|
||||
'-MQ', '@OUTPUT@', '-MF', '@DEPFILE@',
|
||||
'@EXTRA_ARGS@',
|
||||
'@INPUT@',
|
||||
'-o', '@OUTPUT@'
|
||||
])
|
||||
endif
|
||||
|
||||
if is_asm_enabled and host_machine.cpu_family().startswith('riscv')
|
||||
as_option_code = '''__asm__ (
|
||||
".option arch, +v\n"
|
||||
"vsetivli zero, 0, e8, m1, ta, ma"
|
||||
);
|
||||
'''
|
||||
if not cc.compiles(as_option_code, name : 'RISC-V Vector')
|
||||
error('Compiler doesn\'t support \'.option arch\' asm directive. Update to binutils>=2.38 or clang>=17 or use \'-Denable_asm=false\'.')
|
||||
endif
|
||||
endif
|
||||
|
||||
# Generate config.h
|
||||
config_h_target = configure_file(output: 'config.h', configuration: cdata)
|
||||
|
||||
|
||||
|
||||
#
|
||||
# Include subdir meson.build files
|
||||
# The order is important!
|
||||
|
||||
subdir('include')
|
||||
|
||||
subdir('doc')
|
||||
|
||||
subdir('src')
|
||||
|
||||
subdir('tools')
|
||||
|
||||
subdir('examples')
|
||||
|
||||
subdir('tests')
|
||||
75
media/libdav1d/src/meson_options.txt
Normal file
75
media/libdav1d/src/meson_options.txt
Normal file
|
|
@ -0,0 +1,75 @@
|
|||
# General options
|
||||
|
||||
option('bitdepths',
|
||||
type: 'array',
|
||||
choices: ['8', '16'],
|
||||
description: 'Enable only specified bitdepths')
|
||||
|
||||
option('enable_asm',
|
||||
type: 'boolean',
|
||||
value: true,
|
||||
description: 'Build asm files, if available')
|
||||
|
||||
option('enable_tools',
|
||||
type: 'boolean',
|
||||
value: true,
|
||||
description: 'Build dav1d cli tools')
|
||||
|
||||
option('enable_examples',
|
||||
type: 'boolean',
|
||||
value: false,
|
||||
description: 'Build dav1d examples')
|
||||
|
||||
option('enable_tests',
|
||||
type: 'boolean',
|
||||
value: true,
|
||||
description: 'Build dav1d tests')
|
||||
|
||||
option('enable_seek_stress',
|
||||
type: 'boolean',
|
||||
value: false,
|
||||
description: 'Build seek_stress test tool')
|
||||
|
||||
option('enable_docs',
|
||||
type: 'boolean',
|
||||
value: false,
|
||||
description: 'Build dav1d documentation')
|
||||
|
||||
option('logging',
|
||||
type: 'boolean',
|
||||
value: true,
|
||||
description: 'Print error log messages using the provided callback function')
|
||||
|
||||
option('testdata_tests',
|
||||
type: 'boolean',
|
||||
value: false,
|
||||
description: 'Run tests requiring the test data repository')
|
||||
|
||||
option('fuzzing_engine',
|
||||
type: 'combo',
|
||||
choices : ['none', 'libfuzzer', 'oss-fuzz'],
|
||||
value: 'none',
|
||||
description: 'Select the fuzzing engine')
|
||||
|
||||
option('fuzzer_ldflags',
|
||||
type: 'string',
|
||||
description: 'Extra LDFLAGS used during linking of fuzzing binaries')
|
||||
|
||||
option('stack_alignment',
|
||||
type: 'integer',
|
||||
value: 0)
|
||||
|
||||
option('xxhash_muxer',
|
||||
type : 'feature',
|
||||
value : 'auto')
|
||||
|
||||
option('trim_dsp',
|
||||
type: 'combo',
|
||||
choices: ['true', 'false', 'if-release'],
|
||||
value: 'if-release',
|
||||
description: 'Eliminate redundant DSP functions where possible')
|
||||
|
||||
option('macos_kperf',
|
||||
type: 'boolean',
|
||||
value: false,
|
||||
description: 'Use the private macOS kperf API for benchmarking')
|
||||
15
media/libdav1d/src/package/crossfiles/aarch64-android.meson
Normal file
15
media/libdav1d/src/package/crossfiles/aarch64-android.meson
Normal file
|
|
@ -0,0 +1,15 @@
|
|||
[binaries]
|
||||
c = 'aarch64-linux-android21-clang'
|
||||
cpp = 'aarch64-linux-android21-clang++'
|
||||
ar = 'llvm-ar'
|
||||
strip = 'llvm-strip'
|
||||
pkgconfig = 'pkg-config'
|
||||
|
||||
[properties]
|
||||
needs_exe_wrapper = true
|
||||
|
||||
[host_machine]
|
||||
system = 'android'
|
||||
cpu_family = 'aarch64'
|
||||
cpu = 'aarch64'
|
||||
endian = 'little'
|
||||
|
|
@ -0,0 +1,16 @@
|
|||
[binaries]
|
||||
c = 'clang'
|
||||
cpp = 'clang++'
|
||||
ar = 'aarch64-linux-gnu-ar'
|
||||
strip = 'aarch64-linux-gnu-strip'
|
||||
exe_wrapper = 'qemu-aarch64'
|
||||
|
||||
[properties]
|
||||
c_args = '-target aarch64-linux-gnu'
|
||||
c_link_args = '-target aarch64-linux-gnu'
|
||||
|
||||
[host_machine]
|
||||
system = 'linux'
|
||||
cpu_family = 'aarch64'
|
||||
cpu = 'aarch64'
|
||||
endian = 'little'
|
||||
12
media/libdav1d/src/package/crossfiles/aarch64-linux.meson
Normal file
12
media/libdav1d/src/package/crossfiles/aarch64-linux.meson
Normal file
|
|
@ -0,0 +1,12 @@
|
|||
[binaries]
|
||||
c = 'aarch64-linux-gnu-gcc'
|
||||
cpp = 'aarch64-linux-gnu-g++'
|
||||
ar = 'aarch64-linux-gnu-ar'
|
||||
strip = 'aarch64-linux-gnu-strip'
|
||||
exe_wrapper = 'qemu-aarch64'
|
||||
|
||||
[host_machine]
|
||||
system = 'linux'
|
||||
cpu_family = 'aarch64'
|
||||
cpu = 'aarch64'
|
||||
endian = 'little'
|
||||
|
|
@ -0,0 +1,16 @@
|
|||
[binaries]
|
||||
c = 'aarch64-w64-mingw32-clang'
|
||||
cpp = 'aarch64-w64-mingw32-clang++'
|
||||
ar = 'aarch64-w64-mingw32-ar'
|
||||
strip = 'aarch64-w64-mingw32-strip'
|
||||
pkgconfig = 'pkg-config'
|
||||
windres = 'aarch64-w64-mingw32-windres'
|
||||
|
||||
[properties]
|
||||
c_link_args = ['-static-libgcc']
|
||||
|
||||
[host_machine]
|
||||
system = 'windows'
|
||||
cpu_family = 'aarch64'
|
||||
cpu = 'aarch64'
|
||||
endian = 'little'
|
||||
15
media/libdav1d/src/package/crossfiles/arm-android.meson
Normal file
15
media/libdav1d/src/package/crossfiles/arm-android.meson
Normal file
|
|
@ -0,0 +1,15 @@
|
|||
[binaries]
|
||||
c = 'armv7a-linux-androideabi21-clang'
|
||||
cpp = 'armv7a-linux-androideabi21-clang++'
|
||||
ar = 'llvm-ar'
|
||||
strip = 'llvm-strip'
|
||||
pkgconfig = 'pkg-config'
|
||||
|
||||
[properties]
|
||||
needs_exe_wrapper = true
|
||||
|
||||
[host_machine]
|
||||
system = 'android'
|
||||
cpu_family = 'arm'
|
||||
cpu = 'arm'
|
||||
endian = 'little'
|
||||
27
media/libdav1d/src/package/crossfiles/arm64-iPhoneOS.meson
Normal file
27
media/libdav1d/src/package/crossfiles/arm64-iPhoneOS.meson
Normal file
|
|
@ -0,0 +1,27 @@
|
|||
[binaries]
|
||||
c = ['clang', '-arch', 'arm64', '-isysroot', '/Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS.sdk']
|
||||
cpp = ['clang++', '-arch', 'arm64', '-isysroot', '/Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS.sdk']
|
||||
objc = ['clang', '-arch', 'arm64', '-isysroot', '/Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS.sdk']
|
||||
objcpp = ['clang++', '-arch', 'arm64', '-isysroot', '/Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS.sdk']
|
||||
ar = 'ar'
|
||||
strip = 'strip'
|
||||
|
||||
[built-in options]
|
||||
c_args = ['-miphoneos-version-min=11.0']
|
||||
cpp_args = ['-miphoneos-version-min=11.0']
|
||||
c_link_args = ['-miphoneos-version-min=11.0']
|
||||
cpp_link_args = ['-miphoneos-version-min=11.0']
|
||||
objc_args = ['-miphoneos-version-min=11.0']
|
||||
objcpp_args = ['-miphoneos-version-min=11.0']
|
||||
|
||||
[properties]
|
||||
root = '/Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer'
|
||||
needs_exe_wrapper = true
|
||||
|
||||
[host_machine]
|
||||
system = 'darwin'
|
||||
subsystem = 'ios'
|
||||
kernel = 'xnu'
|
||||
cpu_family = 'aarch64'
|
||||
cpu = 'aarch64'
|
||||
endian = 'little'
|
||||
|
|
@ -0,0 +1,16 @@
|
|||
[binaries]
|
||||
c = 'armv7-w64-mingw32-clang'
|
||||
cpp = 'armv7-w64-mingw32-clang++'
|
||||
ar = 'armv7-w64-mingw32-ar'
|
||||
strip = 'armv7-w64-mingw32-strip'
|
||||
pkgconfig = 'pkg-config'
|
||||
windres = 'armv7-w64-mingw32-windres'
|
||||
|
||||
[properties]
|
||||
c_link_args = ['-static-libgcc']
|
||||
|
||||
[host_machine]
|
||||
system = 'windows'
|
||||
cpu_family = 'arm'
|
||||
cpu = 'armv7'
|
||||
endian = 'little'
|
||||
15
media/libdav1d/src/package/crossfiles/i686-linux32.meson
Normal file
15
media/libdav1d/src/package/crossfiles/i686-linux32.meson
Normal file
|
|
@ -0,0 +1,15 @@
|
|||
[binaries]
|
||||
c = 'gcc'
|
||||
cpp = 'g++'
|
||||
ar = 'ar'
|
||||
strip = 'strip'
|
||||
|
||||
[properties]
|
||||
c_link_args = ['-m32', '-Wl,-z,text']
|
||||
c_args = ['-m32']
|
||||
|
||||
[host_machine]
|
||||
system = 'linux'
|
||||
cpu_family = 'x86'
|
||||
cpu = 'i686'
|
||||
endian = 'little'
|
||||
16
media/libdav1d/src/package/crossfiles/i686-w64-mingw32.meson
Normal file
16
media/libdav1d/src/package/crossfiles/i686-w64-mingw32.meson
Normal file
|
|
@ -0,0 +1,16 @@
|
|||
[binaries]
|
||||
c = 'i686-w64-mingw32-gcc'
|
||||
cpp = 'i686-w64-mingw32-g++'
|
||||
ar = 'i686-w64-mingw32-ar'
|
||||
strip = 'i686-w64-mingw32-strip'
|
||||
windres = 'i686-w64-mingw32-windres'
|
||||
exe_wrapper = 'wine'
|
||||
|
||||
[properties]
|
||||
c_link_args = ['-static-libgcc']
|
||||
|
||||
[host_machine]
|
||||
system = 'windows'
|
||||
cpu_family = 'x86'
|
||||
cpu = 'i686'
|
||||
endian = 'little'
|
||||
|
|
@ -0,0 +1,13 @@
|
|||
[binaries]
|
||||
c = 'loongarch64-unknown-linux-gnu-gcc'
|
||||
cpp = 'loongarch64-unknown-linux-gnu-c++'
|
||||
ar = 'loongarch64-unknown-linux-gnu-ar'
|
||||
strip = 'loongarch64-unknown-linux-gnu-strip'
|
||||
pkgconfig = 'pkg-config'
|
||||
exe_wrapper = 'qemu-loongarch64'
|
||||
|
||||
[host_machine]
|
||||
system = 'linux'
|
||||
cpu_family = 'loongarch64'
|
||||
cpu = 'loongarch64'
|
||||
endian = 'little'
|
||||
|
|
@ -0,0 +1,16 @@
|
|||
[binaries]
|
||||
c = 'clang'
|
||||
cpp = 'clang++'
|
||||
ar = 'riscv64-linux-gnu-ar'
|
||||
strip = 'riscv64-linux-gnu-strip'
|
||||
exe_wrapper = 'qemu-riscv64'
|
||||
|
||||
[properties]
|
||||
c_args = '-target riscv64-linux-gnu'
|
||||
c_link_args = '-target riscv64-linux-gnu'
|
||||
|
||||
[host_machine]
|
||||
system = 'linux'
|
||||
cpu_family = 'riscv64'
|
||||
cpu = 'riscv64'
|
||||
endian = 'little'
|
||||
12
media/libdav1d/src/package/crossfiles/riscv64-linux.meson
Normal file
12
media/libdav1d/src/package/crossfiles/riscv64-linux.meson
Normal file
|
|
@ -0,0 +1,12 @@
|
|||
[binaries]
|
||||
c = 'riscv64-linux-gnu-gcc'
|
||||
cpp = 'riscv64-linux-gnu-g++'
|
||||
ar = 'riscv64-linux-gnu-ar'
|
||||
strip = 'riscv64-linux-gnu-strip'
|
||||
exe_wrapper = 'qemu-riscv64'
|
||||
|
||||
[host_machine]
|
||||
system = 'linux'
|
||||
cpu_family = 'riscv64'
|
||||
cpu = 'riscv64'
|
||||
endian = 'little'
|
||||
15
media/libdav1d/src/package/crossfiles/wasm32.meson
Normal file
15
media/libdav1d/src/package/crossfiles/wasm32.meson
Normal file
|
|
@ -0,0 +1,15 @@
|
|||
[binaries]
|
||||
c = 'emcc'
|
||||
cpp = 'em++'
|
||||
ar = 'emar'
|
||||
strip = 'emstrip'
|
||||
exe_wrapper = 'node'
|
||||
|
||||
[properties]
|
||||
c_link_args = ['-sEXPORT_ALL=1']
|
||||
|
||||
[host_machine]
|
||||
system = 'emscripten'
|
||||
cpu_family = 'wasm32'
|
||||
cpu = 'wasm32'
|
||||
endian = 'little'
|
||||
15
media/libdav1d/src/package/crossfiles/wasm64.meson
Normal file
15
media/libdav1d/src/package/crossfiles/wasm64.meson
Normal file
|
|
@ -0,0 +1,15 @@
|
|||
[binaries]
|
||||
c = 'emcc'
|
||||
cpp = 'em++'
|
||||
ar = 'emar'
|
||||
strip = 'emstrip'
|
||||
exe_wrapper = 'node'
|
||||
|
||||
[properties]
|
||||
c_link_args = ['-sEXPORT_ALL=1']
|
||||
|
||||
[host_machine]
|
||||
system = 'emscripten'
|
||||
cpu_family = 'wasm64'
|
||||
cpu = 'wasm64'
|
||||
endian = 'little'
|
||||
15
media/libdav1d/src/package/crossfiles/x86-android.meson
Normal file
15
media/libdav1d/src/package/crossfiles/x86-android.meson
Normal file
|
|
@ -0,0 +1,15 @@
|
|||
[binaries]
|
||||
c = 'i686-linux-android19-clang'
|
||||
cpp = 'i686-linux-android19-clang++'
|
||||
ar = 'llvm-ar'
|
||||
strip = 'llvm-strip'
|
||||
pkgconfig = 'pkg-config'
|
||||
|
||||
[properties]
|
||||
needs_exe_wrapper = true
|
||||
|
||||
[host_machine]
|
||||
system = 'android'
|
||||
cpu_family = 'x86'
|
||||
cpu = 'i686'
|
||||
endian = 'little'
|
||||
15
media/libdav1d/src/package/crossfiles/x86_64-android.meson
Normal file
15
media/libdav1d/src/package/crossfiles/x86_64-android.meson
Normal file
|
|
@ -0,0 +1,15 @@
|
|||
[binaries]
|
||||
c = 'x86_64-linux-android21-clang'
|
||||
cpp = 'x86_64-linux-android21-clang++'
|
||||
ar = 'llvm-ar'
|
||||
strip = 'llvm-strip'
|
||||
pkgconfig = 'pkg-config'
|
||||
|
||||
[properties]
|
||||
needs_exe_wrapper = true
|
||||
|
||||
[host_machine]
|
||||
system = 'android'
|
||||
cpu_family = 'x86_64'
|
||||
cpu = 'x86_64'
|
||||
endian = 'little'
|
||||
|
|
@ -0,0 +1,27 @@
|
|||
[binaries]
|
||||
c = ['clang', '-arch', 'x86_64', '-isysroot', '/Applications/Xcode.app/Contents/Developer/Platforms/iPhoneSimulator.platform/Developer/SDKs/iPhoneSimulator.sdk']
|
||||
cpp = ['clang++', '-arch', 'x86_64', '-isysroot', '/Applications/Xcode.app/Contents/Developer/Platforms/iPhoneSimulator.platform/Developer/SDKs/iPhoneSimulator.sdk']
|
||||
objc = ['clang', '-arch', 'x86_64', '-isysroot', '/Applications/Xcode.app/Contents/Developer/Platforms/iPhoneSimulator.platform/Developer/SDKs/iPhoneSimulator.sdk']
|
||||
objcpp = ['clang++', '-arch', 'x86_64', '-isysroot', '/Applications/Xcode.app/Contents/Developer/Platforms/iPhoneSimulator.platform/Developer/SDKs/iPhoneSimulator.sdk']
|
||||
ar = 'ar'
|
||||
strip = 'strip'
|
||||
|
||||
[built-in options]
|
||||
c_args = ['-miphoneos-version-min=11.0']
|
||||
cpp_args = ['-miphoneos-version-min=11.0']
|
||||
c_link_args = ['-miphoneos-version-min=11.0']
|
||||
cpp_link_args = ['-miphoneos-version-min=11.0']
|
||||
objc_args = ['-miphoneos-version-min=11.0']
|
||||
objcpp_args = ['-miphoneos-version-min=11.0']
|
||||
|
||||
[properties]
|
||||
root = '/Applications/Xcode.app/Contents/Developer/Platforms/iPhoneSimulator.platform/Developer'
|
||||
needs_exe_wrapper = true
|
||||
|
||||
[host_machine]
|
||||
system = 'darwin'
|
||||
subsystem = 'ios-simulator'
|
||||
kernel = 'xnu'
|
||||
cpu_family = 'x86_64'
|
||||
cpu = 'x86_64'
|
||||
endian = 'little'
|
||||
|
|
@ -0,0 +1,16 @@
|
|||
[binaries]
|
||||
c = 'x86_64-w64-mingw32-gcc'
|
||||
cpp = 'x86_64-w64-mingw32-g++'
|
||||
ar = 'x86_64-w64-mingw32-ar'
|
||||
strip = 'x86_64-w64-mingw32-strip'
|
||||
windres = 'x86_64-w64-mingw32-windres'
|
||||
exe_wrapper = 'wine'
|
||||
|
||||
[properties]
|
||||
c_link_args = ['-static-libgcc']
|
||||
|
||||
[host_machine]
|
||||
system = 'windows'
|
||||
cpu_family = 'x86_64'
|
||||
cpu = 'x86_64'
|
||||
endian = 'little'
|
||||
24
media/libdav1d/src/package/snap/snapcraft.yaml
Normal file
24
media/libdav1d/src/package/snap/snapcraft.yaml
Normal file
|
|
@ -0,0 +1,24 @@
|
|||
name: dav1d
|
||||
base: core18
|
||||
version: git
|
||||
version-script: git describe HEAD --always
|
||||
summary: AV1 decoder from VideoLAN
|
||||
description: |
|
||||
A small and fast AV1 decoder from the people who brought you VLC.
|
||||
|
||||
grade: stable
|
||||
confinement: strict # use 'strict' once you have the right plugs and slots
|
||||
|
||||
apps:
|
||||
dav1d:
|
||||
command: usr/bin/dav1d
|
||||
plugs: [ 'home' ]
|
||||
|
||||
parts:
|
||||
dav1d:
|
||||
plugin: meson
|
||||
source: ../../
|
||||
build-packages: [ 'nasm' ]
|
||||
meson-parameters:
|
||||
- --prefix=/usr
|
||||
- --buildtype=release
|
||||
540
media/libdav1d/src/src/arm/32/cdef.S
Normal file
540
media/libdav1d/src/src/arm/32/cdef.S
Normal file
|
|
@ -0,0 +1,540 @@
|
|||
/*
|
||||
* Copyright © 2018, VideoLAN and dav1d authors
|
||||
* Copyright © 2019, Martin Storsjo
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include "src/arm/asm.S"
|
||||
#include "util.S"
|
||||
#include "cdef_tmpl.S"
|
||||
|
||||
// n1 = s0/d0
|
||||
// w1 = d0/q0
|
||||
// n2 = s4/d2
|
||||
// w2 = d2/q1
|
||||
.macro pad_top_bottom s1, s2, w, stride, n1, w1, n2, w2, align, ret
|
||||
tst r7, #1 // CDEF_HAVE_LEFT
|
||||
beq 2f
|
||||
// CDEF_HAVE_LEFT
|
||||
tst r7, #2 // CDEF_HAVE_RIGHT
|
||||
beq 1f
|
||||
// CDEF_HAVE_LEFT+CDEF_HAVE_RIGHT
|
||||
ldrh r12, [\s1, #-2]
|
||||
vldr \n1, [\s1]
|
||||
vdup.16 d4, r12
|
||||
ldrh r12, [\s1, #\w]
|
||||
vmov.16 d4[1], r12
|
||||
ldrh r12, [\s2, #-2]
|
||||
vldr \n2, [\s2]
|
||||
vmov.16 d4[2], r12
|
||||
ldrh r12, [\s2, #\w]
|
||||
vmovl.u8 q0, d0
|
||||
vmov.16 d4[3], r12
|
||||
vmovl.u8 q1, d2
|
||||
vmovl.u8 q2, d4
|
||||
vstr s8, [r0, #-4]
|
||||
vst1.16 {\w1}, [r0, :\align]
|
||||
vstr s9, [r0, #2*\w]
|
||||
add r0, r0, #2*\stride
|
||||
vstr s10, [r0, #-4]
|
||||
vst1.16 {\w2}, [r0, :\align]
|
||||
vstr s11, [r0, #2*\w]
|
||||
.if \ret
|
||||
pop {r4-r8,pc}
|
||||
.else
|
||||
add r0, r0, #2*\stride
|
||||
b 3f
|
||||
.endif
|
||||
|
||||
1:
|
||||
// CDEF_HAVE_LEFT+!CDEF_HAVE_RIGHT
|
||||
ldrh r12, [\s1, #-2]
|
||||
vldr \n1, [\s1]
|
||||
vdup.16 d4, r12
|
||||
ldrh r12, [\s2, #-2]
|
||||
vldr \n2, [\s2]
|
||||
vmovl.u8 q0, d0
|
||||
vmov.16 d4[1], r12
|
||||
vmovl.u8 q1, d2
|
||||
vmovl.u8 q2, d4
|
||||
vstr s8, [r0, #-4]
|
||||
vst1.16 {\w1}, [r0, :\align]
|
||||
vstr s12, [r0, #2*\w]
|
||||
add r0, r0, #2*\stride
|
||||
vstr s9, [r0, #-4]
|
||||
vst1.16 {\w2}, [r0, :\align]
|
||||
vstr s12, [r0, #2*\w]
|
||||
.if \ret
|
||||
pop {r4-r8,pc}
|
||||
.else
|
||||
add r0, r0, #2*\stride
|
||||
b 3f
|
||||
.endif
|
||||
|
||||
2:
|
||||
// !CDEF_HAVE_LEFT
|
||||
tst r7, #2 // CDEF_HAVE_RIGHT
|
||||
beq 1f
|
||||
// !CDEF_HAVE_LEFT+CDEF_HAVE_RIGHT
|
||||
vldr \n1, [\s1]
|
||||
ldrh r12, [\s1, #\w]
|
||||
vldr \n2, [\s2]
|
||||
vdup.16 d4, r12
|
||||
ldrh r12, [\s2, #\w]
|
||||
vmovl.u8 q0, d0
|
||||
vmov.16 d4[1], r12
|
||||
vmovl.u8 q1, d2
|
||||
vmovl.u8 q2, d4
|
||||
vstr s12, [r0, #-4]
|
||||
vst1.16 {\w1}, [r0, :\align]
|
||||
vstr s8, [r0, #2*\w]
|
||||
add r0, r0, #2*\stride
|
||||
vstr s12, [r0, #-4]
|
||||
vst1.16 {\w2}, [r0, :\align]
|
||||
vstr s9, [r0, #2*\w]
|
||||
.if \ret
|
||||
pop {r4-r8,pc}
|
||||
.else
|
||||
add r0, r0, #2*\stride
|
||||
b 3f
|
||||
.endif
|
||||
|
||||
1:
|
||||
// !CDEF_HAVE_LEFT+!CDEF_HAVE_RIGHT
|
||||
vldr \n1, [\s1]
|
||||
vldr \n2, [\s2]
|
||||
vmovl.u8 q0, d0
|
||||
vmovl.u8 q1, d2
|
||||
vstr s12, [r0, #-4]
|
||||
vst1.16 {\w1}, [r0, :\align]
|
||||
vstr s12, [r0, #2*\w]
|
||||
add r0, r0, #2*\stride
|
||||
vstr s12, [r0, #-4]
|
||||
vst1.16 {\w2}, [r0, :\align]
|
||||
vstr s12, [r0, #2*\w]
|
||||
.if \ret
|
||||
pop {r4-r8,pc}
|
||||
.else
|
||||
add r0, r0, #2*\stride
|
||||
.endif
|
||||
3:
|
||||
.endm
|
||||
|
||||
.macro load_n_incr dst, src, incr, w
|
||||
.if \w == 4
|
||||
vld1.32 {\dst\()[0]}, [\src, :32], \incr
|
||||
.else
|
||||
vld1.8 {\dst\()}, [\src, :64], \incr
|
||||
.endif
|
||||
.endm
|
||||
|
||||
// void dav1d_cdef_paddingX_8bpc_neon(uint16_t *tmp, const pixel *src,
|
||||
// ptrdiff_t src_stride, const pixel (*left)[2],
|
||||
// const pixel *const top,
|
||||
// const pixel *const bottom, int h,
|
||||
// enum CdefEdgeFlags edges);
|
||||
|
||||
// n1 = s0/d0
|
||||
// w1 = d0/q0
|
||||
// n2 = s4/d2
|
||||
// w2 = d2/q1
|
||||
.macro padding_func w, stride, n1, w1, n2, w2, align
|
||||
function cdef_padding\w\()_8bpc_neon, export=1
|
||||
push {r4-r8,lr}
|
||||
ldrd r4, r5, [sp, #24]
|
||||
ldrd r6, r7, [sp, #32]
|
||||
cmp r7, #0xf // fully edged
|
||||
beq cdef_padding\w\()_edged_8bpc_neon
|
||||
vmov.i16 q3, #0x8000
|
||||
tst r7, #4 // CDEF_HAVE_TOP
|
||||
bne 1f
|
||||
// !CDEF_HAVE_TOP
|
||||
sub r12, r0, #2*(2*\stride+2)
|
||||
vmov.i16 q2, #0x8000
|
||||
vst1.16 {q2,q3}, [r12]!
|
||||
.if \w == 8
|
||||
vst1.16 {q2,q3}, [r12]!
|
||||
.endif
|
||||
b 3f
|
||||
1:
|
||||
// CDEF_HAVE_TOP
|
||||
add r8, r4, r2
|
||||
sub r0, r0, #2*(2*\stride)
|
||||
pad_top_bottom r4, r8, \w, \stride, \n1, \w1, \n2, \w2, \align, 0
|
||||
|
||||
// Middle section
|
||||
3:
|
||||
tst r7, #1 // CDEF_HAVE_LEFT
|
||||
beq 2f
|
||||
// CDEF_HAVE_LEFT
|
||||
tst r7, #2 // CDEF_HAVE_RIGHT
|
||||
beq 1f
|
||||
// CDEF_HAVE_LEFT+CDEF_HAVE_RIGHT
|
||||
0:
|
||||
vld1.16 {d2[]}, [r3, :16]!
|
||||
ldrh r12, [r1, #\w]
|
||||
load_n_incr d0, r1, r2, \w
|
||||
subs r6, r6, #1
|
||||
vmov.16 d2[1], r12
|
||||
vmovl.u8 q0, d0
|
||||
vmovl.u8 q1, d2
|
||||
vstr s4, [r0, #-4]
|
||||
vst1.16 {\w1}, [r0, :\align]
|
||||
vstr s5, [r0, #2*\w]
|
||||
add r0, r0, #2*\stride
|
||||
bgt 0b
|
||||
b 3f
|
||||
1:
|
||||
// CDEF_HAVE_LEFT+!CDEF_HAVE_RIGHT
|
||||
vld1.16 {d2[]}, [r3, :16]!
|
||||
load_n_incr d0, r1, r2, \w
|
||||
subs r6, r6, #1
|
||||
vmovl.u8 q0, d0
|
||||
vmovl.u8 q1, d2
|
||||
vstr s4, [r0, #-4]
|
||||
vst1.16 {\w1}, [r0, :\align]
|
||||
vstr s12, [r0, #2*\w]
|
||||
add r0, r0, #2*\stride
|
||||
bgt 1b
|
||||
b 3f
|
||||
2:
|
||||
tst r7, #2 // CDEF_HAVE_RIGHT
|
||||
beq 1f
|
||||
// !CDEF_HAVE_LEFT+CDEF_HAVE_RIGHT
|
||||
0:
|
||||
ldrh r12, [r1, #\w]
|
||||
load_n_incr d0, r1, r2, \w
|
||||
vdup.16 d2, r12
|
||||
subs r6, r6, #1
|
||||
vmovl.u8 q0, d0
|
||||
vmovl.u8 q1, d2
|
||||
vstr s12, [r0, #-4]
|
||||
vst1.16 {\w1}, [r0, :\align]
|
||||
vstr s4, [r0, #2*\w]
|
||||
add r0, r0, #2*\stride
|
||||
bgt 0b
|
||||
b 3f
|
||||
1:
|
||||
// !CDEF_HAVE_LEFT+!CDEF_HAVE_RIGHT
|
||||
load_n_incr d0, r1, r2, \w
|
||||
subs r6, r6, #1
|
||||
vmovl.u8 q0, d0
|
||||
vstr s12, [r0, #-4]
|
||||
vst1.16 {\w1}, [r0, :\align]
|
||||
vstr s12, [r0, #2*\w]
|
||||
add r0, r0, #2*\stride
|
||||
bgt 1b
|
||||
|
||||
3:
|
||||
tst r7, #8 // CDEF_HAVE_BOTTOM
|
||||
bne 1f
|
||||
// !CDEF_HAVE_BOTTOM
|
||||
sub r12, r0, #4
|
||||
vmov.i16 q2, #0x8000
|
||||
vst1.16 {q2,q3}, [r12]!
|
||||
.if \w == 8
|
||||
vst1.16 {q2,q3}, [r12]!
|
||||
.endif
|
||||
pop {r4-r8,pc}
|
||||
1:
|
||||
// CDEF_HAVE_BOTTOM
|
||||
add r8, r5, r2
|
||||
pad_top_bottom r5, r8, \w, \stride, \n1, \w1, \n2, \w2, \align, 1
|
||||
endfunc
|
||||
.endm
|
||||
|
||||
padding_func 8, 16, d0, q0, d2, q1, 128
|
||||
padding_func 4, 8, s0, d0, s4, d2, 64
|
||||
|
||||
// void cdef_paddingX_edged_8bpc_neon(uint16_t *tmp, const pixel *src,
|
||||
// ptrdiff_t src_stride, const pixel (*left)[2],
|
||||
// const pixel *const top,
|
||||
// const pixel *const bottom, int h,
|
||||
// enum CdefEdgeFlags edges);
|
||||
|
||||
.macro padding_func_edged w, stride, reg, align
|
||||
function cdef_padding\w\()_edged_8bpc_neon
|
||||
sub r0, r0, #(2*\stride)
|
||||
|
||||
ldrh r12, [r4, #-2]
|
||||
vldr \reg, [r4]
|
||||
add r8, r4, r2
|
||||
strh r12, [r0, #-2]
|
||||
ldrh r12, [r4, #\w]
|
||||
vstr \reg, [r0]
|
||||
strh r12, [r0, #\w]
|
||||
|
||||
ldrh r12, [r8, #-2]
|
||||
vldr \reg, [r8]
|
||||
strh r12, [r0, #\stride-2]
|
||||
ldrh r12, [r8, #\w]
|
||||
vstr \reg, [r0, #\stride]
|
||||
strh r12, [r0, #\stride+\w]
|
||||
add r0, r0, #2*\stride
|
||||
|
||||
0:
|
||||
ldrh r12, [r3], #2
|
||||
vldr \reg, [r1]
|
||||
str r12, [r0, #-2]
|
||||
ldrh r12, [r1, #\w]
|
||||
add r1, r1, r2
|
||||
subs r6, r6, #1
|
||||
vstr \reg, [r0]
|
||||
str r12, [r0, #\w]
|
||||
add r0, r0, #\stride
|
||||
bgt 0b
|
||||
|
||||
ldrh r12, [r5, #-2]
|
||||
vldr \reg, [r5]
|
||||
add r8, r5, r2
|
||||
strh r12, [r0, #-2]
|
||||
ldrh r12, [r5, #\w]
|
||||
vstr \reg, [r0]
|
||||
strh r12, [r0, #\w]
|
||||
|
||||
ldrh r12, [r8, #-2]
|
||||
vldr \reg, [r8]
|
||||
strh r12, [r0, #\stride-2]
|
||||
ldrh r12, [r8, #\w]
|
||||
vstr \reg, [r0, #\stride]
|
||||
strh r12, [r0, #\stride+\w]
|
||||
|
||||
pop {r4-r8,pc}
|
||||
endfunc
|
||||
.endm
|
||||
|
||||
padding_func_edged 8, 16, d0, 64
|
||||
padding_func_edged 4, 8, s0, 32
|
||||
|
||||
tables
|
||||
|
||||
filter 8, 8
|
||||
filter 4, 8
|
||||
|
||||
find_dir 8
|
||||
|
||||
.macro load_px_8 d11, d12, d21, d22, w
|
||||
.if \w == 8
|
||||
add r6, r2, r9 // x + off
|
||||
sub r9, r2, r9 // x - off
|
||||
vld1.8 {\d11}, [r6] // p0
|
||||
add r6, r6, #16 // += stride
|
||||
vld1.8 {\d21}, [r9] // p1
|
||||
add r9, r9, #16 // += stride
|
||||
vld1.8 {\d12}, [r6] // p0
|
||||
vld1.8 {\d22}, [r9] // p1
|
||||
.else
|
||||
add r6, r2, r9 // x + off
|
||||
sub r9, r2, r9 // x - off
|
||||
vld1.32 {\d11[0]}, [r6] // p0
|
||||
add r6, r6, #8 // += stride
|
||||
vld1.32 {\d21[0]}, [r9] // p1
|
||||
add r9, r9, #8 // += stride
|
||||
vld1.32 {\d11[1]}, [r6] // p0
|
||||
add r6, r6, #8 // += stride
|
||||
vld1.32 {\d21[1]}, [r9] // p1
|
||||
add r9, r9, #8 // += stride
|
||||
vld1.32 {\d12[0]}, [r6] // p0
|
||||
add r6, r6, #8 // += stride
|
||||
vld1.32 {\d22[0]}, [r9] // p1
|
||||
add r9, r9, #8 // += stride
|
||||
vld1.32 {\d12[1]}, [r6] // p0
|
||||
vld1.32 {\d22[1]}, [r9] // p1
|
||||
.endif
|
||||
.endm
|
||||
.macro handle_pixel_8 s1, s2, thresh_vec, shift, tap, min
|
||||
.if \min
|
||||
vmin.u8 q3, q3, \s1
|
||||
vmax.u8 q4, q4, \s1
|
||||
vmin.u8 q3, q3, \s2
|
||||
vmax.u8 q4, q4, \s2
|
||||
.endif
|
||||
vabd.u8 q8, q0, \s1 // abs(diff)
|
||||
vabd.u8 q11, q0, \s2 // abs(diff)
|
||||
vshl.u8 q9, q8, \shift // abs(diff) >> shift
|
||||
vshl.u8 q12, q11, \shift // abs(diff) >> shift
|
||||
vqsub.u8 q9, \thresh_vec, q9 // clip = imax(0, threshold - (abs(diff) >> shift))
|
||||
vqsub.u8 q12, \thresh_vec, q12// clip = imax(0, threshold - (abs(diff) >> shift))
|
||||
vcgt.u8 q10, q0, \s1 // px > p0
|
||||
vcgt.u8 q13, q0, \s2 // px > p1
|
||||
vmin.u8 q9, q9, q8 // imin(abs(diff), clip)
|
||||
vmin.u8 q12, q12, q11 // imin(abs(diff), clip)
|
||||
vneg.s8 q8, q9 // -imin()
|
||||
vneg.s8 q11, q12 // -imin()
|
||||
vbsl q10, q8, q9 // constrain() = imax(imin(diff, clip), -clip)
|
||||
vdup.8 d18, \tap // taps[k]
|
||||
vbsl q13, q11, q12 // constrain() = imax(imin(diff, clip), -clip)
|
||||
vmlal.s8 q1, d20, d18 // sum += taps[k] * constrain()
|
||||
vmlal.s8 q1, d26, d18 // sum += taps[k] * constrain()
|
||||
vmlal.s8 q2, d21, d18 // sum += taps[k] * constrain()
|
||||
vmlal.s8 q2, d27, d18 // sum += taps[k] * constrain()
|
||||
.endm
|
||||
|
||||
// void cdef_filterX_edged_neon(pixel *dst, ptrdiff_t dst_stride,
|
||||
// const uint16_t *tmp, int pri_strength,
|
||||
// int sec_strength, int dir, int damping,
|
||||
// int h, size_t edges);
|
||||
.macro filter_func_8 w, pri, sec, min, suffix
|
||||
function cdef_filter\w\suffix\()_edged_neon
|
||||
.if \pri
|
||||
movrel_local r8, pri_taps
|
||||
and r9, r3, #1
|
||||
add r8, r8, r9, lsl #1
|
||||
.endif
|
||||
movrel_local r9, directions\w
|
||||
add r5, r9, r5, lsl #1
|
||||
vmov.u8 d17, #7
|
||||
vdup.8 d16, r6 // damping
|
||||
|
||||
vmov.8 d8[0], r3
|
||||
vmov.8 d8[1], r4
|
||||
vclz.i8 d8, d8 // clz(threshold)
|
||||
vsub.i8 d8, d17, d8 // ulog2(threshold)
|
||||
vqsub.u8 d8, d16, d8 // shift = imax(0, damping - ulog2(threshold))
|
||||
vneg.s8 d8, d8 // -shift
|
||||
.if \sec
|
||||
vdup.8 q6, d8[1]
|
||||
.endif
|
||||
.if \pri
|
||||
vdup.8 q5, d8[0]
|
||||
.endif
|
||||
|
||||
1:
|
||||
.if \w == 8
|
||||
add r12, r2, #16
|
||||
vld1.8 {d0}, [r2, :64] // px
|
||||
vld1.8 {d1}, [r12, :64] // px
|
||||
.else
|
||||
add r12, r2, #8
|
||||
vld1.32 {d0[0]}, [r2, :32] // px
|
||||
add r9, r2, #2*8
|
||||
vld1.32 {d0[1]}, [r12, :32] // px
|
||||
add r12, r12, #2*8
|
||||
vld1.32 {d1[0]}, [r9, :32] // px
|
||||
vld1.32 {d1[1]}, [r12, :32] // px
|
||||
.endif
|
||||
|
||||
vmov.u8 q1, #0 // sum
|
||||
vmov.u8 q2, #0 // sum
|
||||
.if \min
|
||||
vmov.u16 q3, q0 // min
|
||||
vmov.u16 q4, q0 // max
|
||||
.endif
|
||||
|
||||
// Instead of loading sec_taps 2, 1 from memory, just set it
|
||||
// to 2 initially and decrease for the second round.
|
||||
// This is also used as loop counter.
|
||||
mov lr, #2 // sec_taps[0]
|
||||
|
||||
2:
|
||||
.if \pri
|
||||
ldrsb r9, [r5] // off1
|
||||
|
||||
load_px_8 d28, d29, d30, d31, \w
|
||||
.endif
|
||||
|
||||
.if \sec
|
||||
add r5, r5, #4 // +2*2
|
||||
ldrsb r9, [r5] // off2
|
||||
.endif
|
||||
|
||||
.if \pri
|
||||
ldrb r12, [r8] // *pri_taps
|
||||
vdup.8 q7, r3 // threshold
|
||||
|
||||
handle_pixel_8 q14, q15, q7, q5, r12, \min
|
||||
.endif
|
||||
|
||||
.if \sec
|
||||
load_px_8 d28, d29, d30, d31, \w
|
||||
|
||||
add r5, r5, #8 // +2*4
|
||||
ldrsb r9, [r5] // off3
|
||||
|
||||
vdup.8 q7, r4 // threshold
|
||||
|
||||
handle_pixel_8 q14, q15, q7, q6, lr, \min
|
||||
|
||||
load_px_8 d28, d29, d30, d31, \w
|
||||
|
||||
handle_pixel_8 q14, q15, q7, q6, lr, \min
|
||||
|
||||
sub r5, r5, #11 // r5 -= 2*(2+4); r5 += 1;
|
||||
.else
|
||||
add r5, r5, #1 // r5 += 1
|
||||
.endif
|
||||
subs lr, lr, #1 // sec_tap-- (value)
|
||||
.if \pri
|
||||
add r8, r8, #1 // pri_taps++ (pointer)
|
||||
.endif
|
||||
bne 2b
|
||||
|
||||
vshr.s16 q14, q1, #15 // -(sum < 0)
|
||||
vshr.s16 q15, q2, #15 // -(sum < 0)
|
||||
vadd.i16 q1, q1, q14 // sum - (sum < 0)
|
||||
vadd.i16 q2, q2, q15 // sum - (sum < 0)
|
||||
vrshr.s16 q1, q1, #4 // (8 + sum - (sum < 0)) >> 4
|
||||
vrshr.s16 q2, q2, #4 // (8 + sum - (sum < 0)) >> 4
|
||||
vaddw.u8 q1, q1, d0 // px + (8 + sum ...) >> 4
|
||||
vaddw.u8 q2, q2, d1 // px + (8 + sum ...) >> 4
|
||||
vqmovun.s16 d0, q1
|
||||
vqmovun.s16 d1, q2
|
||||
.if \min
|
||||
vmin.u8 q0, q0, q4
|
||||
vmax.u8 q0, q0, q3 // iclip(px + .., min, max)
|
||||
.endif
|
||||
.if \w == 8
|
||||
vst1.8 {d0}, [r0, :64], r1
|
||||
add r2, r2, #2*16 // tmp += 2*tmp_stride
|
||||
subs r7, r7, #2 // h -= 2
|
||||
vst1.8 {d1}, [r0, :64], r1
|
||||
.else
|
||||
vst1.32 {d0[0]}, [r0, :32], r1
|
||||
add r2, r2, #4*8 // tmp += 4*tmp_stride
|
||||
vst1.32 {d0[1]}, [r0, :32], r1
|
||||
subs r7, r7, #4 // h -= 4
|
||||
vst1.32 {d1[0]}, [r0, :32], r1
|
||||
vst1.32 {d1[1]}, [r0, :32], r1
|
||||
.endif
|
||||
|
||||
// Reset pri_taps and directions back to the original point
|
||||
sub r5, r5, #2
|
||||
.if \pri
|
||||
sub r8, r8, #2
|
||||
.endif
|
||||
|
||||
bgt 1b
|
||||
vpop {q4-q7}
|
||||
pop {r4-r9,pc}
|
||||
endfunc
|
||||
.endm
|
||||
|
||||
.macro filter_8 w
|
||||
filter_func_8 \w, pri=1, sec=0, min=0, suffix=_pri
|
||||
filter_func_8 \w, pri=0, sec=1, min=0, suffix=_sec
|
||||
filter_func_8 \w, pri=1, sec=1, min=1, suffix=_pri_sec
|
||||
.endm
|
||||
|
||||
filter_8 8
|
||||
filter_8 4
|
||||
233
media/libdav1d/src/src/arm/32/cdef16.S
Normal file
233
media/libdav1d/src/src/arm/32/cdef16.S
Normal file
|
|
@ -0,0 +1,233 @@
|
|||
/*
|
||||
* Copyright © 2018, VideoLAN and dav1d authors
|
||||
* Copyright © 2020, Martin Storsjo
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include "src/arm/asm.S"
|
||||
#include "util.S"
|
||||
#include "cdef_tmpl.S"
|
||||
|
||||
// r1 = d0/q0
|
||||
// r2 = d2/q1
|
||||
.macro pad_top_bot_16 s1, s2, w, stride, r1, r2, align, ret
|
||||
tst r7, #1 // CDEF_HAVE_LEFT
|
||||
beq 2f
|
||||
// CDEF_HAVE_LEFT
|
||||
tst r7, #2 // CDEF_HAVE_RIGHT
|
||||
beq 1f
|
||||
// CDEF_HAVE_LEFT+CDEF_HAVE_RIGHT
|
||||
vldr s8, [\s1, #-4]
|
||||
vld1.16 {\r1}, [\s1, :\align]
|
||||
vldr s9, [\s1, #2*\w]
|
||||
vldr s10, [\s2, #-4]
|
||||
vld1.16 {\r2}, [\s2, :\align]
|
||||
vldr s11, [\s2, #2*\w]
|
||||
vstr s8, [r0, #-4]
|
||||
vst1.16 {\r1}, [r0, :\align]
|
||||
vstr s9, [r0, #2*\w]
|
||||
add r0, r0, #2*\stride
|
||||
vstr s10, [r0, #-4]
|
||||
vst1.16 {\r2}, [r0, :\align]
|
||||
vstr s11, [r0, #2*\w]
|
||||
.if \ret
|
||||
pop {r4-r8,pc}
|
||||
.else
|
||||
add r0, r0, #2*\stride
|
||||
b 3f
|
||||
.endif
|
||||
|
||||
1:
|
||||
// CDEF_HAVE_LEFT+!CDEF_HAVE_RIGHT
|
||||
vldr s8, [\s1, #-4]
|
||||
vld1.16 {\r1}, [\s1, :\align]
|
||||
vldr s9, [\s2, #-4]
|
||||
vld1.16 {\r2}, [\s2, :\align]
|
||||
vstr s8, [r0, #-4]
|
||||
vst1.16 {\r1}, [r0, :\align]
|
||||
vstr s12, [r0, #2*\w]
|
||||
add r0, r0, #2*\stride
|
||||
vstr s9, [r0, #-4]
|
||||
vst1.16 {\r2}, [r0, :\align]
|
||||
vstr s12, [r0, #2*\w]
|
||||
.if \ret
|
||||
pop {r4-r8,pc}
|
||||
.else
|
||||
add r0, r0, #2*\stride
|
||||
b 3f
|
||||
.endif
|
||||
|
||||
2:
|
||||
// !CDEF_HAVE_LEFT
|
||||
tst r7, #2 // CDEF_HAVE_RIGHT
|
||||
beq 1f
|
||||
// !CDEF_HAVE_LEFT+CDEF_HAVE_RIGHT
|
||||
vld1.16 {\r1}, [\s1, :\align]
|
||||
vldr s8, [\s1, #2*\w]
|
||||
vld1.16 {\r2}, [\s2, :\align]
|
||||
vldr s9, [\s2, #2*\w]
|
||||
vstr s12, [r0, #-4]
|
||||
vst1.16 {\r1}, [r0, :\align]
|
||||
vstr s8, [r0, #2*\w]
|
||||
add r0, r0, #2*\stride
|
||||
vstr s12, [r0, #-4]
|
||||
vst1.16 {\r2}, [r0, :\align]
|
||||
vstr s9, [r0, #2*\w]
|
||||
.if \ret
|
||||
pop {r4-r8,pc}
|
||||
.else
|
||||
add r0, r0, #2*\stride
|
||||
b 3f
|
||||
.endif
|
||||
|
||||
1:
|
||||
// !CDEF_HAVE_LEFT+!CDEF_HAVE_RIGHT
|
||||
vld1.16 {\r1}, [\s1, :\align]
|
||||
vld1.16 {\r2}, [\s2, :\align]
|
||||
vstr s12, [r0, #-4]
|
||||
vst1.16 {\r1}, [r0, :\align]
|
||||
vstr s12, [r0, #2*\w]
|
||||
add r0, r0, #2*\stride
|
||||
vstr s12, [r0, #-4]
|
||||
vst1.16 {\r2}, [r0, :\align]
|
||||
vstr s12, [r0, #2*\w]
|
||||
.if \ret
|
||||
pop {r4-r8,pc}
|
||||
.else
|
||||
add r0, r0, #2*\stride
|
||||
.endif
|
||||
3:
|
||||
.endm
|
||||
|
||||
// void dav1d_cdef_paddingX_16bpc_neon(uint16_t *tmp, const pixel *src,
|
||||
// ptrdiff_t src_stride, const pixel (*left)[2],
|
||||
// const pixel *const top,
|
||||
// const pixel *const bottom, int h,
|
||||
// enum CdefEdgeFlags edges);
|
||||
|
||||
// r1 = d0/q0
|
||||
// r2 = d2/q1
|
||||
.macro padding_func_16 w, stride, r1, r2, align
|
||||
function cdef_padding\w\()_16bpc_neon, export=1
|
||||
push {r4-r8,lr}
|
||||
ldrd r4, r5, [sp, #24]
|
||||
ldrd r6, r7, [sp, #32]
|
||||
vmov.i16 q3, #0x8000
|
||||
tst r7, #4 // CDEF_HAVE_TOP
|
||||
bne 1f
|
||||
// !CDEF_HAVE_TOP
|
||||
sub r12, r0, #2*(2*\stride+2)
|
||||
vmov.i16 q2, #0x8000
|
||||
vst1.16 {q2,q3}, [r12]!
|
||||
.if \w == 8
|
||||
vst1.16 {q2,q3}, [r12]!
|
||||
.endif
|
||||
b 3f
|
||||
1:
|
||||
// CDEF_HAVE_TOP
|
||||
add r8, r4, r2
|
||||
sub r0, r0, #2*(2*\stride)
|
||||
pad_top_bot_16 r4, r8, \w, \stride, \r1, \r2, \align, 0
|
||||
|
||||
// Middle section
|
||||
3:
|
||||
tst r7, #1 // CDEF_HAVE_LEFT
|
||||
beq 2f
|
||||
// CDEF_HAVE_LEFT
|
||||
tst r7, #2 // CDEF_HAVE_RIGHT
|
||||
beq 1f
|
||||
// CDEF_HAVE_LEFT+CDEF_HAVE_RIGHT
|
||||
0:
|
||||
vld1.32 {d2[]}, [r3, :32]!
|
||||
vldr s5, [r1, #2*\w]
|
||||
vld1.16 {\r1}, [r1, :\align], r2
|
||||
subs r6, r6, #1
|
||||
vstr s4, [r0, #-4]
|
||||
vst1.16 {\r1}, [r0, :\align]
|
||||
vstr s5, [r0, #2*\w]
|
||||
add r0, r0, #2*\stride
|
||||
bgt 0b
|
||||
b 3f
|
||||
1:
|
||||
// CDEF_HAVE_LEFT+!CDEF_HAVE_RIGHT
|
||||
vld1.32 {d2[]}, [r3, :32]!
|
||||
vld1.16 {\r1}, [r1, :\align], r2
|
||||
subs r6, r6, #1
|
||||
vstr s4, [r0, #-4]
|
||||
vst1.16 {\r1}, [r0, :\align]
|
||||
vstr s12, [r0, #2*\w]
|
||||
add r0, r0, #2*\stride
|
||||
bgt 1b
|
||||
b 3f
|
||||
2:
|
||||
tst r7, #2 // CDEF_HAVE_RIGHT
|
||||
beq 1f
|
||||
// !CDEF_HAVE_LEFT+CDEF_HAVE_RIGHT
|
||||
0:
|
||||
vldr s4, [r1, #2*\w]
|
||||
vld1.16 {\r1}, [r1, :\align], r2
|
||||
subs r6, r6, #1
|
||||
vstr s12, [r0, #-4]
|
||||
vst1.16 {\r1}, [r0, :\align]
|
||||
vstr s4, [r0, #2*\w]
|
||||
add r0, r0, #2*\stride
|
||||
bgt 0b
|
||||
b 3f
|
||||
1:
|
||||
// !CDEF_HAVE_LEFT+!CDEF_HAVE_RIGHT
|
||||
vld1.16 {\r1}, [r1, :\align], r2
|
||||
subs r6, r6, #1
|
||||
vstr s12, [r0, #-4]
|
||||
vst1.16 {\r1}, [r0, :\align]
|
||||
vstr s12, [r0, #2*\w]
|
||||
add r0, r0, #2*\stride
|
||||
bgt 1b
|
||||
|
||||
3:
|
||||
tst r7, #8 // CDEF_HAVE_BOTTOM
|
||||
bne 1f
|
||||
// !CDEF_HAVE_BOTTOM
|
||||
sub r12, r0, #4
|
||||
vmov.i16 q2, #0x8000
|
||||
vst1.16 {q2,q3}, [r12]!
|
||||
.if \w == 8
|
||||
vst1.16 {q2,q3}, [r12]!
|
||||
.endif
|
||||
pop {r4-r8,pc}
|
||||
1:
|
||||
// CDEF_HAVE_BOTTOM
|
||||
add r8, r5, r2
|
||||
pad_top_bot_16 r5, r8, \w, \stride, \r1, \r2, \align, 1
|
||||
endfunc
|
||||
.endm
|
||||
|
||||
padding_func_16 8, 16, q0, q1, 128
|
||||
padding_func_16 4, 8, d0, d2, 64
|
||||
|
||||
tables
|
||||
|
||||
filter 8, 16
|
||||
filter 4, 16
|
||||
|
||||
find_dir 16
|
||||
515
media/libdav1d/src/src/arm/32/cdef_tmpl.S
Normal file
515
media/libdav1d/src/src/arm/32/cdef_tmpl.S
Normal file
|
|
@ -0,0 +1,515 @@
|
|||
/*
|
||||
* Copyright © 2018, VideoLAN and dav1d authors
|
||||
* Copyright © 2020, Martin Storsjo
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include "src/arm/asm.S"
|
||||
#include "util.S"
|
||||
|
||||
.macro dir_table w, stride
|
||||
const directions\w
|
||||
.byte -1 * \stride + 1, -2 * \stride + 2
|
||||
.byte 0 * \stride + 1, -1 * \stride + 2
|
||||
.byte 0 * \stride + 1, 0 * \stride + 2
|
||||
.byte 0 * \stride + 1, 1 * \stride + 2
|
||||
.byte 1 * \stride + 1, 2 * \stride + 2
|
||||
.byte 1 * \stride + 0, 2 * \stride + 1
|
||||
.byte 1 * \stride + 0, 2 * \stride + 0
|
||||
.byte 1 * \stride + 0, 2 * \stride - 1
|
||||
// Repeated, to avoid & 7
|
||||
.byte -1 * \stride + 1, -2 * \stride + 2
|
||||
.byte 0 * \stride + 1, -1 * \stride + 2
|
||||
.byte 0 * \stride + 1, 0 * \stride + 2
|
||||
.byte 0 * \stride + 1, 1 * \stride + 2
|
||||
.byte 1 * \stride + 1, 2 * \stride + 2
|
||||
.byte 1 * \stride + 0, 2 * \stride + 1
|
||||
endconst
|
||||
.endm
|
||||
|
||||
.macro tables
|
||||
dir_table 8, 16
|
||||
dir_table 4, 8
|
||||
|
||||
const pri_taps
|
||||
.byte 4, 2, 3, 3
|
||||
endconst
|
||||
.endm
|
||||
|
||||
.macro load_px d11, d12, d21, d22, w
|
||||
.if \w == 8
|
||||
add r6, r2, r9, lsl #1 // x + off
|
||||
sub r9, r2, r9, lsl #1 // x - off
|
||||
vld1.16 {\d11,\d12}, [r6] // p0
|
||||
vld1.16 {\d21,\d22}, [r9] // p1
|
||||
.else
|
||||
add r6, r2, r9, lsl #1 // x + off
|
||||
sub r9, r2, r9, lsl #1 // x - off
|
||||
vld1.16 {\d11}, [r6] // p0
|
||||
add r6, r6, #2*8 // += stride
|
||||
vld1.16 {\d21}, [r9] // p1
|
||||
add r9, r9, #2*8 // += stride
|
||||
vld1.16 {\d12}, [r6] // p0
|
||||
vld1.16 {\d22}, [r9] // p1
|
||||
.endif
|
||||
.endm
|
||||
.macro handle_pixel s1, s2, thresh_vec, shift, tap, min
|
||||
.if \min
|
||||
vmin.u16 q2, q2, \s1
|
||||
vmax.s16 q3, q3, \s1
|
||||
vmin.u16 q2, q2, \s2
|
||||
vmax.s16 q3, q3, \s2
|
||||
.endif
|
||||
vabd.u16 q8, q0, \s1 // abs(diff)
|
||||
vabd.u16 q11, q0, \s2 // abs(diff)
|
||||
vshl.u16 q9, q8, \shift // abs(diff) >> shift
|
||||
vshl.u16 q12, q11, \shift // abs(diff) >> shift
|
||||
vqsub.u16 q9, \thresh_vec, q9 // clip = imax(0, threshold - (abs(diff) >> shift))
|
||||
vqsub.u16 q12, \thresh_vec, q12// clip = imax(0, threshold - (abs(diff) >> shift))
|
||||
vsub.i16 q10, \s1, q0 // diff = p0 - px
|
||||
vsub.i16 q13, \s2, q0 // diff = p1 - px
|
||||
vneg.s16 q8, q9 // -clip
|
||||
vneg.s16 q11, q12 // -clip
|
||||
vmin.s16 q10, q10, q9 // imin(diff, clip)
|
||||
vmin.s16 q13, q13, q12 // imin(diff, clip)
|
||||
vdup.16 q9, \tap // taps[k]
|
||||
vmax.s16 q10, q10, q8 // constrain() = imax(imin(diff, clip), -clip)
|
||||
vmax.s16 q13, q13, q11 // constrain() = imax(imin(diff, clip), -clip)
|
||||
vmla.i16 q1, q10, q9 // sum += taps[k] * constrain()
|
||||
vmla.i16 q1, q13, q9 // sum += taps[k] * constrain()
|
||||
.endm
|
||||
|
||||
// void dav1d_cdef_filterX_Ybpc_neon(pixel *dst, ptrdiff_t dst_stride,
|
||||
// const uint16_t *tmp, int pri_strength,
|
||||
// int sec_strength, int dir, int damping,
|
||||
// int h, size_t edges);
|
||||
.macro filter_func w, bpc, pri, sec, min, suffix
|
||||
function cdef_filter\w\suffix\()_\bpc\()bpc_neon
|
||||
.if \bpc == 8
|
||||
cmp r8, #0xf
|
||||
beq cdef_filter\w\suffix\()_edged_neon
|
||||
.endif
|
||||
.if \pri
|
||||
.if \bpc == 16
|
||||
clz r9, r9
|
||||
sub r9, r9, #24 // -bitdepth_min_8
|
||||
neg r9, r9 // bitdepth_min_8
|
||||
.endif
|
||||
movrel_local r8, pri_taps
|
||||
.if \bpc == 16
|
||||
lsr r9, r3, r9 // pri_strength >> bitdepth_min_8
|
||||
and r9, r9, #1 // (pri_strength >> bitdepth_min_8) & 1
|
||||
.else
|
||||
and r9, r3, #1
|
||||
.endif
|
||||
add r8, r8, r9, lsl #1
|
||||
.endif
|
||||
movrel_local r9, directions\w
|
||||
add r5, r9, r5, lsl #1
|
||||
vmov.u16 d17, #15
|
||||
vdup.16 d16, r6 // damping
|
||||
|
||||
.if \pri
|
||||
vdup.16 q5, r3 // threshold
|
||||
.endif
|
||||
.if \sec
|
||||
vdup.16 q7, r4 // threshold
|
||||
.endif
|
||||
vmov.16 d8[0], r3
|
||||
vmov.16 d8[1], r4
|
||||
vclz.i16 d8, d8 // clz(threshold)
|
||||
vsub.i16 d8, d17, d8 // ulog2(threshold)
|
||||
vqsub.u16 d8, d16, d8 // shift = imax(0, damping - ulog2(threshold))
|
||||
vneg.s16 d8, d8 // -shift
|
||||
.if \sec
|
||||
vdup.16 q6, d8[1]
|
||||
.endif
|
||||
.if \pri
|
||||
vdup.16 q4, d8[0]
|
||||
.endif
|
||||
|
||||
1:
|
||||
.if \w == 8
|
||||
vld1.16 {q0}, [r2, :128] // px
|
||||
.else
|
||||
add r12, r2, #2*8
|
||||
vld1.16 {d0}, [r2, :64] // px
|
||||
vld1.16 {d1}, [r12, :64] // px
|
||||
.endif
|
||||
|
||||
vmov.u16 q1, #0 // sum
|
||||
.if \min
|
||||
vmov.u16 q2, q0 // min
|
||||
vmov.u16 q3, q0 // max
|
||||
.endif
|
||||
|
||||
// Instead of loading sec_taps 2, 1 from memory, just set it
|
||||
// to 2 initially and decrease for the second round.
|
||||
// This is also used as loop counter.
|
||||
mov lr, #2 // sec_taps[0]
|
||||
|
||||
2:
|
||||
.if \pri
|
||||
ldrsb r9, [r5] // off1
|
||||
|
||||
load_px d28, d29, d30, d31, \w
|
||||
.endif
|
||||
|
||||
.if \sec
|
||||
add r5, r5, #4 // +2*2
|
||||
ldrsb r9, [r5] // off2
|
||||
.endif
|
||||
|
||||
.if \pri
|
||||
ldrb r12, [r8] // *pri_taps
|
||||
|
||||
handle_pixel q14, q15, q5, q4, r12, \min
|
||||
.endif
|
||||
|
||||
.if \sec
|
||||
load_px d28, d29, d30, d31, \w
|
||||
|
||||
add r5, r5, #8 // +2*4
|
||||
ldrsb r9, [r5] // off3
|
||||
|
||||
handle_pixel q14, q15, q7, q6, lr, \min
|
||||
|
||||
load_px d28, d29, d30, d31, \w
|
||||
|
||||
handle_pixel q14, q15, q7, q6, lr, \min
|
||||
|
||||
sub r5, r5, #11 // r5 -= 2*(2+4); r5 += 1;
|
||||
.else
|
||||
add r5, r5, #1 // r5 += 1
|
||||
.endif
|
||||
subs lr, lr, #1 // sec_tap-- (value)
|
||||
.if \pri
|
||||
add r8, r8, #1 // pri_taps++ (pointer)
|
||||
.endif
|
||||
bne 2b
|
||||
|
||||
vshr.s16 q14, q1, #15 // -(sum < 0)
|
||||
vadd.i16 q1, q1, q14 // sum - (sum < 0)
|
||||
vrshr.s16 q1, q1, #4 // (8 + sum - (sum < 0)) >> 4
|
||||
vadd.i16 q0, q0, q1 // px + (8 + sum ...) >> 4
|
||||
.if \min
|
||||
vmin.s16 q0, q0, q3
|
||||
vmax.s16 q0, q0, q2 // iclip(px + .., min, max)
|
||||
.endif
|
||||
.if \bpc == 8
|
||||
vmovn.u16 d0, q0
|
||||
.endif
|
||||
.if \w == 8
|
||||
add r2, r2, #2*16 // tmp += tmp_stride
|
||||
subs r7, r7, #1 // h--
|
||||
.if \bpc == 8
|
||||
vst1.8 {d0}, [r0, :64], r1
|
||||
.else
|
||||
vst1.16 {q0}, [r0, :128], r1
|
||||
.endif
|
||||
.else
|
||||
.if \bpc == 8
|
||||
vst1.32 {d0[0]}, [r0, :32], r1
|
||||
.else
|
||||
vst1.16 {d0}, [r0, :64], r1
|
||||
.endif
|
||||
add r2, r2, #2*16 // tmp += 2*tmp_stride
|
||||
subs r7, r7, #2 // h -= 2
|
||||
.if \bpc == 8
|
||||
vst1.32 {d0[1]}, [r0, :32], r1
|
||||
.else
|
||||
vst1.16 {d1}, [r0, :64], r1
|
||||
.endif
|
||||
.endif
|
||||
|
||||
// Reset pri_taps and directions back to the original point
|
||||
sub r5, r5, #2
|
||||
.if \pri
|
||||
sub r8, r8, #2
|
||||
.endif
|
||||
|
||||
bgt 1b
|
||||
vpop {q4-q7}
|
||||
pop {r4-r9,pc}
|
||||
endfunc
|
||||
.endm
|
||||
|
||||
.macro filter w, bpc
|
||||
filter_func \w, \bpc, pri=1, sec=0, min=0, suffix=_pri
|
||||
filter_func \w, \bpc, pri=0, sec=1, min=0, suffix=_sec
|
||||
filter_func \w, \bpc, pri=1, sec=1, min=1, suffix=_pri_sec
|
||||
|
||||
function cdef_filter\w\()_\bpc\()bpc_neon, export=1
|
||||
push {r4-r9,lr}
|
||||
vpush {q4-q7}
|
||||
ldrd r4, r5, [sp, #92]
|
||||
ldrd r6, r7, [sp, #100]
|
||||
.if \bpc == 16
|
||||
ldrd r8, r9, [sp, #108]
|
||||
.else
|
||||
ldr r8, [sp, #108]
|
||||
.endif
|
||||
cmp r3, #0 // pri_strength
|
||||
bne 1f
|
||||
b cdef_filter\w\()_sec_\bpc\()bpc_neon // only sec
|
||||
1:
|
||||
cmp r4, #0 // sec_strength
|
||||
bne 1f
|
||||
b cdef_filter\w\()_pri_\bpc\()bpc_neon // only pri
|
||||
1:
|
||||
b cdef_filter\w\()_pri_sec_\bpc\()bpc_neon // both pri and sec
|
||||
endfunc
|
||||
.endm
|
||||
|
||||
const div_table, align=4
|
||||
.short 840, 420, 280, 210, 168, 140, 120, 105
|
||||
endconst
|
||||
|
||||
const alt_fact, align=4
|
||||
.short 420, 210, 140, 105, 105, 105, 105, 105, 140, 210, 420, 0
|
||||
endconst
|
||||
|
||||
.macro cost_alt dest, s1, s2, s3, s4, s5, s6
|
||||
vmull.s16 q1, \s1, \s1 // sum_alt[n]*sum_alt[n]
|
||||
vmull.s16 q2, \s2, \s2
|
||||
vmull.s16 q3, \s3, \s3
|
||||
vmull.s16 q5, \s4, \s4 // sum_alt[n]*sum_alt[n]
|
||||
vmull.s16 q12, \s5, \s5
|
||||
vmull.s16 q6, \s6, \s6 // q6 overlaps the first \s1-\s2 here
|
||||
vmul.i32 q1, q1, q13 // sum_alt[n]^2*fact
|
||||
vmla.i32 q1, q2, q14
|
||||
vmla.i32 q1, q3, q15
|
||||
vmul.i32 q5, q5, q13 // sum_alt[n]^2*fact
|
||||
vmla.i32 q5, q12, q14
|
||||
vmla.i32 q5, q6, q15
|
||||
vadd.i32 d2, d2, d3
|
||||
vadd.i32 d3, d10, d11
|
||||
vpadd.i32 \dest, d2, d3 // *cost_ptr
|
||||
.endm
|
||||
|
||||
.macro find_best s1, s2, s3
|
||||
.ifnb \s2
|
||||
vmov.32 lr, \s2
|
||||
.endif
|
||||
cmp r12, r1 // cost[n] > best_cost
|
||||
itt gt
|
||||
movgt r0, r3 // best_dir = n
|
||||
movgt r1, r12 // best_cost = cost[n]
|
||||
.ifnb \s2
|
||||
add r3, r3, #1 // n++
|
||||
cmp lr, r1 // cost[n] > best_cost
|
||||
vmov.32 r12, \s3
|
||||
itt gt
|
||||
movgt r0, r3 // best_dir = n
|
||||
movgt r1, lr // best_cost = cost[n]
|
||||
add r3, r3, #1 // n++
|
||||
.endif
|
||||
.endm
|
||||
|
||||
// int dav1d_cdef_find_dir_Xbpc_neon(const pixel *img, const ptrdiff_t stride,
|
||||
// unsigned *const var)
|
||||
.macro find_dir bpc
|
||||
function cdef_find_dir_\bpc\()bpc_neon, export=1
|
||||
push {lr}
|
||||
vpush {q4-q7}
|
||||
.if \bpc == 16
|
||||
clz r3, r3 // clz(bitdepth_max)
|
||||
sub lr, r3, #24 // -bitdepth_min_8
|
||||
.endif
|
||||
sub sp, sp, #32 // cost
|
||||
mov r3, #8
|
||||
vmov.u16 q1, #0 // q0-q1 sum_diag[0]
|
||||
vmov.u16 q3, #0 // q2-q3 sum_diag[1]
|
||||
vmov.u16 q5, #0 // q4-q5 sum_hv[0-1]
|
||||
vmov.u16 q8, #0 // q6,d16 sum_alt[0]
|
||||
// q7,d17 sum_alt[1]
|
||||
vmov.u16 q9, #0 // q9,d22 sum_alt[2]
|
||||
vmov.u16 q11, #0
|
||||
vmov.u16 q10, #0 // q10,d23 sum_alt[3]
|
||||
|
||||
|
||||
.irpc i, 01234567
|
||||
.if \bpc == 8
|
||||
vld1.8 {d30}, [r0, :64], r1
|
||||
vmov.u8 d31, #128
|
||||
vsubl.u8 q15, d30, d31 // img[x] - 128
|
||||
.else
|
||||
vld1.16 {q15}, [r0, :128], r1
|
||||
vdup.16 q14, lr // -bitdepth_min_8
|
||||
vshl.u16 q15, q15, q14
|
||||
vmov.u16 q14, #128
|
||||
vsub.i16 q15, q15, q14 // img[x] - 128
|
||||
.endif
|
||||
vmov.u16 q14, #0
|
||||
|
||||
.if \i == 0
|
||||
vmov q0, q15 // sum_diag[0]
|
||||
.else
|
||||
vext.8 q12, q14, q15, #(16-2*\i)
|
||||
vext.8 q13, q15, q14, #(16-2*\i)
|
||||
vadd.i16 q0, q0, q12 // sum_diag[0]
|
||||
vadd.i16 q1, q1, q13 // sum_diag[0]
|
||||
.endif
|
||||
vrev64.16 q13, q15
|
||||
vswp d26, d27 // [-x]
|
||||
.if \i == 0
|
||||
vmov q2, q13 // sum_diag[1]
|
||||
.else
|
||||
vext.8 q12, q14, q13, #(16-2*\i)
|
||||
vext.8 q13, q13, q14, #(16-2*\i)
|
||||
vadd.i16 q2, q2, q12 // sum_diag[1]
|
||||
vadd.i16 q3, q3, q13 // sum_diag[1]
|
||||
.endif
|
||||
|
||||
vpadd.u16 d26, d30, d31 // [(x >> 1)]
|
||||
vmov.u16 d27, #0
|
||||
vpadd.u16 d24, d26, d28
|
||||
vpadd.u16 d24, d24, d28 // [y]
|
||||
vmov.u16 r12, d24[0]
|
||||
vadd.i16 q5, q5, q15 // sum_hv[1]
|
||||
.if \i < 4
|
||||
vmov.16 d8[\i], r12 // sum_hv[0]
|
||||
.else
|
||||
vmov.16 d9[\i-4], r12 // sum_hv[0]
|
||||
.endif
|
||||
|
||||
.if \i == 0
|
||||
vmov.u16 q6, q13 // sum_alt[0]
|
||||
.else
|
||||
vext.8 q12, q14, q13, #(16-2*\i)
|
||||
vext.8 q14, q13, q14, #(16-2*\i)
|
||||
vadd.i16 q6, q6, q12 // sum_alt[0]
|
||||
vadd.i16 d16, d16, d28 // sum_alt[0]
|
||||
.endif
|
||||
vrev64.16 d26, d26 // [-(x >> 1)]
|
||||
vmov.u16 q14, #0
|
||||
.if \i == 0
|
||||
vmov q7, q13 // sum_alt[1]
|
||||
.else
|
||||
vext.8 q12, q14, q13, #(16-2*\i)
|
||||
vext.8 q13, q13, q14, #(16-2*\i)
|
||||
vadd.i16 q7, q7, q12 // sum_alt[1]
|
||||
vadd.i16 d17, d17, d26 // sum_alt[1]
|
||||
.endif
|
||||
|
||||
.if \i < 6
|
||||
vext.8 q12, q14, q15, #(16-2*(3-(\i/2)))
|
||||
vext.8 q13, q15, q14, #(16-2*(3-(\i/2)))
|
||||
vadd.i16 q9, q9, q12 // sum_alt[2]
|
||||
vadd.i16 d22, d22, d26 // sum_alt[2]
|
||||
.else
|
||||
vadd.i16 q9, q9, q15 // sum_alt[2]
|
||||
.endif
|
||||
.if \i == 0
|
||||
vmov q10, q15 // sum_alt[3]
|
||||
.elseif \i == 1
|
||||
vadd.i16 q10, q10, q15 // sum_alt[3]
|
||||
.else
|
||||
vext.8 q12, q14, q15, #(16-2*(\i/2))
|
||||
vext.8 q13, q15, q14, #(16-2*(\i/2))
|
||||
vadd.i16 q10, q10, q12 // sum_alt[3]
|
||||
vadd.i16 d23, d23, d26 // sum_alt[3]
|
||||
.endif
|
||||
.endr
|
||||
|
||||
vmov.u32 q15, #105
|
||||
|
||||
vmull.s16 q12, d8, d8 // sum_hv[0]*sum_hv[0]
|
||||
vmlal.s16 q12, d9, d9
|
||||
vmull.s16 q13, d10, d10 // sum_hv[1]*sum_hv[1]
|
||||
vmlal.s16 q13, d11, d11
|
||||
vadd.s32 d8, d24, d25
|
||||
vadd.s32 d9, d26, d27
|
||||
vpadd.s32 d8, d8, d9 // cost[2,6] (s16, s17)
|
||||
vmul.i32 d8, d8, d30 // cost[2,6] *= 105
|
||||
|
||||
vrev64.16 q1, q1
|
||||
vrev64.16 q3, q3
|
||||
vext.8 q1, q1, q1, #10 // sum_diag[0][14-n]
|
||||
vext.8 q3, q3, q3, #10 // sum_diag[1][14-n]
|
||||
|
||||
vstr s16, [sp, #2*4] // cost[2]
|
||||
vstr s17, [sp, #6*4] // cost[6]
|
||||
|
||||
movrel_local r12, div_table
|
||||
vld1.16 {q14}, [r12, :128]
|
||||
|
||||
vmull.s16 q5, d0, d0 // sum_diag[0]*sum_diag[0]
|
||||
vmull.s16 q12, d1, d1
|
||||
vmlal.s16 q5, d2, d2
|
||||
vmlal.s16 q12, d3, d3
|
||||
vmull.s16 q0, d4, d4 // sum_diag[1]*sum_diag[1]
|
||||
vmull.s16 q1, d5, d5
|
||||
vmlal.s16 q0, d6, d6
|
||||
vmlal.s16 q1, d7, d7
|
||||
vmovl.u16 q13, d28 // div_table
|
||||
vmovl.u16 q14, d29
|
||||
vmul.i32 q5, q5, q13 // cost[0]
|
||||
vmla.i32 q5, q12, q14
|
||||
vmul.i32 q0, q0, q13 // cost[4]
|
||||
vmla.i32 q0, q1, q14
|
||||
vadd.i32 d10, d10, d11
|
||||
vadd.i32 d0, d0, d1
|
||||
vpadd.i32 d0, d10, d0 // cost[0,4] = s0,s1
|
||||
|
||||
movrel_local r12, alt_fact
|
||||
vld1.16 {d29, d30, d31}, [r12, :64] // div_table[2*m+1] + 105
|
||||
|
||||
vstr s0, [sp, #0*4] // cost[0]
|
||||
vstr s1, [sp, #4*4] // cost[4]
|
||||
|
||||
vmovl.u16 q13, d29 // div_table[2*m+1] + 105
|
||||
vmovl.u16 q14, d30
|
||||
vmovl.u16 q15, d31
|
||||
|
||||
cost_alt d14, d12, d13, d16, d14, d15, d17 // cost[1], cost[3]
|
||||
cost_alt d15, d18, d19, d22, d20, d21, d23 // cost[5], cost[7]
|
||||
vstr s28, [sp, #1*4] // cost[1]
|
||||
vstr s29, [sp, #3*4] // cost[3]
|
||||
|
||||
mov r0, #0 // best_dir
|
||||
vmov.32 r1, d0[0] // best_cost
|
||||
mov r3, #1 // n
|
||||
|
||||
vstr s30, [sp, #5*4] // cost[5]
|
||||
vstr s31, [sp, #7*4] // cost[7]
|
||||
|
||||
vmov.32 r12, d14[0]
|
||||
|
||||
find_best d14[0], d8[0], d14[1]
|
||||
find_best d14[1], d0[1], d15[0]
|
||||
find_best d15[0], d8[1], d15[1]
|
||||
find_best d15[1]
|
||||
|
||||
eor r3, r0, #4 // best_dir ^4
|
||||
ldr r12, [sp, r3, lsl #2]
|
||||
sub r1, r1, r12 // best_cost - cost[best_dir ^ 4]
|
||||
lsr r1, r1, #10
|
||||
str r1, [r2] // *var
|
||||
|
||||
add sp, sp, #32
|
||||
vpop {q4-q7}
|
||||
pop {pc}
|
||||
endfunc
|
||||
.endm
|
||||
2039
media/libdav1d/src/src/arm/32/filmgrain.S
Normal file
2039
media/libdav1d/src/src/arm/32/filmgrain.S
Normal file
File diff suppressed because it is too large
Load diff
2137
media/libdav1d/src/src/arm/32/filmgrain16.S
Normal file
2137
media/libdav1d/src/src/arm/32/filmgrain16.S
Normal file
File diff suppressed because it is too large
Load diff
2958
media/libdav1d/src/src/arm/32/ipred.S
Normal file
2958
media/libdav1d/src/src/arm/32/ipred.S
Normal file
File diff suppressed because it is too large
Load diff
3276
media/libdav1d/src/src/arm/32/ipred16.S
Normal file
3276
media/libdav1d/src/src/arm/32/ipred16.S
Normal file
File diff suppressed because it is too large
Load diff
3368
media/libdav1d/src/src/arm/32/itx.S
Normal file
3368
media/libdav1d/src/src/arm/32/itx.S
Normal file
File diff suppressed because it is too large
Load diff
3632
media/libdav1d/src/src/arm/32/itx16.S
Normal file
3632
media/libdav1d/src/src/arm/32/itx16.S
Normal file
File diff suppressed because it is too large
Load diff
868
media/libdav1d/src/src/arm/32/loopfilter.S
Normal file
868
media/libdav1d/src/src/arm/32/loopfilter.S
Normal file
|
|
@ -0,0 +1,868 @@
|
|||
/*
|
||||
* Copyright © 2018, VideoLAN and dav1d authors
|
||||
* Copyright © 2019, Martin Storsjo
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include "src/arm/asm.S"
|
||||
#include "util.S"
|
||||
|
||||
.macro loop_filter wd
|
||||
function lpf_8_wd\wd\()_neon
|
||||
vabd.u8 d0, d22, d23 // abs(p1 - p0)
|
||||
vabd.u8 d1, d25, d24 // abs(q1 - q0)
|
||||
vabd.u8 d2, d23, d24 // abs(p0 - q0)
|
||||
vabd.u8 d3, d22, d25 // abs(p1 - q1)
|
||||
.if \wd >= 6
|
||||
vabd.u8 d4, d21, d22 // abs(p2 - p1)
|
||||
vabd.u8 d5, d26, d25 // abs(q2 - q1)
|
||||
.endif
|
||||
.if \wd >= 8
|
||||
vabd.u8 d6, d20, d21 // abs(p3 - p2)
|
||||
vabd.u8 d7, d27, d26 // abs(q3 - q3)
|
||||
.endif
|
||||
.if \wd >= 6
|
||||
vmax.u8 d4, d4, d5
|
||||
.endif
|
||||
vqadd.u8 d2, d2, d2 // abs(p0 - q0) * 2
|
||||
.if \wd >= 8
|
||||
vmax.u8 d6, d6, d7
|
||||
.endif
|
||||
vshr.u8 d3, d3, #1
|
||||
.if \wd >= 8
|
||||
vmax.u8 d4, d4, d6
|
||||
.endif
|
||||
.if \wd >= 6
|
||||
vand d4, d4, d14
|
||||
.endif
|
||||
vmax.u8 d0, d0, d1 // max(abs(p1 - p0), abs(q1 - q0))
|
||||
vqadd.u8 d2, d2, d3 // abs(p0 - q0) * 2 + abs(p1 - q1) >> 1
|
||||
.if \wd >= 6
|
||||
vmax.u8 d4, d0, d4
|
||||
vcge.u8 d1, d11, d4 // max(abs(p1 - p0), abs(q1 - q0), abs(), abs(), ...) <= I
|
||||
.else
|
||||
vcge.u8 d1, d11, d0 // max(abs(p1 - p0), abs(q1 - q0)) <= I
|
||||
.endif
|
||||
vcge.u8 d2, d10, d2 // abs(p0 - q0) * 2 + abs(p1 - q1) >> 1 <= E
|
||||
vand d1, d1, d2 // fm
|
||||
vand d1, d1, d13 // fm && wd >= 4
|
||||
.if \wd >= 6
|
||||
vand d14, d14, d1 // fm && wd > 4
|
||||
.endif
|
||||
.if \wd >= 16
|
||||
vand d15, d15, d1 // fm && wd == 16
|
||||
.endif
|
||||
|
||||
vmov r10, r11, d1
|
||||
orrs r10, r10, r11
|
||||
beq 9f // if (!fm || wd < 4) return;
|
||||
|
||||
.if \wd >= 6
|
||||
vmov.i8 d10, #1
|
||||
vabd.u8 d2, d21, d23 // abs(p2 - p0)
|
||||
vabd.u8 d3, d22, d23 // abs(p1 - p0)
|
||||
vabd.u8 d4, d25, d24 // abs(q1 - q0)
|
||||
vabd.u8 d5, d26, d24 // abs(q2 - q0)
|
||||
.if \wd >= 8
|
||||
vabd.u8 d6, d20, d23 // abs(p3 - p0)
|
||||
vabd.u8 d7, d27, d24 // abs(q3 - q0)
|
||||
.endif
|
||||
vmax.u8 d2, d2, d3
|
||||
vmax.u8 d4, d4, d5
|
||||
.if \wd >= 8
|
||||
vmax.u8 d6, d6, d7
|
||||
.endif
|
||||
vmax.u8 d2, d2, d4
|
||||
.if \wd >= 8
|
||||
vmax.u8 d2, d2, d6
|
||||
.endif
|
||||
|
||||
.if \wd == 16
|
||||
vabd.u8 d3, d17, d23 // abs(p6 - p0)
|
||||
vabd.u8 d4, d18, d23 // abs(p5 - p0)
|
||||
vabd.u8 d5, d19, d23 // abs(p4 - p0)
|
||||
.endif
|
||||
vcge.u8 d2, d10, d2 // flat8in
|
||||
.if \wd == 16
|
||||
vabd.u8 d6, d28, d24 // abs(q4 - q0)
|
||||
vabd.u8 d7, d29, d24 // abs(q5 - q0)
|
||||
vabd.u8 d8, d30, d24 // abs(q6 - q0)
|
||||
.endif
|
||||
vand d14, d2, d14 // flat8in && fm && wd > 4
|
||||
vbic d1, d1, d14 // fm && wd >= 4 && !flat8in
|
||||
.if \wd == 16
|
||||
vmax.u8 d3, d3, d4
|
||||
vmax.u8 d5, d5, d6
|
||||
.endif
|
||||
vmov r10, r11, d1
|
||||
.if \wd == 16
|
||||
vmax.u8 d7, d7, d8
|
||||
vmax.u8 d3, d3, d5
|
||||
vmax.u8 d3, d3, d7
|
||||
vcge.u8 d3, d10, d3 // flat8out
|
||||
.endif
|
||||
orrs r10, r10, r11
|
||||
.if \wd == 16
|
||||
vand d15, d15, d3 // flat8out && fm && wd == 16
|
||||
vand d15, d15, d14 // flat8out && flat8in && fm && wd == 16
|
||||
vbic d14, d14, d15 // flat8in && fm && wd >= 4 && !flat8out
|
||||
.endif
|
||||
beq 1f // skip wd == 4 case
|
||||
.endif
|
||||
|
||||
vsubl.u8 q1, d22, d25 // p1 - q1
|
||||
vcgt.u8 d0, d0, d12 // hev
|
||||
vqmovn.s16 d2, q1
|
||||
vand d4, d2, d0 // if (hev) iclip_diff(p1 - q1)
|
||||
vbic d0, d1, d0 // (fm && wd >= 4 && !hev)
|
||||
vsubl.u8 q1, d24, d23
|
||||
vmov.i16 q3, #3
|
||||
vmul.i16 q1, q1, q3
|
||||
vmov.i8 d6, #4
|
||||
vaddw.s8 q1, q1, d4
|
||||
vmov.i8 d7, #3
|
||||
vqmovn.s16 d2, q1 // f
|
||||
vqadd.s8 d4, d6, d2 // imin(f + 4, 127)
|
||||
vqadd.s8 d5, d7, d2 // imin(f + 3, 127)
|
||||
vshr.s8 d4, d4, #3 // f1
|
||||
vshr.s8 d5, d5, #3 // f2
|
||||
vmovl.u8 q1, d23 // p0
|
||||
vmovl.u8 q3, d24 // q0
|
||||
vaddw.s8 q1, q1, d5
|
||||
vsubw.s8 q3, q3, d4
|
||||
vrshr.s8 d4, d4, #1 // (f1 + 1) >> 1
|
||||
vqmovun.s16 d2, q1 // out p0
|
||||
vqmovun.s16 d6, q3 // out q0
|
||||
vbit d23, d2, d1 // if (fm && wd >= 4)
|
||||
vmovl.u8 q1, d22 // p1
|
||||
vbit d24, d6, d1 // if (fm && wd >= 4)
|
||||
vmovl.u8 q3, d25 // q1
|
||||
vaddw.s8 q1, q1, d4
|
||||
vsubw.s8 q3, q3, d4
|
||||
vqmovun.s16 d2, q1 // out p1
|
||||
vqmovun.s16 d6, q3 // out q1
|
||||
vbit d22, d2, d0 // if (fm && wd >= 4 && !hev)
|
||||
vbit d25, d6, d0 // if (fm && wd >= 4 && !hev)
|
||||
1:
|
||||
|
||||
.if \wd == 6
|
||||
vmov r10, r11, d14
|
||||
orrs r10, r10, r11
|
||||
beq 2f // skip if there's no flat8in
|
||||
|
||||
vaddl.u8 q0, d21, d21 // p2 * 2
|
||||
vaddl.u8 q1, d21, d22 // p2 + p1
|
||||
vaddl.u8 q2, d22, d23 // p1 + p0
|
||||
vaddl.u8 q3, d23, d24 // p0 + q0
|
||||
vadd.i16 q4, q0, q1
|
||||
vadd.i16 q5, q2, q3
|
||||
vaddl.u8 q6, d24, d25 // q0 + q1
|
||||
vadd.i16 q4, q4, q5
|
||||
vsub.i16 q6, q6, q0
|
||||
vaddl.u8 q5, d25, d26 // q1 + q2
|
||||
vrshrn.i16 d0, q4, #3 // out p1
|
||||
|
||||
vadd.i16 q4, q4, q6
|
||||
vsub.i16 q5, q5, q1
|
||||
vaddl.u8 q6, d26, d26 // q2 + q2
|
||||
vrshrn.i16 d1, q4, #3 // out p0
|
||||
|
||||
vadd.i16 q4, q4, q5
|
||||
vsub.i16 q6, q6, q2
|
||||
vrshrn.i16 d2, q4, #3 // out q0
|
||||
|
||||
vbit d22, d0, d14 // p1 if (flat8in)
|
||||
vadd.i16 q4, q4, q6
|
||||
vbit d23, d1, d14 // p0 if (flat8in)
|
||||
vrshrn.i16 d3, q4, #3 // out q1
|
||||
vbit d24, d2, d14 // q0 if (flat8in)
|
||||
vbit d25, d3, d14 // q1 if (flat8in)
|
||||
.elseif \wd >= 8
|
||||
vmov r10, r11, d14
|
||||
orrs r10, r10, r11
|
||||
.if \wd == 8
|
||||
beq 8f // skip if there's no flat8in
|
||||
.else
|
||||
beq 2f // skip if there's no flat8in
|
||||
.endif
|
||||
|
||||
vaddl.u8 q0, d20, d21 // p3 + p2
|
||||
vaddl.u8 q1, d22, d25 // p1 + q1
|
||||
vaddl.u8 q2, d20, d22 // p3 + p1
|
||||
vaddl.u8 q3, d23, d26 // p0 + q2
|
||||
vadd.i16 q4, q0, q0 // 2 * (p3 + p2)
|
||||
vaddw.u8 q4, q4, d23 // + p0
|
||||
vaddw.u8 q4, q4, d24 // + q0
|
||||
vadd.i16 q4, q4, q2 // + p3 + p1
|
||||
vsub.i16 q1, q1, q0 // p1 + q1 - p3 - p2
|
||||
vsub.i16 q3, q3, q2 // p0 + q2 - p3 - p1
|
||||
vrshrn.i16 d10, q4, #3 // out p2
|
||||
|
||||
vadd.i16 q4, q4, q1
|
||||
vaddl.u8 q0, d20, d23 // p3 + p0
|
||||
vaddl.u8 q1, d24, d27 // q0 + q3
|
||||
vrshrn.i16 d11, q4, #3 // out p1
|
||||
|
||||
vadd.i16 q4, q4, q3
|
||||
vsub.i16 q1, q1, q0 // q0 + q3 - p3 - p0
|
||||
vaddl.u8 q2, d21, d24 // p2 + q0
|
||||
vaddl.u8 q3, d25, d27 // q1 + q3
|
||||
vrshrn.i16 d12, q4, #3 // out p0
|
||||
|
||||
vadd.i16 q4, q4, q1
|
||||
vsub.i16 q3, q3, q2 // q1 + q3 - p2 - q0
|
||||
vaddl.u8 q0, d22, d25 // p1 + q1
|
||||
vaddl.u8 q1, d26, d27 // q2 + q3
|
||||
vrshrn.i16 d13, q4, #3 // out q0
|
||||
|
||||
vadd.i16 q4, q4, q3
|
||||
vsub.i16 q1, q1, q0 // q2 + q3 - p1 - q1
|
||||
vrshrn.i16 d0, q4, #3 // out q1
|
||||
|
||||
vadd.i16 q4, q4, q1
|
||||
|
||||
vbit d21, d10, d14
|
||||
vbit d22, d11, d14
|
||||
vbit d23, d12, d14
|
||||
vrshrn.i16 d1, q4, #3 // out q2
|
||||
vbit d24, d13, d14
|
||||
vbit d25, d0, d14
|
||||
vbit d26, d1, d14
|
||||
.endif
|
||||
2:
|
||||
.if \wd == 16
|
||||
vmov r10, r11, d15
|
||||
orrs r10, r10, r11
|
||||
bne 1f // check if flat8out is needed
|
||||
vmov r10, r11, d14
|
||||
orrs r10, r10, r11
|
||||
beq 8f // if there was no flat8in, just write the inner 4 pixels
|
||||
b 7f // if flat8in was used, write the inner 6 pixels
|
||||
1:
|
||||
|
||||
vaddl.u8 q1, d17, d17 // p6 + p6
|
||||
vaddl.u8 q2, d17, d18 // p6 + p5
|
||||
vaddl.u8 q3, d17, d19 // p6 + p4
|
||||
vaddl.u8 q4, d17, d20 // p6 + p3
|
||||
vadd.i16 q6, q1, q2
|
||||
vadd.i16 q5, q3, q4
|
||||
vaddl.u8 q3, d17, d21 // p6 + p2
|
||||
vadd.i16 q6, q6, q5
|
||||
vaddl.u8 q4, d17, d22 // p6 + p1
|
||||
vaddl.u8 q5, d18, d23 // p5 + p0
|
||||
vadd.i16 q3, q3, q4
|
||||
vaddl.u8 q4, d19, d24 // p4 + q0
|
||||
vadd.i16 q6, q6, q3
|
||||
vadd.i16 q5, q5, q4
|
||||
vaddl.u8 q3, d20, d25 // p3 + q1
|
||||
vadd.i16 q6, q6, q5
|
||||
vsub.i16 q3, q3, q1
|
||||
vaddl.u8 q1, d21, d26 // p2 + q2
|
||||
vrshrn.i16 d0, q6, #4 // out p5
|
||||
vadd.i16 q6, q6, q3 // - (p6 + p6) + (p3 + q1)
|
||||
vsub.i16 q1, q1, q2
|
||||
vaddl.u8 q2, d22, d27 // p1 + q3
|
||||
vaddl.u8 q3, d17, d19 // p6 + p4
|
||||
vrshrn.i16 d1, q6, #4 // out p4
|
||||
vadd.i16 q6, q6, q1 // - (p6 + p5) + (p2 + q2)
|
||||
vsub.i16 q2, q2, q3
|
||||
vaddl.u8 q3, d23, d28 // p0 + q4
|
||||
vaddl.u8 q4, d17, d20 // p6 + p3
|
||||
vrshrn.i16 d2, q6, #4 // out p3
|
||||
vadd.i16 q6, q6, q2 // - (p6 + p4) + (p1 + q3)
|
||||
vsub.i16 q3, q3, q4
|
||||
vaddl.u8 q4, d24, d29 // q0 + q5
|
||||
vaddl.u8 q2, d17, d21 // p6 + p2
|
||||
vrshrn.i16 d3, q6, #4 // out p2
|
||||
vadd.i16 q6, q6, q3 // - (p6 + p3) + (p0 + q4)
|
||||
vsub.i16 q4, q4, q2
|
||||
vaddl.u8 q3, d25, d30 // q1 + q6
|
||||
vaddl.u8 q5, d17, d22 // p6 + p1
|
||||
vrshrn.i16 d4, q6, #4 // out p1
|
||||
vadd.i16 q6, q6, q4 // - (p6 + p2) + (q0 + q5)
|
||||
vsub.i16 q3, q3, q5
|
||||
vaddl.u8 q4, d26, d30 // q2 + q6
|
||||
vbif d0, d18, d15 // out p5
|
||||
vaddl.u8 q5, d18, d23 // p5 + p0
|
||||
vrshrn.i16 d5, q6, #4 // out p0
|
||||
vadd.i16 q6, q6, q3 // - (p6 + p1) + (q1 + q6)
|
||||
vsub.i16 q4, q4, q5
|
||||
vaddl.u8 q5, d27, d30 // q3 + q6
|
||||
vbif d1, d19, d15 // out p4
|
||||
vaddl.u8 q9, d19, d24 // p4 + q0
|
||||
vrshrn.i16 d6, q6, #4 // out q0
|
||||
vadd.i16 q6, q6, q4 // - (p5 + p0) + (q2 + q6)
|
||||
vsub.i16 q5, q5, q9
|
||||
vaddl.u8 q4, d28, d30 // q4 + q6
|
||||
vbif d2, d20, d15 // out p3
|
||||
vaddl.u8 q9, d20, d25 // p3 + q1
|
||||
vrshrn.i16 d7, q6, #4 // out q1
|
||||
vadd.i16 q6, q6, q5 // - (p4 + q0) + (q3 + q6)
|
||||
vsub.i16 q9, q4, q9
|
||||
vaddl.u8 q5, d29, d30 // q5 + q6
|
||||
vbif d3, d21, d15 // out p2
|
||||
vaddl.u8 q10, d21, d26 // p2 + q2
|
||||
vrshrn.i16 d8, q6, #4 // out q2
|
||||
vadd.i16 q6, q6, q9 // - (p3 + q1) + (q4 + q6)
|
||||
vsub.i16 q5, q5, q10
|
||||
vaddl.u8 q9, d30, d30 // q6 + q6
|
||||
vbif d4, d22, d15 // out p1
|
||||
vaddl.u8 q10, d22, d27 // p1 + q3
|
||||
vrshrn.i16 d9, q6, #4 // out q3
|
||||
vadd.i16 q6, q6, q5 // - (p2 + q2) + (q5 + q6)
|
||||
vsub.i16 q9, q9, q10
|
||||
vbif d5, d23, d15 // out p0
|
||||
vrshrn.i16 d10, q6, #4 // out q4
|
||||
vadd.i16 q6, q6, q9 // - (p1 + q3) + (q6 + q6)
|
||||
vrshrn.i16 d11, q6, #4 // out q5
|
||||
vbif d6, d24, d15 // out q0
|
||||
vbif d7, d25, d15 // out q1
|
||||
vbif d8, d26, d15 // out q2
|
||||
vbif d9, d27, d15 // out q3
|
||||
vbif d10, d28, d15 // out q4
|
||||
vbif d11, d29, d15 // out q5
|
||||
.endif
|
||||
|
||||
bx lr
|
||||
.if \wd == 16
|
||||
7:
|
||||
// Return to a shorter epilogue, writing only the inner 6 pixels
|
||||
bx r8
|
||||
.endif
|
||||
.if \wd >= 8
|
||||
8:
|
||||
// Return to a shorter epilogue, writing only the inner 4 pixels
|
||||
bx r9
|
||||
.endif
|
||||
9:
|
||||
// Return directly without writing back any pixels
|
||||
bx r12
|
||||
endfunc
|
||||
.endm
|
||||
|
||||
loop_filter 16
|
||||
loop_filter 8
|
||||
loop_filter 6
|
||||
loop_filter 4
|
||||
|
||||
.macro lpf_8_wd16
|
||||
adr r8, 7f + CONFIG_THUMB
|
||||
adr r9, 8f + CONFIG_THUMB
|
||||
bl lpf_8_wd16_neon
|
||||
.endm
|
||||
|
||||
.macro lpf_8_wd8
|
||||
adr r9, 8f + CONFIG_THUMB
|
||||
bl lpf_8_wd8_neon
|
||||
.endm
|
||||
|
||||
.macro lpf_8_wd6
|
||||
bl lpf_8_wd6_neon
|
||||
.endm
|
||||
|
||||
.macro lpf_8_wd4
|
||||
bl lpf_8_wd4_neon
|
||||
.endm
|
||||
|
||||
function lpf_v_4_8_neon
|
||||
mov r12, lr
|
||||
sub r10, r0, r1, lsl #1
|
||||
vld1.8 {d22}, [r10, :64], r1 // p1
|
||||
vld1.8 {d24}, [r0, :64], r1 // q0
|
||||
vld1.8 {d23}, [r10, :64], r1 // p0
|
||||
vld1.8 {d25}, [r0, :64], r1 // q1
|
||||
sub r0, r0, r1, lsl #1
|
||||
|
||||
lpf_8_wd4
|
||||
|
||||
sub r10, r0, r1, lsl #1
|
||||
vst1.8 {d22}, [r10, :64], r1 // p1
|
||||
vst1.8 {d24}, [r0, :64], r1 // q0
|
||||
vst1.8 {d23}, [r10, :64], r1 // p0
|
||||
vst1.8 {d25}, [r0, :64], r1 // q1
|
||||
sub r0, r0, r1, lsl #1
|
||||
bx r12
|
||||
endfunc
|
||||
|
||||
function lpf_h_4_8_neon
|
||||
mov r12, lr
|
||||
sub r10, r0, #2
|
||||
add r0, r10, r1, lsl #2
|
||||
vld1.32 {d22[0]}, [r10], r1
|
||||
vld1.32 {d22[1]}, [r0], r1
|
||||
vld1.32 {d23[0]}, [r10], r1
|
||||
vld1.32 {d23[1]}, [r0], r1
|
||||
vld1.32 {d24[0]}, [r10], r1
|
||||
vld1.32 {d24[1]}, [r0], r1
|
||||
vld1.32 {d25[0]}, [r10], r1
|
||||
vld1.32 {d25[1]}, [r0], r1
|
||||
add r0, r0, #2
|
||||
|
||||
transpose_4x8b q11, q12, d22, d23, d24, d25
|
||||
|
||||
lpf_8_wd4
|
||||
|
||||
sub r10, r0, r1, lsl #3
|
||||
sub r10, r10, #2
|
||||
transpose_4x8b q11, q12, d22, d23, d24, d25
|
||||
add r0, r10, r1, lsl #2
|
||||
|
||||
vst1.32 {d22[0]}, [r10], r1
|
||||
vst1.32 {d22[1]}, [r0], r1
|
||||
vst1.32 {d23[0]}, [r10], r1
|
||||
vst1.32 {d23[1]}, [r0], r1
|
||||
vst1.32 {d24[0]}, [r10], r1
|
||||
vst1.32 {d24[1]}, [r0], r1
|
||||
vst1.32 {d25[0]}, [r10], r1
|
||||
vst1.32 {d25[1]}, [r0], r1
|
||||
add r0, r0, #2
|
||||
bx r12
|
||||
endfunc
|
||||
|
||||
function lpf_v_6_8_neon
|
||||
mov r12, lr
|
||||
sub r10, r0, r1, lsl #1
|
||||
sub r10, r10, r1
|
||||
vld1.8 {d21}, [r10, :64], r1 // p2
|
||||
vld1.8 {d24}, [r0, :64], r1 // q0
|
||||
vld1.8 {d22}, [r10, :64], r1 // p1
|
||||
vld1.8 {d25}, [r0, :64], r1 // q1
|
||||
vld1.8 {d23}, [r10, :64], r1 // p0
|
||||
vld1.8 {d26}, [r0, :64], r1 // q2
|
||||
sub r0, r0, r1, lsl #1
|
||||
sub r0, r0, r1
|
||||
|
||||
lpf_8_wd6
|
||||
|
||||
sub r10, r0, r1, lsl #1
|
||||
vst1.8 {d22}, [r10, :64], r1 // p1
|
||||
vst1.8 {d24}, [r0, :64], r1 // q0
|
||||
vst1.8 {d23}, [r10, :64], r1 // p0
|
||||
vst1.8 {d25}, [r0, :64], r1 // q1
|
||||
sub r0, r0, r1, lsl #1
|
||||
bx r12
|
||||
endfunc
|
||||
|
||||
function lpf_h_6_8_neon
|
||||
mov r12, lr
|
||||
sub r10, r0, #4
|
||||
add r0, r10, r1, lsl #2
|
||||
vld1.8 {d20}, [r10], r1
|
||||
vld1.8 {d24}, [r0], r1
|
||||
vld1.8 {d21}, [r10], r1
|
||||
vld1.8 {d25}, [r0], r1
|
||||
vld1.8 {d22}, [r10], r1
|
||||
vld1.8 {d26}, [r0], r1
|
||||
vld1.8 {d23}, [r10], r1
|
||||
vld1.8 {d27}, [r0], r1
|
||||
add r0, r0, #4
|
||||
|
||||
transpose_8x8b q10, q11, q12, q13, d20, d21, d22, d23, d24, d25, d26, d27
|
||||
|
||||
lpf_8_wd6
|
||||
|
||||
sub r10, r0, r1, lsl #3
|
||||
sub r10, r10, #2
|
||||
transpose_4x8b q11, q12, d22, d23, d24, d25
|
||||
add r0, r10, r1, lsl #2
|
||||
|
||||
vst1.32 {d22[0]}, [r10], r1
|
||||
vst1.32 {d22[1]}, [r0], r1
|
||||
vst1.32 {d23[0]}, [r10], r1
|
||||
vst1.32 {d23[1]}, [r0], r1
|
||||
vst1.32 {d24[0]}, [r10], r1
|
||||
vst1.32 {d24[1]}, [r0], r1
|
||||
vst1.32 {d25[0]}, [r10], r1
|
||||
vst1.32 {d25[1]}, [r0], r1
|
||||
add r0, r0, #2
|
||||
bx r12
|
||||
endfunc
|
||||
|
||||
function lpf_v_8_8_neon
|
||||
mov r12, lr
|
||||
sub r10, r0, r1, lsl #2
|
||||
vld1.8 {d20}, [r10, :64], r1 // p3
|
||||
vld1.8 {d24}, [r0, :64], r1 // q0
|
||||
vld1.8 {d21}, [r10, :64], r1 // p2
|
||||
vld1.8 {d25}, [r0, :64], r1 // q1
|
||||
vld1.8 {d22}, [r10, :64], r1 // p1
|
||||
vld1.8 {d26}, [r0, :64], r1 // q2
|
||||
vld1.8 {d23}, [r10, :64], r1 // p0
|
||||
vld1.8 {d27}, [r0, :64], r1 // q3
|
||||
sub r0, r0, r1, lsl #2
|
||||
|
||||
lpf_8_wd8
|
||||
|
||||
sub r10, r0, r1, lsl #1
|
||||
sub r10, r10, r1
|
||||
vst1.8 {d21}, [r10, :64], r1 // p2
|
||||
vst1.8 {d24}, [r0, :64], r1 // q0
|
||||
vst1.8 {d22}, [r10, :64], r1 // p1
|
||||
vst1.8 {d25}, [r0, :64], r1 // q1
|
||||
vst1.8 {d23}, [r10, :64], r1 // p0
|
||||
vst1.8 {d26}, [r0, :64], r1 // q2
|
||||
sub r0, r0, r1, lsl #1
|
||||
sub r0, r0, r1
|
||||
bx r12
|
||||
|
||||
8:
|
||||
sub r10, r0, r1, lsl #1
|
||||
vst1.8 {d22}, [r10, :64], r1 // p1
|
||||
vst1.8 {d24}, [r0, :64], r1 // q0
|
||||
vst1.8 {d23}, [r10, :64], r1 // p0
|
||||
vst1.8 {d25}, [r0, :64], r1 // q1
|
||||
sub r0, r0, r1, lsl #1
|
||||
bx r12
|
||||
endfunc
|
||||
|
||||
function lpf_h_8_8_neon
|
||||
mov r12, lr
|
||||
sub r10, r0, #4
|
||||
add r0, r10, r1, lsl #2
|
||||
vld1.8 {d20}, [r10], r1
|
||||
vld1.8 {d24}, [r0], r1
|
||||
vld1.8 {d21}, [r10], r1
|
||||
vld1.8 {d25}, [r0], r1
|
||||
vld1.8 {d22}, [r10], r1
|
||||
vld1.8 {d26}, [r0], r1
|
||||
vld1.8 {d23}, [r10], r1
|
||||
vld1.8 {d27}, [r0], r1
|
||||
add r0, r0, #4
|
||||
|
||||
transpose_8x8b q10, q11, q12, q13, d20, d21, d22, d23, d24, d25, d26, d27
|
||||
|
||||
lpf_8_wd8
|
||||
|
||||
sub r10, r0, r1, lsl #3
|
||||
sub r10, r10, #4
|
||||
transpose_8x8b q10, q11, q12, q13, d20, d21, d22, d23, d24, d25, d26, d27
|
||||
add r0, r10, r1, lsl #2
|
||||
|
||||
vst1.8 {d20}, [r10], r1
|
||||
vst1.8 {d24}, [r0], r1
|
||||
vst1.8 {d21}, [r10], r1
|
||||
vst1.8 {d25}, [r0], r1
|
||||
vst1.8 {d22}, [r10], r1
|
||||
vst1.8 {d26}, [r0], r1
|
||||
vst1.8 {d23}, [r10], r1
|
||||
vst1.8 {d27}, [r0], r1
|
||||
add r0, r0, #4
|
||||
bx r12
|
||||
8:
|
||||
sub r10, r0, r1, lsl #3
|
||||
sub r10, r10, #2
|
||||
transpose_4x8b q11, q12, d22, d23, d24, d25
|
||||
add r0, r10, r1, lsl #2
|
||||
|
||||
vst1.32 {d22[0]}, [r10], r1
|
||||
vst1.32 {d22[1]}, [r0], r1
|
||||
vst1.32 {d23[0]}, [r10], r1
|
||||
vst1.32 {d23[1]}, [r0], r1
|
||||
vst1.32 {d24[0]}, [r10], r1
|
||||
vst1.32 {d24[1]}, [r0], r1
|
||||
vst1.32 {d25[0]}, [r10], r1
|
||||
vst1.32 {d25[1]}, [r0], r1
|
||||
add r0, r0, #2
|
||||
bx r12
|
||||
endfunc
|
||||
|
||||
function lpf_v_16_8_neon
|
||||
mov r12, lr
|
||||
|
||||
sub r10, r0, r1, lsl #3
|
||||
add r10, r10, r1
|
||||
vld1.8 {d17}, [r10, :64], r1 // p6
|
||||
vld1.8 {d24}, [r0, :64], r1 // q0
|
||||
vld1.8 {d18}, [r10, :64], r1 // p5
|
||||
vld1.8 {d25}, [r0, :64], r1 // q1
|
||||
vld1.8 {d19}, [r10, :64], r1 // p4
|
||||
vld1.8 {d26}, [r0, :64], r1 // q2
|
||||
vld1.8 {d20}, [r10, :64], r1 // p3
|
||||
vld1.8 {d27}, [r0, :64], r1 // q3
|
||||
vld1.8 {d21}, [r10, :64], r1 // p2
|
||||
vld1.8 {d28}, [r0, :64], r1 // q4
|
||||
vld1.8 {d22}, [r10, :64], r1 // p1
|
||||
vld1.8 {d29}, [r0, :64], r1 // q5
|
||||
vld1.8 {d23}, [r10, :64], r1 // p0
|
||||
vld1.8 {d30}, [r0, :64], r1 // q6
|
||||
sub r0, r0, r1, lsl #3
|
||||
add r0, r0, r1
|
||||
|
||||
lpf_8_wd16
|
||||
|
||||
sub r10, r0, r1, lsl #2
|
||||
sub r10, r10, r1, lsl #1
|
||||
vst1.8 {d0}, [r10, :64], r1 // p5
|
||||
vst1.8 {d6}, [r0, :64], r1 // q0
|
||||
vst1.8 {d1}, [r10, :64], r1 // p4
|
||||
vst1.8 {d7}, [r0, :64], r1 // q1
|
||||
vst1.8 {d2}, [r10, :64], r1 // p3
|
||||
vst1.8 {d8}, [r0, :64], r1 // q2
|
||||
vst1.8 {d3}, [r10, :64], r1 // p2
|
||||
vst1.8 {d9}, [r0, :64], r1 // q3
|
||||
vst1.8 {d4}, [r10, :64], r1 // p1
|
||||
vst1.8 {d10}, [r0, :64], r1 // q4
|
||||
vst1.8 {d5}, [r10, :64], r1 // p0
|
||||
vst1.8 {d11}, [r0, :64], r1 // q5
|
||||
sub r0, r0, r1, lsl #2
|
||||
sub r0, r0, r1, lsl #1
|
||||
bx r12
|
||||
7:
|
||||
sub r10, r0, r1
|
||||
sub r10, r10, r1, lsl #1
|
||||
vst1.8 {d21}, [r10, :64], r1 // p2
|
||||
vst1.8 {d24}, [r0, :64], r1 // q0
|
||||
vst1.8 {d22}, [r10, :64], r1 // p1
|
||||
vst1.8 {d25}, [r0, :64], r1 // q1
|
||||
vst1.8 {d23}, [r10, :64], r1 // p0
|
||||
vst1.8 {d26}, [r0, :64], r1 // q2
|
||||
sub r0, r0, r1, lsl #1
|
||||
sub r0, r0, r1
|
||||
bx r12
|
||||
|
||||
8:
|
||||
sub r10, r0, r1, lsl #1
|
||||
vst1.8 {d22}, [r10, :64], r1 // p1
|
||||
vst1.8 {d24}, [r0, :64], r1 // q0
|
||||
vst1.8 {d23}, [r10, :64], r1 // p0
|
||||
vst1.8 {d25}, [r0, :64], r1 // q1
|
||||
sub r0, r0, r1, lsl #1
|
||||
bx r12
|
||||
endfunc
|
||||
|
||||
function lpf_h_16_8_neon
|
||||
mov r12, lr
|
||||
sub r10, r0, #8
|
||||
vld1.8 {d16}, [r10, :64], r1
|
||||
vld1.8 {d24}, [r0, :64], r1
|
||||
vld1.8 {d17}, [r10, :64], r1
|
||||
vld1.8 {d25}, [r0, :64], r1
|
||||
vld1.8 {d18}, [r10, :64], r1
|
||||
vld1.8 {d26}, [r0, :64], r1
|
||||
vld1.8 {d19}, [r10, :64], r1
|
||||
vld1.8 {d27}, [r0, :64], r1
|
||||
vld1.8 {d20}, [r10, :64], r1
|
||||
vld1.8 {d28}, [r0, :64], r1
|
||||
vld1.8 {d21}, [r10, :64], r1
|
||||
vld1.8 {d29}, [r0, :64], r1
|
||||
vld1.8 {d22}, [r10, :64], r1
|
||||
vld1.8 {d30}, [r0, :64], r1
|
||||
vld1.8 {d23}, [r10, :64], r1
|
||||
vld1.8 {d31}, [r0, :64], r1
|
||||
|
||||
transpose_8x8b q8, q9, q10, q11, d16, d17, d18, d19, d20, d21, d22, d23
|
||||
transpose_8x8b q12, q13, q14, q15, d24, d25, d26, d27, d28, d29, d30, d31
|
||||
|
||||
lpf_8_wd16
|
||||
|
||||
sub r0, r0, r1, lsl #3
|
||||
sub r10, r0, #8
|
||||
|
||||
transpose_8x8b q8, q0, q1, q2, d16, d17, d0, d1, d2, d3, d4, d5
|
||||
transpose_8x8b q3, q4, q5, q15, d6, d7, d8, d9, d10, d11, d30, d31
|
||||
|
||||
vst1.8 {d16}, [r10, :64], r1
|
||||
vst1.8 {d6}, [r0, :64], r1
|
||||
vst1.8 {d17}, [r10, :64], r1
|
||||
vst1.8 {d7}, [r0, :64], r1
|
||||
vst1.8 {d0}, [r10, :64], r1
|
||||
vst1.8 {d8}, [r0, :64], r1
|
||||
vst1.8 {d1}, [r10, :64], r1
|
||||
vst1.8 {d9}, [r0, :64], r1
|
||||
vst1.8 {d2}, [r10, :64], r1
|
||||
vst1.8 {d10}, [r0, :64], r1
|
||||
vst1.8 {d3}, [r10, :64], r1
|
||||
vst1.8 {d11}, [r0, :64], r1
|
||||
vst1.8 {d4}, [r10, :64], r1
|
||||
vst1.8 {d30}, [r0, :64], r1
|
||||
vst1.8 {d5}, [r10, :64], r1
|
||||
vst1.8 {d31}, [r0, :64], r1
|
||||
bx r12
|
||||
|
||||
7:
|
||||
sub r10, r0, r1, lsl #3
|
||||
sub r10, r10, #4
|
||||
transpose_8x8b q10, q11, q12, q13, d20, d21, d22, d23, d24, d25, d26, d27
|
||||
add r0, r10, r1, lsl #2
|
||||
|
||||
vst1.8 {d20}, [r10], r1
|
||||
vst1.8 {d24}, [r0], r1
|
||||
vst1.8 {d21}, [r10], r1
|
||||
vst1.8 {d25}, [r0], r1
|
||||
vst1.8 {d22}, [r10], r1
|
||||
vst1.8 {d26}, [r0], r1
|
||||
vst1.8 {d23}, [r10], r1
|
||||
vst1.8 {d27}, [r0], r1
|
||||
add r0, r0, #4
|
||||
bx r12
|
||||
8:
|
||||
sub r10, r0, r1, lsl #3
|
||||
sub r10, r10, #2
|
||||
transpose_4x8b q11, q12, d22, d23, d24, d25
|
||||
add r0, r10, r1, lsl #2
|
||||
|
||||
vst1.32 {d22[0]}, [r10], r1
|
||||
vst1.32 {d22[1]}, [r0], r1
|
||||
vst1.32 {d23[0]}, [r10], r1
|
||||
vst1.32 {d23[1]}, [r0], r1
|
||||
vst1.32 {d24[0]}, [r10], r1
|
||||
vst1.32 {d24[1]}, [r0], r1
|
||||
vst1.32 {d25[0]}, [r10], r1
|
||||
vst1.32 {d25[1]}, [r0], r1
|
||||
add r0, r0, #2
|
||||
bx r12
|
||||
endfunc
|
||||
|
||||
// void dav1d_lpf_v_sb_y_8bpc_neon(pixel *dst, const ptrdiff_t stride,
|
||||
// const uint32_t *const vmask,
|
||||
// const uint8_t (*l)[4], ptrdiff_t b4_stride,
|
||||
// const Av1FilterLUT *lut, const int w)
|
||||
|
||||
.macro lpf_func dir, type
|
||||
function lpf_\dir\()_sb_\type\()_8bpc_neon, export=1
|
||||
push {r4-r11,lr}
|
||||
vpush {q4-q7}
|
||||
ldrd r4, r5, [sp, #100]
|
||||
ldrd r6, r7, [r2] // vmask[0], vmask[1]
|
||||
.ifc \type, y
|
||||
ldr r2, [r2, #8] // vmask[2]
|
||||
.endif
|
||||
add r5, r5, #128 // Move to sharp part of lut
|
||||
.ifc \type, y
|
||||
orr r7, r7, r2 // vmask[1] |= vmask[2]
|
||||
.endif
|
||||
.ifc \dir, v
|
||||
sub r4, r3, r4, lsl #2
|
||||
.else
|
||||
sub r3, r3, #4
|
||||
lsl r4, r4, #2
|
||||
.endif
|
||||
orr r6, r6, r7 // vmask[0] |= vmask[1]
|
||||
|
||||
1:
|
||||
tst r6, #0x03
|
||||
.ifc \dir, v
|
||||
vld1.8 {d0}, [r4]!
|
||||
vld1.8 {d1}, [r3]!
|
||||
.else
|
||||
vld2.32 {d0[0], d1[0]}, [r3], r4
|
||||
vld2.32 {d0[1], d1[1]}, [r3], r4
|
||||
.endif
|
||||
beq 7f // if (!(vm & bits)) continue;
|
||||
|
||||
vld1.8 {d5[]}, [r5] // sharp[0]
|
||||
add r5, r5, #8
|
||||
vmov.i32 d2, #0xff
|
||||
vdup.32 d13, r6 // vmask[0]
|
||||
|
||||
vand d0, d0, d2 // Keep only lowest byte in each 32 bit word
|
||||
vand d1, d1, d2
|
||||
vtst.8 d3, d1, d2 // Check for nonzero values in l[0][0]
|
||||
vmov.i8 d4, #1
|
||||
vld1.8 {d6[]}, [r5] // sharp[1]
|
||||
sub r5, r5, #8
|
||||
vbif d1, d0, d3 // if (!l[0][0]) L = l[offset][0]
|
||||
vtst.32 d2, d1, d2 // L != 0
|
||||
vmul.i32 d1, d1, d4 // L
|
||||
.ifc \type, y
|
||||
vdup.32 d15, r2 // vmask[2]
|
||||
.endif
|
||||
vdup.32 d14, r7 // vmask[1]
|
||||
vmov r10, r11, d2
|
||||
orrs r10, r10, r11
|
||||
beq 7f // if (!L) continue;
|
||||
vneg.s8 d5, d5 // -sharp[0]
|
||||
movrel_local r10, word_12
|
||||
vshr.u8 d12, d1, #4 // H
|
||||
vld1.32 {d16}, [r10, :64]
|
||||
vshl.s8 d3, d1, d5 // L >> sharp[0]
|
||||
.ifc \type, y
|
||||
vtst.32 d15, d15, d16 // if (vmask[2] & bits)
|
||||
.endif
|
||||
vmov.i8 d7, #2
|
||||
vmin.u8 d3, d3, d6 // imin(L >> sharp[0], sharp[1])
|
||||
vadd.i8 d0, d1, d7 // L + 2
|
||||
vmax.u8 d11, d3, d4 // imax(imin(), 1) = limit = I
|
||||
vadd.u8 d0, d0, d0 // 2*(L + 2)
|
||||
vtst.32 d14, d14, d16 // if (vmask[1] & bits)
|
||||
vadd.i8 d10, d0, d11 // 2*(L + 2) + limit = E
|
||||
vtst.32 d13, d13, d16 // if (vmask[0] & bits)
|
||||
vand d13, d13, d2 // vmask[0] &= L != 0
|
||||
|
||||
.ifc \type, y
|
||||
tst r2, #0x03
|
||||
beq 2f
|
||||
// wd16
|
||||
bl lpf_\dir\()_16_8_neon
|
||||
b 8f
|
||||
2:
|
||||
.endif
|
||||
tst r7, #0x03
|
||||
beq 3f
|
||||
.ifc \type, y
|
||||
// wd8
|
||||
bl lpf_\dir\()_8_8_neon
|
||||
.else
|
||||
// wd6
|
||||
bl lpf_\dir\()_6_8_neon
|
||||
.endif
|
||||
b 8f
|
||||
3:
|
||||
// wd4
|
||||
bl lpf_\dir\()_4_8_neon
|
||||
.ifc \dir, h
|
||||
b 8f
|
||||
7:
|
||||
// For dir h, the functions above increment r0.
|
||||
// If the whole function is skipped, increment it here instead.
|
||||
add r0, r0, r1, lsl #3
|
||||
.else
|
||||
7:
|
||||
.endif
|
||||
8:
|
||||
lsrs r6, r6, #2 // vmask[0] >>= 2
|
||||
lsr r7, r7, #2 // vmask[1] >>= 2
|
||||
.ifc \type, y
|
||||
lsr r2, r2, #2 // vmask[2] >>= 2
|
||||
.endif
|
||||
.ifc \dir, v
|
||||
add r0, r0, #8
|
||||
.else
|
||||
// For dir h, r0 is returned incremented
|
||||
.endif
|
||||
bne 1b
|
||||
|
||||
vpop {q4-q7}
|
||||
pop {r4-r11,pc}
|
||||
endfunc
|
||||
.endm
|
||||
|
||||
lpf_func v, y
|
||||
lpf_func h, y
|
||||
lpf_func v, uv
|
||||
lpf_func h, uv
|
||||
|
||||
const word_12, align=4
|
||||
.word 1, 2
|
||||
endconst
|
||||
859
media/libdav1d/src/src/arm/32/loopfilter16.S
Normal file
859
media/libdav1d/src/src/arm/32/loopfilter16.S
Normal file
|
|
@ -0,0 +1,859 @@
|
|||
/*
|
||||
* Copyright © 2018, VideoLAN and dav1d authors
|
||||
* Copyright © 2020, Martin Storsjo
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include "src/arm/asm.S"
|
||||
#include "util.S"
|
||||
|
||||
.macro loop_filter wd
|
||||
function lpf_4_wd\wd\()_neon
|
||||
vabd.u16 d0, d22, d23 // abs(p1 - p0)
|
||||
vabd.u16 d1, d25, d24 // abs(q1 - q0)
|
||||
vabd.u16 d2, d23, d24 // abs(p0 - q0)
|
||||
vabd.u16 d3, d22, d25 // abs(p1 - q1)
|
||||
.if \wd >= 6
|
||||
vabd.u16 d4, d21, d22 // abs(p2 - p1)
|
||||
vabd.u16 d5, d26, d25 // abs(q2 - q1)
|
||||
.endif
|
||||
.if \wd >= 8
|
||||
vabd.u16 d6, d20, d21 // abs(p3 - p2)
|
||||
vabd.u16 d7, d27, d26 // abs(q3 - q3)
|
||||
.endif
|
||||
.if \wd >= 6
|
||||
vmax.u16 d4, d4, d5
|
||||
.endif
|
||||
vqadd.u16 d2, d2, d2 // abs(p0 - q0) * 2
|
||||
.if \wd >= 8
|
||||
vmax.u16 d6, d6, d7
|
||||
.endif
|
||||
vshr.u16 d3, d3, #1
|
||||
.if \wd >= 8
|
||||
vmax.u16 d4, d4, d6
|
||||
.endif
|
||||
vmax.u16 d0, d0, d1 // max(abs(p1 - p0), abs(q1 - q0))
|
||||
vqadd.u16 d2, d2, d3 // abs(p0 - q0) * 2 + abs(p1 - q1) >> 1
|
||||
.if \wd >= 6
|
||||
vmax.u16 d4, d0, d4
|
||||
vcge.u16 d1, d11, d4 // max(abs(p1 - p0), abs(q1 - q0), abs(), abs(), ...) <= I
|
||||
.else
|
||||
vcge.u16 d1, d11, d0 // max(abs(p1 - p0), abs(q1 - q0)) <= I
|
||||
.endif
|
||||
vcge.u16 d2, d10, d2 // abs(p0 - q0) * 2 + abs(p1 - q1) >> 1 <= E
|
||||
vand d1, d1, d2 // fm && wd >= 4 (implicit)
|
||||
.if \wd >= 6
|
||||
vmov d14, d1 // fm && wd > 4 (implicit)
|
||||
.endif
|
||||
.if \wd >= 16
|
||||
vmov d15, d1 // fm && wd == 16 (implicit)
|
||||
.endif
|
||||
|
||||
vmov r10, r11, d1
|
||||
orrs r10, r10, r11
|
||||
beq 9f // if (!fm || wd < 4) return;
|
||||
|
||||
.if \wd >= 6
|
||||
vmov.i16 d10, #1
|
||||
vabd.u16 d2, d21, d23 // abs(p2 - p0)
|
||||
vabd.u16 d3, d22, d23 // abs(p1 - p0)
|
||||
vabd.u16 d4, d25, d24 // abs(q1 - q0)
|
||||
vabd.u16 d5, d26, d24 // abs(q2 - q0)
|
||||
vdup.16 d9, r9 // bitdepth_min_8
|
||||
.if \wd >= 8
|
||||
vabd.u16 d6, d20, d23 // abs(p3 - p0)
|
||||
vabd.u16 d7, d27, d24 // abs(q3 - q0)
|
||||
.endif
|
||||
vmax.u16 d2, d2, d3
|
||||
vmax.u16 d4, d4, d5
|
||||
.if \wd >= 8
|
||||
vmax.u16 d6, d6, d7
|
||||
.endif
|
||||
vmax.u16 d2, d2, d4
|
||||
vshl.u16 d10, d10, d9 // F = 1 << bitdepth_min_8
|
||||
.if \wd >= 8
|
||||
vmax.u16 d2, d2, d6
|
||||
.endif
|
||||
|
||||
.if \wd == 16
|
||||
vabd.u16 d3, d17, d23 // abs(p6 - p0)
|
||||
vabd.u16 d4, d18, d23 // abs(p5 - p0)
|
||||
vabd.u16 d5, d19, d23 // abs(p4 - p0)
|
||||
.endif
|
||||
vcge.u16 d2, d10, d2 // flat8in
|
||||
.if \wd == 16
|
||||
vabd.u16 d6, d28, d24 // abs(q4 - q0)
|
||||
vabd.u16 d7, d29, d24 // abs(q5 - q0)
|
||||
vabd.u16 d8, d30, d24 // abs(q6 - q0)
|
||||
.endif
|
||||
vand d14, d2, d14 // flat8in && fm && wd > 4
|
||||
vbic d1, d1, d14 // fm && wd >= 4 && !flat8in
|
||||
.if \wd == 16
|
||||
vmax.u16 d3, d3, d4
|
||||
vmax.u16 d5, d5, d6
|
||||
.endif
|
||||
vmov r10, r11, d1
|
||||
.if \wd == 16
|
||||
vmax.u16 d7, d7, d8
|
||||
vmax.u16 d3, d3, d5
|
||||
vmax.u16 d3, d3, d7
|
||||
vcge.u16 d3, d10, d3 // flat8out
|
||||
.endif
|
||||
orrs r10, r10, r11
|
||||
.if \wd == 16
|
||||
vand d15, d15, d3 // flat8out && fm && wd == 16
|
||||
vand d15, d15, d14 // flat8out && flat8in && fm && wd == 16
|
||||
vbic d14, d14, d15 // flat8in && fm && wd >= 4 && !flat8out
|
||||
.endif
|
||||
beq 1f // skip wd == 4 case
|
||||
.endif
|
||||
|
||||
vdup.16 d3, r8 // bitdepth_max
|
||||
vsub.u16 d2, d22, d25 // p1 - q1
|
||||
vshr.u16 d3, d3, #1 // 128 << bitdepth_min_8 - 1
|
||||
vcgt.u16 d0, d0, d12 // hev
|
||||
vmvn d9, d3 // - 128 * (1 << bitdepth_min_8)
|
||||
vmin.s16 d2, d2, d3 // iclip_diff(p1 - q1)
|
||||
vmax.s16 d2, d2, d9 // iclip_diff(p1 - q1)
|
||||
vand d4, d2, d0 // if (hev) iclip_diff(p1 - q1)
|
||||
vsub.u16 d2, d24, d23
|
||||
vmov.i16 d6, #3
|
||||
vbic d0, d1, d0 // (fm && wd >= 4 && !hev)
|
||||
vmul.i16 d2, d2, d6
|
||||
vmov.i16 d7, #4
|
||||
vadd.i16 d2, d2, d4
|
||||
vmin.s16 d2, d2, d3 // f = iclip_diff()
|
||||
vmax.s16 d2, d2, d9 // f = iclip_diff()
|
||||
vqadd.s16 d4, d7, d2 // f + 4
|
||||
vqadd.s16 d5, d6, d2 // f + 3
|
||||
vmin.s16 d4, d4, d3 // imin(f + 4, 128 << bitdepth_min_8 - 1)
|
||||
vmin.s16 d5, d5, d3 // imin(f + 3, 128 << bitdepth_min_8 - 1)
|
||||
vshr.s16 d4, d4, #3 // f1
|
||||
vshr.s16 d5, d5, #3 // f2
|
||||
vmov.i16 d9, #0
|
||||
vdup.16 d3, r8 // bitdepth_max
|
||||
vqadd.s16 d2, d23, d5 // p0 + f2
|
||||
vqsub.s16 d6, d24, d4 // q0 - f1
|
||||
vrshr.s16 d4, d4, #1 // (f1 + 1) >> 1
|
||||
vmin.s16 d2, d2, d3 // out p0 = iclip_pixel()
|
||||
vmin.s16 d6, d6, d3 // out q0 = iclip_pixel()
|
||||
vmax.s16 d2, d2, d9 // out p0 = iclip_pixel()
|
||||
vmax.s16 d6, d6, d9 // out q0 = iclip_pixel()
|
||||
vbit d23, d2, d1 // if (fm && wd >= 4)
|
||||
vbit d24, d6, d1 // if (fm && wd >= 4)
|
||||
vqadd.s16 d2, d22, d4 // p1 + f
|
||||
vqsub.s16 d6, d25, d4 // q1 - f
|
||||
vmin.s16 d2, d2, d3 // out p1 = iclip_pixel()
|
||||
vmin.s16 d6, d6, d3 // out q1 = iclip_pixel()
|
||||
vmax.s16 d2, d2, d9 // out p1 = iclip_pixel()
|
||||
vmax.s16 d6, d6, d9 // out q1 = iclip_pixel()
|
||||
vbit d22, d2, d0 // if (fm && wd >= 4 && !hev)
|
||||
vbit d25, d6, d0 // if (fm && wd >= 4 && !hev)
|
||||
1:
|
||||
|
||||
.if \wd == 6
|
||||
vmov r10, r11, d14
|
||||
orrs r10, r10, r11
|
||||
beq 2f // skip if there's no flat8in
|
||||
|
||||
vadd.i16 d0, d21, d21 // p2 * 2
|
||||
vadd.i16 d2, d21, d22 // p2 + p1
|
||||
vadd.i16 d4, d22, d23 // p1 + p0
|
||||
vadd.i16 d6, d23, d24 // p0 + q0
|
||||
vadd.i16 d8, d0, d2
|
||||
vadd.i16 d10, d4, d6
|
||||
vadd.i16 d12, d24, d25 // q0 + q1
|
||||
vadd.i16 d8, d8, d10
|
||||
vsub.i16 d12, d12, d0
|
||||
vadd.i16 d10, d25, d26 // q1 + q2
|
||||
vrshr.u16 d0, d8, #3 // out p1
|
||||
|
||||
vadd.i16 d8, d8, d12
|
||||
vsub.i16 d10, d10, d2
|
||||
vadd.i16 d12, d26, d26 // q2 + q2
|
||||
vrshr.u16 d1, d8, #3 // out p0
|
||||
|
||||
vadd.i16 d8, d8, d10
|
||||
vsub.i16 d12, d12, d4
|
||||
vrshr.u16 d2, d8, #3 // out q0
|
||||
|
||||
vbit d22, d0, d14 // p1 if (flat8in)
|
||||
vadd.i16 d8, d8, d12
|
||||
vbit d23, d1, d14 // p0 if (flat8in)
|
||||
vrshr.u16 d3, d8, #3 // out q1
|
||||
vbit d24, d2, d14 // q0 if (flat8in)
|
||||
vbit d25, d3, d14 // q1 if (flat8in)
|
||||
.elseif \wd >= 8
|
||||
vmov r10, r11, d14
|
||||
orrs r10, r10, r11
|
||||
.if \wd == 8
|
||||
beq 8f // skip if there's no flat8in
|
||||
.else
|
||||
beq 2f // skip if there's no flat8in
|
||||
.endif
|
||||
|
||||
vadd.i16 d0, d20, d21 // p3 + p2
|
||||
vadd.i16 d2, d22, d25 // p1 + q1
|
||||
vadd.i16 d4, d20, d22 // p3 + p1
|
||||
vadd.i16 d6, d23, d26 // p0 + q2
|
||||
vadd.i16 d8, d0, d0 // 2 * (p3 + p2)
|
||||
vadd.i16 d9, d23, d24 // p0 + q0
|
||||
vadd.i16 d8, d8, d4 // + p3 + p1
|
||||
vsub.i16 d2, d2, d0 // p1 + q1 - p3 - p2
|
||||
vadd.i16 d8, d8, d9 // + p0 + q0
|
||||
vsub.i16 d6, d6, d4 // p0 + q2 - p3 - p1
|
||||
vrshr.u16 d10, d8, #3 // out p2
|
||||
|
||||
vadd.i16 d8, d8, d2
|
||||
vadd.i16 d0, d20, d23 // p3 + p0
|
||||
vadd.i16 d2, d24, d27 // q0 + q3
|
||||
vrshr.u16 d11, d8, #3 // out p1
|
||||
|
||||
vadd.i16 d8, d8, d6
|
||||
vsub.i16 d2, d2, d0 // q0 + q3 - p3 - p0
|
||||
vadd.i16 d4, d21, d24 // p2 + q0
|
||||
vadd.i16 d6, d25, d27 // q1 + q3
|
||||
vrshr.u16 d12, d8, #3 // out p0
|
||||
|
||||
vadd.i16 d8, d8, d2
|
||||
vsub.i16 d6, d6, d4 // q1 + q3 - p2 - q0
|
||||
vadd.i16 d0, d22, d25 // p1 + q1
|
||||
vadd.i16 d2, d26, d27 // q2 + q3
|
||||
vrshr.u16 d13, d8, #3 // out q0
|
||||
|
||||
vadd.i16 d8, d8, d6
|
||||
vsub.i16 d2, d2, d0 // q2 + q3 - p1 - q1
|
||||
vrshr.u16 d0, d8, #3 // out q1
|
||||
|
||||
vadd.i16 d8, d8, d2
|
||||
|
||||
vbit d21, d10, d14
|
||||
vbit d22, d11, d14
|
||||
vbit d23, d12, d14
|
||||
vrshr.u16 d1, d8, #3 // out q2
|
||||
vbit d24, d13, d14
|
||||
vbit d25, d0, d14
|
||||
vbit d26, d1, d14
|
||||
.endif
|
||||
2:
|
||||
.if \wd == 16
|
||||
vmov r10, r11, d15
|
||||
orrs r10, r10, r11
|
||||
bne 1f // check if flat8out is needed
|
||||
vmov r10, r11, d14
|
||||
orrs r10, r10, r11
|
||||
beq 8f // if there was no flat8in, just write the inner 4 pixels
|
||||
b 7f // if flat8in was used, write the inner 6 pixels
|
||||
1:
|
||||
|
||||
vadd.i16 d2, d17, d17 // p6 + p6
|
||||
vadd.i16 d4, d17, d18 // p6 + p5
|
||||
vadd.i16 d6, d17, d19 // p6 + p4
|
||||
vadd.i16 d8, d17, d20 // p6 + p3
|
||||
vadd.i16 d12, d2, d4
|
||||
vadd.i16 d10, d6, d8
|
||||
vadd.i16 d6, d17, d21 // p6 + p2
|
||||
vadd.i16 d12, d12, d10
|
||||
vadd.i16 d8, d17, d22 // p6 + p1
|
||||
vadd.i16 d10, d18, d23 // p5 + p0
|
||||
vadd.i16 d6, d6, d8
|
||||
vadd.i16 d8, d19, d24 // p4 + q0
|
||||
vadd.i16 d12, d12, d6
|
||||
vadd.i16 d10, d10, d8
|
||||
vadd.i16 d6, d20, d25 // p3 + q1
|
||||
vadd.i16 d12, d12, d10
|
||||
vsub.i16 d6, d6, d2
|
||||
vadd.i16 d2, d21, d26 // p2 + q2
|
||||
vrshr.u16 d0, d12, #4 // out p5
|
||||
vadd.i16 d12, d12, d6 // - (p6 + p6) + (p3 + q1)
|
||||
vsub.i16 d2, d2, d4
|
||||
vadd.i16 d4, d22, d27 // p1 + q3
|
||||
vadd.i16 d6, d17, d19 // p6 + p4
|
||||
vrshr.u16 d1, d12, #4 // out p4
|
||||
vadd.i16 d12, d12, d2 // - (p6 + p5) + (p2 + q2)
|
||||
vsub.i16 d4, d4, d6
|
||||
vadd.i16 d6, d23, d28 // p0 + q4
|
||||
vadd.i16 d8, d17, d20 // p6 + p3
|
||||
vrshr.u16 d2, d12, #4 // out p3
|
||||
vadd.i16 d12, d12, d4 // - (p6 + p4) + (p1 + q3)
|
||||
vsub.i16 d6, d6, d8
|
||||
vadd.i16 d8, d24, d29 // q0 + q5
|
||||
vadd.i16 d4, d17, d21 // p6 + p2
|
||||
vrshr.u16 d3, d12, #4 // out p2
|
||||
vadd.i16 d12, d12, d6 // - (p6 + p3) + (p0 + q4)
|
||||
vsub.i16 d8, d8, d4
|
||||
vadd.i16 d6, d25, d30 // q1 + q6
|
||||
vadd.i16 d10, d17, d22 // p6 + p1
|
||||
vrshr.u16 d4, d12, #4 // out p1
|
||||
vadd.i16 d12, d12, d8 // - (p6 + p2) + (q0 + q5)
|
||||
vsub.i16 d6, d6, d10
|
||||
vadd.i16 d8, d26, d30 // q2 + q6
|
||||
vbif d0, d18, d15 // out p5
|
||||
vadd.i16 d10, d18, d23 // p5 + p0
|
||||
vrshr.u16 d5, d12, #4 // out p0
|
||||
vadd.i16 d12, d12, d6 // - (p6 + p1) + (q1 + q6)
|
||||
vsub.i16 d8, d8, d10
|
||||
vadd.i16 d10, d27, d30 // q3 + q6
|
||||
vbif d1, d19, d15 // out p4
|
||||
vadd.i16 d18, d19, d24 // p4 + q0
|
||||
vrshr.u16 d6, d12, #4 // out q0
|
||||
vadd.i16 d12, d12, d8 // - (p5 + p0) + (q2 + q6)
|
||||
vsub.i16 d10, d10, d18
|
||||
vadd.i16 d8, d28, d30 // q4 + q6
|
||||
vbif d2, d20, d15 // out p3
|
||||
vadd.i16 d18, d20, d25 // p3 + q1
|
||||
vrshr.u16 d7, d12, #4 // out q1
|
||||
vadd.i16 d12, d12, d10 // - (p4 + q0) + (q3 + q6)
|
||||
vsub.i16 d18, d8, d18
|
||||
vadd.i16 d10, d29, d30 // q5 + q6
|
||||
vbif d3, d21, d15 // out p2
|
||||
vadd.i16 d20, d21, d26 // p2 + q2
|
||||
vrshr.u16 d8, d12, #4 // out q2
|
||||
vadd.i16 d12, d12, d18 // - (p3 + q1) + (q4 + q6)
|
||||
vsub.i16 d10, d10, d20
|
||||
vadd.i16 d18, d30, d30 // q6 + q6
|
||||
vbif d4, d22, d15 // out p1
|
||||
vadd.i16 d20, d22, d27 // p1 + q3
|
||||
vrshr.u16 d9, d12, #4 // out q3
|
||||
vadd.i16 d12, d12, d10 // - (p2 + q2) + (q5 + q6)
|
||||
vsub.i16 d18, d18, d20
|
||||
vbif d5, d23, d15 // out p0
|
||||
vrshr.u16 d10, d12, #4 // out q4
|
||||
vadd.i16 d12, d12, d18 // - (p1 + q3) + (q6 + q6)
|
||||
vrshr.u16 d11, d12, #4 // out q5
|
||||
vbif d6, d24, d15 // out q0
|
||||
vbif d7, d25, d15 // out q1
|
||||
vbif d8, d26, d15 // out q2
|
||||
vbif d9, d27, d15 // out q3
|
||||
vbif d10, d28, d15 // out q4
|
||||
vbif d11, d29, d15 // out q5
|
||||
.endif
|
||||
|
||||
bx lr
|
||||
.if \wd == 16
|
||||
7:
|
||||
// Return to a shorter epilogue, writing only the inner 6 pixels
|
||||
bx r6
|
||||
.endif
|
||||
.if \wd >= 8
|
||||
8:
|
||||
// Return to a shorter epilogue, writing only the inner 4 pixels
|
||||
bx r7
|
||||
.endif
|
||||
9:
|
||||
// Return directly without writing back any pixels
|
||||
bx r12
|
||||
endfunc
|
||||
.endm
|
||||
|
||||
loop_filter 16
|
||||
loop_filter 8
|
||||
loop_filter 6
|
||||
loop_filter 4
|
||||
|
||||
.macro lpf_4_wd16
|
||||
adr r6, 7f + CONFIG_THUMB
|
||||
adr r7, 8f + CONFIG_THUMB
|
||||
bl lpf_4_wd16_neon
|
||||
.endm
|
||||
|
||||
.macro lpf_4_wd8
|
||||
adr r7, 8f + CONFIG_THUMB
|
||||
bl lpf_4_wd8_neon
|
||||
.endm
|
||||
|
||||
.macro lpf_4_wd6
|
||||
bl lpf_4_wd6_neon
|
||||
.endm
|
||||
|
||||
.macro lpf_4_wd4
|
||||
bl lpf_4_wd4_neon
|
||||
.endm
|
||||
|
||||
function lpf_v_4_4_neon
|
||||
mov r12, lr
|
||||
sub r10, r0, r1, lsl #1
|
||||
vld1.16 {d22}, [r10, :64], r1 // p1
|
||||
vld1.16 {d24}, [r0, :64], r1 // q0
|
||||
vld1.16 {d23}, [r10, :64], r1 // p0
|
||||
vld1.16 {d25}, [r0, :64], r1 // q1
|
||||
sub r0, r0, r1, lsl #1
|
||||
|
||||
lpf_4_wd4
|
||||
|
||||
sub r10, r0, r1, lsl #1
|
||||
vst1.16 {d22}, [r10, :64], r1 // p1
|
||||
vst1.16 {d24}, [r0, :64], r1 // q0
|
||||
vst1.16 {d23}, [r10, :64], r1 // p0
|
||||
vst1.16 {d25}, [r0, :64], r1 // q1
|
||||
sub r0, r0, r1, lsl #1
|
||||
bx r12
|
||||
endfunc
|
||||
|
||||
function lpf_h_4_4_neon
|
||||
mov r12, lr
|
||||
sub r10, r0, #4
|
||||
add r0, r10, r1, lsl #1
|
||||
vld1.16 {d22}, [r10], r1
|
||||
vld1.16 {d24}, [r0], r1
|
||||
vld1.16 {d23}, [r10], r1
|
||||
vld1.16 {d25}, [r0], r1
|
||||
add r0, r0, #4
|
||||
|
||||
transpose_4x4h q11, q12, d22, d23, d24, d25
|
||||
|
||||
lpf_4_wd4
|
||||
|
||||
sub r10, r0, r1, lsl #2
|
||||
sub r10, r10, #4
|
||||
transpose_4x4h q11, q12, d22, d23, d24, d25
|
||||
add r0, r10, r1, lsl #1
|
||||
|
||||
vst1.16 {d22}, [r10], r1
|
||||
vst1.16 {d24}, [r0], r1
|
||||
vst1.16 {d23}, [r10], r1
|
||||
vst1.16 {d25}, [r0], r1
|
||||
add r0, r0, #4
|
||||
bx r12
|
||||
endfunc
|
||||
|
||||
function lpf_v_6_4_neon
|
||||
mov r12, lr
|
||||
sub r10, r0, r1, lsl #1
|
||||
sub r10, r10, r1
|
||||
vld1.16 {d21}, [r10, :64], r1 // p2
|
||||
vld1.16 {d24}, [r0, :64], r1 // q0
|
||||
vld1.16 {d22}, [r10, :64], r1 // p1
|
||||
vld1.16 {d25}, [r0, :64], r1 // q1
|
||||
vld1.16 {d23}, [r10, :64], r1 // p0
|
||||
vld1.16 {d26}, [r0, :64], r1 // q2
|
||||
sub r0, r0, r1, lsl #1
|
||||
sub r0, r0, r1
|
||||
|
||||
lpf_4_wd6
|
||||
|
||||
sub r10, r0, r1, lsl #1
|
||||
vst1.16 {d22}, [r10, :64], r1 // p1
|
||||
vst1.16 {d24}, [r0, :64], r1 // q0
|
||||
vst1.16 {d23}, [r10, :64], r1 // p0
|
||||
vst1.16 {d25}, [r0, :64], r1 // q1
|
||||
sub r0, r0, r1, lsl #1
|
||||
bx r12
|
||||
endfunc
|
||||
|
||||
function lpf_h_6_4_neon
|
||||
mov r12, lr
|
||||
sub r10, r0, #8
|
||||
vld1.16 {d20}, [r10, :64], r1
|
||||
vld1.16 {d24}, [r0, :64], r1
|
||||
vld1.16 {d21}, [r10, :64], r1
|
||||
vld1.16 {d25}, [r0, :64], r1
|
||||
vld1.16 {d22}, [r10, :64], r1
|
||||
vld1.16 {d26}, [r0, :64], r1
|
||||
vld1.16 {d23}, [r10, :64], r1
|
||||
vld1.16 {d27}, [r0, :64], r1
|
||||
|
||||
transpose_4x4h q10, q11, d20, d21, d22, d23
|
||||
transpose_4x4h q12, q13, d24, d25, d26, d27
|
||||
|
||||
lpf_4_wd6
|
||||
|
||||
sub r0, r0, #4
|
||||
transpose_4x4h q11, q12, d22, d23, d24, d25
|
||||
sub r10, r0, r1, lsl #2
|
||||
sub r0, r0, r1, lsl #1
|
||||
|
||||
vst1.16 {d22}, [r10], r1
|
||||
vst1.16 {d24}, [r0], r1
|
||||
vst1.16 {d23}, [r10], r1
|
||||
vst1.16 {d25}, [r0], r1
|
||||
add r0, r0, #4
|
||||
bx r12
|
||||
endfunc
|
||||
|
||||
function lpf_v_8_4_neon
|
||||
mov r12, lr
|
||||
sub r10, r0, r1, lsl #2
|
||||
vld1.16 {d20}, [r10, :64], r1 // p3
|
||||
vld1.16 {d24}, [r0, :64], r1 // q0
|
||||
vld1.16 {d21}, [r10, :64], r1 // p2
|
||||
vld1.16 {d25}, [r0, :64], r1 // q1
|
||||
vld1.16 {d22}, [r10, :64], r1 // p1
|
||||
vld1.16 {d26}, [r0, :64], r1 // q2
|
||||
vld1.16 {d23}, [r10, :64], r1 // p0
|
||||
vld1.16 {d27}, [r0, :64], r1 // q3
|
||||
sub r0, r0, r1, lsl #2
|
||||
|
||||
lpf_4_wd8
|
||||
|
||||
sub r10, r0, r1, lsl #1
|
||||
sub r10, r10, r1
|
||||
vst1.16 {d21}, [r10, :64], r1 // p2
|
||||
vst1.16 {d24}, [r0, :64], r1 // q0
|
||||
vst1.16 {d22}, [r10, :64], r1 // p1
|
||||
vst1.16 {d25}, [r0, :64], r1 // q1
|
||||
vst1.16 {d23}, [r10, :64], r1 // p0
|
||||
vst1.16 {d26}, [r0, :64], r1 // q2
|
||||
sub r0, r0, r1, lsl #1
|
||||
sub r0, r0, r1
|
||||
bx r12
|
||||
|
||||
8:
|
||||
sub r10, r0, r1, lsl #1
|
||||
vst1.16 {d22}, [r10, :64], r1 // p1
|
||||
vst1.16 {d24}, [r0, :64], r1 // q0
|
||||
vst1.16 {d23}, [r10, :64], r1 // p0
|
||||
vst1.16 {d25}, [r0, :64], r1 // q1
|
||||
sub r0, r0, r1, lsl #1
|
||||
bx r12
|
||||
endfunc
|
||||
|
||||
function lpf_h_8_4_neon
|
||||
mov r12, lr
|
||||
sub r10, r0, #8
|
||||
vld1.16 {d20}, [r10, :64], r1
|
||||
vld1.16 {d24}, [r0, :64], r1
|
||||
vld1.16 {d21}, [r10, :64], r1
|
||||
vld1.16 {d25}, [r0, :64], r1
|
||||
vld1.16 {d22}, [r10, :64], r1
|
||||
vld1.16 {d26}, [r0, :64], r1
|
||||
vld1.16 {d23}, [r10, :64], r1
|
||||
vld1.16 {d27}, [r0, :64], r1
|
||||
|
||||
transpose_4x4h q10, q11, d20, d21, d22, d23
|
||||
transpose_4x4h q12, q13, d24, d25, d26, d27
|
||||
|
||||
lpf_4_wd8
|
||||
|
||||
sub r0, r0, r1, lsl #2
|
||||
transpose_4x4h q10, q11, d20, d21, d22, d23
|
||||
transpose_4x4h q12, q13, d24, d25, d26, d27
|
||||
sub r10, r0, #8
|
||||
|
||||
vst1.16 {d20}, [r10, :64], r1
|
||||
vst1.16 {d24}, [r0, :64], r1
|
||||
vst1.16 {d21}, [r10, :64], r1
|
||||
vst1.16 {d25}, [r0, :64], r1
|
||||
vst1.16 {d22}, [r10, :64], r1
|
||||
vst1.16 {d26}, [r0, :64], r1
|
||||
vst1.16 {d23}, [r10, :64], r1
|
||||
vst1.16 {d27}, [r0, :64], r1
|
||||
bx r12
|
||||
8:
|
||||
sub r0, r0, #4
|
||||
transpose_4x4h q11, q12, d22, d23, d24, d25
|
||||
sub r10, r0, r1, lsl #2
|
||||
sub r0, r0, r1, lsl #1
|
||||
|
||||
vst1.16 {d22}, [r10], r1
|
||||
vst1.16 {d24}, [r0], r1
|
||||
vst1.16 {d23}, [r10], r1
|
||||
vst1.16 {d25}, [r0], r1
|
||||
add r0, r0, #4
|
||||
bx r12
|
||||
endfunc
|
||||
|
||||
function lpf_v_16_4_neon
|
||||
mov r12, lr
|
||||
|
||||
sub r10, r0, r1, lsl #3
|
||||
add r10, r10, r1
|
||||
vld1.16 {d17}, [r10, :64], r1 // p6
|
||||
vld1.16 {d24}, [r0, :64], r1 // q0
|
||||
vld1.16 {d18}, [r10, :64], r1 // p5
|
||||
vld1.16 {d25}, [r0, :64], r1 // q1
|
||||
vld1.16 {d19}, [r10, :64], r1 // p4
|
||||
vld1.16 {d26}, [r0, :64], r1 // q2
|
||||
vld1.16 {d20}, [r10, :64], r1 // p3
|
||||
vld1.16 {d27}, [r0, :64], r1 // q3
|
||||
vld1.16 {d21}, [r10, :64], r1 // p2
|
||||
vld1.16 {d28}, [r0, :64], r1 // q4
|
||||
vld1.16 {d22}, [r10, :64], r1 // p1
|
||||
vld1.16 {d29}, [r0, :64], r1 // q5
|
||||
vld1.16 {d23}, [r10, :64], r1 // p0
|
||||
vld1.16 {d30}, [r0, :64], r1 // q6
|
||||
sub r0, r0, r1, lsl #3
|
||||
add r0, r0, r1
|
||||
|
||||
lpf_4_wd16
|
||||
|
||||
sub r10, r0, r1, lsl #2
|
||||
sub r10, r10, r1, lsl #1
|
||||
vst1.16 {d0}, [r10, :64], r1 // p5
|
||||
vst1.16 {d6}, [r0, :64], r1 // q0
|
||||
vst1.16 {d1}, [r10, :64], r1 // p4
|
||||
vst1.16 {d7}, [r0, :64], r1 // q1
|
||||
vst1.16 {d2}, [r10, :64], r1 // p3
|
||||
vst1.16 {d8}, [r0, :64], r1 // q2
|
||||
vst1.16 {d3}, [r10, :64], r1 // p2
|
||||
vst1.16 {d9}, [r0, :64], r1 // q3
|
||||
vst1.16 {d4}, [r10, :64], r1 // p1
|
||||
vst1.16 {d10}, [r0, :64], r1 // q4
|
||||
vst1.16 {d5}, [r10, :64], r1 // p0
|
||||
vst1.16 {d11}, [r0, :64], r1 // q5
|
||||
sub r0, r0, r1, lsl #2
|
||||
sub r0, r0, r1, lsl #1
|
||||
bx r12
|
||||
7:
|
||||
sub r10, r0, r1
|
||||
sub r10, r10, r1, lsl #1
|
||||
vst1.16 {d21}, [r10, :64], r1 // p2
|
||||
vst1.16 {d24}, [r0, :64], r1 // q0
|
||||
vst1.16 {d22}, [r10, :64], r1 // p1
|
||||
vst1.16 {d25}, [r0, :64], r1 // q1
|
||||
vst1.16 {d23}, [r10, :64], r1 // p0
|
||||
vst1.16 {d26}, [r0, :64], r1 // q2
|
||||
sub r0, r0, r1, lsl #1
|
||||
sub r0, r0, r1
|
||||
bx r12
|
||||
|
||||
8:
|
||||
sub r10, r0, r1, lsl #1
|
||||
vst1.16 {d22}, [r10, :64], r1 // p1
|
||||
vst1.16 {d24}, [r0, :64], r1 // q0
|
||||
vst1.16 {d23}, [r10, :64], r1 // p0
|
||||
vst1.16 {d25}, [r0, :64], r1 // q1
|
||||
sub r0, r0, r1, lsl #1
|
||||
bx r12
|
||||
endfunc
|
||||
|
||||
function lpf_h_16_4_neon
|
||||
mov r12, lr
|
||||
sub r10, r0, #16
|
||||
sub r0, r0, #8
|
||||
vld1.16 {d16}, [r10, :64], r1
|
||||
vld1.16 {d20}, [r0, :64], r1
|
||||
vld1.16 {d17}, [r10, :64], r1
|
||||
vld1.16 {d21}, [r0, :64], r1
|
||||
vld1.16 {d18}, [r10, :64], r1
|
||||
vld1.16 {d22}, [r0, :64], r1
|
||||
vld1.16 {d19}, [r10, :64], r1
|
||||
vld1.16 {d23}, [r0, :64], r1
|
||||
sub r10, r10, r1, lsl #2
|
||||
sub r0, r0, r1, lsl #2
|
||||
add r10, r10, #16
|
||||
add r0, r0, #16
|
||||
vld1.16 {d24}, [r10, :64], r1
|
||||
vld1.16 {d28}, [r0, :64], r1
|
||||
vld1.16 {d25}, [r10, :64], r1
|
||||
vld1.16 {d29}, [r0, :64], r1
|
||||
vld1.16 {d26}, [r10, :64], r1
|
||||
vld1.16 {d30}, [r0, :64], r1
|
||||
vld1.16 {d27}, [r10, :64], r1
|
||||
vld1.16 {d31}, [r0, :64], r1
|
||||
sub r0, r0, #8
|
||||
|
||||
transpose_4x4h q8, q9, d16, d17, d18, d19
|
||||
transpose_4x4h q10, q11, d20, d21, d22, d23
|
||||
transpose_4x4h q12, q13, d24, d25, d26, d27
|
||||
transpose_4x4h q14, q15, d28, d29, d30, d31
|
||||
|
||||
lpf_4_wd16
|
||||
|
||||
sub r0, r0, r1, lsl #2
|
||||
transpose_4x4h q8, q0, d16, d17, d0, d1
|
||||
transpose_4x4h q1, q2, d2, d3, d4, d5
|
||||
transpose_4x4h q3, q4, d6, d7, d8, d9
|
||||
transpose_4x4h q5, q15, d10, d11, d30, d31
|
||||
sub r10, r0, #16
|
||||
sub r0, r0, #8
|
||||
|
||||
vst1.16 {d16}, [r10, :64], r1
|
||||
vst1.16 {d2}, [r0, :64], r1
|
||||
vst1.16 {d17}, [r10, :64], r1
|
||||
vst1.16 {d3}, [r0, :64], r1
|
||||
vst1.16 {d0}, [r10, :64], r1
|
||||
vst1.16 {d4}, [r0, :64], r1
|
||||
vst1.16 {d1}, [r10, :64], r1
|
||||
vst1.16 {d5}, [r0, :64], r1
|
||||
sub r10, r10, r1, lsl #2
|
||||
sub r0, r0, r1, lsl #2
|
||||
add r10, r10, #16
|
||||
add r0, r0, #16
|
||||
vst1.16 {d6}, [r10, :64], r1
|
||||
vst1.16 {d10}, [r0, :64], r1
|
||||
vst1.16 {d7}, [r10, :64], r1
|
||||
vst1.16 {d11}, [r0, :64], r1
|
||||
vst1.16 {d8}, [r10, :64], r1
|
||||
vst1.16 {d30}, [r0, :64], r1
|
||||
vst1.16 {d9}, [r10, :64], r1
|
||||
vst1.16 {d31}, [r0, :64], r1
|
||||
sub r0, r0, #8
|
||||
|
||||
bx r12
|
||||
|
||||
7:
|
||||
sub r0, r0, r1, lsl #2
|
||||
transpose_4x4h q10, q11, d20, d21, d22, d23
|
||||
transpose_4x4h q12, q13, d24, d25, d26, d27
|
||||
sub r10, r0, #8
|
||||
|
||||
vst1.16 {d20}, [r10, :64], r1
|
||||
vst1.16 {d24}, [r0, :64], r1
|
||||
vst1.16 {d21}, [r10, :64], r1
|
||||
vst1.16 {d25}, [r0, :64], r1
|
||||
vst1.16 {d22}, [r10, :64], r1
|
||||
vst1.16 {d26}, [r0, :64], r1
|
||||
vst1.16 {d23}, [r10, :64], r1
|
||||
vst1.16 {d27}, [r0, :64], r1
|
||||
bx r12
|
||||
8:
|
||||
sub r0, r0, #4
|
||||
transpose_4x4h q11, q12, d22, d23, d24, d25
|
||||
sub r10, r0, r1, lsl #2
|
||||
sub r0, r0, r1, lsl #1
|
||||
|
||||
vst1.16 {d22}, [r10], r1
|
||||
vst1.16 {d24}, [r0], r1
|
||||
vst1.16 {d23}, [r10], r1
|
||||
vst1.16 {d25}, [r0], r1
|
||||
add r0, r0, #4
|
||||
bx r12
|
||||
endfunc
|
||||
|
||||
// void dav1d_lpf_v_sb_y_16bpc_neon(pixel *dst, const ptrdiff_t stride,
|
||||
// const uint32_t *const vmask,
|
||||
// const uint8_t (*l)[4], ptrdiff_t b4_stride,
|
||||
// const Av1FilterLUT *lut, const int w,
|
||||
// const int bitdepth_max)
|
||||
|
||||
.macro lpf_func dir, type
|
||||
function lpf_\dir\()_sb_\type\()_16bpc_neon, export=1
|
||||
push {r4-r11,lr}
|
||||
vpush {q4-q7}
|
||||
ldrd r4, r5, [sp, #100]
|
||||
ldr r8, [sp, #112] // bitdepth_max; the 'w' parameter isn't loaded
|
||||
sub sp, sp, #8
|
||||
clz r9, r8
|
||||
rsb r9, r9, #24 // bitdepth_min_8
|
||||
ldrd r6, r7, [r2] // vmask[0], vmask[1]
|
||||
.ifc \type, y
|
||||
ldr r2, [r2, #8] // vmask[2]
|
||||
.endif
|
||||
add r5, r5, #128 // Move to sharp part of lut
|
||||
.ifc \type, y
|
||||
orr r7, r7, r2 // vmask[1] |= vmask[2]
|
||||
.endif
|
||||
.ifc \dir, v
|
||||
sub r4, r3, r4, lsl #2
|
||||
.else
|
||||
sub r3, r3, #4
|
||||
lsl r4, r4, #2
|
||||
.endif
|
||||
orr r6, r6, r7 // vmask[0] |= vmask[1]
|
||||
|
||||
1:
|
||||
tst r6, #0x01
|
||||
strd r6, r7, [sp]
|
||||
.ifc \dir, v
|
||||
ldrb r10, [r4], #4
|
||||
ldrb r11, [r3], #4
|
||||
.else
|
||||
ldrb r10, [r3]
|
||||
ldrb r11, [r3, #4]
|
||||
add r3, r3, r4
|
||||
.endif
|
||||
beq 7f // if (!(vm & bits)) continue;
|
||||
|
||||
orrs r12, r10, r11
|
||||
vdup.16 d31, r9 // bitdepth_min_8
|
||||
beq 7f // if (!(l[0][0] | l[offset][0])) continue;
|
||||
cmp r11, #0 // Check for nonzero values in l[0][0]
|
||||
ldrb r6, [r5], #8 // sharp[0]
|
||||
it eq
|
||||
moveq r11, r10 // if (!l[0][0]) L = l[offset][0]
|
||||
ldrb r12, [r5] // sharp[1]
|
||||
lsr r6, r11, r6 // L >> sharp[0]
|
||||
sub r5, r5, #8
|
||||
cmp r12, r6
|
||||
lsr r10, r11, #4 // H
|
||||
add r11, r11, #2 // L + 2
|
||||
it lt
|
||||
movlt r6, r12 // imin(L >> sharp[0], sharp[1])
|
||||
add r11, r11, r11 // 2*(L + 2)
|
||||
cmp r6, #1
|
||||
lsl r10, r10, r9 // H << bitdepth_min_8
|
||||
it lt
|
||||
movlt r6, #1 // imax(imin(), 1) = limit = I
|
||||
vdup.16 d12, r10 // H << bitdepth_min_8
|
||||
add r11, r11, r6 // 2*(L + 2) + limit = E
|
||||
lsl r6, r6, r9 // I << bitdepth_min_8
|
||||
lsl r11, r11, r9 // E << bitdepth_min_8
|
||||
vdup.16 d11, r6 // I << bitdepth_min_8
|
||||
vdup.16 d10, r11 // E << bitdepth_min_8
|
||||
|
||||
.ifc \type, y
|
||||
tst r2, #0x01
|
||||
beq 2f
|
||||
// wd16
|
||||
bl lpf_\dir\()_16_4_neon
|
||||
b 8f
|
||||
2:
|
||||
.endif
|
||||
tst r7, #0x01
|
||||
beq 3f
|
||||
.ifc \type, y
|
||||
// wd8
|
||||
bl lpf_\dir\()_8_4_neon
|
||||
.else
|
||||
// wd6
|
||||
bl lpf_\dir\()_6_4_neon
|
||||
.endif
|
||||
b 8f
|
||||
3:
|
||||
// wd4
|
||||
bl lpf_\dir\()_4_4_neon
|
||||
.ifc \dir, h
|
||||
b 8f
|
||||
7:
|
||||
// For dir h, the functions above increment r0.
|
||||
// If the whole function is skipped, increment it here instead.
|
||||
add r0, r0, r1, lsl #2
|
||||
.else
|
||||
7:
|
||||
.endif
|
||||
8:
|
||||
ldrd r6, r7, [sp]
|
||||
.ifc \type, y
|
||||
lsr r2, r2, #1 // vmask[2] >>= 1
|
||||
.endif
|
||||
.ifc \dir, v
|
||||
add r0, r0, #8
|
||||
.else
|
||||
// For dir h, r0 is returned incremented
|
||||
.endif
|
||||
lsrs r6, r6, #1 // vmask[0] >>= 1
|
||||
lsr r7, r7, #1 // vmask[1] >>= 1
|
||||
bne 1b
|
||||
|
||||
add sp, sp, #8
|
||||
vpop {q4-q7}
|
||||
pop {r4-r11,pc}
|
||||
endfunc
|
||||
.endm
|
||||
|
||||
lpf_func v, y
|
||||
lpf_func h, y
|
||||
lpf_func v, uv
|
||||
lpf_func h, uv
|
||||
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Add a link
Reference in a new issue