...
 
Commits (119)
...@@ -2,17 +2,29 @@ stages: ...@@ -2,17 +2,29 @@ stages:
- build - build
build-debian: build-debian:
image: registry.videolan.org:5000/dav1d-debian-unstable:20180927123816 image: registry.videolan.org:5000/dav1d-debian-unstable:20180928151533
stage: build stage: build
tags: tags:
- debian - debian
- amd64 - amd64
script: script:
- meson build --buildtype release - meson build --buildtype release
- ninja -v -C build - ninja -C build
- cd build && meson test -v
build-debian-static:
image: registry.videolan.org:5000/dav1d-debian-unstable:20180928151533
stage: build
tags:
- debian
- amd64
script:
- meson build --buildtype release --default-library static
- ninja -C build
- cd build && meson test -v
build-win32: build-win32:
image: registry.videolan.org:5000/dav1d-debian-unstable:20180927123816 image: registry.videolan.org:5000/dav1d-debian-unstable:20180928151533
stage: build stage: build
tags: tags:
- win32 - win32
...@@ -22,8 +34,8 @@ build-win32: ...@@ -22,8 +34,8 @@ build-win32:
--prefix "$(pwd)/build/dav1d_install" --prefix "$(pwd)/build/dav1d_install"
--cross-file /opt/crossfiles/i686-w64-mingw32.meson --cross-file /opt/crossfiles/i686-w64-mingw32.meson
-Ddefault_library=both -Ddefault_library=both
- ninja -v -C build - ninja -C build
- ninja -v -C build install - ninja -C build install
artifacts: artifacts:
name: "$CI_JOB_NAME-$CI_COMMIT_REF_SLUG" name: "$CI_JOB_NAME-$CI_COMMIT_REF_SLUG"
paths: paths:
...@@ -31,7 +43,7 @@ build-win32: ...@@ -31,7 +43,7 @@ build-win32:
expire_in: 1 week expire_in: 1 week
build-win64: build-win64:
image: registry.videolan.org:5000/dav1d-debian-unstable:20180927123816 image: registry.videolan.org:5000/dav1d-debian-unstable:20180928151533
stage: build stage: build
tags: tags:
- win64 - win64
...@@ -41,10 +53,40 @@ build-win64: ...@@ -41,10 +53,40 @@ build-win64:
--prefix "$(pwd)/build/dav1d_install" --prefix "$(pwd)/build/dav1d_install"
--cross-file /opt/crossfiles/x86_64-w64-mingw32.meson --cross-file /opt/crossfiles/x86_64-w64-mingw32.meson
-Ddefault_library=both -Ddefault_library=both
- ninja -v -C build - ninja -C build
- ninja -v -C build install - ninja -C build install
artifacts: artifacts:
name: "$CI_JOB_NAME-$CI_COMMIT_REF_SLUG" name: "$CI_JOB_NAME-$CI_COMMIT_REF_SLUG"
paths: paths:
- build/dav1d_install/ - build/dav1d_install/
expire_in: 1 week expire_in: 1 week
build-debian-aarch64:
stage: build
tags:
- aarch64
- debian
script:
- meson build --buildtype release
- ninja -C build
- cd build && meson test -v
build-debian-aarch64-clang-5:
stage: build
tags:
- aarch64
- clang5
- debian
script:
- env CC=clang-5.0 CFLAGS='-integrated-as' meson build --buildtype release
- ninja -C build
- cd build && meson test -v
build-macos:
stage: build
tags:
- macos
script:
- meson build --buildtype release -Ddefault_library=both
- ninja -C build
- cd build && meson test -v
...@@ -61,7 +61,7 @@ The [VideoLAN Code of Conduct](https://wiki.videolan.org/CoC) applies to this pr ...@@ -61,7 +61,7 @@ The [VideoLAN Code of Conduct](https://wiki.videolan.org/CoC) applies to this pr
# Compile # Compile
1. Install [Meson](https://mesonbuild.com/) (0.47 or higher) 1. Install [Meson](https://mesonbuild.com/) (0.47 or higher), [Ninja](https://ninja-build.org/), and, for x86* targets, [nasm](https://nasm.us/) (2.13 or higher)
2. Run `meson build --buildtype release` 2. Run `meson build --buildtype release`
3. Build with `ninja -C build` 3. Build with `ninja -C build`
......
...@@ -66,6 +66,11 @@ ...@@ -66,6 +66,11 @@
#define NOINLINE __attribute__((noinline)) #define NOINLINE __attribute__((noinline))
#endif /* !_MSC_VER */ #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 #ifdef _MSC_VER
#include <intrin.h> #include <intrin.h>
...@@ -82,11 +87,20 @@ static inline int clz(const unsigned int mask) { ...@@ -82,11 +87,20 @@ static inline int clz(const unsigned int mask) {
return (31 - leading_zero); return (31 - leading_zero);
} }
#ifndef _M_IX86
static inline int clzll(const unsigned long long mask) { static inline int clzll(const unsigned long long mask) {
unsigned long leading_zero = 0; unsigned long leading_zero = 0;
_BitScanReverse64(&leading_zero, mask); _BitScanReverse64(&leading_zero, mask);
return (63 - leading_zero); return (63 - leading_zero);
} }
#else /* _M_IX86 */
static inline int clzll(const unsigned long long mask) {
if (mask >> 32)
return clz((unsigned)(mask >> 32));
else
return clz((unsigned)mask) + 32;
}
#endif /* _M_IX86 */
#else /* !_MSC_VER */ #else /* !_MSC_VER */
static inline int ctz(const unsigned int mask) { static inline int ctz(const unsigned int mask) {
return __builtin_ctz(mask); return __builtin_ctz(mask);
......
...@@ -50,8 +50,6 @@ extern int optreset; ...@@ -50,8 +50,6 @@ extern int optreset;
* specific block, only when *not* __UNISTD_H_SOURCED__, in which * specific block, only when *not* __UNISTD_H_SOURCED__, in which
* to declare the extended API. * to declare the extended API.
*/ */
#endif /* !defined(__GETOPT_H__) */
#if !defined(__UNISTD_H_SOURCED__) && !defined(__GETOPT_LONG_H__) #if !defined(__UNISTD_H_SOURCED__) && !defined(__GETOPT_LONG_H__)
#define __GETOPT_LONG_H__ #define __GETOPT_LONG_H__
...@@ -93,3 +91,5 @@ extern int getopt_long_only(int nargc, char * const *nargv, const char *options, ...@@ -93,3 +91,5 @@ extern int getopt_long_only(int nargc, char * const *nargv, const char *options,
#endif #endif
#endif /* !defined(__UNISTD_H_SOURCED__) && !defined(__GETOPT_LONG_H__) */ #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_ */
...@@ -41,12 +41,37 @@ typedef struct Dav1dData { ...@@ -41,12 +41,37 @@ typedef struct Dav1dData {
/** /**
* Allocate data. * Allocate data.
*
* @param data Input context.
* @param sz Size of the data that should be allocated.
*
* @return 0 on success. A negative errno value on error.
*/ */
DAV1D_API int dav1d_data_create(Dav1dData *data, size_t sz); DAV1D_API int dav1d_data_create(Dav1dData *data, size_t sz);
/** /**
* Free data. * 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 $user_data
* will be the $user_data input argument to this function.
* @param user_data Opaque parameter passed to free_callback().
*
* @return 0 on success. A negative errno value on error.
*/
DAV1D_API int dav1d_data_wrap(Dav1dData *data, uint8_t *buf, size_t sz,
void (*free_callback)(uint8_t *buf, void *user_data),
void *user_data);
/**
* Free the data reference.
*
* @param data Input context.
*/ */
DAV1D_API void dav1d_data_unref(Dav1dData *buf); DAV1D_API void dav1d_data_unref(Dav1dData *data);
#endif /* __DAV1D_DATA_H__ */ #endif /* __DAV1D_DATA_H__ */
...@@ -38,13 +38,9 @@ typedef struct Dav1dRef Dav1dRef; ...@@ -38,13 +38,9 @@ typedef struct Dav1dRef Dav1dRef;
typedef struct Dav1dSettings { typedef struct Dav1dSettings {
int n_frame_threads; int n_frame_threads;
int n_tile_threads; int n_tile_threads;
Dav1dPicAllocator allocator;
} Dav1dSettings; } Dav1dSettings;
/*
* Init the library.
*/
DAV1D_API void dav1d_init(void);
/** /**
* Get library version. * Get library version.
*/ */
...@@ -52,36 +48,58 @@ DAV1D_API const char *dav1d_version(void); ...@@ -52,36 +48,58 @@ DAV1D_API const char *dav1d_version(void);
/** /**
* Initialize settings to default values. * Initialize settings to default values.
*
* @param s Input settings context.
*/ */
DAV1D_API void dav1d_default_settings(Dav1dSettings *s); DAV1D_API void dav1d_default_settings(Dav1dSettings *s);
/** /**
* Open/allocate decoder instance. * Allocate and open a decoder instance.
* *
* The resulting instance context will be placed in $c_out and can be used in * @param c_out The decoder instance to open. To be used in iterative calls to
* iterative calls to dav1d_decode(). * dav1d_decode(). *c_out will be set to the allocated context.
* @param s Input settings context.
* *
* You should free the context using dav1d_close() when you're done decoding. * @note The context must be freed using dav1d_close() when decoding is
* finished.
* *
* This returns < 0 (a negative errno code) on error, or 0 on success. * @return 0 on success, or < 0 (a negative errno code) on error.
*/ */
DAV1D_API int dav1d_open(Dav1dContext **c_out, const Dav1dSettings *s); DAV1D_API int dav1d_open(Dav1dContext **c_out, const Dav1dSettings *s);
/** /**
* Decode one input frame. Library takes ownership of the passed-in reference. * Decode one frame.
* After that, it will return < 0 (a negative errno code, but not -EAGAIN) on *
* failure, or 0 on success. If any decoded output frames are available, they * @param c Input decoder instance.
* will be placed in $out. The caller assumes ownership of the returned output * @param in Input bitstream data. On success, the caller retains ownership of
* picture. * the input reference if the data was not fully consumed.
* @param out Output frame. The caller assumes ownership of the returned
* reference.
*
* @return
* 0: Success, and a frame is returned.
* -EAGAIN: Not enough data to output a frame. The fuction should be called
* again with new input.
* other negative errno codes: Error during decoding or because of invalid
* passed-in arguments.
* *
* To flush the decoder (i.e. all input is finished), feed it NULL input data * @note To flush the decoder (i.e. all input is finished), feed it NULL input
* until it returns -EAGAIN. * data until it returns -EAGAIN.
*/ */
DAV1D_API int dav1d_decode(Dav1dContext *c, Dav1dData *in, Dav1dPicture *out); DAV1D_API int dav1d_decode(Dav1dContext *c, Dav1dData *in, Dav1dPicture *out);
/** /**
* Close decoder instance, free all associated memory, and set $c_out to NULL. * 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); DAV1D_API void dav1d_close(Dav1dContext **c_out);
/**
* Flush all delayed frames in decoder, to be used when seeking.
*
* @param c Input decoder instance.
*/
DAV1D_API void dav1d_flush(Dav1dContext *c);
#endif /* __DAV1D_H__ */ #endif /* __DAV1D_H__ */
...@@ -40,6 +40,13 @@ enum Dav1dPixelLayout { ...@@ -40,6 +40,13 @@ enum Dav1dPixelLayout {
DAV1D_PIXEL_LAYOUT_I444, ///< 4:4:4 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 { enum Dav1dColorPrimaries {
DAV1D_COLOR_PRI_BT709 = 1, DAV1D_COLOR_PRI_BT709 = 1,
DAV1D_COLOR_PRI_UNKNOWN = 2, DAV1D_COLOR_PRI_UNKNOWN = 2,
...@@ -103,6 +110,7 @@ typedef struct Dav1dPictureParameters { ...@@ -103,6 +110,7 @@ typedef struct Dav1dPictureParameters {
int w; ///< width (in pixels) int w; ///< width (in pixels)
int h; ///< height (in pixels) int h; ///< height (in pixels)
enum Dav1dPixelLayout layout; ///< format of the picture enum Dav1dPixelLayout layout; ///< format of the picture
enum Dav1dFrameType type; ///< type of the picture
int bpc; ///< bits per pixel component (8 or 10) int bpc; ///< bits per pixel component (8 or 10)
enum Dav1dColorPrimaries pri; ///< color primaries (av1) enum Dav1dColorPrimaries pri; ///< color primaries (av1)
...@@ -135,8 +143,21 @@ typedef struct Dav1dPicture { ...@@ -135,8 +143,21 @@ typedef struct Dav1dPicture {
Dav1dPictureParameters p; Dav1dPictureParameters p;
int poc; ///< frame number int poc; ///< frame number
void *allocator_tag; ///< pointer managed by the allocator
} Dav1dPicture; } Dav1dPicture;
typedef struct Dav1dPicAllocator {
void *cookie;
/**
* Needs to fill the picture data[0], data[1], data[2].
* The allocator can fill the picture allocator_tag pointer with a custom
* pointer that will be passed to pf_release_picture().
*/
uint8_t* (*pf_alloc_picture)(Dav1dPicture *, void* cookie);
void (*pf_release_picture)(uint8_t *, void *allocator_tag, void* cookie);
} Dav1dPicAllocator;
/** /**
* Release reference to a picture. * Release reference to a picture.
*/ */
......
...@@ -22,6 +22,7 @@ ...@@ -22,6 +22,7 @@
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. # SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
# Revision file (version.h) generation
dav1d_git_dir = join_paths(dav1d_src_root, '.git') dav1d_git_dir = join_paths(dav1d_src_root, '.git')
rev_target = vcs_tag(command: [ rev_target = vcs_tag(command: [
'git', '--git-dir', dav1d_git_dir, 'git', '--git-dir', dav1d_git_dir,
...@@ -31,3 +32,6 @@ rev_target = vcs_tag(command: [ ...@@ -31,3 +32,6 @@ rev_target = vcs_tag(command: [
input: 'version.h.in', input: 'version.h.in',
output: 'version.h' output: 'version.h'
) )
# Install include/dav1d headers
install_subdir('dav1d', install_dir: 'include')
...@@ -24,52 +24,152 @@ ...@@ -24,52 +24,152 @@
project('dav1d', ['c'], project('dav1d', ['c'],
version: '0.0.1', version: '0.0.1',
default_options: ['c_std=c99'], default_options: ['c_std=c99',
'warning_level=2'],
meson_version: '>= 0.47.0') 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() dav1d_src_root = meson.current_source_dir()
cc = meson.get_compiler('c')
# Configuratin data for config.h
cdata = configuration_data() cdata = configuration_data()
# Configuration data for config.asm
cdata_asm = configuration_data() cdata_asm = configuration_data()
cc = meson.get_compiler('c')
# On windows, we use a compatibility layer to emulate pthread # Include directories
if host_machine.system() != 'windows' dav1d_inc_dirs = include_directories(['.', 'include', 'include/dav1d'])
thread_dependency = dependency('threads')
else
thread_dependency = declare_dependency(sources: ['src/win32/thread.c'])
endif
dav1d_inc_dirs = include_directories(['include', 'include/dav1d'])
# #
# Option handling # Option handling
# #
# Bitdepth option
dav1d_bitdepths = get_option('bitdepths') dav1d_bitdepths = get_option('bitdepths')
foreach bitdepth : dav1d_bitdepths foreach bitdepth : dav1d_bitdepths
cdata.set('CONFIG_@0@BPC'.format(bitdepth), 1) cdata.set('CONFIG_@0@BPC'.format(bitdepth), 1)
endforeach 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)
# libFuzzer target
is_libfuzzer_enabled = (get_option('build_libfuzzer'))
# #
# OS/Compiler feature detection # OS/Compiler checks and defines
# #
feature_defines = [ # Arguments in test_args will be used even on feature tests
['_POSIX_C_SOURCE', '200112L'], # POSIX.1–2001 (IEEE Std 1003.1-2001) 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'
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' if host_machine.system() == 'windows'
feature_defines += [ thread_dependency = []
['_WIN32_WINNT', 0x0601], thread_compat_dep = declare_dependency(sources : files('src/win32/thread.c'))
['UNICODE', 1], # Define to 1 for Unicode (Wide Chars) APIs else
['_UNICODE', 1], # Define to 1 for Unicode (Wide Chars) APIs thread_dependency = dependency('threads')
['__USE_MINGW_ANSI_STDIO', 1], # Define to force use of MinGW printf thread_compat_dep = []
]
endif endif
# Header checks
stdatomic_dependency = []
if not cc.check_header('stdatomic.h') 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',
'-Werror=vla',
'-Wno-maybe-uninitialized',
'-Wno-unused-parameter',
]
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')
# libFuzzer related things
if is_libfuzzer_enabled
if not cc.has_argument('-fsanitize=fuzzer')
error('build_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 endif
# Stack alignments flags
stackalign_flag = [] stackalign_flag = []
stackrealign_flag = [] stackrealign_flag = []
...@@ -100,6 +200,21 @@ if host_machine.cpu_family().startswith('x86') ...@@ -100,6 +200,21 @@ if host_machine.cpu_family().startswith('x86')
endif endif
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') if host_machine.cpu_family().startswith('x86')
cdata.set10('ARCH_X86', true) cdata.set10('ARCH_X86', true)
if host_machine.cpu_family() == 'x86_64' if host_machine.cpu_family() == 'x86_64'
...@@ -122,123 +237,41 @@ else ...@@ -122,123 +237,41 @@ else
endif endif
if cc.symbols_have_underscore_prefix() if cc.symbols_have_underscore_prefix()
cdata.set10('PREFIX', true)
cdata_asm.set10('PREFIX', true) cdata_asm.set10('PREFIX', true)
endif endif
if cc.has_argument('-fvisibility=hidden') # Generate config.h
add_project_arguments('-fvisibility=hidden', language: 'c') config_h_target = configure_file(output: 'config.h', configuration: cdata)
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')
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) # Generate config.asm
if is_asm_enabled
config_asm_target = configure_file(output: 'config.asm', output_format: 'nasm', configuration: cdata_asm) config_asm_target = configure_file(output: 'config.asm', output_format: 'nasm', configuration: cdata_asm)
endif
subdir('include')
# # NASM compiler support
# 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 = find_program('nasm') nasm = find_program('nasm')
# check NASM version
if nasm.found()
nasm_r = run_command(nasm, '-v')
out = nasm_r.stdout().strip().split()
if out[1].to_lower() == 'version'
if out[2].version_compare('<2.13')
error('nasm 2.13 or later is required, found nasm @0@'.format(out[2]))
endif
else
error('unexpected nasm version string: @0@'.format(nasm_r.stdout()))
endif
endif
if host_machine.system() == 'windows' if host_machine.system() == 'windows'
nasm_format = 'win' nasm_format = 'win'
elif host_machine.system() == 'darwin' elif host_machine.system() == 'darwin'
...@@ -257,76 +290,25 @@ if is_asm_enabled ...@@ -257,76 +290,25 @@ if is_asm_enabled
depfile: '@BASENAME@.obj.ndep', depfile: '@BASENAME@.obj.ndep',
arguments: [ arguments: [
'-f', nasm_format, '-f', nasm_format,
'-I', '@CURRENT_SOURCE_DIR@/', '-I', '@SOURCE_DIR@/src/',
'-I', '@0@/'.format(meson.current_build_dir()),
'-MQ', '@OUTPUT@', '-MF', '@DEPFILE@', '-MQ', '@OUTPUT@', '-MF', '@DEPFILE@',
'@EXTRA_ARGS@', '@EXTRA_ARGS@',
'@INPUT@', '@INPUT@',
'-o', '@OUTPUT@' '-o', '@OUTPUT@'
]) ])
nasm_objs = nasm_gen.process(libdav1d_sources_asm)
else
nasm_objs = []
endif 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 # Include subdir meson.build files
# # The order is important!
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'
)
if cc.get_id() == 'msvc'
dav1d_sources += files('tools/compat/getopt.c')
endif
dav1d = executable('dav1d', subdir('include')
dav1d_sources, rev_target,
link_with: libdav1d,
include_directories: [dav1d_inc_dirs, include_directories('tools')],
install: true,
)
# subdir('src')
# pkg-config boilerplate
# subdir('tools')
pkg_mod = import('pkgconfig')
pkg_mod.generate(libraries: libdav1d, subdir('tests')
version: '0.0.1',
name: 'libdav1d',
filebase: 'dav1d',
description: 'AV1 decoding library'
)
...@@ -9,3 +9,18 @@ option('build_asm', ...@@ -9,3 +9,18 @@ option('build_asm',
type: 'boolean', type: 'boolean',
value: true, value: true,
description: 'Build asm files, if available') 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')
option('build_libfuzzer',
type: 'boolean',
value: false,
description: 'Build dav1d libFuzzer target')
/******************************************************************************
* 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 = { ...@@ -387,7 +387,7 @@ static const CdfModeContext av1_default_cdf = {
{ { AOM_CDF2(28015) }, { AOM_CDF2(21546) }, { AOM_CDF2(14400) }, }, { { AOM_CDF2(28015) }, { AOM_CDF2(21546) }, { AOM_CDF2(14400) }, },
{ { AOM_CDF2(28165) }, { AOM_CDF2(22401) }, { AOM_CDF2(16088) }, }, { { AOM_CDF2(28165) }, { AOM_CDF2(22401) }, { AOM_CDF2(16088) }, },
}, .txtp_inter = { }, .txtp_inter = {
{}, { { { 0 } }, {
{ AOM_CDF16(4458, 5560, 7695, 9709, 13330, 14789, 17537, 20266, { AOM_CDF16(4458, 5560, 7695, 9709, 13330, 14789, 17537, 20266,
21504, 22848, 23934, 25474, 27727, 28915, 30631) }, 21504, 22848, 23934, 25474, 27727, 28915, 30631) },
{ AOM_CDF16(1645, 2573, 4778, 5711, 7807, 8622, 10522, 15357, { AOM_CDF16(1645, 2573, 4778, 5711, 7807, 8622, 10522, 15357,
...@@ -412,7 +412,7 @@ static const CdfModeContext av1_default_cdf = { ...@@ -412,7 +412,7 @@ static const CdfModeContext av1_default_cdf = {
{ AOM_CDF2(748) }, { AOM_CDF2(748) },
}, },
}, .txtp_intra = { }, .txtp_intra = {
{}, { { { { 0 } } }, {
{ {
{ AOM_CDF7(1535, 8035, 9461, 12751, 23467, 27825) }, { AOM_CDF7(1535, 8035, 9461, 12751, 23467, 27825) },
{ AOM_CDF7(564, 3335, 9709, 10870, 18143, 28094) }, { AOM_CDF7(564, 3335, 9709, 10870, 18143, 28094) },
...@@ -4055,26 +4055,26 @@ static CdfThreadContext cdf_init[4] = { ...@@ -4055,26 +4055,26 @@ static CdfThreadContext cdf_init[4] = {
[3] = { .cdf = NULL }, [3] = { .cdf = NULL },
}; };
void av1_init_states(CdfThreadContext *const cdf, const int qidx) { void dav1d_init_states(CdfThreadContext *const cdf, const int qidx) {
const int qcat = get_qcat_idx(qidx); const int qcat = get_qcat_idx(qidx);
if (cdf_init[qcat].cdf) { if (cdf_init[qcat].cdf) {
cdf_thread_ref(cdf, &cdf_init[qcat]); dav1d_cdf_thread_ref(cdf, &cdf_init[qcat]);
return; return;
} }
cdf_thread_alloc(&cdf_init[qcat], NULL); dav1d_cdf_thread_alloc(&cdf_init[qcat], NULL);
cdf_init[qcat].cdf->m = av1_default_cdf; cdf_init[qcat].cdf->m = av1_default_cdf;
memcpy(cdf_init[qcat].cdf->kfym, default_kf_y_mode_cdf, memcpy(cdf_init[qcat].cdf->kfym, default_kf_y_mode_cdf,
sizeof(default_kf_y_mode_cdf)); sizeof(default_kf_y_mode_cdf));
cdf_init[qcat].cdf->coef = av1_default_coef_cdf[qcat]; cdf_init[qcat].cdf->coef = av1_default_coef_cdf[qcat];
cdf_init[qcat].cdf->mv = default_mv_cdf; cdf_init[qcat].cdf->mv = default_mv_cdf;
cdf_init[qcat].cdf->dmv = default_mv_cdf; cdf_init[qcat].cdf->dmv = default_mv_cdf;
cdf_thread_ref(cdf, &cdf_init[qcat]); dav1d_cdf_thread_ref(cdf, &cdf_init[qcat]);
} }
void av1_update_tile_cdf(const Av1FrameHeader *const hdr, void dav1d_update_tile_cdf(const Av1FrameHeader *const hdr,
CdfContext *const dst, CdfContext *const dst,
const CdfContext *const src) const CdfContext *const src)
{ {
int i, j, k, l; int i, j, k, l;
...@@ -4210,7 +4210,9 @@ void av1_update_tile_cdf(const Av1FrameHeader *const hdr, ...@@ -4210,7 +4210,9 @@ void av1_update_tile_cdf(const Av1FrameHeader *const hdr,
/* /*
* CDF threading wrappers. * CDF threading wrappers.
*/ */
void cdf_thread_alloc(CdfThreadContext *const cdf, struct thread_data *const t) { void dav1d_cdf_thread_alloc(CdfThreadContext *const cdf,
struct thread_data *const t)
{
cdf->ref = dav1d_ref_create(sizeof(CdfContext) + cdf->ref = dav1d_ref_create(sizeof(CdfContext) +
(t != NULL) * sizeof(atomic_uint)); (t != NULL) * sizeof(atomic_uint));
cdf->cdf = cdf->ref->data; cdf->cdf = cdf->ref->data;
...@@ -4221,17 +4223,19 @@ void cdf_thread_alloc(CdfThreadContext *const cdf, struct thread_data *const t) ...@@ -4221,17 +4223,19 @@ void cdf_thread_alloc(CdfThreadContext *const cdf, struct thread_data *const t)
} }
} }
void cdf_thread_ref(CdfThreadContext *const dst, CdfThreadContext *const src) { void dav1d_cdf_thread_ref(CdfThreadContext *const dst,
CdfThreadContext *const src)
{
dav1d_ref_inc(src->ref); dav1d_ref_inc(src->ref);
*dst = *src; *dst = *src;
} }
void cdf_thread_unref(CdfThreadContext *const cdf) { void dav1d_cdf_thread_unref(CdfThreadContext *const cdf) {
dav1d_ref_dec(cdf->ref); dav1d_ref_dec(cdf->ref);
memset(cdf, 0, sizeof(*cdf)); memset(cdf, 0, sizeof(*cdf));
} }
void cdf_thread_wait(CdfThreadContext *const cdf) { void dav1d_cdf_thread_wait(CdfThreadContext *const cdf) {
if (!cdf->t) return; if (!cdf->t) return;
if (atomic_load(cdf->progress)) return; if (atomic_load(cdf->progress)) return;
...@@ -4241,7 +4245,7 @@ void cdf_thread_wait(CdfThreadContext *const cdf) { ...@@ -4241,7 +4245,7 @@ void cdf_thread_wait(CdfThreadContext *const cdf) {
pthread_mutex_unlock(&cdf->t->lock); pthread_mutex_unlock(&cdf->t->lock);
} }
void cdf_thread_signal(CdfThreadContext *const cdf) { void dav1d_cdf_thread_signal(CdfThreadContext *const cdf) {
if (!cdf->t) return; if (!cdf->t) return;
pthread_mutex_lock(&cdf->t->lock); pthread_mutex_lock(&cdf->t->lock);
......
...@@ -131,18 +131,18 @@ typedef struct CdfThreadContext { ...@@ -131,18 +131,18 @@ typedef struct CdfThreadContext {
atomic_uint *progress; atomic_uint *progress;
} CdfThreadContext; } CdfThreadContext;
void av1_init_states(CdfThreadContext *cdf, int qidx); void dav1d_init_states(CdfThreadContext *cdf, int qidx);
void av1_update_tile_cdf(const Av1FrameHeader *hdr, CdfContext *dst, void dav1d_update_tile_cdf(const Av1FrameHeader *hdr, CdfContext *dst,
const CdfContext *src); const CdfContext *src);
void cdf_thread_alloc(CdfThreadContext *cdf, struct thread_data *t); void dav1d_cdf_thread_alloc(CdfThreadContext *cdf, struct thread_data *t);
void cdf_thread_ref(CdfThreadContext *dst, CdfThreadContext *src); void dav1d_cdf_thread_ref(CdfThreadContext *dst, CdfThreadContext *src);
void cdf_thread_unref(CdfThreadContext *cdf); void dav1d_cdf_thread_unref(CdfThreadContext *cdf);
/* /*
* These are binary signals (so a signal is either "done" or "not done"). * These are binary signals (so a signal is either "done" or "not done").
*/ */
void cdf_thread_wait(CdfThreadContext *cdf); void dav1d_cdf_thread_wait(CdfThreadContext *cdf);
void cdf_thread_signal(CdfThreadContext *cdf); void dav1d_cdf_thread_signal(CdfThreadContext *cdf);
#endif /* __AV1_CDF_H__ */ #endif /* __AV1_CDF_H__ */
/*
* 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) { ...@@ -48,7 +48,28 @@ int dav1d_data_create(Dav1dData *const buf, const size_t sz) {
return 0; 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, free_callback, user_data, 0, NULL);
if (!buf->ref) return -ENOMEM;
buf->data = ptr;
buf->sz = sz;
return 0;
}
void dav1d_data_unref(Dav1dData *const buf) { 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)); 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
...@@ -134,7 +134,7 @@ static void read_tx_tree(Dav1dTileContext *const t, ...@@ -134,7 +134,7 @@ static void read_tx_tree(Dav1dTileContext *const t,
{ {
const Dav1dFrameContext *const f = t->f; const Dav1dFrameContext *const f = t->f;
const int bx4 = t->bx & 31, by4 = t->by & 31; const int bx4 = t->bx & 31, by4 = t->by & 31;
const TxfmInfo *const t_dim = &av1_txfm_dimensions[from]; const TxfmInfo *const t_dim = &dav1d_txfm_dimensions[from];
const int txw = t_dim->lw, txh = t_dim->lh; const int txw = t_dim->lw, txh = t_dim->lh;
int is_split; int is_split;
...@@ -152,7 +152,7 @@ static void read_tx_tree(Dav1dTileContext *const t, ...@@ -152,7 +152,7 @@ static void read_tx_tree(Dav1dTileContext *const t,
if (is_split && t_dim->max > TX_8X8) { if (is_split && t_dim->max > TX_8X8) {
const enum RectTxfmSize sub = t_dim->sub; const enum RectTxfmSize sub = t_dim->sub;
const TxfmInfo *const sub_t_dim = &av1_txfm_dimensions[sub]; const TxfmInfo *const sub_t_dim = &dav1d_txfm_dimensions[sub];
const int txsw = sub_t_dim->w, txsh = sub_t_dim->h; const int txsw = sub_t_dim->w, txsh = sub_t_dim->h;
read_tx_tree(t, sub, depth + 1, masks, x_off * 2 + 0, y_off * 2 + 0); read_tx_tree(t, sub, depth + 1, masks, x_off * 2 + 0, y_off * 2 + 0);
...@@ -176,7 +176,7 @@ static void read_tx_tree(Dav1dTileContext *const t, ...@@ -176,7 +176,7 @@ static void read_tx_tree(Dav1dTileContext *const t,
} }
} }
int av1_neg_deinterleave(int diff, int ref, int max) { static int neg_deinterleave(int diff, int ref, int max) {
if (!ref) return diff; if (!ref) return diff;
if (ref >= (max - 1)) return max - diff - 1; if (ref >= (max - 1)) return max - diff - 1;
if (2 * ref < max) { if (2 * ref < max) {
...@@ -214,7 +214,7 @@ static void find_matching_ref(const Dav1dTileContext *const t, ...@@ -214,7 +214,7 @@ static void find_matching_ref(const Dav1dTileContext *const t,
have_top && t->bx + bw4 < t->ts->tiling.col_end && have_top && t->bx + bw4 < t->ts->tiling.col_end &&
(intra_edge_flags & EDGE_I444_TOP_HAS_RIGHT); (intra_edge_flags & EDGE_I444_TOP_HAS_RIGHT);
#define bs(rp) av1_block_dimensions[sbtype_to_bs[(rp)->sb_type]] #define bs(rp) dav1d_block_dimensions[sbtype_to_bs[(rp)->sb_type]]
#define matches(rp) ((rp)->ref[0] == ref + 1 && (rp)->ref[1] == -1) #define matches(rp) ((rp)->ref[0] == ref + 1 && (rp)->ref[1] == -1)
if (have_top) { if (have_top) {
...@@ -342,8 +342,8 @@ static void derive_warpmv(const Dav1dTileContext *const t, ...@@ -342,8 +342,8 @@ static void derive_warpmv(const Dav1dTileContext *const t,
memcpy(pts[i], pts[j], sizeof(*pts)); memcpy(pts[i], pts[j], sizeof(*pts));
} }
if (!find_affine_int(pts, ret, bw4, bh4, mv, wmp, t->bx, t->by) && if (!dav1d_find_affine_int(pts, ret, bw4, bh4, mv, wmp, t->bx, t->by) &&
!get_shear_params(wmp)) !dav1d_get_shear_params(wmp))
{ {
wmp->type = WM_TYPE_AFFINE; wmp->type = WM_TYPE_AFFINE;
} else } else
...@@ -449,20 +449,20 @@ static void read_pal_plane(Dav1dTileContext *const t, Av1Block *const b, ...@@ -449,20 +449,20 @@ static void read_pal_plane(Dav1dTileContext *const t, Av1Block *const b,
if (DEBUG_BLOCK_INFO) { if (DEBUG_BLOCK_INFO) {
printf("Post-pal[pl=%d,sz=%d,cache_size=%d,used_cache=%d]: r=%d, cache=", 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);