diff --git a/CHANGELOG.md b/CHANGELOG.md index 38070351..d5769df1 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,6 +9,25 @@ ### Added +- **compat.libvpx 1.17.0(新包)。** libvpx:WebM 项目的 VP9 视频编解码器(编码器与解码器;BSD-3-Clause,附 WebM 项目的 + 免版税专利授权 PATENTS)。从 `v1.17.0` 标签归档构建上游 `configure --target=generic-gnu --disable-vp8 --enable-vp9 + --enable-multithread`(不含示例、工具、文档、单元测试、webm-io、libyuv)所编译的 101 个 C 源文件:通用 C 实现,无 SIMD、 + 无汇编、无运行时 CPU 检测,同一配置在 x86-64 与 aarch64、Linux、macOS、Windows 与 `wasm32-emscripten` 上不变地构建。 + 该配置生成的 `vpx_config.h`、`vpx_config.c`、`vpx_version.h` 与三个 RTCD 头(`vp9_rtcd.h`、`vpx_dsp_rtcd.h`、 + `vpx_scale_rtcd.h`)作为 `generated_files` 原样提供(私有头目录),只有描述宿主操作系统的三行改由预处理器决定: + Windows 以外有 `pthread.h`、`unistd.h`(Windows 上 `vpx_util/vpx_pthread.h` 用 Win32 实现工作线程),glibc 与 Apple + 上有 `pthread_setname_np`;不带 pthreads 的 Emscripten 上 `CONFIG_MULTITHREAD` 为 0(单线程工作器依次执行各块)。 + `-ffp-contract=off`。使用者 `#include `、`` 等(上游安装布局)。url 为上游标签归档 + (暂无 CN 镜像);声明 `extensions.autoupdate`。新增测试成员 `tests/examples/libvpx`:版本与构建配置字符串、 + 一遍编码(好质量、恒定质量)解码回来的 PSNR、实时速度 8、无损逐像素还原、单线程两次编码字节相同、四线程分块编码 + 两线程解码。 +- **compat.libwebm 1.0.0.32(新包)。** libwebm:WebM 项目的 WebM(Matroska)容器库,复用器 mkvmuxer 与解析器 mkvparser + (BSD-3-Clause)。从 `libwebm-1.0.0.32` 标签归档构建上游 CMakeLists.txt 的 `webm` 目标:`common/file_util.cc`、 + `common/hdr_util.cc` 与 mkvmuxer、mkvparser 的源文件(不含默认关闭的新解析器 `webm_parser/`、MPEG-TS 工具、WebVTT + 与示例程序);无配置头、无生成文件。使用者 `#include `、`` 等。新增测试 + 成员 `tests/examples/libwebm`:写一个 VP9 与 Opus 两条轨道的 WebM(BT.709 有限范围的色彩、OpusHead、编码延迟、 + 关键帧、cues、时长)到内存与磁盘(逐字节相同),用 mkvparser 从内存与 MkvReader 读回每一帧的字节与时间;给定轨道 + UID 时两次复用字节相同(不给时 mkvmuxer 按当前时间随机生成)。 - **mcpplibs.mwrap.libwebp 1.5.0(新包)。** libwebp-m:以 C++23 模块(`import mcpplibs.mwrap.libwebp;`)使用 compat.libwebp 1.5.0(BSD-3-Clause 与 Google 专利授权)。从固定版本的公开头文件生成,以 `export using` 导出:根模块 `webp/types.h`、`decode.h`、`encode.h`、`mux_types.h` 的 23 个类型、59 个枚举值与 72 个函数,`mcpplibs.mwrap.libwebp.sharpyuv` diff --git a/mcpp.toml b/mcpp.toml index 2f35e8fc..69835f5d 100644 --- a/mcpp.toml +++ b/mcpp.toml @@ -184,6 +184,8 @@ members = [ "tests/examples/pangocairo", "tests/examples/libgbm", "tests/examples/libpng", + "tests/examples/libvpx", + "tests/examples/libwebm", "tests/examples/libwebp", "tests/examples/llamacpp", "tests/examples/llamacpp-metal", diff --git a/pkgs/c/compat.libvpx.lua b/pkgs/c/compat.libvpx.lua new file mode 100644 index 00000000..68a24c88 --- /dev/null +++ b/pkgs/c/compat.libvpx.lua @@ -0,0 +1,1349 @@ +-- compat.libvpx — libvpx 1.17.0, the WebM project's VP9 video codec (encoder +-- and decoder), BSD-3-Clause with the WebM project's royalty-free patent +-- grant (PATENTS). +-- +-- VP9 is the royalty-free video codec of WebM: what browsers decode +-- everywhere, YouTube streams and the WebM container (compat.libwebm) carries. +-- This package is the reference encoder and decoder: one-pass and two-pass +-- encoding at every speed (good quality and real time), constant quality, +-- bit rate targets, lossless, spatial and temporal layers, and the decoder +-- with frame-parallel and row-multithreaded decoding. +-- +-- ───────────────────────────────────────────────────────────────────────── +-- THE TAG ARCHIVE AND UPSTREAM'S OWN CONFIGURE, ONCE +-- +-- libvpx publishes no release tarball: the archive is the v1.17.0 tag's +-- (GitHub mirror of chromium.googlesource.com/webm/libvpx). Its build is a +-- hand-written configure script and makefiles that generate a config header +-- and three run-time CPU dispatch ("RTCD") headers with perl. They were +-- generated once, by upstream's own +-- +-- configure --target=generic-gnu --disable-vp8 --enable-vp9 +-- --disable-examples --disable-tools --disable-docs +-- --disable-unit-tests --disable-webm-io --disable-libyuv +-- --enable-static --disable-shared --enable-multithread +-- +-- and are carried here as generated_files, unchanged but for the three lines +-- of vpx_config.h that describe the host operating system (pthread.h and +-- unistd.h everywhere but Windows, where vpx_util/vpx_pthread.h maps the +-- worker threads onto Win32; pthread_setname_np where glibc or Apple has it, +-- which vpx_thread.c tests with #ifdef), now decided by the preprocessor. +-- The source list is exactly the 101 C files that configuration's +-- makefiles compile (plus its vpx_config.c, generated: the build-config +-- string vpx_codec_build_config() answers). +-- +-- ───────────────────────────────────────────────────────────────────────── +-- GENERIC C: NO SIMD, NO ASSEMBLER, NO CPU DETECTION +-- +-- The generic target is libvpx's portable reference build: every DSP +-- function is its C version (the RTCD headers #define each name to its _c +-- function), so one configuration builds unchanged on x86-64 and aarch64, +-- on Linux, macOS, Windows and Emscripten. libvpx's x86 speed comes from +-- yasm/nasm assembly and per-file intrinsics flags (-mssse3, -mavx2 …) +-- behind run-time dispatch, which a descriptor cannot select per file and +-- per architecture; those are a later revision. The C paths are the ones +-- upstream's own tests check every SIMD version against. +-- +-- Multithreading is ON (configure's default): an encoder or decoder asked for +-- one thread (the default, g_threads = 0 or 1) creates none, so a +-- single-threaded encode is reproducible; more threads tile the work. On +-- Emscripten without its pthreads (no -pthread) CONFIG_MULTITHREAD is 0: +-- libvpx's single-threaded worker then runs each tile's job in turn, so a +-- request for threads still encodes, on one. +-- +-- ───────────────────────────────────────────────────────────────────────── +-- HEADERS +-- +-- Consumers include , , +-- and (upstream's installed layout) from the +-- archive root. The generated headers are a private include directory of +-- each platform block (the shape compat.opus uses): the library's own +-- sources reach "./vpx_config.h" and "./vpx_dsp_rtcd.h" there, consumers do +-- not need them. +-- +-- kind = "lib": a static library. +package = { + spec = "1", + namespace = "compat", + name = "libvpx", + description = "libvpx 1.17.0 — the VP9 video codec (encoder and decoder), portable C, BSD-3-Clause with a royalty-free patent grant", + licenses = {"BSD-3-Clause"}, + repo = "https://github.com/webmproject/libvpx", + type = "package", + + extensions = { + autoupdate = { + tag = "v${version}", + url = "https://github.com/webmproject/libvpx/archive/refs/tags/${tag}.tar.gz", + }, + }, + + xpm = { + linux = { + ["1.17.0"] = { + url = "https://github.com/webmproject/libvpx/archive/refs/tags/v1.17.0.tar.gz", + sha256 = "1020f184046187baa2985dbde38e0691f49c44088bca7a1842b0236c6081dc0a", + }, + }, + macosx = { + ["1.17.0"] = { + url = "https://github.com/webmproject/libvpx/archive/refs/tags/v1.17.0.tar.gz", + sha256 = "1020f184046187baa2985dbde38e0691f49c44088bca7a1842b0236c6081dc0a", + }, + }, + windows = { + ["1.17.0"] = { + url = "https://github.com/webmproject/libvpx/archive/refs/tags/v1.17.0.tar.gz", + sha256 = "1020f184046187baa2985dbde38e0691f49c44088bca7a1842b0236c6081dc0a", + }, + }, + }, + + mcpp = { + language = "c++23", + import_std = false, + c_standard = "c11", + + -- : the public headers, at the archive root as installed. + include_dirs = { "*" }, + + sources = { + "*/vp9/common/vp9_alloccommon.c", + "*/vp9/common/vp9_blockd.c", + "*/vp9/common/vp9_common_data.c", + "*/vp9/common/vp9_entropy.c", + "*/vp9/common/vp9_entropymode.c", + "*/vp9/common/vp9_entropymv.c", + "*/vp9/common/vp9_filter.c", + "*/vp9/common/vp9_frame_buffers.c", + "*/vp9/common/vp9_idct.c", + "*/vp9/common/vp9_loopfilter.c", + "*/vp9/common/vp9_mvref_common.c", + "*/vp9/common/vp9_pred_common.c", + "*/vp9/common/vp9_quant_common.c", + "*/vp9/common/vp9_reconinter.c", + "*/vp9/common/vp9_reconintra.c", + "*/vp9/common/vp9_rtcd.c", + "*/vp9/common/vp9_scale.c", + "*/vp9/common/vp9_scan.c", + "*/vp9/common/vp9_seg_common.c", + "*/vp9/common/vp9_thread_common.c", + "*/vp9/common/vp9_tile_common.c", + "*/vp9/decoder/vp9_decodeframe.c", + "*/vp9/decoder/vp9_decodemv.c", + "*/vp9/decoder/vp9_decoder.c", + "*/vp9/decoder/vp9_detokenize.c", + "*/vp9/decoder/vp9_dsubexp.c", + "*/vp9/decoder/vp9_job_queue.c", + "*/vp9/encoder/vp9_alt_ref_aq.c", + "*/vp9/encoder/vp9_aq_360.c", + "*/vp9/encoder/vp9_aq_complexity.c", + "*/vp9/encoder/vp9_aq_cyclicrefresh.c", + "*/vp9/encoder/vp9_aq_variance.c", + "*/vp9/encoder/vp9_bitstream.c", + "*/vp9/encoder/vp9_context_tree.c", + "*/vp9/encoder/vp9_cost.c", + "*/vp9/encoder/vp9_dct.c", + "*/vp9/encoder/vp9_encodeframe.c", + "*/vp9/encoder/vp9_encodemb.c", + "*/vp9/encoder/vp9_encodemv.c", + "*/vp9/encoder/vp9_encoder.c", + "*/vp9/encoder/vp9_ethread.c", + "*/vp9/encoder/vp9_extend.c", + "*/vp9/encoder/vp9_ext_ratectrl.c", + "*/vp9/encoder/vp9_firstpass.c", + "*/vp9/encoder/vp9_frame_scale.c", + "*/vp9/encoder/vp9_lookahead.c", + "*/vp9/encoder/vp9_mbgraph.c", + "*/vp9/encoder/vp9_mcomp.c", + "*/vp9/encoder/vp9_multi_thread.c", + "*/vp9/encoder/vp9_noise_estimate.c", + "*/vp9/encoder/vp9_picklpf.c", + "*/vp9/encoder/vp9_pickmode.c", + "*/vp9/encoder/vp9_quantize.c", + "*/vp9/encoder/vp9_ratectrl.c", + "*/vp9/encoder/vp9_rd.c", + "*/vp9/encoder/vp9_rdopt.c", + "*/vp9/encoder/vp9_resize.c", + "*/vp9/encoder/vp9_segmentation.c", + "*/vp9/encoder/vp9_skin_detection.c", + "*/vp9/encoder/vp9_speed_features.c", + "*/vp9/encoder/vp9_subexp.c", + "*/vp9/encoder/vp9_svc_layercontext.c", + "*/vp9/encoder/vp9_temporal_filter.c", + "*/vp9/encoder/vp9_tokenize.c", + "*/vp9/encoder/vp9_tpl_model.c", + "*/vp9/encoder/vp9_treewriter.c", + "*/vp9/vp9_cx_iface.c", + "*/vp9/vp9_dx_iface.c", + "*/vp9/vp9_iface_common.c", + "*/vpx_dsp/avg.c", + "*/vpx_dsp/bitreader_buffer.c", + "*/vpx_dsp/bitreader.c", + "*/vpx_dsp/bitwriter_buffer.c", + "*/vpx_dsp/bitwriter.c", + "*/vpx_dsp/fwd_txfm.c", + "*/vpx_dsp/intrapred.c", + "*/vpx_dsp/inv_txfm.c", + "*/vpx_dsp/loopfilter.c", + "*/vpx_dsp/prob.c", + "*/vpx_dsp/psnr.c", + "*/vpx_dsp/quantize.c", + "*/vpx_dsp/sad.c", + "*/vpx_dsp/skin_detection.c", + "*/vpx_dsp/sse.c", + "*/vpx_dsp/subtract.c", + "*/vpx_dsp/sum_squares.c", + "*/vpx_dsp/variance.c", + "*/vpx_dsp/vpx_convolve.c", + "*/vpx_dsp/vpx_dsp_rtcd.c", + "*/vpx_mem/vpx_mem.c", + "*/vpx_scale/generic/gen_scalers.c", + "*/vpx_scale/generic/vpx_scale.c", + "*/vpx_scale/generic/yv12config.c", + "*/vpx_scale/generic/yv12extend.c", + "*/vpx_scale/vpx_scale_rtcd.c", + "*/vpx/src/vpx_codec.c", + "*/vpx/src/vpx_decoder.c", + "*/vpx/src/vpx_encoder.c", + "*/vpx/src/vpx_image.c", + "*/vpx_util/vpx_thread.c", + "*/vpx_util/vpx_write_yuv_frame.c", + "mcpp_generated/vpx_config.c", + }, + + generated_files = { + ["mcpp_generated/vpx_config.h"] = [==[ +/* Copyright (c) 2011 The WebM project authors. All Rights Reserved. */ +/* */ +/* Use of this source code is governed by a BSD-style license */ +/* that can be found in the LICENSE file in the root of the source */ +/* tree. An additional intellectual property rights grant can be found */ +/* in the file PATENTS. All contributing project authors may */ +/* be found in the AUTHORS file in the root of the source tree. */ +/* This file automatically generated by configure. Do not edit! */ +/* compat.libvpx: configure --target=generic-gnu --disable-vp8 --enable-vp9 + --enable-multithread (no SIMD, no assembler, no run-time CPU detection); + what depends on the operating system is decided below, where configure + would have probed the host. */ +#ifndef VPX_CONFIG_H +#define VPX_CONFIG_H +#define RESTRICT +#define INLINE inline +#define VPX_ARCH_ARM 0 +#define VPX_ARCH_AARCH64 0 +#define VPX_ARCH_MIPS 0 +#define VPX_ARCH_X86 0 +#define VPX_ARCH_X86_64 0 +#define VPX_ARCH_PPC 0 +#define VPX_ARCH_LOONGARCH 0 +#define HAVE_NEON_ASM 0 +#define HAVE_NEON 0 +#define HAVE_NEON_DOTPROD 0 +#define HAVE_NEON_I8MM 0 +#define HAVE_SVE 0 +#define HAVE_SVE2 0 +#define HAVE_MIPS32 0 +#define HAVE_DSPR2 0 +#define HAVE_MSA 0 +#define HAVE_MIPS64 0 +#define HAVE_X86_ASM 0 +#define HAVE_MMX 0 +#define HAVE_SSE 0 +#define HAVE_SSE2 0 +#define HAVE_SSE3 0 +#define HAVE_SSSE3 0 +#define HAVE_SSE4_1 0 +#define HAVE_AVX 0 +#define HAVE_AVX2 0 +#define HAVE_AVX512 0 +#define HAVE_VSX 0 +#define HAVE_MMI 0 +#define HAVE_LSX 0 +#define HAVE_LASX 0 +#define HAVE_VPX_PORTS 1 +#if defined(_WIN32) +/* Windows: vpx_util/vpx_pthread.h maps the worker threads onto Win32. */ +#define HAVE_PTHREAD_H 0 +#define HAVE_UNISTD_H 0 +#else +#define HAVE_PTHREAD_H 1 +#define HAVE_UNISTD_H 1 +#endif +/* Only where it is: vpx_util/vpx_thread.c tests it with #ifdef. */ +#if defined(__APPLE__) || (defined(__GLIBC__) && !defined(__GNU__)) +#define HAVE_PTHREAD_SETNAME_NP 1 +#endif +#define CONFIG_DEPENDENCY_TRACKING 1 +#define CONFIG_EXTERNAL_BUILD 0 +#define CONFIG_INSTALL_DOCS 1 +#define CONFIG_INSTALL_BINS 1 +#define CONFIG_INSTALL_LIBS 1 +#define CONFIG_INSTALL_SRCS 0 +#define CONFIG_DEBUG 0 +#define CONFIG_GPROF 0 +#define CONFIG_GCOV 0 +#define CONFIG_RVCT 0 +#define CONFIG_GCC 1 +#define CONFIG_MSVS 0 +#define CONFIG_PIC 1 +#define CONFIG_BIG_ENDIAN 0 +#define CONFIG_CODEC_SRCS 0 +#define CONFIG_DEBUG_LIBS 0 +#define CONFIG_DEQUANT_TOKENS 0 +#define CONFIG_DC_RECON 0 +#define CONFIG_RUNTIME_CPU_DETECT 0 +#define CONFIG_POSTPROC 0 +#define CONFIG_VP9_POSTPROC 0 +#if defined(__EMSCRIPTEN__) && !defined(__EMSCRIPTEN_PTHREADS__) +#define CONFIG_MULTITHREAD 0 +#else +#define CONFIG_MULTITHREAD 1 +#endif +#define CONFIG_INTERNAL_STATS 0 +#define CONFIG_VP8_ENCODER 0 +#define CONFIG_VP8_DECODER 0 +#define CONFIG_VP9_ENCODER 1 +#define CONFIG_VP9_DECODER 1 +#define CONFIG_VP8 0 +#define CONFIG_VP9 1 +#define CONFIG_ENCODERS 1 +#define CONFIG_DECODERS 1 +#define CONFIG_STATIC_MSVCRT 0 +#define CONFIG_SPATIAL_RESAMPLING 1 +#define CONFIG_REALTIME_ONLY 0 +#define CONFIG_ONTHEFLY_BITPACKING 0 +#define CONFIG_ERROR_CONCEALMENT 0 +#define CONFIG_SHARED 0 +#define CONFIG_STATIC 1 +#define CONFIG_SMALL 0 +#define CONFIG_POSTPROC_VISUALIZER 0 +#define CONFIG_OS_SUPPORT 1 +#define CONFIG_UNIT_TESTS 0 +#define CONFIG_WEBM_IO 0 +#define CONFIG_LIBYUV 0 +#define CONFIG_DECODE_PERF_TESTS 0 +#define CONFIG_ENCODE_PERF_TESTS 0 +#define CONFIG_MULTI_RES_ENCODING 0 +#define CONFIG_TEMPORAL_DENOISING 1 +#define CONFIG_VP9_TEMPORAL_DENOISING 0 +#define CONFIG_COEFFICIENT_RANGE_CHECKING 0 +#define CONFIG_VP9_HIGHBITDEPTH 0 +#define CONFIG_BETTER_HW_COMPATIBILITY 0 +#define CONFIG_EXPERIMENTAL 0 +#define CONFIG_SIZE_LIMIT 0 +#define CONFIG_ALWAYS_ADJUST_BPM 0 +#define CONFIG_BITSTREAM_DEBUG 0 +#define CONFIG_MISMATCH_DEBUG 0 +#define CONFIG_FP_MB_STATS 0 +#define CONFIG_EMULATE_HARDWARE 0 +#define CONFIG_NON_GREEDY_MV 0 +#define CONFIG_COLLECT_COMPONENT_TIMING 0 +#endif /* VPX_CONFIG_H */ +]==], + ["mcpp_generated/vpx_config.c"] = [==[ +/* Copyright (c) 2011 The WebM project authors. All Rights Reserved. */ +/* */ +/* Use of this source code is governed by a BSD-style license */ +/* that can be found in the LICENSE file in the root of the source */ +/* tree. An additional intellectual property rights grant can be found */ +/* in the file PATENTS. All contributing project authors may */ +/* be found in the AUTHORS file in the root of the source tree. */ +#include "vpx/vpx_codec.h" +static const char* const cfg = "--target=generic-gnu --disable-vp8 --enable-vp9 --disable-examples --disable-tools --disable-docs --disable-unit-tests --disable-webm-io --disable-libyuv --enable-static --disable-shared --enable-multithread"; +const char *vpx_codec_build_config(void) {return cfg;} +]==], + ["mcpp_generated/vpx_version.h"] = [==[ +// This file is generated. Do not edit. +#ifndef VPX_VERSION_H_ +#define VPX_VERSION_H_ +#define VERSION_MAJOR 1 +#define VERSION_MINOR 17 +#define VERSION_PATCH 0 +#define VERSION_EXTRA "" +#define VERSION_PACKED ((VERSION_MAJOR<<16)|(VERSION_MINOR<<8)|(VERSION_PATCH)) +#define VERSION_STRING_NOSP "v1.17.0" +#define VERSION_STRING " v1.17.0" +#endif // VPX_VERSION_H_ +]==], + ["mcpp_generated/vp9_rtcd.h"] = [==[ +/* + * Copyright (c) 2017 The WebM project authors. All Rights Reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. An additional intellectual property rights grant can be found + * in the file PATENTS. All contributing project authors may + * be found in the AUTHORS file in the root of the source tree. + */ + +// This file is generated. Do not edit. +#ifndef VP9_RTCD_H_ +#define VP9_RTCD_H_ + +#ifdef RTCD_C +#define RTCD_EXTERN +#else +#define RTCD_EXTERN extern +#endif + +/* + * VP9 + */ + +#include "vpx/vpx_integer.h" +#include "vp9/common/vp9_common.h" +#include "vp9/common/vp9_enums.h" +#include "vp9/common/vp9_filter.h" +#if !CONFIG_REALTIME_ONLY && CONFIG_VP9_ENCODER +#include "vp9/encoder/vp9_temporal_filter.h" +#endif + +struct macroblockd; + +/* Encoder forward decls */ +struct macroblock; +struct macroblock_plane; +struct vp9_sad_table; +struct ScanOrder; +struct search_site_config; +struct mv; +union int_mv; +struct yv12_buffer_config; + +#ifdef __cplusplus +extern "C" { +#endif + +void vp9_apply_temporal_filter_c(const uint8_t *y_src, int y_src_stride, const uint8_t *y_pre, int y_pre_stride, const uint8_t *u_src, const uint8_t *v_src, int uv_src_stride, const uint8_t *u_pre, const uint8_t *v_pre, int uv_pre_stride, unsigned int block_width, unsigned int block_height, int ss_x, int ss_y, int strength, const int *const blk_fw, int use_32x32, uint32_t *y_accumulator, uint16_t *y_count, uint32_t *u_accumulator, uint16_t *u_count, uint32_t *v_accumulator, uint16_t *v_count); +#define vp9_apply_temporal_filter vp9_apply_temporal_filter_c + +int64_t vp9_block_error_c(const tran_low_t *coeff, const tran_low_t *dqcoeff, intptr_t block_size, int64_t *ssz); +#define vp9_block_error vp9_block_error_c + +int64_t vp9_block_error_fp_c(const tran_low_t *coeff, const tran_low_t *dqcoeff, int block_size); +#define vp9_block_error_fp vp9_block_error_fp_c + +int vp9_diamond_search_sad_c(const struct macroblock *x, const struct search_site_config *cfg, struct mv *ref_mv, uint32_t start_mv_sad, struct mv *best_mv, int search_param, int sad_per_bit, int *num00, const struct vp9_sad_table *sad_fn_ptr, const struct mv *center_mv); +#define vp9_diamond_search_sad vp9_diamond_search_sad_c + +void vp9_fht16x16_c(const int16_t *input, tran_low_t *output, int stride, int tx_type); +#define vp9_fht16x16 vp9_fht16x16_c + +void vp9_fht4x4_c(const int16_t *input, tran_low_t *output, int stride, int tx_type); +#define vp9_fht4x4 vp9_fht4x4_c + +void vp9_fht8x8_c(const int16_t *input, tran_low_t *output, int stride, int tx_type); +#define vp9_fht8x8 vp9_fht8x8_c + +void vp9_fwht4x4_c(const int16_t *input, tran_low_t *output, int stride); +#define vp9_fwht4x4 vp9_fwht4x4_c + +void vp9_iht16x16_256_add_c(const tran_low_t *input, uint8_t *dest, int stride, int tx_type); +#define vp9_iht16x16_256_add vp9_iht16x16_256_add_c + +void vp9_iht4x4_16_add_c(const tran_low_t *input, uint8_t *dest, int stride, int tx_type); +#define vp9_iht4x4_16_add vp9_iht4x4_16_add_c + +void vp9_iht8x8_64_add_c(const tran_low_t *input, uint8_t *dest, int stride, int tx_type); +#define vp9_iht8x8_64_add vp9_iht8x8_64_add_c + +void vp9_quantize_fp_c(const tran_low_t *coeff_ptr, intptr_t n_coeffs, const struct macroblock_plane *const mb_plane, tran_low_t *qcoeff_ptr, tran_low_t *dqcoeff_ptr, const int16_t *dequant_ptr, uint16_t *eob_ptr, const struct ScanOrder *const scan_order); +#define vp9_quantize_fp vp9_quantize_fp_c + +void vp9_quantize_fp_32x32_c(const tran_low_t *coeff_ptr, intptr_t n_coeffs, const struct macroblock_plane *const mb_plane, tran_low_t *qcoeff_ptr, tran_low_t *dqcoeff_ptr, const int16_t *dequant_ptr, uint16_t *eob_ptr, const struct ScanOrder *const scan_order); +#define vp9_quantize_fp_32x32 vp9_quantize_fp_32x32_c + +void vp9_scale_and_extend_frame_c(const struct yv12_buffer_config *src, struct yv12_buffer_config *dst, INTERP_FILTER filter_type, int phase_scaler); +#define vp9_scale_and_extend_frame vp9_scale_and_extend_frame_c + +void vpx_convolve12_c(const uint8_t *src, ptrdiff_t src_stride, uint8_t *dst, ptrdiff_t dst_stride, const InterpKernel12 *filter, int x0_q4, int x_step_q4, int y0_q4, int y_step_q4, int w, int h); +#define vpx_convolve12 vpx_convolve12_c + +void vpx_convolve12_horiz_c(const uint8_t *src, ptrdiff_t src_stride, uint8_t *dst, ptrdiff_t dst_stride, const InterpKernel12 *filter, int x0_q4, int x_step_q4, int y0_q4, int y_step_q4, int w, int h); +#define vpx_convolve12_horiz vpx_convolve12_horiz_c + +void vpx_convolve12_vert_c(const uint8_t *src, ptrdiff_t src_stride, uint8_t *dst, ptrdiff_t dst_stride, const InterpKernel12 *filter, int x0_q4, int x_step_q4, int y0_q4, int y_step_q4, int w, int h); +#define vpx_convolve12_vert vpx_convolve12_vert_c + +void vp9_rtcd(void); + +#include "vpx_config.h" + +#ifdef RTCD_C +static void setup_rtcd_internal(void) +{ +} +#endif + +#ifdef __cplusplus +} // extern "C" +#endif + +#endif // VP9_RTCD_H_ +]==], + ["mcpp_generated/vpx_dsp_rtcd.h"] = [==[ +/* + * Copyright (c) 2017 The WebM project authors. All Rights Reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. An additional intellectual property rights grant can be found + * in the file PATENTS. All contributing project authors may + * be found in the AUTHORS file in the root of the source tree. + */ + +// This file is generated. Do not edit. +#ifndef VPX_DSP_RTCD_H_ +#define VPX_DSP_RTCD_H_ + +#ifdef RTCD_C +#define RTCD_EXTERN +#else +#define RTCD_EXTERN extern +#endif + +/* + * DSP + */ + +#include "vpx/vpx_integer.h" +#include "vpx_dsp/vpx_dsp_common.h" +#include "vpx_dsp/vpx_filter.h" +#if CONFIG_VP9_ENCODER + struct macroblock_plane; + struct ScanOrder; +#endif + + +#ifdef __cplusplus +extern "C" { +#endif + +unsigned int vpx_avg_4x4_c(const uint8_t *, int p); +#define vpx_avg_4x4 vpx_avg_4x4_c + +unsigned int vpx_avg_8x8_c(const uint8_t *, int p); +#define vpx_avg_8x8 vpx_avg_8x8_c + +void vpx_comp_avg_pred_c(uint8_t *comp_pred, const uint8_t *pred, int width, int height, const uint8_t *ref, int ref_stride); +#define vpx_comp_avg_pred vpx_comp_avg_pred_c + +void vpx_convolve8_c(const uint8_t *src, ptrdiff_t src_stride, uint8_t *dst, ptrdiff_t dst_stride, const InterpKernel *filter, int x0_q4, int x_step_q4, int y0_q4, int y_step_q4, int w, int h); +#define vpx_convolve8 vpx_convolve8_c + +void vpx_convolve8_avg_c(const uint8_t *src, ptrdiff_t src_stride, uint8_t *dst, ptrdiff_t dst_stride, const InterpKernel *filter, int x0_q4, int x_step_q4, int y0_q4, int y_step_q4, int w, int h); +#define vpx_convolve8_avg vpx_convolve8_avg_c + +void vpx_convolve8_avg_horiz_c(const uint8_t *src, ptrdiff_t src_stride, uint8_t *dst, ptrdiff_t dst_stride, const InterpKernel *filter, int x0_q4, int x_step_q4, int y0_q4, int y_step_q4, int w, int h); +#define vpx_convolve8_avg_horiz vpx_convolve8_avg_horiz_c + +void vpx_convolve8_avg_vert_c(const uint8_t *src, ptrdiff_t src_stride, uint8_t *dst, ptrdiff_t dst_stride, const InterpKernel *filter, int x0_q4, int x_step_q4, int y0_q4, int y_step_q4, int w, int h); +#define vpx_convolve8_avg_vert vpx_convolve8_avg_vert_c + +void vpx_convolve8_horiz_c(const uint8_t *src, ptrdiff_t src_stride, uint8_t *dst, ptrdiff_t dst_stride, const InterpKernel *filter, int x0_q4, int x_step_q4, int y0_q4, int y_step_q4, int w, int h); +#define vpx_convolve8_horiz vpx_convolve8_horiz_c + +void vpx_convolve8_vert_c(const uint8_t *src, ptrdiff_t src_stride, uint8_t *dst, ptrdiff_t dst_stride, const InterpKernel *filter, int x0_q4, int x_step_q4, int y0_q4, int y_step_q4, int w, int h); +#define vpx_convolve8_vert vpx_convolve8_vert_c + +void vpx_convolve_avg_c(const uint8_t *src, ptrdiff_t src_stride, uint8_t *dst, ptrdiff_t dst_stride, const InterpKernel *filter, int x0_q4, int x_step_q4, int y0_q4, int y_step_q4, int w, int h); +#define vpx_convolve_avg vpx_convolve_avg_c + +void vpx_convolve_copy_c(const uint8_t *src, ptrdiff_t src_stride, uint8_t *dst, ptrdiff_t dst_stride, const InterpKernel *filter, int x0_q4, int x_step_q4, int y0_q4, int y_step_q4, int w, int h); +#define vpx_convolve_copy vpx_convolve_copy_c + +void vpx_d117_predictor_16x16_c(uint8_t *dst, ptrdiff_t stride, const uint8_t *above, const uint8_t *left); +#define vpx_d117_predictor_16x16 vpx_d117_predictor_16x16_c + +void vpx_d117_predictor_32x32_c(uint8_t *dst, ptrdiff_t stride, const uint8_t *above, const uint8_t *left); +#define vpx_d117_predictor_32x32 vpx_d117_predictor_32x32_c + +void vpx_d117_predictor_4x4_c(uint8_t *dst, ptrdiff_t stride, const uint8_t *above, const uint8_t *left); +#define vpx_d117_predictor_4x4 vpx_d117_predictor_4x4_c + +void vpx_d117_predictor_8x8_c(uint8_t *dst, ptrdiff_t stride, const uint8_t *above, const uint8_t *left); +#define vpx_d117_predictor_8x8 vpx_d117_predictor_8x8_c + +void vpx_d135_predictor_16x16_c(uint8_t *dst, ptrdiff_t stride, const uint8_t *above, const uint8_t *left); +#define vpx_d135_predictor_16x16 vpx_d135_predictor_16x16_c + +void vpx_d135_predictor_32x32_c(uint8_t *dst, ptrdiff_t stride, const uint8_t *above, const uint8_t *left); +#define vpx_d135_predictor_32x32 vpx_d135_predictor_32x32_c + +void vpx_d135_predictor_4x4_c(uint8_t *dst, ptrdiff_t stride, const uint8_t *above, const uint8_t *left); +#define vpx_d135_predictor_4x4 vpx_d135_predictor_4x4_c + +void vpx_d135_predictor_8x8_c(uint8_t *dst, ptrdiff_t stride, const uint8_t *above, const uint8_t *left); +#define vpx_d135_predictor_8x8 vpx_d135_predictor_8x8_c + +void vpx_d153_predictor_16x16_c(uint8_t *dst, ptrdiff_t stride, const uint8_t *above, const uint8_t *left); +#define vpx_d153_predictor_16x16 vpx_d153_predictor_16x16_c + +void vpx_d153_predictor_32x32_c(uint8_t *dst, ptrdiff_t stride, const uint8_t *above, const uint8_t *left); +#define vpx_d153_predictor_32x32 vpx_d153_predictor_32x32_c + +void vpx_d153_predictor_4x4_c(uint8_t *dst, ptrdiff_t stride, const uint8_t *above, const uint8_t *left); +#define vpx_d153_predictor_4x4 vpx_d153_predictor_4x4_c + +void vpx_d153_predictor_8x8_c(uint8_t *dst, ptrdiff_t stride, const uint8_t *above, const uint8_t *left); +#define vpx_d153_predictor_8x8 vpx_d153_predictor_8x8_c + +void vpx_d207_predictor_16x16_c(uint8_t *dst, ptrdiff_t stride, const uint8_t *above, const uint8_t *left); +#define vpx_d207_predictor_16x16 vpx_d207_predictor_16x16_c + +void vpx_d207_predictor_32x32_c(uint8_t *dst, ptrdiff_t stride, const uint8_t *above, const uint8_t *left); +#define vpx_d207_predictor_32x32 vpx_d207_predictor_32x32_c + +void vpx_d207_predictor_4x4_c(uint8_t *dst, ptrdiff_t stride, const uint8_t *above, const uint8_t *left); +#define vpx_d207_predictor_4x4 vpx_d207_predictor_4x4_c + +void vpx_d207_predictor_8x8_c(uint8_t *dst, ptrdiff_t stride, const uint8_t *above, const uint8_t *left); +#define vpx_d207_predictor_8x8 vpx_d207_predictor_8x8_c + +void vpx_d45_predictor_16x16_c(uint8_t *dst, ptrdiff_t stride, const uint8_t *above, const uint8_t *left); +#define vpx_d45_predictor_16x16 vpx_d45_predictor_16x16_c + +void vpx_d45_predictor_32x32_c(uint8_t *dst, ptrdiff_t stride, const uint8_t *above, const uint8_t *left); +#define vpx_d45_predictor_32x32 vpx_d45_predictor_32x32_c + +void vpx_d45_predictor_4x4_c(uint8_t *dst, ptrdiff_t stride, const uint8_t *above, const uint8_t *left); +#define vpx_d45_predictor_4x4 vpx_d45_predictor_4x4_c + +void vpx_d45_predictor_8x8_c(uint8_t *dst, ptrdiff_t stride, const uint8_t *above, const uint8_t *left); +#define vpx_d45_predictor_8x8 vpx_d45_predictor_8x8_c + +void vpx_d45e_predictor_4x4_c(uint8_t *dst, ptrdiff_t stride, const uint8_t *above, const uint8_t *left); +#define vpx_d45e_predictor_4x4 vpx_d45e_predictor_4x4_c + +void vpx_d63_predictor_16x16_c(uint8_t *dst, ptrdiff_t stride, const uint8_t *above, const uint8_t *left); +#define vpx_d63_predictor_16x16 vpx_d63_predictor_16x16_c + +void vpx_d63_predictor_32x32_c(uint8_t *dst, ptrdiff_t stride, const uint8_t *above, const uint8_t *left); +#define vpx_d63_predictor_32x32 vpx_d63_predictor_32x32_c + +void vpx_d63_predictor_4x4_c(uint8_t *dst, ptrdiff_t stride, const uint8_t *above, const uint8_t *left); +#define vpx_d63_predictor_4x4 vpx_d63_predictor_4x4_c + +void vpx_d63_predictor_8x8_c(uint8_t *dst, ptrdiff_t stride, const uint8_t *above, const uint8_t *left); +#define vpx_d63_predictor_8x8 vpx_d63_predictor_8x8_c + +void vpx_d63e_predictor_4x4_c(uint8_t *dst, ptrdiff_t stride, const uint8_t *above, const uint8_t *left); +#define vpx_d63e_predictor_4x4 vpx_d63e_predictor_4x4_c + +void vpx_dc_128_predictor_16x16_c(uint8_t *dst, ptrdiff_t stride, const uint8_t *above, const uint8_t *left); +#define vpx_dc_128_predictor_16x16 vpx_dc_128_predictor_16x16_c + +void vpx_dc_128_predictor_32x32_c(uint8_t *dst, ptrdiff_t stride, const uint8_t *above, const uint8_t *left); +#define vpx_dc_128_predictor_32x32 vpx_dc_128_predictor_32x32_c + +void vpx_dc_128_predictor_4x4_c(uint8_t *dst, ptrdiff_t stride, const uint8_t *above, const uint8_t *left); +#define vpx_dc_128_predictor_4x4 vpx_dc_128_predictor_4x4_c + +void vpx_dc_128_predictor_8x8_c(uint8_t *dst, ptrdiff_t stride, const uint8_t *above, const uint8_t *left); +#define vpx_dc_128_predictor_8x8 vpx_dc_128_predictor_8x8_c + +void vpx_dc_left_predictor_16x16_c(uint8_t *dst, ptrdiff_t stride, const uint8_t *above, const uint8_t *left); +#define vpx_dc_left_predictor_16x16 vpx_dc_left_predictor_16x16_c + +void vpx_dc_left_predictor_32x32_c(uint8_t *dst, ptrdiff_t stride, const uint8_t *above, const uint8_t *left); +#define vpx_dc_left_predictor_32x32 vpx_dc_left_predictor_32x32_c + +void vpx_dc_left_predictor_4x4_c(uint8_t *dst, ptrdiff_t stride, const uint8_t *above, const uint8_t *left); +#define vpx_dc_left_predictor_4x4 vpx_dc_left_predictor_4x4_c + +void vpx_dc_left_predictor_8x8_c(uint8_t *dst, ptrdiff_t stride, const uint8_t *above, const uint8_t *left); +#define vpx_dc_left_predictor_8x8 vpx_dc_left_predictor_8x8_c + +void vpx_dc_predictor_16x16_c(uint8_t *dst, ptrdiff_t stride, const uint8_t *above, const uint8_t *left); +#define vpx_dc_predictor_16x16 vpx_dc_predictor_16x16_c + +void vpx_dc_predictor_32x32_c(uint8_t *dst, ptrdiff_t stride, const uint8_t *above, const uint8_t *left); +#define vpx_dc_predictor_32x32 vpx_dc_predictor_32x32_c + +void vpx_dc_predictor_4x4_c(uint8_t *dst, ptrdiff_t stride, const uint8_t *above, const uint8_t *left); +#define vpx_dc_predictor_4x4 vpx_dc_predictor_4x4_c + +void vpx_dc_predictor_8x8_c(uint8_t *dst, ptrdiff_t stride, const uint8_t *above, const uint8_t *left); +#define vpx_dc_predictor_8x8 vpx_dc_predictor_8x8_c + +void vpx_dc_top_predictor_16x16_c(uint8_t *dst, ptrdiff_t stride, const uint8_t *above, const uint8_t *left); +#define vpx_dc_top_predictor_16x16 vpx_dc_top_predictor_16x16_c + +void vpx_dc_top_predictor_32x32_c(uint8_t *dst, ptrdiff_t stride, const uint8_t *above, const uint8_t *left); +#define vpx_dc_top_predictor_32x32 vpx_dc_top_predictor_32x32_c + +void vpx_dc_top_predictor_4x4_c(uint8_t *dst, ptrdiff_t stride, const uint8_t *above, const uint8_t *left); +#define vpx_dc_top_predictor_4x4 vpx_dc_top_predictor_4x4_c + +void vpx_dc_top_predictor_8x8_c(uint8_t *dst, ptrdiff_t stride, const uint8_t *above, const uint8_t *left); +#define vpx_dc_top_predictor_8x8 vpx_dc_top_predictor_8x8_c + +void vpx_fdct16x16_c(const int16_t *input, tran_low_t *output, int stride); +#define vpx_fdct16x16 vpx_fdct16x16_c + +void vpx_fdct16x16_1_c(const int16_t *input, tran_low_t *output, int stride); +#define vpx_fdct16x16_1 vpx_fdct16x16_1_c + +void vpx_fdct32x32_c(const int16_t *input, tran_low_t *output, int stride); +#define vpx_fdct32x32 vpx_fdct32x32_c + +void vpx_fdct32x32_1_c(const int16_t *input, tran_low_t *output, int stride); +#define vpx_fdct32x32_1 vpx_fdct32x32_1_c + +void vpx_fdct32x32_rd_c(const int16_t *input, tran_low_t *output, int stride); +#define vpx_fdct32x32_rd vpx_fdct32x32_rd_c + +void vpx_fdct4x4_c(const int16_t *input, tran_low_t *output, int stride); +#define vpx_fdct4x4 vpx_fdct4x4_c + +void vpx_fdct4x4_1_c(const int16_t *input, tran_low_t *output, int stride); +#define vpx_fdct4x4_1 vpx_fdct4x4_1_c + +void vpx_fdct8x8_c(const int16_t *input, tran_low_t *output, int stride); +#define vpx_fdct8x8 vpx_fdct8x8_c + +void vpx_fdct8x8_1_c(const int16_t *input, tran_low_t *output, int stride); +#define vpx_fdct8x8_1 vpx_fdct8x8_1_c + +void vpx_get16x16var_c(const uint8_t *src_ptr, int src_stride, const uint8_t *ref_ptr, int ref_stride, unsigned int *sse, int *sum); +#define vpx_get16x16var vpx_get16x16var_c + +unsigned int vpx_get4x4sse_cs_c(const unsigned char *src_ptr, int src_stride, const unsigned char *ref_ptr, int ref_stride); +#define vpx_get4x4sse_cs vpx_get4x4sse_cs_c + +void vpx_get8x8var_c(const uint8_t *src_ptr, int src_stride, const uint8_t *ref_ptr, int ref_stride, unsigned int *sse, int *sum); +#define vpx_get8x8var vpx_get8x8var_c + +unsigned int vpx_get_mb_ss_c(const int16_t *); +#define vpx_get_mb_ss vpx_get_mb_ss_c + +void vpx_h_predictor_16x16_c(uint8_t *dst, ptrdiff_t stride, const uint8_t *above, const uint8_t *left); +#define vpx_h_predictor_16x16 vpx_h_predictor_16x16_c + +void vpx_h_predictor_32x32_c(uint8_t *dst, ptrdiff_t stride, const uint8_t *above, const uint8_t *left); +#define vpx_h_predictor_32x32 vpx_h_predictor_32x32_c + +void vpx_h_predictor_4x4_c(uint8_t *dst, ptrdiff_t stride, const uint8_t *above, const uint8_t *left); +#define vpx_h_predictor_4x4 vpx_h_predictor_4x4_c + +void vpx_h_predictor_8x8_c(uint8_t *dst, ptrdiff_t stride, const uint8_t *above, const uint8_t *left); +#define vpx_h_predictor_8x8 vpx_h_predictor_8x8_c + +void vpx_hadamard_16x16_c(const int16_t *src_diff, ptrdiff_t src_stride, int16_t *coeff); +#define vpx_hadamard_16x16 vpx_hadamard_16x16_c + +void vpx_hadamard_32x32_c(const int16_t *src_diff, ptrdiff_t src_stride, int16_t *coeff); +#define vpx_hadamard_32x32 vpx_hadamard_32x32_c + +void vpx_hadamard_8x8_c(const int16_t *src_diff, ptrdiff_t src_stride, int16_t *coeff); +#define vpx_hadamard_8x8 vpx_hadamard_8x8_c + +void vpx_he_predictor_4x4_c(uint8_t *dst, ptrdiff_t stride, const uint8_t *above, const uint8_t *left); +#define vpx_he_predictor_4x4 vpx_he_predictor_4x4_c + +void vpx_idct16x16_10_add_c(const tran_low_t *input, uint8_t *dest, int stride); +#define vpx_idct16x16_10_add vpx_idct16x16_10_add_c + +void vpx_idct16x16_1_add_c(const tran_low_t *input, uint8_t *dest, int stride); +#define vpx_idct16x16_1_add vpx_idct16x16_1_add_c + +void vpx_idct16x16_256_add_c(const tran_low_t *input, uint8_t *dest, int stride); +#define vpx_idct16x16_256_add vpx_idct16x16_256_add_c + +void vpx_idct16x16_38_add_c(const tran_low_t *input, uint8_t *dest, int stride); +#define vpx_idct16x16_38_add vpx_idct16x16_38_add_c + +void vpx_idct32x32_1024_add_c(const tran_low_t *input, uint8_t *dest, int stride); +#define vpx_idct32x32_1024_add vpx_idct32x32_1024_add_c + +void vpx_idct32x32_135_add_c(const tran_low_t *input, uint8_t *dest, int stride); +#define vpx_idct32x32_135_add vpx_idct32x32_135_add_c + +void vpx_idct32x32_1_add_c(const tran_low_t *input, uint8_t *dest, int stride); +#define vpx_idct32x32_1_add vpx_idct32x32_1_add_c + +void vpx_idct32x32_34_add_c(const tran_low_t *input, uint8_t *dest, int stride); +#define vpx_idct32x32_34_add vpx_idct32x32_34_add_c + +void vpx_idct4x4_16_add_c(const tran_low_t *input, uint8_t *dest, int stride); +#define vpx_idct4x4_16_add vpx_idct4x4_16_add_c + +void vpx_idct4x4_1_add_c(const tran_low_t *input, uint8_t *dest, int stride); +#define vpx_idct4x4_1_add vpx_idct4x4_1_add_c + +void vpx_idct8x8_12_add_c(const tran_low_t *input, uint8_t *dest, int stride); +#define vpx_idct8x8_12_add vpx_idct8x8_12_add_c + +void vpx_idct8x8_1_add_c(const tran_low_t *input, uint8_t *dest, int stride); +#define vpx_idct8x8_1_add vpx_idct8x8_1_add_c + +void vpx_idct8x8_64_add_c(const tran_low_t *input, uint8_t *dest, int stride); +#define vpx_idct8x8_64_add vpx_idct8x8_64_add_c + +int16_t vpx_int_pro_col_c(const uint8_t *ref, const int width); +#define vpx_int_pro_col vpx_int_pro_col_c + +void vpx_int_pro_row_c(int16_t hbuf[16], const uint8_t *ref, const int ref_stride, const int height); +#define vpx_int_pro_row vpx_int_pro_row_c + +void vpx_iwht4x4_16_add_c(const tran_low_t *input, uint8_t *dest, int stride); +#define vpx_iwht4x4_16_add vpx_iwht4x4_16_add_c + +void vpx_iwht4x4_1_add_c(const tran_low_t *input, uint8_t *dest, int stride); +#define vpx_iwht4x4_1_add vpx_iwht4x4_1_add_c + +void vpx_lpf_horizontal_16_c(uint8_t *s, int pitch, const uint8_t *blimit, const uint8_t *limit, const uint8_t *thresh); +#define vpx_lpf_horizontal_16 vpx_lpf_horizontal_16_c + +void vpx_lpf_horizontal_16_dual_c(uint8_t *s, int pitch, const uint8_t *blimit, const uint8_t *limit, const uint8_t *thresh); +#define vpx_lpf_horizontal_16_dual vpx_lpf_horizontal_16_dual_c + +void vpx_lpf_horizontal_4_c(uint8_t *s, int pitch, const uint8_t *blimit, const uint8_t *limit, const uint8_t *thresh); +#define vpx_lpf_horizontal_4 vpx_lpf_horizontal_4_c + +void vpx_lpf_horizontal_4_dual_c(uint8_t *s, int pitch, const uint8_t *blimit0, const uint8_t *limit0, const uint8_t *thresh0, const uint8_t *blimit1, const uint8_t *limit1, const uint8_t *thresh1); +#define vpx_lpf_horizontal_4_dual vpx_lpf_horizontal_4_dual_c + +void vpx_lpf_horizontal_8_c(uint8_t *s, int pitch, const uint8_t *blimit, const uint8_t *limit, const uint8_t *thresh); +#define vpx_lpf_horizontal_8 vpx_lpf_horizontal_8_c + +void vpx_lpf_horizontal_8_dual_c(uint8_t *s, int pitch, const uint8_t *blimit0, const uint8_t *limit0, const uint8_t *thresh0, const uint8_t *blimit1, const uint8_t *limit1, const uint8_t *thresh1); +#define vpx_lpf_horizontal_8_dual vpx_lpf_horizontal_8_dual_c + +void vpx_lpf_vertical_16_c(uint8_t *s, int pitch, const uint8_t *blimit, const uint8_t *limit, const uint8_t *thresh); +#define vpx_lpf_vertical_16 vpx_lpf_vertical_16_c + +void vpx_lpf_vertical_16_dual_c(uint8_t *s, int pitch, const uint8_t *blimit, const uint8_t *limit, const uint8_t *thresh); +#define vpx_lpf_vertical_16_dual vpx_lpf_vertical_16_dual_c + +void vpx_lpf_vertical_4_c(uint8_t *s, int pitch, const uint8_t *blimit, const uint8_t *limit, const uint8_t *thresh); +#define vpx_lpf_vertical_4 vpx_lpf_vertical_4_c + +void vpx_lpf_vertical_4_dual_c(uint8_t *s, int pitch, const uint8_t *blimit0, const uint8_t *limit0, const uint8_t *thresh0, const uint8_t *blimit1, const uint8_t *limit1, const uint8_t *thresh1); +#define vpx_lpf_vertical_4_dual vpx_lpf_vertical_4_dual_c + +void vpx_lpf_vertical_8_c(uint8_t *s, int pitch, const uint8_t *blimit, const uint8_t *limit, const uint8_t *thresh); +#define vpx_lpf_vertical_8 vpx_lpf_vertical_8_c + +void vpx_lpf_vertical_8_dual_c(uint8_t *s, int pitch, const uint8_t *blimit0, const uint8_t *limit0, const uint8_t *thresh0, const uint8_t *blimit1, const uint8_t *limit1, const uint8_t *thresh1); +#define vpx_lpf_vertical_8_dual vpx_lpf_vertical_8_dual_c + +void vpx_minmax_8x8_c(const uint8_t *s, int p, const uint8_t *d, int dp, int *min, int *max); +#define vpx_minmax_8x8 vpx_minmax_8x8_c + +unsigned int vpx_mse16x16_c(const uint8_t *src_ptr, int src_stride, const uint8_t *ref_ptr, int ref_stride, unsigned int *sse); +#define vpx_mse16x16 vpx_mse16x16_c + +unsigned int vpx_mse16x8_c(const uint8_t *src_ptr, int src_stride, const uint8_t *ref_ptr, int ref_stride, unsigned int *sse); +#define vpx_mse16x8 vpx_mse16x8_c + +unsigned int vpx_mse8x16_c(const uint8_t *src_ptr, int src_stride, const uint8_t *ref_ptr, int ref_stride, unsigned int *sse); +#define vpx_mse8x16 vpx_mse8x16_c + +unsigned int vpx_mse8x8_c(const uint8_t *src_ptr, int src_stride, const uint8_t *ref_ptr, int ref_stride, unsigned int *sse); +#define vpx_mse8x8 vpx_mse8x8_c + +void vpx_quantize_b_c(const tran_low_t *coeff_ptr, intptr_t n_coeffs, const struct macroblock_plane *const mb_plane, tran_low_t *qcoeff_ptr, tran_low_t *dqcoeff_ptr, const int16_t *dequant_ptr, uint16_t *eob_ptr, const struct ScanOrder *const scan_order); +#define vpx_quantize_b vpx_quantize_b_c + +void vpx_quantize_b_32x32_c(const tran_low_t *coeff_ptr, const struct macroblock_plane *const mb_plane, tran_low_t *qcoeff_ptr, tran_low_t *dqcoeff_ptr, const int16_t *dequant_ptr, uint16_t *eob_ptr, const struct ScanOrder *const scan_order); +#define vpx_quantize_b_32x32 vpx_quantize_b_32x32_c + +unsigned int vpx_sad16x16_c(const uint8_t *src_ptr, int src_stride, const uint8_t *ref_ptr, int ref_stride); +#define vpx_sad16x16 vpx_sad16x16_c + +unsigned int vpx_sad16x16_avg_c(const uint8_t *src_ptr, int src_stride, const uint8_t *ref_ptr, int ref_stride, const uint8_t *second_pred); +#define vpx_sad16x16_avg vpx_sad16x16_avg_c + +void vpx_sad16x16x4d_c(const uint8_t *src_ptr, int src_stride, const uint8_t *const ref_array[4], int ref_stride, uint32_t sad_array[4]); +#define vpx_sad16x16x4d vpx_sad16x16x4d_c + +unsigned int vpx_sad16x32_c(const uint8_t *src_ptr, int src_stride, const uint8_t *ref_ptr, int ref_stride); +#define vpx_sad16x32 vpx_sad16x32_c + +unsigned int vpx_sad16x32_avg_c(const uint8_t *src_ptr, int src_stride, const uint8_t *ref_ptr, int ref_stride, const uint8_t *second_pred); +#define vpx_sad16x32_avg vpx_sad16x32_avg_c + +void vpx_sad16x32x4d_c(const uint8_t *src_ptr, int src_stride, const uint8_t *const ref_array[4], int ref_stride, uint32_t sad_array[4]); +#define vpx_sad16x32x4d vpx_sad16x32x4d_c + +unsigned int vpx_sad16x8_c(const uint8_t *src_ptr, int src_stride, const uint8_t *ref_ptr, int ref_stride); +#define vpx_sad16x8 vpx_sad16x8_c + +unsigned int vpx_sad16x8_avg_c(const uint8_t *src_ptr, int src_stride, const uint8_t *ref_ptr, int ref_stride, const uint8_t *second_pred); +#define vpx_sad16x8_avg vpx_sad16x8_avg_c + +void vpx_sad16x8x4d_c(const uint8_t *src_ptr, int src_stride, const uint8_t *const ref_array[4], int ref_stride, uint32_t sad_array[4]); +#define vpx_sad16x8x4d vpx_sad16x8x4d_c + +unsigned int vpx_sad32x16_c(const uint8_t *src_ptr, int src_stride, const uint8_t *ref_ptr, int ref_stride); +#define vpx_sad32x16 vpx_sad32x16_c + +unsigned int vpx_sad32x16_avg_c(const uint8_t *src_ptr, int src_stride, const uint8_t *ref_ptr, int ref_stride, const uint8_t *second_pred); +#define vpx_sad32x16_avg vpx_sad32x16_avg_c + +void vpx_sad32x16x4d_c(const uint8_t *src_ptr, int src_stride, const uint8_t *const ref_array[4], int ref_stride, uint32_t sad_array[4]); +#define vpx_sad32x16x4d vpx_sad32x16x4d_c + +unsigned int vpx_sad32x32_c(const uint8_t *src_ptr, int src_stride, const uint8_t *ref_ptr, int ref_stride); +#define vpx_sad32x32 vpx_sad32x32_c + +unsigned int vpx_sad32x32_avg_c(const uint8_t *src_ptr, int src_stride, const uint8_t *ref_ptr, int ref_stride, const uint8_t *second_pred); +#define vpx_sad32x32_avg vpx_sad32x32_avg_c + +void vpx_sad32x32x4d_c(const uint8_t *src_ptr, int src_stride, const uint8_t *const ref_array[4], int ref_stride, uint32_t sad_array[4]); +#define vpx_sad32x32x4d vpx_sad32x32x4d_c + +unsigned int vpx_sad32x64_c(const uint8_t *src_ptr, int src_stride, const uint8_t *ref_ptr, int ref_stride); +#define vpx_sad32x64 vpx_sad32x64_c + +unsigned int vpx_sad32x64_avg_c(const uint8_t *src_ptr, int src_stride, const uint8_t *ref_ptr, int ref_stride, const uint8_t *second_pred); +#define vpx_sad32x64_avg vpx_sad32x64_avg_c + +void vpx_sad32x64x4d_c(const uint8_t *src_ptr, int src_stride, const uint8_t *const ref_array[4], int ref_stride, uint32_t sad_array[4]); +#define vpx_sad32x64x4d vpx_sad32x64x4d_c + +unsigned int vpx_sad4x4_c(const uint8_t *src_ptr, int src_stride, const uint8_t *ref_ptr, int ref_stride); +#define vpx_sad4x4 vpx_sad4x4_c + +unsigned int vpx_sad4x4_avg_c(const uint8_t *src_ptr, int src_stride, const uint8_t *ref_ptr, int ref_stride, const uint8_t *second_pred); +#define vpx_sad4x4_avg vpx_sad4x4_avg_c + +void vpx_sad4x4x4d_c(const uint8_t *src_ptr, int src_stride, const uint8_t *const ref_array[4], int ref_stride, uint32_t sad_array[4]); +#define vpx_sad4x4x4d vpx_sad4x4x4d_c + +unsigned int vpx_sad4x8_c(const uint8_t *src_ptr, int src_stride, const uint8_t *ref_ptr, int ref_stride); +#define vpx_sad4x8 vpx_sad4x8_c + +unsigned int vpx_sad4x8_avg_c(const uint8_t *src_ptr, int src_stride, const uint8_t *ref_ptr, int ref_stride, const uint8_t *second_pred); +#define vpx_sad4x8_avg vpx_sad4x8_avg_c + +void vpx_sad4x8x4d_c(const uint8_t *src_ptr, int src_stride, const uint8_t *const ref_array[4], int ref_stride, uint32_t sad_array[4]); +#define vpx_sad4x8x4d vpx_sad4x8x4d_c + +unsigned int vpx_sad64x32_c(const uint8_t *src_ptr, int src_stride, const uint8_t *ref_ptr, int ref_stride); +#define vpx_sad64x32 vpx_sad64x32_c + +unsigned int vpx_sad64x32_avg_c(const uint8_t *src_ptr, int src_stride, const uint8_t *ref_ptr, int ref_stride, const uint8_t *second_pred); +#define vpx_sad64x32_avg vpx_sad64x32_avg_c + +void vpx_sad64x32x4d_c(const uint8_t *src_ptr, int src_stride, const uint8_t *const ref_array[4], int ref_stride, uint32_t sad_array[4]); +#define vpx_sad64x32x4d vpx_sad64x32x4d_c + +unsigned int vpx_sad64x64_c(const uint8_t *src_ptr, int src_stride, const uint8_t *ref_ptr, int ref_stride); +#define vpx_sad64x64 vpx_sad64x64_c + +unsigned int vpx_sad64x64_avg_c(const uint8_t *src_ptr, int src_stride, const uint8_t *ref_ptr, int ref_stride, const uint8_t *second_pred); +#define vpx_sad64x64_avg vpx_sad64x64_avg_c + +void vpx_sad64x64x4d_c(const uint8_t *src_ptr, int src_stride, const uint8_t *const ref_array[4], int ref_stride, uint32_t sad_array[4]); +#define vpx_sad64x64x4d vpx_sad64x64x4d_c + +unsigned int vpx_sad8x16_c(const uint8_t *src_ptr, int src_stride, const uint8_t *ref_ptr, int ref_stride); +#define vpx_sad8x16 vpx_sad8x16_c + +unsigned int vpx_sad8x16_avg_c(const uint8_t *src_ptr, int src_stride, const uint8_t *ref_ptr, int ref_stride, const uint8_t *second_pred); +#define vpx_sad8x16_avg vpx_sad8x16_avg_c + +void vpx_sad8x16x4d_c(const uint8_t *src_ptr, int src_stride, const uint8_t *const ref_array[4], int ref_stride, uint32_t sad_array[4]); +#define vpx_sad8x16x4d vpx_sad8x16x4d_c + +unsigned int vpx_sad8x4_c(const uint8_t *src_ptr, int src_stride, const uint8_t *ref_ptr, int ref_stride); +#define vpx_sad8x4 vpx_sad8x4_c + +unsigned int vpx_sad8x4_avg_c(const uint8_t *src_ptr, int src_stride, const uint8_t *ref_ptr, int ref_stride, const uint8_t *second_pred); +#define vpx_sad8x4_avg vpx_sad8x4_avg_c + +void vpx_sad8x4x4d_c(const uint8_t *src_ptr, int src_stride, const uint8_t *const ref_array[4], int ref_stride, uint32_t sad_array[4]); +#define vpx_sad8x4x4d vpx_sad8x4x4d_c + +unsigned int vpx_sad8x8_c(const uint8_t *src_ptr, int src_stride, const uint8_t *ref_ptr, int ref_stride); +#define vpx_sad8x8 vpx_sad8x8_c + +unsigned int vpx_sad8x8_avg_c(const uint8_t *src_ptr, int src_stride, const uint8_t *ref_ptr, int ref_stride, const uint8_t *second_pred); +#define vpx_sad8x8_avg vpx_sad8x8_avg_c + +void vpx_sad8x8x4d_c(const uint8_t *src_ptr, int src_stride, const uint8_t *const ref_array[4], int ref_stride, uint32_t sad_array[4]); +#define vpx_sad8x8x4d vpx_sad8x8x4d_c + +unsigned int vpx_sad_skip_16x16_c(const uint8_t *src_ptr, int src_stride, const uint8_t *ref_ptr, int ref_stride); +#define vpx_sad_skip_16x16 vpx_sad_skip_16x16_c + +void vpx_sad_skip_16x16x4d_c(const uint8_t *src_ptr, int src_stride, const uint8_t *const ref_array[4], int ref_stride, uint32_t sad_array[4]); +#define vpx_sad_skip_16x16x4d vpx_sad_skip_16x16x4d_c + +unsigned int vpx_sad_skip_16x32_c(const uint8_t *src_ptr, int src_stride, const uint8_t *ref_ptr, int ref_stride); +#define vpx_sad_skip_16x32 vpx_sad_skip_16x32_c + +void vpx_sad_skip_16x32x4d_c(const uint8_t *src_ptr, int src_stride, const uint8_t *const ref_array[4], int ref_stride, uint32_t sad_array[4]); +#define vpx_sad_skip_16x32x4d vpx_sad_skip_16x32x4d_c + +unsigned int vpx_sad_skip_16x8_c(const uint8_t *src_ptr, int src_stride, const uint8_t *ref_ptr, int ref_stride); +#define vpx_sad_skip_16x8 vpx_sad_skip_16x8_c + +void vpx_sad_skip_16x8x4d_c(const uint8_t *src_ptr, int src_stride, const uint8_t *const ref_array[4], int ref_stride, uint32_t sad_array[4]); +#define vpx_sad_skip_16x8x4d vpx_sad_skip_16x8x4d_c + +unsigned int vpx_sad_skip_32x16_c(const uint8_t *src_ptr, int src_stride, const uint8_t *ref_ptr, int ref_stride); +#define vpx_sad_skip_32x16 vpx_sad_skip_32x16_c + +void vpx_sad_skip_32x16x4d_c(const uint8_t *src_ptr, int src_stride, const uint8_t *const ref_array[4], int ref_stride, uint32_t sad_array[4]); +#define vpx_sad_skip_32x16x4d vpx_sad_skip_32x16x4d_c + +unsigned int vpx_sad_skip_32x32_c(const uint8_t *src_ptr, int src_stride, const uint8_t *ref_ptr, int ref_stride); +#define vpx_sad_skip_32x32 vpx_sad_skip_32x32_c + +void vpx_sad_skip_32x32x4d_c(const uint8_t *src_ptr, int src_stride, const uint8_t *const ref_array[4], int ref_stride, uint32_t sad_array[4]); +#define vpx_sad_skip_32x32x4d vpx_sad_skip_32x32x4d_c + +unsigned int vpx_sad_skip_32x64_c(const uint8_t *src_ptr, int src_stride, const uint8_t *ref_ptr, int ref_stride); +#define vpx_sad_skip_32x64 vpx_sad_skip_32x64_c + +void vpx_sad_skip_32x64x4d_c(const uint8_t *src_ptr, int src_stride, const uint8_t *const ref_array[4], int ref_stride, uint32_t sad_array[4]); +#define vpx_sad_skip_32x64x4d vpx_sad_skip_32x64x4d_c + +unsigned int vpx_sad_skip_4x4_c(const uint8_t *src_ptr, int src_stride, const uint8_t *ref_ptr, int ref_stride); +#define vpx_sad_skip_4x4 vpx_sad_skip_4x4_c + +void vpx_sad_skip_4x4x4d_c(const uint8_t *src_ptr, int src_stride, const uint8_t *const ref_array[4], int ref_stride, uint32_t sad_array[4]); +#define vpx_sad_skip_4x4x4d vpx_sad_skip_4x4x4d_c + +unsigned int vpx_sad_skip_4x8_c(const uint8_t *src_ptr, int src_stride, const uint8_t *ref_ptr, int ref_stride); +#define vpx_sad_skip_4x8 vpx_sad_skip_4x8_c + +void vpx_sad_skip_4x8x4d_c(const uint8_t *src_ptr, int src_stride, const uint8_t *const ref_array[4], int ref_stride, uint32_t sad_array[4]); +#define vpx_sad_skip_4x8x4d vpx_sad_skip_4x8x4d_c + +unsigned int vpx_sad_skip_64x32_c(const uint8_t *src_ptr, int src_stride, const uint8_t *ref_ptr, int ref_stride); +#define vpx_sad_skip_64x32 vpx_sad_skip_64x32_c + +void vpx_sad_skip_64x32x4d_c(const uint8_t *src_ptr, int src_stride, const uint8_t *const ref_array[4], int ref_stride, uint32_t sad_array[4]); +#define vpx_sad_skip_64x32x4d vpx_sad_skip_64x32x4d_c + +unsigned int vpx_sad_skip_64x64_c(const uint8_t *src_ptr, int src_stride, const uint8_t *ref_ptr, int ref_stride); +#define vpx_sad_skip_64x64 vpx_sad_skip_64x64_c + +void vpx_sad_skip_64x64x4d_c(const uint8_t *src_ptr, int src_stride, const uint8_t *const ref_array[4], int ref_stride, uint32_t sad_array[4]); +#define vpx_sad_skip_64x64x4d vpx_sad_skip_64x64x4d_c + +unsigned int vpx_sad_skip_8x16_c(const uint8_t *src_ptr, int src_stride, const uint8_t *ref_ptr, int ref_stride); +#define vpx_sad_skip_8x16 vpx_sad_skip_8x16_c + +void vpx_sad_skip_8x16x4d_c(const uint8_t *src_ptr, int src_stride, const uint8_t *const ref_array[4], int ref_stride, uint32_t sad_array[4]); +#define vpx_sad_skip_8x16x4d vpx_sad_skip_8x16x4d_c + +unsigned int vpx_sad_skip_8x4_c(const uint8_t *src_ptr, int src_stride, const uint8_t *ref_ptr, int ref_stride); +#define vpx_sad_skip_8x4 vpx_sad_skip_8x4_c + +void vpx_sad_skip_8x4x4d_c(const uint8_t *src_ptr, int src_stride, const uint8_t *const ref_array[4], int ref_stride, uint32_t sad_array[4]); +#define vpx_sad_skip_8x4x4d vpx_sad_skip_8x4x4d_c + +unsigned int vpx_sad_skip_8x8_c(const uint8_t *src_ptr, int src_stride, const uint8_t *ref_ptr, int ref_stride); +#define vpx_sad_skip_8x8 vpx_sad_skip_8x8_c + +void vpx_sad_skip_8x8x4d_c(const uint8_t *src_ptr, int src_stride, const uint8_t *const ref_array[4], int ref_stride, uint32_t sad_array[4]); +#define vpx_sad_skip_8x8x4d vpx_sad_skip_8x8x4d_c + +int vpx_satd_c(const int16_t *coeff, int length); +#define vpx_satd vpx_satd_c + +void vpx_scaled_2d_c(const uint8_t *src, ptrdiff_t src_stride, uint8_t *dst, ptrdiff_t dst_stride, const InterpKernel *filter, int x0_q4, int x_step_q4, int y0_q4, int y_step_q4, int w, int h); +#define vpx_scaled_2d vpx_scaled_2d_c + +void vpx_scaled_avg_2d_c(const uint8_t *src, ptrdiff_t src_stride, uint8_t *dst, ptrdiff_t dst_stride, const InterpKernel *filter, int x0_q4, int x_step_q4, int y0_q4, int y_step_q4, int w, int h); +#define vpx_scaled_avg_2d vpx_scaled_avg_2d_c + +void vpx_scaled_avg_horiz_c(const uint8_t *src, ptrdiff_t src_stride, uint8_t *dst, ptrdiff_t dst_stride, const InterpKernel *filter, int x0_q4, int x_step_q4, int y0_q4, int y_step_q4, int w, int h); +#define vpx_scaled_avg_horiz vpx_scaled_avg_horiz_c + +void vpx_scaled_avg_vert_c(const uint8_t *src, ptrdiff_t src_stride, uint8_t *dst, ptrdiff_t dst_stride, const InterpKernel *filter, int x0_q4, int x_step_q4, int y0_q4, int y_step_q4, int w, int h); +#define vpx_scaled_avg_vert vpx_scaled_avg_vert_c + +void vpx_scaled_horiz_c(const uint8_t *src, ptrdiff_t src_stride, uint8_t *dst, ptrdiff_t dst_stride, const InterpKernel *filter, int x0_q4, int x_step_q4, int y0_q4, int y_step_q4, int w, int h); +#define vpx_scaled_horiz vpx_scaled_horiz_c + +void vpx_scaled_vert_c(const uint8_t *src, ptrdiff_t src_stride, uint8_t *dst, ptrdiff_t dst_stride, const InterpKernel *filter, int x0_q4, int x_step_q4, int y0_q4, int y_step_q4, int w, int h); +#define vpx_scaled_vert vpx_scaled_vert_c + +int64_t vpx_sse_c(const uint8_t *src, int src_stride, const uint8_t *ref, int ref_stride, int width, int height); +#define vpx_sse vpx_sse_c + +uint32_t vpx_sub_pixel_avg_variance16x16_c(const uint8_t *src_ptr, int src_stride, int x_offset, int y_offset, const uint8_t *ref_ptr, int ref_stride, uint32_t *sse, const uint8_t *second_pred); +#define vpx_sub_pixel_avg_variance16x16 vpx_sub_pixel_avg_variance16x16_c + +uint32_t vpx_sub_pixel_avg_variance16x32_c(const uint8_t *src_ptr, int src_stride, int x_offset, int y_offset, const uint8_t *ref_ptr, int ref_stride, uint32_t *sse, const uint8_t *second_pred); +#define vpx_sub_pixel_avg_variance16x32 vpx_sub_pixel_avg_variance16x32_c + +uint32_t vpx_sub_pixel_avg_variance16x8_c(const uint8_t *src_ptr, int src_stride, int x_offset, int y_offset, const uint8_t *ref_ptr, int ref_stride, uint32_t *sse, const uint8_t *second_pred); +#define vpx_sub_pixel_avg_variance16x8 vpx_sub_pixel_avg_variance16x8_c + +uint32_t vpx_sub_pixel_avg_variance32x16_c(const uint8_t *src_ptr, int src_stride, int x_offset, int y_offset, const uint8_t *ref_ptr, int ref_stride, uint32_t *sse, const uint8_t *second_pred); +#define vpx_sub_pixel_avg_variance32x16 vpx_sub_pixel_avg_variance32x16_c + +uint32_t vpx_sub_pixel_avg_variance32x32_c(const uint8_t *src_ptr, int src_stride, int x_offset, int y_offset, const uint8_t *ref_ptr, int ref_stride, uint32_t *sse, const uint8_t *second_pred); +#define vpx_sub_pixel_avg_variance32x32 vpx_sub_pixel_avg_variance32x32_c + +uint32_t vpx_sub_pixel_avg_variance32x64_c(const uint8_t *src_ptr, int src_stride, int x_offset, int y_offset, const uint8_t *ref_ptr, int ref_stride, uint32_t *sse, const uint8_t *second_pred); +#define vpx_sub_pixel_avg_variance32x64 vpx_sub_pixel_avg_variance32x64_c + +uint32_t vpx_sub_pixel_avg_variance4x4_c(const uint8_t *src_ptr, int src_stride, int x_offset, int y_offset, const uint8_t *ref_ptr, int ref_stride, uint32_t *sse, const uint8_t *second_pred); +#define vpx_sub_pixel_avg_variance4x4 vpx_sub_pixel_avg_variance4x4_c + +uint32_t vpx_sub_pixel_avg_variance4x8_c(const uint8_t *src_ptr, int src_stride, int x_offset, int y_offset, const uint8_t *ref_ptr, int ref_stride, uint32_t *sse, const uint8_t *second_pred); +#define vpx_sub_pixel_avg_variance4x8 vpx_sub_pixel_avg_variance4x8_c + +uint32_t vpx_sub_pixel_avg_variance64x32_c(const uint8_t *src_ptr, int src_stride, int x_offset, int y_offset, const uint8_t *ref_ptr, int ref_stride, uint32_t *sse, const uint8_t *second_pred); +#define vpx_sub_pixel_avg_variance64x32 vpx_sub_pixel_avg_variance64x32_c + +uint32_t vpx_sub_pixel_avg_variance64x64_c(const uint8_t *src_ptr, int src_stride, int x_offset, int y_offset, const uint8_t *ref_ptr, int ref_stride, uint32_t *sse, const uint8_t *second_pred); +#define vpx_sub_pixel_avg_variance64x64 vpx_sub_pixel_avg_variance64x64_c + +uint32_t vpx_sub_pixel_avg_variance8x16_c(const uint8_t *src_ptr, int src_stride, int x_offset, int y_offset, const uint8_t *ref_ptr, int ref_stride, uint32_t *sse, const uint8_t *second_pred); +#define vpx_sub_pixel_avg_variance8x16 vpx_sub_pixel_avg_variance8x16_c + +uint32_t vpx_sub_pixel_avg_variance8x4_c(const uint8_t *src_ptr, int src_stride, int x_offset, int y_offset, const uint8_t *ref_ptr, int ref_stride, uint32_t *sse, const uint8_t *second_pred); +#define vpx_sub_pixel_avg_variance8x4 vpx_sub_pixel_avg_variance8x4_c + +uint32_t vpx_sub_pixel_avg_variance8x8_c(const uint8_t *src_ptr, int src_stride, int x_offset, int y_offset, const uint8_t *ref_ptr, int ref_stride, uint32_t *sse, const uint8_t *second_pred); +#define vpx_sub_pixel_avg_variance8x8 vpx_sub_pixel_avg_variance8x8_c + +uint32_t vpx_sub_pixel_variance16x16_c(const uint8_t *src_ptr, int src_stride, int x_offset, int y_offset, const uint8_t *ref_ptr, int ref_stride, uint32_t *sse); +#define vpx_sub_pixel_variance16x16 vpx_sub_pixel_variance16x16_c + +uint32_t vpx_sub_pixel_variance16x32_c(const uint8_t *src_ptr, int src_stride, int x_offset, int y_offset, const uint8_t *ref_ptr, int ref_stride, uint32_t *sse); +#define vpx_sub_pixel_variance16x32 vpx_sub_pixel_variance16x32_c + +uint32_t vpx_sub_pixel_variance16x8_c(const uint8_t *src_ptr, int src_stride, int x_offset, int y_offset, const uint8_t *ref_ptr, int ref_stride, uint32_t *sse); +#define vpx_sub_pixel_variance16x8 vpx_sub_pixel_variance16x8_c + +uint32_t vpx_sub_pixel_variance32x16_c(const uint8_t *src_ptr, int src_stride, int x_offset, int y_offset, const uint8_t *ref_ptr, int ref_stride, uint32_t *sse); +#define vpx_sub_pixel_variance32x16 vpx_sub_pixel_variance32x16_c + +uint32_t vpx_sub_pixel_variance32x32_c(const uint8_t *src_ptr, int src_stride, int x_offset, int y_offset, const uint8_t *ref_ptr, int ref_stride, uint32_t *sse); +#define vpx_sub_pixel_variance32x32 vpx_sub_pixel_variance32x32_c + +uint32_t vpx_sub_pixel_variance32x64_c(const uint8_t *src_ptr, int src_stride, int x_offset, int y_offset, const uint8_t *ref_ptr, int ref_stride, uint32_t *sse); +#define vpx_sub_pixel_variance32x64 vpx_sub_pixel_variance32x64_c + +uint32_t vpx_sub_pixel_variance4x4_c(const uint8_t *src_ptr, int src_stride, int x_offset, int y_offset, const uint8_t *ref_ptr, int ref_stride, uint32_t *sse); +#define vpx_sub_pixel_variance4x4 vpx_sub_pixel_variance4x4_c + +uint32_t vpx_sub_pixel_variance4x8_c(const uint8_t *src_ptr, int src_stride, int x_offset, int y_offset, const uint8_t *ref_ptr, int ref_stride, uint32_t *sse); +#define vpx_sub_pixel_variance4x8 vpx_sub_pixel_variance4x8_c + +uint32_t vpx_sub_pixel_variance64x32_c(const uint8_t *src_ptr, int src_stride, int x_offset, int y_offset, const uint8_t *ref_ptr, int ref_stride, uint32_t *sse); +#define vpx_sub_pixel_variance64x32 vpx_sub_pixel_variance64x32_c + +uint32_t vpx_sub_pixel_variance64x64_c(const uint8_t *src_ptr, int src_stride, int x_offset, int y_offset, const uint8_t *ref_ptr, int ref_stride, uint32_t *sse); +#define vpx_sub_pixel_variance64x64 vpx_sub_pixel_variance64x64_c + +uint32_t vpx_sub_pixel_variance8x16_c(const uint8_t *src_ptr, int src_stride, int x_offset, int y_offset, const uint8_t *ref_ptr, int ref_stride, uint32_t *sse); +#define vpx_sub_pixel_variance8x16 vpx_sub_pixel_variance8x16_c + +uint32_t vpx_sub_pixel_variance8x4_c(const uint8_t *src_ptr, int src_stride, int x_offset, int y_offset, const uint8_t *ref_ptr, int ref_stride, uint32_t *sse); +#define vpx_sub_pixel_variance8x4 vpx_sub_pixel_variance8x4_c + +uint32_t vpx_sub_pixel_variance8x8_c(const uint8_t *src_ptr, int src_stride, int x_offset, int y_offset, const uint8_t *ref_ptr, int ref_stride, uint32_t *sse); +#define vpx_sub_pixel_variance8x8 vpx_sub_pixel_variance8x8_c + +void vpx_subtract_block_c(int rows, int cols, int16_t *diff_ptr, ptrdiff_t diff_stride, const uint8_t *src_ptr, ptrdiff_t src_stride, const uint8_t *pred_ptr, ptrdiff_t pred_stride); +#define vpx_subtract_block vpx_subtract_block_c + +uint64_t vpx_sum_squares_2d_i16_c(const int16_t *src, int stride, int size); +#define vpx_sum_squares_2d_i16 vpx_sum_squares_2d_i16_c + +void vpx_tm_predictor_16x16_c(uint8_t *dst, ptrdiff_t stride, const uint8_t *above, const uint8_t *left); +#define vpx_tm_predictor_16x16 vpx_tm_predictor_16x16_c + +void vpx_tm_predictor_32x32_c(uint8_t *dst, ptrdiff_t stride, const uint8_t *above, const uint8_t *left); +#define vpx_tm_predictor_32x32 vpx_tm_predictor_32x32_c + +void vpx_tm_predictor_4x4_c(uint8_t *dst, ptrdiff_t stride, const uint8_t *above, const uint8_t *left); +#define vpx_tm_predictor_4x4 vpx_tm_predictor_4x4_c + +void vpx_tm_predictor_8x8_c(uint8_t *dst, ptrdiff_t stride, const uint8_t *above, const uint8_t *left); +#define vpx_tm_predictor_8x8 vpx_tm_predictor_8x8_c + +void vpx_v_predictor_16x16_c(uint8_t *dst, ptrdiff_t stride, const uint8_t *above, const uint8_t *left); +#define vpx_v_predictor_16x16 vpx_v_predictor_16x16_c + +void vpx_v_predictor_32x32_c(uint8_t *dst, ptrdiff_t stride, const uint8_t *above, const uint8_t *left); +#define vpx_v_predictor_32x32 vpx_v_predictor_32x32_c + +void vpx_v_predictor_4x4_c(uint8_t *dst, ptrdiff_t stride, const uint8_t *above, const uint8_t *left); +#define vpx_v_predictor_4x4 vpx_v_predictor_4x4_c + +void vpx_v_predictor_8x8_c(uint8_t *dst, ptrdiff_t stride, const uint8_t *above, const uint8_t *left); +#define vpx_v_predictor_8x8 vpx_v_predictor_8x8_c + +unsigned int vpx_variance16x16_c(const uint8_t *src_ptr, int src_stride, const uint8_t *ref_ptr, int ref_stride, unsigned int *sse); +#define vpx_variance16x16 vpx_variance16x16_c + +unsigned int vpx_variance16x32_c(const uint8_t *src_ptr, int src_stride, const uint8_t *ref_ptr, int ref_stride, unsigned int *sse); +#define vpx_variance16x32 vpx_variance16x32_c + +unsigned int vpx_variance16x8_c(const uint8_t *src_ptr, int src_stride, const uint8_t *ref_ptr, int ref_stride, unsigned int *sse); +#define vpx_variance16x8 vpx_variance16x8_c + +unsigned int vpx_variance32x16_c(const uint8_t *src_ptr, int src_stride, const uint8_t *ref_ptr, int ref_stride, unsigned int *sse); +#define vpx_variance32x16 vpx_variance32x16_c + +unsigned int vpx_variance32x32_c(const uint8_t *src_ptr, int src_stride, const uint8_t *ref_ptr, int ref_stride, unsigned int *sse); +#define vpx_variance32x32 vpx_variance32x32_c + +unsigned int vpx_variance32x64_c(const uint8_t *src_ptr, int src_stride, const uint8_t *ref_ptr, int ref_stride, unsigned int *sse); +#define vpx_variance32x64 vpx_variance32x64_c + +unsigned int vpx_variance4x4_c(const uint8_t *src_ptr, int src_stride, const uint8_t *ref_ptr, int ref_stride, unsigned int *sse); +#define vpx_variance4x4 vpx_variance4x4_c + +unsigned int vpx_variance4x8_c(const uint8_t *src_ptr, int src_stride, const uint8_t *ref_ptr, int ref_stride, unsigned int *sse); +#define vpx_variance4x8 vpx_variance4x8_c + +unsigned int vpx_variance64x32_c(const uint8_t *src_ptr, int src_stride, const uint8_t *ref_ptr, int ref_stride, unsigned int *sse); +#define vpx_variance64x32 vpx_variance64x32_c + +unsigned int vpx_variance64x64_c(const uint8_t *src_ptr, int src_stride, const uint8_t *ref_ptr, int ref_stride, unsigned int *sse); +#define vpx_variance64x64 vpx_variance64x64_c + +unsigned int vpx_variance8x16_c(const uint8_t *src_ptr, int src_stride, const uint8_t *ref_ptr, int ref_stride, unsigned int *sse); +#define vpx_variance8x16 vpx_variance8x16_c + +unsigned int vpx_variance8x4_c(const uint8_t *src_ptr, int src_stride, const uint8_t *ref_ptr, int ref_stride, unsigned int *sse); +#define vpx_variance8x4 vpx_variance8x4_c + +unsigned int vpx_variance8x8_c(const uint8_t *src_ptr, int src_stride, const uint8_t *ref_ptr, int ref_stride, unsigned int *sse); +#define vpx_variance8x8 vpx_variance8x8_c + +void vpx_ve_predictor_4x4_c(uint8_t *dst, ptrdiff_t stride, const uint8_t *above, const uint8_t *left); +#define vpx_ve_predictor_4x4 vpx_ve_predictor_4x4_c + +int vpx_vector_var_c(const int16_t *ref, const int16_t *src, const int bwl); +#define vpx_vector_var vpx_vector_var_c + +void vpx_dsp_rtcd(void); + +#include "vpx_config.h" + +#ifdef RTCD_C +static void setup_rtcd_internal(void) +{ +} +#endif + +#ifdef __cplusplus +} // extern "C" +#endif + +#endif // VPX_DSP_RTCD_H_ +]==], + ["mcpp_generated/vpx_scale_rtcd.h"] = [==[ +/* + * Copyright (c) 2017 The WebM project authors. All Rights Reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. An additional intellectual property rights grant can be found + * in the file PATENTS. All contributing project authors may + * be found in the AUTHORS file in the root of the source tree. + */ + +// This file is generated. Do not edit. +#ifndef VPX_SCALE_RTCD_H_ +#define VPX_SCALE_RTCD_H_ + +#ifdef RTCD_C +#define RTCD_EXTERN +#else +#define RTCD_EXTERN extern +#endif + +struct yv12_buffer_config; + +#ifdef __cplusplus +extern "C" { +#endif + +void vp8_horizontal_line_2_1_scale_c(const unsigned char *source, unsigned int source_width, unsigned char *dest, unsigned int dest_width); +#define vp8_horizontal_line_2_1_scale vp8_horizontal_line_2_1_scale_c + +void vp8_horizontal_line_5_3_scale_c(const unsigned char *source, unsigned int source_width, unsigned char *dest, unsigned int dest_width); +#define vp8_horizontal_line_5_3_scale vp8_horizontal_line_5_3_scale_c + +void vp8_horizontal_line_5_4_scale_c(const unsigned char *source, unsigned int source_width, unsigned char *dest, unsigned int dest_width); +#define vp8_horizontal_line_5_4_scale vp8_horizontal_line_5_4_scale_c + +void vp8_vertical_band_2_1_scale_c(unsigned char *source, unsigned int src_pitch, unsigned char *dest, unsigned int dest_pitch, unsigned int dest_width); +#define vp8_vertical_band_2_1_scale vp8_vertical_band_2_1_scale_c + +void vp8_vertical_band_2_1_scale_i_c(unsigned char *source, unsigned int src_pitch, unsigned char *dest, unsigned int dest_pitch, unsigned int dest_width); +#define vp8_vertical_band_2_1_scale_i vp8_vertical_band_2_1_scale_i_c + +void vp8_vertical_band_5_3_scale_c(unsigned char *source, unsigned int src_pitch, unsigned char *dest, unsigned int dest_pitch, unsigned int dest_width); +#define vp8_vertical_band_5_3_scale vp8_vertical_band_5_3_scale_c + +void vp8_vertical_band_5_4_scale_c(unsigned char *source, unsigned int src_pitch, unsigned char *dest, unsigned int dest_pitch, unsigned int dest_width); +#define vp8_vertical_band_5_4_scale vp8_vertical_band_5_4_scale_c + +void vp8_yv12_copy_frame_c(const struct yv12_buffer_config *src_ybc, struct yv12_buffer_config *dst_ybc); +#define vp8_yv12_copy_frame vp8_yv12_copy_frame_c + +void vp8_yv12_extend_frame_borders_c(struct yv12_buffer_config *ybf); +#define vp8_yv12_extend_frame_borders vp8_yv12_extend_frame_borders_c + +void vpx_extend_frame_borders_c(struct yv12_buffer_config *ybf); +#define vpx_extend_frame_borders vpx_extend_frame_borders_c + +void vpx_extend_frame_inner_borders_c(struct yv12_buffer_config *ybf); +#define vpx_extend_frame_inner_borders vpx_extend_frame_inner_borders_c + +void vpx_yv12_copy_frame_c(const struct yv12_buffer_config *src_ybc, struct yv12_buffer_config *dst_ybc); +#define vpx_yv12_copy_frame vpx_yv12_copy_frame_c + +void vpx_yv12_copy_y_c(const struct yv12_buffer_config *src_ybc, struct yv12_buffer_config *dst_ybc); +#define vpx_yv12_copy_y vpx_yv12_copy_y_c + +void vpx_scale_rtcd(void); + +#include "vpx_config.h" + +#ifdef RTCD_C +static void setup_rtcd_internal(void) +{ +} +#endif + +#ifdef __cplusplus +} // extern "C" +#endif + +#endif // VPX_SCALE_RTCD_H_ +]==], + }, + + linux = { + include_dirs = { "mcpp_generated" }, + private_include_dirs = { "mcpp_generated" }, + -- Linked into shared objects by its consumers: position independent. + -- No contraction: a multiply-add fused or not is the same everywhere. + cflags = { "-fPIC", "-ffp-contract=off", "-D_GNU_SOURCE" }, + ldflags = { "-lm", "-lpthread" }, + }, + macosx = { + include_dirs = { "mcpp_generated" }, + private_include_dirs = { "mcpp_generated" }, + cflags = { "-fPIC", "-ffp-contract=off" }, + }, + -- No -fPIC: PE/COFF has no such distinction, and clang rejects it for + -- the MSVC target. + windows = { + include_dirs = { "mcpp_generated" }, + private_include_dirs = { "mcpp_generated" }, + cflags = { "-ffp-contract=off" }, + }, + + targets = { vpx = { kind = "lib" } }, + deps = {}, + }, +} diff --git a/pkgs/c/compat.libwebm.lua b/pkgs/c/compat.libwebm.lua new file mode 100644 index 00000000..d58c69fd --- /dev/null +++ b/pkgs/c/compat.libwebm.lua @@ -0,0 +1,90 @@ +-- compat.libwebm — libwebm 1.0.0.32, the WebM project's WebM (Matroska) +-- container library: the muxer (mkvmuxer) and the parser (mkvparser), +-- BSD-3-Clause. +-- +-- WebM is the royalty-free container of VP8, VP9 and AV1 video with Vorbis or +-- Opus sound, the one browsers play everywhere. mkvmuxer writes it: a +-- Segment over an IMkvWriter (MkvWriter: a file), video and audio tracks with +-- their codec private data and colour (BT.709, ranges, HDR metadata), frames +-- with their timestamps in nanoseconds, clusters and the cues an index needs +-- for seeking, the duration written back at the end. mkvparser reads it back +-- over an IMkvReader (MkvReader: a file; a consumer's own: memory): the EBML +-- header, the segment, its tracks, clusters, blocks and frames. +-- +-- ───────────────────────────────────────────────────────────────────────── +-- WHAT IS BUILT: UPSTREAM'S `webm` LIBRARY +-- +-- The archive is the libwebm-1.0.0.32 tag's (libwebm publishes no release +-- tarball). The sources are upstream CMakeLists.txt's `webm` target: its +-- common sources (common/file_util.cc, common/hdr_util.cc) and the objects +-- of mkvmuxer (mkvmuxer.cc, mkvmuxerutil.cc, mkvwriter.cc) and mkvparser +-- (mkvparser.cc, mkvreader.cc). Not built, as upstream does not by default: +-- the newer callback parser (webm_parser/, ENABLE_WEBM_PARSER), the MPEG-TS +-- tools (m2ts/), WebVTT and the sample programs. +-- +-- No configuration: libwebm has no config header and no generated files. +-- Consumers include upstream's layout from the archive root: +-- , , , +-- , . +-- +-- kind = "lib": a static library. +package = { + spec = "1", + namespace = "compat", + name = "libwebm", + description = "libwebm 1.0.0.32 — the WebM (Matroska) container: muxer and parser, BSD-3-Clause", + licenses = {"BSD-3-Clause"}, + repo = "https://github.com/webmproject/libwebm", + type = "package", + + extensions = { + autoupdate = { + tag = "libwebm-${version}", + url = "https://github.com/webmproject/libwebm/archive/refs/tags/${tag}.tar.gz", + }, + }, + + xpm = { + linux = { + ["1.0.0.32"] = { + url = "https://github.com/webmproject/libwebm/archive/refs/tags/libwebm-1.0.0.32.tar.gz", + sha256 = "7fd5e085bda9f8031cf2ad2a1e52d9b7b29cba9c0b96ad2ce794ce89e4249eb8", + }, + }, + macosx = { + ["1.0.0.32"] = { + url = "https://github.com/webmproject/libwebm/archive/refs/tags/libwebm-1.0.0.32.tar.gz", + sha256 = "7fd5e085bda9f8031cf2ad2a1e52d9b7b29cba9c0b96ad2ce794ce89e4249eb8", + }, + }, + windows = { + ["1.0.0.32"] = { + url = "https://github.com/webmproject/libwebm/archive/refs/tags/libwebm-1.0.0.32.tar.gz", + sha256 = "7fd5e085bda9f8031cf2ad2a1e52d9b7b29cba9c0b96ad2ce794ce89e4249eb8", + }, + }, + }, + + mcpp = { + language = "c++23", + import_std = false, + include_dirs = { "*" }, + + sources = { + "*/common/file_util.cc", + "*/common/hdr_util.cc", + "*/mkvmuxer/mkvmuxer.cc", + "*/mkvmuxer/mkvmuxerutil.cc", + "*/mkvmuxer/mkvwriter.cc", + "*/mkvparser/mkvparser.cc", + "*/mkvparser/mkvreader.cc", + }, + + linux = { cxxflags = { "-fPIC" } }, + macosx = { cxxflags = { "-fPIC" } }, + windows = { cxxflags = { "-D_CRT_SECURE_NO_WARNINGS" } }, + + targets = { webm = { kind = "lib" } }, + deps = {}, + }, +} diff --git a/tests/examples/libvpx/mcpp.toml b/tests/examples/libvpx/mcpp.toml new file mode 100644 index 00000000..49230255 --- /dev/null +++ b/tests/examples/libvpx/mcpp.toml @@ -0,0 +1,9 @@ +# compat.libvpx — VP9 frames encoded and decoded back, on every platform the +# descriptor declares. +[package] +name = "libvpx-tests" +version = "0.1.0" +standard = "c++23" + +[dependencies] +compat.libvpx = "1.17.0" diff --git a/tests/examples/libvpx/tests/libvpx.cpp b/tests/examples/libvpx/tests/libvpx.cpp new file mode 100644 index 00000000..c5debe0a --- /dev/null +++ b/tests/examples/libvpx/tests/libvpx.cpp @@ -0,0 +1,187 @@ +// compat.libvpx — VP9 end to end. +// +// WHAT THIS ASSERTS AND WHY +// +// Each check exercises a different part of the source list, so a file left +// out of the descriptor shows up as a link error or a wrong answer here: +// +// the versions vpx_codec_version_str, the generated vpx_version.h, +// vpx_codec_build_config (the generated vpx_config.c) +// one pass, good quality 24 frames of a moving gradient at constant quality, +// the first a key frame, decoded back by the VP9 +// decoder with a PSNR a correct codec reaches +// real time the same frames at speed 8 (vp9_pickmode, the +// cyclic-refresh aq), decoded back +// lossless every pixel back exactly (the WHT, lossless mode) +// reproducible one thread, the same settings: the same bytes twice +// threads four tile columns on four threads, decoded on two +// +// A pass means the encoder and the decoder agree with one another on this +// platform's build of each. + +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +namespace { + +int failures = 0; + +void check(bool ok, const char *what) +{ + std::printf("%-64s %s\n", what, ok ? "ok" : "FAILED"); + if (!ok) ++failures; +} + +constexpr int W = 320, H = 192, FRAMES = 24; + +// A gradient that moves and a square that crosses it: motion to predict, +// edges to keep. +void draw(vpx_image_t &img, int t) +{ + for (int y = 0; y < H; ++y) + for (int x = 0; x < W; ++x) { + int v = (x * 2 + y + t * 5) & 255; + if (x >= 40 + t * 8 && x < 80 + t * 8 && y >= 60 && y < 100) v = 235; + img.planes[0][y * img.stride[0] + x] = static_cast(v); + } + for (int y = 0; y < H / 2; ++y) + for (int x = 0; x < W / 2; ++x) { + img.planes[1][y * img.stride[1] + x] = static_cast(128 + ((x + t) & 31) - 16); + img.planes[2][y * img.stride[2] + x] = static_cast(128 - ((y + t) & 31) + 16); + } +} + +struct Encoded { + std::vector> packets; + std::vector keys; + bool ok = false; +}; + +Encoded encode(unsigned long deadline, int speed, bool lossless, int threads) +{ + Encoded out; + vpx_codec_enc_cfg_t cfg; + if (vpx_codec_enc_config_default(vpx_codec_vp9_cx(), &cfg, 0) != VPX_CODEC_OK) return out; + cfg.g_w = W; + cfg.g_h = H; + cfg.g_timebase = {1, 30}; + cfg.g_threads = threads; + cfg.g_lag_in_frames = 0; + cfg.rc_end_usage = VPX_Q; + cfg.kf_max_dist = 1000; + vpx_codec_ctx_t ctx; + if (vpx_codec_enc_init(&ctx, vpx_codec_vp9_cx(), &cfg, 0) != VPX_CODEC_OK) return out; + vpx_codec_control(&ctx, VP8E_SET_CPUUSED, speed); + vpx_codec_control(&ctx, VP8E_SET_CQ_LEVEL, 20); + if (lossless) vpx_codec_control(&ctx, VP9E_SET_LOSSLESS, 1); + if (threads > 1) vpx_codec_control(&ctx, VP9E_SET_TILE_COLUMNS, 2); + vpx_image_t img; + vpx_img_alloc(&img, VPX_IMG_FMT_I420, W, H, 16); + auto drain = [&] { + vpx_codec_iter_t it = nullptr; + while (const vpx_codec_cx_pkt_t *p = vpx_codec_get_cx_data(&ctx, &it)) { + if (p->kind != VPX_CODEC_CX_FRAME_PKT) continue; + const auto *b = static_cast(p->data.frame.buf); + out.packets.emplace_back(b, b + p->data.frame.sz); + out.keys.push_back((p->data.frame.flags & VPX_FRAME_IS_KEY) != 0); + } + }; + bool ok = true; + for (int t = 0; t < FRAMES; ++t) { + draw(img, t); + ok = ok && vpx_codec_encode(&ctx, &img, t, 1, 0, deadline) == VPX_CODEC_OK; + drain(); + } + ok = ok && vpx_codec_encode(&ctx, nullptr, FRAMES, 1, 0, deadline) == VPX_CODEC_OK; + drain(); + vpx_img_free(&img); + out.ok = ok && vpx_codec_destroy(&ctx) == VPX_CODEC_OK; + return out; +} + +// Decoded back: the lowest luma PSNR over the frames, and whether every pixel matched. +struct Decoded { + int frames = 0; + double worst_psnr = 1e9; + bool exact = true; +}; + +Decoded decode(const Encoded &e, int threads) +{ + Decoded d; + vpx_codec_ctx_t ctx; + vpx_codec_dec_cfg_t cfg{}; + cfg.threads = threads; + if (vpx_codec_dec_init(&ctx, vpx_codec_vp9_dx(), &cfg, 0) != VPX_CODEC_OK) return d; + vpx_image_t ref; + vpx_img_alloc(&ref, VPX_IMG_FMT_I420, W, H, 16); + for (const auto &p : e.packets) { + if (vpx_codec_decode(&ctx, p.data(), static_cast(p.size()), nullptr, 0) != VPX_CODEC_OK) return d; + vpx_codec_iter_t it = nullptr; + while (vpx_image_t *img = vpx_codec_get_frame(&ctx, &it)) { + draw(ref, d.frames); + double se = 0; + for (int plane = 0; plane < 3; ++plane) { + const int pw = plane ? W / 2 : W, ph = plane ? H / 2 : H; + for (int y = 0; y < ph; ++y) + for (int x = 0; x < pw; ++x) { + const int a = img->planes[plane][y * img->stride[plane] + x]; + const int b = ref.planes[plane][y * ref.stride[plane] + x]; + if (a != b) d.exact = false; + if (plane == 0) se += double(a - b) * (a - b); + } + } + const double mse = se / (W * H); + const double psnr = mse == 0 ? 99 : 10 * std::log10(255.0 * 255.0 / mse); + if (psnr < d.worst_psnr) d.worst_psnr = psnr; + ++d.frames; + } + } + vpx_img_free(&ref); + vpx_codec_destroy(&ctx); + return d; +} + +} // namespace + +int main() +{ + std::printf("%s / %s\n", vpx_codec_version_str(), vpx_codec_build_config()); + check(std::string(vpx_codec_version_str()) == "v1.17.0", "vpx_codec_version_str is v1.17.0 (the generated vpx_version.h)"); + check(std::string(vpx_codec_build_config()).find("--target=generic-gnu") != std::string::npos, "vpx_codec_build_config (the generated vpx_config.c)"); + check(std::string(vpx_codec_iface_name(vpx_codec_vp9_cx())).find("VP9 Encoder") != std::string::npos, "the VP9 encoder interface"); + + const Encoded good = encode(VPX_DL_GOOD_QUALITY, 4, false, 1); + check(good.ok && good.packets.size() == FRAMES && good.keys.front() && !good.keys.back(), "good quality: a packet a frame, the first a key frame"); + const Decoded gd = decode(good, 1); + std::printf(" good: %zu packets, worst PSNR %.2f dB\n", good.packets.size(), gd.worst_psnr); + check(gd.frames == FRAMES && gd.worst_psnr > 38, "good quality decoded back above 38 dB"); + + const Encoded rt = encode(VPX_DL_REALTIME, 8, false, 1); + const Decoded rd = decode(rt, 1); + std::printf(" real time: worst PSNR %.2f dB\n", rd.worst_psnr); + check(rt.ok && rd.frames == FRAMES && rd.worst_psnr > 30, "real time (speed 8) decoded back above 30 dB"); + + const Encoded ll = encode(VPX_DL_GOOD_QUALITY, 4, true, 1); + const Decoded ld = decode(ll, 1); + check(ll.ok && ld.frames == FRAMES && ld.exact, "lossless: every pixel back exactly"); + + const Encoded again = encode(VPX_DL_GOOD_QUALITY, 4, false, 1); + check(again.packets == good.packets, "one thread: the same bytes twice"); + + const Encoded mt = encode(VPX_DL_GOOD_QUALITY, 5, false, 4); + const Decoded md = decode(mt, 2); + check(mt.ok && md.frames == FRAMES && md.worst_psnr > 36, "four threads and tile columns, decoded on two"); + + std::printf("%s\n", failures ? "FAILED" : "all passed"); + return failures ? 1 : 0; +} diff --git a/tests/examples/libwebm/mcpp.toml b/tests/examples/libwebm/mcpp.toml new file mode 100644 index 00000000..0ba82c21 --- /dev/null +++ b/tests/examples/libwebm/mcpp.toml @@ -0,0 +1,9 @@ +# compat.libwebm — a WebM file written with mkvmuxer and read back with +# mkvparser, on every platform the descriptor declares. +[package] +name = "libwebm-tests" +version = "0.1.0" +standard = "c++23" + +[dependencies] +compat.libwebm = "1.0.0.32" diff --git a/tests/examples/libwebm/tests/libwebm.cpp b/tests/examples/libwebm/tests/libwebm.cpp new file mode 100644 index 00000000..ddd2e68e --- /dev/null +++ b/tests/examples/libwebm/tests/libwebm.cpp @@ -0,0 +1,232 @@ +// compat.libwebm — a WebM file written and read back. +// +// WHAT THIS ASSERTS AND WHY +// +// the muxer mkvmuxer::Segment over a writer of our own (memory, seekable): +// a VP9 video track with its colour (BT.709, limited range), an +// Opus audio track with its codec private data and delay, frames +// at their nanosecond timestamps, key frames, cues, the duration +// written back at the end (mkvmuxer.cc, mkvmuxerutil.cc) +// the writer mkvmuxer::MkvWriter: the same file written to disk +// (mkvwriter.cc), byte for byte the memory one +// the parser mkvparser over a reader of our own (memory) and over +// MkvReader (the file; mkvreader.cc): the EBML header's doc +// type, the tracks, their codecs, colour and private data, +// every frame in order with its time, track and bytes, the +// cues, the duration (mkvparser.cc) +// hdr_util the colour read back into mkvmuxer's form (common/hdr_util.cc) +// reproducible the same frames and track UIDs twice: the same bytes +// +// A pass means the muxer and the parser agree with one another. + +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +namespace { + +int failures = 0; + +void check(bool ok, const char *what) +{ + std::printf("%-64s %s\n", what, ok ? "ok" : "FAILED"); + if (!ok) ++failures; +} + +class MemoryWriter : public mkvmuxer::IMkvWriter { +public: + std::vector bytes; + std::int64_t at = 0; + mkvmuxer::int32 Write(const void *buf, mkvmuxer::uint32 len) override + { + if (bytes.size() < static_cast(at) + len) bytes.resize(static_cast(at) + len); + std::memcpy(bytes.data() + at, buf, len); + at += len; + return 0; + } + mkvmuxer::int64 Position() const override { return at; } + mkvmuxer::int32 Position(mkvmuxer::int64 position) override + { + at = position; + return 0; + } + bool Seekable() const override { return true; } + void ElementStartNotify(mkvmuxer::uint64, mkvmuxer::int64) override {} +}; + +class MemoryReader : public mkvparser::IMkvReader { +public: + explicit MemoryReader(const std::vector &b) : bytes(b) {} + int Read(long long pos, long len, unsigned char *buf) override + { + if (pos < 0 || len < 0 || static_cast(pos + len) > bytes.size()) return -1; + std::memcpy(buf, bytes.data() + pos, static_cast(len)); + return 0; + } + int Length(long long *total, long long *available) override + { + if (total) *total = static_cast(bytes.size()); + if (available) *available = static_cast(bytes.size()); + return 0; + } + const std::vector &bytes; +}; + +constexpr int FRAMES = 30; // a second at 30 fps +constexpr std::uint64_t FRAME_NS = 1000000000ull / 30; +constexpr std::uint64_t PACKET_NS = 20000000ull; // Opus: 20 ms + +std::vector payload(int track, int i) +{ + std::vector p(static_cast(40 + (i * 37) % 200)); + for (std::size_t k = 0; k < p.size(); ++k) p[k] = static_cast(track * 91 + i * 13 + static_cast(k)); + return p; +} + +bool mux(mkvmuxer::IMkvWriter &w) +{ + mkvmuxer::Segment segment; + if (!segment.Init(&w)) return false; + segment.set_mode(mkvmuxer::Segment::kFile); + segment.OutputCues(true); + segment.GetSegmentInfo()->set_writing_app("libwebm-tests"); + segment.GetSegmentInfo()->set_muxing_app("libwebm-tests"); + const mkvmuxer::uint64 video = segment.AddVideoTrack(320, 192, 1); + const mkvmuxer::uint64 audio = segment.AddAudioTrack(48000, 2, 2); + auto *v = static_cast(segment.GetTrackByNumber(video)); + auto *a = static_cast(segment.GetTrackByNumber(audio)); + if (!v || !a) return false; + // Track UIDs are random (seeded by the time) unless given: given, the bytes are reproducible. + v->set_uid(0x1234567890abcdull); + a->set_uid(0x0fedcba0987654ull); + v->set_codec_id(mkvmuxer::Tracks::kVp9CodecId); + v->set_frame_rate(30.0); + mkvmuxer::Colour colour; + colour.set_matrix_coefficients(mkvmuxer::Colour::kBt709); + colour.set_range(mkvmuxer::Colour::kBroadcastRange); + colour.set_transfer_characteristics(mkvmuxer::Colour::kIturBt709Tc); + colour.set_primaries(mkvmuxer::Colour::kIturBt709P); + if (!v->SetColour(colour)) return false; + a->set_codec_id(mkvmuxer::Tracks::kOpusCodecId); + const unsigned char head[19] = {'O', 'p', 'u', 's', 'H', 'e', 'a', 'd', 1, 2, 0x38, 0x01, 0x80, 0xbb, 0, 0, 0, 0, 0}; + if (!a->SetCodecPrivate(head, sizeof head)) return false; + a->set_codec_delay(6500000); + a->set_seek_pre_roll(80000000); + segment.CuesTrack(video); + // Interleaved by time, as a muxer must be given them. + int vi = 0, ai = 0; + while (vi < FRAMES || ai < 50) { + const std::uint64_t vt = vi * FRAME_NS, at = ai * PACKET_NS; + if (vi < FRAMES && (ai >= 50 || vt <= at)) { + const auto p = payload(1, vi); + if (!segment.AddFrame(p.data(), p.size(), video, vt, vi % 10 == 0)) return false; + ++vi; + } else { + const auto p = payload(2, ai); + if (!segment.AddFrame(p.data(), p.size(), audio, at, true)) return false; + ++ai; + } + } + segment.set_duration(1000.0); // in the segment's timecode scale: milliseconds + return segment.Finalize(); +} + +} // namespace + +int main() +{ + MemoryWriter w; + check(mux(w) && !w.bytes.empty(), "mkvmuxer: a VP9 and an Opus track, 30 frames and 50 packets"); + MemoryWriter again; + check(mux(again) && again.bytes == w.bytes, "the same frames twice: the same bytes"); + + const std::string file = "libwebm-test.webm"; + { + mkvmuxer::MkvWriter disk; + check(disk.Open(file.c_str()) && mux(disk), "mkvmuxer::MkvWriter: the same file on disk"); + disk.Close(); + } + { + std::FILE *f = std::fopen(file.c_str(), "rb"); + std::vector b; + if (f) { + unsigned char buf[4096]; + std::size_t n; + while ((n = std::fread(buf, 1, sizeof buf, f)) > 0) b.insert(b.end(), buf, buf + n); + std::fclose(f); + } + check(b == w.bytes, "the file is byte for byte the memory one"); + } + + MemoryReader reader(w.bytes); + long long pos = 0; + mkvparser::EBMLHeader ebml; + check(ebml.Parse(&reader, pos) == 0 && std::string(ebml.m_docType) == "webm", "mkvparser: the EBML header, doc type webm"); + mkvparser::Segment *segment = nullptr; + check(mkvparser::Segment::CreateInstance(&reader, pos, segment) == 0 && segment && segment->Load() == 0, "the segment loads"); + if (!segment) return 1; + const mkvparser::Tracks *tracks = segment->GetTracks(); + check(tracks && tracks->GetTracksCount() == 2, "two tracks"); + const auto *v = static_cast(tracks->GetTrackByNumber(1)); + const auto *a = static_cast(tracks->GetTrackByNumber(2)); + check(v && std::string(v->GetCodecId()) == "V_VP9" && v->GetWidth() == 320 && v->GetHeight() == 192, "the video track: V_VP9, 320 x 192"); + check(v && v->GetColour() && v->GetColour()->matrix_coefficients == mkvmuxer::Colour::kBt709 && + v->GetColour()->range == mkvmuxer::Colour::kBroadcastRange, + "its colour: BT.709, broadcast range"); + mkvmuxer::Colour back; + check(v && v->GetColour() && libwebm::CopyColour(*v->GetColour(), &back) && back.matrix_coefficients() == mkvmuxer::Colour::kBt709, + "hdr_util: the colour copied back into the muxer's form"); + size_t private_size = 0; + const unsigned char *priv = a ? a->GetCodecPrivate(private_size) : nullptr; + check(a && std::string(a->GetCodecId()) == "A_OPUS" && a->GetSamplingRate() == 48000 && a->GetChannels() == 2 && private_size == 19 && + std::memcmp(priv, "OpusHead", 8) == 0 && a->GetCodecDelay() == 6500000, + "the audio track: A_OPUS, 48 kHz stereo, OpusHead, the codec delay"); + + int vframes = 0, aframes = 0, keys = 0; + bool payloads = true, order = true; + long long last = -1; + for (const mkvparser::Cluster *c = segment->GetFirst(); c && !c->EOS(); c = segment->GetNext(c)) { + const mkvparser::BlockEntry *e = nullptr; + if (c->GetFirst(e) != 0) break; + while (e && !e->EOS()) { + const mkvparser::Block *b = e->GetBlock(); + const long long t = b->GetTime(c); + order = order && t >= last; + last = t; + const int n = b->GetTrackNumber() == 1 ? vframes++ : aframes++; + if (b->GetTrackNumber() == 1 && b->IsKey()) ++keys; + const mkvparser::Block::Frame &f = b->GetFrame(0); + std::vector data(static_cast(f.len)); + payloads = payloads && f.Read(&reader, data.data()) == 0 && data == payload(static_cast(b->GetTrackNumber()), n) && + t == static_cast(b->GetTrackNumber() == 1 ? n * FRAME_NS : n * PACKET_NS) / 1000000 * 1000000; + if (c->GetNext(e, e) != 0) break; + } + } + check(vframes == FRAMES && aframes == 50, "every frame and packet read back"); + check(payloads, "each with its bytes and its time (milliseconds)"); + check(order && keys == 3, "in time order, the key frames where they were"); + check(segment->GetCues() && segment->GetInfo()->GetDuration() > 0, "the cues and the duration"); + delete segment; + + mkvparser::MkvReader disk; + long long pos2 = 0; + mkvparser::EBMLHeader h2; + mkvparser::Segment *s2 = nullptr; + check(disk.Open(file.c_str()) == 0 && h2.Parse(&disk, pos2) == 0 && mkvparser::Segment::CreateInstance(&disk, pos2, s2) == 0 && s2 && s2->Load() == 0 && + s2->GetTracks()->GetTracksCount() == 2, + "mkvparser::MkvReader: the file read back"); + delete s2; + disk.Close(); + std::remove(file.c_str()); + + std::printf("%s\n", failures ? "FAILED" : "all passed"); + return failures ? 1 : 0; +}