Merge pull request #485 from signalwire/images

Update libvpx to 1.8.1 and libyuv to ea23edfb
This commit is contained in:
Andrey Volk 2020-03-06 21:41:23 +04:00 committed by GitHub
commit 43df2e1c2e
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
877 changed files with 95177 additions and 50635 deletions

View File

@ -4,12 +4,13 @@
Aaron Watry <awatry@gmail.com>
Abo Talib Mahfoodh <ab.mahfoodh@gmail.com>
Adrian Grange <agrange@google.com>
Aex Converse <aconverse@google.com>
Ahmad Sharif <asharif@google.com>
Aidan Welch <aidansw@yahoo.com>
Aleksey Vasenev <margtu-fivt@ya.ru>
Alexander Potapenko <glider@google.com>
Alexander Voronov <avoronov@graphics.cs.msu.ru>
Alexandra Hájková <alexandra.khirnova@gmail.com>
Aex Converse <aconverse@google.com>
Alexis Ballier <aballier@gentoo.org>
Alok Ahuja <waveletcoeff@gmail.com>
Alpha Lam <hclam@google.com>
@ -26,11 +27,13 @@ Brion Vibber <bvibber@wikimedia.org>
changjun.yang <changjun.yang@intel.com>
Charles 'Buck' Krasic <ckrasic@google.com>
Cheng Chen <chengchen@google.com>
Chi Yo Tsai <chiyotsai@google.com>
chm <chm@rock-chips.com>
Chris Cunningham <chcunningham@chromium.org>
Christian Duvivier <cduvivier@google.com>
Daniele Castagna <dcastagna@chromium.org>
Daniel Kang <ddkang@google.com>
Dan Zhu <zxdan@google.com>
Deb Mukherjee <debargha@google.com>
Deepa K G <deepa.kg@ittiam.com>
Dim Temp <dimtemp0@gmail.com>
@ -38,11 +41,13 @@ Dmitry Kovalev <dkovalev@google.com>
Dragan Mrdjan <dmrdjan@mips.com>
Ed Baker <edward.baker@intel.com>
Ehsan Akhgari <ehsan.akhgari@gmail.com>
Elliott Karpilovsky <elliottk@google.com>
Erik Niemeyer <erik.a.niemeyer@intel.com>
Fabio Pedretti <fabio.ped@libero.it>
Frank Galligan <fgalligan@google.com>
Fredrik Söderquist <fs@opera.com>
Fritz Koenig <frkoenig@google.com>
Fyodor Kyslov <kyslov@google.com>
Gabriel Marin <gmx@chromium.org>
Gaute Strokkenes <gaute.strokkenes@broadcom.com>
Geza Lore <gezalore@gmail.com>
@ -55,7 +60,9 @@ Guillermo Ballester Valor <gbvalor@gmail.com>
Hangyu Kuang <hkuang@google.com>
Hanno Böck <hanno@hboeck.de>
Han Shen <shenhan@google.com>
Harish Mahendrakar <harish.mahendrakar@ittiam.com>
Henrik Lundin <hlundin@google.com>
Hien Ho <hienho@google.com>
Hui Su <huisu@google.com>
Ivan Krasin <krasin@chromium.org>
Ivan Maltz <ivanmaltz@google.com>
@ -81,6 +88,7 @@ Johann Koenig <johannkoenig@google.com>
John Koleszar <jkoleszar@google.com>
Johnny Klonaris <google@jawknee.com>
John Stark <jhnstrk@gmail.com>
Jon Kunkee <jkunkee@microsoft.com>
Joshua Bleecher Snyder <josh@treelinelabs.com>
Joshua Litt <joshualitt@google.com>
Julia Robson <juliamrobson@gmail.com>
@ -91,15 +99,19 @@ KO Myung-Hun <komh@chollian.net>
Kyle Siefring <kylesiefring@gmail.com>
Lawrence Velázquez <larryv@macports.org>
Linfeng Zhang <linfengz@google.com>
Liu Peng <pengliu.mail@gmail.com>
Lou Quillio <louquillio@google.com>
Luca Barbato <lu_zero@gentoo.org>
Luc Trudeau <luc@trud.ca>
Makoto Kato <makoto.kt@gmail.com>
Mans Rullgard <mans@mansr.com>
Marco Paniconi <marpan@google.com>
Mark Mentovai <mark@chromium.org>
Martin Ettl <ettl.martin78@googlemail.com>
Martin Storsjo <martin@martin.st>
Martin Storsjö <martin@martin.st>
Matthew Heaney <matthewjheaney@chromium.org>
Matthias Räncker <theonetruecamper@gmx.de>
Michael Horowitz <mhoro@webrtc.org>
Michael Kohler <michaelkohler@live.com>
Mike Frysinger <vapier@chromium.org>
Mike Hommey <mhommey@mozilla.com>
@ -107,10 +119,12 @@ Mikhal Shemer <mikhal@google.com>
Min Chen <chenm003@gmail.com>
Minghai Shang <minghai@google.com>
Min Ye <yeemmi@google.com>
Mirko Bonadei <mbonadei@google.com>
Moriyoshi Koizumi <mozo@mozo.jp>
Morton Jonuschat <yabawock@gmail.com>
Nathan E. Egge <negge@mozilla.com>
Nico Weber <thakis@chromium.org>
Niveditha Rau <niveditha.rau@gmail.com>
Parag Salasakar <img.mips1@gmail.com>
Pascal Massimino <pascal.massimino@gmail.com>
Patrik Westin <patrik.westin@gmail.com>
@ -129,9 +143,13 @@ Rafael de Lucena Valle <rafaeldelucena@gmail.com>
Rahul Chaudhry <rahulchaudhry@google.com>
Ralph Giles <giles@xiph.org>
Ranjit Kumar Tulabandu <ranjit.tulabandu@ittiam.com>
Raphael Kubo da Costa <raphael.kubo.da.costa@intel.com>
Ravi Chaudhary <ravi.chaudhary@ittiam.com>
Ritu Baldwa <ritu.baldwa@ittiam.com>
Rob Bradford <rob@linux.intel.com>
Ronald S. Bultje <rsbultje@gmail.com>
Rui Ueyama <ruiu@google.com>
Sai Deng <sdeng@google.com>
Sami Pietilä <samipietila@google.com>
Sarah Parker <sarahparker@google.com>
Sasi Inguva <isasi@google.com>
@ -139,12 +157,15 @@ Scott Graham <scottmg@chromium.org>
Scott LaVarnway <slavarnway@google.com>
Sean McGovern <gseanmcg@gmail.com>
Sergey Kolomenkin <kolomenkin@gmail.com>
Sergey Silkin <ssilkin@google.com>
Sergey Ulanov <sergeyu@chromium.org>
Shimon Doodkin <helpmepro1@gmail.com>
Shiyou Yin <yinshiyou-hf@loongson.cn>
Shubham Tandle <shubham.tandle@ittiam.com>
Shunyao Li <shunyaoli@google.com>
Stefan Holmer <holmer@google.com>
Suman Sunkara <sunkaras@google.com>
Supradeep T R <supradeep.tr@ittiam.com>
Sylvestre Ledru <sylvestre@mozilla.com>
Taekhyun Kim <takim@nvidia.com>
Takanori MATSUURA <t.matsuu@gmail.com>
@ -157,11 +178,15 @@ Timothy B. Terriberry <tterribe@xiph.org>
Tom Finegan <tomfinegan@google.com>
Tristan Matthews <le.businessman@gmail.com>
Urvang Joshi <urvang@google.com>
Venkatarama NG. Avadhani <venkatarama.avadhani@ittiam.com>
Vignesh Venkatasubramanian <vigneshv@google.com>
Vlad Tsyrklevich <vtsyrklevich@chromium.org>
Wan-Teh Chang <wtc@google.com>
xiwei gu <guxiwei-hf@loongson.cn>
Yaowu Xu <yaowu@google.com>
Yi Luo <luoyi@google.com>
Yongzhe Wang <yongzhe@google.com>
Yue Chen <yuec@google.com>
Yunqing Wang <yunqingwang@google.com>
Yury Gitman <yuryg@google.com>
Zoe Liu <zoeliu@google.com>

View File

@ -1,4 +1,63 @@
2017-01-04 v1.7.0 "Mandarin Duck"
2019-07-15 v1.8.1 "Orpington Duck"
This release collects incremental improvements to many aspects of the library.
- Upgrading:
VP8E_SET_CPUUSED now accepts values up to 9 for vp9.
VPX_CTRL_VP9E_SET_MAX_INTER_BITRATE_PCT had a spelling fix (was VP8E).
The --sdk-path option has been removed. If you were using it to build for
Android please read build/make/Android.mk for alternatives.
All PPC optimizations have been disabled:
https://bugs.chromium.org/p/webm/issues/detail?id=1522.
- Enhancements:
Various changes to improve encoder rate control, quality and speed
for practically every use case.
- Bug fixes:
vp9-rtc: Fix color artifacts for speed >= 8.
2019-01-31 v1.8.0 "Northern Shoveler Duck"
This release focused on encoding performance for realtime and VOD use cases.
- Upgrading:
This adds and improves several vp9 controls. Most are related to SVC:
VP9E_SET_SVC_FRAME_DROP_LAYER:
- Frame dropping in SVC.
VP9E_SET_SVC_INTER_LAYER_PRED:
- Inter-layer prediction in SVC.
VP9E_SET_SVC_GF_TEMPORAL_REF:
- Enable long term temporal reference in SVC.
VP9E_SET_SVC_REF_FRAME_CONFIG/VP9E_GET_SVC_REF_FRAME_CONFIG:
- Extend and improve this control for better flexibility in setting SVC
pattern dynamically.
VP9E_SET_POSTENCODE_DROP:
- Allow for post-encode frame dropping (applies to non-SVC too).
VP9E_SET_SVC_SPATIAL_LAYER_SYNC:
- Enable spatial layer sync frames.
VP9E_SET_SVC_LAYER_ID:
- Extend api to specify temporal id for each spatial layers.
VP9E_SET_ROI_MAP:
- Extend Region of Interest functionality to VP9.
- Enhancements:
2 pass vp9 encoding has improved substantially. When using --auto-alt-ref=6,
we see approximately 8% for VBR and 10% for CQ. When using --auto-alt-ref=1,
the gains are approximately 4% for VBR and 5% for CQ.
For real-time encoding, speed 7 has improved by ~5-10%. Encodes targeted at
screen sharing have improved when the content changes significantly (slide
sharing) or scrolls. There is a new speed 9 setting for mobile devices which
is about 10-20% faster than speed 8.
- Bug fixes:
VP9 denoiser issue.
VP9 partition issue for 1080p.
VP9 rate control improvments.
Postprocessing Multi Frame Quality Enhancement (MFQE) issue.
VP8 multithread decoder issues.
A variety of fuzzing issues.
2018-01-04 v1.7.0 "Mandarin Duck"
This release focused on high bit depth performance (10/12 bit) and vp9
encoding improvements.

View File

@ -1,4 +1,4 @@
README - 24 January 2018
README - 15 July 2019
Welcome to the WebM VP8/VP9 Codec SDK!
@ -9,22 +9,26 @@ COMPILING THE APPLICATIONS/LIBRARIES:
1. Prerequisites
* All x86 targets require the Yasm[1] assembler be installed.
* All Windows builds require that Cygwin[2] be installed.
* Building the documentation requires Doxygen[3]. If you do not
* All x86 targets require the Yasm[1] assembler be installed[2].
* All Windows builds require that Cygwin[3] be installed.
* Building the documentation requires Doxygen[4]. If you do not
have this package, the install-docs option will be disabled.
* Downloading the data for the unit tests requires curl[4] and sha1sum.
* Downloading the data for the unit tests requires curl[5] and sha1sum.
sha1sum is provided via the GNU coreutils, installed by default on
many *nix platforms, as well as MinGW and Cygwin. If coreutils is not
available, a compatible version of sha1sum can be built from
source[5]. These requirements are optional if not running the unit
source[6]. These requirements are optional if not running the unit
tests.
[1]: http://www.tortall.net/projects/yasm
[2]: http://www.cygwin.com
[3]: http://www.doxygen.org
[4]: http://curl.haxx.se
[5]: http://www.microbrew.org/tools/md5sha1sum/
[2]: For Visual Studio the base yasm binary (not vsyasm) should be in the
PATH for Visual Studio. For VS2017 it is sufficient to rename
yasm-<version>-<arch>.exe to yasm.exe and place it in:
Program Files (x86)/Microsoft Visual Studio/2017/<level>/Common7/Tools/
[3]: http://www.cygwin.com
[4]: http://www.doxygen.org
[5]: http://curl.haxx.se
[6]: http://www.microbrew.org/tools/md5sha1sum/
2. Out-of-tree builds
Out of tree builds are a supported method of building the application. For
@ -41,7 +45,16 @@ COMPILING THE APPLICATIONS/LIBRARIES:
used to get a list of supported options:
$ ../libvpx/configure --help
4. Cross development
4. Compiler analyzers
Compilers have added sanitizers which instrument binaries with information
about address calculation, memory usage, threading, undefined behavior, and
other common errors. To simplify building libvpx with some of these features
use tools/set_analyzer_env.sh before running configure. It will set the
compiler and necessary flags for building as well as environment variables
read by the analyzer when testing the binaries.
$ source ../libvpx/tools/set_analyzer_env.sh address
5. Cross development
For cross development, the most notable option is the --target option. The
most up-to-date list of supported targets can be found at the bottom of the
--help output of the configure script. As of this writing, the list of
@ -50,20 +63,20 @@ COMPILING THE APPLICATIONS/LIBRARIES:
arm64-android-gcc
arm64-darwin-gcc
arm64-linux-gcc
arm64-win64-gcc
arm64-win64-vs15
armv7-android-gcc
armv7-darwin-gcc
armv7-linux-rvct
armv7-linux-gcc
armv7-none-rvct
armv7-win32-vs11
armv7-win32-vs12
armv7-win32-gcc
armv7-win32-vs14
armv7-win32-vs15
armv7s-darwin-gcc
armv8-linux-gcc
mips32-linux-gcc
mips64-linux-gcc
ppc64-linux-gcc
ppc64le-linux-gcc
sparc-solaris-gcc
x86-android-gcc
@ -78,15 +91,13 @@ COMPILING THE APPLICATIONS/LIBRARIES:
x86-darwin14-gcc
x86-darwin15-gcc
x86-darwin16-gcc
x86-darwin17-gcc
x86-iphonesimulator-gcc
x86-linux-gcc
x86-linux-icc
x86-os2-gcc
x86-solaris-gcc
x86-win32-gcc
x86-win32-vs10
x86-win32-vs11
x86-win32-vs12
x86-win32-vs14
x86-win32-vs15
x86_64-android-gcc
@ -98,14 +109,12 @@ COMPILING THE APPLICATIONS/LIBRARIES:
x86_64-darwin14-gcc
x86_64-darwin15-gcc
x86_64-darwin16-gcc
x86_64-darwin17-gcc
x86_64-iphonesimulator-gcc
x86_64-linux-gcc
x86_64-linux-icc
x86_64-solaris-gcc
x86_64-win64-gcc
x86_64-win64-vs10
x86_64-win64-vs11
x86_64-win64-vs12
x86_64-win64-vs14
x86_64-win64-vs15
generic-gnu
@ -123,7 +132,7 @@ COMPILING THE APPLICATIONS/LIBRARIES:
environment variables: CC, AR, LD, AS, STRIP, NM. Additional flags can be
passed to these executables with CFLAGS, LDFLAGS, and ASFLAGS.
5. Configuration errors
6. Configuration errors
If the configuration step fails, the first step is to look in the error log.
This defaults to config.log. This should give a good indication of what went
wrong. If not, contact us for support.

View File

@ -8,8 +8,8 @@
* be found in the AUTHORS file in the root of the source tree.
*/
#ifndef ARGS_H_
#define ARGS_H_
#ifndef VPX_ARGS_H_
#define VPX_ARGS_H_
#include <stdio.h>
#ifdef __cplusplus
@ -60,4 +60,4 @@ int arg_parse_enum_or_int(const struct arg *arg);
} // extern "C"
#endif
#endif // ARGS_H_
#endif // VPX_ARGS_H_

View File

@ -1,2 +0,0 @@
*-vs8/*.rules -crlf
*-msvs/*.rules -crlf

View File

@ -1 +0,0 @@
x86*-win32-vs*

View File

@ -14,7 +14,7 @@
# Run the configure script from the jni directory. Base libvpx
# encoder/decoder configuration will look similar to:
# ./libvpx/configure --target=armv7-android-gcc --disable-examples \
# --sdk-path=/opt/android-ndk-r6b/
# --enable-external-build
#
# When targeting Android, realtime-only is enabled by default. This can
# be overridden by adding the command line flag:
@ -29,37 +29,20 @@
# include $(CLEAR_VARS)
# include jni/libvpx/build/make/Android.mk
#
# By default libvpx will detect at runtime the existance of NEON extension.
# For this we import the 'cpufeatures' module from the NDK sources.
# libvpx can also be configured without this runtime detection method.
# Configuring with --disable-runtime-cpu-detect will assume presence of NEON.
# Configuring with --disable-runtime-cpu-detect --disable-neon \
# --disable-neon-asm
# will remove any NEON dependency.
# By default libvpx will use the 'cpufeatures' module from the NDK. This allows
# the library to be built with all available optimizations (SSE2->AVX512 for
# x86, NEON for arm, DSPr2 for mips). This can be disabled with
# --disable-runtime-cpu-detect
# but the resulting library *must* be run on devices supporting all of the
# enabled extensions. They can be disabled individually with
# --disable-{sse2, sse3, ssse3, sse4_1, avx, avx2, avx512}
# --disable-neon[-asm]
# --disable-{dspr2, msa}
#
# Running ndk-build will build libvpx and include it in your project.
#
# Alternatively, building the examples and unit tests can be accomplished in the
# following way:
#
# Create a standalone toolchain from the NDK:
# https://developer.android.com/ndk/guides/standalone_toolchain.html
#
# For example - to test on arm64 devices with clang:
# $NDK/build/tools/make_standalone_toolchain.py \
# --arch arm64 --install-dir=/tmp/my-android-toolchain
# export PATH=/tmp/my-android-toolchain/bin:$PATH
# CROSS=aarch64-linux-android- CC=clang CXX=clang++ /path/to/libvpx/configure \
# --target=arm64-android-gcc
#
# Push the resulting binaries to a device and run them:
# adb push test_libvpx /data/tmp/test_libvpx
# adb shell /data/tmp/test_libvpx --gtest_filter=\*Sixtap\*
#
# Make sure to push the test data as well and set LIBVPX_TEST_DATA
CONFIG_DIR := $(LOCAL_PATH)/
LIBVPX_PATH := $(LOCAL_PATH)/libvpx
ASM_CNV_PATH_LOCAL := $(TARGET_ARCH_ABI)/ads2gas

View File

@ -99,6 +99,7 @@ distclean: clean
rm -f Makefile; \
rm -f config.log config.mk; \
rm -f vpx_config.[hc] vpx_config.asm; \
rm -f arm_neon.h; \
else \
rm -f $(target)-$(TOOLCHAIN).mk; \
fi

View File

@ -23,16 +23,17 @@ use lib $FindBin::Bin;
use thumb;
my $thumb = 0;
my $elf = 1;
foreach my $arg (@ARGV) {
$thumb = 1 if ($arg eq "-thumb");
$elf = 0 if ($arg eq "-noelf");
}
print "@ This file was created from a .asm file\n";
print "@ using the ads2gas.pl script.\n";
print "\t.equ DO1STROUNDING, 0\n";
print "\t.syntax unified\n";
if ($thumb) {
print "\t.syntax unified\n";
print "\t.thumb\n";
}
@ -140,7 +141,11 @@ while (<STDIN>)
# Make function visible to linker, and make additional symbol with
# prepended underscore
s/EXPORT\s+\|([\$\w]*)\|/.global $1 \n\t.type $1, function/;
if ($elf) {
s/EXPORT\s+\|([\$\w]*)\|/.global $1 \n\t.type $1, function/;
} else {
s/EXPORT\s+\|([\$\w]*)\|/.global $1/;
}
s/IMPORT\s+\|([\$\w]*)\|/.global $1/;
s/EXPORT\s+([\$\w]*)/.global $1/;
@ -181,11 +186,16 @@ while (<STDIN>)
# eabi_attributes numerical equivalents can be found in the
# "ARM IHI 0045C" document.
# REQUIRE8 Stack is required to be 8-byte aligned
s/\sREQUIRE8/.eabi_attribute 24, 1 \@Tag_ABI_align_needed/g;
if ($elf) {
# REQUIRE8 Stack is required to be 8-byte aligned
s/\sREQUIRE8/.eabi_attribute 24, 1 \@Tag_ABI_align_needed/g;
# PRESERVE8 Stack 8-byte align is preserved
s/\sPRESERVE8/.eabi_attribute 25, 1 \@Tag_ABI_align_preserved/g;
# PRESERVE8 Stack 8-byte align is preserved
s/\sPRESERVE8/.eabi_attribute 25, 1 \@Tag_ABI_align_preserved/g;
} else {
s/\sREQUIRE8//;
s/\sPRESERVE8//;
}
# Use PROC and ENDP to give the symbols a .size directive.
# This makes them show up properly in debugging tools like gdb and valgrind.
@ -202,7 +212,7 @@ while (<STDIN>)
my $proc;
s/\bENDP\b/@ $&/;
$proc = pop(@proc_stack);
$_ = "\t.size $proc, .-$proc".$_ if ($proc);
$_ = "\t.size $proc, .-$proc".$_ if ($proc and $elf);
}
# EQU directive
@ -225,4 +235,4 @@ while (<STDIN>)
}
# Mark that this object doesn't need an executable stack.
printf ("\t.section\t.note.GNU-stack,\"\",\%\%progbits\n");
printf ("\t.section\t.note.GNU-stack,\"\",\%\%progbits\n") if $elf;

View File

@ -20,9 +20,7 @@
print "@ This file was created from a .asm file\n";
print "@ using the ads2gas_apple.pl script.\n\n";
print "\t.set WIDE_REFERENCE, 0\n";
print "\t.set ARCHITECTURE, 5\n";
print "\t.set DO1STROUNDING, 0\n";
print "\t.syntax unified\n";
my %register_aliases;
my %macro_aliases;

View File

@ -319,6 +319,12 @@ check_ld() {
&& check_cmd ${LD} ${LDFLAGS} "$@" -o ${TMP_X} ${TMP_O} ${extralibs}
}
check_lib() {
log check_lib "$@"
check_cc $@ \
&& check_cmd ${LD} ${LDFLAGS} -o ${TMP_X} ${TMP_O} "$@" ${extralibs}
}
check_header(){
log check_header "$@"
header=$1
@ -420,6 +426,26 @@ check_gcc_machine_options() {
fi
}
check_gcc_avx512_compiles() {
if disabled gcc; then
return
fi
check_cc -mavx512f <<EOF
#include <immintrin.h>
void f(void) {
__m512i x = _mm512_set1_epi16(0);
(void)x;
}
EOF
compile_result=$?
if [ ${compile_result} -ne 0 ]; then
log_echo " disabling avx512: not supported by compiler"
disable_feature avx512
RTCD_OPTIONS="${RTCD_OPTIONS}--disable-avx512 "
fi
}
write_common_config_banner() {
print_webm_license config.mk "##" ""
echo '# This file automatically generated by configure. Do not edit!' >> config.mk
@ -481,6 +507,7 @@ AS_SFX = ${AS_SFX:-.asm}
EXE_SFX = ${EXE_SFX}
VCPROJ_SFX = ${VCPROJ_SFX}
RTCD_OPTIONS = ${RTCD_OPTIONS}
LIBYUV_CXXFLAGS = ${LIBYUV_CXXFLAGS}
EOF
if enabled rvct; then cat >> $1 << EOF
@ -520,6 +547,24 @@ EOF
cmp "$1" ${TMP_H} >/dev/null 2>&1 || mv ${TMP_H} "$1"
}
write_win_arm64_neon_h_workaround() {
print_webm_license ${TMP_H} "/*" " */"
cat >> ${TMP_H} << EOF
/* This file automatically generated by configure. Do not edit! */
#ifndef VPX_WIN_ARM_NEON_H_WORKAROUND
#define VPX_WIN_ARM_NEON_H_WORKAROUND
/* The Windows SDK has arm_neon.h, but unlike on other platforms it is
* ARM32-only. ARM64 NEON support is provided by arm64_neon.h, a proper
* superset of arm_neon.h. Work around this by providing a more local
* arm_neon.h that simply #includes arm64_neon.h.
*/
#include <arm64_neon.h>
#endif /* VPX_WIN_ARM_NEON_H_WORKAROUND */
EOF
mkdir -p `dirname "$1"`
cmp "$1" ${TMP_H} >/dev/null 2>&1 || mv ${TMP_H} "$1"
}
process_common_cmdline() {
for opt in "$@"; do
optval="${opt#*=}"
@ -602,11 +647,7 @@ process_common_cmdline() {
--libdir=*)
libdir="${optval}"
;;
--sdk-path=*)
[ -d "${optval}" ] || die "Not a directory: ${optval}"
sdk_path="${optval}"
;;
--libc|--as|--prefix|--libdir|--sdk-path)
--libc|--as|--prefix|--libdir)
die "Option ${opt} requires argument"
;;
--help|-h)
@ -713,11 +754,8 @@ process_common_toolchain() {
*sparc*)
tgt_isa=sparc
;;
power*64*-*)
tgt_isa=ppc64
;;
power*)
tgt_isa=ppc
power*64le*-*)
tgt_isa=ppc64le
;;
*mips64el*)
tgt_isa=mips64
@ -837,7 +875,7 @@ process_common_toolchain() {
IOS_VERSION_MIN="8.0"
else
IOS_VERSION_OPTIONS=""
IOS_VERSION_MIN="6.0"
IOS_VERSION_MIN="7.0"
fi
# Handle darwin variants. Newer SDKs allow targeting older
@ -957,7 +995,6 @@ process_common_toolchain() {
setup_gnu_toolchain
arch_int=${tgt_isa##armv}
arch_int=${arch_int%%te}
check_add_asflags --defsym ARCHITECTURE=${arch_int}
tune_cflags="-mtune="
if [ ${tgt_isa} = "armv7" ] || [ ${tgt_isa} = "armv7s" ]; then
if [ -z "${float_abi}" ]; then
@ -984,6 +1021,16 @@ EOF
enabled debug && add_asflags -g
asm_conversion_cmd="${source_path}/build/make/ads2gas.pl"
case ${tgt_os} in
win*)
asm_conversion_cmd="$asm_conversion_cmd -noelf"
AS="$CC -c"
EXE_SFX=.exe
enable_feature thumb
;;
esac
if enabled thumb; then
asm_conversion_cmd="$asm_conversion_cmd -thumb"
check_add_cflags -mthumb
@ -991,18 +1038,41 @@ EOF
fi
;;
vs*)
asm_conversion_cmd="${source_path}/build/make/ads2armasm_ms.pl"
AS_SFX=.S
msvs_arch_dir=arm-msvs
disable_feature multithread
disable_feature unit_tests
vs_version=${tgt_cc##vs}
if [ $vs_version -ge 12 ]; then
# MSVC 2013 doesn't allow doing plain .exe projects for ARM,
# only "AppContainerApplication" which requires an AppxManifest.
# Therefore disable the examples, just build the library.
disable_feature examples
disable_feature tools
# A number of ARM-based Windows platforms are constrained by their
# respective SDKs' limitations. Fortunately, these are all 32-bit ABIs
# and so can be selected as 'win32'.
if [ ${tgt_os} = "win32" ]; then
asm_conversion_cmd="${source_path}/build/make/ads2armasm_ms.pl"
AS_SFX=.S
msvs_arch_dir=arm-msvs
disable_feature multithread
disable_feature unit_tests
if [ ${tgt_cc##vs} -ge 12 ]; then
# MSVC 2013 doesn't allow doing plain .exe projects for ARM32,
# only "AppContainerApplication" which requires an AppxManifest.
# Therefore disable the examples, just build the library.
disable_feature examples
disable_feature tools
fi
else
# Windows 10 on ARM, on the other hand, has full Windows SDK support
# for building Win32 ARM64 applications in addition to ARM64
# Windows Store apps. It is the only 64-bit ARM ABI that
# Windows supports, so it is the default definition of 'win64'.
# ARM64 build support officially shipped in Visual Studio 15.9.0.
# Because the ARM64 Windows SDK's arm_neon.h is ARM32-specific
# while LLVM's is not, probe its validity.
if enabled neon; then
if [ -n "${CC}" ]; then
check_header arm_neon.h || check_header arm64_neon.h && \
enable_feature win_arm64_neon_h_workaround
else
# If a probe is not possible, assume this is the pure Windows
# SDK and so the workaround is necessary.
enable_feature win_arm64_neon_h_workaround
fi
fi
fi
;;
rvct)
@ -1030,7 +1100,6 @@ EOF
fi
arch_int=${tgt_isa##armv}
arch_int=${arch_int%%te}
check_add_asflags --pd "\"ARCHITECTURE SETA ${arch_int}\""
enabled debug && add_asflags -g
add_cflags --gnu
add_cflags --enum_is_int
@ -1045,51 +1114,10 @@ EOF
;;
android*)
if [ -n "${sdk_path}" ]; then
SDK_PATH=${sdk_path}
COMPILER_LOCATION=`find "${SDK_PATH}" \
-name "arm-linux-androideabi-gcc*" -print -quit`
TOOLCHAIN_PATH=${COMPILER_LOCATION%/*}/arm-linux-androideabi-
CC=${TOOLCHAIN_PATH}gcc
CXX=${TOOLCHAIN_PATH}g++
AR=${TOOLCHAIN_PATH}ar
LD=${TOOLCHAIN_PATH}gcc
AS=${TOOLCHAIN_PATH}as
STRIP=${TOOLCHAIN_PATH}strip
NM=${TOOLCHAIN_PATH}nm
if [ -z "${alt_libc}" ]; then
alt_libc=`find "${SDK_PATH}" -name arch-arm -print | \
awk '{n = split($0,a,"/"); \
split(a[n-1],b,"-"); \
print $0 " " b[2]}' | \
sort -g -k 2 | \
awk '{ print $1 }' | tail -1`
fi
if [ -d "${alt_libc}" ]; then
add_cflags "--sysroot=${alt_libc}"
add_ldflags "--sysroot=${alt_libc}"
fi
# linker flag that routes around a CPU bug in some
# Cortex-A8 implementations (NDK Dev Guide)
add_ldflags "-Wl,--fix-cortex-a8"
enable_feature pic
soft_enable realtime_only
if [ ${tgt_isa} = "armv7" ]; then
soft_enable runtime_cpu_detect
fi
if enabled runtime_cpu_detect; then
add_cflags "-I${SDK_PATH}/sources/android/cpufeatures"
fi
else
echo "Assuming standalone build with NDK toolchain."
echo "See build/make/Android.mk for details."
check_add_ldflags -static
soft_enable unit_tests
fi
echo "Assuming standalone build with NDK toolchain."
echo "See build/make/Android.mk for details."
check_add_ldflags -static
soft_enable unit_tests
;;
darwin*)
@ -1204,6 +1232,11 @@ EOF
esac
if enabled msa; then
# TODO(libyuv:793)
# The new mips functions in libyuv do not build
# with the toolchains we currently use for testing.
soft_disable libyuv
add_cflags -mmsa
add_asflags -mmsa
add_ldflags -mmsa
@ -1219,13 +1252,25 @@ EOF
check_add_asflags -march=${tgt_isa}
check_add_asflags -KPIC
;;
ppc*)
ppc64le*)
link_with_cc=gcc
setup_gnu_toolchain
check_gcc_machine_option "vsx"
# Do not enable vsx by default.
# https://bugs.chromium.org/p/webm/issues/detail?id=1522
enabled vsx || RTCD_OPTIONS="${RTCD_OPTIONS}--disable-vsx "
if [ -n "${tune_cpu}" ]; then
case ${tune_cpu} in
power?)
tune_cflags="-mcpu="
;;
esac
fi
;;
x86*)
case ${tgt_os} in
android)
soft_enable realtime_only
;;
win*)
enabled gcc && add_cflags -fno-common
;;
@ -1277,28 +1322,13 @@ EOF
# Skip the check by setting AS arbitrarily
AS=msvs
msvs_arch_dir=x86-msvs
vc_version=${tgt_cc##vs}
case $vc_version in
7|8|9|10|11|12|13|14)
case ${tgt_cc##vs} in
14)
echo "${tgt_cc} does not support avx512, disabling....."
RTCD_OPTIONS="${RTCD_OPTIONS}--disable-avx512 "
soft_disable avx512
;;
esac
case $vc_version in
7|8|9|10)
echo "${tgt_cc} does not support avx/avx2, disabling....."
RTCD_OPTIONS="${RTCD_OPTIONS}--disable-avx --disable-avx2 "
soft_disable avx
soft_disable avx2
;;
esac
case $vc_version in
7|8|9)
echo "${tgt_cc} omits stdint.h, disabling webm-io..."
soft_disable webm_io
;;
esac
;;
esac
@ -1331,16 +1361,12 @@ EOF
else
if [ "$ext" = "avx512" ]; then
check_gcc_machine_options $ext avx512f avx512cd avx512bw avx512dq avx512vl
check_gcc_avx512_compiles
else
# use the shortened version for the flag: sse4_1 -> sse4
check_gcc_machine_option ${ext%_*} $ext
fi
fi
# https://bugs.chromium.org/p/webm/issues/detail?id=1464
# The assembly optimizations for vpx_sub_pixel_variance do not link with
# gcc 6.
enabled sse2 && soft_enable pic
done
if enabled external_build; then
@ -1400,7 +1426,8 @@ EOF
add_cflags ${sim_arch}
add_ldflags ${sim_arch}
if [ "$(show_darwin_sdk_major_version iphonesimulator)" -gt 8 ]; then
if [ "$(disabled external_build)" ] &&
[ "$(show_darwin_sdk_major_version iphonesimulator)" -gt 8 ]; then
# yasm v1.3.0 doesn't know what -fembed-bitcode means, so turning it
# on is pointless (unless building a C-only lib). Warn the user, but
# do nothing here.
@ -1490,7 +1517,11 @@ EOF
# bionic includes basic pthread functionality, obviating -lpthread.
;;
*)
check_header pthread.h && add_extralibs -lpthread
check_header pthread.h && check_lib -lpthread <<EOF && add_extralibs -lpthread || disable_feature pthread_h
#include <pthread.h>
#include <stddef.h>
int main(void) { return pthread_create(NULL, NULL, NULL, NULL); }
EOF
;;
esac
fi

View File

@ -261,6 +261,11 @@ case "$target" in
asm_Debug_cmdline="yasm -Xvc -g cv8 -f win32 ${yasmincs} &quot;%(FullPath)&quot;"
asm_Release_cmdline="yasm -Xvc -f win32 ${yasmincs} &quot;%(FullPath)&quot;"
;;
arm64*)
platforms[0]="ARM64"
asm_Debug_cmdline="armasm64 -nologo -oldit &quot;%(FullPath)&quot;"
asm_Release_cmdline="armasm64 -nologo -oldit &quot;%(FullPath)&quot;"
;;
arm*)
platforms[0]="ARM"
asm_Debug_cmdline="armasm -nologo -oldit &quot;%(FullPath)&quot;"
@ -307,6 +312,16 @@ generate_vcxproj() {
tag_content ApplicationType "Windows Store"
tag_content ApplicationTypeRevision 8.1
fi
if [ "${platforms[0]}" = "ARM64" ]; then
# Require the first Visual Studio version to have ARM64 support.
tag_content MinimumVisualStudioVersion 15.9
fi
if [ $vs_ver -eq 15 ] && [ "${platforms[0]}" = "ARM64" ]; then
# Since VS 15 does not have a 'use latest SDK version' facility,
# specifically require the contemporaneous SDK with official ARM64
# support.
tag_content WindowsTargetPlatformVersion 10.0.17763.0
fi
close_tag PropertyGroup
tag Import \

View File

@ -132,7 +132,8 @@ create_vpx_framework_config_shim() {
done
# Consume the last line of output from the loop: We don't want it.
sed -i '' -e '$d' "${config_file}"
sed -i.bak -e '$d' "${config_file}"
rm "${config_file}.bak"
printf "#endif\n\n" >> "${config_file}"
printf "#endif // ${include_guard}" >> "${config_file}"
@ -244,7 +245,7 @@ build_framework() {
# Trap function. Cleans up the subtree used to build all targets contained in
# $TARGETS.
cleanup() {
local readonly res=$?
local res=$?
cd "${ORIG_PWD}"
if [ $res -ne 0 ]; then
@ -350,7 +351,7 @@ if [ "$ENABLE_SHARED" = "yes" ]; then
IOS_VERSION_MIN="8.0"
else
IOS_VERSION_OPTIONS=""
IOS_VERSION_MIN="6.0"
IOS_VERSION_MIN="7.0"
fi
if [ "${VERBOSE}" = "yes" ]; then

View File

@ -41,6 +41,15 @@ fix_path() {
# Corrects the paths in file_list in one pass for efficiency.
# $1 is the name of the array to be modified.
fix_file_list() {
if [ "${FIXPATH}" = "echo_path" ] ; then
# When used with echo_path, fix_file_list is a no-op. Avoid warning about
# unsupported 'declare -n' when it is not important.
return 0
elif [ "${BASH_VERSINFO}" -lt 4 ] ; then
echo "Cygwin path conversion has failed. Please use a version of bash"
echo "which supports nameref (-n), introduced in bash 4.3"
return 1
fi
declare -n array_ref=$1
files=$(fix_path "${array_ref[@]}")
local IFS=$'\n'

View File

@ -400,12 +400,13 @@ EOF
#
&require("c");
&require(keys %required);
if ($opts{arch} eq 'x86') {
@ALL_ARCHS = filter(qw/mmx sse sse2 sse3 ssse3 sse4_1 avx avx2 avx512/);
x86;
} elsif ($opts{arch} eq 'x86_64') {
@ALL_ARCHS = filter(qw/mmx sse sse2 sse3 ssse3 sse4_1 avx avx2 avx512/);
@REQUIRES = filter(keys %required ? keys %required : qw/mmx sse sse2/);
@REQUIRES = filter(qw/mmx sse sse2/);
&require(@REQUIRES);
x86;
} elsif ($opts{arch} eq 'mips32' || $opts{arch} eq 'mips64') {
@ -433,6 +434,7 @@ if ($opts{arch} eq 'x86') {
arm;
} elsif ($opts{arch} eq 'armv8' || $opts{arch} eq 'arm64' ) {
@ALL_ARCHS = filter(qw/neon/);
&require("neon");
arm;
} elsif ($opts{arch} =~ /^ppc/ ) {
@ALL_ARCHS = filter(qw/vsx/);

View File

@ -54,13 +54,6 @@ sub FixThumbInstructions($$)
# "addne r0, r0, r2".
s/^(\s*)((ldr|str)(ne)?[bhd]?)(\s+)(\w+),(\s*\w+,)?\s*\[(\w+)\],\s*(\w+)/$1$2$5$6,$7 [$8]\n$1add$4$5$8, $8, $9/g;
# Convert a conditional addition to the pc register into a series of
# instructions. This converts "addlt pc, pc, r3, lsl #2" into
# "itttt lt", "movlt.n r12, pc", "addlt.w r12, #12",
# "addlt.w r12, r12, r3, lsl #2", "movlt.n pc, r12".
# This assumes that r12 is free at this point.
s/^(\s*)addlt(\s+)pc,\s*pc,\s*(\w+),\s*lsl\s*#(\d+)/$1itttt$2lt\n$1movlt.n$2r12, pc\n$1addlt.w$2r12, #12\n$1addlt.w$2r12, r12, $3, lsl #($4-$branch_shift_offset)\n$1movlt.n$2pc, r12/g;
# Convert "mov pc, lr" into "bx lr", since the former only works
# for switching from arm to thumb (and only in armv7), but not
# from thumb to arm.

View File

@ -1,5 +1,4 @@
# This file is used by gcl to get repository specific information.
GERRIT_HOST: chromium-review.googlesource.com
GERRIT_PORT: 29418
# This file is used by git cl to get repository specific information.
GERRIT_HOST: True
CODE_REVIEW_SERVER: chromium-review.googlesource.com
GERRIT_SQUASH_UPLOADS: False

94
libs/libvpx/configure vendored
View File

@ -31,7 +31,6 @@ Advanced options:
--libc=PATH path to alternate libc
--size-limit=WxH max size to allow in the decoder
--as={yasm|nasm|auto} use specified assembler [auto, yasm preferred]
--sdk-path=PATH path to root of sdk (android builds only)
${toggle_codec_srcs} in/exclude codec library source code
${toggle_debug_libs} in/exclude debug version of libraries
${toggle_static_msvcrt} use static MSVCRT (VS builds only)
@ -101,20 +100,20 @@ EOF
all_platforms="${all_platforms} arm64-android-gcc"
all_platforms="${all_platforms} arm64-darwin-gcc"
all_platforms="${all_platforms} arm64-linux-gcc"
all_platforms="${all_platforms} arm64-win64-gcc"
all_platforms="${all_platforms} arm64-win64-vs15"
all_platforms="${all_platforms} armv7-android-gcc" #neon Cortex-A8
all_platforms="${all_platforms} armv7-darwin-gcc" #neon Cortex-A8
all_platforms="${all_platforms} armv7-linux-rvct" #neon Cortex-A8
all_platforms="${all_platforms} armv7-linux-gcc" #neon Cortex-A8
all_platforms="${all_platforms} armv7-none-rvct" #neon Cortex-A8
all_platforms="${all_platforms} armv7-win32-vs11"
all_platforms="${all_platforms} armv7-win32-vs12"
all_platforms="${all_platforms} armv7-win32-gcc"
all_platforms="${all_platforms} armv7-win32-vs14"
all_platforms="${all_platforms} armv7-win32-vs15"
all_platforms="${all_platforms} armv7s-darwin-gcc"
all_platforms="${all_platforms} armv8-linux-gcc"
all_platforms="${all_platforms} mips32-linux-gcc"
all_platforms="${all_platforms} mips64-linux-gcc"
all_platforms="${all_platforms} ppc64-linux-gcc"
all_platforms="${all_platforms} ppc64le-linux-gcc"
all_platforms="${all_platforms} sparc-solaris-gcc"
all_platforms="${all_platforms} x86-android-gcc"
@ -137,9 +136,6 @@ all_platforms="${all_platforms} x86-linux-icc"
all_platforms="${all_platforms} x86-os2-gcc"
all_platforms="${all_platforms} x86-solaris-gcc"
all_platforms="${all_platforms} x86-win32-gcc"
all_platforms="${all_platforms} x86-win32-vs10"
all_platforms="${all_platforms} x86-win32-vs11"
all_platforms="${all_platforms} x86-win32-vs12"
all_platforms="${all_platforms} x86-win32-vs14"
all_platforms="${all_platforms} x86-win32-vs15"
all_platforms="${all_platforms} x86_64-android-gcc"
@ -159,9 +155,6 @@ all_platforms="${all_platforms} x86_64-linux-gcc"
all_platforms="${all_platforms} x86_64-linux-icc"
all_platforms="${all_platforms} x86_64-solaris-gcc"
all_platforms="${all_platforms} x86_64-win64-gcc"
all_platforms="${all_platforms} x86_64-win64-vs10"
all_platforms="${all_platforms} x86_64-win64-vs11"
all_platforms="${all_platforms} x86_64-win64-vs12"
all_platforms="${all_platforms} x86_64-win64-vs14"
all_platforms="${all_platforms} x86_64-win64-vs15"
all_platforms="${all_platforms} generic-gnu"
@ -278,9 +271,9 @@ HAVE_LIST="
unistd_h
"
EXPERIMENT_LIST="
spatial_svc
fp_mb_stats
emulate_hardware
non_greedy_mv
"
CONFIG_LIST="
dependency_tracking
@ -330,12 +323,15 @@ CONFIG_LIST="
multi_res_encoding
temporal_denoising
vp9_temporal_denoising
consistent_recode
coefficient_range_checking
vp9_highbitdepth
better_hw_compatibility
experimental
size_limit
always_adjust_bpm
bitstream_debug
mismatch_debug
${EXPERIMENT_LIST}
"
CMDLINE_SELECT="
@ -391,11 +387,14 @@ CMDLINE_SELECT="
multi_res_encoding
temporal_denoising
vp9_temporal_denoising
consistent_recode
coefficient_range_checking
better_hw_compatibility
vp9_highbitdepth
experimental
always_adjust_bpm
bitstream_debug
mismatch_debug
"
process_cmdline() {
@ -426,6 +425,12 @@ process_cmdline() {
}
post_process_cmdline() {
if enabled coefficient_range_checking; then
echo "coefficient-range-checking is for decoders only, disabling encoders:"
soft_disable vp8_encoder
soft_disable vp9_encoder
fi
c=""
# Enable all detected codecs, if they haven't been disabled
@ -447,6 +452,7 @@ process_targets() {
enabled child || write_common_config_banner
write_common_target_config_h ${BUILD_PFX}vpx_config.h
write_common_config_targets
enabled win_arm64_neon_h_workaround && write_win_arm64_neon_h_workaround ${BUILD_PFX}arm_neon.h
# Calculate the default distribution name, based on the enabled features
cf=""
@ -523,7 +529,7 @@ process_detect() {
# here rather than at option parse time because the target auto-detect
# magic happens after the command line has been parsed.
case "${tgt_os}" in
linux|os2|darwin*|iphonesimulator*)
linux|os2|solaris|darwin*|iphonesimulator*)
# Supported platforms
;;
*)
@ -575,16 +581,30 @@ process_detect() {
check_ld() {
true
}
check_lib() {
true
}
fi
check_header stdio.h || die "Unable to invoke compiler: ${CC} ${CFLAGS}"
check_ld <<EOF || die "Toolchain is unable to link executables"
int main(void) {return 0;}
EOF
# check system headers
check_header pthread.h
# Use both check_header and check_lib here, since check_lib
# could be a stub that always returns true.
check_header pthread.h && check_lib -lpthread <<EOF || disable_feature pthread_h
#include <pthread.h>
#include <stddef.h>
int main(void) { return pthread_create(NULL, NULL, NULL, NULL); }
EOF
check_header unistd.h # for sysconf(3) and friends.
check_header vpx/vpx_integer.h -I${source_path} && enable_feature vpx_ports
if enabled neon && ! enabled external_build; then
check_header arm_neon.h || die "Unable to find arm_neon.h"
fi
}
process_toolchain() {
@ -603,22 +623,39 @@ process_toolchain() {
check_add_cflags -Wcast-qual
check_add_cflags -Wvla
check_add_cflags -Wimplicit-function-declaration
check_add_cflags -Wmissing-declarations
check_add_cflags -Wmissing-prototypes
check_add_cflags -Wuninitialized
check_add_cflags -Wunused
# -Wextra has some tricky cases. Rather than fix them all now, get the
# flag for as many files as possible and fix the remaining issues
# piecemeal.
# https://bugs.chromium.org/p/webm/issues/detail?id=1069
check_add_cflags -Wextra
# check_add_cflags also adds to cxxflags. gtest does not do well with
# -Wundef so add it explicitly to CFLAGS only.
# these flags so add them explicitly to CFLAGS only.
check_cflags -Wundef && add_cflags_only -Wundef
check_cflags -Wframe-larger-than=52000 && \
add_cflags_only -Wframe-larger-than=52000
if enabled mips || [ -z "${INLINE}" ]; then
enabled extra_warnings || check_add_cflags -Wno-unused-function
fi
# Enforce c89 for c files. Don't be too strict about it though. Allow
# gnu extensions like "//" for comments.
check_cflags -std=gnu89 && add_cflags_only -std=gnu89
# Avoid this warning for third_party C++ sources. Some reorganization
# would be needed to apply this only to test/*.cc.
check_cflags -Wshorten-64-to-32 && add_cflags_only -Wshorten-64-to-32
# Quiet gcc 6 vs 7 abi warnings:
# https://gcc.gnu.org/bugzilla/show_bug.cgi?id=77728
if enabled arm; then
check_add_cxxflags -Wno-psabi
fi
# disable some warnings specific to libyuv.
check_cxxflags -Wno-missing-declarations \
&& LIBYUV_CXXFLAGS="${LIBYUV_CXXFLAGS} -Wno-missing-declarations"
check_cxxflags -Wno-missing-prototypes \
&& LIBYUV_CXXFLAGS="${LIBYUV_CXXFLAGS} -Wno-missing-prototypes"
check_cxxflags -Wno-unused-parameter \
&& LIBYUV_CXXFLAGS="${LIBYUV_CXXFLAGS} -Wno-unused-parameter"
fi
if enabled icc; then
@ -689,7 +726,7 @@ process_toolchain() {
soft_enable libyuv
;;
*-android-*)
soft_enable webm_io
check_add_cxxflags -std=c++11 && soft_enable webm_io
soft_enable libyuv
# GTestLog must be modified to use Android logging utilities.
;;
@ -698,30 +735,23 @@ process_toolchain() {
# x86 targets.
;;
*-iphonesimulator-*)
soft_enable webm_io
check_add_cxxflags -std=c++11 && soft_enable webm_io
soft_enable libyuv
;;
*-win*)
# Some mingw toolchains don't have pthread available by default.
# Treat these more like visual studio where threading in gtest
# would be disabled for the same reason.
check_cxx "$@" <<EOF && soft_enable unit_tests
int z;
EOF
check_cxx "$@" <<EOF && soft_enable webm_io
int z;
EOF
check_add_cxxflags -std=c++11 && soft_enable unit_tests \
&& soft_enable webm_io
check_cxx "$@" <<EOF && soft_enable libyuv
int z;
EOF
;;
*)
enabled pthread_h && check_cxx "$@" <<EOF && soft_enable unit_tests
int z;
EOF
check_cxx "$@" <<EOF && soft_enable webm_io
int z;
EOF
enabled pthread_h && check_add_cxxflags -std=c++11 \
&& soft_enable unit_tests
check_add_cxxflags -std=c++11 && soft_enable webm_io
check_cxx "$@" <<EOF && soft_enable libyuv
int z;
EOF

View File

@ -23,7 +23,7 @@ LIBYUV_SRCS += third_party/libyuv/include/libyuv/basic_types.h \
third_party/libyuv/source/row_any.cc \
third_party/libyuv/source/row_common.cc \
third_party/libyuv/source/row_gcc.cc \
third_party/libyuv/source/row_mips.cc \
third_party/libyuv/source/row_msa.cc \
third_party/libyuv/source/row_neon.cc \
third_party/libyuv/source/row_neon64.cc \
third_party/libyuv/source/row_win.cc \
@ -31,7 +31,7 @@ LIBYUV_SRCS += third_party/libyuv/include/libyuv/basic_types.h \
third_party/libyuv/source/scale_any.cc \
third_party/libyuv/source/scale_common.cc \
third_party/libyuv/source/scale_gcc.cc \
third_party/libyuv/source/scale_mips.cc \
third_party/libyuv/source/scale_msa.cc \
third_party/libyuv/source/scale_neon.cc \
third_party/libyuv/source/scale_neon64.cc \
third_party/libyuv/source/scale_win.cc \
@ -72,11 +72,12 @@ vpxdec.SRCS += vpx_ports/vpx_timer.h
vpxdec.SRCS += vpx/vpx_integer.h
vpxdec.SRCS += args.c args.h
vpxdec.SRCS += ivfdec.c ivfdec.h
vpxdec.SRCS += y4minput.c y4minput.h
vpxdec.SRCS += tools_common.c tools_common.h
vpxdec.SRCS += y4menc.c y4menc.h
ifeq ($(CONFIG_LIBYUV),yes)
vpxdec.SRCS += $(LIBYUV_SRCS)
$(BUILD_PFX)third_party/libyuv/%.cc.o: CXXFLAGS += -Wno-unused-parameter
$(BUILD_PFX)third_party/libyuv/%.cc.o: CXXFLAGS += ${LIBYUV_CXXFLAGS}
endif
ifeq ($(CONFIG_WEBM_IO),yes)
vpxdec.SRCS += $(LIBWEBM_COMMON_SRCS)
@ -109,18 +110,20 @@ ifeq ($(CONFIG_WEBM_IO),yes)
endif
vpxenc.GUID = 548DEC74-7A15-4B2B-AFC3-AA102E7C25C1
vpxenc.DESCRIPTION = Full featured encoder
ifeq ($(CONFIG_SPATIAL_SVC),yes)
EXAMPLES-$(CONFIG_VP9_ENCODER) += vp9_spatial_svc_encoder.c
vp9_spatial_svc_encoder.SRCS += args.c args.h
vp9_spatial_svc_encoder.SRCS += ivfenc.c ivfenc.h
vp9_spatial_svc_encoder.SRCS += tools_common.c tools_common.h
vp9_spatial_svc_encoder.SRCS += video_common.h
vp9_spatial_svc_encoder.SRCS += video_writer.h video_writer.c
vp9_spatial_svc_encoder.SRCS += vpx_ports/msvc.h
vp9_spatial_svc_encoder.SRCS += vpxstats.c vpxstats.h
vp9_spatial_svc_encoder.GUID = 4A38598D-627D-4505-9C7B-D4020C84100D
vp9_spatial_svc_encoder.DESCRIPTION = VP9 Spatial SVC Encoder
endif
EXAMPLES-$(CONFIG_VP9_ENCODER) += vp9_spatial_svc_encoder.c
vp9_spatial_svc_encoder.SRCS += args.c args.h
vp9_spatial_svc_encoder.SRCS += ivfenc.c ivfenc.h
vp9_spatial_svc_encoder.SRCS += y4minput.c y4minput.h
vp9_spatial_svc_encoder.SRCS += tools_common.c tools_common.h
vp9_spatial_svc_encoder.SRCS += video_common.h
vp9_spatial_svc_encoder.SRCS += video_writer.h video_writer.c
vp9_spatial_svc_encoder.SRCS += vpx_ports/msvc.h
vp9_spatial_svc_encoder.SRCS += vpxstats.c vpxstats.h
vp9_spatial_svc_encoder.SRCS += examples/svc_encodeframe.c
vp9_spatial_svc_encoder.SRCS += examples/svc_context.h
vp9_spatial_svc_encoder.GUID = 4A38598D-627D-4505-9C7B-D4020C84100D
vp9_spatial_svc_encoder.DESCRIPTION = VP9 Spatial SVC Encoder
ifneq ($(CONFIG_SHARED),yes)
EXAMPLES-$(CONFIG_VP9_ENCODER) += resize_util.c
@ -128,6 +131,7 @@ endif
EXAMPLES-$(CONFIG_ENCODERS) += vpx_temporal_svc_encoder.c
vpx_temporal_svc_encoder.SRCS += ivfenc.c ivfenc.h
vpx_temporal_svc_encoder.SRCS += y4minput.c y4minput.h
vpx_temporal_svc_encoder.SRCS += tools_common.c tools_common.h
vpx_temporal_svc_encoder.SRCS += video_common.h
vpx_temporal_svc_encoder.SRCS += video_writer.h video_writer.c
@ -137,6 +141,7 @@ vpx_temporal_svc_encoder.DESCRIPTION = Temporal SVC Encoder
EXAMPLES-$(CONFIG_DECODERS) += simple_decoder.c
simple_decoder.GUID = D3BBF1E9-2427-450D-BBFF-B2843C1D44CC
simple_decoder.SRCS += ivfdec.h ivfdec.c
simple_decoder.SRCS += y4minput.c y4minput.h
simple_decoder.SRCS += tools_common.h tools_common.c
simple_decoder.SRCS += video_common.h
simple_decoder.SRCS += video_reader.h video_reader.c
@ -146,6 +151,7 @@ simple_decoder.SRCS += vpx_ports/msvc.h
simple_decoder.DESCRIPTION = Simplified decoder loop
EXAMPLES-$(CONFIG_DECODERS) += postproc.c
postproc.SRCS += ivfdec.h ivfdec.c
postproc.SRCS += y4minput.c y4minput.h
postproc.SRCS += tools_common.h tools_common.c
postproc.SRCS += video_common.h
postproc.SRCS += video_reader.h video_reader.c
@ -157,6 +163,7 @@ postproc.DESCRIPTION = Decoder postprocessor control
EXAMPLES-$(CONFIG_DECODERS) += decode_to_md5.c
decode_to_md5.SRCS += md5_utils.h md5_utils.c
decode_to_md5.SRCS += ivfdec.h ivfdec.c
decode_to_md5.SRCS += y4minput.c y4minput.h
decode_to_md5.SRCS += tools_common.h tools_common.c
decode_to_md5.SRCS += video_common.h
decode_to_md5.SRCS += video_reader.h video_reader.c
@ -167,6 +174,7 @@ decode_to_md5.GUID = 59120B9B-2735-4BFE-B022-146CA340FE42
decode_to_md5.DESCRIPTION = Frame by frame MD5 checksum
EXAMPLES-$(CONFIG_ENCODERS) += simple_encoder.c
simple_encoder.SRCS += ivfenc.h ivfenc.c
simple_encoder.SRCS += y4minput.c y4minput.h
simple_encoder.SRCS += tools_common.h tools_common.c
simple_encoder.SRCS += video_common.h
simple_encoder.SRCS += video_writer.h video_writer.c
@ -175,6 +183,7 @@ simple_encoder.GUID = 4607D299-8A71-4D2C-9B1D-071899B6FBFD
simple_encoder.DESCRIPTION = Simplified encoder loop
EXAMPLES-$(CONFIG_VP9_ENCODER) += vp9_lossless_encoder.c
vp9_lossless_encoder.SRCS += ivfenc.h ivfenc.c
vp9_lossless_encoder.SRCS += y4minput.c y4minput.h
vp9_lossless_encoder.SRCS += tools_common.h tools_common.c
vp9_lossless_encoder.SRCS += video_common.h
vp9_lossless_encoder.SRCS += video_writer.h video_writer.c
@ -183,6 +192,7 @@ vp9_lossless_encoder.GUID = B63C7C88-5348-46DC-A5A6-CC151EF93366
vp9_lossless_encoder.DESCRIPTION = Simplified lossless VP9 encoder
EXAMPLES-$(CONFIG_ENCODERS) += twopass_encoder.c
twopass_encoder.SRCS += ivfenc.h ivfenc.c
twopass_encoder.SRCS += y4minput.c y4minput.h
twopass_encoder.SRCS += tools_common.h tools_common.c
twopass_encoder.SRCS += video_common.h
twopass_encoder.SRCS += video_writer.h video_writer.c
@ -191,6 +201,7 @@ twopass_encoder.GUID = 73494FA6-4AF9-4763-8FBB-265C92402FD8
twopass_encoder.DESCRIPTION = Two-pass encoder loop
EXAMPLES-$(CONFIG_DECODERS) += decode_with_drops.c
decode_with_drops.SRCS += ivfdec.h ivfdec.c
decode_with_drops.SRCS += y4minput.c y4minput.h
decode_with_drops.SRCS += tools_common.h tools_common.c
decode_with_drops.SRCS += video_common.h
decode_with_drops.SRCS += video_reader.h video_reader.c
@ -201,6 +212,7 @@ decode_with_drops.GUID = CE5C53C4-8DDA-438A-86ED-0DDD3CDB8D26
decode_with_drops.DESCRIPTION = Drops frames while decoding
EXAMPLES-$(CONFIG_ENCODERS) += set_maps.c
set_maps.SRCS += ivfenc.h ivfenc.c
set_maps.SRCS += y4minput.c y4minput.h
set_maps.SRCS += tools_common.h tools_common.c
set_maps.SRCS += video_common.h
set_maps.SRCS += video_writer.h video_writer.c
@ -209,6 +221,7 @@ set_maps.GUID = ECB2D24D-98B8-4015-A465-A4AF3DCC145F
set_maps.DESCRIPTION = Set active and ROI maps
EXAMPLES-$(CONFIG_VP8_ENCODER) += vp8cx_set_ref.c
vp8cx_set_ref.SRCS += ivfenc.h ivfenc.c
vp8cx_set_ref.SRCS += y4minput.c y4minput.h
vp8cx_set_ref.SRCS += tools_common.h tools_common.c
vp8cx_set_ref.SRCS += video_common.h
vp8cx_set_ref.SRCS += video_writer.h video_writer.c
@ -220,6 +233,7 @@ ifeq ($(CONFIG_VP9_ENCODER),yes)
ifeq ($(CONFIG_DECODERS),yes)
EXAMPLES-yes += vp9cx_set_ref.c
vp9cx_set_ref.SRCS += ivfenc.h ivfenc.c
vp9cx_set_ref.SRCS += y4minput.c y4minput.h
vp9cx_set_ref.SRCS += tools_common.h tools_common.c
vp9cx_set_ref.SRCS += video_common.h
vp9cx_set_ref.SRCS += video_writer.h video_writer.c
@ -232,6 +246,7 @@ ifeq ($(CONFIG_MULTI_RES_ENCODING),yes)
ifeq ($(CONFIG_LIBYUV),yes)
EXAMPLES-$(CONFIG_VP8_ENCODER) += vp8_multi_resolution_encoder.c
vp8_multi_resolution_encoder.SRCS += ivfenc.h ivfenc.c
vp8_multi_resolution_encoder.SRCS += y4minput.c y4minput.h
vp8_multi_resolution_encoder.SRCS += tools_common.h tools_common.c
vp8_multi_resolution_encoder.SRCS += video_writer.h video_writer.c
vp8_multi_resolution_encoder.SRCS += vpx_ports/msvc.h
@ -403,3 +418,4 @@ CLEAN-OBJS += examples.doxy samples.dox $(ALL_EXAMPLES:.c=.dox)
DOCS-yes += examples.doxy samples.dox
examples.doxy: samples.dox $(ALL_EXAMPLES:.c=.dox)
@echo "INPUT += $^" > $@
@echo "ENABLED_SECTIONS += samples" >> $@

View File

@ -13,11 +13,11 @@
* spatial SVC frame
*/
#ifndef VPX_SVC_CONTEXT_H_
#define VPX_SVC_CONTEXT_H_
#ifndef VPX_EXAMPLES_SVC_CONTEXT_H_
#define VPX_EXAMPLES_SVC_CONTEXT_H_
#include "./vp8cx.h"
#include "./vpx_encoder.h"
#include "vpx/vp8cx.h"
#include "vpx/vpx_encoder.h"
#ifdef __cplusplus
extern "C" {
@ -35,10 +35,8 @@ typedef struct {
int temporal_layers; // number of temporal layers
int temporal_layering_mode;
SVC_LOG_LEVEL log_level; // amount of information to display
int log_print; // when set, printf log messages instead of returning the
// message with svc_get_message
int output_rc_stat; // for outputting rc stats
int speed; // speed setting for codec
int output_rc_stat; // for outputting rc stats
int speed; // speed setting for codec
int threads;
int aqmode; // turns on aq-mode=3 (cyclic_refresh): 0=off, 1=on.
// private storage for vpx_svc_encode
@ -71,7 +69,6 @@ typedef struct SvcInternal {
int layer;
int use_multiple_frame_contexts;
char message_buffer[2048];
vpx_codec_ctx_t *codec_ctx;
} SvcInternal_t;
@ -106,15 +103,10 @@ void vpx_svc_release(SvcContext *svc_ctx);
/**
* dump accumulated statistics and reset accumulated values
*/
const char *vpx_svc_dump_statistics(SvcContext *svc_ctx);
/**
* get status message from previous encode
*/
const char *vpx_svc_get_message(const SvcContext *svc_ctx);
void vpx_svc_dump_statistics(SvcContext *svc_ctx);
#ifdef __cplusplus
} // extern "C"
#endif
#endif // VPX_SVC_CONTEXT_H_
#endif // VPX_EXAMPLES_SVC_CONTEXT_H_

View File

@ -22,7 +22,7 @@
#include <string.h>
#define VPX_DISABLE_CTRL_TYPECHECKS 1
#include "./vpx_config.h"
#include "vpx/svc_context.h"
#include "./svc_context.h"
#include "vpx/vp8cx.h"
#include "vpx/vpx_encoder.h"
#include "vpx_mem/vpx_mem.h"
@ -95,17 +95,11 @@ static const SvcInternal_t *get_const_svc_internal(const SvcContext *svc_ctx) {
return (const SvcInternal_t *)svc_ctx->internal;
}
static void svc_log_reset(SvcContext *svc_ctx) {
SvcInternal_t *const si = (SvcInternal_t *)svc_ctx->internal;
si->message_buffer[0] = '\0';
}
static int svc_log(SvcContext *svc_ctx, SVC_LOG_LEVEL level, const char *fmt,
...) {
char buf[512];
int retval = 0;
va_list ap;
SvcInternal_t *const si = get_svc_internal(svc_ctx);
if (level > svc_ctx->log_level) {
return retval;
@ -115,16 +109,8 @@ static int svc_log(SvcContext *svc_ctx, SVC_LOG_LEVEL level, const char *fmt,
retval = vsnprintf(buf, sizeof(buf), fmt, ap);
va_end(ap);
if (svc_ctx->log_print) {
printf("%s", buf);
} else {
strncat(si->message_buffer, buf,
sizeof(si->message_buffer) - strlen(si->message_buffer) - 1);
}
printf("%s", buf);
if (level == SVC_LOG_ERROR) {
si->codec_ctx->err_detail = si->message_buffer;
}
return retval;
}
@ -169,6 +155,7 @@ static vpx_codec_err_t parse_layer_options_from_string(SvcContext *svc_ctx,
return VPX_CODEC_INVALID_PARAM;
input_string = strdup(input);
if (input_string == NULL) return VPX_CODEC_MEM_ERROR;
token = strtok_r(input_string, delim, &save_ptr);
for (i = 0; i < num_layers; ++i) {
if (token != NULL) {
@ -208,6 +195,7 @@ static vpx_codec_err_t parse_options(SvcContext *svc_ctx, const char *options) {
if (options == NULL) return VPX_CODEC_OK;
input_string = strdup(options);
if (input_string == NULL) return VPX_CODEC_MEM_ERROR;
// parse option name
option_name = strtok_r(input_string, "=", &input_ptr);
@ -294,8 +282,8 @@ vpx_codec_err_t vpx_svc_set_options(SvcContext *svc_ctx, const char *options) {
return VPX_CODEC_OK;
}
vpx_codec_err_t assign_layer_bitrates(const SvcContext *svc_ctx,
vpx_codec_enc_cfg_t *const enc_cfg) {
static vpx_codec_err_t assign_layer_bitrates(
const SvcContext *svc_ctx, vpx_codec_enc_cfg_t *const enc_cfg) {
int i;
const SvcInternal_t *const si = get_const_svc_internal(svc_ctx);
int sl, tl, spatial_layer_target;
@ -471,8 +459,7 @@ vpx_codec_err_t vpx_svc_init(SvcContext *svc_ctx, vpx_codec_ctx_t *codec_ctx,
svc_log(svc_ctx, SVC_LOG_ERROR,
"spatial layers * temporal layers exceeds the maximum number of "
"allowed layers of %d\n",
svc_ctx->spatial_layers * svc_ctx->temporal_layers,
(int)VPX_MAX_LAYERS);
svc_ctx->spatial_layers * svc_ctx->temporal_layers, VPX_MAX_LAYERS);
return VPX_CODEC_INVALID_PARAM;
}
res = assign_layer_bitrates(svc_ctx, enc_cfg);
@ -485,11 +472,6 @@ vpx_codec_err_t vpx_svc_init(SvcContext *svc_ctx, vpx_codec_ctx_t *codec_ctx,
return VPX_CODEC_INVALID_PARAM;
}
#if CONFIG_SPATIAL_SVC
for (i = 0; i < svc_ctx->spatial_layers; ++i)
enc_cfg->ss_enable_auto_alt_ref[i] = si->enable_auto_alt_ref[i];
#endif
if (svc_ctx->temporal_layers > 1) {
int i;
for (i = 0; i < svc_ctx->temporal_layers; ++i) {
@ -514,7 +496,17 @@ vpx_codec_err_t vpx_svc_init(SvcContext *svc_ctx, vpx_codec_ctx_t *codec_ctx,
enc_cfg->rc_buf_initial_sz = 500;
enc_cfg->rc_buf_optimal_sz = 600;
enc_cfg->rc_buf_sz = 1000;
enc_cfg->rc_dropframe_thresh = 0;
}
for (tl = 0; tl < svc_ctx->temporal_layers; ++tl) {
for (sl = 0; sl < svc_ctx->spatial_layers; ++sl) {
i = sl * svc_ctx->temporal_layers + tl;
if (enc_cfg->rc_end_usage == VPX_CBR &&
enc_cfg->g_pass == VPX_RC_ONE_PASS) {
si->svc_params.max_quantizers[i] = enc_cfg->rc_max_quantizer;
si->svc_params.min_quantizers[i] = enc_cfg->rc_min_quantizer;
}
}
}
if (enc_cfg->g_error_resilient == 0 && si->use_multiple_frame_contexts == 0)
@ -548,8 +540,6 @@ vpx_codec_err_t vpx_svc_encode(SvcContext *svc_ctx, vpx_codec_ctx_t *codec_ctx,
return VPX_CODEC_INVALID_PARAM;
}
svc_log_reset(svc_ctx);
res =
vpx_codec_encode(codec_ctx, rawimg, pts, (uint32_t)duration, 0, deadline);
if (res != VPX_CODEC_OK) {
@ -559,56 +549,7 @@ vpx_codec_err_t vpx_svc_encode(SvcContext *svc_ctx, vpx_codec_ctx_t *codec_ctx,
iter = NULL;
while ((cx_pkt = vpx_codec_get_cx_data(codec_ctx, &iter))) {
switch (cx_pkt->kind) {
#if CONFIG_SPATIAL_SVC && defined(VPX_TEST_SPATIAL_SVC)
case VPX_CODEC_SPATIAL_SVC_LAYER_PSNR: {
int i;
for (i = 0; i < svc_ctx->spatial_layers; ++i) {
int j;
svc_log(svc_ctx, SVC_LOG_DEBUG,
"SVC frame: %d, layer: %d, PSNR(Total/Y/U/V): "
"%2.3f %2.3f %2.3f %2.3f \n",
si->psnr_pkt_received, i, cx_pkt->data.layer_psnr[i].psnr[0],
cx_pkt->data.layer_psnr[i].psnr[1],
cx_pkt->data.layer_psnr[i].psnr[2],
cx_pkt->data.layer_psnr[i].psnr[3]);
svc_log(svc_ctx, SVC_LOG_DEBUG,
"SVC frame: %d, layer: %d, SSE(Total/Y/U/V): "
"%2.3f %2.3f %2.3f %2.3f \n",
si->psnr_pkt_received, i, cx_pkt->data.layer_psnr[i].sse[0],
cx_pkt->data.layer_psnr[i].sse[1],
cx_pkt->data.layer_psnr[i].sse[2],
cx_pkt->data.layer_psnr[i].sse[3]);
for (j = 0; j < COMPONENTS; ++j) {
si->psnr_sum[i][j] += cx_pkt->data.layer_psnr[i].psnr[j];
si->sse_sum[i][j] += cx_pkt->data.layer_psnr[i].sse[j];
}
}
++si->psnr_pkt_received;
break;
}
case VPX_CODEC_SPATIAL_SVC_LAYER_SIZES: {
int i;
for (i = 0; i < svc_ctx->spatial_layers; ++i)
si->bytes_sum[i] += cx_pkt->data.layer_sizes[i];
break;
}
#endif
case VPX_CODEC_PSNR_PKT: {
#if CONFIG_SPATIAL_SVC && defined(VPX_TEST_SPATIAL_SVC)
int j;
svc_log(svc_ctx, SVC_LOG_DEBUG,
"frame: %d, layer: %d, PSNR(Total/Y/U/V): "
"%2.3f %2.3f %2.3f %2.3f \n",
si->psnr_pkt_received, 0, cx_pkt->data.layer_psnr[0].psnr[0],
cx_pkt->data.layer_psnr[0].psnr[1],
cx_pkt->data.layer_psnr[0].psnr[2],
cx_pkt->data.layer_psnr[0].psnr[3]);
for (j = 0; j < COMPONENTS; ++j) {
si->psnr_sum[0][j] += cx_pkt->data.layer_psnr[0].psnr[j];
si->sse_sum[0][j] += cx_pkt->data.layer_psnr[0].sse[j];
}
#endif
}
++si->psnr_pkt_received;
break;
@ -619,19 +560,13 @@ vpx_codec_err_t vpx_svc_encode(SvcContext *svc_ctx, vpx_codec_ctx_t *codec_ctx,
return VPX_CODEC_OK;
}
const char *vpx_svc_get_message(const SvcContext *svc_ctx) {
const SvcInternal_t *const si = get_const_svc_internal(svc_ctx);
if (svc_ctx == NULL || si == NULL) return NULL;
return si->message_buffer;
}
static double calc_psnr(double d) {
if (d == 0) return 100;
return -10.0 * log(d) / log(10.0);
}
// dump accumulated statistics and reset accumulated values
const char *vpx_svc_dump_statistics(SvcContext *svc_ctx) {
void vpx_svc_dump_statistics(SvcContext *svc_ctx) {
int number_of_frames;
int i, j;
uint32_t bytes_total = 0;
@ -641,21 +576,19 @@ const char *vpx_svc_dump_statistics(SvcContext *svc_ctx) {
double y_scale;
SvcInternal_t *const si = get_svc_internal(svc_ctx);
if (svc_ctx == NULL || si == NULL) return NULL;
svc_log_reset(svc_ctx);
if (svc_ctx == NULL || si == NULL) return;
number_of_frames = si->psnr_pkt_received;
if (number_of_frames <= 0) return vpx_svc_get_message(svc_ctx);
if (number_of_frames <= 0) return;
svc_log(svc_ctx, SVC_LOG_INFO, "\n");
for (i = 0; i < svc_ctx->spatial_layers; ++i) {
svc_log(svc_ctx, SVC_LOG_INFO,
"Layer %d Average PSNR=[%2.3f, %2.3f, %2.3f, %2.3f], Bytes=[%u]\n",
i, (double)si->psnr_sum[i][0] / number_of_frames,
(double)si->psnr_sum[i][1] / number_of_frames,
(double)si->psnr_sum[i][2] / number_of_frames,
(double)si->psnr_sum[i][3] / number_of_frames, si->bytes_sum[i]);
i, si->psnr_sum[i][0] / number_of_frames,
si->psnr_sum[i][1] / number_of_frames,
si->psnr_sum[i][2] / number_of_frames,
si->psnr_sum[i][3] / number_of_frames, si->bytes_sum[i]);
// the following psnr calculation is deduced from ffmpeg.c#print_report
y_scale = si->width * si->height * 255.0 * 255.0 * number_of_frames;
scale[1] = y_scale;
@ -686,7 +619,6 @@ const char *vpx_svc_dump_statistics(SvcContext *svc_ctx) {
si->psnr_pkt_received = 0;
svc_log(svc_ctx, SVC_LOG_INFO, "Total Bytes=[%u]\n", bytes_total);
return vpx_svc_get_message(svc_ctx);
}
void vpx_svc_release(SvcContext *svc_ctx) {

View File

@ -61,7 +61,7 @@ void usage_exit(void) { exit(EXIT_FAILURE); }
int (*read_frame_p)(FILE *f, vpx_image_t *img);
static int read_frame(FILE *f, vpx_image_t *img) {
static int mulres_read_frame(FILE *f, vpx_image_t *img) {
size_t nbytes, to_read;
int res = 1;
@ -75,7 +75,7 @@ static int read_frame(FILE *f, vpx_image_t *img) {
return res;
}
static int read_frame_by_row(FILE *f, vpx_image_t *img) {
static int mulres_read_frame_by_row(FILE *f, vpx_image_t *img) {
size_t nbytes, to_read;
int res = 1;
int plane;
@ -471,9 +471,9 @@ int main(int argc, char **argv) {
die("Failed to allocate image", cfg[i].g_w, cfg[i].g_h);
if (raw[0].stride[VPX_PLANE_Y] == (int)raw[0].d_w)
read_frame_p = read_frame;
read_frame_p = mulres_read_frame;
else
read_frame_p = read_frame_by_row;
read_frame_p = mulres_read_frame_by_row;
for (i = 0; i < NUM_ENCODERS; i++)
if (outfile[i]) write_ivf_file_header(outfile[i], &cfg[i], 0);

File diff suppressed because it is too large Load Diff

View File

@ -68,128 +68,6 @@ void usage_exit() {
exit(EXIT_FAILURE);
}
static int compare_img(const vpx_image_t *const img1,
const vpx_image_t *const img2) {
uint32_t l_w = img1->d_w;
uint32_t c_w = (img1->d_w + img1->x_chroma_shift) >> img1->x_chroma_shift;
const uint32_t c_h =
(img1->d_h + img1->y_chroma_shift) >> img1->y_chroma_shift;
uint32_t i;
int match = 1;
match &= (img1->fmt == img2->fmt);
match &= (img1->d_w == img2->d_w);
match &= (img1->d_h == img2->d_h);
for (i = 0; i < img1->d_h; ++i)
match &= (memcmp(img1->planes[VPX_PLANE_Y] + i * img1->stride[VPX_PLANE_Y],
img2->planes[VPX_PLANE_Y] + i * img2->stride[VPX_PLANE_Y],
l_w) == 0);
for (i = 0; i < c_h; ++i)
match &= (memcmp(img1->planes[VPX_PLANE_U] + i * img1->stride[VPX_PLANE_U],
img2->planes[VPX_PLANE_U] + i * img2->stride[VPX_PLANE_U],
c_w) == 0);
for (i = 0; i < c_h; ++i)
match &= (memcmp(img1->planes[VPX_PLANE_V] + i * img1->stride[VPX_PLANE_V],
img2->planes[VPX_PLANE_V] + i * img2->stride[VPX_PLANE_V],
c_w) == 0);
return match;
}
#define mmin(a, b) ((a) < (b) ? (a) : (b))
static void find_mismatch(const vpx_image_t *const img1,
const vpx_image_t *const img2, int yloc[4],
int uloc[4], int vloc[4]) {
const uint32_t bsize = 64;
const uint32_t bsizey = bsize >> img1->y_chroma_shift;
const uint32_t bsizex = bsize >> img1->x_chroma_shift;
const uint32_t c_w =
(img1->d_w + img1->x_chroma_shift) >> img1->x_chroma_shift;
const uint32_t c_h =
(img1->d_h + img1->y_chroma_shift) >> img1->y_chroma_shift;
int match = 1;
uint32_t i, j;
yloc[0] = yloc[1] = yloc[2] = yloc[3] = -1;
for (i = 0, match = 1; match && i < img1->d_h; i += bsize) {
for (j = 0; match && j < img1->d_w; j += bsize) {
int k, l;
const int si = mmin(i + bsize, img1->d_h) - i;
const int sj = mmin(j + bsize, img1->d_w) - j;
for (k = 0; match && k < si; ++k) {
for (l = 0; match && l < sj; ++l) {
if (*(img1->planes[VPX_PLANE_Y] +
(i + k) * img1->stride[VPX_PLANE_Y] + j + l) !=
*(img2->planes[VPX_PLANE_Y] +
(i + k) * img2->stride[VPX_PLANE_Y] + j + l)) {
yloc[0] = i + k;
yloc[1] = j + l;
yloc[2] = *(img1->planes[VPX_PLANE_Y] +
(i + k) * img1->stride[VPX_PLANE_Y] + j + l);
yloc[3] = *(img2->planes[VPX_PLANE_Y] +
(i + k) * img2->stride[VPX_PLANE_Y] + j + l);
match = 0;
break;
}
}
}
}
}
uloc[0] = uloc[1] = uloc[2] = uloc[3] = -1;
for (i = 0, match = 1; match && i < c_h; i += bsizey) {
for (j = 0; match && j < c_w; j += bsizex) {
int k, l;
const int si = mmin(i + bsizey, c_h - i);
const int sj = mmin(j + bsizex, c_w - j);
for (k = 0; match && k < si; ++k) {
for (l = 0; match && l < sj; ++l) {
if (*(img1->planes[VPX_PLANE_U] +
(i + k) * img1->stride[VPX_PLANE_U] + j + l) !=
*(img2->planes[VPX_PLANE_U] +
(i + k) * img2->stride[VPX_PLANE_U] + j + l)) {
uloc[0] = i + k;
uloc[1] = j + l;
uloc[2] = *(img1->planes[VPX_PLANE_U] +
(i + k) * img1->stride[VPX_PLANE_U] + j + l);
uloc[3] = *(img2->planes[VPX_PLANE_U] +
(i + k) * img2->stride[VPX_PLANE_U] + j + l);
match = 0;
break;
}
}
}
}
}
vloc[0] = vloc[1] = vloc[2] = vloc[3] = -1;
for (i = 0, match = 1; match && i < c_h; i += bsizey) {
for (j = 0; match && j < c_w; j += bsizex) {
int k, l;
const int si = mmin(i + bsizey, c_h - i);
const int sj = mmin(j + bsizex, c_w - j);
for (k = 0; match && k < si; ++k) {
for (l = 0; match && l < sj; ++l) {
if (*(img1->planes[VPX_PLANE_V] +
(i + k) * img1->stride[VPX_PLANE_V] + j + l) !=
*(img2->planes[VPX_PLANE_V] +
(i + k) * img2->stride[VPX_PLANE_V] + j + l)) {
vloc[0] = i + k;
vloc[1] = j + l;
vloc[2] = *(img1->planes[VPX_PLANE_V] +
(i + k) * img1->stride[VPX_PLANE_V] + j + l);
vloc[3] = *(img2->planes[VPX_PLANE_V] +
(i + k) * img2->stride[VPX_PLANE_V] + j + l);
match = 0;
break;
}
}
}
}
}
}
static void testing_decode(vpx_codec_ctx_t *encoder, vpx_codec_ctx_t *decoder,
unsigned int frame_out, int *mismatch_seen) {
vpx_image_t enc_img, dec_img;

View File

@ -0,0 +1,118 @@
/*
* Copyright (c) 2018 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.
*/
/*
* Fuzzer for libvpx decoders
* ==========================
* Requirements
* --------------
* Requires Clang 6.0 or above as -fsanitize=fuzzer is used as a linker
* option.
* Steps to build
* --------------
* Clone libvpx repository
$git clone https://chromium.googlesource.com/webm/libvpx
* Create a directory in parallel to libvpx and change directory
$mkdir vpx_dec_fuzzer
$cd vpx_dec_fuzzer/
* Enable sanitizers (Supported: address integer memory thread undefined)
$source ../libvpx/tools/set_analyzer_env.sh address
* Configure libvpx.
* Note --size-limit and VPX_MAX_ALLOCABLE_MEMORY are defined to avoid
* Out of memory errors when running generated fuzzer binary
$../libvpx/configure --disable-unit-tests --size-limit=12288x12288 \
--extra-cflags="-fsanitize=fuzzer-no-link \
-DVPX_MAX_ALLOCABLE_MEMORY=1073741824" \
--disable-webm-io --enable-debug --disable-vp8-encoder \
--disable-vp9-encoder --disable-examples
* Build libvpx
$make -j32
* Build vp9 fuzzer
$ $CXX $CXXFLAGS -std=c++11 -DDECODER=vp9 \
-fsanitize=fuzzer -I../libvpx -I. -Wl,--start-group \
../libvpx/examples/vpx_dec_fuzzer.cc -o ./vpx_dec_fuzzer_vp9 \
./libvpx.a -Wl,--end-group
* DECODER should be defined as vp9 or vp8 to enable vp9/vp8
*
* create a corpus directory and copy some ivf files there.
* Based on which codec (vp8/vp9) is being tested, it is recommended to
* have corresponding ivf files in corpus directory
* Empty corpus directoy also is acceptable, though not recommended
$mkdir CORPUS && cp some-files CORPUS
* Run fuzzing:
$./vpx_dec_fuzzer_vp9 CORPUS
* References:
* http://llvm.org/docs/LibFuzzer.html
* https://github.com/google/oss-fuzz
*/
#include <stddef.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <algorithm>
#include <memory>
#include "vpx/vp8dx.h"
#include "vpx/vpx_decoder.h"
#include "vpx_ports/mem_ops.h"
#define IVF_FRAME_HDR_SZ (4 + 8) /* 4 byte size + 8 byte timestamp */
#define IVF_FILE_HDR_SZ 32
#define VPXD_INTERFACE(name) VPXD_INTERFACE_(name)
#define VPXD_INTERFACE_(name) vpx_codec_##name##_dx()
extern "C" void usage_exit(void) { exit(EXIT_FAILURE); }
extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) {
if (size <= IVF_FILE_HDR_SZ) {
return 0;
}
vpx_codec_ctx_t codec;
// Set thread count in the range [1, 64].
const unsigned int threads = (data[IVF_FILE_HDR_SZ] & 0x3f) + 1;
vpx_codec_dec_cfg_t cfg = { threads, 0, 0 };
if (vpx_codec_dec_init(&codec, VPXD_INTERFACE(DECODER), &cfg, 0)) {
return 0;
}
data += IVF_FILE_HDR_SZ;
size -= IVF_FILE_HDR_SZ;
while (size > IVF_FRAME_HDR_SZ) {
size_t frame_size = mem_get_le32(data);
size -= IVF_FRAME_HDR_SZ;
data += IVF_FRAME_HDR_SZ;
frame_size = std::min(size, frame_size);
const vpx_codec_err_t err =
vpx_codec_decode(&codec, data, frame_size, nullptr, 0);
static_cast<void>(err);
vpx_codec_iter_t iter = nullptr;
vpx_image_t *img = nullptr;
while ((img = vpx_codec_get_frame(&codec, &iter)) != nullptr) {
}
data += frame_size;
size -= frame_size;
}
vpx_codec_destroy(&codec);
return 0;
}

View File

@ -19,14 +19,18 @@
#include <string.h>
#include "./vpx_config.h"
#include "./y4minput.h"
#include "../vpx_ports/vpx_timer.h"
#include "vpx/vp8cx.h"
#include "vpx/vpx_encoder.h"
#include "vpx_ports/bitops.h"
#include "../tools_common.h"
#include "../video_writer.h"
#define VP8_ROI_MAP 0
#define ROI_MAP 0
#define zero(Dest) memset(&(Dest), 0, sizeof(Dest));
static const char *exec_name;
@ -89,19 +93,21 @@ struct RateControlMetrics {
// in the stream.
static void set_rate_control_metrics(struct RateControlMetrics *rc,
vpx_codec_enc_cfg_t *cfg) {
unsigned int i = 0;
int i = 0;
// Set the layer (cumulative) framerate and the target layer (non-cumulative)
// per-frame-bandwidth, for the rate control encoding stats below.
const double framerate = cfg->g_timebase.den / cfg->g_timebase.num;
const int ts_number_layers = cfg->ts_number_layers;
rc->layer_framerate[0] = framerate / cfg->ts_rate_decimator[0];
rc->layer_pfb[0] =
1000.0 * rc->layer_target_bitrate[0] / rc->layer_framerate[0];
for (i = 0; i < cfg->ts_number_layers; ++i) {
for (i = 0; i < ts_number_layers; ++i) {
if (i > 0) {
rc->layer_framerate[i] = framerate / cfg->ts_rate_decimator[i];
rc->layer_pfb[i] = 1000.0 * (rc->layer_target_bitrate[i] -
rc->layer_target_bitrate[i - 1]) /
(rc->layer_framerate[i] - rc->layer_framerate[i - 1]);
rc->layer_pfb[i] =
1000.0 *
(rc->layer_target_bitrate[i] - rc->layer_target_bitrate[i - 1]) /
(rc->layer_framerate[i] - rc->layer_framerate[i - 1]);
}
rc->layer_input_frames[i] = 0;
rc->layer_enc_frames[i] = 0;
@ -114,6 +120,9 @@ static void set_rate_control_metrics(struct RateControlMetrics *rc,
rc->window_size = 15;
rc->avg_st_encoding_bitrate = 0.0;
rc->variance_st_encoding_bitrate = 0.0;
// Target bandwidth for the whole stream.
// Set to layer_target_bitrate for highest layer (total bitrate).
cfg->rc_target_bitrate = rc->layer_target_bitrate[ts_number_layers - 1];
}
static void printout_rate_control_summary(struct RateControlMetrics *rc,
@ -164,38 +173,60 @@ static void printout_rate_control_summary(struct RateControlMetrics *rc,
die("Error: Number of input frames not equal to output! \n");
}
#if VP8_ROI_MAP
static void vp8_set_roi_map(vpx_codec_enc_cfg_t *cfg, vpx_roi_map_t *roi) {
#if ROI_MAP
static void set_roi_map(const char *enc_name, vpx_codec_enc_cfg_t *cfg,
vpx_roi_map_t *roi) {
unsigned int i, j;
memset(roi, 0, sizeof(*roi));
int block_size = 0;
uint8_t is_vp8 = strncmp(enc_name, "vp8", 3) == 0 ? 1 : 0;
uint8_t is_vp9 = strncmp(enc_name, "vp9", 3) == 0 ? 1 : 0;
if (!is_vp8 && !is_vp9) {
die("unsupported codec.");
}
zero(*roi);
block_size = is_vp9 && !is_vp8 ? 8 : 16;
// ROI is based on the segments (4 for vp8, 8 for vp9), smallest unit for
// segment is 16x16 for vp8, 8x8 for vp9.
roi->rows = (cfg->g_h + 15) / 16;
roi->cols = (cfg->g_w + 15) / 16;
roi->rows = (cfg->g_h + block_size - 1) / block_size;
roi->cols = (cfg->g_w + block_size - 1) / block_size;
// Applies delta QP on the segment blocks, varies from -63 to 63.
// Setting to negative means lower QP (better quality).
// Below we set delta_q to the extreme (-63) to show strong effect.
roi->delta_q[0] = 0;
// VP8 uses the first 4 segments. VP9 uses all 8 segments.
zero(roi->delta_q);
roi->delta_q[1] = -63;
roi->delta_q[2] = 0;
roi->delta_q[3] = 0;
// Applies delta loopfilter strength on the segment blocks, varies from -63 to
// 63. Setting to positive means stronger loopfilter.
roi->delta_lf[0] = 0;
roi->delta_lf[1] = 0;
roi->delta_lf[2] = 0;
roi->delta_lf[3] = 0;
// 63. Setting to positive means stronger loopfilter. VP8 uses the first 4
// segments. VP9 uses all 8 segments.
zero(roi->delta_lf);
// Applies skip encoding threshold on the segment blocks, varies from 0 to
// UINT_MAX. Larger value means more skipping of encoding is possible.
// This skip threshold only applies on delta frames.
roi->static_threshold[0] = 0;
roi->static_threshold[1] = 0;
roi->static_threshold[2] = 0;
roi->static_threshold[3] = 0;
if (is_vp8) {
// Applies skip encoding threshold on the segment blocks, varies from 0 to
// UINT_MAX. Larger value means more skipping of encoding is possible.
// This skip threshold only applies on delta frames.
zero(roi->static_threshold);
}
if (is_vp9) {
// Apply skip segment. Setting to 1 means this block will be copied from
// previous frame.
zero(roi->skip);
}
if (is_vp9) {
// Apply ref frame segment.
// -1 : Do not apply this segment.
// 0 : Froce using intra.
// 1 : Force using last.
// 2 : Force using golden.
// 3 : Force using alfref but not used in non-rd pickmode for 0 lag.
memset(roi->ref_frame, -1, sizeof(roi->ref_frame));
roi->ref_frame[1] = 1;
}
// Use 2 states: 1 is center square, 0 is the rest.
roi->roi_map =
@ -563,12 +594,12 @@ int main(int argc, char **argv) {
int layering_mode = 0;
int layer_flags[VPX_TS_MAX_PERIODICITY] = { 0 };
int flag_periodicity = 1;
#if VP8_ROI_MAP
#if ROI_MAP
vpx_roi_map_t roi;
#endif
vpx_svc_layer_id_t layer_id = { 0, 0 };
vpx_svc_layer_id_t layer_id;
const VpxInterface *encoder = NULL;
FILE *infile = NULL;
struct VpxInputContext input_ctx;
struct RateControlMetrics rc;
int64_t cx_time = 0;
const int min_args_base = 13;
@ -583,6 +614,15 @@ int main(int argc, char **argv) {
double sum_bitrate2 = 0.0;
double framerate = 30.0;
zero(rc.layer_target_bitrate);
memset(&layer_id, 0, sizeof(vpx_svc_layer_id_t));
memset(&input_ctx, 0, sizeof(input_ctx));
/* Setup default input stream settings */
input_ctx.framerate.numerator = 30;
input_ctx.framerate.denominator = 1;
input_ctx.only_i420 = 1;
input_ctx.bit_depth = 0;
exec_name = argv[0];
// Check usage and arguments.
if (argc < min_args) {
@ -621,6 +661,9 @@ int main(int argc, char **argv) {
die("Invalid number of arguments");
}
input_ctx.filename = argv[1];
open_input_file(&input_ctx);
#if CONFIG_VP9_HIGHBITDEPTH
switch (strtol(argv[argc - 1], NULL, 0)) {
case 8:
@ -637,14 +680,22 @@ int main(int argc, char **argv) {
break;
default: die("Invalid bit depth (8, 10, 12) %s", argv[argc - 1]);
}
if (!vpx_img_alloc(
&raw, bit_depth == VPX_BITS_8 ? VPX_IMG_FMT_I420 : VPX_IMG_FMT_I42016,
width, height, 32)) {
die("Failed to allocate image", width, height);
// Y4M reader has its own allocation.
if (input_ctx.file_type != FILE_TYPE_Y4M) {
if (!vpx_img_alloc(
&raw,
bit_depth == VPX_BITS_8 ? VPX_IMG_FMT_I420 : VPX_IMG_FMT_I42016,
width, height, 32)) {
die("Failed to allocate image", width, height);
}
}
#else
if (!vpx_img_alloc(&raw, VPX_IMG_FMT_I420, width, height, 32)) {
die("Failed to allocate image", width, height);
// Y4M reader has its own allocation.
if (input_ctx.file_type != FILE_TYPE_Y4M) {
if (!vpx_img_alloc(&raw, VPX_IMG_FMT_I420, width, height, 32)) {
die("Failed to allocate image", width, height);
}
}
#endif // CONFIG_VP9_HIGHBITDEPTH
@ -675,6 +726,9 @@ int main(int argc, char **argv) {
if (speed < 0) {
die("Invalid speed setting: must be positive");
}
if (strncmp(encoder->name, "vp9", 3) == 0 && speed > 9) {
warn("Mapping speed %d to speed 9.\n", speed);
}
for (i = min_args_base;
(int)i < min_args_base + mode_to_num_layers[layering_mode]; ++i) {
@ -722,13 +776,15 @@ int main(int argc, char **argv) {
set_rate_control_metrics(&rc, &cfg);
// Target bandwidth for the whole stream.
// Set to layer_target_bitrate for highest layer (total bitrate).
cfg.rc_target_bitrate = rc.layer_target_bitrate[cfg.ts_number_layers - 1];
// Open input file.
if (!(infile = fopen(argv[1], "rb"))) {
die("Failed to open %s for reading", argv[1]);
if (input_ctx.file_type == FILE_TYPE_Y4M) {
if (input_ctx.width != cfg.g_w || input_ctx.height != cfg.g_h) {
die("Incorrect width or height: %d x %d", cfg.g_w, cfg.g_h);
}
if (input_ctx.framerate.numerator != cfg.g_timebase.den ||
input_ctx.framerate.denominator != cfg.g_timebase.num) {
die("Incorrect framerate: numerator %d denominator %d",
cfg.g_timebase.num, cfg.g_timebase.den);
}
}
framerate = cfg.g_timebase.den / cfg.g_timebase.num;
@ -766,8 +822,8 @@ int main(int argc, char **argv) {
vpx_codec_control(&codec, VP8E_SET_NOISE_SENSITIVITY, kVp8DenoiserOff);
vpx_codec_control(&codec, VP8E_SET_STATIC_THRESHOLD, 1);
vpx_codec_control(&codec, VP8E_SET_GF_CBR_BOOST_PCT, 0);
#if VP8_ROI_MAP
vp8_set_roi_map(&cfg, &roi);
#if ROI_MAP
set_roi_map(encoder->name, &cfg, &roi);
if (vpx_codec_control(&codec, VP8E_SET_ROI_MAP, &roi))
die_codec(&codec, "Failed to set ROI map");
#endif
@ -783,7 +839,13 @@ int main(int argc, char **argv) {
vpx_codec_control(&codec, VP9E_SET_NOISE_SENSITIVITY, kVp9DenoiserOff);
vpx_codec_control(&codec, VP8E_SET_STATIC_THRESHOLD, 1);
vpx_codec_control(&codec, VP9E_SET_TUNE_CONTENT, 0);
vpx_codec_control(&codec, VP9E_SET_TILE_COLUMNS, (cfg.g_threads >> 1));
vpx_codec_control(&codec, VP9E_SET_TILE_COLUMNS, get_msb(cfg.g_threads));
#if ROI_MAP
set_roi_map(encoder->name, &cfg, &roi);
if (vpx_codec_control(&codec, VP9E_SET_ROI_MAP, &roi))
die_codec(&codec, "Failed to set ROI map");
vpx_codec_control(&codec, VP9E_SET_AQ_MODE, 0);
#endif
// TODO(marpan/jianj): There is an issue with row-mt for low resolutons at
// high speed settings, disable its use for those cases for now.
if (cfg.g_threads > 1 && ((cfg.g_w > 320 && cfg.g_h > 240) || speed < 7))
@ -822,6 +884,7 @@ int main(int argc, char **argv) {
layer_id.spatial_layer_id = 0;
layer_id.temporal_layer_id =
cfg.ts_layer_id[frame_cnt % cfg.ts_periodicity];
layer_id.temporal_layer_id_per_spatial[0] = layer_id.temporal_layer_id;
if (strncmp(encoder->name, "vp9", 3) == 0) {
vpx_codec_control(&codec, VP9E_SET_SVC_LAYER_ID, &layer_id);
} else if (strncmp(encoder->name, "vp8", 3) == 0) {
@ -830,7 +893,7 @@ int main(int argc, char **argv) {
}
flags = layer_flags[frame_cnt % flag_periodicity];
if (layering_mode == 0) flags = 0;
frame_avail = vpx_img_read(&raw, infile);
frame_avail = read_frame(&input_ctx, &raw);
if (frame_avail) ++rc.layer_input_frames[layer_id.temporal_layer_id];
vpx_usec_timer_start(&timer);
if (vpx_codec_encode(&codec, frame_avail ? &raw : NULL, pts, 1, flags,
@ -898,7 +961,7 @@ int main(int argc, char **argv) {
++frame_cnt;
pts += frame_duration;
}
fclose(infile);
close_input_file(&input_ctx);
printout_rate_control_summary(&rc, &cfg, frame_cnt);
printf("\n");
printf("Frame cnt and encoding time/FPS stats for encoding: %d %f %f \n",
@ -910,6 +973,12 @@ int main(int argc, char **argv) {
// Try to rewrite the output file headers with the actual frame count.
for (i = 0; i < cfg.ts_number_layers; ++i) vpx_video_writer_close(outfile[i]);
vpx_img_free(&raw);
if (input_ctx.file_type != FILE_TYPE_Y4M) {
vpx_img_free(&raw);
}
#if ROI_MAP
free(roi.roi_map);
#endif
return EXIT_SUCCESS;
}

View File

@ -76,12 +76,12 @@ int ivf_read_frame(FILE *infile, uint8_t **buffer, size_t *bytes_read,
size_t frame_size = 0;
if (fread(raw_header, IVF_FRAME_HDR_SZ, 1, infile) != 1) {
if (!feof(infile)) warn("Failed to read frame size\n");
if (!feof(infile)) warn("Failed to read frame size");
} else {
frame_size = mem_get_le32(raw_header);
if (frame_size > 256 * 1024 * 1024) {
warn("Read invalid frame size (%u)\n", (unsigned int)frame_size);
warn("Read invalid frame size (%u)", (unsigned int)frame_size);
frame_size = 0;
}
@ -92,7 +92,7 @@ int ivf_read_frame(FILE *infile, uint8_t **buffer, size_t *bytes_read,
*buffer = new_buffer;
*buffer_size = 2 * frame_size;
} else {
warn("Failed to allocate compressed data buffer\n");
warn("Failed to allocate compressed data buffer");
frame_size = 0;
}
}
@ -100,7 +100,7 @@ int ivf_read_frame(FILE *infile, uint8_t **buffer, size_t *bytes_read,
if (!feof(infile)) {
if (fread(*buffer, 1, frame_size, infile) != frame_size) {
warn("Failed to read full frame\n");
warn("Failed to read full frame");
return 1;
}

View File

@ -7,8 +7,8 @@
* in the file PATENTS. All contributing project authors may
* be found in the AUTHORS file in the root of the source tree.
*/
#ifndef IVFDEC_H_
#define IVFDEC_H_
#ifndef VPX_IVFDEC_H_
#define VPX_IVFDEC_H_
#include "./tools_common.h"
@ -25,4 +25,4 @@ int ivf_read_frame(FILE *infile, uint8_t **buffer, size_t *bytes_read,
} /* extern "C" */
#endif
#endif // IVFDEC_H_
#endif // VPX_IVFDEC_H_

View File

@ -7,8 +7,8 @@
* in the file PATENTS. All contributing project authors may
* be found in the AUTHORS file in the root of the source tree.
*/
#ifndef IVFENC_H_
#define IVFENC_H_
#ifndef VPX_IVFENC_H_
#define VPX_IVFENC_H_
#include "./tools_common.h"
@ -30,4 +30,4 @@ void ivf_write_frame_size(FILE *outfile, size_t frame_size);
} /* extern "C" */
#endif
#endif // IVFENC_H_
#endif // VPX_IVFENC_H_

View File

@ -943,18 +943,6 @@ GENERATE_XML = NO
XML_OUTPUT = xml
# The XML_SCHEMA tag can be used to specify an XML schema,
# which can be used by a validating XML parser to check the
# syntax of the XML files.
XML_SCHEMA =
# The XML_DTD tag can be used to specify an XML DTD,
# which can be used by a validating XML parser to check the
# syntax of the XML files.
XML_DTD =
# If the XML_PROGRAMLISTING tag is set to YES Doxygen will
# dump the program listings (including syntax highlighting
# and cross-referencing information) to the XML output. Note that

View File

@ -88,7 +88,6 @@ ifeq ($(CONFIG_VP9_ENCODER),yes)
CODEC_EXPORTS-yes += $(addprefix $(VP9_PREFIX),$(VP9_CX_EXPORTS))
CODEC_SRCS-yes += $(VP9_PREFIX)vp9cx.mk vpx/vp8.h vpx/vp8cx.h
INSTALL-LIBS-yes += include/vpx/vp8.h include/vpx/vp8cx.h
INSTALL-LIBS-$(CONFIG_SPATIAL_SVC) += include/vpx/svc_context.h
INSTALL_MAPS += include/vpx/% $(SRC_PATH_BARE)/$(VP9_PREFIX)/%
CODEC_DOC_SRCS += vpx/vp8.h vpx/vp8cx.h
CODEC_DOC_SECTIONS += vp9 vp9_encoder
@ -113,13 +112,6 @@ ifeq ($(CONFIG_DECODERS),yes)
CODEC_DOC_SECTIONS += decoder
endif
# Suppress -Wextra warnings in third party code.
$(BUILD_PFX)third_party/googletest/%.cc.o: CXXFLAGS += -Wno-missing-field-initializers
# Suppress -Wextra warnings in first party code pending investigation.
# https://bugs.chromium.org/p/webm/issues/detail?id=1069
$(BUILD_PFX)vp8/encoder/onyx_if.c.o: CFLAGS += -Wno-unknown-warning-option -Wno-clobbered
$(BUILD_PFX)vp8/decoder/onyxd_if.c.o: CFLAGS += -Wno-unknown-warning-option -Wno-clobbered
ifeq ($(CONFIG_MSVS),yes)
CODEC_LIB=$(if $(CONFIG_STATIC_MSVCRT),vpxmt,vpxmd)
GTEST_LIB=$(if $(CONFIG_STATIC_MSVCRT),gtestmt,gtestmd)
@ -153,9 +145,6 @@ INSTALL-SRCS-$(CONFIG_CODEC_SRCS) += vpx_dsp/x86/bitdepth_conversion_sse2.asm
endif
CODEC_EXPORTS-yes += vpx/exports_com
CODEC_EXPORTS-$(CONFIG_ENCODERS) += vpx/exports_enc
ifeq ($(CONFIG_SPATIAL_SVC),yes)
CODEC_EXPORTS-$(CONFIG_ENCODERS) += vpx/exports_spatial_svc
endif
CODEC_EXPORTS-$(CONFIG_DECODERS) += vpx/exports_dec
INSTALL-LIBS-yes += include/vpx/vpx_codec.h
@ -206,6 +195,8 @@ vpx.def: $(call enabled,CODEC_EXPORTS)
--out=$@ $^
CLEAN-OBJS += vpx.def
vpx.$(VCPROJ_SFX): VCPROJ_SRCS=$(filter-out $(addprefix %, $(ASM_INCLUDES)), $^)
vpx.$(VCPROJ_SFX): $(CODEC_SRCS) vpx.def
@echo " [CREATE] $@"
$(qexec)$(GEN_VCPROJ) \
@ -218,7 +209,15 @@ vpx.$(VCPROJ_SFX): $(CODEC_SRCS) vpx.def
--ver=$(CONFIG_VS_VERSION) \
--src-path-bare="$(SRC_PATH_BARE)" \
--out=$@ $(CFLAGS) \
$(filter-out $(addprefix %, $(ASM_INCLUDES)), $^) \
$(filter $(SRC_PATH_BARE)/vp8/%.c, $(VCPROJ_SRCS)) \
$(filter $(SRC_PATH_BARE)/vp8/%.h, $(VCPROJ_SRCS)) \
$(filter $(SRC_PATH_BARE)/vp9/%.c, $(VCPROJ_SRCS)) \
$(filter $(SRC_PATH_BARE)/vp9/%.h, $(VCPROJ_SRCS)) \
$(filter $(SRC_PATH_BARE)/vpx/%, $(VCPROJ_SRCS)) \
$(filter $(SRC_PATH_BARE)/vpx_dsp/%, $(VCPROJ_SRCS)) \
$(filter-out $(addprefix $(SRC_PATH_BARE)/, \
vp8/%.c vp8/%.h vp9/%.c vp9/%.h vpx/% vpx_dsp/%), \
$(VCPROJ_SRCS)) \
--src-path-bare="$(SRC_PATH_BARE)" \
PROJECTS-yes += vpx.$(VCPROJ_SFX)
@ -233,8 +232,8 @@ OBJS-yes += $(LIBVPX_OBJS)
LIBS-$(if yes,$(CONFIG_STATIC)) += $(BUILD_PFX)libvpx.a $(BUILD_PFX)libvpx_g.a
$(BUILD_PFX)libvpx_g.a: $(LIBVPX_OBJS)
SO_VERSION_MAJOR := 5
SO_VERSION_MINOR := 0
SO_VERSION_MAJOR := 6
SO_VERSION_MINOR := 1
SO_VERSION_PATCH := 0
ifeq ($(filter darwin%,$(TGT_OS)),$(TGT_OS))
LIBVPX_SO := libvpx.$(SO_VERSION_MAJOR).dylib
@ -274,18 +273,6 @@ $(BUILD_PFX)$(LIBVPX_SO): extralibs += -lm
$(BUILD_PFX)$(LIBVPX_SO): SONAME = libvpx.so.$(SO_VERSION_MAJOR)
$(BUILD_PFX)$(LIBVPX_SO): EXPORTS_FILE = $(EXPORT_FILE)
libvpx.ver: $(call enabled,CODEC_EXPORTS)
@echo " [CREATE] $@"
$(qexec)echo "{ global:" > $@
$(qexec)for f in $?; do awk '{print $$2";"}' < $$f >>$@; done
$(qexec)echo "local: *; };" >> $@
CLEAN-OBJS += libvpx.ver
libvpx.syms: $(call enabled,CODEC_EXPORTS)
@echo " [CREATE] $@"
$(qexec)awk '{print "_"$$2}' $^ >$@
CLEAN-OBJS += libvpx.syms
libvpx.def: $(call enabled,CODEC_EXPORTS)
@echo " [CREATE] $@"
$(qexec)echo LIBRARY $(LIBVPX_SO:.dll=) INITINSTANCE TERMINSTANCE > $@
@ -345,6 +332,18 @@ INSTALL_MAPS += $(LIBSUBDIR)/pkgconfig/%.pc %.pc
CLEAN-OBJS += vpx.pc
endif
libvpx.ver: $(call enabled,CODEC_EXPORTS)
@echo " [CREATE] $@"
$(qexec)echo "{ global:" > $@
$(qexec)for f in $?; do awk '{print $$2";"}' < $$f >>$@; done
$(qexec)echo "local: *; };" >> $@
CLEAN-OBJS += libvpx.ver
libvpx.syms: $(call enabled,CODEC_EXPORTS)
@echo " [CREATE] $@"
$(qexec)awk '{print "_"$$2}' $^ >$@
CLEAN-OBJS += libvpx.syms
#
# Rule to make assembler configuration file from C configuration file
#

View File

@ -25,8 +25,10 @@
release.
- The \ref readme contains instructions on recompiling the sample applications.
- Read the \ref usage "usage" for a narrative on codec usage.
\if samples
- Read the \ref samples "sample code" for examples of how to interact with the
codec.
\endif
- \ref codec reference
\if encoder
- \ref encoder reference

View File

@ -163,7 +163,7 @@ void MD5Final(md5byte digest[16], struct MD5Context *ctx) {
*/
VPX_NO_UNSIGNED_OVERFLOW_CHECK void MD5Transform(UWORD32 buf[4],
UWORD32 const in[16]) {
register UWORD32 a, b, c, d;
UWORD32 a, b, c, d;
a = buf[0];
b = buf[1];

View File

@ -20,8 +20,8 @@
* Still in the public domain.
*/
#ifndef MD5_UTILS_H_
#define MD5_UTILS_H_
#ifndef VPX_MD5_UTILS_H_
#define VPX_MD5_UTILS_H_
#ifdef __cplusplus
extern "C" {
@ -46,4 +46,4 @@ void MD5Transform(UWORD32 buf[4], UWORD32 const in[16]);
} // extern "C"
#endif
#endif // MD5_UTILS_H_
#endif // VPX_MD5_UTILS_H_

View File

@ -8,8 +8,8 @@
* be found in the AUTHORS file in the root of the source tree.
*/
#ifndef RATE_HIST_H_
#define RATE_HIST_H_
#ifndef VPX_RATE_HIST_H_
#define VPX_RATE_HIST_H_
#include "vpx/vpx_encoder.h"
@ -37,4 +37,4 @@ void show_rate_histogram(struct rate_hist *hist, const vpx_codec_enc_cfg_t *cfg,
} // extern "C"
#endif
#endif // RATE_HIST_H_
#endif // VPX_RATE_HIST_H_

View File

@ -8,8 +8,8 @@
* be found in the AUTHORS file in the root of the source tree.
*/
#ifndef TEST_ACM_RANDOM_H_
#define TEST_ACM_RANDOM_H_
#ifndef VPX_TEST_ACM_RANDOM_H_
#define VPX_TEST_ACM_RANDOM_H_
#include <assert.h>
@ -34,6 +34,24 @@ class ACMRandom {
return (value >> 15) & 0xffff;
}
int32_t Rand20Signed(void) {
// Use 20 bits: values between 524287 and -524288.
const uint32_t value = random_.Generate(1048576);
return static_cast<int32_t>(value) - 524288;
}
int16_t Rand16Signed(void) {
// Use 16 bits: values between 32767 and -32768.
const uint32_t value = random_.Generate(65536);
return static_cast<int16_t>(value) - 32768;
}
int16_t Rand13Signed(void) {
// Use 13 bits: values between 4095 and -4096.
const uint32_t value = random_.Generate(8192);
return static_cast<int16_t>(value) - 4096;
}
int16_t Rand9Signed(void) {
// Use 9 bits: values between 255 (0x0FF) and -256 (0x100).
const uint32_t value = random_.Generate(512);
@ -73,4 +91,4 @@ class ACMRandom {
} // namespace libvpx_test
#endif // TEST_ACM_RANDOM_H_
#endif // VPX_TEST_ACM_RANDOM_H_

View File

@ -74,7 +74,7 @@ class ActiveMapRefreshTest
::libvpx_test::Encoder *encoder) {
::libvpx_test::Y4mVideoSource *y4m_video =
static_cast<libvpx_test::Y4mVideoSource *>(video);
if (video->frame() == 1) {
if (video->frame() == 0) {
encoder->Control(VP8E_SET_CPUUSED, cpu_used_);
encoder->Control(VP9E_SET_AQ_MODE, kAqModeCyclicRefresh);
} else if (video->frame() >= 2 && video->img()) {

View File

@ -35,7 +35,7 @@ class ActiveMapTest
virtual void PreEncodeFrameHook(::libvpx_test::VideoSource *video,
::libvpx_test::Encoder *encoder) {
if (video->frame() == 1) {
if (video->frame() == 0) {
encoder->Control(VP8E_SET_CPUUSED, cpu_used_);
} else if (video->frame() == 3) {
vpx_active_map_t map = vpx_active_map_t();

View File

@ -8,8 +8,11 @@
* be found in the AUTHORS file in the root of the source tree.
*/
#include <math.h>
#include <tuple>
#include "test/clear_system_state.h"
#include "test/register_state_check.h"
#include "test/util.h"
#include "third_party/googletest/src/include/gtest/gtest.h"
#include "./vpx_dsp_rtcd.h"
#include "vpx/vpx_integer.h"
@ -25,7 +28,10 @@ typedef void (*AddNoiseFunc)(uint8_t *start, const int8_t *noise,
int blackclamp, int whiteclamp, int width,
int height, int pitch);
class AddNoiseTest : public ::testing::TestWithParam<AddNoiseFunc> {
typedef std::tuple<double, AddNoiseFunc> AddNoiseTestFPParam;
class AddNoiseTest : public ::testing::Test,
public ::testing::WithParamInterface<AddNoiseTestFPParam> {
public:
virtual void TearDown() { libvpx_test::ClearSystemState(); }
virtual ~AddNoiseTest() {}
@ -44,14 +50,14 @@ TEST_P(AddNoiseTest, CheckNoiseAdded) {
const int height = 64;
const int image_size = width * height;
int8_t noise[kNoiseSize];
const int clamp = vpx_setup_noise(4.4, noise, kNoiseSize);
const int clamp = vpx_setup_noise(GET_PARAM(0), noise, kNoiseSize);
uint8_t *const s =
reinterpret_cast<uint8_t *>(vpx_calloc(image_size, sizeof(*s)));
ASSERT_TRUE(s != NULL);
memset(s, 99, image_size * sizeof(*s));
ASM_REGISTER_STATE_CHECK(
GetParam()(s, noise, clamp, clamp, width, height, width));
GET_PARAM(1)(s, noise, clamp, clamp, width, height, width));
// Check to make sure we don't end up having either the same or no added
// noise either vertically or horizontally.
@ -70,7 +76,7 @@ TEST_P(AddNoiseTest, CheckNoiseAdded) {
memset(s, 255, image_size);
ASM_REGISTER_STATE_CHECK(
GetParam()(s, noise, clamp, clamp, width, height, width));
GET_PARAM(1)(s, noise, clamp, clamp, width, height, width));
// Check to make sure don't roll over.
for (int i = 0; i < image_size; ++i) {
@ -81,7 +87,7 @@ TEST_P(AddNoiseTest, CheckNoiseAdded) {
memset(s, 0, image_size);
ASM_REGISTER_STATE_CHECK(
GetParam()(s, noise, clamp, clamp, width, height, width));
GET_PARAM(1)(s, noise, clamp, clamp, width, height, width));
// Check to make sure don't roll under.
for (int i = 0; i < image_size; ++i) {
@ -108,7 +114,7 @@ TEST_P(AddNoiseTest, CheckCvsAssembly) {
srand(0);
ASM_REGISTER_STATE_CHECK(
GetParam()(s, noise, clamp, clamp, width, height, width));
GET_PARAM(1)(s, noise, clamp, clamp, width, height, width));
srand(0);
ASM_REGISTER_STATE_CHECK(
vpx_plane_add_noise_c(d, noise, clamp, clamp, width, height, width));
@ -121,16 +127,24 @@ TEST_P(AddNoiseTest, CheckCvsAssembly) {
vpx_free(s);
}
INSTANTIATE_TEST_CASE_P(C, AddNoiseTest,
::testing::Values(vpx_plane_add_noise_c));
using std::make_tuple;
INSTANTIATE_TEST_CASE_P(
C, AddNoiseTest,
::testing::Values(make_tuple(3.25, vpx_plane_add_noise_c),
make_tuple(4.4, vpx_plane_add_noise_c)));
#if HAVE_SSE2
INSTANTIATE_TEST_CASE_P(SSE2, AddNoiseTest,
::testing::Values(vpx_plane_add_noise_sse2));
INSTANTIATE_TEST_CASE_P(
SSE2, AddNoiseTest,
::testing::Values(make_tuple(3.25, vpx_plane_add_noise_sse2),
make_tuple(4.4, vpx_plane_add_noise_sse2)));
#endif
#if HAVE_MSA
INSTANTIATE_TEST_CASE_P(MSA, AddNoiseTest,
::testing::Values(vpx_plane_add_noise_msa));
INSTANTIATE_TEST_CASE_P(
MSA, AddNoiseTest,
::testing::Values(make_tuple(3.25, vpx_plane_add_noise_msa),
make_tuple(4.4, vpx_plane_add_noise_msa)));
#endif
} // namespace

View File

@ -32,7 +32,7 @@ class AltRefAqSegmentTest
virtual void PreEncodeFrameHook(::libvpx_test::VideoSource *video,
::libvpx_test::Encoder *encoder) {
if (video->frame() == 1) {
if (video->frame() == 0) {
encoder->Control(VP8E_SET_CPUUSED, set_cpu_used_);
encoder->Control(VP9E_SET_ALT_REF_AQ, alt_ref_aq_mode_);
encoder->Control(VP9E_SET_AQ_MODE, aq_mode_);

View File

@ -35,7 +35,7 @@ class AltRefTest : public ::libvpx_test::EncoderTest,
virtual void PreEncodeFrameHook(libvpx_test::VideoSource *video,
libvpx_test::Encoder *encoder) {
if (video->frame() == 1) {
if (video->frame() == 0) {
encoder->Control(VP8E_SET_ENABLEAUTOALTREF, 1);
encoder->Control(VP8E_SET_CPUUSED, 3);
}

View File

@ -3,12 +3,12 @@ Android.mk will build vpx unittests on android.
./libvpx/configure --target=armv7-android-gcc --enable-external-build \
--enable-postproc --disable-install-srcs --enable-multi-res-encoding \
--enable-temporal-denoising --disable-unit-tests --disable-install-docs \
--disable-examples --disable-runtime-cpu-detect --sdk-path=$NDK
--disable-examples --disable-runtime-cpu-detect
2) From the parent directory, invoke ndk-build:
NDK_PROJECT_PATH=. ndk-build APP_BUILD_SCRIPT=./libvpx/test/android/Android.mk \
APP_ABI=armeabi-v7a APP_PLATFORM=android-18 APP_OPTIM=release \
APP_STL=gnustl_static
APP_STL=c++_static
Note: Both adb and ndk-build are available prebuilt at:
https://chromium.googlesource.com/android_tools

View File

@ -31,7 +31,7 @@ class AqSegmentTest
virtual void PreEncodeFrameHook(::libvpx_test::VideoSource *video,
::libvpx_test::Encoder *encoder) {
if (video->frame() == 1) {
if (video->frame() == 0) {
encoder->Control(VP8E_SET_CPUUSED, set_cpu_used_);
encoder->Control(VP9E_SET_AQ_MODE, aq_mode_);
encoder->Control(VP8E_SET_MAX_INTRA_BITRATE_PCT, 100);

View File

@ -11,6 +11,7 @@
#include <limits.h>
#include <stdio.h>
#include <string.h>
#include <tuple>
#include "third_party/googletest/src/include/gtest/gtest.h"
@ -22,40 +23,43 @@
#include "test/clear_system_state.h"
#include "test/register_state_check.h"
#include "test/util.h"
#include "vpx/vpx_codec.h"
#include "vpx_mem/vpx_mem.h"
#include "vpx_ports/vpx_timer.h"
using libvpx_test::ACMRandom;
namespace {
template <typename Pixel>
class AverageTestBase : public ::testing::Test {
public:
AverageTestBase(int width, int height) : width_(width), height_(height) {}
AverageTestBase(int width, int height)
: width_(width), height_(height), source_data_(NULL), source_stride_(0),
bit_depth_(8) {}
static void SetUpTestCase() {
source_data_ = reinterpret_cast<uint8_t *>(
vpx_memalign(kDataAlignment, kDataBlockSize));
}
static void TearDownTestCase() {
virtual void TearDown() {
vpx_free(source_data_);
source_data_ = NULL;
libvpx_test::ClearSystemState();
}
virtual void TearDown() { libvpx_test::ClearSystemState(); }
protected:
// Handle blocks up to 4 blocks 64x64 with stride up to 128
static const int kDataAlignment = 16;
static const int kDataBlockSize = 64 * 128;
virtual void SetUp() {
source_data_ = reinterpret_cast<Pixel *>(
vpx_memalign(kDataAlignment, kDataBlockSize * sizeof(source_data_[0])));
ASSERT_TRUE(source_data_ != NULL);
source_stride_ = (width_ + 31) & ~31;
bit_depth_ = 8;
rnd_.Reset(ACMRandom::DeterministicSeed());
}
// Sum Pixels
static unsigned int ReferenceAverage8x8(const uint8_t *source, int pitch) {
static unsigned int ReferenceAverage8x8(const Pixel *source, int pitch) {
unsigned int average = 0;
for (int h = 0; h < 8; ++h) {
for (int w = 0; w < 8; ++w) average += source[h * pitch + w];
@ -63,7 +67,7 @@ class AverageTestBase : public ::testing::Test {
return ((average + 32) >> 6);
}
static unsigned int ReferenceAverage4x4(const uint8_t *source, int pitch) {
static unsigned int ReferenceAverage4x4(const Pixel *source, int pitch) {
unsigned int average = 0;
for (int h = 0; h < 4; ++h) {
for (int w = 0; w < 4; ++w) average += source[h * pitch + w];
@ -71,7 +75,7 @@ class AverageTestBase : public ::testing::Test {
return ((average + 8) >> 4);
}
void FillConstant(uint8_t fill_constant) {
void FillConstant(Pixel fill_constant) {
for (int i = 0; i < width_ * height_; ++i) {
source_data_[i] = fill_constant;
}
@ -79,21 +83,22 @@ class AverageTestBase : public ::testing::Test {
void FillRandom() {
for (int i = 0; i < width_ * height_; ++i) {
source_data_[i] = rnd_.Rand8();
source_data_[i] = rnd_.Rand16() & ((1 << bit_depth_) - 1);
}
}
int width_, height_;
static uint8_t *source_data_;
Pixel *source_data_;
int source_stride_;
int bit_depth_;
ACMRandom rnd_;
};
typedef unsigned int (*AverageFunction)(const uint8_t *s, int pitch);
typedef std::tr1::tuple<int, int, int, int, AverageFunction> AvgFunc;
typedef std::tuple<int, int, int, int, AverageFunction> AvgFunc;
class AverageTest : public AverageTestBase,
class AverageTest : public AverageTestBase<uint8_t>,
public ::testing::WithParamInterface<AvgFunc> {
public:
AverageTest() : AverageTestBase(GET_PARAM(0), GET_PARAM(1)) {}
@ -119,12 +124,40 @@ class AverageTest : public AverageTestBase,
}
};
#if CONFIG_VP9_HIGHBITDEPTH
class AverageTestHBD : public AverageTestBase<uint16_t>,
public ::testing::WithParamInterface<AvgFunc> {
public:
AverageTestHBD() : AverageTestBase(GET_PARAM(0), GET_PARAM(1)) {}
protected:
void CheckAverages() {
const int block_size = GET_PARAM(3);
unsigned int expected = 0;
if (block_size == 8) {
expected =
ReferenceAverage8x8(source_data_ + GET_PARAM(2), source_stride_);
} else if (block_size == 4) {
expected =
ReferenceAverage4x4(source_data_ + GET_PARAM(2), source_stride_);
}
ASM_REGISTER_STATE_CHECK(GET_PARAM(4)(
CONVERT_TO_BYTEPTR(source_data_ + GET_PARAM(2)), source_stride_));
unsigned int actual = GET_PARAM(4)(
CONVERT_TO_BYTEPTR(source_data_ + GET_PARAM(2)), source_stride_);
EXPECT_EQ(expected, actual);
}
};
#endif // CONFIG_VP9_HIGHBITDEPTH
typedef void (*IntProRowFunc)(int16_t hbuf[16], uint8_t const *ref,
const int ref_stride, const int height);
typedef std::tr1::tuple<int, IntProRowFunc, IntProRowFunc> IntProRowParam;
typedef std::tuple<int, IntProRowFunc, IntProRowFunc> IntProRowParam;
class IntProRowTest : public AverageTestBase,
class IntProRowTest : public AverageTestBase<uint8_t>,
public ::testing::WithParamInterface<IntProRowParam> {
public:
IntProRowTest()
@ -135,6 +168,10 @@ class IntProRowTest : public AverageTestBase,
protected:
virtual void SetUp() {
source_data_ = reinterpret_cast<uint8_t *>(
vpx_memalign(kDataAlignment, kDataBlockSize * sizeof(source_data_[0])));
ASSERT_TRUE(source_data_ != NULL);
hbuf_asm_ = reinterpret_cast<int16_t *>(
vpx_memalign(kDataAlignment, sizeof(*hbuf_asm_) * 16));
hbuf_c_ = reinterpret_cast<int16_t *>(
@ -142,6 +179,8 @@ class IntProRowTest : public AverageTestBase,
}
virtual void TearDown() {
vpx_free(source_data_);
source_data_ = NULL;
vpx_free(hbuf_c_);
hbuf_c_ = NULL;
vpx_free(hbuf_asm_);
@ -164,9 +203,9 @@ class IntProRowTest : public AverageTestBase,
typedef int16_t (*IntProColFunc)(uint8_t const *ref, const int width);
typedef std::tr1::tuple<int, IntProColFunc, IntProColFunc> IntProColParam;
typedef std::tuple<int, IntProColFunc, IntProColFunc> IntProColParam;
class IntProColTest : public AverageTestBase,
class IntProColTest : public AverageTestBase<uint8_t>,
public ::testing::WithParamInterface<IntProColParam> {
public:
IntProColTest() : AverageTestBase(GET_PARAM(0), 1), sum_asm_(0), sum_c_(0) {
@ -189,7 +228,7 @@ class IntProColTest : public AverageTestBase,
};
typedef int (*SatdFunc)(const tran_low_t *coeffs, int length);
typedef std::tr1::tuple<int, SatdFunc> SatdTestParam;
typedef std::tuple<int, SatdFunc> SatdTestParam;
class SatdTest : public ::testing::Test,
public ::testing::WithParamInterface<SatdTestParam> {
@ -212,12 +251,7 @@ class SatdTest : public ::testing::Test,
for (int i = 0; i < satd_size_; ++i) src_[i] = val;
}
void FillRandom() {
for (int i = 0; i < satd_size_; ++i) {
const int16_t tmp = rnd_.Rand16();
src_[i] = (tran_low_t)tmp;
}
}
virtual void FillRandom() = 0;
void Check(const int expected) {
int total;
@ -225,17 +259,29 @@ class SatdTest : public ::testing::Test,
EXPECT_EQ(expected, total);
}
tran_low_t *GetCoeff() const { return src_; }
int satd_size_;
ACMRandom rnd_;
tran_low_t *src_;
private:
tran_low_t *src_;
SatdFunc satd_func_;
ACMRandom rnd_;
};
class SatdLowbdTest : public SatdTest {
protected:
virtual void FillRandom() {
for (int i = 0; i < satd_size_; ++i) {
const int16_t tmp = rnd_.Rand16Signed();
src_[i] = (tran_low_t)tmp;
}
}
};
typedef int64_t (*BlockErrorFunc)(const tran_low_t *coeff,
const tran_low_t *dqcoeff, int block_size);
typedef std::tr1::tuple<int, BlockErrorFunc> BlockErrorTestFPParam;
typedef std::tuple<int, BlockErrorFunc> BlockErrorTestFPParam;
class BlockErrorTestFP
: public ::testing::Test,
@ -279,6 +325,10 @@ class BlockErrorTestFP
EXPECT_EQ(expected, total);
}
tran_low_t *GetCoeff() const { return coeff_; }
tran_low_t *GetDQCoeff() const { return dqcoeff_; }
int txfm_size_;
private:
@ -288,8 +338,6 @@ class BlockErrorTestFP
ACMRandom rnd_;
};
uint8_t *AverageTestBase::source_data_ = NULL;
TEST_P(AverageTest, MinValue) {
FillConstant(0);
CheckAverages();
@ -308,6 +356,27 @@ TEST_P(AverageTest, Random) {
CheckAverages();
}
}
#if CONFIG_VP9_HIGHBITDEPTH
TEST_P(AverageTestHBD, MinValue) {
FillConstant(0);
CheckAverages();
}
TEST_P(AverageTestHBD, MaxValue) {
FillConstant((1 << VPX_BITS_12) - 1);
CheckAverages();
}
TEST_P(AverageTestHBD, Random) {
bit_depth_ = VPX_BITS_12;
// The reference frame, but not the source frame, may be unaligned for
// certain types of searches.
for (int i = 0; i < 1000; i++) {
FillRandom();
CheckAverages();
}
}
#endif // CONFIG_VP9_HIGHBITDEPTH
TEST_P(IntProRowTest, MinValue) {
FillConstant(0);
@ -339,27 +408,27 @@ TEST_P(IntProColTest, Random) {
RunComparison();
}
TEST_P(SatdTest, MinValue) {
TEST_P(SatdLowbdTest, MinValue) {
const int kMin = -32640;
const int expected = -kMin * satd_size_;
FillConstant(kMin);
Check(expected);
}
TEST_P(SatdTest, MaxValue) {
TEST_P(SatdLowbdTest, MaxValue) {
const int kMax = 32640;
const int expected = kMax * satd_size_;
FillConstant(kMax);
Check(expected);
}
TEST_P(SatdTest, Random) {
TEST_P(SatdLowbdTest, Random) {
int expected;
switch (satd_size_) {
case 16: expected = 205298; break;
case 64: expected = 1113950; break;
case 256: expected = 4268415; break;
case 1024: expected = 16954082; break;
case 16: expected = 263252; break;
case 64: expected = 1105420; break;
case 256: expected = 4252250; break;
case 1024: expected = 16876840; break;
default:
FAIL() << "Invalid satd size (" << satd_size_
<< ") valid: 16/64/256/1024";
@ -368,11 +437,12 @@ TEST_P(SatdTest, Random) {
Check(expected);
}
TEST_P(SatdTest, DISABLED_Speed) {
TEST_P(SatdLowbdTest, DISABLED_Speed) {
const int kCountSpeedTestBlock = 20000;
vpx_usec_timer timer;
DECLARE_ALIGNED(16, tran_low_t, coeff[1024]);
const int blocksize = GET_PARAM(0);
FillRandom();
tran_low_t *coeff = GetCoeff();
vpx_usec_timer_start(&timer);
for (int i = 0; i < kCountSpeedTestBlock; ++i) {
@ -383,6 +453,62 @@ TEST_P(SatdTest, DISABLED_Speed) {
printf("blocksize: %4d time: %4d us\n", blocksize, elapsed_time);
}
#if CONFIG_VP9_HIGHBITDEPTH
class SatdHighbdTest : public SatdTest {
protected:
virtual void FillRandom() {
for (int i = 0; i < satd_size_; ++i) {
src_[i] = rnd_.Rand20Signed();
}
}
};
TEST_P(SatdHighbdTest, MinValue) {
const int kMin = -524280;
const int expected = -kMin * satd_size_;
FillConstant(kMin);
Check(expected);
}
TEST_P(SatdHighbdTest, MaxValue) {
const int kMax = 524280;
const int expected = kMax * satd_size_;
FillConstant(kMax);
Check(expected);
}
TEST_P(SatdHighbdTest, Random) {
int expected;
switch (satd_size_) {
case 16: expected = 5249712; break;
case 64: expected = 18362120; break;
case 256: expected = 66100520; break;
case 1024: expected = 266094734; break;
default:
FAIL() << "Invalid satd size (" << satd_size_
<< ") valid: 16/64/256/1024";
}
FillRandom();
Check(expected);
}
TEST_P(SatdHighbdTest, DISABLED_Speed) {
const int kCountSpeedTestBlock = 20000;
vpx_usec_timer timer;
const int blocksize = GET_PARAM(0);
FillRandom();
tran_low_t *coeff = GetCoeff();
vpx_usec_timer_start(&timer);
for (int i = 0; i < kCountSpeedTestBlock; ++i) {
GET_PARAM(1)(coeff, blocksize);
}
vpx_usec_timer_mark(&timer);
const int elapsed_time = static_cast<int>(vpx_usec_timer_elapsed(&timer));
printf("blocksize: %4d time: %4d us\n", blocksize, elapsed_time);
}
#endif // CONFIG_VP9_HIGHBITDEPTH
TEST_P(BlockErrorTestFP, MinValue) {
const int64_t kMin = -32640;
const int64_t expected = kMin * kMin * txfm_size_;
@ -415,9 +541,10 @@ TEST_P(BlockErrorTestFP, Random) {
TEST_P(BlockErrorTestFP, DISABLED_Speed) {
const int kCountSpeedTestBlock = 20000;
vpx_usec_timer timer;
DECLARE_ALIGNED(16, tran_low_t, coeff[1024]);
DECLARE_ALIGNED(16, tran_low_t, dqcoeff[1024]);
const int blocksize = GET_PARAM(0);
FillRandom();
tran_low_t *coeff = GetCoeff();
tran_low_t *dqcoeff = GetDQCoeff();
vpx_usec_timer_start(&timer);
for (int i = 0; i < kCountSpeedTestBlock; ++i) {
@ -428,14 +555,34 @@ TEST_P(BlockErrorTestFP, DISABLED_Speed) {
printf("blocksize: %4d time: %4d us\n", blocksize, elapsed_time);
}
using std::tr1::make_tuple;
using std::make_tuple;
INSTANTIATE_TEST_CASE_P(
C, AverageTest,
::testing::Values(make_tuple(16, 16, 1, 8, &vpx_avg_8x8_c),
make_tuple(16, 16, 1, 4, &vpx_avg_4x4_c)));
INSTANTIATE_TEST_CASE_P(C, SatdTest,
#if CONFIG_VP9_HIGHBITDEPTH
INSTANTIATE_TEST_CASE_P(
C, AverageTestHBD,
::testing::Values(make_tuple(16, 16, 1, 8, &vpx_highbd_avg_8x8_c),
make_tuple(16, 16, 1, 4, &vpx_highbd_avg_4x4_c)));
#if HAVE_SSE2
INSTANTIATE_TEST_CASE_P(
SSE2, AverageTestHBD,
::testing::Values(make_tuple(16, 16, 1, 8, &vpx_highbd_avg_8x8_sse2),
make_tuple(16, 16, 1, 4, &vpx_highbd_avg_4x4_sse2)));
#endif // HAVE_SSE2
INSTANTIATE_TEST_CASE_P(C, SatdHighbdTest,
::testing::Values(make_tuple(16, &vpx_satd_c),
make_tuple(64, &vpx_satd_c),
make_tuple(256, &vpx_satd_c),
make_tuple(1024, &vpx_satd_c)));
#endif // CONFIG_VP9_HIGHBITDEPTH
INSTANTIATE_TEST_CASE_P(C, SatdLowbdTest,
::testing::Values(make_tuple(16, &vpx_satd_c),
make_tuple(64, &vpx_satd_c),
make_tuple(256, &vpx_satd_c),
@ -472,7 +619,7 @@ INSTANTIATE_TEST_CASE_P(
make_tuple(64, &vpx_int_pro_col_sse2,
&vpx_int_pro_col_c)));
INSTANTIATE_TEST_CASE_P(SSE2, SatdTest,
INSTANTIATE_TEST_CASE_P(SSE2, SatdLowbdTest,
::testing::Values(make_tuple(16, &vpx_satd_sse2),
make_tuple(64, &vpx_satd_sse2),
make_tuple(256, &vpx_satd_sse2),
@ -487,12 +634,21 @@ INSTANTIATE_TEST_CASE_P(
#endif // HAVE_SSE2
#if HAVE_AVX2
INSTANTIATE_TEST_CASE_P(AVX2, SatdTest,
INSTANTIATE_TEST_CASE_P(AVX2, SatdLowbdTest,
::testing::Values(make_tuple(16, &vpx_satd_avx2),
make_tuple(64, &vpx_satd_avx2),
make_tuple(256, &vpx_satd_avx2),
make_tuple(1024, &vpx_satd_avx2)));
#if CONFIG_VP9_HIGHBITDEPTH
INSTANTIATE_TEST_CASE_P(
AVX2, SatdHighbdTest,
::testing::Values(make_tuple(16, &vpx_highbd_satd_avx2),
make_tuple(64, &vpx_highbd_satd_avx2),
make_tuple(256, &vpx_highbd_satd_avx2),
make_tuple(1024, &vpx_highbd_satd_avx2)));
#endif // CONFIG_VP9_HIGHBITDEPTH
INSTANTIATE_TEST_CASE_P(
AVX2, BlockErrorTestFP,
::testing::Values(make_tuple(16, &vp9_block_error_fp_avx2),
@ -525,7 +681,7 @@ INSTANTIATE_TEST_CASE_P(
make_tuple(64, &vpx_int_pro_col_neon,
&vpx_int_pro_col_c)));
INSTANTIATE_TEST_CASE_P(NEON, SatdTest,
INSTANTIATE_TEST_CASE_P(NEON, SatdLowbdTest,
::testing::Values(make_tuple(16, &vpx_satd_neon),
make_tuple(64, &vpx_satd_neon),
make_tuple(256, &vpx_satd_neon),
@ -570,7 +726,7 @@ INSTANTIATE_TEST_CASE_P(
// TODO(jingning): Remove the highbitdepth flag once the SIMD functions are
// in place.
#if !CONFIG_VP9_HIGHBITDEPTH
INSTANTIATE_TEST_CASE_P(MSA, SatdTest,
INSTANTIATE_TEST_CASE_P(MSA, SatdLowbdTest,
::testing::Values(make_tuple(16, &vpx_satd_msa),
make_tuple(64, &vpx_satd_msa),
make_tuple(256, &vpx_satd_msa),

38
libs/libvpx/test/bench.cc Normal file
View File

@ -0,0 +1,38 @@
/*
* Copyright (c) 2018 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 <stdio.h>
#include <algorithm>
#include "test/bench.h"
#include "vpx_ports/vpx_timer.h"
void AbstractBench::RunNTimes(int n) {
for (int r = 0; r < VPX_BENCH_ROBUST_ITER; r++) {
vpx_usec_timer timer;
vpx_usec_timer_start(&timer);
for (int j = 0; j < n; ++j) {
Run();
}
vpx_usec_timer_mark(&timer);
times_[r] = static_cast<int>(vpx_usec_timer_elapsed(&timer));
}
}
void AbstractBench::PrintMedian(const char *title) {
std::sort(times_, times_ + VPX_BENCH_ROBUST_ITER);
const int med = times_[VPX_BENCH_ROBUST_ITER >> 1];
int sad = 0;
for (int t = 0; t < VPX_BENCH_ROBUST_ITER; t++) {
sad += abs(times_[t] - med);
}
printf("[%10s] %s %.1f ms ( ±%.1f ms )\n", "BENCH ", title, med / 1000.0,
sad / (VPX_BENCH_ROBUST_ITER * 1000.0));
}

30
libs/libvpx/test/bench.h Normal file
View File

@ -0,0 +1,30 @@
/*
* Copyright (c) 2018 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.
*/
#ifndef VPX_TEST_BENCH_H_
#define VPX_TEST_BENCH_H_
// Number of iterations used to compute median run time.
#define VPX_BENCH_ROBUST_ITER 15
class AbstractBench {
public:
void RunNTimes(int n);
void PrintMedian(const char *title);
protected:
// Implement this method and put the code to benchmark in it.
virtual void Run() = 0;
private:
int times_[VPX_BENCH_ROBUST_ITER];
};
#endif // VPX_TEST_BENCH_H_

View File

@ -11,6 +11,7 @@
#include <limits.h>
#include <stdio.h>
#include <string.h>
#include <tuple>
#include "third_party/googletest/src/include/gtest/gtest.h"
@ -25,10 +26,7 @@
#include "test/util.h"
#include "vpx_mem/vpx_mem.h"
extern "C" double vp9_get_blockiness(const unsigned char *img1, int img1_pitch,
const unsigned char *img2, int img2_pitch,
int width, int height);
#include "vp9/encoder/vp9_blockiness.h"
using libvpx_test::ACMRandom;
@ -141,7 +139,7 @@ class BlockinessTestBase : public ::testing::Test {
};
#if CONFIG_VP9_ENCODER
typedef std::tr1::tuple<int, int> BlockinessParam;
typedef std::tuple<int, int> BlockinessParam;
class BlockinessVP9Test
: public BlockinessTestBase,
public ::testing::WithParamInterface<BlockinessParam> {
@ -208,15 +206,15 @@ TEST_P(BlockinessVP9Test, WorstCaseBlockiness) {
}
#endif // CONFIG_VP9_ENCODER
using std::tr1::make_tuple;
using std::make_tuple;
//------------------------------------------------------------------------------
// C functions
#if CONFIG_VP9_ENCODER
const BlockinessParam c_vp9_tests[] = {
make_tuple(320, 240), make_tuple(318, 242), make_tuple(318, 238),
};
const BlockinessParam c_vp9_tests[] = { make_tuple(320, 240),
make_tuple(318, 242),
make_tuple(318, 238) };
INSTANTIATE_TEST_CASE_P(C, BlockinessVP9Test, ::testing::ValuesIn(c_vp9_tests));
#endif

View File

@ -31,7 +31,7 @@ class BordersTest
virtual void PreEncodeFrameHook(::libvpx_test::VideoSource *video,
::libvpx_test::Encoder *encoder) {
if (video->frame() == 1) {
if (video->frame() == 0) {
encoder->Control(VP8E_SET_CPUUSED, 1);
encoder->Control(VP8E_SET_ENABLEAUTOALTREF, 1);
encoder->Control(VP8E_SET_ARNR_MAXFRAMES, 7);

View File

@ -8,8 +8,8 @@
* be found in the AUTHORS file in the root of the source tree.
*/
#ifndef TEST_BUFFER_H_
#define TEST_BUFFER_H_
#ifndef VPX_TEST_BUFFER_H_
#define VPX_TEST_BUFFER_H_
#include <stdio.h>
@ -379,4 +379,4 @@ bool Buffer<T>::BufferSizesMatch(const Buffer<T> &a) const {
return true;
}
} // namespace libvpx_test
#endif // TEST_BUFFER_H_
#endif // VPX_TEST_BUFFER_H_

View File

@ -171,8 +171,9 @@ TEST_F(ByteAlignmentTest, SwitchByteAlignment) {
TEST_P(ByteAlignmentTest, TestAlignment) {
const ByteAlignmentTestParam t = GetParam();
SetByteAlignment(t.byte_alignment, t.expected_value);
if (t.decode_remaining)
if (t.decode_remaining) {
ASSERT_EQ(VPX_CODEC_OK, DecodeRemainingFrames(t.byte_alignment));
}
}
INSTANTIATE_TEST_CASE_P(Alignments, ByteAlignmentTest,

View File

@ -7,23 +7,17 @@
* in the file PATENTS. All contributing project authors may
* be found in the AUTHORS file in the root of the source tree.
*/
#ifndef TEST_CLEAR_SYSTEM_STATE_H_
#define TEST_CLEAR_SYSTEM_STATE_H_
#ifndef VPX_TEST_CLEAR_SYSTEM_STATE_H_
#define VPX_TEST_CLEAR_SYSTEM_STATE_H_
#include "./vpx_config.h"
#if ARCH_X86 || ARCH_X86_64
#include "vpx_ports/x86.h"
#endif
#include "vpx_ports/system_state.h"
namespace libvpx_test {
// Reset system to a known state. This function should be used for all non-API
// test cases.
inline void ClearSystemState() {
#if ARCH_X86 || ARCH_X86_64
vpx_reset_mmx_state();
#endif
}
inline void ClearSystemState() { vpx_clear_system_state(); }
} // namespace libvpx_test
#endif // TEST_CLEAR_SYSTEM_STATE_H_
#endif // VPX_TEST_CLEAR_SYSTEM_STATE_H_

View File

@ -7,8 +7,10 @@
* in the file PATENTS. All contributing project authors may
* be found in the AUTHORS file in the root of the source tree.
*/
#ifndef TEST_CODEC_FACTORY_H_
#define TEST_CODEC_FACTORY_H_
#ifndef VPX_TEST_CODEC_FACTORY_H_
#define VPX_TEST_CODEC_FACTORY_H_
#include <tuple>
#include "./vpx_config.h"
#include "vpx/vpx_decoder.h"
@ -53,23 +55,22 @@ class CodecFactory {
template <class T1>
class CodecTestWithParam
: public ::testing::TestWithParam<
std::tr1::tuple<const libvpx_test::CodecFactory *, T1> > {};
std::tuple<const libvpx_test::CodecFactory *, T1> > {};
template <class T1, class T2>
class CodecTestWith2Params
: public ::testing::TestWithParam<
std::tr1::tuple<const libvpx_test::CodecFactory *, T1, T2> > {};
std::tuple<const libvpx_test::CodecFactory *, T1, T2> > {};
template <class T1, class T2, class T3>
class CodecTestWith3Params
: public ::testing::TestWithParam<
std::tr1::tuple<const libvpx_test::CodecFactory *, T1, T2, T3> > {};
std::tuple<const libvpx_test::CodecFactory *, T1, T2, T3> > {};
template <class T1, class T2, class T3, class T4>
class CodecTestWith4Params
: public ::testing::TestWithParam<
std::tr1::tuple<const libvpx_test::CodecFactory *, T1, T2, T3, T4> > {
};
std::tuple<const libvpx_test::CodecFactory *, T1, T2, T3, T4> > {};
/*
* VP8 Codec Definitions
@ -264,4 +265,4 @@ const libvpx_test::VP9CodecFactory kVP9;
#endif // CONFIG_VP9
} // namespace libvpx_test
#endif // TEST_CODEC_FACTORY_H_
#endif // VPX_TEST_CODEC_FACTORY_H_

View File

@ -29,6 +29,10 @@ uint8_t avg_with_rounding(uint8_t a, uint8_t b) { return (a + b + 1) >> 1; }
void reference_pred(const Buffer<uint8_t> &pred, const Buffer<uint8_t> &ref,
int width, int height, Buffer<uint8_t> *avg) {
ASSERT_TRUE(avg->TopLeftPixel() != NULL);
ASSERT_TRUE(pred.TopLeftPixel() != NULL);
ASSERT_TRUE(ref.TopLeftPixel() != NULL);
for (int y = 0; y < height; ++y) {
for (int x = 0; x < width; ++x) {
avg->TopLeftPixel()[y * avg->stride() + x] =

View File

@ -11,6 +11,7 @@
#include <limits.h>
#include <stdio.h>
#include <string.h>
#include <tuple>
#include "third_party/googletest/src/include/gtest/gtest.h"
@ -127,7 +128,7 @@ class ConsistencyTestBase : public ::testing::Test {
};
#if CONFIG_VP9_ENCODER
typedef std::tr1::tuple<int, int> ConsistencyParam;
typedef std::tuple<int, int> ConsistencyParam;
class ConsistencyVP9Test
: public ConsistencyTestBase,
public ::testing::WithParamInterface<ConsistencyParam> {
@ -198,15 +199,15 @@ TEST_P(ConsistencyVP9Test, ConsistencyIsZero) {
}
#endif // CONFIG_VP9_ENCODER
using std::tr1::make_tuple;
using std::make_tuple;
//------------------------------------------------------------------------------
// C functions
#if CONFIG_VP9_ENCODER
const ConsistencyParam c_vp9_tests[] = {
make_tuple(320, 240), make_tuple(318, 242), make_tuple(318, 238),
};
const ConsistencyParam c_vp9_tests[] = { make_tuple(320, 240),
make_tuple(318, 242),
make_tuple(318, 238) };
INSTANTIATE_TEST_CASE_P(C, ConsistencyVP9Test,
::testing::ValuesIn(c_vp9_tests));
#endif

View File

@ -9,6 +9,7 @@
*/
#include <string.h>
#include <tuple>
#include "third_party/googletest/src/include/gtest/gtest.h"
@ -77,7 +78,7 @@ struct ConvolveFunctions {
int use_highbd_; // 0 if high bitdepth not used, else the actual bit depth.
};
typedef std::tr1::tuple<int, int, const ConvolveFunctions *> ConvolveParam;
typedef std::tuple<int, int, const ConvolveFunctions *> ConvolveParam;
#define ALL_SIZES(convolve_fn) \
make_tuple(4, 4, &convolve_fn), make_tuple(8, 4, &convolve_fn), \
@ -114,6 +115,7 @@ void filter_block2d_8_c(const uint8_t *src_ptr, const unsigned int src_stride,
// and filter_max_width = 16
//
uint8_t intermediate_buffer[71 * kMaxDimension];
vp9_zero(intermediate_buffer);
const int intermediate_next_stride =
1 - static_cast<int>(intermediate_height * output_width);
@ -213,6 +215,8 @@ void highbd_filter_block2d_8_c(const uint16_t *src_ptr,
const int intermediate_next_stride =
1 - static_cast<int>(intermediate_height * output_width);
vp9_zero(intermediate_buffer);
// Horizontal pass (src -> transposed intermediate).
{
uint16_t *output_ptr = intermediate_buffer;
@ -412,8 +416,14 @@ class ConvolveTest : public ::testing::TestWithParam<ConvolveParam> {
for (int i = 0; i < kOutputBufferSize; ++i) {
if (IsIndexInBorder(i)) {
output_[i] = 255;
#if CONFIG_VP9_HIGHBITDEPTH
output16_[i] = mask_;
#endif
} else {
output_[i] = 0;
#if CONFIG_VP9_HIGHBITDEPTH
output16_[i] = 0;
#endif
}
}
@ -450,7 +460,9 @@ class ConvolveTest : public ::testing::TestWithParam<ConvolveParam> {
void CheckGuardBlocks() {
for (int i = 0; i < kOutputBufferSize; ++i) {
if (IsIndexInBorder(i)) EXPECT_EQ(255, output_[i]);
if (IsIndexInBorder(i)) {
EXPECT_EQ(255, output_[i]);
}
}
}
@ -672,6 +684,74 @@ TEST_P(ConvolveTest, DISABLED_8Tap_Vert_Speed) {
UUT_->use_highbd_ ? UUT_->use_highbd_ : 8, elapsed_time);
}
TEST_P(ConvolveTest, DISABLED_4Tap_Speed) {
const uint8_t *const in = input();
uint8_t *const out = output();
const InterpKernel *const fourtap = vp9_filter_kernels[FOURTAP];
const int kNumTests = 5000000;
const int width = Width();
const int height = Height();
vpx_usec_timer timer;
SetConstantInput(127);
vpx_usec_timer_start(&timer);
for (int n = 0; n < kNumTests; ++n) {
UUT_->hv8_[0](in, kInputStride, out, kOutputStride, fourtap, 8, 16, 8, 16,
width, height);
}
vpx_usec_timer_mark(&timer);
const int elapsed_time = static_cast<int>(vpx_usec_timer_elapsed(&timer));
printf("convolve4_%dx%d_%d: %d us\n", width, height,
UUT_->use_highbd_ ? UUT_->use_highbd_ : 8, elapsed_time);
}
TEST_P(ConvolveTest, DISABLED_4Tap_Horiz_Speed) {
const uint8_t *const in = input();
uint8_t *const out = output();
const InterpKernel *const fourtap = vp9_filter_kernels[FOURTAP];
const int kNumTests = 5000000;
const int width = Width();
const int height = Height();
vpx_usec_timer timer;
SetConstantInput(127);
vpx_usec_timer_start(&timer);
for (int n = 0; n < kNumTests; ++n) {
UUT_->h8_[0](in, kInputStride, out, kOutputStride, fourtap, 8, 16, 8, 16,
width, height);
}
vpx_usec_timer_mark(&timer);
const int elapsed_time = static_cast<int>(vpx_usec_timer_elapsed(&timer));
printf("convolve4_horiz_%dx%d_%d: %d us\n", width, height,
UUT_->use_highbd_ ? UUT_->use_highbd_ : 8, elapsed_time);
}
TEST_P(ConvolveTest, DISABLED_4Tap_Vert_Speed) {
const uint8_t *const in = input();
uint8_t *const out = output();
const InterpKernel *const fourtap = vp9_filter_kernels[FOURTAP];
const int kNumTests = 5000000;
const int width = Width();
const int height = Height();
vpx_usec_timer timer;
SetConstantInput(127);
vpx_usec_timer_start(&timer);
for (int n = 0; n < kNumTests; ++n) {
UUT_->v8_[0](in, kInputStride, out, kOutputStride, fourtap, 8, 16, 8, 16,
width, height);
}
vpx_usec_timer_mark(&timer);
const int elapsed_time = static_cast<int>(vpx_usec_timer_elapsed(&timer));
printf("convolve4_vert_%dx%d_%d: %d us\n", width, height,
UUT_->use_highbd_ ? UUT_->use_highbd_ : 8, elapsed_time);
}
TEST_P(ConvolveTest, DISABLED_8Tap_Avg_Speed) {
const uint8_t *const in = input();
uint8_t *const out = output();
@ -787,7 +867,7 @@ TEST_P(ConvolveTest, Copy2D) {
}
}
const int kNumFilterBanks = 4;
const int kNumFilterBanks = 5;
const int kNumFilters = 16;
TEST(ConvolveTest, FiltersWontSaturateWhenAddedPairwise) {
@ -1040,7 +1120,7 @@ TEST_P(ConvolveTest, CheckScalingFiltering) {
}
#endif
using std::tr1::make_tuple;
using std::make_tuple;
#if CONFIG_VP9_HIGHBITDEPTH
#define WRAP(func, bd) \
@ -1183,9 +1263,9 @@ const ConvolveFunctions convolve12_c(
wrap_convolve8_horiz_c_12, wrap_convolve8_avg_horiz_c_12,
wrap_convolve8_vert_c_12, wrap_convolve8_avg_vert_c_12, wrap_convolve8_c_12,
wrap_convolve8_avg_c_12, 12);
const ConvolveParam kArrayConvolve_c[] = {
ALL_SIZES(convolve8_c), ALL_SIZES(convolve10_c), ALL_SIZES(convolve12_c)
};
const ConvolveParam kArrayConvolve_c[] = { ALL_SIZES(convolve8_c),
ALL_SIZES(convolve10_c),
ALL_SIZES(convolve12_c) };
#else
const ConvolveFunctions convolve8_c(
@ -1377,4 +1457,16 @@ const ConvolveParam kArrayConvolve_vsx[] = { ALL_SIZES(convolve8_vsx) };
INSTANTIATE_TEST_CASE_P(VSX, ConvolveTest,
::testing::ValuesIn(kArrayConvolve_vsx));
#endif // HAVE_VSX
#if HAVE_MMI
const ConvolveFunctions convolve8_mmi(
vpx_convolve_copy_c, vpx_convolve_avg_mmi, vpx_convolve8_horiz_mmi,
vpx_convolve8_avg_horiz_mmi, vpx_convolve8_vert_mmi,
vpx_convolve8_avg_vert_mmi, vpx_convolve8_mmi, vpx_convolve8_avg_mmi,
vpx_scaled_horiz_c, vpx_scaled_avg_horiz_c, vpx_scaled_vert_c,
vpx_scaled_avg_vert_c, vpx_scaled_2d_c, vpx_scaled_avg_2d_c, 0);
const ConvolveParam kArrayConvolve_mmi[] = { ALL_SIZES(convolve8_mmi) };
INSTANTIATE_TEST_CASE_P(MMI, ConvolveTest,
::testing::ValuesIn(kArrayConvolve_mmi));
#endif // HAVE_MMI
} // namespace

View File

@ -44,7 +44,7 @@ class CpuSpeedTest
virtual void PreEncodeFrameHook(::libvpx_test::VideoSource *video,
::libvpx_test::Encoder *encoder) {
if (video->frame() == 1) {
if (video->frame() == 0) {
encoder->Control(VP8E_SET_CPUUSED, set_cpu_used_);
encoder->Control(VP9E_SET_TUNE_CONTENT, tune_content_);
if (encoding_mode_ != ::libvpx_test::kRealTime) {
@ -152,5 +152,5 @@ VP9_INSTANTIATE_TEST_CASE(CpuSpeedTest,
::testing::Values(::libvpx_test::kTwoPassGood,
::libvpx_test::kOnePassGood,
::libvpx_test::kRealTime),
::testing::Range(0, 9));
::testing::Range(0, 10));
} // namespace

View File

@ -65,7 +65,7 @@ class CQTest : public ::libvpx_test::EncoderTest,
virtual void PreEncodeFrameHook(libvpx_test::VideoSource *video,
libvpx_test::Encoder *encoder) {
if (video->frame() == 1) {
if (video->frame() == 0) {
if (cfg_.rc_end_usage == VPX_CQ) {
encoder->Control(VP8E_SET_CQ_LEVEL, cq_level_);
}

File diff suppressed because it is too large Load Diff

View File

@ -11,6 +11,7 @@
#include <math.h>
#include <stdlib.h>
#include <string.h>
#include <tuple>
#include "third_party/googletest/src/include/gtest/gtest.h"
@ -229,10 +230,9 @@ typedef void (*FhtFunc)(const int16_t *in, tran_low_t *out, int stride,
typedef void (*IhtFunc)(const tran_low_t *in, uint8_t *out, int stride,
int tx_type);
typedef std::tr1::tuple<FdctFunc, IdctFunc, int, vpx_bit_depth_t> Dct16x16Param;
typedef std::tr1::tuple<FhtFunc, IhtFunc, int, vpx_bit_depth_t> Ht16x16Param;
typedef std::tr1::tuple<IdctFunc, IdctFunc, int, vpx_bit_depth_t>
Idct16x16Param;
typedef std::tuple<FdctFunc, IdctFunc, int, vpx_bit_depth_t> Dct16x16Param;
typedef std::tuple<FhtFunc, IhtFunc, int, vpx_bit_depth_t> Ht16x16Param;
typedef std::tuple<IdctFunc, IdctFunc, int, vpx_bit_depth_t> Idct16x16Param;
void fdct16x16_ref(const int16_t *in, tran_low_t *out, int stride,
int /*tx_type*/) {
@ -744,7 +744,7 @@ TEST_P(InvTrans16x16DCT, CompareReference) {
CompareInvReference(ref_txfm_, thresh_);
}
using std::tr1::make_tuple;
using std::make_tuple;
#if CONFIG_VP9_HIGHBITDEPTH
INSTANTIATE_TEST_CASE_P(

View File

@ -11,6 +11,7 @@
#include <math.h>
#include <stdlib.h>
#include <string.h>
#include <tuple>
#include "third_party/googletest/src/include/gtest/gtest.h"
@ -18,6 +19,7 @@
#include "./vpx_config.h"
#include "./vpx_dsp_rtcd.h"
#include "test/acm_random.h"
#include "test/bench.h"
#include "test/clear_system_state.h"
#include "test/register_state_check.h"
#include "test/util.h"
@ -66,7 +68,7 @@ void reference_32x32_dct_2d(const int16_t input[kNumCoeffs],
typedef void (*FwdTxfmFunc)(const int16_t *in, tran_low_t *out, int stride);
typedef void (*InvTxfmFunc)(const tran_low_t *in, uint8_t *out, int stride);
typedef std::tr1::tuple<FwdTxfmFunc, InvTxfmFunc, int, vpx_bit_depth_t>
typedef std::tuple<FwdTxfmFunc, InvTxfmFunc, int, vpx_bit_depth_t>
Trans32x32Param;
#if CONFIG_VP9_HIGHBITDEPTH
@ -79,7 +81,8 @@ void idct32x32_12(const tran_low_t *in, uint8_t *out, int stride) {
}
#endif // CONFIG_VP9_HIGHBITDEPTH
class Trans32x32Test : public ::testing::TestWithParam<Trans32x32Param> {
class Trans32x32Test : public AbstractBench,
public ::testing::TestWithParam<Trans32x32Param> {
public:
virtual ~Trans32x32Test() {}
virtual void SetUp() {
@ -99,8 +102,14 @@ class Trans32x32Test : public ::testing::TestWithParam<Trans32x32Param> {
int mask_;
FwdTxfmFunc fwd_txfm_;
InvTxfmFunc inv_txfm_;
int16_t *bench_in_;
tran_low_t *bench_out_;
virtual void Run();
};
void Trans32x32Test::Run() { fwd_txfm_(bench_in_, bench_out_, 32); }
TEST_P(Trans32x32Test, AccuracyCheck) {
ACMRandom rnd(ACMRandom::DeterministicSeed());
uint32_t max_error = 0;
@ -237,6 +246,19 @@ TEST_P(Trans32x32Test, MemCheck) {
}
}
TEST_P(Trans32x32Test, DISABLED_Speed) {
ACMRandom rnd(ACMRandom::DeterministicSeed());
DECLARE_ALIGNED(16, int16_t, input_extreme_block[kNumCoeffs]);
DECLARE_ALIGNED(16, tran_low_t, output_block[kNumCoeffs]);
bench_in_ = input_extreme_block;
bench_out_ = output_block;
RunNTimes(INT16_MAX);
PrintMedian("32x32");
}
TEST_P(Trans32x32Test, InverseAccuracy) {
ACMRandom rnd(ACMRandom::DeterministicSeed());
const int count_test_block = 1000;
@ -292,7 +314,7 @@ TEST_P(Trans32x32Test, InverseAccuracy) {
}
}
using std::tr1::make_tuple;
using std::make_tuple;
#if CONFIG_VP9_HIGHBITDEPTH
INSTANTIATE_TEST_CASE_P(
@ -371,7 +393,7 @@ INSTANTIATE_TEST_CASE_P(
VSX, Trans32x32Test,
::testing::Values(make_tuple(&vpx_fdct32x32_c, &vpx_idct32x32_1024_add_vsx,
0, VPX_BITS_8),
make_tuple(&vpx_fdct32x32_rd_c,
make_tuple(&vpx_fdct32x32_rd_vsx,
&vpx_idct32x32_1024_add_vsx, 1, VPX_BITS_8)));
#endif // HAVE_VSX && !CONFIG_VP9_HIGHBITDEPTH && !CONFIG_EMULATE_HARDWARE
} // namespace

View File

@ -11,8 +11,8 @@
#include <math.h>
#include <stdlib.h>
#include <string.h>
#include <limits>
#include <tuple>
#include "third_party/googletest/src/include/gtest/gtest.h"
@ -28,8 +28,8 @@
using libvpx_test::ACMRandom;
using libvpx_test::Buffer;
using std::tr1::tuple;
using std::tr1::make_tuple;
using std::make_tuple;
using std::tuple;
namespace {
typedef void (*PartialFdctFunc)(const int16_t *in, tran_low_t *out, int stride);
@ -39,10 +39,14 @@ typedef tuple<PartialFdctFunc, int /* size */, vpx_bit_depth_t>
tran_low_t partial_fdct_ref(const Buffer<int16_t> &in, int size) {
int64_t sum = 0;
for (int y = 0; y < size; ++y) {
for (int x = 0; x < size; ++x) {
sum += in.TopLeftPixel()[y * in.stride() + x];
if (in.TopLeftPixel() != NULL) {
for (int y = 0; y < size; ++y) {
for (int x = 0; x < size; ++x) {
sum += in.TopLeftPixel()[y * in.stride() + x];
}
}
} else {
assert(0);
}
switch (size) {
@ -77,21 +81,25 @@ class PartialFdctTest : public ::testing::TestWithParam<PartialFdctParam> {
Buffer<tran_low_t> output_block = Buffer<tran_low_t>(size_, size_, 0, 16);
ASSERT_TRUE(output_block.Init());
for (int i = 0; i < 100; ++i) {
if (i == 0) {
input_block.Set(maxvalue);
} else if (i == 1) {
input_block.Set(minvalue);
} else {
input_block.Set(&rnd, minvalue, maxvalue);
if (output_block.TopLeftPixel() != NULL) {
for (int i = 0; i < 100; ++i) {
if (i == 0) {
input_block.Set(maxvalue);
} else if (i == 1) {
input_block.Set(minvalue);
} else {
input_block.Set(&rnd, minvalue, maxvalue);
}
ASM_REGISTER_STATE_CHECK(fwd_txfm_(input_block.TopLeftPixel(),
output_block.TopLeftPixel(),
input_block.stride()));
EXPECT_EQ(partial_fdct_ref(input_block, size_),
output_block.TopLeftPixel()[0]);
}
ASM_REGISTER_STATE_CHECK(fwd_txfm_(input_block.TopLeftPixel(),
output_block.TopLeftPixel(),
input_block.stride()));
EXPECT_EQ(partial_fdct_ref(input_block, size_),
output_block.TopLeftPixel()[0]);
} else {
assert(0);
}
}

File diff suppressed because it is too large Load Diff

View File

@ -138,8 +138,30 @@ TEST(DecodeAPI, Vp9InvalidDecode) {
EXPECT_EQ(VPX_CODEC_OK, vpx_codec_destroy(&dec));
}
TEST(DecodeAPI, Vp9PeekSI) {
void TestPeekInfo(const uint8_t *const data, uint32_t data_sz,
uint32_t peek_size) {
const vpx_codec_iface_t *const codec = &vpx_codec_vp9_dx_algo;
// Verify behavior of vpx_codec_decode. vpx_codec_decode doesn't even get
// to decoder_peek_si_internal on frames of size < 8.
if (data_sz >= 8) {
vpx_codec_ctx_t dec;
EXPECT_EQ(VPX_CODEC_OK, vpx_codec_dec_init(&dec, codec, NULL, 0));
EXPECT_EQ((data_sz < peek_size) ? VPX_CODEC_UNSUP_BITSTREAM
: VPX_CODEC_CORRUPT_FRAME,
vpx_codec_decode(&dec, data, data_sz, NULL, 0));
vpx_codec_iter_t iter = NULL;
EXPECT_EQ(NULL, vpx_codec_get_frame(&dec, &iter));
EXPECT_EQ(VPX_CODEC_OK, vpx_codec_destroy(&dec));
}
// Verify behavior of vpx_codec_peek_stream_info.
vpx_codec_stream_info_t si;
si.sz = sizeof(si);
EXPECT_EQ((data_sz < peek_size) ? VPX_CODEC_UNSUP_BITSTREAM : VPX_CODEC_OK,
vpx_codec_peek_stream_info(codec, data, data_sz, &si));
}
TEST(DecodeAPI, Vp9PeekStreamInfo) {
// The first 9 bytes are valid and the rest of the bytes are made up. Until
// size 10, this should return VPX_CODEC_UNSUP_BITSTREAM and after that it
// should return VPX_CODEC_CORRUPT_FRAME.
@ -150,24 +172,18 @@ TEST(DecodeAPI, Vp9PeekSI) {
};
for (uint32_t data_sz = 1; data_sz <= 32; ++data_sz) {
// Verify behavior of vpx_codec_decode. vpx_codec_decode doesn't even get
// to decoder_peek_si_internal on frames of size < 8.
if (data_sz >= 8) {
vpx_codec_ctx_t dec;
EXPECT_EQ(VPX_CODEC_OK, vpx_codec_dec_init(&dec, codec, NULL, 0));
EXPECT_EQ(
(data_sz < 10) ? VPX_CODEC_UNSUP_BITSTREAM : VPX_CODEC_CORRUPT_FRAME,
vpx_codec_decode(&dec, data, data_sz, NULL, 0));
vpx_codec_iter_t iter = NULL;
EXPECT_EQ(NULL, vpx_codec_get_frame(&dec, &iter));
EXPECT_EQ(VPX_CODEC_OK, vpx_codec_destroy(&dec));
}
TestPeekInfo(data, data_sz, 10);
}
}
// Verify behavior of vpx_codec_peek_stream_info.
vpx_codec_stream_info_t si;
si.sz = sizeof(si);
EXPECT_EQ((data_sz < 10) ? VPX_CODEC_UNSUP_BITSTREAM : VPX_CODEC_OK,
vpx_codec_peek_stream_info(codec, data, data_sz, &si));
TEST(DecodeAPI, Vp9PeekStreamInfoTruncated) {
// This profile 1 header requires 10.25 bytes, ensure
// vpx_codec_peek_stream_info doesn't over read.
const uint8_t profile1_data[10] = { 0xa4, 0xe9, 0x30, 0x68, 0x53,
0xe9, 0x30, 0x68, 0x53, 0x04 };
for (uint32_t data_sz = 1; data_sz <= 10; ++data_sz) {
TestPeekInfo(profile1_data, data_sz, 11);
}
}
#endif // CONFIG_VP9_DECODER

View File

@ -0,0 +1,103 @@
/*
* Copyright (c) 2018 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 <tuple>
#include "third_party/googletest/src/include/gtest/gtest.h"
#include "test/codec_factory.h"
#include "test/encode_test_driver.h"
#include "test/util.h"
#include "test/i420_video_source.h"
#include "vpx_mem/vpx_mem.h"
namespace {
class DecodeCorruptedFrameTest
: public ::libvpx_test::EncoderTest,
public ::testing::TestWithParam<
std::tuple<const libvpx_test::CodecFactory *> > {
public:
DecodeCorruptedFrameTest() : EncoderTest(GET_PARAM(0)) {}
protected:
virtual ~DecodeCorruptedFrameTest() {}
virtual void SetUp() {
InitializeConfig();
SetMode(::libvpx_test::kRealTime);
cfg_.g_lag_in_frames = 0;
cfg_.rc_end_usage = VPX_CBR;
cfg_.rc_buf_sz = 1000;
cfg_.rc_buf_initial_sz = 500;
cfg_.rc_buf_optimal_sz = 600;
// Set small key frame distance such that we insert more key frames.
cfg_.kf_max_dist = 3;
dec_cfg_.threads = 1;
}
virtual void PreEncodeFrameHook(::libvpx_test::VideoSource *video,
::libvpx_test::Encoder *encoder) {
if (video->frame() == 0) encoder->Control(VP8E_SET_CPUUSED, 7);
}
virtual void MismatchHook(const vpx_image_t * /*img1*/,
const vpx_image_t * /*img2*/) {}
virtual const vpx_codec_cx_pkt_t *MutateEncoderOutputHook(
const vpx_codec_cx_pkt_t *pkt) {
// Don't edit frame packet on key frame.
if (pkt->data.frame.flags & VPX_FRAME_IS_KEY) return pkt;
if (pkt->kind != VPX_CODEC_CX_FRAME_PKT) return pkt;
memcpy(&modified_pkt_, pkt, sizeof(*pkt));
// Halve the size so it's corrupted to decoder.
modified_pkt_.data.frame.sz = modified_pkt_.data.frame.sz / 2;
return &modified_pkt_;
}
virtual bool HandleDecodeResult(const vpx_codec_err_t res_dec,
const libvpx_test::VideoSource & /*video*/,
libvpx_test::Decoder *decoder) {
EXPECT_NE(res_dec, VPX_CODEC_MEM_ERROR) << decoder->DecodeError();
return VPX_CODEC_MEM_ERROR != res_dec;
}
vpx_codec_cx_pkt_t modified_pkt_;
};
TEST_P(DecodeCorruptedFrameTest, DecodeCorruptedFrame) {
cfg_.rc_target_bitrate = 200;
cfg_.g_error_resilient = 0;
::libvpx_test::I420VideoSource video("hantro_collage_w352h288.yuv", 352, 288,
30, 1, 0, 300);
ASSERT_NO_FATAL_FAILURE(RunLoop(&video));
}
#if CONFIG_VP9
INSTANTIATE_TEST_CASE_P(
VP9, DecodeCorruptedFrameTest,
::testing::Values(
static_cast<const libvpx_test::CodecFactory *>(&libvpx_test::kVP9)));
#endif // CONFIG_VP9
#if CONFIG_VP8
INSTANTIATE_TEST_CASE_P(
VP8, DecodeCorruptedFrameTest,
::testing::Values(
static_cast<const libvpx_test::CodecFactory *>(&libvpx_test::kVP8)));
#endif // CONFIG_VP8
} // namespace

View File

@ -9,6 +9,8 @@
*/
#include <string>
#include <tuple>
#include "test/codec_factory.h"
#include "test/decode_test_driver.h"
#include "test/encode_test_driver.h"
@ -21,7 +23,7 @@
#include "./ivfenc.h"
#include "./vpx_version.h"
using std::tr1::make_tuple;
using std::make_tuple;
namespace {
@ -34,7 +36,7 @@ const char kNewEncodeOutputFile[] = "new_encode.ivf";
/*
DecodePerfTest takes a tuple of filename + number of threads to decode with
*/
typedef std::tr1::tuple<const char *, unsigned> DecodePerfParam;
typedef std::tuple<const char *, unsigned> DecodePerfParam;
const DecodePerfParam kVP9DecodePerfVectors[] = {
make_tuple("vp90-2-bbb_426x240_tile_1x1_180kbps.webm", 1),
@ -137,7 +139,7 @@ class VP9NewEncodeDecodePerfTest
virtual void PreEncodeFrameHook(::libvpx_test::VideoSource *video,
::libvpx_test::Encoder *encoder) {
if (video->frame() == 1) {
if (video->frame() == 0) {
encoder->Control(VP8E_SET_CPUUSED, speed_);
encoder->Control(VP9E_SET_FRAME_PARALLEL_DECODING, 1);
encoder->Control(VP9E_SET_TILE_COLUMNS, 2);

View File

@ -8,6 +8,7 @@
* be found in the AUTHORS file in the root of the source tree.
*/
#include <memory>
#include <string>
#include "test/codec_factory.h"
@ -53,7 +54,7 @@ class DecodeSvcTest : public ::libvpx_test::DecoderTest,
// number of frames decoded. This results in 1/4x1/4 resolution (320x180).
TEST_P(DecodeSvcTest, DecodeSvcTestUpToSpatialLayer0) {
const std::string filename = GET_PARAM(1);
testing::internal::scoped_ptr<libvpx_test::CompressedVideoSource> video;
std::unique_ptr<libvpx_test::CompressedVideoSource> video;
video.reset(new libvpx_test::IVFVideoSource(filename));
ASSERT_TRUE(video.get() != NULL);
video->Init();
@ -70,7 +71,7 @@ TEST_P(DecodeSvcTest, DecodeSvcTestUpToSpatialLayer0) {
// number of frames decoded. This results in 1/2x1/2 resolution (640x360).
TEST_P(DecodeSvcTest, DecodeSvcTestUpToSpatialLayer1) {
const std::string filename = GET_PARAM(1);
testing::internal::scoped_ptr<libvpx_test::CompressedVideoSource> video;
std::unique_ptr<libvpx_test::CompressedVideoSource> video;
video.reset(new libvpx_test::IVFVideoSource(filename));
ASSERT_TRUE(video.get() != NULL);
video->Init();
@ -87,7 +88,7 @@ TEST_P(DecodeSvcTest, DecodeSvcTestUpToSpatialLayer1) {
// number of frames decoded. This results in the full resolution (1280x720).
TEST_P(DecodeSvcTest, DecodeSvcTestUpToSpatialLayer2) {
const std::string filename = GET_PARAM(1);
testing::internal::scoped_ptr<libvpx_test::CompressedVideoSource> video;
std::unique_ptr<libvpx_test::CompressedVideoSource> video;
video.reset(new libvpx_test::IVFVideoSource(filename));
ASSERT_TRUE(video.get() != NULL);
video->Init();
@ -105,7 +106,7 @@ TEST_P(DecodeSvcTest, DecodeSvcTestUpToSpatialLayer2) {
// the decoding should result in the full resolution (1280x720).
TEST_P(DecodeSvcTest, DecodeSvcTestUpToSpatialLayer10) {
const std::string filename = GET_PARAM(1);
testing::internal::scoped_ptr<libvpx_test::CompressedVideoSource> video;
std::unique_ptr<libvpx_test::CompressedVideoSource> video;
video.reset(new libvpx_test::IVFVideoSource(filename));
ASSERT_TRUE(video.get() != NULL);
video->Init();

View File

@ -52,9 +52,10 @@ void DecoderTest::HandlePeekResult(Decoder *const decoder,
/* Vp8's implementation of PeekStream returns an error if the frame you
* pass it is not a keyframe, so we only expect VPX_CODEC_OK on the first
* frame, which must be a keyframe. */
if (video->frame_number() == 0)
if (video->frame_number() == 0) {
ASSERT_EQ(VPX_CODEC_OK, res_peek)
<< "Peek return failed: " << vpx_codec_err_to_string(res_peek);
}
} else {
/* The Vp9 implementation of PeekStream returns an error only if the
* data passed to it isn't a valid Vp9 chunk. */
@ -97,7 +98,7 @@ void DecoderTest::RunLoop(CompressedVideoSource *video,
const vpx_image_t *img = NULL;
// Get decompressed data
while ((img = dec_iter.Next())) {
while (!::testing::Test::HasFailure() && (img = dec_iter.Next())) {
DecompressedFrameHook(*img, video->frame_number());
}
}

View File

@ -8,8 +8,8 @@
* be found in the AUTHORS file in the root of the source tree.
*/
#ifndef TEST_DECODE_TEST_DRIVER_H_
#define TEST_DECODE_TEST_DRIVER_H_
#ifndef VPX_TEST_DECODE_TEST_DRIVER_H_
#define VPX_TEST_DECODE_TEST_DRIVER_H_
#include <cstring>
#include "third_party/googletest/src/include/gtest/gtest.h"
#include "./vpx_config.h"
@ -159,4 +159,4 @@ class DecoderTest {
} // namespace libvpx_test
#endif // TEST_DECODE_TEST_DRIVER_H_
#endif // VPX_TEST_DECODE_TEST_DRIVER_H_

View File

@ -48,7 +48,7 @@ const EncodePerfTestVideo kVP9EncodePerfTestVectors[] = {
EncodePerfTestVideo("niklas_1280_720_30.yuv", 1280, 720, 600, 470),
};
const int kEncodePerfTestSpeeds[] = { 5, 6, 7, 8 };
const int kEncodePerfTestSpeeds[] = { 5, 6, 7, 8, 9 };
const int kEncodePerfTestThreads[] = { 1, 2, 4 };
#define NELEMENTS(x) (sizeof((x)) / sizeof((x)[0]))

View File

@ -8,6 +8,7 @@
* be found in the AUTHORS file in the root of the source tree.
*/
#include <memory>
#include <string>
#include "third_party/googletest/src/include/gtest/gtest.h"
@ -128,6 +129,8 @@ static bool compare_img(const vpx_image_t *img1, const vpx_image_t *img2) {
bool match = (img1->fmt == img2->fmt) && (img1->cs == img2->cs) &&
(img1->d_w == img2->d_w) && (img1->d_h == img2->d_h);
if (!match) return false;
const unsigned int width_y = img1->d_w;
const unsigned int height_y = img1->d_h;
unsigned int i;
@ -177,7 +180,7 @@ void EncoderTest::RunLoop(VideoSource *video) {
}
BeginPassHook(pass);
testing::internal::scoped_ptr<Encoder> encoder(
std::unique_ptr<Encoder> encoder(
codec_->CreateEncoder(cfg_, deadline_, init_flags_, &stats_));
ASSERT_TRUE(encoder.get() != NULL);
@ -191,7 +194,7 @@ void EncoderTest::RunLoop(VideoSource *video) {
if (init_flags_ & VPX_CODEC_USE_OUTPUT_PARTITION) {
dec_init_flags |= VPX_CODEC_USE_INPUT_FRAGMENTS;
}
testing::internal::scoped_ptr<Decoder> decoder(
std::unique_ptr<Decoder> decoder(
codec_->CreateDecoder(dec_cfg, dec_init_flags));
bool again;
for (again = true; again; video->Next()) {
@ -214,6 +217,7 @@ void EncoderTest::RunLoop(VideoSource *video) {
case VPX_CODEC_CX_FRAME_PKT:
has_cxdata = true;
if (decoder.get() != NULL && DoDecode()) {
PreDecodeFrameHook(video, decoder.get());
vpx_codec_err_t res_dec = decoder->DecodeFrame(
(const uint8_t *)pkt->data.frame.buf, pkt->data.frame.sz);

View File

@ -7,8 +7,8 @@
* in the file PATENTS. All contributing project authors may
* be found in the AUTHORS file in the root of the source tree.
*/
#ifndef TEST_ENCODE_TEST_DRIVER_H_
#define TEST_ENCODE_TEST_DRIVER_H_
#ifndef VPX_TEST_ENCODE_TEST_DRIVER_H_
#define VPX_TEST_ENCODE_TEST_DRIVER_H_
#include <string>
#include <vector>
@ -128,24 +128,37 @@ class Encoder {
ASSERT_EQ(VPX_CODEC_OK, res) << EncoderError();
}
void Control(int ctrl_id, struct vpx_svc_ref_frame_config *arg) {
const vpx_codec_err_t res = vpx_codec_control_(&encoder_, ctrl_id, arg);
ASSERT_EQ(VPX_CODEC_OK, res) << EncoderError();
}
void Control(int ctrl_id, struct vpx_svc_parameters *arg) {
const vpx_codec_err_t res = vpx_codec_control_(&encoder_, ctrl_id, arg);
ASSERT_EQ(VPX_CODEC_OK, res) << EncoderError();
}
void Control(int ctrl_id, struct vpx_svc_frame_drop *arg) {
const vpx_codec_err_t res = vpx_codec_control_(&encoder_, ctrl_id, arg);
ASSERT_EQ(VPX_CODEC_OK, res) << EncoderError();
}
void Control(int ctrl_id, struct vpx_svc_spatial_layer_sync *arg) {
const vpx_codec_err_t res = vpx_codec_control_(&encoder_, ctrl_id, arg);
ASSERT_EQ(VPX_CODEC_OK, res) << EncoderError();
}
#if CONFIG_VP8_ENCODER || CONFIG_VP9_ENCODER
void Control(int ctrl_id, vpx_active_map_t *arg) {
const vpx_codec_err_t res = vpx_codec_control_(&encoder_, ctrl_id, arg);
ASSERT_EQ(VPX_CODEC_OK, res) << EncoderError();
}
#endif
#if CONFIG_VP8_ENCODER
void Control(int ctrl_id, vpx_roi_map_t *arg) {
const vpx_codec_err_t res = vpx_codec_control_(&encoder_, ctrl_id, arg);
ASSERT_EQ(VPX_CODEC_OK, res) << EncoderError();
}
#endif
void Config(const vpx_codec_enc_cfg_t *cfg) {
const vpx_codec_err_t res = vpx_codec_enc_config_set(&encoder_, cfg);
ASSERT_EQ(VPX_CODEC_OK, res) << EncoderError();
@ -219,6 +232,9 @@ class EncoderTest {
virtual void PreEncodeFrameHook(VideoSource * /*video*/,
Encoder * /*encoder*/) {}
virtual void PreDecodeFrameHook(VideoSource * /*video*/,
Decoder * /*decoder*/) {}
virtual void PostEncodeFrameHook(Encoder * /*encoder*/) {}
// Hook to be called on every compressed data packet.
@ -273,4 +289,4 @@ class EncoderTest {
} // namespace libvpx_test
#endif // TEST_ENCODE_TEST_DRIVER_H_
#endif // VPX_TEST_ENCODE_TEST_DRIVER_H_

View File

@ -8,6 +8,7 @@
* be found in the AUTHORS file in the root of the source tree.
*/
#include <memory>
#include <string>
#include "./vpx_config.h"
@ -113,9 +114,9 @@ class ExternalFrameBufferList {
return 0;
}
// Checks that the ximage data is contained within the external frame buffer
// private data passed back in the ximage.
void CheckXImageFrameBuffer(const vpx_image_t *img) {
// Checks that the vpx_image_t data is contained within the external frame
// buffer private data passed back in the vpx_image_t.
void CheckImageFrameBuffer(const vpx_image_t *img) {
if (img->fb_priv != NULL) {
const struct ExternalFrameBuffer *const ext_fb =
reinterpret_cast<ExternalFrameBuffer *>(img->fb_priv);
@ -335,14 +336,13 @@ class ExternalFrameBufferTest : public ::testing::Test {
return VPX_CODEC_OK;
}
protected:
void CheckDecodedFrames() {
libvpx_test::DxDataIterator dec_iter = decoder_->GetDxData();
const vpx_image_t *img = NULL;
// Get decompressed data
while ((img = dec_iter.Next()) != NULL) {
fb_list_.CheckXImageFrameBuffer(img);
fb_list_.CheckImageFrameBuffer(img);
}
}
@ -393,7 +393,7 @@ TEST_P(ExternalFrameBufferMD5Test, ExtFBMD5Match) {
#endif
// Open compressed video file.
testing::internal::scoped_ptr<libvpx_test::CompressedVideoSource> video;
std::unique_ptr<libvpx_test::CompressedVideoSource> video;
if (filename.substr(filename.length() - 3, 3) == "ivf") {
video.reset(new libvpx_test::IVFVideoSource(filename));
} else {

View File

@ -11,6 +11,7 @@
#include <math.h>
#include <stdlib.h>
#include <string.h>
#include <tuple>
#include "third_party/googletest/src/include/gtest/gtest.h"
@ -43,9 +44,9 @@ typedef void (*FhtFunc)(const int16_t *in, tran_low_t *out, int stride,
typedef void (*IhtFunc)(const tran_low_t *in, uint8_t *out, int stride,
int tx_type);
typedef std::tr1::tuple<FdctFunc, IdctFunc, int, vpx_bit_depth_t> Dct8x8Param;
typedef std::tr1::tuple<FhtFunc, IhtFunc, int, vpx_bit_depth_t> Ht8x8Param;
typedef std::tr1::tuple<IdctFunc, IdctFunc, int, vpx_bit_depth_t> Idct8x8Param;
typedef std::tuple<FdctFunc, IdctFunc, int, vpx_bit_depth_t> Dct8x8Param;
typedef std::tuple<FhtFunc, IhtFunc, int, vpx_bit_depth_t> Ht8x8Param;
typedef std::tuple<IdctFunc, IdctFunc, int, vpx_bit_depth_t> Idct8x8Param;
void reference_8x8_dct_1d(const double in[8], double out[8]) {
const double kInvSqrt2 = 0.707106781186547524400844362104;
@ -628,7 +629,7 @@ TEST_P(InvTrans8x8DCT, CompareReference) {
CompareInvReference(ref_txfm_, thresh_);
}
using std::tr1::make_tuple;
using std::make_tuple;
#if CONFIG_VP9_HIGHBITDEPTH
INSTANTIATE_TEST_CASE_P(
@ -675,6 +676,7 @@ INSTANTIATE_TEST_CASE_P(NEON, FwdTrans8x8DCT,
::testing::Values(make_tuple(&vpx_fdct8x8_neon,
&vpx_idct8x8_64_add_neon,
0, VPX_BITS_8)));
#if !CONFIG_VP9_HIGHBITDEPTH
INSTANTIATE_TEST_CASE_P(
NEON, FwdTrans8x8HT,

View File

@ -34,7 +34,7 @@ class VP9FrameSizeTestsLarge : public ::libvpx_test::EncoderTest,
virtual void PreEncodeFrameHook(::libvpx_test::VideoSource *video,
::libvpx_test::Encoder *encoder) {
if (video->frame() == 1) {
if (video->frame() == 0) {
encoder->Control(VP8E_SET_CPUUSED, 7);
encoder->Control(VP8E_SET_ENABLEAUTOALTREF, 1);
encoder->Control(VP8E_SET_ARNR_MAXFRAMES, 7);

View File

@ -25,13 +25,13 @@ using ::libvpx_test::ACMRandom;
typedef void (*HadamardFunc)(const int16_t *a, ptrdiff_t a_stride,
tran_low_t *b);
void hadamard_loop(const int16_t *a, int a_stride, int16_t *out) {
int16_t b[8];
void hadamard_loop(const tran_low_t *a, tran_low_t *out) {
tran_low_t b[8];
for (int i = 0; i < 8; i += 2) {
b[i + 0] = a[i * a_stride] + a[(i + 1) * a_stride];
b[i + 1] = a[i * a_stride] - a[(i + 1) * a_stride];
b[i + 0] = a[i * 8] + a[(i + 1) * 8];
b[i + 1] = a[i * 8] - a[(i + 1) * 8];
}
int16_t c[8];
tran_low_t c[8];
for (int i = 0; i < 8; i += 4) {
c[i + 0] = b[i + 0] + b[i + 2];
c[i + 1] = b[i + 1] + b[i + 3];
@ -49,12 +49,15 @@ void hadamard_loop(const int16_t *a, int a_stride, int16_t *out) {
}
void reference_hadamard8x8(const int16_t *a, int a_stride, tran_low_t *b) {
int16_t buf[64];
int16_t buf2[64];
for (int i = 0; i < 8; ++i) hadamard_loop(a + i, a_stride, buf + i * 8);
for (int i = 0; i < 8; ++i) hadamard_loop(buf + i, 8, buf2 + i * 8);
for (int i = 0; i < 64; ++i) b[i] = (tran_low_t)buf2[i];
tran_low_t input[64];
tran_low_t buf[64];
for (int i = 0; i < 8; ++i) {
for (int j = 0; j < 8; ++j) {
input[i * 8 + j] = static_cast<tran_low_t>(a[i * a_stride + j]);
}
}
for (int i = 0; i < 8; ++i) hadamard_loop(input + i, buf + i * 8);
for (int i = 0; i < 8; ++i) hadamard_loop(buf + i, b + i * 8);
}
void reference_hadamard16x16(const int16_t *a, int a_stride, tran_low_t *b) {
@ -89,205 +92,229 @@ void reference_hadamard16x16(const int16_t *a, int a_stride, tran_low_t *b) {
}
}
class HadamardTestBase : public ::testing::TestWithParam<HadamardFunc> {
void reference_hadamard32x32(const int16_t *a, int a_stride, tran_low_t *b) {
reference_hadamard16x16(a + 0 + 0 * a_stride, a_stride, b + 0);
reference_hadamard16x16(a + 16 + 0 * a_stride, a_stride, b + 256);
reference_hadamard16x16(a + 0 + 16 * a_stride, a_stride, b + 512);
reference_hadamard16x16(a + 16 + 16 * a_stride, a_stride, b + 768);
for (int i = 0; i < 256; ++i) {
const tran_low_t a0 = b[0];
const tran_low_t a1 = b[256];
const tran_low_t a2 = b[512];
const tran_low_t a3 = b[768];
const tran_low_t b0 = (a0 + a1) >> 2;
const tran_low_t b1 = (a0 - a1) >> 2;
const tran_low_t b2 = (a2 + a3) >> 2;
const tran_low_t b3 = (a2 - a3) >> 2;
b[0] = b0 + b2;
b[256] = b1 + b3;
b[512] = b0 - b2;
b[768] = b1 - b3;
++b;
}
}
struct HadamardFuncWithSize {
HadamardFuncWithSize(HadamardFunc f, int s) : func(f), block_size(s) {}
HadamardFunc func;
int block_size;
};
std::ostream &operator<<(std::ostream &os, const HadamardFuncWithSize &hfs) {
return os << "block size: " << hfs.block_size;
}
class HadamardTestBase : public ::testing::TestWithParam<HadamardFuncWithSize> {
public:
virtual void SetUp() {
h_func_ = GetParam();
h_func_ = GetParam().func;
bwh_ = GetParam().block_size;
block_size_ = bwh_ * bwh_;
rnd_.Reset(ACMRandom::DeterministicSeed());
}
virtual int16_t Rand() = 0;
void ReferenceHadamard(const int16_t *a, int a_stride, tran_low_t *b,
int bwh) {
if (bwh == 32)
reference_hadamard32x32(a, a_stride, b);
else if (bwh == 16)
reference_hadamard16x16(a, a_stride, b);
else
reference_hadamard8x8(a, a_stride, b);
}
void CompareReferenceRandom() {
const int kMaxBlockSize = 32 * 32;
DECLARE_ALIGNED(16, int16_t, a[kMaxBlockSize]);
DECLARE_ALIGNED(16, tran_low_t, b[kMaxBlockSize]);
memset(a, 0, sizeof(a));
memset(b, 0, sizeof(b));
tran_low_t b_ref[kMaxBlockSize];
memset(b_ref, 0, sizeof(b_ref));
for (int i = 0; i < block_size_; ++i) a[i] = Rand();
ReferenceHadamard(a, bwh_, b_ref, bwh_);
ASM_REGISTER_STATE_CHECK(h_func_(a, bwh_, b));
// The order of the output is not important. Sort before checking.
std::sort(b, b + block_size_);
std::sort(b_ref, b_ref + block_size_);
EXPECT_EQ(0, memcmp(b, b_ref, sizeof(b)));
}
void VaryStride() {
const int kMaxBlockSize = 32 * 32;
DECLARE_ALIGNED(16, int16_t, a[kMaxBlockSize * 8]);
DECLARE_ALIGNED(16, tran_low_t, b[kMaxBlockSize]);
memset(a, 0, sizeof(a));
for (int i = 0; i < block_size_ * 8; ++i) a[i] = Rand();
tran_low_t b_ref[kMaxBlockSize];
for (int i = 8; i < 64; i += 8) {
memset(b, 0, sizeof(b));
memset(b_ref, 0, sizeof(b_ref));
ReferenceHadamard(a, i, b_ref, bwh_);
ASM_REGISTER_STATE_CHECK(h_func_(a, i, b));
// The order of the output is not important. Sort before checking.
std::sort(b, b + block_size_);
std::sort(b_ref, b_ref + block_size_);
EXPECT_EQ(0, memcmp(b, b_ref, sizeof(b)));
}
}
void SpeedTest(int times) {
const int kMaxBlockSize = 32 * 32;
DECLARE_ALIGNED(16, int16_t, input[kMaxBlockSize]);
DECLARE_ALIGNED(16, tran_low_t, output[kMaxBlockSize]);
memset(input, 1, sizeof(input));
memset(output, 0, sizeof(output));
vpx_usec_timer timer;
vpx_usec_timer_start(&timer);
for (int i = 0; i < times; ++i) {
h_func_(input, bwh_, output);
}
vpx_usec_timer_mark(&timer);
const int elapsed_time = static_cast<int>(vpx_usec_timer_elapsed(&timer));
printf("Hadamard%dx%d[%12d runs]: %d us\n", bwh_, bwh_, times,
elapsed_time);
}
protected:
int bwh_;
int block_size_;
HadamardFunc h_func_;
ACMRandom rnd_;
};
void HadamardSpeedTest(const char *name, HadamardFunc const func,
const int16_t *input, int stride, tran_low_t *output,
int times) {
int i;
vpx_usec_timer timer;
class HadamardLowbdTest : public HadamardTestBase {
protected:
virtual int16_t Rand() { return rnd_.Rand9Signed(); }
};
vpx_usec_timer_start(&timer);
for (i = 0; i < times; ++i) {
func(input, stride, output);
}
vpx_usec_timer_mark(&timer);
TEST_P(HadamardLowbdTest, CompareReferenceRandom) { CompareReferenceRandom(); }
const int elapsed_time = static_cast<int>(vpx_usec_timer_elapsed(&timer));
printf("%s[%12d runs]: %d us\n", name, times, elapsed_time);
TEST_P(HadamardLowbdTest, VaryStride) { VaryStride(); }
TEST_P(HadamardLowbdTest, DISABLED_Speed) {
SpeedTest(10);
SpeedTest(10000);
SpeedTest(10000000);
}
class Hadamard8x8Test : public HadamardTestBase {};
void HadamardSpeedTest8x8(HadamardFunc const func, int times) {
DECLARE_ALIGNED(16, int16_t, input[64]);
DECLARE_ALIGNED(16, tran_low_t, output[64]);
memset(input, 1, sizeof(input));
HadamardSpeedTest("Hadamard8x8", func, input, 8, output, times);
}
TEST_P(Hadamard8x8Test, CompareReferenceRandom) {
DECLARE_ALIGNED(16, int16_t, a[64]);
DECLARE_ALIGNED(16, tran_low_t, b[64]);
tran_low_t b_ref[64];
for (int i = 0; i < 64; ++i) {
a[i] = rnd_.Rand9Signed();
}
memset(b, 0, sizeof(b));
memset(b_ref, 0, sizeof(b_ref));
reference_hadamard8x8(a, 8, b_ref);
ASM_REGISTER_STATE_CHECK(h_func_(a, 8, b));
// The order of the output is not important. Sort before checking.
std::sort(b, b + 64);
std::sort(b_ref, b_ref + 64);
EXPECT_EQ(0, memcmp(b, b_ref, sizeof(b)));
}
TEST_P(Hadamard8x8Test, VaryStride) {
DECLARE_ALIGNED(16, int16_t, a[64 * 8]);
DECLARE_ALIGNED(16, tran_low_t, b[64]);
tran_low_t b_ref[64];
for (int i = 0; i < 64 * 8; ++i) {
a[i] = rnd_.Rand9Signed();
}
for (int i = 8; i < 64; i += 8) {
memset(b, 0, sizeof(b));
memset(b_ref, 0, sizeof(b_ref));
reference_hadamard8x8(a, i, b_ref);
ASM_REGISTER_STATE_CHECK(h_func_(a, i, b));
// The order of the output is not important. Sort before checking.
std::sort(b, b + 64);
std::sort(b_ref, b_ref + 64);
EXPECT_EQ(0, memcmp(b, b_ref, sizeof(b)));
}
}
TEST_P(Hadamard8x8Test, DISABLED_Speed) {
HadamardSpeedTest8x8(h_func_, 10);
HadamardSpeedTest8x8(h_func_, 10000);
HadamardSpeedTest8x8(h_func_, 10000000);
}
INSTANTIATE_TEST_CASE_P(C, Hadamard8x8Test,
::testing::Values(&vpx_hadamard_8x8_c));
INSTANTIATE_TEST_CASE_P(
C, HadamardLowbdTest,
::testing::Values(HadamardFuncWithSize(&vpx_hadamard_8x8_c, 8),
HadamardFuncWithSize(&vpx_hadamard_16x16_c, 16),
HadamardFuncWithSize(&vpx_hadamard_32x32_c, 32)));
#if HAVE_SSE2
INSTANTIATE_TEST_CASE_P(SSE2, Hadamard8x8Test,
::testing::Values(&vpx_hadamard_8x8_sse2));
INSTANTIATE_TEST_CASE_P(
SSE2, HadamardLowbdTest,
::testing::Values(HadamardFuncWithSize(&vpx_hadamard_8x8_sse2, 8),
HadamardFuncWithSize(&vpx_hadamard_16x16_sse2, 16),
HadamardFuncWithSize(&vpx_hadamard_32x32_sse2, 32)));
#endif // HAVE_SSE2
#if HAVE_AVX2
INSTANTIATE_TEST_CASE_P(
AVX2, HadamardLowbdTest,
::testing::Values(HadamardFuncWithSize(&vpx_hadamard_16x16_avx2, 16),
HadamardFuncWithSize(&vpx_hadamard_32x32_avx2, 32)));
#endif // HAVE_AVX2
#if HAVE_SSSE3 && ARCH_X86_64
INSTANTIATE_TEST_CASE_P(SSSE3, Hadamard8x8Test,
::testing::Values(&vpx_hadamard_8x8_ssse3));
INSTANTIATE_TEST_CASE_P(
SSSE3, HadamardLowbdTest,
::testing::Values(HadamardFuncWithSize(&vpx_hadamard_8x8_ssse3, 8)));
#endif // HAVE_SSSE3 && ARCH_X86_64
#if HAVE_NEON
INSTANTIATE_TEST_CASE_P(NEON, Hadamard8x8Test,
::testing::Values(&vpx_hadamard_8x8_neon));
INSTANTIATE_TEST_CASE_P(
NEON, HadamardLowbdTest,
::testing::Values(HadamardFuncWithSize(&vpx_hadamard_8x8_neon, 8),
HadamardFuncWithSize(&vpx_hadamard_16x16_neon, 16)));
#endif // HAVE_NEON
// TODO(jingning): Remove highbitdepth flag when the SIMD functions are
// in place and turn on the unit test.
#if !CONFIG_VP9_HIGHBITDEPTH
#if HAVE_MSA
INSTANTIATE_TEST_CASE_P(MSA, Hadamard8x8Test,
::testing::Values(&vpx_hadamard_8x8_msa));
INSTANTIATE_TEST_CASE_P(
MSA, HadamardLowbdTest,
::testing::Values(HadamardFuncWithSize(&vpx_hadamard_8x8_msa, 8),
HadamardFuncWithSize(&vpx_hadamard_16x16_msa, 16)));
#endif // HAVE_MSA
#endif // !CONFIG_VP9_HIGHBITDEPTH
#if HAVE_VSX
INSTANTIATE_TEST_CASE_P(VSX, Hadamard8x8Test,
::testing::Values(&vpx_hadamard_8x8_vsx));
INSTANTIATE_TEST_CASE_P(
VSX, HadamardLowbdTest,
::testing::Values(HadamardFuncWithSize(&vpx_hadamard_8x8_vsx, 8),
HadamardFuncWithSize(&vpx_hadamard_16x16_vsx, 16)));
#endif // HAVE_VSX
class Hadamard16x16Test : public HadamardTestBase {};
#if CONFIG_VP9_HIGHBITDEPTH
class HadamardHighbdTest : public HadamardTestBase {
protected:
virtual int16_t Rand() { return rnd_.Rand13Signed(); }
};
void HadamardSpeedTest16x16(HadamardFunc const func, int times) {
DECLARE_ALIGNED(16, int16_t, input[256]);
DECLARE_ALIGNED(16, tran_low_t, output[256]);
memset(input, 1, sizeof(input));
HadamardSpeedTest("Hadamard16x16", func, input, 16, output, times);
TEST_P(HadamardHighbdTest, CompareReferenceRandom) { CompareReferenceRandom(); }
TEST_P(HadamardHighbdTest, VaryStride) { VaryStride(); }
TEST_P(HadamardHighbdTest, DISABLED_Speed) {
SpeedTest(10);
SpeedTest(10000);
SpeedTest(10000000);
}
TEST_P(Hadamard16x16Test, CompareReferenceRandom) {
DECLARE_ALIGNED(16, int16_t, a[16 * 16]);
DECLARE_ALIGNED(16, tran_low_t, b[16 * 16]);
tran_low_t b_ref[16 * 16];
for (int i = 0; i < 16 * 16; ++i) {
a[i] = rnd_.Rand9Signed();
}
memset(b, 0, sizeof(b));
memset(b_ref, 0, sizeof(b_ref));
reference_hadamard16x16(a, 16, b_ref);
ASM_REGISTER_STATE_CHECK(h_func_(a, 16, b));
// The order of the output is not important. Sort before checking.
std::sort(b, b + 16 * 16);
std::sort(b_ref, b_ref + 16 * 16);
EXPECT_EQ(0, memcmp(b, b_ref, sizeof(b)));
}
TEST_P(Hadamard16x16Test, VaryStride) {
DECLARE_ALIGNED(16, int16_t, a[16 * 16 * 8]);
DECLARE_ALIGNED(16, tran_low_t, b[16 * 16]);
tran_low_t b_ref[16 * 16];
for (int i = 0; i < 16 * 16 * 8; ++i) {
a[i] = rnd_.Rand9Signed();
}
for (int i = 8; i < 64; i += 8) {
memset(b, 0, sizeof(b));
memset(b_ref, 0, sizeof(b_ref));
reference_hadamard16x16(a, i, b_ref);
ASM_REGISTER_STATE_CHECK(h_func_(a, i, b));
// The order of the output is not important. Sort before checking.
std::sort(b, b + 16 * 16);
std::sort(b_ref, b_ref + 16 * 16);
EXPECT_EQ(0, memcmp(b, b_ref, sizeof(b)));
}
}
TEST_P(Hadamard16x16Test, DISABLED_Speed) {
HadamardSpeedTest16x16(h_func_, 10);
HadamardSpeedTest16x16(h_func_, 10000);
HadamardSpeedTest16x16(h_func_, 10000000);
}
INSTANTIATE_TEST_CASE_P(C, Hadamard16x16Test,
::testing::Values(&vpx_hadamard_16x16_c));
#if HAVE_SSE2
INSTANTIATE_TEST_CASE_P(SSE2, Hadamard16x16Test,
::testing::Values(&vpx_hadamard_16x16_sse2));
#endif // HAVE_SSE2
INSTANTIATE_TEST_CASE_P(
C, HadamardHighbdTest,
::testing::Values(HadamardFuncWithSize(&vpx_highbd_hadamard_8x8_c, 8),
HadamardFuncWithSize(&vpx_highbd_hadamard_16x16_c, 16),
HadamardFuncWithSize(&vpx_highbd_hadamard_32x32_c, 32)));
#if HAVE_AVX2
INSTANTIATE_TEST_CASE_P(AVX2, Hadamard16x16Test,
::testing::Values(&vpx_hadamard_16x16_avx2));
INSTANTIATE_TEST_CASE_P(
AVX2, HadamardHighbdTest,
::testing::Values(HadamardFuncWithSize(&vpx_highbd_hadamard_8x8_avx2, 8),
HadamardFuncWithSize(&vpx_highbd_hadamard_16x16_avx2, 16),
HadamardFuncWithSize(&vpx_highbd_hadamard_32x32_avx2,
32)));
#endif // HAVE_AVX2
#if HAVE_VSX
INSTANTIATE_TEST_CASE_P(VSX, Hadamard16x16Test,
::testing::Values(&vpx_hadamard_16x16_vsx));
#endif // HAVE_VSX
#if HAVE_NEON
INSTANTIATE_TEST_CASE_P(NEON, Hadamard16x16Test,
::testing::Values(&vpx_hadamard_16x16_neon));
#endif // HAVE_NEON
#if !CONFIG_VP9_HIGHBITDEPTH
#if HAVE_MSA
INSTANTIATE_TEST_CASE_P(MSA, Hadamard16x16Test,
::testing::Values(&vpx_hadamard_16x16_msa));
#endif // HAVE_MSA
#endif // !CONFIG_VP9_HIGHBITDEPTH
#endif // CONFIG_VP9_HIGHBITDEPTH
} // namespace

View File

@ -7,8 +7,8 @@
* in the file PATENTS. All contributing project authors may
* be found in the AUTHORS file in the root of the source tree.
*/
#ifndef TEST_I420_VIDEO_SOURCE_H_
#define TEST_I420_VIDEO_SOURCE_H_
#ifndef VPX_TEST_I420_VIDEO_SOURCE_H_
#define VPX_TEST_I420_VIDEO_SOURCE_H_
#include <cstdio>
#include <cstdlib>
#include <string>
@ -30,4 +30,4 @@ class I420VideoSource : public YUVVideoSource {
} // namespace libvpx_test
#endif // TEST_I420_VIDEO_SOURCE_H_
#endif // VPX_TEST_I420_VIDEO_SOURCE_H_

View File

@ -72,6 +72,7 @@ TEST_P(IDCTTest, TestAllZeros) {
TEST_P(IDCTTest, TestAllOnes) {
input->Set(0);
ASSERT_TRUE(input->TopLeftPixel() != NULL);
// When the first element is '4' it will fill the output buffer with '1'.
input->TopLeftPixel()[0] = 4;
predict->Set(0);
@ -89,6 +90,7 @@ TEST_P(IDCTTest, TestAddOne) {
// Set the transform output to '1' and make sure it gets added to the
// prediction buffer.
input->Set(0);
ASSERT_TRUE(input->TopLeftPixel() != NULL);
input->TopLeftPixel()[0] = 4;
output->Set(0);
@ -174,4 +176,4 @@ INSTANTIATE_TEST_CASE_P(MSA, IDCTTest,
INSTANTIATE_TEST_CASE_P(MMI, IDCTTest,
::testing::Values(vp8_short_idct4x4llm_mmi));
#endif // HAVE_MMI
}
} // namespace

View File

@ -10,6 +10,7 @@
#include <cstdio>
#include <cstdlib>
#include <memory>
#include <string>
#include <vector>
#include "third_party/googletest/src/include/gtest/gtest.h"
@ -89,7 +90,7 @@ class InvalidFileTest : public ::libvpx_test::DecoderTest,
const std::string filename = input.filename;
// Open compressed video file.
testing::internal::scoped_ptr<libvpx_test::CompressedVideoSource> video;
std::unique_ptr<libvpx_test::CompressedVideoSource> video;
if (filename.substr(filename.length() - 3, 3) == "ivf") {
video.reset(new libvpx_test::IVFVideoSource(filename));
} else if (filename.substr(filename.length() - 4, 4) == "webm") {
@ -123,6 +124,8 @@ TEST_P(InvalidFileTest, ReturnCode) { RunTest(); }
#if CONFIG_VP8_DECODER
const DecodeParam kVP8InvalidFileTests[] = {
{ 1, "invalid-bug-1443.ivf" },
{ 1, "invalid-token-partition.ivf" },
{ 1, "invalid-vp80-00-comprehensive-s17661_r01-05_b6-.ivf" },
};
VP8_INSTANTIATE_TEST_CASE(InvalidFileTest,
@ -202,6 +205,8 @@ const DecodeParam kMultiThreadedVP9InvalidFileTests[] = {
{ 2, "invalid-vp90-2-09-aq2.webm.ivf.s3984_r01-05_b6-.v2.ivf" },
{ 4, "invalid-vp90-2-09-subpixel-00.ivf.s19552_r01-05_b6-.v2.ivf" },
{ 2, "invalid-crbug-629481.webm" },
{ 3, "invalid-crbug-1558.ivf" },
{ 4, "invalid-crbug-1562.ivf" },
};
INSTANTIATE_TEST_CASE_P(

View File

@ -7,8 +7,8 @@
* in the file PATENTS. All contributing project authors may
* be found in the AUTHORS file in the root of the source tree.
*/
#ifndef TEST_IVF_VIDEO_SOURCE_H_
#define TEST_IVF_VIDEO_SOURCE_H_
#ifndef VPX_TEST_IVF_VIDEO_SOURCE_H_
#define VPX_TEST_IVF_VIDEO_SOURCE_H_
#include <cstdio>
#include <cstdlib>
#include <new>
@ -16,7 +16,7 @@
#include "test/video_source.h"
namespace libvpx_test {
const unsigned int kCodeBufferSize = 256 * 1024;
const unsigned int kCodeBufferSize = 256 * 1024 * 1024;
const unsigned int kIvfFileHdrSize = 32;
const unsigned int kIvfFrameHdrSize = 12;
@ -103,4 +103,4 @@ class IVFVideoSource : public CompressedVideoSource {
} // namespace libvpx_test
#endif // TEST_IVF_VIDEO_SOURCE_H_
#endif // VPX_TEST_IVF_VIDEO_SOURCE_H_

View File

@ -38,7 +38,7 @@ class KeyframeTest
if (kf_do_force_kf_) {
frame_flags_ = (video->frame() % 3) ? 0 : VPX_EFLAG_FORCE_KF;
}
if (set_cpu_used_ && video->frame() == 1) {
if (set_cpu_used_ && video->frame() == 0) {
encoder->Control(VP8E_SET_CPUUSED, set_cpu_used_);
}
}
@ -68,7 +68,9 @@ TEST_P(KeyframeTest, TestRandomVideoSource) {
// In realtime mode - auto placed keyframes are exceedingly rare, don't
// bother with this check if(GetParam() > 0)
if (GET_PARAM(1) > 0) EXPECT_GT(kf_count_, 1);
if (GET_PARAM(1) > 0) {
EXPECT_GT(kf_count_, 1);
}
}
TEST_P(KeyframeTest, TestDisableKeyframes) {
@ -128,8 +130,9 @@ TEST_P(KeyframeTest, TestAutoKeyframe) {
// In realtime mode - auto placed keyframes are exceedingly rare, don't
// bother with this check
if (GET_PARAM(1) > 0)
if (GET_PARAM(1) > 0) {
EXPECT_EQ(2u, kf_pts_list_.size()) << " Not the right number of keyframes ";
}
// Verify that keyframes match the file keyframes in the file.
for (std::vector<vpx_codec_pts_t>::const_iterator iter = kf_pts_list_.begin();

View File

@ -11,6 +11,7 @@
#include <cmath>
#include <cstdlib>
#include <string>
#include <tuple>
#include "third_party/googletest/src/include/gtest/gtest.h"
@ -56,8 +57,8 @@ typedef void (*dual_loop_op_t)(Pixel *s, int p, const uint8_t *blimit0,
const uint8_t *thresh1);
#endif // CONFIG_VP9_HIGHBITDEPTH
typedef std::tr1::tuple<loop_op_t, loop_op_t, int> loop8_param_t;
typedef std::tr1::tuple<dual_loop_op_t, dual_loop_op_t, int> dualloop8_param_t;
typedef std::tuple<loop_op_t, loop_op_t, int> loop8_param_t;
typedef std::tuple<dual_loop_op_t, dual_loop_op_t, int> dualloop8_param_t;
void InitInput(Pixel *s, Pixel *ref_s, ACMRandom *rnd, const uint8_t limit,
const int mask, const int32_t p, const int i) {
@ -402,7 +403,7 @@ TEST_P(Loop8Test9Param, ValueCheck) {
<< "First failed at test case " << first_failure;
}
using std::tr1::make_tuple;
using std::make_tuple;
#if HAVE_SSE2
#if CONFIG_VP9_HIGHBITDEPTH

View File

@ -8,8 +8,8 @@
* be found in the AUTHORS file in the root of the source tree.
*/
#ifndef TEST_MD5_HELPER_H_
#define TEST_MD5_HELPER_H_
#ifndef VPX_TEST_MD5_HELPER_H_
#define VPX_TEST_MD5_HELPER_H_
#include "./md5_utils.h"
#include "vpx/vpx_decoder.h"
@ -72,4 +72,4 @@ class MD5 {
} // namespace libvpx_test
#endif // TEST_MD5_HELPER_H_
#endif // VPX_TEST_MD5_HELPER_H_

View File

@ -11,8 +11,8 @@
#include <math.h>
#include <stdlib.h>
#include <string.h>
#include <limits>
#include <tuple>
#include "third_party/googletest/src/include/gtest/gtest.h"
@ -51,8 +51,8 @@ void highbd_wrapper(const tran_low_t *in, uint8_t *out, int stride, int bd) {
}
#endif
typedef std::tr1::tuple<FwdTxfmFunc, InvTxfmWithBdFunc, InvTxfmWithBdFunc,
TX_SIZE, int, int, int>
typedef std::tuple<FwdTxfmFunc, InvTxfmWithBdFunc, InvTxfmWithBdFunc, TX_SIZE,
int, int, int>
PartialInvTxfmParam;
const int kMaxNumCoeffs = 1024;
const int kCountTestBlock = 1000;
@ -324,7 +324,7 @@ TEST_P(PartialIDctTest, DISABLED_Speed) {
<< "Error: partial inverse transform produces different results";
}
using std::tr1::make_tuple;
using std::make_tuple;
const PartialInvTxfmParam c_partial_idct_tests[] = {
#if CONFIG_VP9_HIGHBITDEPTH

View File

@ -11,6 +11,7 @@
#include "./vpx_config.h"
#include "./vpx_dsp_rtcd.h"
#include "test/acm_random.h"
#include "test/bench.h"
#include "test/buffer.h"
#include "test/clear_system_state.h"
#include "test/register_state_check.h"
@ -32,7 +33,6 @@ typedef void (*VpxMbPostProcDownFunc)(unsigned char *dst, int pitch, int rows,
int cols, int flimit);
namespace {
// Compute the filter level used in post proc from the loop filter strength
int q2mbl(int x) {
if (x < 20) x = 20;
@ -42,33 +42,52 @@ int q2mbl(int x) {
}
class VpxPostProcDownAndAcrossMbRowTest
: public ::testing::TestWithParam<VpxPostProcDownAndAcrossMbRowFunc> {
: public AbstractBench,
public ::testing::TestWithParam<VpxPostProcDownAndAcrossMbRowFunc> {
public:
VpxPostProcDownAndAcrossMbRowTest()
: mb_post_proc_down_and_across_(GetParam()) {}
virtual void TearDown() { libvpx_test::ClearSystemState(); }
protected:
virtual void Run();
const VpxPostProcDownAndAcrossMbRowFunc mb_post_proc_down_and_across_;
// Size of the underlying data block that will be filtered.
int block_width_;
int block_height_;
Buffer<uint8_t> *src_image_;
Buffer<uint8_t> *dst_image_;
uint8_t *flimits_;
};
void VpxPostProcDownAndAcrossMbRowTest::Run() {
mb_post_proc_down_and_across_(
src_image_->TopLeftPixel(), dst_image_->TopLeftPixel(),
src_image_->stride(), dst_image_->stride(), block_width_, flimits_, 16);
}
// Test routine for the VPx post-processing function
// vpx_post_proc_down_and_across_mb_row_c.
TEST_P(VpxPostProcDownAndAcrossMbRowTest, CheckFilterOutput) {
// Size of the underlying data block that will be filtered.
const int block_width = 16;
const int block_height = 16;
block_width_ = 16;
block_height_ = 16;
// 5-tap filter needs 2 padding rows above and below the block in the input.
Buffer<uint8_t> src_image = Buffer<uint8_t>(block_width, block_height, 2);
Buffer<uint8_t> src_image = Buffer<uint8_t>(block_width_, block_height_, 2);
ASSERT_TRUE(src_image.Init());
// Filter extends output block by 8 samples at left and right edges.
// Though the left padding is only 8 bytes, the assembly code tries to
// read 16 bytes before the pointer.
Buffer<uint8_t> dst_image =
Buffer<uint8_t>(block_width, block_height, 8, 16, 8, 8);
Buffer<uint8_t>(block_width_, block_height_, 8, 16, 8, 8);
ASSERT_TRUE(dst_image.Init());
uint8_t *const flimits =
reinterpret_cast<uint8_t *>(vpx_memalign(16, block_width));
(void)memset(flimits, 255, block_width);
flimits_ = reinterpret_cast<uint8_t *>(vpx_memalign(16, block_width_));
(void)memset(flimits_, 255, block_width_);
// Initialize pixels in the input:
// block pixels to value 1,
@ -79,37 +98,36 @@ TEST_P(VpxPostProcDownAndAcrossMbRowTest, CheckFilterOutput) {
// Initialize pixels in the output to 99.
dst_image.Set(99);
ASM_REGISTER_STATE_CHECK(GetParam()(
ASM_REGISTER_STATE_CHECK(mb_post_proc_down_and_across_(
src_image.TopLeftPixel(), dst_image.TopLeftPixel(), src_image.stride(),
dst_image.stride(), block_width, flimits, 16));
dst_image.stride(), block_width_, flimits_, 16));
static const uint8_t kExpectedOutput[block_height] = {
4, 3, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 3, 4
};
static const uint8_t kExpectedOutput[] = { 4, 3, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 3, 4 };
uint8_t *pixel_ptr = dst_image.TopLeftPixel();
for (int i = 0; i < block_height; ++i) {
for (int j = 0; j < block_width; ++j) {
for (int i = 0; i < block_height_; ++i) {
for (int j = 0; j < block_width_; ++j) {
ASSERT_EQ(kExpectedOutput[i], pixel_ptr[j])
<< "at (" << i << ", " << j << ")";
}
pixel_ptr += dst_image.stride();
}
vpx_free(flimits);
vpx_free(flimits_);
};
TEST_P(VpxPostProcDownAndAcrossMbRowTest, CheckCvsAssembly) {
// Size of the underlying data block that will be filtered.
// Y blocks are always a multiple of 16 wide and exactly 16 high. U and V
// blocks are always a multiple of 8 wide and exactly 8 high.
const int block_width = 136;
const int block_height = 16;
block_width_ = 136;
block_height_ = 16;
// 5-tap filter needs 2 padding rows above and below the block in the input.
// SSE2 reads in blocks of 16. Pad an extra 8 in case the width is not %16.
Buffer<uint8_t> src_image =
Buffer<uint8_t>(block_width, block_height, 2, 2, 10, 2);
Buffer<uint8_t>(block_width_, block_height_, 2, 2, 10, 2);
ASSERT_TRUE(src_image.Init());
// Filter extends output block by 8 samples at left and right edges.
@ -118,17 +136,17 @@ TEST_P(VpxPostProcDownAndAcrossMbRowTest, CheckCvsAssembly) {
// not a problem.
// SSE2 reads in blocks of 16. Pad an extra 8 in case the width is not %16.
Buffer<uint8_t> dst_image =
Buffer<uint8_t>(block_width, block_height, 8, 8, 16, 8);
Buffer<uint8_t>(block_width_, block_height_, 8, 8, 16, 8);
ASSERT_TRUE(dst_image.Init());
Buffer<uint8_t> dst_image_ref = Buffer<uint8_t>(block_width, block_height, 8);
Buffer<uint8_t> dst_image_ref =
Buffer<uint8_t>(block_width_, block_height_, 8);
ASSERT_TRUE(dst_image_ref.Init());
// Filter values are set in blocks of 16 for Y and 8 for U/V. Each macroblock
// can have a different filter. SSE2 assembly reads flimits in blocks of 16 so
// it must be padded out.
const int flimits_width = block_width % 16 ? block_width + 8 : block_width;
uint8_t *const flimits =
reinterpret_cast<uint8_t *>(vpx_memalign(16, flimits_width));
const int flimits_width = block_width_ % 16 ? block_width_ + 8 : block_width_;
flimits_ = reinterpret_cast<uint8_t *>(vpx_memalign(16, flimits_width));
ACMRandom rnd;
rnd.Reset(ACMRandom::DeterministicSeed());
@ -138,37 +156,78 @@ TEST_P(VpxPostProcDownAndAcrossMbRowTest, CheckCvsAssembly) {
src_image.SetPadding(10);
src_image.Set(&rnd, &ACMRandom::Rand8);
for (int blocks = 0; blocks < block_width; blocks += 8) {
(void)memset(flimits, 0, sizeof(*flimits) * flimits_width);
for (int blocks = 0; blocks < block_width_; blocks += 8) {
(void)memset(flimits_, 0, sizeof(*flimits_) * flimits_width);
for (int f = 0; f < 255; f++) {
(void)memset(flimits + blocks, f, sizeof(*flimits) * 8);
(void)memset(flimits_ + blocks, f, sizeof(*flimits_) * 8);
dst_image.Set(0);
dst_image_ref.Set(0);
vpx_post_proc_down_and_across_mb_row_c(
src_image.TopLeftPixel(), dst_image_ref.TopLeftPixel(),
src_image.stride(), dst_image_ref.stride(), block_width, flimits,
block_height);
ASM_REGISTER_STATE_CHECK(
GetParam()(src_image.TopLeftPixel(), dst_image.TopLeftPixel(),
src_image.stride(), dst_image.stride(), block_width,
flimits, block_height));
src_image.stride(), dst_image_ref.stride(), block_width_, flimits_,
block_height_);
ASM_REGISTER_STATE_CHECK(mb_post_proc_down_and_across_(
src_image.TopLeftPixel(), dst_image.TopLeftPixel(),
src_image.stride(), dst_image.stride(), block_width_, flimits_,
block_height_));
ASSERT_TRUE(dst_image.CheckValues(dst_image_ref));
}
}
vpx_free(flimits);
vpx_free(flimits_);
}
TEST_P(VpxPostProcDownAndAcrossMbRowTest, DISABLED_Speed) {
// Size of the underlying data block that will be filtered.
block_width_ = 16;
block_height_ = 16;
// 5-tap filter needs 2 padding rows above and below the block in the input.
Buffer<uint8_t> src_image = Buffer<uint8_t>(block_width_, block_height_, 2);
ASSERT_TRUE(src_image.Init());
this->src_image_ = &src_image;
// Filter extends output block by 8 samples at left and right edges.
// Though the left padding is only 8 bytes, the assembly code tries to
// read 16 bytes before the pointer.
Buffer<uint8_t> dst_image =
Buffer<uint8_t>(block_width_, block_height_, 8, 16, 8, 8);
ASSERT_TRUE(dst_image.Init());
this->dst_image_ = &dst_image;
flimits_ = reinterpret_cast<uint8_t *>(vpx_memalign(16, block_width_));
(void)memset(flimits_, 255, block_width_);
// Initialize pixels in the input:
// block pixels to value 1,
// border pixels to value 10.
src_image.SetPadding(10);
src_image.Set(1);
// Initialize pixels in the output to 99.
dst_image.Set(99);
RunNTimes(INT16_MAX);
PrintMedian("16x16");
vpx_free(flimits_);
};
class VpxMbPostProcAcrossIpTest
: public ::testing::TestWithParam<VpxMbPostProcAcrossIpFunc> {
: public AbstractBench,
public ::testing::TestWithParam<VpxMbPostProcAcrossIpFunc> {
public:
VpxMbPostProcAcrossIpTest()
: rows_(16), cols_(16), mb_post_proc_across_ip_(GetParam()),
src_(Buffer<uint8_t>(rows_, cols_, 8, 8, 17, 8)) {}
virtual void TearDown() { libvpx_test::ClearSystemState(); }
protected:
virtual void Run();
void SetCols(unsigned char *s, int rows, int cols, int src_width) {
for (int r = 0; r < rows; r++) {
for (int c = 0; c < cols; c++) {
@ -195,71 +254,67 @@ class VpxMbPostProcAcrossIpTest
GetParam()(s, src_width, rows, cols, filter_level));
RunComparison(expected_output, s, rows, cols, src_width);
}
const int rows_;
const int cols_;
const VpxMbPostProcAcrossIpFunc mb_post_proc_across_ip_;
Buffer<uint8_t> src_;
};
void VpxMbPostProcAcrossIpTest::Run() {
mb_post_proc_across_ip_(src_.TopLeftPixel(), src_.stride(), rows_, cols_,
q2mbl(0));
}
TEST_P(VpxMbPostProcAcrossIpTest, CheckLowFilterOutput) {
const int rows = 16;
const int cols = 16;
ASSERT_TRUE(src_.Init());
src_.SetPadding(10);
SetCols(src_.TopLeftPixel(), rows_, cols_, src_.stride());
Buffer<uint8_t> src = Buffer<uint8_t>(cols, rows, 8, 8, 17, 8);
ASSERT_TRUE(src.Init());
src.SetPadding(10);
SetCols(src.TopLeftPixel(), rows, cols, src.stride());
Buffer<uint8_t> expected_output = Buffer<uint8_t>(cols, rows, 0);
Buffer<uint8_t> expected_output = Buffer<uint8_t>(cols_, rows_, 0);
ASSERT_TRUE(expected_output.Init());
SetCols(expected_output.TopLeftPixel(), rows, cols, expected_output.stride());
SetCols(expected_output.TopLeftPixel(), rows_, cols_,
expected_output.stride());
RunFilterLevel(src.TopLeftPixel(), rows, cols, src.stride(), q2mbl(0),
RunFilterLevel(src_.TopLeftPixel(), rows_, cols_, src_.stride(), q2mbl(0),
expected_output.TopLeftPixel());
}
TEST_P(VpxMbPostProcAcrossIpTest, CheckMediumFilterOutput) {
const int rows = 16;
const int cols = 16;
ASSERT_TRUE(src_.Init());
src_.SetPadding(10);
SetCols(src_.TopLeftPixel(), rows_, cols_, src_.stride());
Buffer<uint8_t> src = Buffer<uint8_t>(cols, rows, 8, 8, 17, 8);
ASSERT_TRUE(src.Init());
src.SetPadding(10);
SetCols(src.TopLeftPixel(), rows, cols, src.stride());
static const unsigned char kExpectedOutput[cols] = {
static const unsigned char kExpectedOutput[] = {
2, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 13
};
RunFilterLevel(src.TopLeftPixel(), rows, cols, src.stride(), q2mbl(70),
RunFilterLevel(src_.TopLeftPixel(), rows_, cols_, src_.stride(), q2mbl(70),
kExpectedOutput);
}
TEST_P(VpxMbPostProcAcrossIpTest, CheckHighFilterOutput) {
const int rows = 16;
const int cols = 16;
ASSERT_TRUE(src_.Init());
src_.SetPadding(10);
SetCols(src_.TopLeftPixel(), rows_, cols_, src_.stride());
Buffer<uint8_t> src = Buffer<uint8_t>(cols, rows, 8, 8, 17, 8);
ASSERT_TRUE(src.Init());
src.SetPadding(10);
SetCols(src.TopLeftPixel(), rows, cols, src.stride());
static const unsigned char kExpectedOutput[cols] = {
static const unsigned char kExpectedOutput[] = {
2, 2, 3, 4, 4, 5, 6, 7, 8, 9, 10, 11, 11, 12, 13, 13
};
RunFilterLevel(src.TopLeftPixel(), rows, cols, src.stride(), INT_MAX,
RunFilterLevel(src_.TopLeftPixel(), rows_, cols_, src_.stride(), INT_MAX,
kExpectedOutput);
SetCols(src.TopLeftPixel(), rows, cols, src.stride());
SetCols(src_.TopLeftPixel(), rows_, cols_, src_.stride());
RunFilterLevel(src.TopLeftPixel(), rows, cols, src.stride(), q2mbl(100),
RunFilterLevel(src_.TopLeftPixel(), rows_, cols_, src_.stride(), q2mbl(100),
kExpectedOutput);
}
TEST_P(VpxMbPostProcAcrossIpTest, CheckCvsAssembly) {
const int rows = 16;
const int cols = 16;
Buffer<uint8_t> c_mem = Buffer<uint8_t>(cols, rows, 8, 8, 17, 8);
Buffer<uint8_t> c_mem = Buffer<uint8_t>(cols_, rows_, 8, 8, 17, 8);
ASSERT_TRUE(c_mem.Init());
Buffer<uint8_t> asm_mem = Buffer<uint8_t>(cols, rows, 8, 8, 17, 8);
Buffer<uint8_t> asm_mem = Buffer<uint8_t>(cols_, rows_, 8, 8, 17, 8);
ASSERT_TRUE(asm_mem.Init());
// When level >= 100, the filter behaves the same as the level = INT_MAX
@ -267,24 +322,41 @@ TEST_P(VpxMbPostProcAcrossIpTest, CheckCvsAssembly) {
for (int level = 0; level < 100; level++) {
c_mem.SetPadding(10);
asm_mem.SetPadding(10);
SetCols(c_mem.TopLeftPixel(), rows, cols, c_mem.stride());
SetCols(asm_mem.TopLeftPixel(), rows, cols, asm_mem.stride());
SetCols(c_mem.TopLeftPixel(), rows_, cols_, c_mem.stride());
SetCols(asm_mem.TopLeftPixel(), rows_, cols_, asm_mem.stride());
vpx_mbpost_proc_across_ip_c(c_mem.TopLeftPixel(), c_mem.stride(), rows,
cols, q2mbl(level));
vpx_mbpost_proc_across_ip_c(c_mem.TopLeftPixel(), c_mem.stride(), rows_,
cols_, q2mbl(level));
ASM_REGISTER_STATE_CHECK(GetParam()(
asm_mem.TopLeftPixel(), asm_mem.stride(), rows, cols, q2mbl(level)));
asm_mem.TopLeftPixel(), asm_mem.stride(), rows_, cols_, q2mbl(level)));
ASSERT_TRUE(asm_mem.CheckValues(c_mem));
}
}
TEST_P(VpxMbPostProcAcrossIpTest, DISABLED_Speed) {
ASSERT_TRUE(src_.Init());
src_.SetPadding(10);
SetCols(src_.TopLeftPixel(), rows_, cols_, src_.stride());
RunNTimes(100000);
PrintMedian("16x16");
}
class VpxMbPostProcDownTest
: public ::testing::TestWithParam<VpxMbPostProcDownFunc> {
: public AbstractBench,
public ::testing::TestWithParam<VpxMbPostProcDownFunc> {
public:
VpxMbPostProcDownTest()
: rows_(16), cols_(16), mb_post_proc_down_(GetParam()),
src_c_(Buffer<uint8_t>(rows_, cols_, 8, 8, 8, 17)) {}
virtual void TearDown() { libvpx_test::ClearSystemState(); }
protected:
virtual void Run();
void SetRows(unsigned char *src_c, int rows, int cols, int src_width) {
for (int r = 0; r < rows; r++) {
memset(src_c, r, cols);
@ -306,22 +378,28 @@ class VpxMbPostProcDownTest
void RunFilterLevel(unsigned char *s, int rows, int cols, int src_width,
int filter_level, const unsigned char *expected_output) {
ASM_REGISTER_STATE_CHECK(
GetParam()(s, src_width, rows, cols, filter_level));
mb_post_proc_down_(s, src_width, rows, cols, filter_level));
RunComparison(expected_output, s, rows, cols, src_width);
}
const int rows_;
const int cols_;
const VpxMbPostProcDownFunc mb_post_proc_down_;
Buffer<uint8_t> src_c_;
};
void VpxMbPostProcDownTest::Run() {
mb_post_proc_down_(src_c_.TopLeftPixel(), src_c_.stride(), rows_, cols_,
q2mbl(0));
}
TEST_P(VpxMbPostProcDownTest, CheckHighFilterOutput) {
const int rows = 16;
const int cols = 16;
ASSERT_TRUE(src_c_.Init());
src_c_.SetPadding(10);
Buffer<uint8_t> src_c = Buffer<uint8_t>(cols, rows, 8, 8, 8, 17);
ASSERT_TRUE(src_c.Init());
src_c.SetPadding(10);
SetRows(src_c_.TopLeftPixel(), rows_, cols_, src_c_.stride());
SetRows(src_c.TopLeftPixel(), rows, cols, src_c.stride());
static const unsigned char kExpectedOutput[rows * cols] = {
static const unsigned char kExpectedOutput[] = {
2, 2, 1, 1, 2, 2, 2, 2, 2, 2, 1, 1, 2, 2, 2, 2, 2, 2, 2,
2, 3, 2, 2, 2, 2, 2, 2, 2, 3, 2, 2, 2, 3, 3, 3, 3, 3, 3,
3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 4, 4, 3, 4, 4, 3, 3, 3,
@ -338,26 +416,22 @@ TEST_P(VpxMbPostProcDownTest, CheckHighFilterOutput) {
13, 13, 13, 13, 14, 13, 13, 13, 13
};
RunFilterLevel(src_c.TopLeftPixel(), rows, cols, src_c.stride(), INT_MAX,
RunFilterLevel(src_c_.TopLeftPixel(), rows_, cols_, src_c_.stride(), INT_MAX,
kExpectedOutput);
src_c.SetPadding(10);
SetRows(src_c.TopLeftPixel(), rows, cols, src_c.stride());
RunFilterLevel(src_c.TopLeftPixel(), rows, cols, src_c.stride(), q2mbl(100),
kExpectedOutput);
src_c_.SetPadding(10);
SetRows(src_c_.TopLeftPixel(), rows_, cols_, src_c_.stride());
RunFilterLevel(src_c_.TopLeftPixel(), rows_, cols_, src_c_.stride(),
q2mbl(100), kExpectedOutput);
}
TEST_P(VpxMbPostProcDownTest, CheckMediumFilterOutput) {
const int rows = 16;
const int cols = 16;
ASSERT_TRUE(src_c_.Init());
src_c_.SetPadding(10);
Buffer<uint8_t> src_c = Buffer<uint8_t>(cols, rows, 8, 8, 8, 17);
ASSERT_TRUE(src_c.Init());
src_c.SetPadding(10);
SetRows(src_c_.TopLeftPixel(), rows_, cols_, src_c_.stride());
SetRows(src_c.TopLeftPixel(), rows, cols, src_c.stride());
static const unsigned char kExpectedOutput[rows * cols] = {
static const unsigned char kExpectedOutput[] = {
2, 2, 1, 1, 2, 2, 2, 2, 2, 2, 1, 1, 2, 2, 2, 2, 2, 2, 2,
2, 3, 2, 2, 2, 2, 2, 2, 2, 3, 2, 2, 2, 2, 2, 2, 2, 2, 2,
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3, 3,
@ -374,67 +448,69 @@ TEST_P(VpxMbPostProcDownTest, CheckMediumFilterOutput) {
13, 13, 13, 13, 14, 13, 13, 13, 13
};
RunFilterLevel(src_c.TopLeftPixel(), rows, cols, src_c.stride(), q2mbl(70),
kExpectedOutput);
RunFilterLevel(src_c_.TopLeftPixel(), rows_, cols_, src_c_.stride(),
q2mbl(70), kExpectedOutput);
}
TEST_P(VpxMbPostProcDownTest, CheckLowFilterOutput) {
const int rows = 16;
const int cols = 16;
ASSERT_TRUE(src_c_.Init());
src_c_.SetPadding(10);
Buffer<uint8_t> src_c = Buffer<uint8_t>(cols, rows, 8, 8, 8, 17);
ASSERT_TRUE(src_c.Init());
src_c.SetPadding(10);
SetRows(src_c_.TopLeftPixel(), rows_, cols_, src_c_.stride());
SetRows(src_c.TopLeftPixel(), rows, cols, src_c.stride());
unsigned char *expected_output = new unsigned char[rows * cols];
unsigned char *expected_output = new unsigned char[rows_ * cols_];
ASSERT_TRUE(expected_output != NULL);
SetRows(expected_output, rows, cols, cols);
SetRows(expected_output, rows_, cols_, cols_);
RunFilterLevel(src_c.TopLeftPixel(), rows, cols, src_c.stride(), q2mbl(0),
RunFilterLevel(src_c_.TopLeftPixel(), rows_, cols_, src_c_.stride(), q2mbl(0),
expected_output);
delete[] expected_output;
}
TEST_P(VpxMbPostProcDownTest, CheckCvsAssembly) {
const int rows = 16;
const int cols = 16;
ACMRandom rnd;
rnd.Reset(ACMRandom::DeterministicSeed());
Buffer<uint8_t> src_c = Buffer<uint8_t>(cols, rows, 8, 8, 8, 17);
ASSERT_TRUE(src_c.Init());
Buffer<uint8_t> src_asm = Buffer<uint8_t>(cols, rows, 8, 8, 8, 17);
ASSERT_TRUE(src_c_.Init());
Buffer<uint8_t> src_asm = Buffer<uint8_t>(cols_, rows_, 8, 8, 8, 17);
ASSERT_TRUE(src_asm.Init());
for (int level = 0; level < 100; level++) {
src_c.SetPadding(10);
src_c_.SetPadding(10);
src_asm.SetPadding(10);
src_c.Set(&rnd, &ACMRandom::Rand8);
src_asm.CopyFrom(src_c);
src_c_.Set(&rnd, &ACMRandom::Rand8);
src_asm.CopyFrom(src_c_);
vpx_mbpost_proc_down_c(src_c.TopLeftPixel(), src_c.stride(), rows, cols,
vpx_mbpost_proc_down_c(src_c_.TopLeftPixel(), src_c_.stride(), rows_, cols_,
q2mbl(level));
ASM_REGISTER_STATE_CHECK(GetParam()(
src_asm.TopLeftPixel(), src_asm.stride(), rows, cols, q2mbl(level)));
ASSERT_TRUE(src_asm.CheckValues(src_c));
ASM_REGISTER_STATE_CHECK(mb_post_proc_down_(
src_asm.TopLeftPixel(), src_asm.stride(), rows_, cols_, q2mbl(level)));
ASSERT_TRUE(src_asm.CheckValues(src_c_));
src_c.SetPadding(10);
src_c_.SetPadding(10);
src_asm.SetPadding(10);
src_c.Set(&rnd, &ACMRandom::Rand8Extremes);
src_asm.CopyFrom(src_c);
src_c_.Set(&rnd, &ACMRandom::Rand8Extremes);
src_asm.CopyFrom(src_c_);
vpx_mbpost_proc_down_c(src_c.TopLeftPixel(), src_c.stride(), rows, cols,
vpx_mbpost_proc_down_c(src_c_.TopLeftPixel(), src_c_.stride(), rows_, cols_,
q2mbl(level));
ASM_REGISTER_STATE_CHECK(GetParam()(
src_asm.TopLeftPixel(), src_asm.stride(), rows, cols, q2mbl(level)));
ASSERT_TRUE(src_asm.CheckValues(src_c));
ASM_REGISTER_STATE_CHECK(mb_post_proc_down_(
src_asm.TopLeftPixel(), src_asm.stride(), rows_, cols_, q2mbl(level)));
ASSERT_TRUE(src_asm.CheckValues(src_c_));
}
}
TEST_P(VpxMbPostProcDownTest, DISABLED_Speed) {
ASSERT_TRUE(src_c_.Init());
src_c_.SetPadding(10);
SetRows(src_c_.TopLeftPixel(), rows_, cols_, src_c_.stride());
RunNTimes(100000);
PrintMedian("16x16");
}
INSTANTIATE_TEST_CASE_P(
C, VpxPostProcDownAndAcrossMbRowTest,
::testing::Values(vpx_post_proc_down_and_across_mb_row_c));
@ -481,4 +557,16 @@ INSTANTIATE_TEST_CASE_P(MSA, VpxMbPostProcDownTest,
::testing::Values(vpx_mbpost_proc_down_msa));
#endif // HAVE_MSA
#if HAVE_VSX
INSTANTIATE_TEST_CASE_P(
VSX, VpxPostProcDownAndAcrossMbRowTest,
::testing::Values(vpx_post_proc_down_and_across_mb_row_vsx));
INSTANTIATE_TEST_CASE_P(VSX, VpxMbPostProcAcrossIpTest,
::testing::Values(vpx_mbpost_proc_across_ip_vsx));
INSTANTIATE_TEST_CASE_P(VSX, VpxMbPostProcDownTest,
::testing::Values(vpx_mbpost_proc_down_vsx));
#endif // HAVE_VSX
} // namespace

View File

@ -10,30 +10,34 @@
#include <stdlib.h>
#include <string.h>
#include <tuple>
#include "third_party/googletest/src/include/gtest/gtest.h"
#include "./vp8_rtcd.h"
#include "./vpx_config.h"
#include "test/acm_random.h"
#include "test/bench.h"
#include "test/clear_system_state.h"
#include "test/register_state_check.h"
#include "test/util.h"
#include "vpx/vpx_integer.h"
#include "vpx_mem/vpx_mem.h"
#include "vpx_ports/msvc.h"
namespace {
using libvpx_test::ACMRandom;
using std::tr1::make_tuple;
using std::make_tuple;
typedef void (*PredictFunc)(uint8_t *src_ptr, int src_pixels_per_line,
int xoffset, int yoffset, uint8_t *dst_ptr,
int dst_pitch);
typedef std::tr1::tuple<int, int, PredictFunc> PredictParam;
typedef std::tuple<int, int, PredictFunc> PredictParam;
class PredictTestBase : public ::testing::TestWithParam<PredictParam> {
class PredictTestBase : public AbstractBench,
public ::testing::TestWithParam<PredictParam> {
public:
PredictTestBase()
: width_(GET_PARAM(0)), height_(GET_PARAM(1)), predict_(GET_PARAM(2)),
@ -204,7 +208,20 @@ class PredictTestBase : public ::testing::TestWithParam<PredictParam> {
}
}
}
};
void Run() {
for (int xoffset = 0; xoffset < 8; ++xoffset) {
for (int yoffset = 0; yoffset < 8; ++yoffset) {
if (xoffset == 0 && yoffset == 0) {
continue;
}
predict_(&src_[kSrcStride * 2 + 2], kSrcStride, xoffset, yoffset, dst_,
dst_stride_);
}
}
}
}; // namespace
class SixtapPredictTest : public PredictTestBase {};
@ -341,6 +358,14 @@ TEST_P(BilinearPredictTest, TestWithRandomData) {
TEST_P(BilinearPredictTest, TestWithUnalignedDst) {
TestWithUnalignedDst(vp8_bilinear_predict16x16_c);
}
TEST_P(BilinearPredictTest, DISABLED_Speed) {
const int kCountSpeedTestBlock = 5000000 / (width_ * height_);
RunNTimes(kCountSpeedTestBlock);
char title[16];
snprintf(title, sizeof(title), "%dx%d", width_, height_);
PrintMedian(title);
}
INSTANTIATE_TEST_CASE_P(
C, BilinearPredictTest,
@ -356,17 +381,13 @@ INSTANTIATE_TEST_CASE_P(
make_tuple(8, 4, &vp8_bilinear_predict8x4_neon),
make_tuple(4, 4, &vp8_bilinear_predict4x4_neon)));
#endif
#if HAVE_MMX
INSTANTIATE_TEST_CASE_P(
MMX, BilinearPredictTest,
::testing::Values(make_tuple(8, 4, &vp8_bilinear_predict8x4_mmx),
make_tuple(4, 4, &vp8_bilinear_predict4x4_mmx)));
#endif
#if HAVE_SSE2
INSTANTIATE_TEST_CASE_P(
SSE2, BilinearPredictTest,
::testing::Values(make_tuple(16, 16, &vp8_bilinear_predict16x16_sse2),
make_tuple(8, 8, &vp8_bilinear_predict8x8_sse2)));
make_tuple(8, 8, &vp8_bilinear_predict8x8_sse2),
make_tuple(8, 4, &vp8_bilinear_predict8x4_sse2),
make_tuple(4, 4, &vp8_bilinear_predict4x4_sse2)));
#endif
#if HAVE_SSSE3
INSTANTIATE_TEST_CASE_P(

View File

@ -9,12 +9,14 @@
*/
#include <string.h>
#include <tuple>
#include "third_party/googletest/src/include/gtest/gtest.h"
#include "./vpx_config.h"
#include "./vp8_rtcd.h"
#include "./vpx_config.h"
#include "test/acm_random.h"
#include "test/bench.h"
#include "test/clear_system_state.h"
#include "test/register_state_check.h"
#include "test/util.h"
@ -33,10 +35,10 @@ const int kNumBlockEntries = 16;
typedef void (*VP8Quantize)(BLOCK *b, BLOCKD *d);
typedef std::tr1::tuple<VP8Quantize, VP8Quantize> VP8QuantizeParam;
typedef std::tuple<VP8Quantize, VP8Quantize> VP8QuantizeParam;
using libvpx_test::ACMRandom;
using std::tr1::make_tuple;
using std::make_tuple;
// Create and populate a VP8_COMP instance which has a complete set of
// quantization inputs as well as a second MACROBLOCKD for output.
@ -116,7 +118,8 @@ class QuantizeTestBase {
};
class QuantizeTest : public QuantizeTestBase,
public ::testing::TestWithParam<VP8QuantizeParam> {
public ::testing::TestWithParam<VP8QuantizeParam>,
public AbstractBench {
protected:
virtual void SetUp() {
SetupCompressor();
@ -124,6 +127,10 @@ class QuantizeTest : public QuantizeTestBase,
c_quant_ = GET_PARAM(1);
}
virtual void Run() {
asm_quant_(&vp8_comp_->mb.block[0], &macroblockd_dst_->block[0]);
}
void RunComparison() {
for (int i = 0; i < kNumBlocks; ++i) {
ASM_REGISTER_STATE_CHECK(
@ -166,6 +173,13 @@ TEST_P(QuantizeTest, TestMultipleQ) {
}
}
TEST_P(QuantizeTest, DISABLED_Speed) {
FillCoeffRandom();
RunNTimes(10000000);
PrintMedian("vp8 quantize");
}
#if HAVE_SSE2
INSTANTIATE_TEST_CASE_P(
SSE2, QuantizeTest,

View File

@ -8,8 +8,8 @@
* be found in the AUTHORS file in the root of the source tree.
*/
#ifndef TEST_REGISTER_STATE_CHECK_H_
#define TEST_REGISTER_STATE_CHECK_H_
#ifndef VPX_TEST_REGISTER_STATE_CHECK_H_
#define VPX_TEST_REGISTER_STATE_CHECK_H_
#include "third_party/googletest/src/include/gtest/gtest.h"
#include "./vpx_config.h"
@ -28,7 +28,7 @@
// See platform implementations of RegisterStateCheckXXX for details.
//
#if defined(_WIN64)
#if defined(_WIN64) && ARCH_X86_64
#undef NOMINMAX
#define NOMINMAX
@ -138,7 +138,7 @@ class RegisterStateCheck {};
} // namespace libvpx_test
#endif // _WIN64
#endif // _WIN64 && ARCH_X86_64
#if ARCH_X86 || ARCH_X86_64
#if defined(__GNUC__)
@ -184,4 +184,4 @@ class RegisterStateCheckMMX {
#define API_REGISTER_STATE_CHECK ASM_REGISTER_STATE_CHECK
#endif
#endif // TEST_REGISTER_STATE_CHECK_H_
#endif // VPX_TEST_REGISTER_STATE_CHECK_H_

View File

@ -277,12 +277,29 @@ class ResizeTest
SetMode(GET_PARAM(1));
}
virtual void FramePktHook(const vpx_codec_cx_pkt_t *pkt) {
ASSERT_NE(static_cast<int>(pkt->data.frame.width[0]), 0);
ASSERT_NE(static_cast<int>(pkt->data.frame.height[0]), 0);
encode_frame_width_.push_back(pkt->data.frame.width[0]);
encode_frame_height_.push_back(pkt->data.frame.height[0]);
}
unsigned int GetFrameWidth(size_t idx) const {
return encode_frame_width_[idx];
}
unsigned int GetFrameHeight(size_t idx) const {
return encode_frame_height_[idx];
}
virtual void DecompressedFrameHook(const vpx_image_t &img,
vpx_codec_pts_t pts) {
frame_info_list_.push_back(FrameInfo(pts, img.d_w, img.d_h));
}
std::vector<FrameInfo> frame_info_list_;
std::vector<unsigned int> encode_frame_width_;
std::vector<unsigned int> encode_frame_height_;
};
TEST_P(ResizeTest, TestExternalResizeWorks) {
@ -296,6 +313,9 @@ TEST_P(ResizeTest, TestExternalResizeWorks) {
const unsigned int frame = static_cast<unsigned>(info->pts);
unsigned int expected_w;
unsigned int expected_h;
const size_t idx = info - frame_info_list_.begin();
ASSERT_EQ(info->w, GetFrameWidth(idx));
ASSERT_EQ(info->h, GetFrameHeight(idx));
ScaleForFrameNumber(frame, kInitialWidth, kInitialHeight, &expected_w,
&expected_h, 0);
EXPECT_EQ(expected_w, info->w)
@ -464,8 +484,23 @@ class ResizeRealtimeTest
++mismatch_nframes_;
}
virtual void FramePktHook(const vpx_codec_cx_pkt_t *pkt) {
ASSERT_NE(static_cast<int>(pkt->data.frame.width[0]), 0);
ASSERT_NE(static_cast<int>(pkt->data.frame.height[0]), 0);
encode_frame_width_.push_back(pkt->data.frame.width[0]);
encode_frame_height_.push_back(pkt->data.frame.height[0]);
}
unsigned int GetMismatchFrames() { return mismatch_nframes_; }
unsigned int GetFrameWidth(size_t idx) const {
return encode_frame_width_[idx];
}
unsigned int GetFrameHeight(size_t idx) const {
return encode_frame_height_[idx];
}
void DefaultConfig() {
cfg_.rc_buf_initial_sz = 500;
cfg_.rc_buf_optimal_sz = 600;
@ -493,6 +528,8 @@ class ResizeRealtimeTest
bool change_bitrate_;
double mismatch_psnr_;
int mismatch_nframes_;
std::vector<unsigned int> encode_frame_width_;
std::vector<unsigned int> encode_frame_height_;
};
TEST_P(ResizeRealtimeTest, TestExternalResizeWorks) {
@ -582,6 +619,9 @@ TEST_P(ResizeRealtimeTest, TestInternalResizeDownUpChangeBitRate) {
int resize_count = 0;
for (std::vector<FrameInfo>::const_iterator info = frame_info_list_.begin();
info != frame_info_list_.end(); ++info) {
const size_t idx = info - frame_info_list_.begin();
ASSERT_EQ(info->w, GetFrameWidth(idx));
ASSERT_EQ(info->h, GetFrameHeight(idx));
if (info->w != last_w || info->h != last_h) {
resize_count++;
if (resize_count == 1) {

View File

@ -10,19 +10,21 @@
#include <string.h>
#include <limits.h>
#include <stdio.h>
#include "third_party/googletest/src/include/gtest/gtest.h"
#include "./vpx_config.h"
#include "./vpx_dsp_rtcd.h"
#include "test/acm_random.h"
#include "test/bench.h"
#include "test/clear_system_state.h"
#include "test/register_state_check.h"
#include "test/util.h"
#include "vpx/vpx_codec.h"
#include "vpx_mem/vpx_mem.h"
#include "vpx_ports/mem.h"
#include "vpx_ports/msvc.h"
#include "vpx_ports/vpx_timer.h"
template <typename Function>
struct TestParams {
@ -84,7 +86,7 @@ class SADTestBase : public ::testing::TestWithParam<ParamType> {
#endif // CONFIG_VP9_HIGHBITDEPTH
}
mask_ = (1 << bit_depth_) - 1;
source_stride_ = (params_.width + 31) & ~31;
source_stride_ = (params_.width + 63) & ~63;
reference_stride_ = params_.width * 2;
rnd_.Reset(ACMRandom::DeterministicSeed());
}
@ -108,7 +110,7 @@ class SADTestBase : public ::testing::TestWithParam<ParamType> {
protected:
// Handle blocks up to 4 blocks 64x64 with stride up to 128
static const int kDataAlignment = 16;
static const int kDataAlignment = 32;
static const int kDataBlockSize = 64 * 128;
static const int kDataBufferSize = 4 * kDataBlockSize;
@ -264,7 +266,7 @@ class SADx4Test : public SADTestBase<SadMxNx4Param> {
}
};
class SADTest : public SADTestBase<SadMxNParam> {
class SADTest : public AbstractBench, public SADTestBase<SadMxNParam> {
public:
SADTest() : SADTestBase(GetParam()) {}
@ -284,6 +286,11 @@ class SADTest : public SADTestBase<SadMxNParam> {
ASSERT_EQ(reference_sad, exp_sad);
}
void Run() {
params_.func(source_data_, source_stride_, reference_data_,
reference_stride_);
}
};
class SADavgTest : public SADTestBase<SadMxNAvgParam> {
@ -350,6 +357,17 @@ TEST_P(SADTest, ShortSrc) {
source_stride_ = tmp_stride;
}
TEST_P(SADTest, DISABLED_Speed) {
const int kCountSpeedTestBlock = 50000000 / (params_.width * params_.height);
FillRandom(source_data_, source_stride_);
RunNTimes(kCountSpeedTestBlock);
char title[16];
snprintf(title, sizeof(title), "%dx%d", params_.width, params_.height);
PrintMedian(title);
}
TEST_P(SADavgTest, MaxRef) {
FillConstant(source_data_, source_stride_, 0);
FillConstant(reference_data_, reference_stride_, mask_);
@ -463,6 +481,38 @@ TEST_P(SADx4Test, SrcAlignedByWidth) {
source_data_ = tmp_source_data;
}
TEST_P(SADx4Test, DISABLED_Speed) {
int tmp_stride = reference_stride_;
reference_stride_ -= 1;
FillRandom(source_data_, source_stride_);
FillRandom(GetReference(0), reference_stride_);
FillRandom(GetReference(1), reference_stride_);
FillRandom(GetReference(2), reference_stride_);
FillRandom(GetReference(3), reference_stride_);
const int kCountSpeedTestBlock = 500000000 / (params_.width * params_.height);
uint32_t reference_sad[4], exp_sad[4];
vpx_usec_timer timer;
memset(reference_sad, 0, sizeof(reference_sad));
SADs(exp_sad);
vpx_usec_timer_start(&timer);
for (int i = 0; i < kCountSpeedTestBlock; ++i) {
for (int block = 0; block < 4; ++block) {
reference_sad[block] = ReferenceSAD(block);
}
}
vpx_usec_timer_mark(&timer);
for (int block = 0; block < 4; ++block) {
EXPECT_EQ(reference_sad[block], exp_sad[block]) << "block " << block;
}
const int elapsed_time =
static_cast<int>(vpx_usec_timer_elapsed(&timer) / 1000);
printf("sad%dx%dx4 (%2dbit) time: %5d ms\n", params_.width, params_.height,
bit_depth_, elapsed_time);
reference_stride_ = tmp_stride;
}
//------------------------------------------------------------------------------
// C functions
const SadMxNParam c_tests[] = {
@ -971,6 +1021,9 @@ const SadMxNParam vsx_tests[] = {
SadMxNParam(16, 32, &vpx_sad16x32_vsx),
SadMxNParam(16, 16, &vpx_sad16x16_vsx),
SadMxNParam(16, 8, &vpx_sad16x8_vsx),
SadMxNParam(8, 16, &vpx_sad8x16_vsx),
SadMxNParam(8, 8, &vpx_sad8x8_vsx),
SadMxNParam(8, 4, &vpx_sad8x4_vsx),
};
INSTANTIATE_TEST_CASE_P(VSX, SADTest, ::testing::ValuesIn(vsx_tests));

View File

@ -30,7 +30,7 @@ SHA1_FILE="$(dirname $0)/test-data.sha1"
# Download a file from the url and check its sha1sum.
download_and_check_file() {
# Get the file from the file path.
local readonly root="${1#${LIBVPX_TEST_DATA_PATH}/}"
local root="${1#${LIBVPX_TEST_DATA_PATH}/}"
# Download the file using curl. Trap to insure non partial file.
(trap "rm -f $1" INT TERM \
@ -72,13 +72,13 @@ stress_verify_environment() {
# This function runs tests on libvpx that run multiple encodes and decodes
# in parallel in hopes of catching synchronization and/or threading issues.
stress() {
local readonly decoder="$(vpx_tool_path vpxdec)"
local readonly encoder="$(vpx_tool_path vpxenc)"
local readonly codec="$1"
local readonly webm="$2"
local readonly decode_count="$3"
local readonly threads="$4"
local readonly enc_args="$5"
local decoder="$(vpx_tool_path vpxdec)"
local encoder="$(vpx_tool_path vpxenc)"
local codec="$1"
local webm="$2"
local decode_count="$3"
local threads="$4"
local enc_args="$5"
local pids=""
local rt_max_jobs=${STRESS_RT_MAX_JOBS:-5}
local onepass_max_jobs=${STRESS_ONEPASS_MAX_JOBS:-5}
@ -144,6 +144,19 @@ vp8_stress_test() {
fi
}
vp8_stress_test_token_parititions() {
local vp8_max_jobs=${STRESS_VP8_DECODE_MAX_JOBS:-40}
if [ "$(vp8_decode_available)" = "yes" -a \
"$(vp8_encode_available)" = "yes" ]; then
for threads in 2 4 8; do
for token_partitions in 1 2 3; do
stress vp8 "${VP8}" "${vp8_max_jobs}" ${threads} \
"--token-parts=$token_partitions"
done
done
fi
}
vp9_stress() {
local vp9_max_jobs=${STRESS_VP9_DECODE_MAX_JOBS:-25}
@ -154,16 +167,17 @@ vp9_stress() {
}
vp9_stress_test() {
for threads in 4 8 100; do
for threads in 4 8 64; do
vp9_stress "$threads" "--row-mt=0"
done
}
vp9_stress_test_row_mt() {
for threads in 4 8 100; do
for threads in 4 8 64; do
vp9_stress "$threads" "--row-mt=1"
done
}
run_tests stress_verify_environment \
"vp8_stress_test vp9_stress_test vp9_stress_test_row_mt"
"vp8_stress_test vp8_stress_test_token_parititions
vp9_stress_test vp9_stress_test_row_mt"

View File

@ -11,6 +11,7 @@
#include <cmath>
#include <cstdlib>
#include <string>
#include <tuple>
#include "third_party/googletest/src/include/gtest/gtest.h"
@ -28,7 +29,7 @@ namespace {
const int kNumIterations = 10000;
typedef uint64_t (*SSI16Func)(const int16_t *src, int stride, int size);
typedef std::tr1::tuple<SSI16Func, SSI16Func> SumSquaresParam;
typedef std::tuple<SSI16Func, SSI16Func> SumSquaresParam;
class SumSquaresTest : public ::testing::TestWithParam<SumSquaresParam> {
public:
@ -102,7 +103,14 @@ TEST_P(SumSquaresTest, ExtremeValues) {
}
}
using std::tr1::make_tuple;
using std::make_tuple;
#if HAVE_NEON
INSTANTIATE_TEST_CASE_P(
NEON, SumSquaresTest,
::testing::Values(make_tuple(&vpx_sum_squares_2d_i16_c,
&vpx_sum_squares_2d_i16_neon)));
#endif // HAVE_NEON
#if HAVE_SSE2
INSTANTIATE_TEST_CASE_P(
@ -112,8 +120,9 @@ INSTANTIATE_TEST_CASE_P(
#endif // HAVE_SSE2
#if HAVE_MSA
INSTANTIATE_TEST_CASE_P(MSA, SumSquaresTest, ::testing::Values(make_tuple(
&vpx_sum_squares_2d_i16_c,
&vpx_sum_squares_2d_i16_msa)));
INSTANTIATE_TEST_CASE_P(
MSA, SumSquaresTest,
::testing::Values(make_tuple(&vpx_sum_squares_2d_i16_c,
&vpx_sum_squares_2d_i16_msa)));
#endif // HAVE_MSA
} // namespace

View File

@ -8,6 +8,8 @@
* be found in the AUTHORS file in the root of the source tree.
*/
#include <climits>
#include <tuple>
#include "third_party/googletest/src/include/gtest/gtest.h"
#include "test/codec_factory.h"
#include "test/encode_test_driver.h"
@ -18,7 +20,7 @@ namespace {
const int kTestMode = 0;
typedef std::tr1::tuple<libvpx_test::TestMode, int> SuperframeTestParam;
typedef std::tuple<libvpx_test::TestMode, int> SuperframeTestParam;
class SuperframeTest
: public ::libvpx_test::EncoderTest,
@ -31,7 +33,7 @@ class SuperframeTest
virtual void SetUp() {
InitializeConfig();
const SuperframeTestParam input = GET_PARAM(1);
const libvpx_test::TestMode mode = std::tr1::get<kTestMode>(input);
const libvpx_test::TestMode mode = std::get<kTestMode>(input);
SetMode(mode);
sf_count_ = 0;
sf_count_max_ = INT_MAX;
@ -41,7 +43,7 @@ class SuperframeTest
virtual void PreEncodeFrameHook(libvpx_test::VideoSource *video,
libvpx_test::Encoder *encoder) {
if (video->frame() == 1) {
if (video->frame() == 0) {
encoder->Control(VP8E_SET_ENABLEAUTOALTREF, 1);
}
}

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,481 @@
/*
* Copyright (c) 2018 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_config.h"
#include "third_party/googletest/src/include/gtest/gtest.h"
#include "test/codec_factory.h"
#include "test/encode_test_driver.h"
#include "test/i420_video_source.h"
#include "test/svc_test.h"
#include "test/util.h"
#include "test/y4m_video_source.h"
#include "vpx/vpx_codec.h"
#include "vpx_ports/bitops.h"
namespace svc_test {
namespace {
typedef enum {
// Inter-layer prediction is on on all frames.
INTER_LAYER_PRED_ON,
// Inter-layer prediction is off on all frames.
INTER_LAYER_PRED_OFF,
// Inter-layer prediction is off on non-key frames and non-sync frames.
INTER_LAYER_PRED_OFF_NONKEY,
// Inter-layer prediction is on on all frames, but constrained such
// that any layer S (> 0) can only predict from previous spatial
// layer S-1, from the same superframe.
INTER_LAYER_PRED_ON_CONSTRAINED
} INTER_LAYER_PRED;
class ScalePartitionOnePassCbrSvc
: public OnePassCbrSvc,
public ::testing::TestWithParam<const ::libvpx_test::CodecFactory *> {
public:
ScalePartitionOnePassCbrSvc()
: OnePassCbrSvc(GetParam()), mismatch_nframes_(0), num_nonref_frames_(0) {
SetMode(::libvpx_test::kRealTime);
}
protected:
virtual ~ScalePartitionOnePassCbrSvc() {}
virtual void SetUp() {
InitializeConfig();
speed_setting_ = 7;
}
virtual void PreEncodeFrameHook(::libvpx_test::VideoSource *video,
::libvpx_test::Encoder *encoder) {
PreEncodeFrameHookSetup(video, encoder);
}
virtual void FramePktHook(const vpx_codec_cx_pkt_t *pkt) {
// Keep track of number of non-reference frames, needed for mismatch check.
// Non-reference frames are top spatial and temporal layer frames,
// for TL > 0.
if (temporal_layer_id_ == number_temporal_layers_ - 1 &&
temporal_layer_id_ > 0 &&
pkt->data.frame.spatial_layer_encoded[number_spatial_layers_ - 1])
num_nonref_frames_++;
}
virtual void MismatchHook(const vpx_image_t * /*img1*/,
const vpx_image_t * /*img2*/) {
++mismatch_nframes_;
}
virtual void SetConfig(const int /*num_temporal_layer*/) {}
unsigned int GetMismatchFrames() const { return mismatch_nframes_; }
unsigned int GetNonRefFrames() const { return num_nonref_frames_; }
private:
unsigned int mismatch_nframes_;
unsigned int num_nonref_frames_;
};
TEST_P(ScalePartitionOnePassCbrSvc, OnePassCbrSvc3SL3TL1080P) {
SetSvcConfig(3, 3);
cfg_.rc_buf_initial_sz = 500;
cfg_.rc_buf_optimal_sz = 500;
cfg_.rc_buf_sz = 1000;
cfg_.rc_min_quantizer = 0;
cfg_.rc_max_quantizer = 63;
cfg_.g_threads = 1;
cfg_.rc_dropframe_thresh = 10;
cfg_.rc_target_bitrate = 800;
cfg_.kf_max_dist = 9999;
cfg_.rc_end_usage = VPX_CBR;
cfg_.g_lag_in_frames = 0;
cfg_.g_error_resilient = 1;
cfg_.ts_rate_decimator[0] = 4;
cfg_.ts_rate_decimator[1] = 2;
cfg_.ts_rate_decimator[2] = 1;
cfg_.temporal_layering_mode = 3;
::libvpx_test::I420VideoSource video(
"slides_code_term_web_plot.1920_1080.yuv", 1920, 1080, 30, 1, 0, 100);
// For this 3 temporal layer case, pattern repeats every 4 frames, so choose
// 4 key neighboring key frame periods (so key frame will land on 0-2-1-2).
AssignLayerBitrates();
ASSERT_NO_FATAL_FAILURE(RunLoop(&video));
#if CONFIG_VP9_DECODER
// The non-reference frames are expected to be mismatched frames as the
// encoder will avoid loopfilter on these frames.
EXPECT_EQ(GetNonRefFrames(), GetMismatchFrames());
#endif
}
// Params: Inter layer prediction modes.
class SyncFrameOnePassCbrSvc : public OnePassCbrSvc,
public ::libvpx_test::CodecTestWithParam<int> {
public:
SyncFrameOnePassCbrSvc()
: OnePassCbrSvc(GET_PARAM(0)), current_video_frame_(0),
frame_to_start_decode_(0), frame_to_sync_(0),
inter_layer_pred_mode_(GET_PARAM(1)), decode_to_layer_before_sync_(-1),
decode_to_layer_after_sync_(-1), denoiser_on_(0),
intra_only_test_(false), mismatch_nframes_(0), num_nonref_frames_(0) {
SetMode(::libvpx_test::kRealTime);
memset(&svc_layer_sync_, 0, sizeof(svc_layer_sync_));
}
protected:
virtual ~SyncFrameOnePassCbrSvc() {}
virtual void SetUp() {
InitializeConfig();
speed_setting_ = 7;
}
virtual bool DoDecode() const {
return current_video_frame_ >= frame_to_start_decode_;
}
virtual void PreEncodeFrameHook(::libvpx_test::VideoSource *video,
::libvpx_test::Encoder *encoder) {
current_video_frame_ = video->frame();
PreEncodeFrameHookSetup(video, encoder);
if (video->frame() == 0) {
// Do not turn off inter-layer pred completely because simulcast mode
// fails.
if (inter_layer_pred_mode_ != INTER_LAYER_PRED_OFF)
encoder->Control(VP9E_SET_SVC_INTER_LAYER_PRED, inter_layer_pred_mode_);
encoder->Control(VP9E_SET_NOISE_SENSITIVITY, denoiser_on_);
if (intra_only_test_)
// Decoder sets the color_space for Intra-only frames
// to BT_601 (see line 1810 in vp9_decodeframe.c).
// So set it here in these tess to avoid encoder-decoder
// mismatch check on color space setting.
encoder->Control(VP9E_SET_COLOR_SPACE, VPX_CS_BT_601);
}
if (video->frame() == frame_to_sync_) {
encoder->Control(VP9E_SET_SVC_SPATIAL_LAYER_SYNC, &svc_layer_sync_);
}
}
#if CONFIG_VP9_DECODER
virtual void PreDecodeFrameHook(::libvpx_test::VideoSource *video,
::libvpx_test::Decoder *decoder) {
if (video->frame() < frame_to_sync_) {
if (decode_to_layer_before_sync_ >= 0)
decoder->Control(VP9_DECODE_SVC_SPATIAL_LAYER,
decode_to_layer_before_sync_);
} else {
if (decode_to_layer_after_sync_ >= 0)
decoder->Control(VP9_DECODE_SVC_SPATIAL_LAYER,
decode_to_layer_after_sync_);
}
}
#endif
virtual void FramePktHook(const vpx_codec_cx_pkt_t *pkt) {
// Keep track of number of non-reference frames, needed for mismatch check.
// Non-reference frames are top spatial and temporal layer frames,
// for TL > 0.
if (temporal_layer_id_ == number_temporal_layers_ - 1 &&
temporal_layer_id_ > 0 &&
pkt->data.frame.spatial_layer_encoded[number_spatial_layers_ - 1] &&
current_video_frame_ >= frame_to_sync_)
num_nonref_frames_++;
if (intra_only_test_ && current_video_frame_ == frame_to_sync_) {
// Intra-only frame is only generated for spatial layers > 1 and <= 3,
// among other conditions (see constraint in set_intra_only_frame(). If
// intra-only is no allowed then encoder will insert key frame instead.
const bool key_frame =
(pkt->data.frame.flags & VPX_FRAME_IS_KEY) ? true : false;
if (number_spatial_layers_ == 1 || number_spatial_layers_ > 3)
ASSERT_TRUE(key_frame);
else
ASSERT_FALSE(key_frame);
}
}
virtual void MismatchHook(const vpx_image_t * /*img1*/,
const vpx_image_t * /*img2*/) {
if (current_video_frame_ >= frame_to_sync_) ++mismatch_nframes_;
}
unsigned int GetMismatchFrames() const { return mismatch_nframes_; }
unsigned int GetNonRefFrames() const { return num_nonref_frames_; }
unsigned int current_video_frame_;
unsigned int frame_to_start_decode_;
unsigned int frame_to_sync_;
int inter_layer_pred_mode_;
int decode_to_layer_before_sync_;
int decode_to_layer_after_sync_;
int denoiser_on_;
bool intra_only_test_;
vpx_svc_spatial_layer_sync_t svc_layer_sync_;
private:
virtual void SetConfig(const int num_temporal_layer) {
cfg_.rc_buf_initial_sz = 500;
cfg_.rc_buf_optimal_sz = 500;
cfg_.rc_buf_sz = 1000;
cfg_.rc_min_quantizer = 0;
cfg_.rc_max_quantizer = 63;
cfg_.rc_end_usage = VPX_CBR;
cfg_.g_lag_in_frames = 0;
cfg_.g_error_resilient = 1;
cfg_.g_threads = 1;
cfg_.rc_dropframe_thresh = 30;
cfg_.kf_max_dist = 9999;
if (num_temporal_layer == 3) {
cfg_.ts_rate_decimator[0] = 4;
cfg_.ts_rate_decimator[1] = 2;
cfg_.ts_rate_decimator[2] = 1;
cfg_.temporal_layering_mode = 3;
} else if (num_temporal_layer == 2) {
cfg_.ts_rate_decimator[0] = 2;
cfg_.ts_rate_decimator[1] = 1;
cfg_.temporal_layering_mode = 2;
} else if (num_temporal_layer == 1) {
cfg_.ts_rate_decimator[0] = 1;
cfg_.temporal_layering_mode = 1;
}
}
unsigned int mismatch_nframes_;
unsigned int num_nonref_frames_;
};
// Test for sync layer for 1 pass CBR SVC: 3 spatial layers and
// 3 temporal layers. Only start decoding on the sync layer.
// Full sync: insert key frame on base layer.
TEST_P(SyncFrameOnePassCbrSvc, OnePassCbrSvc3SL3TLFullSync) {
SetSvcConfig(3, 3);
// Sync is on base layer so the frame to sync and the frame to start decoding
// is the same.
frame_to_start_decode_ = 20;
frame_to_sync_ = 20;
decode_to_layer_before_sync_ = -1;
decode_to_layer_after_sync_ = 2;
// Set up svc layer sync structure.
svc_layer_sync_.base_layer_intra_only = 0;
svc_layer_sync_.spatial_layer_sync[0] = 1;
::libvpx_test::Y4mVideoSource video("niklas_1280_720_30.y4m", 0, 60);
cfg_.rc_target_bitrate = 600;
AssignLayerBitrates();
ASSERT_NO_FATAL_FAILURE(RunLoop(&video));
#if CONFIG_VP9_DECODER
// The non-reference frames are expected to be mismatched frames as the
// encoder will avoid loopfilter on these frames.
EXPECT_EQ(GetNonRefFrames(), GetMismatchFrames());
#endif
}
// Test for sync layer for 1 pass CBR SVC: 2 spatial layers and
// 3 temporal layers. Decoding QVGA before sync frame and decode up to
// VGA on and after sync.
TEST_P(SyncFrameOnePassCbrSvc, OnePassCbrSvc2SL3TLSyncToVGA) {
SetSvcConfig(2, 3);
frame_to_start_decode_ = 0;
frame_to_sync_ = 100;
decode_to_layer_before_sync_ = 0;
decode_to_layer_after_sync_ = 1;
// Set up svc layer sync structure.
svc_layer_sync_.base_layer_intra_only = 0;
svc_layer_sync_.spatial_layer_sync[0] = 0;
svc_layer_sync_.spatial_layer_sync[1] = 1;
::libvpx_test::I420VideoSource video("niklas_640_480_30.yuv", 640, 480, 30, 1,
0, 400);
cfg_.rc_target_bitrate = 400;
AssignLayerBitrates();
ASSERT_NO_FATAL_FAILURE(RunLoop(&video));
#if CONFIG_VP9_DECODER
// The non-reference frames are expected to be mismatched frames as the
// encoder will avoid loopfilter on these frames.
EXPECT_EQ(GetNonRefFrames(), GetMismatchFrames());
#endif
}
// Test for sync layer for 1 pass CBR SVC: 3 spatial layers and
// 3 temporal layers. Decoding QVGA and VGA before sync frame and decode up to
// HD on and after sync.
TEST_P(SyncFrameOnePassCbrSvc, OnePassCbrSvc3SL3TLSyncToHD) {
SetSvcConfig(3, 3);
frame_to_start_decode_ = 0;
frame_to_sync_ = 20;
decode_to_layer_before_sync_ = 1;
decode_to_layer_after_sync_ = 2;
// Set up svc layer sync structure.
svc_layer_sync_.base_layer_intra_only = 0;
svc_layer_sync_.spatial_layer_sync[0] = 0;
svc_layer_sync_.spatial_layer_sync[1] = 0;
svc_layer_sync_.spatial_layer_sync[2] = 1;
::libvpx_test::Y4mVideoSource video("niklas_1280_720_30.y4m", 0, 60);
cfg_.rc_target_bitrate = 600;
AssignLayerBitrates();
ASSERT_NO_FATAL_FAILURE(RunLoop(&video));
#if CONFIG_VP9_DECODER
// The non-reference frames are expected to be mismatched frames as the
// encoder will avoid loopfilter on these frames.
EXPECT_EQ(GetNonRefFrames(), GetMismatchFrames());
#endif
}
// Test for sync layer for 1 pass CBR SVC: 3 spatial layers and
// 3 temporal layers. Decoding QVGA before sync frame and decode up to
// HD on and after sync.
TEST_P(SyncFrameOnePassCbrSvc, OnePassCbrSvc3SL3TLSyncToVGAHD) {
SetSvcConfig(3, 3);
frame_to_start_decode_ = 0;
frame_to_sync_ = 20;
decode_to_layer_before_sync_ = 0;
decode_to_layer_after_sync_ = 2;
// Set up svc layer sync structure.
svc_layer_sync_.base_layer_intra_only = 0;
svc_layer_sync_.spatial_layer_sync[0] = 0;
svc_layer_sync_.spatial_layer_sync[1] = 1;
svc_layer_sync_.spatial_layer_sync[2] = 1;
::libvpx_test::Y4mVideoSource video("niklas_1280_720_30.y4m", 0, 60);
cfg_.rc_target_bitrate = 600;
AssignLayerBitrates();
ASSERT_NO_FATAL_FAILURE(RunLoop(&video));
#if CONFIG_VP9_DECODER
// The non-reference frames are expected to be mismatched frames as the
// encoder will avoid loopfilter on these frames.
EXPECT_EQ(GetNonRefFrames(), GetMismatchFrames());
#endif
}
#if CONFIG_VP9_TEMPORAL_DENOISING
// Test for sync layer for 1 pass CBR SVC: 2 spatial layers and
// 3 temporal layers. Decoding QVGA before sync frame and decode up to
// VGA on and after sync.
TEST_P(SyncFrameOnePassCbrSvc, OnePassCbrSvc2SL3TLSyncFrameVGADenoise) {
SetSvcConfig(2, 3);
frame_to_start_decode_ = 0;
frame_to_sync_ = 100;
decode_to_layer_before_sync_ = 0;
decode_to_layer_after_sync_ = 1;
denoiser_on_ = 1;
// Set up svc layer sync structure.
svc_layer_sync_.base_layer_intra_only = 0;
svc_layer_sync_.spatial_layer_sync[0] = 0;
svc_layer_sync_.spatial_layer_sync[1] = 1;
::libvpx_test::I420VideoSource video("niklas_640_480_30.yuv", 640, 480, 30, 1,
0, 400);
cfg_.rc_target_bitrate = 400;
AssignLayerBitrates();
ASSERT_NO_FATAL_FAILURE(RunLoop(&video));
#if CONFIG_VP9_DECODER
// The non-reference frames are expected to be mismatched frames as the
// encoder will avoid loopfilter on these frames.
EXPECT_EQ(GetNonRefFrames(), GetMismatchFrames());
#endif
}
#endif
// Start decoding from beginning of sequence, during sequence insert intra-only
// on base/qvga layer. Decode all layers.
TEST_P(SyncFrameOnePassCbrSvc, OnePassCbrSvc3SL3TLSyncFrameIntraOnlyQVGA) {
SetSvcConfig(3, 3);
frame_to_start_decode_ = 0;
frame_to_sync_ = 20;
decode_to_layer_before_sync_ = 2;
// The superframe containing intra-only layer will have 4 frames. Thus set the
// layer to decode after sync frame to 3.
decode_to_layer_after_sync_ = 3;
intra_only_test_ = true;
// Set up svc layer sync structure.
svc_layer_sync_.base_layer_intra_only = 1;
svc_layer_sync_.spatial_layer_sync[0] = 1;
svc_layer_sync_.spatial_layer_sync[1] = 0;
svc_layer_sync_.spatial_layer_sync[2] = 0;
::libvpx_test::Y4mVideoSource video("niklas_1280_720_30.y4m", 0, 60);
cfg_.rc_target_bitrate = 600;
AssignLayerBitrates();
ASSERT_NO_FATAL_FAILURE(RunLoop(&video));
#if CONFIG_VP9_DECODER
// The non-reference frames are expected to be mismatched frames as the
// encoder will avoid loopfilter on these frames.
EXPECT_EQ(GetNonRefFrames(), GetMismatchFrames());
#endif
}
// Start decoding from beginning of sequence, during sequence insert intra-only
// on base/qvga layer and sync_layer on middle/VGA layer. Decode all layers.
TEST_P(SyncFrameOnePassCbrSvc, OnePassCbrSvc3SL3TLSyncFrameIntraOnlyVGA) {
SetSvcConfig(3, 3);
frame_to_start_decode_ = 0;
frame_to_sync_ = 20;
decode_to_layer_before_sync_ = 2;
// The superframe containing intra-only layer will have 4 frames. Thus set the
// layer to decode after sync frame to 3.
decode_to_layer_after_sync_ = 3;
intra_only_test_ = true;
// Set up svc layer sync structure.
svc_layer_sync_.base_layer_intra_only = 1;
svc_layer_sync_.spatial_layer_sync[0] = 1;
svc_layer_sync_.spatial_layer_sync[1] = 1;
svc_layer_sync_.spatial_layer_sync[2] = 0;
::libvpx_test::Y4mVideoSource video("niklas_1280_720_30.y4m", 0, 60);
cfg_.rc_target_bitrate = 600;
AssignLayerBitrates();
ASSERT_NO_FATAL_FAILURE(RunLoop(&video));
#if CONFIG_VP9_DECODER
// The non-reference frames are expected to be mismatched frames as the
// encoder will avoid loopfilter on these frames.
EXPECT_EQ(GetNonRefFrames(), GetMismatchFrames());
#endif
}
// Start decoding from sync frame, insert intra-only on base/qvga layer. Decode
// all layers. For 1 spatial layer, it inserts a key frame.
TEST_P(SyncFrameOnePassCbrSvc, OnePassCbrSvc1SL3TLSyncFrameIntraOnlyQVGA) {
SetSvcConfig(1, 3);
frame_to_start_decode_ = 20;
frame_to_sync_ = 20;
decode_to_layer_before_sync_ = 0;
decode_to_layer_after_sync_ = 0;
intra_only_test_ = true;
// Set up svc layer sync structure.
svc_layer_sync_.base_layer_intra_only = 1;
svc_layer_sync_.spatial_layer_sync[0] = 1;
::libvpx_test::Y4mVideoSource video("niklas_1280_720_30.y4m", 0, 60);
cfg_.rc_target_bitrate = 600;
AssignLayerBitrates();
ASSERT_NO_FATAL_FAILURE(RunLoop(&video));
#if CONFIG_VP9_DECODER
// The non-reference frames are expected to be mismatched frames as the
// encoder will avoid loopfilter on these frames.
EXPECT_EQ(GetNonRefFrames(), GetMismatchFrames());
#endif
}
VP9_INSTANTIATE_TEST_CASE(SyncFrameOnePassCbrSvc, ::testing::Range(0, 3));
INSTANTIATE_TEST_CASE_P(
VP9, ScalePartitionOnePassCbrSvc,
::testing::Values(
static_cast<const libvpx_test::CodecFactory *>(&libvpx_test::kVP9)));
} // namespace
} // namespace svc_test

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2013 The WebM project authors. All Rights Reserved.
* Copyright (c) 2018 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
@ -8,782 +8,127 @@
* be found in the AUTHORS file in the root of the source tree.
*/
#include <string>
#include "third_party/googletest/src/include/gtest/gtest.h"
#include "test/codec_factory.h"
#include "test/decode_test_driver.h"
#include "test/i420_video_source.h"
#include "test/svc_test.h"
#include "vp9/decoder/vp9_decoder.h"
namespace svc_test {
void OnePassCbrSvc::SetSvcConfig(const int num_spatial_layer,
const int num_temporal_layer) {
SetConfig(num_temporal_layer);
cfg_.ss_number_layers = num_spatial_layer;
cfg_.ts_number_layers = num_temporal_layer;
if (num_spatial_layer == 1) {
svc_params_.scaling_factor_num[0] = 288;
svc_params_.scaling_factor_den[0] = 288;
} else if (num_spatial_layer == 2) {
svc_params_.scaling_factor_num[0] = 144;
svc_params_.scaling_factor_den[0] = 288;
svc_params_.scaling_factor_num[1] = 288;
svc_params_.scaling_factor_den[1] = 288;
} else if (num_spatial_layer == 3) {
svc_params_.scaling_factor_num[0] = 72;
svc_params_.scaling_factor_den[0] = 288;
svc_params_.scaling_factor_num[1] = 144;
svc_params_.scaling_factor_den[1] = 288;
svc_params_.scaling_factor_num[2] = 288;
svc_params_.scaling_factor_den[2] = 288;
}
number_spatial_layers_ = cfg_.ss_number_layers;
number_temporal_layers_ = cfg_.ts_number_layers;
}
#include "vpx/svc_context.h"
#include "vpx/vp8cx.h"
#include "vpx/vpx_encoder.h"
void OnePassCbrSvc::PreEncodeFrameHookSetup(::libvpx_test::VideoSource *video,
::libvpx_test::Encoder *encoder) {
if (video->frame() == 0) {
for (int i = 0; i < VPX_MAX_LAYERS; ++i) {
svc_params_.max_quantizers[i] = 63;
svc_params_.min_quantizers[i] = 0;
}
svc_params_.speed_per_layer[0] = base_speed_setting_;
for (int i = 1; i < VPX_SS_MAX_LAYERS; ++i) {
svc_params_.speed_per_layer[i] = speed_setting_;
}
namespace {
using libvpx_test::CodecFactory;
using libvpx_test::Decoder;
using libvpx_test::DxDataIterator;
using libvpx_test::VP9CodecFactory;
class SvcTest : public ::testing::Test {
protected:
static const uint32_t kWidth = 352;
static const uint32_t kHeight = 288;
SvcTest()
: codec_iface_(0), test_file_name_("hantro_collage_w352h288.yuv"),
codec_initialized_(false), decoder_(0) {
memset(&svc_, 0, sizeof(svc_));
memset(&codec_, 0, sizeof(codec_));
memset(&codec_enc_, 0, sizeof(codec_enc_));
encoder->Control(VP9E_SET_SVC, 1);
encoder->Control(VP9E_SET_SVC_PARAMETERS, &svc_params_);
encoder->Control(VP8E_SET_CPUUSED, speed_setting_);
encoder->Control(VP9E_SET_AQ_MODE, 3);
encoder->Control(VP8E_SET_MAX_INTRA_BITRATE_PCT, 300);
encoder->Control(VP9E_SET_TILE_COLUMNS, get_msb(cfg_.g_threads));
encoder->Control(VP9E_SET_ROW_MT, 1);
encoder->Control(VP8E_SET_STATIC_THRESHOLD, 1);
}
virtual ~SvcTest() {}
virtual void SetUp() {
svc_.log_level = SVC_LOG_DEBUG;
svc_.log_print = 0;
codec_iface_ = vpx_codec_vp9_cx();
const vpx_codec_err_t res =
vpx_codec_enc_config_default(codec_iface_, &codec_enc_, 0);
EXPECT_EQ(VPX_CODEC_OK, res);
codec_enc_.g_w = kWidth;
codec_enc_.g_h = kHeight;
codec_enc_.g_timebase.num = 1;
codec_enc_.g_timebase.den = 60;
codec_enc_.kf_min_dist = 100;
codec_enc_.kf_max_dist = 100;
vpx_codec_dec_cfg_t dec_cfg = vpx_codec_dec_cfg_t();
VP9CodecFactory codec_factory;
decoder_ = codec_factory.CreateDecoder(dec_cfg, 0);
tile_columns_ = 0;
tile_rows_ = 0;
}
virtual void TearDown() {
ReleaseEncoder();
delete (decoder_);
}
void InitializeEncoder() {
const vpx_codec_err_t res =
vpx_svc_init(&svc_, &codec_, vpx_codec_vp9_cx(), &codec_enc_);
EXPECT_EQ(VPX_CODEC_OK, res);
vpx_codec_control(&codec_, VP8E_SET_CPUUSED, 4); // Make the test faster
vpx_codec_control(&codec_, VP9E_SET_TILE_COLUMNS, tile_columns_);
vpx_codec_control(&codec_, VP9E_SET_TILE_ROWS, tile_rows_);
codec_initialized_ = true;
}
void ReleaseEncoder() {
vpx_svc_release(&svc_);
if (codec_initialized_) vpx_codec_destroy(&codec_);
codec_initialized_ = false;
}
void GetStatsData(std::string *const stats_buf) {
vpx_codec_iter_t iter = NULL;
const vpx_codec_cx_pkt_t *cx_pkt;
while ((cx_pkt = vpx_codec_get_cx_data(&codec_, &iter)) != NULL) {
if (cx_pkt->kind == VPX_CODEC_STATS_PKT) {
EXPECT_GT(cx_pkt->data.twopass_stats.sz, 0U);
ASSERT_TRUE(cx_pkt->data.twopass_stats.buf != NULL);
stats_buf->append(static_cast<char *>(cx_pkt->data.twopass_stats.buf),
cx_pkt->data.twopass_stats.sz);
}
superframe_count_++;
temporal_layer_id_ = 0;
if (number_temporal_layers_ == 2) {
temporal_layer_id_ = (superframe_count_ % 2 != 0);
} else if (number_temporal_layers_ == 3) {
if (superframe_count_ % 2 != 0) temporal_layer_id_ = 2;
if (superframe_count_ > 1) {
if ((superframe_count_ - 2) % 4 == 0) temporal_layer_id_ = 1;
}
}
void Pass1EncodeNFrames(const int n, const int layers,
std::string *const stats_buf) {
vpx_codec_err_t res;
frame_flags_ = 0;
}
ASSERT_GT(n, 0);
ASSERT_GT(layers, 0);
svc_.spatial_layers = layers;
codec_enc_.g_pass = VPX_RC_FIRST_PASS;
InitializeEncoder();
libvpx_test::I420VideoSource video(
test_file_name_, codec_enc_.g_w, codec_enc_.g_h,
codec_enc_.g_timebase.den, codec_enc_.g_timebase.num, 0, 30);
video.Begin();
for (int i = 0; i < n; ++i) {
res = vpx_svc_encode(&svc_, &codec_, video.img(), video.pts(),
video.duration(), VPX_DL_GOOD_QUALITY);
ASSERT_EQ(VPX_CODEC_OK, res);
GetStatsData(stats_buf);
video.Next();
}
// Flush encoder and test EOS packet.
res = vpx_svc_encode(&svc_, &codec_, NULL, video.pts(), video.duration(),
VPX_DL_GOOD_QUALITY);
ASSERT_EQ(VPX_CODEC_OK, res);
GetStatsData(stats_buf);
ReleaseEncoder();
}
void StoreFrames(const size_t max_frame_received,
struct vpx_fixed_buf *const outputs,
size_t *const frame_received) {
vpx_codec_iter_t iter = NULL;
const vpx_codec_cx_pkt_t *cx_pkt;
while ((cx_pkt = vpx_codec_get_cx_data(&codec_, &iter)) != NULL) {
if (cx_pkt->kind == VPX_CODEC_CX_FRAME_PKT) {
const size_t frame_size = cx_pkt->data.frame.sz;
EXPECT_GT(frame_size, 0U);
ASSERT_TRUE(cx_pkt->data.frame.buf != NULL);
ASSERT_LT(*frame_received, max_frame_received);
if (*frame_received == 0)
EXPECT_EQ(1, !!(cx_pkt->data.frame.flags & VPX_FRAME_IS_KEY));
outputs[*frame_received].buf = malloc(frame_size + 16);
ASSERT_TRUE(outputs[*frame_received].buf != NULL);
memcpy(outputs[*frame_received].buf, cx_pkt->data.frame.buf,
frame_size);
outputs[*frame_received].sz = frame_size;
++(*frame_received);
}
void OnePassCbrSvc::PostEncodeFrameHook(::libvpx_test::Encoder *encoder) {
vpx_svc_layer_id_t layer_id;
encoder->Control(VP9E_GET_SVC_LAYER_ID, &layer_id);
temporal_layer_id_ = layer_id.temporal_layer_id;
for (int sl = 0; sl < number_spatial_layers_; ++sl) {
for (int tl = temporal_layer_id_; tl < number_temporal_layers_; ++tl) {
const int layer = sl * number_temporal_layers_ + tl;
bits_in_buffer_model_[layer] +=
static_cast<int64_t>(layer_target_avg_bandwidth_[layer]);
}
}
}
void Pass2EncodeNFrames(std::string *const stats_buf, const int n,
const int layers,
struct vpx_fixed_buf *const outputs) {
vpx_codec_err_t res;
size_t frame_received = 0;
ASSERT_TRUE(outputs != NULL);
ASSERT_GT(n, 0);
ASSERT_GT(layers, 0);
svc_.spatial_layers = layers;
codec_enc_.rc_target_bitrate = 500;
if (codec_enc_.g_pass == VPX_RC_LAST_PASS) {
ASSERT_TRUE(stats_buf != NULL);
ASSERT_GT(stats_buf->size(), 0U);
codec_enc_.rc_twopass_stats_in.buf = &(*stats_buf)[0];
codec_enc_.rc_twopass_stats_in.sz = stats_buf->size();
}
InitializeEncoder();
libvpx_test::I420VideoSource video(
test_file_name_, codec_enc_.g_w, codec_enc_.g_h,
codec_enc_.g_timebase.den, codec_enc_.g_timebase.num, 0, 30);
video.Begin();
for (int i = 0; i < n; ++i) {
res = vpx_svc_encode(&svc_, &codec_, video.img(), video.pts(),
video.duration(), VPX_DL_GOOD_QUALITY);
ASSERT_EQ(VPX_CODEC_OK, res);
StoreFrames(n, outputs, &frame_received);
video.Next();
}
// Flush encoder.
res = vpx_svc_encode(&svc_, &codec_, NULL, 0, video.duration(),
VPX_DL_GOOD_QUALITY);
EXPECT_EQ(VPX_CODEC_OK, res);
StoreFrames(n, outputs, &frame_received);
EXPECT_EQ(frame_received, static_cast<size_t>(n));
ReleaseEncoder();
}
void DecodeNFrames(const struct vpx_fixed_buf *const inputs, const int n) {
int decoded_frames = 0;
int received_frames = 0;
ASSERT_TRUE(inputs != NULL);
ASSERT_GT(n, 0);
for (int i = 0; i < n; ++i) {
ASSERT_TRUE(inputs[i].buf != NULL);
ASSERT_GT(inputs[i].sz, 0U);
const vpx_codec_err_t res_dec = decoder_->DecodeFrame(
static_cast<const uint8_t *>(inputs[i].buf), inputs[i].sz);
ASSERT_EQ(VPX_CODEC_OK, res_dec) << decoder_->DecodeError();
++decoded_frames;
DxDataIterator dec_iter = decoder_->GetDxData();
while (dec_iter.Next() != NULL) {
++received_frames;
}
}
EXPECT_EQ(decoded_frames, n);
EXPECT_EQ(received_frames, n);
}
void DropEnhancementLayers(struct vpx_fixed_buf *const inputs,
const int num_super_frames,
const int remained_spatial_layers) {
ASSERT_TRUE(inputs != NULL);
ASSERT_GT(num_super_frames, 0);
ASSERT_GT(remained_spatial_layers, 0);
for (int i = 0; i < num_super_frames; ++i) {
uint32_t frame_sizes[8] = { 0 };
int frame_count = 0;
int frames_found = 0;
int frame;
ASSERT_TRUE(inputs[i].buf != NULL);
ASSERT_GT(inputs[i].sz, 0U);
vpx_codec_err_t res = vp9_parse_superframe_index(
static_cast<const uint8_t *>(inputs[i].buf), inputs[i].sz,
frame_sizes, &frame_count, NULL, NULL);
ASSERT_EQ(VPX_CODEC_OK, res);
if (frame_count == 0) {
// There's no super frame but only a single frame.
ASSERT_EQ(1, remained_spatial_layers);
} else {
// Found a super frame.
uint8_t *frame_data = static_cast<uint8_t *>(inputs[i].buf);
uint8_t *frame_start = frame_data;
for (frame = 0; frame < frame_count; ++frame) {
// Looking for a visible frame.
if (frame_data[0] & 0x02) {
++frames_found;
if (frames_found == remained_spatial_layers) break;
}
frame_data += frame_sizes[frame];
}
ASSERT_LT(frame, frame_count)
<< "Couldn't find a visible frame. "
<< "remained_spatial_layers: " << remained_spatial_layers
<< " super_frame: " << i;
if (frame == frame_count - 1) continue;
frame_data += frame_sizes[frame];
// We need to add one more frame for multiple frame contexts.
uint8_t marker =
static_cast<const uint8_t *>(inputs[i].buf)[inputs[i].sz - 1];
const uint32_t mag = ((marker >> 3) & 0x3) + 1;
const size_t index_sz = 2 + mag * frame_count;
const size_t new_index_sz = 2 + mag * (frame + 1);
marker &= 0x0f8;
marker |= frame;
// Copy existing frame sizes.
memmove(frame_data + 1, frame_start + inputs[i].sz - index_sz + 1,
new_index_sz - 2);
// New marker.
frame_data[0] = marker;
frame_data += (mag * (frame + 1) + 1);
*frame_data++ = marker;
inputs[i].sz = frame_data - frame_start;
}
void OnePassCbrSvc::AssignLayerBitrates() {
int sl, spatial_layer_target;
int spatial_layers = cfg_.ss_number_layers;
int temporal_layers = cfg_.ts_number_layers;
float total = 0;
float alloc_ratio[VPX_MAX_LAYERS] = { 0 };
float framerate = 30.0;
for (sl = 0; sl < spatial_layers; ++sl) {
if (svc_params_.scaling_factor_den[sl] > 0) {
alloc_ratio[sl] =
static_cast<float>((svc_params_.scaling_factor_num[sl] * 1.0 /
svc_params_.scaling_factor_den[sl]));
total += alloc_ratio[sl];
}
}
void FreeBitstreamBuffers(struct vpx_fixed_buf *const inputs, const int n) {
ASSERT_TRUE(inputs != NULL);
ASSERT_GT(n, 0);
for (int i = 0; i < n; ++i) {
free(inputs[i].buf);
inputs[i].buf = NULL;
inputs[i].sz = 0;
for (sl = 0; sl < spatial_layers; ++sl) {
cfg_.ss_target_bitrate[sl] = spatial_layer_target =
static_cast<unsigned int>(cfg_.rc_target_bitrate * alloc_ratio[sl] /
total);
const int index = sl * temporal_layers;
if (cfg_.temporal_layering_mode == 3) {
cfg_.layer_target_bitrate[index] = spatial_layer_target >> 1;
cfg_.layer_target_bitrate[index + 1] =
(spatial_layer_target >> 1) + (spatial_layer_target >> 2);
cfg_.layer_target_bitrate[index + 2] = spatial_layer_target;
} else if (cfg_.temporal_layering_mode == 2) {
cfg_.layer_target_bitrate[index] = spatial_layer_target * 2 / 3;
cfg_.layer_target_bitrate[index + 1] = spatial_layer_target;
} else if (cfg_.temporal_layering_mode <= 1) {
cfg_.layer_target_bitrate[index] = spatial_layer_target;
}
}
for (sl = 0; sl < spatial_layers; ++sl) {
for (int tl = 0; tl < temporal_layers; ++tl) {
const int layer = sl * temporal_layers + tl;
float layer_framerate = framerate;
if (temporal_layers == 2 && tl == 0) layer_framerate = framerate / 2;
if (temporal_layers == 3 && tl == 0) layer_framerate = framerate / 4;
if (temporal_layers == 3 && tl == 1) layer_framerate = framerate / 2;
layer_target_avg_bandwidth_[layer] = static_cast<int>(
cfg_.layer_target_bitrate[layer] * 1000.0 / layer_framerate);
bits_in_buffer_model_[layer] =
cfg_.layer_target_bitrate[layer] * cfg_.rc_buf_initial_sz;
}
}
SvcContext svc_;
vpx_codec_ctx_t codec_;
struct vpx_codec_enc_cfg codec_enc_;
vpx_codec_iface_t *codec_iface_;
std::string test_file_name_;
bool codec_initialized_;
Decoder *decoder_;
int tile_columns_;
int tile_rows_;
};
TEST_F(SvcTest, SvcInit) {
// test missing parameters
vpx_codec_err_t res = vpx_svc_init(NULL, &codec_, codec_iface_, &codec_enc_);
EXPECT_EQ(VPX_CODEC_INVALID_PARAM, res);
res = vpx_svc_init(&svc_, NULL, codec_iface_, &codec_enc_);
EXPECT_EQ(VPX_CODEC_INVALID_PARAM, res);
res = vpx_svc_init(&svc_, &codec_, NULL, &codec_enc_);
EXPECT_EQ(VPX_CODEC_INVALID_PARAM, res);
res = vpx_svc_init(&svc_, &codec_, codec_iface_, NULL);
EXPECT_EQ(VPX_CODEC_INVALID_PARAM, res);
svc_.spatial_layers = 6; // too many layers
res = vpx_svc_init(&svc_, &codec_, codec_iface_, &codec_enc_);
EXPECT_EQ(VPX_CODEC_INVALID_PARAM, res);
svc_.spatial_layers = 0; // use default layers
InitializeEncoder();
EXPECT_EQ(VPX_SS_DEFAULT_LAYERS, svc_.spatial_layers);
}
TEST_F(SvcTest, InitTwoLayers) {
svc_.spatial_layers = 2;
InitializeEncoder();
}
TEST_F(SvcTest, InvalidOptions) {
vpx_codec_err_t res = vpx_svc_set_options(&svc_, NULL);
EXPECT_EQ(VPX_CODEC_INVALID_PARAM, res);
res = vpx_svc_set_options(&svc_, "not-an-option=1");
EXPECT_EQ(VPX_CODEC_OK, res);
res = vpx_svc_init(&svc_, &codec_, vpx_codec_vp9_cx(), &codec_enc_);
EXPECT_EQ(VPX_CODEC_INVALID_PARAM, res);
}
TEST_F(SvcTest, SetLayersOption) {
vpx_codec_err_t res = vpx_svc_set_options(&svc_, "spatial-layers=3");
EXPECT_EQ(VPX_CODEC_OK, res);
InitializeEncoder();
EXPECT_EQ(3, svc_.spatial_layers);
}
TEST_F(SvcTest, SetMultipleOptions) {
vpx_codec_err_t res =
vpx_svc_set_options(&svc_, "spatial-layers=2 scale-factors=1/3,2/3");
EXPECT_EQ(VPX_CODEC_OK, res);
InitializeEncoder();
EXPECT_EQ(2, svc_.spatial_layers);
}
TEST_F(SvcTest, SetScaleFactorsOption) {
svc_.spatial_layers = 2;
vpx_codec_err_t res =
vpx_svc_set_options(&svc_, "scale-factors=not-scale-factors");
EXPECT_EQ(VPX_CODEC_OK, res);
res = vpx_svc_init(&svc_, &codec_, vpx_codec_vp9_cx(), &codec_enc_);
EXPECT_EQ(VPX_CODEC_INVALID_PARAM, res);
res = vpx_svc_set_options(&svc_, "scale-factors=1/3, 3*3");
EXPECT_EQ(VPX_CODEC_OK, res);
res = vpx_svc_init(&svc_, &codec_, vpx_codec_vp9_cx(), &codec_enc_);
EXPECT_EQ(VPX_CODEC_INVALID_PARAM, res);
res = vpx_svc_set_options(&svc_, "scale-factors=1/3");
EXPECT_EQ(VPX_CODEC_OK, res);
res = vpx_svc_init(&svc_, &codec_, vpx_codec_vp9_cx(), &codec_enc_);
EXPECT_EQ(VPX_CODEC_INVALID_PARAM, res);
res = vpx_svc_set_options(&svc_, "scale-factors=1/3,2/3");
EXPECT_EQ(VPX_CODEC_OK, res);
InitializeEncoder();
}
TEST_F(SvcTest, SetQuantizersOption) {
svc_.spatial_layers = 2;
vpx_codec_err_t res = vpx_svc_set_options(&svc_, "max-quantizers=nothing");
EXPECT_EQ(VPX_CODEC_OK, res);
res = vpx_svc_init(&svc_, &codec_, vpx_codec_vp9_cx(), &codec_enc_);
EXPECT_EQ(VPX_CODEC_INVALID_PARAM, res);
res = vpx_svc_set_options(&svc_, "min-quantizers=nothing");
EXPECT_EQ(VPX_CODEC_OK, res);
res = vpx_svc_init(&svc_, &codec_, vpx_codec_vp9_cx(), &codec_enc_);
EXPECT_EQ(VPX_CODEC_INVALID_PARAM, res);
res = vpx_svc_set_options(&svc_, "max-quantizers=40");
EXPECT_EQ(VPX_CODEC_OK, res);
res = vpx_svc_init(&svc_, &codec_, vpx_codec_vp9_cx(), &codec_enc_);
EXPECT_EQ(VPX_CODEC_INVALID_PARAM, res);
res = vpx_svc_set_options(&svc_, "min-quantizers=40");
EXPECT_EQ(VPX_CODEC_OK, res);
res = vpx_svc_init(&svc_, &codec_, vpx_codec_vp9_cx(), &codec_enc_);
EXPECT_EQ(VPX_CODEC_INVALID_PARAM, res);
res = vpx_svc_set_options(&svc_, "max-quantizers=30,30 min-quantizers=40,40");
EXPECT_EQ(VPX_CODEC_OK, res);
res = vpx_svc_init(&svc_, &codec_, vpx_codec_vp9_cx(), &codec_enc_);
EXPECT_EQ(VPX_CODEC_INVALID_PARAM, res);
res = vpx_svc_set_options(&svc_, "max-quantizers=40,40 min-quantizers=30,30");
InitializeEncoder();
}
TEST_F(SvcTest, SetAutoAltRefOption) {
svc_.spatial_layers = 5;
vpx_codec_err_t res = vpx_svc_set_options(&svc_, "auto-alt-refs=none");
EXPECT_EQ(VPX_CODEC_OK, res);
res = vpx_svc_init(&svc_, &codec_, vpx_codec_vp9_cx(), &codec_enc_);
EXPECT_EQ(VPX_CODEC_INVALID_PARAM, res);
res = vpx_svc_set_options(&svc_, "auto-alt-refs=1,1,1,1,0");
EXPECT_EQ(VPX_CODEC_OK, res);
res = vpx_svc_init(&svc_, &codec_, vpx_codec_vp9_cx(), &codec_enc_);
EXPECT_EQ(VPX_CODEC_INVALID_PARAM, res);
vpx_svc_set_options(&svc_, "auto-alt-refs=0,1,1,1,0");
InitializeEncoder();
}
// Test that decoder can handle an SVC frame as the first frame in a sequence.
TEST_F(SvcTest, OnePassEncodeOneFrame) {
codec_enc_.g_pass = VPX_RC_ONE_PASS;
vpx_fixed_buf output = vpx_fixed_buf();
Pass2EncodeNFrames(NULL, 1, 2, &output);
DecodeNFrames(&output, 1);
FreeBitstreamBuffers(&output, 1);
}
TEST_F(SvcTest, OnePassEncodeThreeFrames) {
codec_enc_.g_pass = VPX_RC_ONE_PASS;
codec_enc_.g_lag_in_frames = 0;
vpx_fixed_buf outputs[3];
memset(&outputs[0], 0, sizeof(outputs));
Pass2EncodeNFrames(NULL, 3, 2, &outputs[0]);
DecodeNFrames(&outputs[0], 3);
FreeBitstreamBuffers(&outputs[0], 3);
}
TEST_F(SvcTest, TwoPassEncode10Frames) {
// First pass encode
std::string stats_buf;
Pass1EncodeNFrames(10, 2, &stats_buf);
// Second pass encode
codec_enc_.g_pass = VPX_RC_LAST_PASS;
vpx_fixed_buf outputs[10];
memset(&outputs[0], 0, sizeof(outputs));
Pass2EncodeNFrames(&stats_buf, 10, 2, &outputs[0]);
DecodeNFrames(&outputs[0], 10);
FreeBitstreamBuffers(&outputs[0], 10);
}
TEST_F(SvcTest, TwoPassEncode20FramesWithAltRef) {
// First pass encode
std::string stats_buf;
Pass1EncodeNFrames(20, 2, &stats_buf);
// Second pass encode
codec_enc_.g_pass = VPX_RC_LAST_PASS;
vpx_svc_set_options(&svc_, "auto-alt-refs=1,1");
vpx_fixed_buf outputs[20];
memset(&outputs[0], 0, sizeof(outputs));
Pass2EncodeNFrames(&stats_buf, 20, 2, &outputs[0]);
DecodeNFrames(&outputs[0], 20);
FreeBitstreamBuffers(&outputs[0], 20);
}
TEST_F(SvcTest, TwoPassEncode2SpatialLayersDecodeBaseLayerOnly) {
// First pass encode
std::string stats_buf;
Pass1EncodeNFrames(10, 2, &stats_buf);
// Second pass encode
codec_enc_.g_pass = VPX_RC_LAST_PASS;
vpx_svc_set_options(&svc_, "auto-alt-refs=1,1");
vpx_fixed_buf outputs[10];
memset(&outputs[0], 0, sizeof(outputs));
Pass2EncodeNFrames(&stats_buf, 10, 2, &outputs[0]);
DropEnhancementLayers(&outputs[0], 10, 1);
DecodeNFrames(&outputs[0], 10);
FreeBitstreamBuffers(&outputs[0], 10);
}
TEST_F(SvcTest, TwoPassEncode5SpatialLayersDecode54321Layers) {
// First pass encode
std::string stats_buf;
Pass1EncodeNFrames(10, 5, &stats_buf);
// Second pass encode
codec_enc_.g_pass = VPX_RC_LAST_PASS;
vpx_svc_set_options(&svc_, "auto-alt-refs=0,1,1,1,0");
vpx_fixed_buf outputs[10];
memset(&outputs[0], 0, sizeof(outputs));
Pass2EncodeNFrames(&stats_buf, 10, 5, &outputs[0]);
DecodeNFrames(&outputs[0], 10);
DropEnhancementLayers(&outputs[0], 10, 4);
DecodeNFrames(&outputs[0], 10);
DropEnhancementLayers(&outputs[0], 10, 3);
DecodeNFrames(&outputs[0], 10);
DropEnhancementLayers(&outputs[0], 10, 2);
DecodeNFrames(&outputs[0], 10);
DropEnhancementLayers(&outputs[0], 10, 1);
DecodeNFrames(&outputs[0], 10);
FreeBitstreamBuffers(&outputs[0], 10);
}
TEST_F(SvcTest, TwoPassEncode2SNRLayers) {
// First pass encode
std::string stats_buf;
vpx_svc_set_options(&svc_, "scale-factors=1/1,1/1");
Pass1EncodeNFrames(20, 2, &stats_buf);
// Second pass encode
codec_enc_.g_pass = VPX_RC_LAST_PASS;
vpx_svc_set_options(&svc_, "auto-alt-refs=1,1 scale-factors=1/1,1/1");
vpx_fixed_buf outputs[20];
memset(&outputs[0], 0, sizeof(outputs));
Pass2EncodeNFrames(&stats_buf, 20, 2, &outputs[0]);
DecodeNFrames(&outputs[0], 20);
FreeBitstreamBuffers(&outputs[0], 20);
}
TEST_F(SvcTest, TwoPassEncode3SNRLayersDecode321Layers) {
// First pass encode
std::string stats_buf;
vpx_svc_set_options(&svc_, "scale-factors=1/1,1/1,1/1");
Pass1EncodeNFrames(20, 3, &stats_buf);
// Second pass encode
codec_enc_.g_pass = VPX_RC_LAST_PASS;
vpx_svc_set_options(&svc_, "auto-alt-refs=1,1,1 scale-factors=1/1,1/1,1/1");
vpx_fixed_buf outputs[20];
memset(&outputs[0], 0, sizeof(outputs));
Pass2EncodeNFrames(&stats_buf, 20, 3, &outputs[0]);
DecodeNFrames(&outputs[0], 20);
DropEnhancementLayers(&outputs[0], 20, 2);
DecodeNFrames(&outputs[0], 20);
DropEnhancementLayers(&outputs[0], 20, 1);
DecodeNFrames(&outputs[0], 20);
FreeBitstreamBuffers(&outputs[0], 20);
}
TEST_F(SvcTest, SetMultipleFrameContextsOption) {
svc_.spatial_layers = 5;
vpx_codec_err_t res = vpx_svc_set_options(&svc_, "multi-frame-contexts=1");
EXPECT_EQ(VPX_CODEC_OK, res);
res = vpx_svc_init(&svc_, &codec_, vpx_codec_vp9_cx(), &codec_enc_);
EXPECT_EQ(VPX_CODEC_INVALID_PARAM, res);
svc_.spatial_layers = 2;
res = vpx_svc_set_options(&svc_, "multi-frame-contexts=1");
InitializeEncoder();
}
TEST_F(SvcTest, TwoPassEncode2SpatialLayersWithMultipleFrameContexts) {
// First pass encode
std::string stats_buf;
Pass1EncodeNFrames(10, 2, &stats_buf);
// Second pass encode
codec_enc_.g_pass = VPX_RC_LAST_PASS;
codec_enc_.g_error_resilient = 0;
vpx_svc_set_options(&svc_, "auto-alt-refs=1,1 multi-frame-contexts=1");
vpx_fixed_buf outputs[10];
memset(&outputs[0], 0, sizeof(outputs));
Pass2EncodeNFrames(&stats_buf, 10, 2, &outputs[0]);
DecodeNFrames(&outputs[0], 10);
FreeBitstreamBuffers(&outputs[0], 10);
}
TEST_F(SvcTest,
TwoPassEncode2SpatialLayersWithMultipleFrameContextsDecodeBaselayer) {
// First pass encode
std::string stats_buf;
Pass1EncodeNFrames(10, 2, &stats_buf);
// Second pass encode
codec_enc_.g_pass = VPX_RC_LAST_PASS;
codec_enc_.g_error_resilient = 0;
vpx_svc_set_options(&svc_, "auto-alt-refs=1,1 multi-frame-contexts=1");
vpx_fixed_buf outputs[10];
memset(&outputs[0], 0, sizeof(outputs));
Pass2EncodeNFrames(&stats_buf, 10, 2, &outputs[0]);
DropEnhancementLayers(&outputs[0], 10, 1);
DecodeNFrames(&outputs[0], 10);
FreeBitstreamBuffers(&outputs[0], 10);
}
TEST_F(SvcTest, TwoPassEncode2SNRLayersWithMultipleFrameContexts) {
// First pass encode
std::string stats_buf;
vpx_svc_set_options(&svc_, "scale-factors=1/1,1/1");
Pass1EncodeNFrames(10, 2, &stats_buf);
// Second pass encode
codec_enc_.g_pass = VPX_RC_LAST_PASS;
codec_enc_.g_error_resilient = 0;
vpx_svc_set_options(&svc_,
"auto-alt-refs=1,1 scale-factors=1/1,1/1 "
"multi-frame-contexts=1");
vpx_fixed_buf outputs[10];
memset(&outputs[0], 0, sizeof(outputs));
Pass2EncodeNFrames(&stats_buf, 10, 2, &outputs[0]);
DecodeNFrames(&outputs[0], 10);
FreeBitstreamBuffers(&outputs[0], 10);
}
TEST_F(SvcTest,
TwoPassEncode3SNRLayersWithMultipleFrameContextsDecode321Layer) {
// First pass encode
std::string stats_buf;
vpx_svc_set_options(&svc_, "scale-factors=1/1,1/1,1/1");
Pass1EncodeNFrames(10, 3, &stats_buf);
// Second pass encode
codec_enc_.g_pass = VPX_RC_LAST_PASS;
codec_enc_.g_error_resilient = 0;
vpx_svc_set_options(&svc_,
"auto-alt-refs=1,1,1 scale-factors=1/1,1/1,1/1 "
"multi-frame-contexts=1");
vpx_fixed_buf outputs[10];
memset(&outputs[0], 0, sizeof(outputs));
Pass2EncodeNFrames(&stats_buf, 10, 3, &outputs[0]);
DecodeNFrames(&outputs[0], 10);
DropEnhancementLayers(&outputs[0], 10, 2);
DecodeNFrames(&outputs[0], 10);
DropEnhancementLayers(&outputs[0], 10, 1);
DecodeNFrames(&outputs[0], 10);
FreeBitstreamBuffers(&outputs[0], 10);
}
TEST_F(SvcTest, TwoPassEncode2TemporalLayers) {
// First pass encode
std::string stats_buf;
vpx_svc_set_options(&svc_, "scale-factors=1/1");
svc_.temporal_layers = 2;
Pass1EncodeNFrames(10, 1, &stats_buf);
// Second pass encode
codec_enc_.g_pass = VPX_RC_LAST_PASS;
svc_.temporal_layers = 2;
vpx_svc_set_options(&svc_, "auto-alt-refs=1 scale-factors=1/1");
vpx_fixed_buf outputs[10];
memset(&outputs[0], 0, sizeof(outputs));
Pass2EncodeNFrames(&stats_buf, 10, 1, &outputs[0]);
DecodeNFrames(&outputs[0], 10);
FreeBitstreamBuffers(&outputs[0], 10);
}
TEST_F(SvcTest, TwoPassEncode2TemporalLayersWithMultipleFrameContexts) {
// First pass encode
std::string stats_buf;
vpx_svc_set_options(&svc_, "scale-factors=1/1");
svc_.temporal_layers = 2;
Pass1EncodeNFrames(10, 1, &stats_buf);
// Second pass encode
codec_enc_.g_pass = VPX_RC_LAST_PASS;
svc_.temporal_layers = 2;
codec_enc_.g_error_resilient = 0;
vpx_svc_set_options(&svc_,
"auto-alt-refs=1 scale-factors=1/1 "
"multi-frame-contexts=1");
vpx_fixed_buf outputs[10];
memset(&outputs[0], 0, sizeof(outputs));
Pass2EncodeNFrames(&stats_buf, 10, 1, &outputs[0]);
DecodeNFrames(&outputs[0], 10);
FreeBitstreamBuffers(&outputs[0], 10);
}
TEST_F(SvcTest, TwoPassEncode2TemporalLayersDecodeBaseLayer) {
// First pass encode
std::string stats_buf;
vpx_svc_set_options(&svc_, "scale-factors=1/1");
svc_.temporal_layers = 2;
Pass1EncodeNFrames(10, 1, &stats_buf);
// Second pass encode
codec_enc_.g_pass = VPX_RC_LAST_PASS;
svc_.temporal_layers = 2;
vpx_svc_set_options(&svc_, "auto-alt-refs=1 scale-factors=1/1");
vpx_fixed_buf outputs[10];
memset(&outputs[0], 0, sizeof(outputs));
Pass2EncodeNFrames(&stats_buf, 10, 1, &outputs[0]);
vpx_fixed_buf base_layer[5];
for (int i = 0; i < 5; ++i) base_layer[i] = outputs[i * 2];
DecodeNFrames(&base_layer[0], 5);
FreeBitstreamBuffers(&outputs[0], 10);
}
TEST_F(SvcTest,
TwoPassEncode2TemporalLayersWithMultipleFrameContextsDecodeBaseLayer) {
// First pass encode
std::string stats_buf;
vpx_svc_set_options(&svc_, "scale-factors=1/1");
svc_.temporal_layers = 2;
Pass1EncodeNFrames(10, 1, &stats_buf);
// Second pass encode
codec_enc_.g_pass = VPX_RC_LAST_PASS;
svc_.temporal_layers = 2;
codec_enc_.g_error_resilient = 0;
vpx_svc_set_options(&svc_,
"auto-alt-refs=1 scale-factors=1/1 "
"multi-frame-contexts=1");
vpx_fixed_buf outputs[10];
memset(&outputs[0], 0, sizeof(outputs));
Pass2EncodeNFrames(&stats_buf, 10, 1, &outputs[0]);
vpx_fixed_buf base_layer[5];
for (int i = 0; i < 5; ++i) base_layer[i] = outputs[i * 2];
DecodeNFrames(&base_layer[0], 5);
FreeBitstreamBuffers(&outputs[0], 10);
}
TEST_F(SvcTest, TwoPassEncode2TemporalLayersWithTiles) {
// First pass encode
std::string stats_buf;
vpx_svc_set_options(&svc_, "scale-factors=1/1");
svc_.temporal_layers = 2;
Pass1EncodeNFrames(10, 1, &stats_buf);
// Second pass encode
codec_enc_.g_pass = VPX_RC_LAST_PASS;
svc_.temporal_layers = 2;
vpx_svc_set_options(&svc_, "auto-alt-refs=1 scale-factors=1/1");
codec_enc_.g_w = 704;
codec_enc_.g_h = 144;
tile_columns_ = 1;
tile_rows_ = 1;
vpx_fixed_buf outputs[10];
memset(&outputs[0], 0, sizeof(outputs));
Pass2EncodeNFrames(&stats_buf, 10, 1, &outputs[0]);
DecodeNFrames(&outputs[0], 10);
FreeBitstreamBuffers(&outputs[0], 10);
}
TEST_F(SvcTest, TwoPassEncode2TemporalLayersWithMultipleFrameContextsAndTiles) {
// First pass encode
std::string stats_buf;
vpx_svc_set_options(&svc_, "scale-factors=1/1");
svc_.temporal_layers = 2;
Pass1EncodeNFrames(10, 1, &stats_buf);
// Second pass encode
codec_enc_.g_pass = VPX_RC_LAST_PASS;
svc_.temporal_layers = 2;
codec_enc_.g_error_resilient = 0;
codec_enc_.g_w = 704;
codec_enc_.g_h = 144;
tile_columns_ = 1;
tile_rows_ = 1;
vpx_svc_set_options(&svc_,
"auto-alt-refs=1 scale-factors=1/1 "
"multi-frame-contexts=1");
vpx_fixed_buf outputs[10];
memset(&outputs[0], 0, sizeof(outputs));
Pass2EncodeNFrames(&stats_buf, 10, 1, &outputs[0]);
DecodeNFrames(&outputs[0], 10);
FreeBitstreamBuffers(&outputs[0], 10);
}
} // namespace
} // namespace svc_test

View File

@ -0,0 +1,67 @@
/*
* Copyright (c) 2018 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.
*/
#ifndef VPX_TEST_SVC_TEST_H_
#define VPX_TEST_SVC_TEST_H_
#include "./vpx_config.h"
#include "third_party/googletest/src/include/gtest/gtest.h"
#include "test/codec_factory.h"
#include "test/encode_test_driver.h"
#include "test/i420_video_source.h"
#include "test/util.h"
#include "test/y4m_video_source.h"
#include "vpx/vpx_codec.h"
#include "vpx_ports/bitops.h"
namespace svc_test {
class OnePassCbrSvc : public ::libvpx_test::EncoderTest {
public:
explicit OnePassCbrSvc(const ::libvpx_test::CodecFactory *codec)
: EncoderTest(codec), base_speed_setting_(0), speed_setting_(0),
superframe_count_(0), temporal_layer_id_(0), number_temporal_layers_(0),
number_spatial_layers_(0) {
memset(&svc_params_, 0, sizeof(svc_params_));
memset(bits_in_buffer_model_, 0,
sizeof(bits_in_buffer_model_[0]) * VPX_MAX_LAYERS);
memset(layer_target_avg_bandwidth_, 0,
sizeof(layer_target_avg_bandwidth_[0]) * VPX_MAX_LAYERS);
}
protected:
virtual ~OnePassCbrSvc() {}
virtual void SetConfig(const int num_temporal_layer) = 0;
virtual void SetSvcConfig(const int num_spatial_layer,
const int num_temporal_layer);
virtual void PreEncodeFrameHookSetup(::libvpx_test::VideoSource *video,
::libvpx_test::Encoder *encoder);
virtual void PostEncodeFrameHook(::libvpx_test::Encoder *encoder);
virtual void AssignLayerBitrates();
virtual void MismatchHook(const vpx_image_t *, const vpx_image_t *) {}
vpx_svc_extra_cfg_t svc_params_;
int64_t bits_in_buffer_model_[VPX_MAX_LAYERS];
int layer_target_avg_bandwidth_[VPX_MAX_LAYERS];
int base_speed_setting_;
int speed_setting_;
int superframe_count_;
int temporal_layer_id_;
int number_temporal_layers_;
int number_spatial_layers_;
};
} // namespace svc_test
#endif // VPX_TEST_SVC_TEST_H_

View File

@ -1,277 +0,0 @@
/*
* Copyright (c) 2016 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 <limits>
#include "third_party/googletest/src/include/gtest/gtest.h"
#include "./vp9_rtcd.h"
#include "test/acm_random.h"
#include "test/buffer.h"
#include "test/register_state_check.h"
#include "vpx_ports/vpx_timer.h"
namespace {
using ::libvpx_test::ACMRandom;
using ::libvpx_test::Buffer;
typedef void (*TemporalFilterFunc)(const uint8_t *a, unsigned int stride,
const uint8_t *b, unsigned int w,
unsigned int h, int filter_strength,
int filter_weight, unsigned int *accumulator,
uint16_t *count);
// Calculate the difference between 'a' and 'b', sum in blocks of 9, and apply
// filter based on strength and weight. Store the resulting filter amount in
// 'count' and apply it to 'b' and store it in 'accumulator'.
void reference_filter(const Buffer<uint8_t> &a, const Buffer<uint8_t> &b, int w,
int h, int filter_strength, int filter_weight,
Buffer<unsigned int> *accumulator,
Buffer<uint16_t> *count) {
Buffer<int> diff_sq = Buffer<int>(w, h, 0);
ASSERT_TRUE(diff_sq.Init());
diff_sq.Set(0);
int rounding = 0;
if (filter_strength > 0) {
rounding = 1 << (filter_strength - 1);
}
// Calculate all the differences. Avoids re-calculating a bunch of extra
// values.
for (int height = 0; height < h; ++height) {
for (int width = 0; width < w; ++width) {
int diff = a.TopLeftPixel()[height * a.stride() + width] -
b.TopLeftPixel()[height * b.stride() + width];
diff_sq.TopLeftPixel()[height * diff_sq.stride() + width] = diff * diff;
}
}
// For any given point, sum the neighboring values and calculate the
// modifier.
for (int height = 0; height < h; ++height) {
for (int width = 0; width < w; ++width) {
// Determine how many values are being summed.
int summed_values = 9;
if (height == 0 || height == (h - 1)) {
summed_values -= 3;
}
if (width == 0 || width == (w - 1)) {
if (summed_values == 6) { // corner
summed_values -= 2;
} else {
summed_values -= 3;
}
}
// Sum the diff_sq of the surrounding values.
int sum = 0;
for (int idy = -1; idy <= 1; ++idy) {
for (int idx = -1; idx <= 1; ++idx) {
const int y = height + idy;
const int x = width + idx;
// If inside the border.
if (y >= 0 && y < h && x >= 0 && x < w) {
sum += diff_sq.TopLeftPixel()[y * diff_sq.stride() + x];
}
}
}
sum *= 3;
sum /= summed_values;
sum += rounding;
sum >>= filter_strength;
// Clamp the value and invert it.
if (sum > 16) sum = 16;
sum = 16 - sum;
sum *= filter_weight;
count->TopLeftPixel()[height * count->stride() + width] += sum;
accumulator->TopLeftPixel()[height * accumulator->stride() + width] +=
sum * b.TopLeftPixel()[height * b.stride() + width];
}
}
}
class TemporalFilterTest : public ::testing::TestWithParam<TemporalFilterFunc> {
public:
virtual void SetUp() {
filter_func_ = GetParam();
rnd_.Reset(ACMRandom::DeterministicSeed());
}
protected:
TemporalFilterFunc filter_func_;
ACMRandom rnd_;
};
TEST_P(TemporalFilterTest, SizeCombinations) {
// Depending on subsampling this function may be called with values of 8 or 16
// for width and height, in any combination.
Buffer<uint8_t> a = Buffer<uint8_t>(16, 16, 8);
ASSERT_TRUE(a.Init());
const int filter_weight = 2;
const int filter_strength = 6;
for (int width = 8; width <= 16; width += 8) {
for (int height = 8; height <= 16; height += 8) {
// The second buffer must not have any border.
Buffer<uint8_t> b = Buffer<uint8_t>(width, height, 0);
ASSERT_TRUE(b.Init());
Buffer<unsigned int> accum_ref = Buffer<unsigned int>(width, height, 0);
ASSERT_TRUE(accum_ref.Init());
Buffer<unsigned int> accum_chk = Buffer<unsigned int>(width, height, 0);
ASSERT_TRUE(accum_chk.Init());
Buffer<uint16_t> count_ref = Buffer<uint16_t>(width, height, 0);
ASSERT_TRUE(count_ref.Init());
Buffer<uint16_t> count_chk = Buffer<uint16_t>(width, height, 0);
ASSERT_TRUE(count_chk.Init());
// The difference between the buffers must be small to pass the threshold
// to apply the filter.
a.Set(&rnd_, 0, 7);
b.Set(&rnd_, 0, 7);
accum_ref.Set(rnd_.Rand8());
accum_chk.CopyFrom(accum_ref);
count_ref.Set(rnd_.Rand8());
count_chk.CopyFrom(count_ref);
reference_filter(a, b, width, height, filter_strength, filter_weight,
&accum_ref, &count_ref);
ASM_REGISTER_STATE_CHECK(
filter_func_(a.TopLeftPixel(), a.stride(), b.TopLeftPixel(), width,
height, filter_strength, filter_weight,
accum_chk.TopLeftPixel(), count_chk.TopLeftPixel()));
EXPECT_TRUE(accum_chk.CheckValues(accum_ref));
EXPECT_TRUE(count_chk.CheckValues(count_ref));
if (HasFailure()) {
printf("Width: %d Height: %d\n", width, height);
count_chk.PrintDifference(count_ref);
accum_chk.PrintDifference(accum_ref);
return;
}
}
}
}
TEST_P(TemporalFilterTest, CompareReferenceRandom) {
for (int width = 8; width <= 16; width += 8) {
for (int height = 8; height <= 16; height += 8) {
Buffer<uint8_t> a = Buffer<uint8_t>(width, height, 8);
ASSERT_TRUE(a.Init());
// The second buffer must not have any border.
Buffer<uint8_t> b = Buffer<uint8_t>(width, height, 0);
ASSERT_TRUE(b.Init());
Buffer<unsigned int> accum_ref = Buffer<unsigned int>(width, height, 0);
ASSERT_TRUE(accum_ref.Init());
Buffer<unsigned int> accum_chk = Buffer<unsigned int>(width, height, 0);
ASSERT_TRUE(accum_chk.Init());
Buffer<uint16_t> count_ref = Buffer<uint16_t>(width, height, 0);
ASSERT_TRUE(count_ref.Init());
Buffer<uint16_t> count_chk = Buffer<uint16_t>(width, height, 0);
ASSERT_TRUE(count_chk.Init());
for (int filter_strength = 0; filter_strength <= 6; ++filter_strength) {
for (int filter_weight = 0; filter_weight <= 2; ++filter_weight) {
for (int repeat = 0; repeat < 100; ++repeat) {
if (repeat < 50) {
a.Set(&rnd_, 0, 7);
b.Set(&rnd_, 0, 7);
} else {
// Check large (but close) values as well.
a.Set(&rnd_, std::numeric_limits<uint8_t>::max() - 7,
std::numeric_limits<uint8_t>::max());
b.Set(&rnd_, std::numeric_limits<uint8_t>::max() - 7,
std::numeric_limits<uint8_t>::max());
}
accum_ref.Set(rnd_.Rand8());
accum_chk.CopyFrom(accum_ref);
count_ref.Set(rnd_.Rand8());
count_chk.CopyFrom(count_ref);
reference_filter(a, b, width, height, filter_strength,
filter_weight, &accum_ref, &count_ref);
ASM_REGISTER_STATE_CHECK(filter_func_(
a.TopLeftPixel(), a.stride(), b.TopLeftPixel(), width, height,
filter_strength, filter_weight, accum_chk.TopLeftPixel(),
count_chk.TopLeftPixel()));
EXPECT_TRUE(accum_chk.CheckValues(accum_ref));
EXPECT_TRUE(count_chk.CheckValues(count_ref));
if (HasFailure()) {
printf("Weight: %d Strength: %d\n", filter_weight,
filter_strength);
count_chk.PrintDifference(count_ref);
accum_chk.PrintDifference(accum_ref);
return;
}
}
}
}
}
}
}
TEST_P(TemporalFilterTest, DISABLED_Speed) {
Buffer<uint8_t> a = Buffer<uint8_t>(16, 16, 8);
ASSERT_TRUE(a.Init());
const int filter_weight = 2;
const int filter_strength = 6;
for (int width = 8; width <= 16; width += 8) {
for (int height = 8; height <= 16; height += 8) {
// The second buffer must not have any border.
Buffer<uint8_t> b = Buffer<uint8_t>(width, height, 0);
ASSERT_TRUE(b.Init());
Buffer<unsigned int> accum_ref = Buffer<unsigned int>(width, height, 0);
ASSERT_TRUE(accum_ref.Init());
Buffer<unsigned int> accum_chk = Buffer<unsigned int>(width, height, 0);
ASSERT_TRUE(accum_chk.Init());
Buffer<uint16_t> count_ref = Buffer<uint16_t>(width, height, 0);
ASSERT_TRUE(count_ref.Init());
Buffer<uint16_t> count_chk = Buffer<uint16_t>(width, height, 0);
ASSERT_TRUE(count_chk.Init());
a.Set(&rnd_, 0, 7);
b.Set(&rnd_, 0, 7);
accum_chk.Set(0);
count_chk.Set(0);
vpx_usec_timer timer;
vpx_usec_timer_start(&timer);
for (int i = 0; i < 10000; ++i) {
filter_func_(a.TopLeftPixel(), a.stride(), b.TopLeftPixel(), width,
height, filter_strength, filter_weight,
accum_chk.TopLeftPixel(), count_chk.TopLeftPixel());
}
vpx_usec_timer_mark(&timer);
const int elapsed_time = static_cast<int>(vpx_usec_timer_elapsed(&timer));
printf("Temporal filter %dx%d time: %5d us\n", width, height,
elapsed_time);
}
}
}
INSTANTIATE_TEST_CASE_P(C, TemporalFilterTest,
::testing::Values(&vp9_temporal_filter_apply_c));
#if HAVE_SSE4_1
INSTANTIATE_TEST_CASE_P(SSE4_1, TemporalFilterTest,
::testing::Values(&vp9_temporal_filter_apply_sse4_1));
#endif // HAVE_SSE4_1
} // namespace

View File

@ -3,14 +3,16 @@ LIBVPX_TEST_SRCS-yes += test-data.mk
# Encoder test source
LIBVPX_TEST_DATA-$(CONFIG_ENCODERS) += hantro_collage_w352h288.yuv
LIBVPX_TEST_DATA-$(CONFIG_ENCODERS) += hantro_odd.yuv
LIBVPX_TEST_DATA-$(CONFIG_ENCODERS) += desktop_office1.1280_720-020.yuv
LIBVPX_TEST_DATA-$(CONFIG_ENCODERS) += slides_code_term_web_plot.1920_1080.yuv
LIBVPX_TEST_DATA-$(CONFIG_ENCODERS) += park_joy_90p_10_420.y4m
LIBVPX_TEST_DATA-$(CONFIG_ENCODERS) += park_joy_90p_10_422.y4m
LIBVPX_TEST_DATA-$(CONFIG_ENCODERS) += park_joy_90p_10_444.y4m
LIBVPX_TEST_DATA-$(CONFIG_ENCODERS) += park_joy_90p_10_420_20f.y4m
LIBVPX_TEST_DATA-$(CONFIG_ENCODERS) += park_joy_90p_10_422_20f.y4m
LIBVPX_TEST_DATA-$(CONFIG_ENCODERS) += park_joy_90p_10_444_20f.y4m
LIBVPX_TEST_DATA-$(CONFIG_ENCODERS) += park_joy_90p_10_440.yuv
LIBVPX_TEST_DATA-$(CONFIG_ENCODERS) += park_joy_90p_12_420.y4m
LIBVPX_TEST_DATA-$(CONFIG_ENCODERS) += park_joy_90p_12_422.y4m
LIBVPX_TEST_DATA-$(CONFIG_ENCODERS) += park_joy_90p_12_444.y4m
LIBVPX_TEST_DATA-$(CONFIG_ENCODERS) += park_joy_90p_12_420_20f.y4m
LIBVPX_TEST_DATA-$(CONFIG_ENCODERS) += park_joy_90p_12_422_20f.y4m
LIBVPX_TEST_DATA-$(CONFIG_ENCODERS) += park_joy_90p_12_444_20f.y4m
LIBVPX_TEST_DATA-$(CONFIG_ENCODERS) += park_joy_90p_12_440.yuv
LIBVPX_TEST_DATA-$(CONFIG_ENCODERS) += park_joy_90p_8_420_a10-1.y4m
LIBVPX_TEST_DATA-$(CONFIG_ENCODERS) += park_joy_90p_8_420.y4m
@ -734,8 +736,12 @@ endif # CONFIG_VP9_HIGHBITDEPTH
# Invalid files for testing libvpx error checking.
LIBVPX_TEST_DATA-$(CONFIG_VP8_DECODER) += invalid-bug-1443.ivf
LIBVPX_TEST_DATA-$(CONFIG_VP8_DECODER) += invalid-bug-1443.ivf.res
LIBVPX_TEST_DATA-$(CONFIG_VP8_DECODER) += invalid-token-partition.ivf
LIBVPX_TEST_DATA-$(CONFIG_VP8_DECODER) += invalid-token-partition.ivf.res
LIBVPX_TEST_DATA-$(CONFIG_VP8_DECODER) += invalid-vp80-00-comprehensive-018.ivf.2kf_0x6.ivf
LIBVPX_TEST_DATA-$(CONFIG_VP8_DECODER) += invalid-vp80-00-comprehensive-018.ivf.2kf_0x6.ivf.res
LIBVPX_TEST_DATA-$(CONFIG_VP8_DECODER) += invalid-vp80-00-comprehensive-s17661_r01-05_b6-.ivf
LIBVPX_TEST_DATA-$(CONFIG_VP8_DECODER) += invalid-vp80-00-comprehensive-s17661_r01-05_b6-.ivf.res
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += invalid-vp90-01-v3.webm
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += invalid-vp90-01-v3.webm.res
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += invalid-vp90-02-v2.webm
@ -783,8 +789,13 @@ LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += invalid-vp90-2-07-frame_parallel-2.web
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += invalid-vp90-2-07-frame_parallel-3.webm
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += invalid-crbug-629481.webm
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += invalid-crbug-629481.webm.res
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += invalid-crbug-1558.ivf
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += invalid-crbug-1558.ivf.res
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += invalid-crbug-1562.ivf
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += invalid-crbug-1562.ivf.res
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += invalid-crbug-667044.webm
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += invalid-crbug-667044.webm.res
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += crbug-1539.rawfile
ifeq ($(CONFIG_DECODE_PERF_TESTS),yes)
# Encode / Decode test

View File

@ -17,13 +17,13 @@ df1a1453feb3c00d7d89746c7003b4163523bff3 *invalid-vp90-03-v3.webm
d637297561dd904eb2c97a9015deeb31c4a1e8d2 *invalid-vp90-2-08-tile_1x4_frame_parallel_all_key.webm
3a204bdbeaa3c6458b77bcebb8366d107267f55d *invalid-vp90-2-08-tile_1x4_frame_parallel_all_key.webm.res
9aa21d8b2cb9d39abe8a7bb6032dc66955fb4342 *noisy_clip_640_360.y4m
a432f96ff0a787268e2f94a8092ab161a18d1b06 *park_joy_90p_10_420.y4m
0b194cc312c3a2e84d156a221b0a5eb615dfddc5 *park_joy_90p_10_422.y4m
ff0e0a21dc2adc95b8c1b37902713700655ced17 *park_joy_90p_10_444.y4m
0936b837708ae68c034719f8e07596021c2c214f *park_joy_90p_10_420_20f.y4m
5727a853c083c1099f837d27967bc1322d50ed4f *park_joy_90p_10_422_20f.y4m
e13489470ef8e8b2a871a5640d795a42a39be58d *park_joy_90p_10_444_20f.y4m
c934da6fb8cc54ee2a8c17c54cf6076dac37ead0 *park_joy_90p_10_440.yuv
614c32ae1eca391e867c70d19974f0d62664dd99 *park_joy_90p_12_420.y4m
c92825f1ea25c5c37855083a69faac6ac4641a9e *park_joy_90p_12_422.y4m
b592189b885b6cc85db55cc98512a197d73d3b34 *park_joy_90p_12_444.y4m
79b0dc1784635a7f291e21c4e8d66a29c496ab99 *park_joy_90p_12_420_20f.y4m
9cf22b0f809f7464c8b9058f0cfa9d905921cbd1 *park_joy_90p_12_422_20f.y4m
22b2a4abaecc4a9ade6bb503d25fb82367947e85 *park_joy_90p_12_444_20f.y4m
82c1bfcca368c2f22bad7d693d690d5499ecdd11 *park_joy_90p_12_440.yuv
b9e1e90aece2be6e2c90d89e6ab2372d5f8c792d *park_joy_90p_8_420_a10-1.y4m
4e0eb61e76f0684188d9bc9f3ce61f6b6b77bb2c *park_joy_90p_8_420.y4m
@ -852,5 +852,16 @@ e402cbbf9e550ae017a1e9f1f73931c1d18474e8 *invalid-crbug-667044.webm
d3964f9dad9f60363c81b688324d95b4ec7c8038 *invalid-crbug-667044.webm.res
fd9df7f3f6992af1d7a9dde975c9a0d6f28c053d *invalid-bug-1443.ivf
fd3020fa6e9ca5966206738654c97dec313b0a95 *invalid-bug-1443.ivf.res
1a0e405606939f2febab1a21b30c37cb8f2c8cb1 *invalid-token-partition.ivf
90a8a95e7024f015b87f5483a65036609b3d1b74 *invalid-token-partition.ivf.res
17696cd21e875f1d6e5d418cbf89feab02c8850a *vp90-2-22-svc_1280x720_1.webm
e2f9e1e47a791b4e939a9bdc50bf7a25b3761f77 *vp90-2-22-svc_1280x720_1.webm.md5
a0fbbbc5dd50fd452096f4455a58c1a8c9f66697 *invalid-vp80-00-comprehensive-s17661_r01-05_b6-.ivf
a61774cf03fc584bd9f0904fc145253bb8ea6c4c *invalid-vp80-00-comprehensive-s17661_r01-05_b6-.ivf.res
894fae3afee0290546590823974203ab4b8abd95 *crbug-1539.rawfile
f1026c03efd5da21b381c8eb21f0d64e6d7e4ba3 *invalid-crbug-1558.ivf
eb198c25f861c3fe2cbd310de11eb96843019345 *invalid-crbug-1558.ivf.res
c62b005a9fd32c36a1b3f67de6840330f9915e34 *invalid-crbug-1562.ivf
f0cd8389948ad16085714d96567612136f6a46c5 *invalid-crbug-1562.ivf.res
bac455906360b45338a16dd626ac5f19bc36a307 *desktop_office1.1280_720-020.yuv
094be4b80fa30bd227149ea16ab6476d549ea092 *slides_code_term_web_plot.1920_1080.yuv

View File

@ -1,4 +1,6 @@
LIBVPX_TEST_SRCS-yes += acm_random.h
LIBVPX_TEST_SRCS-yes += bench.h
LIBVPX_TEST_SRCS-yes += bench.cc
LIBVPX_TEST_SRCS-yes += buffer.h
LIBVPX_TEST_SRCS-yes += clear_system_state.h
LIBVPX_TEST_SRCS-yes += codec_factory.h
@ -22,7 +24,8 @@ LIBVPX_TEST_SRCS-$(CONFIG_ENCODERS) += ../y4minput.h ../y4minput.c
LIBVPX_TEST_SRCS-$(CONFIG_ENCODERS) += altref_test.cc
LIBVPX_TEST_SRCS-$(CONFIG_ENCODERS) += aq_segment_test.cc
LIBVPX_TEST_SRCS-$(CONFIG_ENCODERS) += alt_ref_aq_segment_test.cc
LIBVPX_TEST_SRCS-$(CONFIG_ENCODERS) += datarate_test.cc
LIBVPX_TEST_SRCS-$(CONFIG_ENCODERS) += vp8_datarate_test.cc
LIBVPX_TEST_SRCS-$(CONFIG_ENCODERS) += vp9_datarate_test.cc
LIBVPX_TEST_SRCS-$(CONFIG_ENCODERS) += encode_api_test.cc
LIBVPX_TEST_SRCS-$(CONFIG_ENCODERS) += error_resilience_test.cc
LIBVPX_TEST_SRCS-$(CONFIG_ENCODERS) += i420_video_source.h
@ -46,9 +49,15 @@ LIBVPX_TEST_SRCS-$(CONFIG_VP9_ENCODER) += cpu_speed_test.cc
LIBVPX_TEST_SRCS-$(CONFIG_VP9_ENCODER) += frame_size_tests.cc
LIBVPX_TEST_SRCS-$(CONFIG_VP9_ENCODER) += vp9_lossless_test.cc
LIBVPX_TEST_SRCS-$(CONFIG_VP9_ENCODER) += vp9_end_to_end_test.cc
LIBVPX_TEST_SRCS-$(CONFIG_VP9_ENCODER) += decode_corrupted.cc
LIBVPX_TEST_SRCS-$(CONFIG_VP9_ENCODER) += vp9_ethread_test.cc
LIBVPX_TEST_SRCS-$(CONFIG_VP9_ENCODER) += vp9_motion_vector_test.cc
LIBVPX_TEST_SRCS-$(CONFIG_VP9_ENCODER) += level_test.cc
LIBVPX_TEST_SRCS-$(CONFIG_VP9_ENCODER) += svc_datarate_test.cc
LIBVPX_TEST_SRCS-$(CONFIG_VP9_ENCODER) += svc_test.cc
LIBVPX_TEST_SRCS-$(CONFIG_VP9_ENCODER) += svc_test.h
LIBVPX_TEST_SRCS-$(CONFIG_VP9_ENCODER) += svc_end_to_end_test.cc
LIBVPX_TEST_SRCS-$(CONFIG_VP9_ENCODER) += timestamp_test.cc
LIBVPX_TEST_SRCS-yes += decode_test_driver.cc
LIBVPX_TEST_SRCS-yes += decode_test_driver.h
@ -67,6 +76,7 @@ LIBWEBM_PARSER_SRCS += ../third_party/libwebm/mkvparser/mkvparser.cc
LIBWEBM_PARSER_SRCS += ../third_party/libwebm/mkvparser/mkvreader.cc
LIBWEBM_PARSER_SRCS += ../third_party/libwebm/mkvparser/mkvparser.h
LIBWEBM_PARSER_SRCS += ../third_party/libwebm/mkvparser/mkvreader.h
LIBWEBM_PARSER_SRCS += ../third_party/libwebm/common/webmids.h
LIBVPX_TEST_SRCS-$(CONFIG_DECODERS) += $(LIBWEBM_PARSER_SRCS)
LIBVPX_TEST_SRCS-$(CONFIG_DECODERS) += ../tools_common.h
LIBVPX_TEST_SRCS-$(CONFIG_DECODERS) += ../webmdec.cc
@ -161,7 +171,7 @@ LIBVPX_TEST_SRCS-$(CONFIG_VP9_ENCODER) += hadamard_test.cc
LIBVPX_TEST_SRCS-$(CONFIG_VP9_ENCODER) += minmax_test.cc
LIBVPX_TEST_SRCS-$(CONFIG_VP9_ENCODER) += vp9_scale_test.cc
ifneq ($(CONFIG_REALTIME_ONLY),yes)
LIBVPX_TEST_SRCS-$(CONFIG_VP9_ENCODER) += temporal_filter_test.cc
LIBVPX_TEST_SRCS-$(CONFIG_VP9_ENCODER) += yuv_temporal_filter_test.cc
endif
LIBVPX_TEST_SRCS-$(CONFIG_VP9_ENCODER) += variance_test.cc
LIBVPX_TEST_SRCS-$(CONFIG_VP9_ENCODER) += vp9_block_error_test.cc
@ -169,7 +179,6 @@ LIBVPX_TEST_SRCS-$(CONFIG_VP9_ENCODER) += vp9_quantize_test.cc
LIBVPX_TEST_SRCS-$(CONFIG_VP9_ENCODER) += vp9_subtract_test.cc
ifeq ($(CONFIG_VP9_ENCODER),yes)
LIBVPX_TEST_SRCS-$(CONFIG_SPATIAL_SVC) += svc_test.cc
LIBVPX_TEST_SRCS-$(CONFIG_INTERNAL_STATS) += blockiness_test.cc
LIBVPX_TEST_SRCS-$(CONFIG_INTERNAL_STATS) += consistency_test.cc
endif

Some files were not shown because too many files have changed in this diff Show More