...
 
Commits (55)
......@@ -2,17 +2,18 @@ stages:
- build
build-debian:
image: registry.videolan.org:5000/dav1d-debian-unstable:20180927123816
image: registry.videolan.org:5000/dav1d-debian-unstable:20180928151533
stage: build
tags:
- debian
- amd64
script:
- meson build --buildtype release
- ninja -v -C build
- ninja -C build
- cd build && meson test -v
build-win32:
image: registry.videolan.org:5000/dav1d-debian-unstable:20180927123816
image: registry.videolan.org:5000/dav1d-debian-unstable:20180928151533
stage: build
tags:
- win32
......@@ -22,8 +23,8 @@ build-win32:
--prefix "$(pwd)/build/dav1d_install"
--cross-file /opt/crossfiles/i686-w64-mingw32.meson
-Ddefault_library=both
- ninja -v -C build
- ninja -v -C build install
- ninja -C build
- ninja -C build install
artifacts:
name: "$CI_JOB_NAME-$CI_COMMIT_REF_SLUG"
paths:
......@@ -31,7 +32,7 @@ build-win32:
expire_in: 1 week
build-win64:
image: registry.videolan.org:5000/dav1d-debian-unstable:20180927123816
image: registry.videolan.org:5000/dav1d-debian-unstable:20180928151533
stage: build
tags:
- win64
......@@ -41,8 +42,8 @@ build-win64:
--prefix "$(pwd)/build/dav1d_install"
--cross-file /opt/crossfiles/x86_64-w64-mingw32.meson
-Ddefault_library=both
- ninja -v -C build
- ninja -v -C build install
- ninja -C build
- ninja -C build install
artifacts:
name: "$CI_JOB_NAME-$CI_COMMIT_REF_SLUG"
paths:
......
......@@ -66,6 +66,11 @@
#define NOINLINE __attribute__((noinline))
#endif /* !_MSC_VER */
#if defined(__GNUC__) && !defined(__INTEL_COMPILER) && !defined(__clang__)
# define dav1d_uninit(x) x=x
#else
# define dav1d_uninit(x) x
#endif
#ifdef _MSC_VER
#include <intrin.h>
......
......@@ -50,8 +50,6 @@ extern int optreset;
* specific block, only when *not* __UNISTD_H_SOURCED__, in which
* to declare the extended API.
*/
#endif /* !defined(__GETOPT_H__) */
#if !defined(__UNISTD_H_SOURCED__) && !defined(__GETOPT_LONG_H__)
#define __GETOPT_LONG_H__
......@@ -93,3 +91,5 @@ extern int getopt_long_only(int nargc, char * const *nargv, const char *options,
#endif
#endif /* !defined(__UNISTD_H_SOURCED__) && !defined(__GETOPT_LONG_H__) */
#endif /* !defined(__GETOPT_H__) */
/*
* 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 __declspec(align(32)) atomic_int;
typedef volatile ULONG __declspec(align(32)) 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_load_explicit(p_a, mo) atomic_load(p_a)
/*
* 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))
#endif /* ! stdatomic.h */
#pragma warning(pop)
#endif /* !defined(__cplusplus) && defined(_MSC_VER) */
#endif /* MSCVER_STDATOMIC_H_ */
......@@ -44,6 +44,18 @@ typedef struct Dav1dData {
*/
DAV1D_API int dav1d_data_create(Dav1dData *data, size_t sz);
/**
* Wrap an existing data packet.
* $ptr/$sz are the pointer and size of the data to be wrapped.
* $free_callback/$user_data are a function and function argument to be
* called when we release our last reference to this data. In this callback,
* $data will be the $ptr argument to this function, and $user_data will be
* the $user_data input argument to this function.
*/
DAV1D_API int dav1d_data_wrap(Dav1dData *data, uint8_t *ptr, size_t sz,
void (*free_callback)(uint8_t *data, void *user_data),
void *user_data);
/**
* Free data.
*/
......
......@@ -84,4 +84,9 @@ DAV1D_API int dav1d_decode(Dav1dContext *c, Dav1dData *in, Dav1dPicture *out);
*/
DAV1D_API void dav1d_close(Dav1dContext **c_out);
/**
* Flush all delayed frames in decoder, to be used when seeking.
*/
DAV1D_API void dav1d_flush(Dav1dContext *c);
#endif /* __DAV1D_H__ */
......@@ -40,6 +40,13 @@ enum Dav1dPixelLayout {
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,
......@@ -103,6 +110,7 @@ typedef struct Dav1dPictureParameters {
int w; ///< width (in pixels)
int h; ///< height (in pixels)
enum Dav1dPixelLayout layout; ///< format of the picture
enum Dav1dFrameType type; ///< type of the picture
int bpc; ///< bits per pixel component (8 or 10)
enum Dav1dColorPrimaries pri; ///< color primaries (av1)
......
......@@ -22,6 +22,7 @@
# (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 (version.h) generation
dav1d_git_dir = join_paths(dav1d_src_root, '.git')
rev_target = vcs_tag(command: [
'git', '--git-dir', dav1d_git_dir,
......@@ -31,3 +32,6 @@ rev_target = vcs_tag(command: [
input: 'version.h.in',
output: 'version.h'
)
# Install include/dav1d headers
install_subdir('dav1d', install_dir: 'include')
......@@ -24,52 +24,137 @@
project('dav1d', ['c'],
version: '0.0.1',
default_options: ['c_std=c99'],
default_options: ['c_std=c99',
'warning_level=2'],
meson_version: '>= 0.47.0')
dav1d_version_array = meson.project_version().split('.')
dav1d_version_major = dav1d_version_array[0]
dav1d_version_minor = dav1d_version_array[1]
dav1d_version_revision = dav1d_version_array[2]
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()
cc = meson.get_compiler('c')
# On windows, we use a compatibility layer to emulate pthread
if host_machine.system() != 'windows'
thread_dependency = dependency('threads')
else
thread_dependency = declare_dependency(sources: ['src/win32/thread.c'])
endif
# Include directories
dav1d_inc_dirs = include_directories(['.', 'include', 'include/dav1d'])
dav1d_inc_dirs = include_directories(['include', 'include/dav1d'])
#
# Option handling
#
# Bitdepth option
dav1d_bitdepths = get_option('bitdepths')
foreach bitdepth : dav1d_bitdepths
cdata.set('CONFIG_@0@BPC'.format(bitdepth), 1)
endforeach
# ASM option
is_asm_enabled = (get_option('build_asm') == true and
(host_machine.cpu_family().startswith('x86')) or
host_machine.cpu_family() == 'aarch64' or
host_machine.cpu_family().startswith('arm'))
cdata.set10('HAVE_ASM', is_asm_enabled)
#
# OS/Compiler feature detection
# OS/Compiler checks and defines
#
feature_defines = [
['_POSIX_C_SOURCE', '200112L'], # POSIX.1–2001 (IEEE Std 1003.1-2001)
]
# Arguments in test_args will be used even on feature tests
test_args = []
# Define _POSIX_C_SOURCE to POSIX.1–2001 (IEEE Std 1003.1-2001)
test_args += '-D_POSIX_C_SOURCE=200112L'
add_project_arguments('-D_POSIX_C_SOURCE=200112L', language: 'c')
if host_machine.system() == 'windows'
feature_defines += [
['_WIN32_WINNT', 0x0601],
['UNICODE', 1], # Define to 1 for Unicode (Wide Chars) APIs
['_UNICODE', 1], # Define to 1 for Unicode (Wide Chars) APIs
['__USE_MINGW_ANSI_STDIO', 1], # Define to force use of MinGW printf
]
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
endif
# On Windows, we use a compatibility layer to emulate pthread
if host_machine.system() == 'windows'
thread_dependency = declare_dependency(sources : files('src/win32/thread.c'))
else
thread_dependency = dependency('threads')
endif
# Header checks
stdatomic_dependency = []
if not cc.check_header('stdatomic.h')
error('Atomics not supported')
if cc.get_id() == 'msvc'
# we have a custom replacement for MSVC
stdatomic_dependency = declare_dependency(
include_directories : include_directories('include/compat'),
)
else
error('Atomics not supported')
endif
endif
if cc.check_header('unistd.h')
cdata.set('HAVE_UNISTD_H', 1)
endif
# 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
if cc.has_function('posix_memalign', prefix : '#include <stdlib.h>', args : test_args)
cdata.set('HAVE_POSIX_MEMALIGN', 1)
elif cc.has_function('_aligned_malloc', prefix : '#include <malloc.h>', args : test_args)
cdata.set('HAVE_ALIGNED_MALLOC', 1)
endif
# 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
optional_arguments = [
'-Wundef',
'-Wvla', # should be '-Werror=vla
]
if (get_option('buildtype') != 'debug' and get_option('buildtype') != 'plain')
optional_arguments += '-fomit-frame-pointer'
optional_arguments += '-ffast-math'
endif
add_project_arguments(cc.get_supported_arguments(optional_arguments), language : 'c')
# Stack alignments flags
stackalign_flag = []
stackrealign_flag = []
......@@ -100,6 +185,21 @@ if host_machine.cpu_family().startswith('x86')
endif
endif
cdata.set10('ARCH_AARCH64', host_machine.cpu_family() == 'aarch64')
cdata.set10('ARCH_ARM', host_machine.cpu_family().startswith('arm'))
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)
cdata.set10('HAVE_AS_FUNC', have_as_func)
endif
if host_machine.cpu_family().startswith('x86')
cdata.set10('ARCH_X86', true)
if host_machine.cpu_family() == 'x86_64'
......@@ -122,120 +222,25 @@ else
endif
if cc.symbols_have_underscore_prefix()
cdata.set10('PREFIX', true)
cdata_asm.set10('PREFIX', true)
endif
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
if cc.has_function('posix_memalign', prefix: '#include <stdlib.h>', args: ['-D_POSIX_C_SOURCE=200112L'])
cdata.set('HAVE_POSIX_MEMALIGN', 1)
elif cc.has_function('_aligned_malloc', prefix: '#include <malloc.h>')
cdata.set('HAVE_ALIGNED_MALLOC', 1)
endif
if cc.check_header('unistd.h')
cdata.set('HAVE_UNISTD_H', 1)
endif
if (get_option('buildtype') != 'debug' and
get_option('buildtype') != 'plain')
add_project_arguments('-fomit-frame-pointer', '-ffast-math',
language: 'c')
endif
warning_flags = [
'-Wundef',
'-Wvla', # should be '-Werror=vla
]
add_project_arguments(cc.get_supported_arguments(warning_flags), language: 'c')
# Generate config.h
config_h_target = configure_file(output: 'config.h', configuration: cdata)
foreach f : feature_defines
cdata.set(f.get(0), f.get(1))
endforeach
is_asm_enabled = (get_option('build_asm') == true and
host_machine.cpu_family().startswith('x86'))
cdata.set10('HAVE_ASM', is_asm_enabled)
#
# Generate config headers
# ASM specific stuff
#
if is_asm_enabled and host_machine.cpu_family().startswith('x86')
config_h_target = configure_file(output: 'config.h', configuration: cdata)
if is_asm_enabled
# Generate config.asm
config_asm_target = configure_file(output: 'config.asm', output_format: 'nasm', configuration: cdata_asm)
endif
subdir('include')
#
# dav1d library
#
libdav1d_tmpl_sources = files(
'src/ipred.c',
'src/itx.c',
'src/ipred_prepare.c',
'src/lf_apply.c',
'src/loopfilter.c',
'src/mc.c',
'src/cdef_apply.c',
'src/cdef.c',
'src/lr_apply.c',
'src/looprestoration.c',
'src/recon.c'
)
entrypoints_src = files(
'src/lib.c',
'src/thread_task.c'
)
entrypoints_lib = static_library(
'libdav1dentrypoint',
entrypoints_src, rev_target,
include_directories: dav1d_inc_dirs,
c_args: stackrealign_flag,
install: false,
build_by_default: false,
)
entrypoints_objs = entrypoints_lib.extract_all_objects()
libdav1d_sources = files(
'src/picture.c',
'src/data.c',
'src/ref.c',
'src/getbits.c',
'src/obu.c',
'src/decode.c',
'src/cdf.c',
'src/msac.c',
'src/tables.c',
'src/scan.c',
'src/dequant_tables.c',
'src/intra_edge.c',
'src/lf_mask.c',
'src/ref_mvs.c',
'src/warpmv.c',
'src/wedge.c',
'src/qm.c',
)
if is_asm_enabled
libdav1d_sources += files(
'src/x86/cpu.c',
)
libdav1d_tmpl_sources += files(
'src/x86/mc_init.c',
)
libdav1d_sources_asm = files(
'src/x86/cpuid.asm',
'src/x86/mc.asm',
)
# NASM compiler support
nasm = find_program('nasm')
......@@ -257,75 +262,37 @@ if is_asm_enabled
depfile: '@BASENAME@.obj.ndep',
arguments: [
'-f', nasm_format,
'-I', '@CURRENT_SOURCE_DIR@/',
'-I', '@SOURCE_DIR@/src/',
'-I', '@0@/'.format(meson.current_build_dir()),
'-MQ', '@OUTPUT@', '-MF', '@DEPFILE@',
'@EXTRA_ARGS@',
'@INPUT@',
'-o', '@OUTPUT@'
])
nasm_objs = nasm_gen.process(libdav1d_sources_asm)
else
nasm_objs = []
endif
# Build a helper library for each bitdepth
bitdepth_objs = []
foreach bitdepth : dav1d_bitdepths
bitdepth_lib = static_library(
'dav1d_bitdepth_@0@'.format(bitdepth),
libdav1d_tmpl_sources, config_h_target,
include_directories: dav1d_inc_dirs,
c_args: ['-DBITDEPTH=@0@'.format(bitdepth)] + stackalign_flag,
install: false,
build_by_default: false,
)
bitdepth_objs += bitdepth_lib.extract_all_objects()
endforeach
libdav1d = library('dav1d',
libdav1d_sources, nasm_objs,
version: '0.0.1',
objects: [bitdepth_objs, entrypoints_objs],
include_directories: dav1d_inc_dirs,
c_args: [stackalign_flag],
dependencies: thread_dependency,
install: true
)
install_subdir('include/dav1d/', install_dir: 'include')
#
# dav1d cli tool
#
dav1d_sources = files(
'tools/dav1d.c',
'tools/dav1d_cli_parse.c',
'tools/input/input.c',
'tools/input/ivf.c',
'tools/output/md5.c',
'tools/output/output.c',
'tools/output/y4m2.c',
'tools/output/yuv.c'
)
# Include subdir meson.build files
# The order is important!
subdir('include')
subdir('src')
subdir('tools')
subdir('tests')
if cc.get_id() == 'msvc'
dav1d_sources += files('tools/compat/getopt.c')
endif
dav1d = executable('dav1d',
dav1d_sources, rev_target,
link_with: libdav1d,
include_directories: [dav1d_inc_dirs, include_directories('tools')],
install: true,
)
#
# pkg-config boilerplate
# Generate pkg-config .pc file
#
pkg_mod = import('pkgconfig')
pkg_mod.generate(libraries: libdav1d,
version: '0.0.1',
version: meson.project_version(),
name: 'libdav1d',
filebase: 'dav1d',
description: 'AV1 decoding library'
......
......@@ -9,3 +9,13 @@ option('build_asm',
type: 'boolean',
value: true,
description: 'Build asm files, if available')
option('build_tools',
type: 'boolean',
value: true,
description: 'Build dav1d cli tools')
option('build_tests',
type: 'boolean',
value: true,
description: 'Build dav1d tests')
/******************************************************************************
* Copyright © 2018, VideoLAN and dav1d authors
* Copyright © 2015 Martin Storsjo
* Copyright © 2015 Janne Grunau
* 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 __DAVID_SRC_ARM_32_UTIL_S__
#define __DAVID_SRC_ARM_32_UTIL_S__
#include "config.h"
#include "src/arm/asm.S"
.macro movrel rd, val
#if defined(PIC)
ldr \rd, 1f
b 2f
1:
@ FIXME: thumb
.word \val - (2f + 8)
2:
add \rd, \rd, pc
#else
movw \rd, #:lower16:\val
movt \rd, #:upper16:\val
#endif
.endm
#endif /* __DAVID_SRC_ARM_32_UTIL_S__ */
/******************************************************************************
* Copyright © 2018, VideoLAN and dav1d authors
* Copyright © 2015 Martin Storsjo
* Copyright © 2015 Janne Grunau
* 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 __DAVID_SRC_ARM_64_UTIL_S__
#define __DAVID_SRC_ARM_64_UTIL_S__
#include "config.h"
#include "src/arm/asm.S"
.macro movrel rd, val, offset=0
#if defined(__APPLE__)
.if \offset < 0
adrp \rd, \val@PAGE
add \rd, \rd, \val@PAGEOFF
sub \rd, \rd, -(\offset)
.else
adrp \rd, \val+(\offset)@PAGE
add \rd, \rd, \val+(\offset)@PAGEOFF
.endif
#elif defined(PIC) && defined(_WIN32)
.if \offset < 0
adrp \rd, \val
add \rd, \rd, :lo12:\val
sub \rd, \rd, -(\offset)
.else
adrp \rd, \val+(\offset)
add \rd, \rd, :lo12:\val+(\offset)
.endif
#elif defined(PIC)
adrp \rd, \val+(\offset)
add \rd, \rd, :lo12:\val+(\offset)
#else
ldr \rd, =\val+\offset
#endif
.endm
#endif /* __DAVID_SRC_ARM_64_UTIL_S__ */
/*
* Copyright © 2018, VideoLAN and dav1d authors
* Copyright © 2018, Janne Grunau
* 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_SRC_ARM_ASM_S__
#define __DAV1D_SRC_ARM_ASM_S__
#include "config.h"
#ifndef PRIVATE_PREFIX
#define PRIVATE_PREFIX dav1d_
#endif
#define PASTE(a,b) a ## b
#define CONCAT(a,b) PASTE(a,b)
#ifdef PREFIX
#define EXTERN CONCAT(_,PRIVATE_PREFIX)
#else
#define EXTERN PRIVATE_PREFIX
#endif
.macro function name, export=0, align=2
.macro endfunc
#ifdef __ELF__
.size \name, . - \name
#endif
#if HAVE_AS_FUNC
.endfunc
#endif
.purgem endfunc
.endm
.text
.align \align
.if \export
.global EXTERN\name
#ifdef __ELF__
.type EXTERN\name, %function
#endif
#if HAVE_AS_FUNC
.func EXTERN\name
#endif
EXTERN\name:
.else
#ifdef __ELF__
.type \name, %function
#endif
#if HAVE_AS_FUNC
.func \name
#endif
.endif
\name:
.endm
.macro const name, align=2
.macro endconst
#ifdef __ELF__
.size \name, . - \name
#endif
.purgem endconst
.endm
#if !defined(__MACH__)
.section .rodata
#else
.const_data
#endif
.align \align
\name:
.endm
#endif /* __DAV1D_SRC_ARM_ASM_S__ */
/*
* Copyright © 2018, VideoLAN and dav1d authors
* Copyright © 2018, Janne Grunau
* 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/cpu.h"
unsigned dav1d_get_cpu_flags_arm(void) {
return DAV1D_ARM_CPU_FLAG_NEON;
}
/*
* Copyright © 2018, VideoLAN and dav1d authors
* Copyright © 2018, Janne Grunau
* 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_SRC_ARM_CPU_H__
#define __DAV1D_SRC_ARM_CPU_H__
enum CpuFlags {
DAV1D_ARM_CPU_FLAG_NEON = 1 << 0,
};
unsigned dav1d_get_cpu_flags_arm(void);
#endif /* __DAV1D_SRC_ARM_CPU_H__ */
......@@ -387,7 +387,7 @@ static const CdfModeContext av1_default_cdf = {
{ { AOM_CDF2(28015) }, { AOM_CDF2(21546) }, { AOM_CDF2(14400) }, },
{ { AOM_CDF2(28165) }, { AOM_CDF2(22401) }, { AOM_CDF2(16088) }, },
}, .txtp_inter = {
{}, {
{ { 0 } }, {
{ AOM_CDF16(4458, 5560, 7695, 9709, 13330, 14789, 17537, 20266,
21504, 22848, 23934, 25474, 27727, 28915, 30631) },
{ AOM_CDF16(1645, 2573, 4778, 5711, 7807, 8622, 10522, 15357,
......@@ -412,7 +412,7 @@ static const CdfModeContext av1_default_cdf = {
{ AOM_CDF2(748) },
},
}, .txtp_intra = {
{}, {
{ { { 0 } } }, {
{
{ AOM_CDF7(1535, 8035, 9461, 12751, 23467, 27825) },
{ AOM_CDF7(564, 3335, 9709, 10870, 18143, 28094) },
......
/*
* 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.
*/
#include "config.h"
#include <stdint.h>
#include "src/cpu.h"
static unsigned flags_mask = -1;
unsigned dav1d_get_cpu_flags(void) {
static unsigned flags;
static uint8_t checked = 0;
if (!checked) {
#if ARCH_AARCH64 || ARCH_ARM
flags = dav1d_get_cpu_flags_arm();
#elif ARCH_X86 && HAVE_ASM
flags = dav1d_get_cpu_flags_x86();
#else
flags = 0;
#endif
checked = 1;
}
return flags & flags_mask;
}
void dav1d_set_cpu_flags_mask(const unsigned mask) {
flags_mask = mask;
}
/*
* 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_SRC_CPU_H__
#define __DAV1D_SRC_CPU_H__
#include "config.h"
#if ARCH_AARCH64 || ARCH_ARM
#include "src/arm/cpu.h"
#elif ARCH_X86
#include "src/x86/cpu.h"
#endif
unsigned dav1d_get_cpu_flags(void);
void dav1d_set_cpu_flags_mask(const unsigned mask);
#endif /* __DAV1D_SRC_CPU_H__ */
......@@ -48,7 +48,28 @@ int dav1d_data_create(Dav1dData *const buf, const size_t sz) {
return 0;
}
int dav1d_data_wrap(Dav1dData *const buf, uint8_t *const ptr, const size_t sz,
void (*free_callback)(uint8_t *data, void *user_data),
void *user_data)
{
validate_input_or_ret(buf != NULL, -EINVAL);
validate_input_or_ret(ptr != NULL, -EINVAL);
validate_input_or_ret(free_callback != NULL, -EINVAL);
buf->ref = dav1d_ref_wrap(ptr, sz, free_callback, user_data);
if (!buf->ref) return -ENOMEM;
buf->data = ptr;
buf->sz = sz;
return 0;
}
void dav1d_data_unref(Dav1dData *const buf) {
dav1d_ref_dec(buf->ref);
validate_input(buf != NULL);
if (buf->ref) {
validate_input(buf->data != NULL);
dav1d_ref_dec(buf->ref);
}
memset(buf, 0, sizeof(*buf));
}
#define VERSION_NUMBER @VERSION_MAJOR@,@VERSION_MINOR@,@VERSION_REVISION@,@VERSION_EXTRA@
#define VERSION_NUMBER_STR "@VERSION_MAJOR@.@VERSION_MINOR@.@VERSION_REVISION@.@VERSION_EXTRA@"
#include <windows.h>
1 VERSIONINFO
FILETYPE VFT_DLL
FILEOS VOS_NT_WINDOWS32
PRODUCTVERSION VERSION_NUMBER
FILEVERSION VERSION_NUMBER
BEGIN
BLOCK "StringFileInfo"
BEGIN
BLOCK "040904E4"
BEGIN
VALUE "CompanyName", "VideoLAN"
VALUE "ProductName", "dav1d"
VALUE "ProductVersion", VERSION_NUMBER_STR
VALUE "FileVersion", VERSION_NUMBER_STR
VALUE "FileDescription", "dav1d AV1 decoder"
VALUE "InternalName", "dav1d"
VALUE "OriginalFilename", "libdav1d.dll"
VALUE "LegalCopyright", "Copyright \251 @COPYRIGHT_YEARS@ VideoLAN and dav1d Authors"
END
END
BLOCK "VarFileInfo"
BEGIN
VALUE "Translation", 0x409, 1252
END
END
......@@ -449,20 +449,20 @@ static void read_pal_plane(Dav1dTileContext *const t, Av1Block *const b,
if (DEBUG_BLOCK_INFO) {
printf("Post-pal[pl=%d,sz=%d,cache_size=%d,used_cache=%d]: r=%d, cache=",
pl, b->pal_sz[pl], n_cache, n_used_cache, ts->msac.rng);
pl, pal_sz, n_cache, n_used_cache, ts->msac.rng);
for (int n = 0; n < n_cache; n++)
printf("%c%02x", n ? ' ' : '[', cache[n]);
printf("%s, pal=", n_cache ? "]" : "[]");
for (int n = 0; n < b->pal_sz[0]; n++)
for (int n = 0; n < pal_sz; n++)
printf("%c%02x", n ? ' ' : '[', pal[n]);
printf("]\n");
}
}
static void read_pal_uv(Dav1dTileContext *const t, Av1Block *const b,
const int sz_ctx, const int cbx4, const int cby4)
const int sz_ctx, const int bx4, const int by4)
{
read_pal_plane(t, b, 1, sz_ctx, cbx4, cby4);
read_pal_plane(t, b, 1, sz_ctx, bx4, by4);
// V pal coding
Dav1dTileState *const ts = t->ts;
......@@ -1013,8 +1013,8 @@ static void decode_b(Dav1dTileContext *const t,
msac_decode_bool_adapt(&ts->msac, ts->cdf.m.pal_uv[pal_ctx]);
if (DEBUG_BLOCK_INFO)
printf("Post-uv_pal[%d]: r=%d\n", use_uv_pal, ts->msac.rng);
if (use_uv_pal)
read_pal_uv(t, b, sz_ctx, cbx4, cby4);
if (use_uv_pal) // see aomedia bug 2183 for why we use luma coordinates
read_pal_uv(t, b, sz_ctx, bx4, by4);
}
}
......@@ -1118,17 +1118,22 @@ static void decode_b(Dav1dTileContext *const t,
if (has_chroma) {
memset(&t->l.uvmode[cby4], b->uv_mode, cbh4);
memset(&t->a->uvmode[cbx4], b->uv_mode, cbw4);
memset(&t->pal_sz_uv[1][cby4], b->pal_sz[1], cbh4);
memset(&t->pal_sz_uv[0][cbx4], b->pal_sz[1], cbw4);
// see aomedia bug 2183 for why we use luma coordinates here
memset(&t->pal_sz_uv[1][by4], b->pal_sz[1], bh4);
memset(&t->pal_sz_uv[0][bx4], b->pal_sz[1], bw4);
if (b->pal_sz[1]) for (int pl = 1; pl < 3; pl++) {
uint16_t *const pal = f->frame_thread.pass ?
f->frame_thread.pal[((t->by >> 1) + (t->bx & 1)) * (f->b4_stride >> 1) +
((t->bx >> 1) + (t->by & 1))][pl] : t->pal[pl];
for (int x = 0; x < cbw4; x++)
memcpy(t->al_pal[0][cbx4 + x][pl], pal, 16);
for (int y = 0; y < cbh4; y++)
memcpy(t->al_pal[1][cby4 + y][pl], pal, 16);
// see aomedia bug 2183 for why we use luma coordinates here
for (int x = 0; x < bw4; x++)
memcpy(t->al_pal[0][bx4 + x][pl], pal, 16);
for (int y = 0; y < bh4; y++)
memcpy(t->al_pal[1][by4 + y][pl], pal, 16);
}
} else { // see aomedia bug 2183 for why we reset this
memset(&t->pal_sz_uv[1][by4], 0, bh4);
memset(&t->pal_sz_uv[0][bx4], 0, bw4);
}
if ((f->frame_hdr.frame_type & 1) || f->frame_hdr.allow_intrabc) {
memset(&t->a->tx[bx4], t_dim->lw, bw4);
......@@ -1196,11 +1201,12 @@ static void decode_b(Dav1dTileContext *const t,
memset(&t->a->mode[bx4], DC_PRED, bw4);
memset(&t->l.pal_sz[by4], 0, bh4);
memset(&t->a->pal_sz[bx4], 0, bw4);
// see aomedia bug 2183 for why this is outside if (has_chroma)
memset(&t->pal_sz_uv[1][by4], 0, bh4);
memset(&t->pal_sz_uv[0][bx4], 0, bw4);
if (has_chroma) {
memset(&t->l.uvmode[cby4], DC_PRED, cbh4);
memset(&t->a->uvmode[cbx4], DC_PRED, cbw4);
memset(&t->pal_sz_uv[1][cby4], 0, cbh4);
memset(&t->pal_sz_uv[0][cbx4], 0, cbw4);
}
} else {
// inter-specific mode/mv coding
......@@ -1696,11 +1702,12 @@ static void decode_b(Dav1dTileContext *const t,
}
memset(&t->l.pal_sz[by4], 0, bh4);
memset(&t->a->pal_sz[bx4], 0, bw4);
// see aomedia bug 2183 for why this is outside if (has_chroma)
memset(&t->pal_sz_uv[1][by4], 0, bh4);
memset(&t->pal_sz_uv[0][bx4], 0, bw4);
if (has_chroma) {
memset(&t->l.uvmode[cby4], DC_PRED, cbh4);
memset(&t->a->uvmode[cbx4], DC_PRED, cbw4);
memset(&t->pal_sz_uv[1][cby4], 0, cbh4);
memset(&t->pal_sz_uv[0][cbx4], 0, cbw4);
}
memset(&t->a->tx_intra[bx4], b_dim[2], bw4);
memset(&t->l.tx_intra[by4], b_dim[3], bh4);
......@@ -2544,7 +2551,7 @@ int decode_frame(Dav1dFrameContext *const f) {
{
t->by = sby << (4 + f->seq_hdr.sb128);
for (int tile_col = 0; tile_col < f->frame_hdr.tiling.cols; tile_col++) {
t->ts = &f->ts[tile_row * f->frame_hdr.tiling.rows + tile_col];
t->ts = &f->ts[tile_row * f->frame_hdr.tiling.cols + tile_col];
int res;
if ((res = decode_tile_sbrow(t)))
......@@ -2681,7 +2688,7 @@ int submit_frame(Dav1dContext *const c) {
&f->frame_thread.td.lock);
out_delayed = &c->frame_thread.out_delayed[next];
if (out_delayed->p.data[0]) {
if (out_delayed->visible)
if (out_delayed->visible && !out_delayed->flushed)
dav1d_picture_ref(&c->out, &out_delayed->p);
dav1d_thread_picture_unref(out_delayed);
}
......@@ -2772,6 +2779,7 @@ int submit_frame(Dav1dContext *const c) {
}
f->cur.p.poc = f->frame_hdr.frame_offset;
f->cur.p.p.type = f->frame_hdr.frame_type;
f->cur.p.p.pri = f->seq_hdr.pri;
f->cur.p.p.trc = f->seq_hdr.trc;
f->cur.p.p.mtrx = f->seq_hdr.mtrx;
......
......@@ -408,13 +408,13 @@ static inline int av1_get_fwd_ref_2_ctx(const BlockContext *const a,
int cnt[2] = { 0 };
if (have_top && !a->intra[xb4]) {
if (a->ref[0][xb4] - 2U < 2) cnt[a->ref[0][xb4] - 2]++;
if (a->comp_type[xb4] && a->ref[1][xb4] - 2U < 2) cnt[a->ref[1][xb4] - 2]++;
if ((a->ref[0][xb4] ^ 2U) < 2) cnt[a->ref[0][xb4] - 2]++;
if (a->comp_type[xb4] && (a->ref[1][xb4] ^ 2U) < 2) cnt[a->ref[1][xb4] - 2]++;
}
if (have_left && !l->intra[yb4]) {
if (l->ref[0][yb4] - 2U < 2) cnt[l->ref[0][yb4] - 2]++;
if (l->comp_type[yb4] && l->ref[1][yb4] - 2U < 2) cnt[l->ref[1][yb4] - 2]++;
if ((l->ref[0][yb4] ^ 2U) < 2) cnt[l->ref[0][yb4] - 2]++;
if (l->comp_type[yb4] && (l->ref[1][yb4] ^ 2U) < 2) cnt[l->ref[1][yb4] - 2]++;
}
return cnt[0] == cnt[1] ? 1 : cnt[0] < cnt[1] ? 0 : 2;
......
......@@ -145,23 +145,23 @@ dc_lfn(width, height,, unsigned dc = (width + height) >> 1; \
#endif
dc2d_lfn( 4, 4, dc >>= 3)
dc2d_lfn( 4, 8, dc = iclip_pixel(MULTIPLIER_1x2 * dc >> (BASE_SHIFT + 2)))
dc2d_lfn( 4, 16, dc = iclip_pixel(MULTIPLIER_1x4 * dc >> (BASE_SHIFT + 2)))
dc2d_lfn( 8, 4, dc = iclip_pixel(MULTIPLIER_1x2 * dc >> (BASE_SHIFT + 2)))
dc2d_lfn( 4, 8, dc = iclip_pixel(MULTIPLIER_1x2 * (dc >> 2) >> BASE_SHIFT))
dc2d_lfn( 4, 16, dc = iclip_pixel(MULTIPLIER_1x4 * (dc >> 2) >> BASE_SHIFT))
dc2d_lfn( 8, 4, dc = iclip_pixel(MULTIPLIER_1x2 * (dc >> 2) >> BASE_SHIFT))
dc2d_lfn( 8, 8, dc >>= 4)
dc2d_lfn( 8, 16, dc = iclip_pixel(MULTIPLIER_1x2 * dc >> (BASE_SHIFT + 3)))
dc2d_lfn( 8, 32, dc = iclip_pixel(MULTIPLIER_1x4 * dc >> (BASE_SHIFT + 3)))
dc2d_lfn(16, 4, dc = iclip_pixel(MULTIPLIER_1x4 * dc >> (BASE_SHIFT + 2)))
dc2d_lfn(16, 8, dc = iclip_pixel(MULTIPLIER_1x2 * dc >> (BASE_SHIFT + 3)))
dc2d_lfn( 8, 16, dc = iclip_pixel(MULTIPLIER_1x2 * (dc >> 3) >> BASE_SHIFT))
dc2d_lfn( 8, 32, dc = iclip_pixel(MULTIPLIER_1x4 * (dc >> 3) >> BASE_SHIFT))
dc2d_lfn(16, 4, dc = iclip_pixel(MULTIPLIER_1x4 * (dc >> 2) >> BASE_SHIFT))
dc2d_lfn(16, 8, dc = iclip_pixel(MULTIPLIER_1x2 * (dc >> 3) >> BASE_SHIFT))
dc2d_lfn(16, 16, dc >>= 5)
dc2d_lfn(16, 32, dc = iclip_pixel(MULTIPLIER_1x2 * dc >> (BASE_SHIFT + 4)))
dc2d_lfn(16, 64, dc = iclip_pixel(MULTIPLIER_1x4 * dc >> (BASE_SHIFT + 4)))
dc2d_lfn(32, 8, dc = iclip_pixel(MULTIPLIER_1x4 * dc >> (BASE_SHIFT + 3)))
dc2d_lfn(32, 16, dc = iclip_pixel(MULTIPLIER_1x2 * dc >> (BASE_SHIFT + 4)))
dc2d_lfn(16, 32, dc = iclip_pixel(MULTIPLIER_1x2 * (dc >> 4) >> BASE_SHIFT))
dc2d_lfn(16, 64, dc = iclip_pixel(MULTIPLIER_1x4 * (dc >> 4) >> BASE_SHIFT))
dc2d_lfn(32, 8, dc = iclip_pixel(MULTIPLIER_1x4 * (dc >> 3) >> BASE_SHIFT))
dc2d_lfn(32, 16, dc = iclip_pixel(MULTIPLIER_1x2 * (dc >> 4) >> BASE_SHIFT))
dc2d_lfn(32, 32, dc >>= 6)
dc2d_lfn(32, 64, dc = iclip_pixel(MULTIPLIER_1x2 * dc >> (BASE_SHIFT + 5)))
dc2d_lfn(64, 16, dc = iclip_pixel(MULTIPLIER_1x4 * dc >> (BASE_SHIFT + 4)))
dc2d_lfn(64, 32, dc = iclip_pixel(MULTIPLIER_1x2 * dc >> (BASE_SHIFT + 5)))
dc2d_lfn(32, 64, dc = iclip_pixel(MULTIPLIER_1x2 * (dc >> 5) >> BASE_SHIFT))
dc2d_lfn(64, 16, dc = iclip_pixel(MULTIPLIER_1x4 * (dc >> 4) >> BASE_SHIFT))
dc2d_lfn(64, 32, dc = iclip_pixel(MULTIPLIER_1x2 * (dc >> 5) >> BASE_SHIFT))
dc2d_lfn(64, 64, dc >>= 7)
#undef MULTIPLIER_1x2
......@@ -880,18 +880,46 @@ cfl_ac_fn(32, 16, 32, 16, 0, 0, 9)
cfl_ac_fn(32, 32, 32, 32, 0, 0, 10)
static NOINLINE void
cfl_pred_c(pixel *dstU, pixel *dstV, const ptrdiff_t stride,
const int16_t *ac, const pixel *const dc_pred,
cfl_pred_1_c(pixel *dst, const ptrdiff_t stride, const int16_t *ac,
const int8_t alpha, const int width, const int height)
{
const pixel dc = *dst;
for (int y = 0; y < height; y++) {
for (int x = 0; x < width; x++) {
const int diff = alpha * ac[x];
dst[x] = iclip_pixel(dc + apply_sign((abs(diff) + 32) >> 6, diff));
}
ac += width;
dst += PXSTRIDE(stride);
}
}
#define cfl_pred_1_fn(width) \
static void cfl_pred_1_##width##xN_c(pixel *const dst, \
const ptrdiff_t stride, \
const int16_t *const ac, \
const int8_t alpha, \
const int height) \
{ \
cfl_pred_1_c(dst, stride, ac, alpha, width, height); \
}
cfl_pred_1_fn( 4)
cfl_pred_1_fn( 8)
cfl_pred_1_fn(16)
cfl_pred_1_fn(32)
static NOINLINE void
cfl_pred_c(pixel *dstU, pixel *dstV, const ptrdiff_t stride, const int16_t *ac,
const int8_t *const alphas, const int width, const int height)
{
const pixel dcU = *dstU, dcV = *dstV;
for (int y = 0; y < height; y++) {
for (int x = 0; x < width; x++) {
const int diff1 = alphas[0] * ac[x];
dstU[x] = iclip_pixel(dc_pred[ 0] + apply_sign((abs(diff1) + 32) >> 6,
diff1));
dstU[x] = iclip_pixel(dcU + apply_sign((abs(diff1) + 32) >> 6, diff1));
const int diff2 = alphas[1] * ac[x];
dstV[x] = iclip_pixel(dc_pred[32] + apply_sign((abs(diff2) + 32) >> 6,
diff2));
dstV[x] = iclip_pixel(dcV + apply_sign((abs(diff2) + 32) >> 6, diff2));
}
ac += width;
dstU += PXSTRIDE(stride);
......@@ -904,11 +932,10 @@ static void cfl_pred_##width##xN_c(pixel *const dstU, \
pixel *const dstV, \
const ptrdiff_t stride, \
const int16_t *const ac, \
const pixel *const dc_pred, \
const int8_t *const alphas, \
const int height) \
{ \
cfl_pred_c(dstU, dstV, stride, ac, dc_pred, alphas, width, height); \
cfl_pred_c(dstU, dstV, stride, ac, alphas, width, height); \
}
cfl_pred_fn( 4)
......@@ -1016,6 +1043,11 @@ void bitfn(dav1d_intra_pred_dsp_init)(Dav1dIntraPredDSPContext *const c) {
c->cfl_ac[DAV1D_PIXEL_LAYOUT_I444 - 1][RTX_32X16] = cfl_ac_32x16_to_32x16_c;
c->cfl_ac[DAV1D_PIXEL_LAYOUT_I444 - 1][ TX_32X32] = cfl_ac_32x32_to_32x32_c;
c->cfl_pred_1[0] = cfl_pred_1_4xN_c;
c->cfl_pred_1[1] = cfl_pred_1_8xN_c;
c->cfl_pred_1[2] = cfl_pred_1_16xN_c;
c->cfl_pred_1[3] = cfl_pred_1_32xN_c;
c->cfl_pred[0] = cfl_pred_4xN_c;
c->cfl_pred[1] = cfl_pred_8xN_c;
c->cfl_pred[2] = cfl_pred_16xN_c;
......
......@@ -55,15 +55,23 @@ void (name)(int16_t *ac, const pixel *y, ptrdiff_t stride, \
typedef decl_cfl_ac_fn(*cfl_ac_fn);
/*
* dst[plane][x,y] = dc[plane] + alpha[plane] * ac[x,y]
* dst[x,y] += alpha * ac[x,y]
* - alpha contains a q3 scalar in [-16,16] range;
*/
#define decl_cfl_pred_1_fn(name) \
void (name)(pixel *dst, ptrdiff_t stride, \
const int16_t *ac, const int8_t alpha, \
const int height)
typedef decl_cfl_pred_1_fn(*cfl_pred_1_fn);
/*
* dst[plane][x,y] += alpha[plane] * ac[x,y]
* - alphas contains two q3 scalars (one for each plane) in [-16,16] range;
* - dc_pred[] is the first line of each plane's DC prediction, the second plane
* starting at an offset of 16 * sizeof(pixel) bytes.
*/
#define decl_cfl_pred_fn(name) \
void (name)(pixel *u_dst, pixel *v_dst, ptrdiff_t stride, \
const int16_t *ac, const pixel *dc_pred, \
const int8_t *const alphas, const int height)
const int16_t *ac, const int8_t *const alphas, \
const int height)
typedef decl_cfl_pred_fn(*cfl_pred_fn);
/*
......@@ -80,6 +88,7 @@ typedef struct Dav1dIntraPredDSPContext {
// chroma-from-luma
cfl_ac_fn cfl_ac[3 /* 420, 422, 444 */][N_RECT_TX_SIZES /* chroma tx size */];
cfl_pred_1_fn cfl_pred_1[4];
cfl_pred_fn cfl_pred[4];
// palette
......
......@@ -40,13 +40,6 @@ enum ObuType {
OBU_PADDING = 15,
};
enum FrameType {
KEY_FRAME = 0,
INTER_FRAME = 1,
INTRAONLY_FRAME = 2,
S_FRAME = 3,
} FRAME_TYPE;
enum TxfmSize {
TX_4X4,
TX_8X8,
......@@ -421,7 +414,7 @@ typedef struct Av1FrameHeader {
int show_existing_frame;
int existing_frame_idx;
int frame_id;
enum FrameType frame_type;
enum Dav1dFrameType frame_type;
int show_frame;
int showable_frame;
int error_resilient_mode;
......
......@@ -111,13 +111,17 @@ static inline void mask_edges_inter(uint32_t (*masks)[32][3],
for (y = 0; y < h4; y++) {
int ltx = txa[0][0][y][0];
int step = txa[0][1][y][0];