Compare commits
1 Commits
Author | SHA1 | Date | |
---|---|---|---|
|
3219aac9df |
@ -1,12 +1,12 @@
|
||||
---
|
||||
Language: Cpp
|
||||
# BasedOnStyle: Google
|
||||
# Generated with clang-format 5.0.0
|
||||
# Generated with clang-format 3.8.1
|
||||
AccessModifierOffset: -1
|
||||
AlignAfterOpenBracket: Align
|
||||
AlignConsecutiveAssignments: false
|
||||
AlignConsecutiveDeclarations: false
|
||||
AlignEscapedNewlines: Left
|
||||
AlignEscapedNewlinesLeft: true
|
||||
AlignOperands: true
|
||||
AlignTrailingComments: true
|
||||
AllowAllParametersOfDeclarationOnNextLine: true
|
||||
@ -33,20 +33,12 @@ BraceWrapping:
|
||||
BeforeCatch: false
|
||||
BeforeElse: false
|
||||
IndentBraces: false
|
||||
SplitEmptyFunction: true
|
||||
SplitEmptyRecord: true
|
||||
SplitEmptyNamespace: true
|
||||
BreakBeforeBinaryOperators: None
|
||||
BreakBeforeBraces: Attach
|
||||
BreakBeforeInheritanceComma: false
|
||||
BreakBeforeTernaryOperators: true
|
||||
BreakConstructorInitializersBeforeComma: false
|
||||
BreakConstructorInitializers: BeforeColon
|
||||
BreakAfterJavaFieldAnnotations: false
|
||||
BreakStringLiterals: true
|
||||
ColumnLimit: 80
|
||||
CommentPragmas: '^ IWYU pragma:'
|
||||
CompactNamespaces: false
|
||||
ConstructorInitializerAllOnOneLineOrOnePerLine: false
|
||||
ConstructorInitializerIndentWidth: 4
|
||||
ContinuationIndentWidth: 4
|
||||
@ -54,11 +46,7 @@ Cpp11BracedListStyle: false
|
||||
DerivePointerAlignment: false
|
||||
DisableFormat: false
|
||||
ExperimentalAutoDetectBinPacking: false
|
||||
FixNamespaceComments: true
|
||||
ForEachMacros:
|
||||
- foreach
|
||||
- Q_FOREACH
|
||||
- BOOST_FOREACH
|
||||
ForEachMacros: [ foreach, Q_FOREACH, BOOST_FOREACH ]
|
||||
IncludeCategories:
|
||||
- Regex: '^<.*\.h>'
|
||||
Priority: 1
|
||||
@ -66,12 +54,9 @@ IncludeCategories:
|
||||
Priority: 2
|
||||
- Regex: '.*'
|
||||
Priority: 3
|
||||
IncludeIsMainRegex: '([-_](test|unittest))?$'
|
||||
IndentCaseLabels: true
|
||||
IndentWidth: 2
|
||||
IndentWrappedFunctionNames: false
|
||||
JavaScriptQuotes: Leave
|
||||
JavaScriptWrapImports: true
|
||||
KeepEmptyLinesAtTheStartOfBlocks: false
|
||||
MacroBlockBegin: ''
|
||||
MacroBlockEnd: ''
|
||||
@ -80,7 +65,6 @@ NamespaceIndentation: None
|
||||
ObjCBlockIndentWidth: 2
|
||||
ObjCSpaceAfterProperty: false
|
||||
ObjCSpaceBeforeProtocolList: false
|
||||
PenaltyBreakAssignment: 2
|
||||
PenaltyBreakBeforeFirstCallParameter: 1
|
||||
PenaltyBreakComment: 300
|
||||
PenaltyBreakFirstLessLess: 120
|
||||
@ -90,9 +74,7 @@ PenaltyReturnTypeOnItsOwnLine: 200
|
||||
PointerAlignment: Right
|
||||
ReflowComments: true
|
||||
SortIncludes: false
|
||||
SortUsingDeclarations: true
|
||||
SpaceAfterCStyleCast: false
|
||||
SpaceAfterTemplateKeyword: true
|
||||
SpaceBeforeAssignmentOperators: true
|
||||
SpaceBeforeParens: ControlStatements
|
||||
SpaceInEmptyParentheses: false
|
||||
|
5
.mailmap
5
.mailmap
@ -3,7 +3,6 @@ Aℓex Converse <aconverse@google.com>
|
||||
Aℓex Converse <aconverse@google.com> <alex.converse@gmail.com>
|
||||
Alexis Ballier <aballier@gentoo.org> <alexis.ballier@gmail.com>
|
||||
Alpha Lam <hclam@google.com> <hclam@chromium.org>
|
||||
Chris Cunningham <chcunningham@chromium.org>
|
||||
Daniele Castagna <dcastagna@chromium.org> <dcastagna@google.com>
|
||||
Deb Mukherjee <debargha@google.com>
|
||||
Erik Niemeyer <erik.a.niemeyer@intel.com> <erik.a.niemeyer@gmail.com>
|
||||
@ -22,21 +21,17 @@ Marco Paniconi <marpan@google.com>
|
||||
Marco Paniconi <marpan@google.com> <marpan@chromium.org>
|
||||
Pascal Massimino <pascal.massimino@gmail.com>
|
||||
Paul Wilkins <paulwilkins@google.com>
|
||||
Peter Boström <pbos@chromium.org> <pbos@google.com>
|
||||
Peter de Rivaz <peter.derivaz@gmail.com>
|
||||
Peter de Rivaz <peter.derivaz@gmail.com> <peter.derivaz@argondesign.com>
|
||||
Ralph Giles <giles@xiph.org> <giles@entropywave.com>
|
||||
Ralph Giles <giles@xiph.org> <giles@mozilla.com>
|
||||
Ronald S. Bultje <rsbultje@gmail.com> <rbultje@google.com>
|
||||
Sami Pietilä <samipietila@google.com>
|
||||
Shiyou Yin <yinshiyou-hf@loongson.cn>
|
||||
Tamar Levy <tamar.levy@intel.com>
|
||||
Tamar Levy <tamar.levy@intel.com> <levytamar82@gmail.com>
|
||||
Tero Rintaluoma <teror@google.com> <tero.rintaluoma@on2.com>
|
||||
Timothy B. Terriberry <tterribe@xiph.org> <tterriberry@mozilla.com>
|
||||
Tom Finegan <tomfinegan@google.com>
|
||||
Tom Finegan <tomfinegan@google.com> <tomfinegan@chromium.org>
|
||||
Urvang Joshi <urvang@google.com> <urvang@chromium.org>
|
||||
Yaowu Xu <yaowu@google.com> <adam@xuyaowu.com>
|
||||
Yaowu Xu <yaowu@google.com> <yaowu@xuyaowu.com>
|
||||
Yaowu Xu <yaowu@google.com> <Yaowu Xu>
|
||||
|
29
AUTHORS
29
AUTHORS
@ -3,13 +3,11 @@
|
||||
|
||||
Aaron Watry <awatry@gmail.com>
|
||||
Abo Talib Mahfoodh <ab.mahfoodh@gmail.com>
|
||||
Adam Xu <adam@xuyaowu.com>
|
||||
Adrian Grange <agrange@google.com>
|
||||
Aℓex Converse <aconverse@google.com>
|
||||
Ahmad Sharif <asharif@google.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>
|
||||
Alexis Ballier <aballier@gentoo.org>
|
||||
Alok Ahuja <waveletcoeff@gmail.com>
|
||||
Alpha Lam <hclam@google.com>
|
||||
@ -17,7 +15,6 @@ A.Mahfoodh <ab.mahfoodh@gmail.com>
|
||||
Ami Fischman <fischman@chromium.org>
|
||||
Andoni Morales Alastruey <ylatuya@gmail.com>
|
||||
Andres Mejia <mcitadel@gmail.com>
|
||||
Andrew Lewis <andrewlewis@google.com>
|
||||
Andrew Russell <anrussell@google.com>
|
||||
Angie Chiang <angiebird@google.com>
|
||||
Aron Rosenberg <arosenberg@logitech.com>
|
||||
@ -25,14 +22,11 @@ Attila Nagy <attilanagy@google.com>
|
||||
Brion Vibber <bvibber@wikimedia.org>
|
||||
changjun.yang <changjun.yang@intel.com>
|
||||
Charles 'Buck' Krasic <ckrasic@google.com>
|
||||
Cheng Chen <chengchen@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>
|
||||
Deb Mukherjee <debargha@google.com>
|
||||
Deepa K G <deepa.kg@ittiam.com>
|
||||
Dim Temp <dimtemp0@gmail.com>
|
||||
Dmitry Kovalev <dkovalev@google.com>
|
||||
Dragan Mrdjan <dmrdjan@mips.com>
|
||||
@ -43,21 +37,17 @@ Fabio Pedretti <fabio.ped@libero.it>
|
||||
Frank Galligan <fgalligan@google.com>
|
||||
Fredrik Söderquist <fs@opera.com>
|
||||
Fritz Koenig <frkoenig@google.com>
|
||||
Gabriel Marin <gmx@chromium.org>
|
||||
Gaute Strokkenes <gaute.strokkenes@broadcom.com>
|
||||
Geza Lore <gezalore@gmail.com>
|
||||
Ghislain MARY <ghislainmary2@gmail.com>
|
||||
Giuseppe Scrivano <gscrivano@gnu.org>
|
||||
Gordana Cmiljanovic <gordana.cmiljanovic@imgtec.com>
|
||||
Gregor Jasny <gjasny@gmail.com>
|
||||
Guillaume Martres <gmartres@google.com>
|
||||
Guillermo Ballester Valor <gbvalor@gmail.com>
|
||||
Hangyu Kuang <hkuang@google.com>
|
||||
Hanno Böck <hanno@hboeck.de>
|
||||
Han Shen <shenhan@google.com>
|
||||
Henrik Lundin <hlundin@google.com>
|
||||
Hui Su <huisu@google.com>
|
||||
Ivan Krasin <krasin@chromium.org>
|
||||
Ivan Maltz <ivanmaltz@google.com>
|
||||
Jacek Caban <cjacek@gmail.com>
|
||||
Jacky Chen <jackychen@google.com>
|
||||
@ -71,7 +61,6 @@ Jean-Yves Avenard <jyavenard@mozilla.com>
|
||||
Jeff Faust <jfaust@google.com>
|
||||
Jeff Muizelaar <jmuizelaar@mozilla.com>
|
||||
Jeff Petkau <jpet@chromium.org>
|
||||
Jerome Jiang <jianj@google.com>
|
||||
Jia Jia <jia.jia@linaro.org>
|
||||
Jian Zhou <zhoujian@google.com>
|
||||
Jim Bankoski <jimbankoski@google.com>
|
||||
@ -88,7 +77,6 @@ Justin Clift <justin@salasaga.org>
|
||||
Justin Lebar <justin.lebar@gmail.com>
|
||||
Kaustubh Raste <kaustubh.raste@imgtec.com>
|
||||
KO Myung-Hun <komh@chollian.net>
|
||||
Kyle Siefring <kylesiefring@gmail.com>
|
||||
Lawrence Velázquez <larryv@macports.org>
|
||||
Linfeng Zhang <linfengz@google.com>
|
||||
Lou Quillio <louquillio@google.com>
|
||||
@ -104,12 +92,8 @@ Michael Kohler <michaelkohler@live.com>
|
||||
Mike Frysinger <vapier@chromium.org>
|
||||
Mike Hommey <mhommey@mozilla.com>
|
||||
Mikhal Shemer <mikhal@google.com>
|
||||
Min Chen <chenm003@gmail.com>
|
||||
Minghai Shang <minghai@google.com>
|
||||
Min Ye <yeemmi@google.com>
|
||||
Moriyoshi Koizumi <mozo@mozo.jp>
|
||||
Morton Jonuschat <yabawock@gmail.com>
|
||||
Nathan E. Egge <negge@mozilla.com>
|
||||
Nico Weber <thakis@chromium.org>
|
||||
Parag Salasakar <img.mips1@gmail.com>
|
||||
Pascal Massimino <pascal.massimino@gmail.com>
|
||||
@ -118,22 +102,16 @@ Paul Wilkins <paulwilkins@google.com>
|
||||
Pavol Rusnak <stick@gk2.sk>
|
||||
Paweł Hajdan <phajdan@google.com>
|
||||
Pengchong Jin <pengchong@google.com>
|
||||
Peter Boström <pbos@chromium.org>
|
||||
Peter Collingbourne <pcc@chromium.org>
|
||||
Peter de Rivaz <peter.derivaz@gmail.com>
|
||||
Philip Jägenstedt <philipj@opera.com>
|
||||
Priit Laes <plaes@plaes.org>
|
||||
Rafael Ávila de Espíndola <rafael.espindola@gmail.com>
|
||||
Rafaël Carré <funman@videolan.org>
|
||||
Rafael de Lucena Valle <rafaeldelucena@gmail.com>
|
||||
Rahul Chaudhry <rahulchaudhry@google.com>
|
||||
Ralph Giles <giles@xiph.org>
|
||||
Ranjit Kumar Tulabandu <ranjit.tulabandu@ittiam.com>
|
||||
Rob Bradford <rob@linux.intel.com>
|
||||
Ronald S. Bultje <rsbultje@gmail.com>
|
||||
Rui Ueyama <ruiu@google.com>
|
||||
Sami Pietilä <samipietila@google.com>
|
||||
Sarah Parker <sarahparker@google.com>
|
||||
Sasi Inguva <isasi@google.com>
|
||||
Scott Graham <scottmg@chromium.org>
|
||||
Scott LaVarnway <slavarnway@google.com>
|
||||
@ -141,11 +119,9 @@ Sean McGovern <gseanmcg@gmail.com>
|
||||
Sergey Kolomenkin <kolomenkin@gmail.com>
|
||||
Sergey Ulanov <sergeyu@chromium.org>
|
||||
Shimon Doodkin <helpmepro1@gmail.com>
|
||||
Shiyou Yin <yinshiyou-hf@loongson.cn>
|
||||
Shunyao Li <shunyaoli@google.com>
|
||||
Stefan Holmer <holmer@google.com>
|
||||
Suman Sunkara <sunkaras@google.com>
|
||||
Sylvestre Ledru <sylvestre@mozilla.com>
|
||||
Taekhyun Kim <takim@nvidia.com>
|
||||
Takanori MATSUURA <t.matsuu@gmail.com>
|
||||
Tamar Levy <tamar.levy@intel.com>
|
||||
@ -155,10 +131,7 @@ Thijs Vermeir <thijsvermeir@gmail.com>
|
||||
Tim Kopp <tkopp@google.com>
|
||||
Timothy B. Terriberry <tterribe@xiph.org>
|
||||
Tom Finegan <tomfinegan@google.com>
|
||||
Tristan Matthews <le.businessman@gmail.com>
|
||||
Urvang Joshi <urvang@google.com>
|
||||
Vignesh Venkatasubramanian <vigneshv@google.com>
|
||||
Vlad Tsyrklevich <vtsyrklevich@chromium.org>
|
||||
Yaowu Xu <yaowu@google.com>
|
||||
Yi Luo <luoyi@google.com>
|
||||
Yongzhe Wang <yongzhe@google.com>
|
||||
|
41
CHANGELOG
41
CHANGELOG
@ -1,44 +1,3 @@
|
||||
2017-01-04 v1.7.0 "Mandarin Duck"
|
||||
This release focused on high bit depth performance (10/12 bit) and vp9
|
||||
encoding improvements.
|
||||
|
||||
- Upgrading:
|
||||
This release is ABI incompatible due to new vp9 encoder features.
|
||||
|
||||
Frame parallel decoding for vp9 has been removed.
|
||||
|
||||
- Enhancements:
|
||||
vp9 encoding supports additional threads with --row-mt. This can be greater
|
||||
than the number of tiles.
|
||||
|
||||
Two new vp9 encoder options have been added:
|
||||
--corpus-complexity
|
||||
--tune-content=film
|
||||
|
||||
Additional tooling for respecting the vp9 "level" profiles has been added.
|
||||
|
||||
- Bug fixes:
|
||||
A variety of fuzzing issues.
|
||||
vp8 threading fix for ARM.
|
||||
Codec control VP9_SET_SKIP_LOOP_FILTER fixed.
|
||||
Reject invalid multi resolution configurations.
|
||||
|
||||
2017-01-09 v1.6.1 "Long Tailed Duck"
|
||||
This release improves upon the VP9 encoder and speeds up the encoding and
|
||||
decoding processes.
|
||||
|
||||
- Upgrading:
|
||||
This release is ABI compatible with 1.6.0.
|
||||
|
||||
- Enhancements:
|
||||
Faster VP9 encoding and decoding.
|
||||
High bit depth builds now provide similar speed for 8 bit encode and decode
|
||||
for x86 targets. Other platforms and higher bit depth improvements are in
|
||||
progress.
|
||||
|
||||
- Bug Fixes:
|
||||
A variety of fuzzing issues.
|
||||
|
||||
2016-07-20 v1.6.0 "Khaki Campbell Duck"
|
||||
This release improves upon the VP9 encoder and speeds up the encoding and
|
||||
decoding processes.
|
||||
|
45
README
45
README
@ -1,4 +1,4 @@
|
||||
README - 24 January 2018
|
||||
README - 20 July 2016
|
||||
|
||||
Welcome to the WebM VP8/VP9 Codec SDK!
|
||||
|
||||
@ -9,26 +9,22 @@ COMPILING THE APPLICATIONS/LIBRARIES:
|
||||
|
||||
1. Prerequisites
|
||||
|
||||
* 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
|
||||
* 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
|
||||
have this package, the install-docs option will be disabled.
|
||||
* Downloading the data for the unit tests requires curl[5] and sha1sum.
|
||||
* Downloading the data for the unit tests requires curl[4] 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[6]. These requirements are optional if not running the unit
|
||||
source[5]. These requirements are optional if not running the unit
|
||||
tests.
|
||||
|
||||
[1]: http://www.tortall.net/projects/yasm
|
||||
[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]: http://www.cygwin.com
|
||||
[3]: http://www.doxygen.org
|
||||
[4]: http://curl.haxx.se
|
||||
[5]: http://www.microbrew.org/tools/md5sha1sum/
|
||||
|
||||
2. Out-of-tree builds
|
||||
Out of tree builds are a supported method of building the application. For
|
||||
@ -45,22 +41,12 @@ COMPILING THE APPLICATIONS/LIBRARIES:
|
||||
used to get a list of supported options:
|
||||
$ ../libvpx/configure --help
|
||||
|
||||
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
|
||||
4. 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
|
||||
available targets is:
|
||||
|
||||
arm64-android-gcc
|
||||
arm64-darwin-gcc
|
||||
arm64-linux-gcc
|
||||
armv7-android-gcc
|
||||
@ -71,13 +57,10 @@ COMPILING THE APPLICATIONS/LIBRARIES:
|
||||
armv7-win32-vs11
|
||||
armv7-win32-vs12
|
||||
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
|
||||
x86-darwin8-gcc
|
||||
@ -90,7 +73,6 @@ COMPILING THE APPLICATIONS/LIBRARIES:
|
||||
x86-darwin13-gcc
|
||||
x86-darwin14-gcc
|
||||
x86-darwin15-gcc
|
||||
x86-darwin16-gcc
|
||||
x86-iphonesimulator-gcc
|
||||
x86-linux-gcc
|
||||
x86-linux-icc
|
||||
@ -101,7 +83,6 @@ COMPILING THE APPLICATIONS/LIBRARIES:
|
||||
x86-win32-vs11
|
||||
x86-win32-vs12
|
||||
x86-win32-vs14
|
||||
x86-win32-vs15
|
||||
x86_64-android-gcc
|
||||
x86_64-darwin9-gcc
|
||||
x86_64-darwin10-gcc
|
||||
@ -110,7 +91,6 @@ COMPILING THE APPLICATIONS/LIBRARIES:
|
||||
x86_64-darwin13-gcc
|
||||
x86_64-darwin14-gcc
|
||||
x86_64-darwin15-gcc
|
||||
x86_64-darwin16-gcc
|
||||
x86_64-iphonesimulator-gcc
|
||||
x86_64-linux-gcc
|
||||
x86_64-linux-icc
|
||||
@ -120,7 +100,6 @@ COMPILING THE APPLICATIONS/LIBRARIES:
|
||||
x86_64-win64-vs11
|
||||
x86_64-win64-vs12
|
||||
x86_64-win64-vs14
|
||||
x86_64-win64-vs15
|
||||
generic-gnu
|
||||
|
||||
The generic-gnu target, in conjunction with the CROSS environment variable,
|
||||
@ -136,7 +115,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.
|
||||
|
||||
6. Configuration errors
|
||||
5. 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.
|
||||
|
2
build/.gitattributes
vendored
Normal file
2
build/.gitattributes
vendored
Normal file
@ -0,0 +1,2 @@
|
||||
*-vs8/*.rules -crlf
|
||||
*-msvs/*.rules -crlf
|
1
build/.gitignore
vendored
Normal file
1
build/.gitignore
vendored
Normal file
@ -0,0 +1 @@
|
||||
x86*-win32-vs*
|
@ -64,9 +64,6 @@ CONFIG_DIR := $(LOCAL_PATH)/
|
||||
LIBVPX_PATH := $(LOCAL_PATH)/libvpx
|
||||
ASM_CNV_PATH_LOCAL := $(TARGET_ARCH_ABI)/ads2gas
|
||||
ASM_CNV_PATH := $(LOCAL_PATH)/$(ASM_CNV_PATH_LOCAL)
|
||||
ifneq ($(V),1)
|
||||
qexec := @
|
||||
endif
|
||||
|
||||
# Use the makefiles generated by upstream configure to determine which files to
|
||||
# build. Also set any architecture-specific flags.
|
||||
@ -106,8 +103,8 @@ LOCAL_ASMFLAGS := -I$(LIBVPX_PATH)
|
||||
|
||||
.PRECIOUS: %.asm.S
|
||||
$(ASM_CNV_PATH)/libvpx/%.asm.S: $(LIBVPX_PATH)/%.asm
|
||||
$(qexec)mkdir -p $(dir $@)
|
||||
$(qexec)$(CONFIG_DIR)$(ASM_CONVERSION) <$< > $@
|
||||
@mkdir -p $(dir $@)
|
||||
@$(CONFIG_DIR)$(ASM_CONVERSION) <$< > $@
|
||||
|
||||
# For building *_rtcd.h, which have rules in libs.mk
|
||||
TGT_ISA:=$(word 1, $(subst -, ,$(TOOLCHAIN)))
|
||||
@ -153,27 +150,15 @@ CODEC_SRCS_ASM_ADS2GAS = $(patsubst %.S, \
|
||||
LOCAL_SRC_FILES += $(CODEC_SRCS_ASM_ADS2GAS)
|
||||
|
||||
ifeq ($(TARGET_ARCH_ABI),armeabi-v7a)
|
||||
ASM_INCLUDES := vpx_dsp/arm/idct_neon.asm.S
|
||||
CODEC_SRCS_ASM_NEON = $(foreach v, \
|
||||
$(CODEC_SRCS_ASM_ARM_ALL),\
|
||||
$(if $(findstring neon,$(v)),$(v),))
|
||||
CODEC_SRCS_ASM_NEON := $(filter-out $(addprefix %, $(ASM_INCLUDES)), \
|
||||
$(CODEC_SRCS_ASM_NEON))
|
||||
CODEC_SRCS_ASM_NEON_ADS2GAS = $(patsubst %.S, \
|
||||
$(ASM_CNV_PATH_LOCAL)/libvpx/%.S, \
|
||||
$(CODEC_SRCS_ASM_NEON))
|
||||
LOCAL_SRC_FILES += $(patsubst %.S, \
|
||||
%.S.neon, \
|
||||
$(CODEC_SRCS_ASM_NEON_ADS2GAS))
|
||||
|
||||
NEON_ASM_TARGETS = $(patsubst %.S, \
|
||||
$(ASM_CNV_PATH)/libvpx/%.S, \
|
||||
$(CODEC_SRCS_ASM_NEON))
|
||||
# add a dependency to the full path to the ads2gas output to ensure the
|
||||
# includes are converted first.
|
||||
ifneq ($(strip $(NEON_ASM_TARGETS)),)
|
||||
$(NEON_ASM_TARGETS): $(addprefix $(ASM_CNV_PATH)/libvpx/, $(ASM_INCLUDES))
|
||||
endif
|
||||
endif
|
||||
|
||||
LOCAL_CFLAGS += \
|
||||
@ -202,7 +187,7 @@ $$(rtcd_dep_template_SRCS): vpx_scale_rtcd.h
|
||||
$$(rtcd_dep_template_SRCS): vpx_dsp_rtcd.h
|
||||
|
||||
rtcd_dep_template_CONFIG_ASM_ABIS := x86 x86_64 armeabi-v7a
|
||||
ifneq ($$(findstring $(TARGET_ARCH_ABI),$$(rtcd_dep_template_CONFIG_ASM_ABIS)),)
|
||||
ifneq ($(findstring $(TARGET_ARCH_ABI),$(rtcd_dep_template_CONFIG_ASM_ABIS)),)
|
||||
$$(rtcd_dep_template_SRCS): vpx_config.asm
|
||||
endif
|
||||
endef
|
||||
@ -212,17 +197,16 @@ $(eval $(call rtcd_dep_template))
|
||||
.PHONY: clean
|
||||
clean:
|
||||
@echo "Clean: ads2gas files [$(TARGET_ARCH_ABI)]"
|
||||
$(qexec)$(RM) $(CODEC_SRCS_ASM_ADS2GAS) $(CODEC_SRCS_ASM_NEON_ADS2GAS)
|
||||
$(qexec)$(RM) -r $(ASM_CNV_PATH)
|
||||
$(qexec)$(RM) $(CLEAN-OBJS)
|
||||
@$(RM) $(CODEC_SRCS_ASM_ADS2GAS) $(CODEC_SRCS_ASM_NEON_ADS2GAS)
|
||||
@$(RM) -r $(ASM_CNV_PATH)
|
||||
@$(RM) $(CLEAN-OBJS)
|
||||
|
||||
ifeq ($(ENABLE_SHARED),1)
|
||||
LOCAL_CFLAGS += -fPIC
|
||||
include $(BUILD_SHARED_LIBRARY)
|
||||
else
|
||||
include $(BUILD_STATIC_LIBRARY)
|
||||
endif
|
||||
|
||||
ifeq ($(CONFIG_RUNTIME_CPU_DETECT),yes)
|
||||
$(call import-module,android/cpufeatures)
|
||||
$(call import-module,cpufeatures)
|
||||
endif
|
||||
|
@ -124,7 +124,6 @@ ifeq ($(TOOLCHAIN), x86-os2-gcc)
|
||||
CFLAGS += -mstackrealign
|
||||
endif
|
||||
|
||||
# x86[_64]
|
||||
$(BUILD_PFX)%_mmx.c.d: CFLAGS += -mmmx
|
||||
$(BUILD_PFX)%_mmx.c.o: CFLAGS += -mmmx
|
||||
$(BUILD_PFX)%_sse2.c.d: CFLAGS += -msse2
|
||||
@ -139,12 +138,6 @@ $(BUILD_PFX)%_avx.c.d: CFLAGS += -mavx
|
||||
$(BUILD_PFX)%_avx.c.o: CFLAGS += -mavx
|
||||
$(BUILD_PFX)%_avx2.c.d: CFLAGS += -mavx2
|
||||
$(BUILD_PFX)%_avx2.c.o: CFLAGS += -mavx2
|
||||
$(BUILD_PFX)%_avx512.c.d: CFLAGS += -mavx512f -mavx512cd -mavx512bw -mavx512dq -mavx512vl
|
||||
$(BUILD_PFX)%_avx512.c.o: CFLAGS += -mavx512f -mavx512cd -mavx512bw -mavx512dq -mavx512vl
|
||||
|
||||
# POWER
|
||||
$(BUILD_PFX)%_vsx.c.d: CFLAGS += -maltivec -mvsx
|
||||
$(BUILD_PFX)%_vsx.c.o: CFLAGS += -maltivec -mvsx
|
||||
|
||||
$(BUILD_PFX)%.c.d: %.c
|
||||
$(if $(quiet),@echo " [DEP] $@")
|
||||
|
@ -23,11 +23,9 @@ 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";
|
||||
@ -142,11 +140,7 @@ while (<STDIN>)
|
||||
|
||||
# Make function visible to linker, and make additional symbol with
|
||||
# prepended underscore
|
||||
if ($elf) {
|
||||
s/EXPORT\s+\|([\$\w]*)\|/.global $1 \n\t.type $1, function/;
|
||||
} else {
|
||||
s/EXPORT\s+\|([\$\w]*)\|/.global $1/;
|
||||
}
|
||||
s/EXPORT\s+\|([\$\w]*)\|/.global $1 \n\t.type $1, function/;
|
||||
s/IMPORT\s+\|([\$\w]*)\|/.global $1/;
|
||||
|
||||
s/EXPORT\s+([\$\w]*)/.global $1/;
|
||||
@ -187,16 +181,11 @@ while (<STDIN>)
|
||||
# eabi_attributes numerical equivalents can be found in the
|
||||
# "ARM IHI 0045C" document.
|
||||
|
||||
if ($elf) {
|
||||
# REQUIRE8 Stack is required to be 8-byte aligned
|
||||
s/\sREQUIRE8/.eabi_attribute 24, 1 \@Tag_ABI_align_needed/g;
|
||||
# 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;
|
||||
} else {
|
||||
s/\sREQUIRE8//;
|
||||
s/\sPRESERVE8//;
|
||||
}
|
||||
# PRESERVE8 Stack 8-byte align is preserved
|
||||
s/\sPRESERVE8/.eabi_attribute 25, 1 \@Tag_ABI_align_preserved/g;
|
||||
|
||||
# Use PROC and ENDP to give the symbols a .size directive.
|
||||
# This makes them show up properly in debugging tools like gdb and valgrind.
|
||||
@ -213,7 +202,7 @@ while (<STDIN>)
|
||||
my $proc;
|
||||
s/\bENDP\b/@ $&/;
|
||||
$proc = pop(@proc_stack);
|
||||
$_ = "\t.size $proc, .-$proc".$_ if ($proc and $elf);
|
||||
$_ = "\t.size $proc, .-$proc".$_ if ($proc);
|
||||
}
|
||||
|
||||
# EQU directive
|
||||
@ -236,4 +225,4 @@ while (<STDIN>)
|
||||
}
|
||||
|
||||
# Mark that this object doesn't need an executable stack.
|
||||
printf ("\t.section\t.note.GNU-stack,\"\",\%\%progbits\n") if $elf;
|
||||
printf ("\t.section\t.note.GNU-stack,\"\",\%\%progbits\n");
|
||||
|
@ -403,23 +403,6 @@ check_gcc_machine_option() {
|
||||
fi
|
||||
}
|
||||
|
||||
# tests for -m$2, -m$3, -m$4... toggling the feature given in $1.
|
||||
check_gcc_machine_options() {
|
||||
feature="$1"
|
||||
shift
|
||||
flags="-m$1"
|
||||
shift
|
||||
for opt in $*; do
|
||||
flags="$flags -m$opt"
|
||||
done
|
||||
|
||||
if enabled gcc && ! disabled "$feature" && ! check_cflags $flags; then
|
||||
RTCD_OPTIONS="${RTCD_OPTIONS}--disable-$feature "
|
||||
else
|
||||
soft_enable "$feature"
|
||||
fi
|
||||
}
|
||||
|
||||
write_common_config_banner() {
|
||||
print_webm_license config.mk "##" ""
|
||||
echo '# This file automatically generated by configure. Do not edit!' >> config.mk
|
||||
@ -691,6 +674,7 @@ check_xcode_minimum_version() {
|
||||
process_common_toolchain() {
|
||||
if [ -z "$toolchain" ]; then
|
||||
gcctarget="${CHOST:-$(gcc -dumpmachine 2> /dev/null)}"
|
||||
|
||||
# detect tgt_isa
|
||||
case "$gcctarget" in
|
||||
aarch64*)
|
||||
@ -713,18 +697,6 @@ process_common_toolchain() {
|
||||
*sparc*)
|
||||
tgt_isa=sparc
|
||||
;;
|
||||
power*64*-*)
|
||||
tgt_isa=ppc64
|
||||
;;
|
||||
power*)
|
||||
tgt_isa=ppc
|
||||
;;
|
||||
*mips64el*)
|
||||
tgt_isa=mips64
|
||||
;;
|
||||
*mips32el*)
|
||||
tgt_isa=mips32
|
||||
;;
|
||||
esac
|
||||
|
||||
# detect tgt_os
|
||||
@ -753,20 +725,9 @@ process_common_toolchain() {
|
||||
tgt_isa=x86_64
|
||||
tgt_os=darwin15
|
||||
;;
|
||||
*darwin16*)
|
||||
tgt_isa=x86_64
|
||||
tgt_os=darwin16
|
||||
;;
|
||||
*darwin17*)
|
||||
tgt_isa=x86_64
|
||||
tgt_os=darwin17
|
||||
;;
|
||||
x86_64*mingw32*)
|
||||
tgt_os=win64
|
||||
;;
|
||||
x86_64*cygwin*)
|
||||
tgt_os=win64
|
||||
;;
|
||||
*mingw32*|*cygwin*)
|
||||
[ -z "$tgt_isa" ] && tgt_isa=x86
|
||||
tgt_os=win32
|
||||
@ -814,9 +775,6 @@ process_common_toolchain() {
|
||||
mips*)
|
||||
enable_feature mips
|
||||
;;
|
||||
ppc*)
|
||||
enable_feature ppc
|
||||
;;
|
||||
esac
|
||||
|
||||
# PIC is probably what we want when building shared libs
|
||||
@ -885,14 +843,6 @@ process_common_toolchain() {
|
||||
add_cflags "-mmacosx-version-min=10.11"
|
||||
add_ldflags "-mmacosx-version-min=10.11"
|
||||
;;
|
||||
*-darwin16-*)
|
||||
add_cflags "-mmacosx-version-min=10.12"
|
||||
add_ldflags "-mmacosx-version-min=10.12"
|
||||
;;
|
||||
*-darwin17-*)
|
||||
add_cflags "-mmacosx-version-min=10.13"
|
||||
add_ldflags "-mmacosx-version-min=10.13"
|
||||
;;
|
||||
*-iphonesimulator-*)
|
||||
add_cflags "-miphoneos-version-min=${IOS_VERSION_MIN}"
|
||||
add_ldflags "-miphoneos-version-min=${IOS_VERSION_MIN}"
|
||||
@ -941,6 +891,7 @@ 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
|
||||
@ -967,19 +918,6 @@ 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
|
||||
;;
|
||||
*)
|
||||
check_add_asflags --defsym ARCHITECTURE=${arch_int}
|
||||
;;
|
||||
esac
|
||||
|
||||
if enabled thumb; then
|
||||
asm_conversion_cmd="$asm_conversion_cmd -thumb"
|
||||
check_add_cflags -mthumb
|
||||
@ -1206,25 +1144,12 @@ EOF
|
||||
fi
|
||||
fi
|
||||
|
||||
if enabled mmi; then
|
||||
tgt_isa=loongson3a
|
||||
check_add_ldflags -march=loongson3a
|
||||
fi
|
||||
|
||||
check_add_cflags -march=${tgt_isa}
|
||||
check_add_asflags -march=${tgt_isa}
|
||||
check_add_asflags -KPIC
|
||||
;;
|
||||
ppc*)
|
||||
link_with_cc=gcc
|
||||
setup_gnu_toolchain
|
||||
check_gcc_machine_option "vsx"
|
||||
;;
|
||||
x86*)
|
||||
case ${tgt_os} in
|
||||
android)
|
||||
soft_enable realtime_only
|
||||
;;
|
||||
win*)
|
||||
enabled gcc && add_cflags -fno-common
|
||||
;;
|
||||
@ -1277,13 +1202,6 @@ EOF
|
||||
AS=msvs
|
||||
msvs_arch_dir=x86-msvs
|
||||
vc_version=${tgt_cc##vs}
|
||||
case $vc_version in
|
||||
7|8|9|10|11|12|13|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....."
|
||||
@ -1328,12 +1246,8 @@ EOF
|
||||
elif disabled $ext; then
|
||||
disable_exts="yes"
|
||||
else
|
||||
if [ "$ext" = "avx512" ]; then
|
||||
check_gcc_machine_options $ext avx512f avx512cd avx512bw avx512dq avx512vl
|
||||
else
|
||||
# use the shortened version for the flag: sse4_1 -> sse4
|
||||
check_gcc_machine_option ${ext%_*} $ext
|
||||
fi
|
||||
# use the shortened version for the flag: sse4_1 -> sse4
|
||||
check_gcc_machine_option ${ext%_*} $ext
|
||||
fi
|
||||
done
|
||||
|
||||
@ -1359,6 +1273,7 @@ EOF
|
||||
esac
|
||||
log_echo " using $AS"
|
||||
fi
|
||||
[ "${AS##*/}" = nasm ] && add_asflags -Ox
|
||||
AS_SFX=.asm
|
||||
case ${tgt_os} in
|
||||
win32)
|
||||
@ -1367,7 +1282,7 @@ EOF
|
||||
EXE_SFX=.exe
|
||||
;;
|
||||
win64)
|
||||
add_asflags -f win64
|
||||
add_asflags -f x64
|
||||
enabled debug && add_asflags -g cv8
|
||||
EXE_SFX=.exe
|
||||
;;
|
||||
@ -1394,8 +1309,7 @@ EOF
|
||||
add_cflags ${sim_arch}
|
||||
add_ldflags ${sim_arch}
|
||||
|
||||
if [ "$(disabled external_build)" ] &&
|
||||
[ "$(show_darwin_sdk_major_version iphonesimulator)" -gt 8 ]; then
|
||||
if [ "$(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.
|
||||
@ -1502,10 +1416,6 @@ EOF
|
||||
echo "msa optimizations are available only for little endian platforms"
|
||||
disable_feature msa
|
||||
fi
|
||||
if enabled mmi; then
|
||||
echo "mmi optimizations are available only for little endian platforms"
|
||||
disable_feature mmi
|
||||
fi
|
||||
fi
|
||||
;;
|
||||
esac
|
||||
|
@ -25,7 +25,7 @@ files.
|
||||
Options:
|
||||
--help Print this message
|
||||
--out=outfile Redirect output to a file
|
||||
--ver=version Version (7,8,9,10,11,12,14,15) of visual studio to generate for
|
||||
--ver=version Version (7,8,9,10,11,12,14) of visual studio to generate for
|
||||
--target=isa-os-cc Target specifier
|
||||
EOF
|
||||
exit 1
|
||||
@ -215,7 +215,7 @@ for opt in "$@"; do
|
||||
;;
|
||||
--ver=*) vs_ver="$optval"
|
||||
case $optval in
|
||||
10|11|12|14|15)
|
||||
10|11|12|14)
|
||||
;;
|
||||
*) die Unrecognized Visual Studio Version in $opt
|
||||
;;
|
||||
@ -240,12 +240,9 @@ case "${vs_ver:-10}" in
|
||||
12) sln_vers="12.00"
|
||||
sln_vers_str="Visual Studio 2013"
|
||||
;;
|
||||
14) sln_vers="12.00"
|
||||
14) sln_vers="14.00"
|
||||
sln_vers_str="Visual Studio 2015"
|
||||
;;
|
||||
15) sln_vers="12.00"
|
||||
sln_vers_str="Visual Studio 2017"
|
||||
;;
|
||||
esac
|
||||
sfx=vcxproj
|
||||
|
||||
|
@ -34,7 +34,7 @@ Options:
|
||||
--name=project_name Name of the project (required)
|
||||
--proj-guid=GUID GUID to use for the project
|
||||
--module-def=filename File containing export definitions (for DLLs)
|
||||
--ver=version Version (10,11,12,14,15) of visual studio to generate for
|
||||
--ver=version Version (10,11,12,14) of visual studio to generate for
|
||||
--src-path-bare=dir Path to root of source tree
|
||||
-Ipath/to/include Additional include directories
|
||||
-DFLAG[=value] Preprocessor macros to define
|
||||
@ -168,7 +168,7 @@ for opt in "$@"; do
|
||||
--ver=*)
|
||||
vs_ver="$optval"
|
||||
case "$optval" in
|
||||
10|11|12|14|15)
|
||||
10|11|12|14)
|
||||
;;
|
||||
*) die Unrecognized Visual Studio Version in $opt
|
||||
;;
|
||||
@ -218,7 +218,7 @@ guid=${guid:-`generate_uuid`}
|
||||
asm_use_custom_step=false
|
||||
uses_asm=${uses_asm:-false}
|
||||
case "${vs_ver:-11}" in
|
||||
10|11|12|14|15)
|
||||
10|11|12|14)
|
||||
asm_use_custom_step=$uses_asm
|
||||
;;
|
||||
esac
|
||||
@ -347,9 +347,6 @@ generate_vcxproj() {
|
||||
if [ "$vs_ver" = "14" ]; then
|
||||
tag_content PlatformToolset v140
|
||||
fi
|
||||
if [ "$vs_ver" = "15" ]; then
|
||||
tag_content PlatformToolset v141
|
||||
fi
|
||||
tag_content CharacterSet Unicode
|
||||
if [ "$config" = "Release" ]; then
|
||||
tag_content WholeProgramOptimization true
|
||||
|
@ -35,8 +35,8 @@ ARM_TARGETS="arm64-darwin-gcc
|
||||
armv7s-darwin-gcc"
|
||||
SIM_TARGETS="x86-iphonesimulator-gcc
|
||||
x86_64-iphonesimulator-gcc"
|
||||
OSX_TARGETS="x86-darwin16-gcc
|
||||
x86_64-darwin16-gcc"
|
||||
OSX_TARGETS="x86-darwin15-gcc
|
||||
x86_64-darwin15-gcc"
|
||||
TARGETS="${ARM_TARGETS} ${SIM_TARGETS}"
|
||||
|
||||
# Configures for the target specified by $1, and invokes make with the dist
|
||||
@ -271,7 +271,7 @@ cat << EOF
|
||||
--help: Display this message and exit.
|
||||
--enable-shared: Build a dynamic framework for use on iOS 8 or later.
|
||||
--extra-configure-args <args>: Extra args to pass when configuring libvpx.
|
||||
--macosx: Uses darwin16 targets instead of iphonesimulator targets for x86
|
||||
--macosx: Uses darwin15 targets instead of iphonesimulator targets for x86
|
||||
and x86_64. Allows linking to framework when builds target MacOSX
|
||||
instead of iOS.
|
||||
--preserve-build-output: Do not delete the build directory.
|
||||
|
@ -41,15 +41,6 @@ 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'
|
||||
|
@ -1,13 +1,4 @@
|
||||
#!/usr/bin/env perl
|
||||
##
|
||||
## Copyright (c) 2017 The WebM project authors. All Rights Reserved.
|
||||
##
|
||||
## Use of this source code is governed by a BSD-style license
|
||||
## that can be found in the LICENSE file in the root of the source
|
||||
## tree. An additional intellectual property rights grant can be found
|
||||
## in the file PATENTS. All contributing project authors may
|
||||
## be found in the AUTHORS file in the root of the source tree.
|
||||
##
|
||||
|
||||
no strict 'refs';
|
||||
use warnings;
|
||||
@ -209,7 +200,6 @@ sub filter {
|
||||
sub common_top() {
|
||||
my $include_guard = uc($opts{sym})."_H_";
|
||||
print <<EOF;
|
||||
// This file is generated. Do not edit.
|
||||
#ifndef ${include_guard}
|
||||
#define ${include_guard}
|
||||
|
||||
@ -345,36 +335,6 @@ EOF
|
||||
common_bottom;
|
||||
}
|
||||
|
||||
sub ppc() {
|
||||
determine_indirection("c", @ALL_ARCHS);
|
||||
|
||||
# Assign the helper variable for each enabled extension
|
||||
foreach my $opt (@ALL_ARCHS) {
|
||||
my $opt_uc = uc $opt;
|
||||
eval "\$have_${opt}=\"flags & HAS_${opt_uc}\"";
|
||||
}
|
||||
|
||||
common_top;
|
||||
print <<EOF;
|
||||
#include "vpx_config.h"
|
||||
|
||||
#ifdef RTCD_C
|
||||
#include "vpx_ports/ppc.h"
|
||||
static void setup_rtcd_internal(void)
|
||||
{
|
||||
int flags = ppc_simd_caps();
|
||||
(void)flags;
|
||||
EOF
|
||||
|
||||
set_function_pointers("c", @ALL_ARCHS);
|
||||
|
||||
print <<EOF;
|
||||
}
|
||||
#endif
|
||||
EOF
|
||||
common_bottom;
|
||||
}
|
||||
|
||||
sub unoptimized() {
|
||||
determine_indirection "c";
|
||||
common_top;
|
||||
@ -401,10 +361,10 @@ EOF
|
||||
|
||||
&require("c");
|
||||
if ($opts{arch} eq 'x86') {
|
||||
@ALL_ARCHS = filter(qw/mmx sse sse2 sse3 ssse3 sse4_1 avx avx2 avx512/);
|
||||
@ALL_ARCHS = filter(qw/mmx sse sse2 sse3 ssse3 sse4_1 avx avx2/);
|
||||
x86;
|
||||
} elsif ($opts{arch} eq 'x86_64') {
|
||||
@ALL_ARCHS = filter(qw/mmx sse sse2 sse3 ssse3 sse4_1 avx avx2 avx512/);
|
||||
@ALL_ARCHS = filter(qw/mmx sse sse2 sse3 ssse3 sse4_1 avx avx2/);
|
||||
@REQUIRES = filter(keys %required ? keys %required : qw/mmx sse sse2/);
|
||||
&require(@REQUIRES);
|
||||
x86;
|
||||
@ -421,10 +381,6 @@ if ($opts{arch} eq 'x86') {
|
||||
@ALL_ARCHS = filter("$opts{arch}", qw/msa/);
|
||||
last;
|
||||
}
|
||||
if (/HAVE_MMI=yes/) {
|
||||
@ALL_ARCHS = filter("$opts{arch}", qw/mmi/);
|
||||
last;
|
||||
}
|
||||
}
|
||||
close CONFIG_FILE;
|
||||
mips;
|
||||
@ -434,9 +390,6 @@ if ($opts{arch} eq 'x86') {
|
||||
} elsif ($opts{arch} eq 'armv8' || $opts{arch} eq 'arm64' ) {
|
||||
@ALL_ARCHS = filter(qw/neon/);
|
||||
arm;
|
||||
} elsif ($opts{arch} =~ /^ppc/ ) {
|
||||
@ALL_ARCHS = filter(qw/vsx/);
|
||||
ppc;
|
||||
} else {
|
||||
unoptimized;
|
||||
}
|
||||
|
@ -54,6 +54,13 @@ 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.
|
||||
|
@ -60,7 +60,6 @@ if [ ${bare} ]; then
|
||||
echo "${changelog_version}${git_version_id}" > $$.tmp
|
||||
else
|
||||
cat<<EOF>$$.tmp
|
||||
// This file is generated. Do not edit.
|
||||
#define VERSION_MAJOR $major_version
|
||||
#define VERSION_MINOR $minor_version
|
||||
#define VERSION_PATCH $patch_version
|
||||
|
@ -1,4 +1,5 @@
|
||||
# This file is used by git cl to get repository specific information.
|
||||
GERRIT_HOST: True
|
||||
# This file is used by gcl to get repository specific information.
|
||||
GERRIT_HOST: chromium-review.googlesource.com
|
||||
GERRIT_PORT: 29418
|
||||
CODE_REVIEW_SERVER: chromium-review.googlesource.com
|
||||
GERRIT_SQUASH_UPLOADS: False
|
||||
|
46
configure
vendored
46
configure
vendored
@ -101,23 +101,18 @@ 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} 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-gcc"
|
||||
all_platforms="${all_platforms} armv7-win32-vs11"
|
||||
all_platforms="${all_platforms} armv7-win32-vs12"
|
||||
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"
|
||||
all_platforms="${all_platforms} x86-darwin8-gcc"
|
||||
@ -130,8 +125,6 @@ all_platforms="${all_platforms} x86-darwin12-gcc"
|
||||
all_platforms="${all_platforms} x86-darwin13-gcc"
|
||||
all_platforms="${all_platforms} x86-darwin14-gcc"
|
||||
all_platforms="${all_platforms} x86-darwin15-gcc"
|
||||
all_platforms="${all_platforms} x86-darwin16-gcc"
|
||||
all_platforms="${all_platforms} x86-darwin17-gcc"
|
||||
all_platforms="${all_platforms} x86-iphonesimulator-gcc"
|
||||
all_platforms="${all_platforms} x86-linux-gcc"
|
||||
all_platforms="${all_platforms} x86-linux-icc"
|
||||
@ -142,7 +135,6 @@ 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"
|
||||
all_platforms="${all_platforms} x86_64-darwin9-gcc"
|
||||
all_platforms="${all_platforms} x86_64-darwin10-gcc"
|
||||
@ -151,8 +143,6 @@ all_platforms="${all_platforms} x86_64-darwin12-gcc"
|
||||
all_platforms="${all_platforms} x86_64-darwin13-gcc"
|
||||
all_platforms="${all_platforms} x86_64-darwin14-gcc"
|
||||
all_platforms="${all_platforms} x86_64-darwin15-gcc"
|
||||
all_platforms="${all_platforms} x86_64-darwin16-gcc"
|
||||
all_platforms="${all_platforms} x86_64-darwin17-gcc"
|
||||
all_platforms="${all_platforms} x86_64-iphonesimulator-gcc"
|
||||
all_platforms="${all_platforms} x86_64-linux-gcc"
|
||||
all_platforms="${all_platforms} x86_64-linux-icc"
|
||||
@ -162,7 +152,6 @@ 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"
|
||||
|
||||
# all_targets is a list of all targets that can be configured
|
||||
@ -174,14 +163,11 @@ for t in ${all_targets}; do
|
||||
[ -f "${source_path}/${t}.mk" ] && enable_feature ${t}
|
||||
done
|
||||
|
||||
if ! diff --version >/dev/null; then
|
||||
die "diff missing: Try installing diffutils via your package manager."
|
||||
fi
|
||||
|
||||
if ! perl --version >/dev/null; then
|
||||
die "Perl is required to build"
|
||||
fi
|
||||
|
||||
|
||||
if [ "`cd \"${source_path}\" && pwd`" != "`pwd`" ]; then
|
||||
# test to see if source_path already configured
|
||||
if [ -f "${source_path}/vpx_config.h" ]; then
|
||||
@ -237,7 +223,6 @@ ARCH_LIST="
|
||||
mips
|
||||
x86
|
||||
x86_64
|
||||
ppc
|
||||
"
|
||||
ARCH_EXT_LIST_X86="
|
||||
mmx
|
||||
@ -248,13 +233,7 @@ ARCH_EXT_LIST_X86="
|
||||
sse4_1
|
||||
avx
|
||||
avx2
|
||||
avx512
|
||||
"
|
||||
|
||||
ARCH_EXT_LIST_LOONGSON="
|
||||
mmi
|
||||
"
|
||||
|
||||
ARCH_EXT_LIST="
|
||||
neon
|
||||
neon_asm
|
||||
@ -265,10 +244,6 @@ ARCH_EXT_LIST="
|
||||
mips64
|
||||
|
||||
${ARCH_EXT_LIST_X86}
|
||||
|
||||
vsx
|
||||
|
||||
${ARCH_EXT_LIST_LOONGSON}
|
||||
"
|
||||
HAVE_LIST="
|
||||
${ARCH_EXT_LIST}
|
||||
@ -277,8 +252,10 @@ HAVE_LIST="
|
||||
unistd_h
|
||||
"
|
||||
EXPERIMENT_LIST="
|
||||
spatial_svc
|
||||
fp_mb_stats
|
||||
emulate_hardware
|
||||
misc_fixes
|
||||
"
|
||||
CONFIG_LIST="
|
||||
dependency_tracking
|
||||
@ -333,7 +310,6 @@ CONFIG_LIST="
|
||||
better_hw_compatibility
|
||||
experimental
|
||||
size_limit
|
||||
always_adjust_bpm
|
||||
${EXPERIMENT_LIST}
|
||||
"
|
||||
CMDLINE_SELECT="
|
||||
@ -393,7 +369,6 @@ CMDLINE_SELECT="
|
||||
better_hw_compatibility
|
||||
vp9_highbitdepth
|
||||
experimental
|
||||
always_adjust_bpm
|
||||
"
|
||||
|
||||
process_cmdline() {
|
||||
@ -595,7 +570,6 @@ process_toolchain() {
|
||||
check_add_cflags -Wdeclaration-after-statement
|
||||
check_add_cflags -Wdisabled-optimization
|
||||
check_add_cflags -Wfloat-conversion
|
||||
check_add_cflags -Wparentheses-equality
|
||||
check_add_cflags -Wpointer-arith
|
||||
check_add_cflags -Wtype-limits
|
||||
check_add_cflags -Wcast-qual
|
||||
@ -609,16 +583,16 @@ process_toolchain() {
|
||||
# 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
|
||||
# these flags so add them explicitly to CFLAGS only.
|
||||
# -Wundef so add it 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
|
||||
# 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
|
||||
if ! enabled vp9_highbitdepth; then
|
||||
# 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
|
||||
fi
|
||||
fi
|
||||
|
||||
if enabled icc; then
|
||||
@ -670,7 +644,7 @@ process_toolchain() {
|
||||
gen_vcproj_cmd=${source_path}/build/make/gen_msvs_vcxproj.sh
|
||||
enabled werror && gen_vcproj_cmd="${gen_vcproj_cmd} --enable-werror"
|
||||
all_targets="${all_targets} solution"
|
||||
INLINE="__inline"
|
||||
INLINE="__forceinline"
|
||||
;;
|
||||
esac
|
||||
|
||||
|
23
examples.mk
23
examples.mk
@ -109,17 +109,18 @@ ifeq ($(CONFIG_WEBM_IO),yes)
|
||||
endif
|
||||
vpxenc.GUID = 548DEC74-7A15-4B2B-AFC3-AA102E7C25C1
|
||||
vpxenc.DESCRIPTION = Full featured encoder
|
||||
|
||||
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
|
||||
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
|
||||
|
||||
ifneq ($(CONFIG_SHARED),yes)
|
||||
EXAMPLES-$(CONFIG_VP9_ENCODER) += resize_util.c
|
||||
|
@ -151,7 +151,7 @@ static void write_ivf_frame_header(FILE *outfile,
|
||||
if (pkt->kind != VPX_CODEC_CX_FRAME_PKT) return;
|
||||
|
||||
pts = pkt->data.frame.pts;
|
||||
mem_put_le32(header, (int)pkt->data.frame.sz);
|
||||
mem_put_le32(header, pkt->data.frame.sz);
|
||||
mem_put_le32(header + 4, pts & 0xFFFFFFFF);
|
||||
mem_put_le32(header + 8, pts >> 32);
|
||||
|
||||
@ -190,7 +190,7 @@ static void set_temporal_layer_pattern(int num_temporal_layers,
|
||||
cfg->ts_layer_id[0] = 0;
|
||||
cfg->ts_layer_id[1] = 1;
|
||||
// Use 60/40 bit allocation as example.
|
||||
cfg->ts_target_bitrate[0] = (int)(0.6f * bitrate);
|
||||
cfg->ts_target_bitrate[0] = 0.6f * bitrate;
|
||||
cfg->ts_target_bitrate[1] = bitrate;
|
||||
|
||||
/* 0=L, 1=GF */
|
||||
@ -240,9 +240,9 @@ static void set_temporal_layer_pattern(int num_temporal_layers,
|
||||
cfg->ts_layer_id[1] = 2;
|
||||
cfg->ts_layer_id[2] = 1;
|
||||
cfg->ts_layer_id[3] = 2;
|
||||
// Use 45/20/35 bit allocation as example.
|
||||
cfg->ts_target_bitrate[0] = (int)(0.45f * bitrate);
|
||||
cfg->ts_target_bitrate[1] = (int)(0.65f * bitrate);
|
||||
// Use 40/20/40 bit allocation as example.
|
||||
cfg->ts_target_bitrate[0] = 0.4f * bitrate;
|
||||
cfg->ts_target_bitrate[1] = 0.6f * bitrate;
|
||||
cfg->ts_target_bitrate[2] = bitrate;
|
||||
|
||||
/* 0=L, 1=GF, 2=ARF */
|
||||
@ -294,8 +294,8 @@ int main(int argc, char **argv) {
|
||||
vpx_codec_err_t res[NUM_ENCODERS];
|
||||
|
||||
int i;
|
||||
int width;
|
||||
int height;
|
||||
long width;
|
||||
long height;
|
||||
int length_frame;
|
||||
int frame_avail;
|
||||
int got_data;
|
||||
@ -347,9 +347,9 @@ int main(int argc, char **argv) {
|
||||
|
||||
printf("Using %s\n", vpx_codec_iface_name(interface));
|
||||
|
||||
width = (int)strtol(argv[1], NULL, 0);
|
||||
height = (int)strtol(argv[2], NULL, 0);
|
||||
framerate = (int)strtol(argv[3], NULL, 0);
|
||||
width = strtol(argv[1], NULL, 0);
|
||||
height = strtol(argv[2], NULL, 0);
|
||||
framerate = strtol(argv[3], NULL, 0);
|
||||
|
||||
if (width < 16 || width % 2 || height < 16 || height % 2)
|
||||
die("Invalid resolution: %ldx%ld", width, height);
|
||||
@ -371,13 +371,12 @@ int main(int argc, char **argv) {
|
||||
|
||||
// Bitrates per spatial layer: overwrite default rates above.
|
||||
for (i = 0; i < NUM_ENCODERS; i++) {
|
||||
target_bitrate[i] = (int)strtol(argv[NUM_ENCODERS + 5 + i], NULL, 0);
|
||||
target_bitrate[i] = strtol(argv[NUM_ENCODERS + 5 + i], NULL, 0);
|
||||
}
|
||||
|
||||
// Temporal layers per spatial layers: overwrite default settings above.
|
||||
for (i = 0; i < NUM_ENCODERS; i++) {
|
||||
num_temporal_layers[i] =
|
||||
(int)strtol(argv[2 * NUM_ENCODERS + 5 + i], NULL, 0);
|
||||
num_temporal_layers[i] = strtol(argv[2 * NUM_ENCODERS + 5 + i], NULL, 0);
|
||||
if (num_temporal_layers[i] < 1 || num_temporal_layers[i] > 3)
|
||||
die("Invalid temporal layers: %d, Must be 1, 2, or 3. \n",
|
||||
num_temporal_layers);
|
||||
@ -392,9 +391,9 @@ int main(int argc, char **argv) {
|
||||
downsampled_input[i] = fopen(filename, "wb");
|
||||
}
|
||||
|
||||
key_frame_insert = (int)strtol(argv[3 * NUM_ENCODERS + 5], NULL, 0);
|
||||
key_frame_insert = strtol(argv[3 * NUM_ENCODERS + 5], NULL, 0);
|
||||
|
||||
show_psnr = (int)strtol(argv[3 * NUM_ENCODERS + 6], NULL, 0);
|
||||
show_psnr = strtol(argv[3 * NUM_ENCODERS + 6], NULL, 0);
|
||||
|
||||
/* Populate default encoder configuration */
|
||||
for (i = 0; i < NUM_ENCODERS; i++) {
|
||||
@ -461,7 +460,7 @@ int main(int argc, char **argv) {
|
||||
|
||||
// Set the number of threads per encode/spatial layer.
|
||||
// (1, 1, 1) means no encoder threading.
|
||||
cfg[0].g_threads = 1;
|
||||
cfg[0].g_threads = 2;
|
||||
cfg[1].g_threads = 1;
|
||||
cfg[2].g_threads = 1;
|
||||
|
||||
@ -470,7 +469,7 @@ int main(int argc, char **argv) {
|
||||
if (!vpx_img_alloc(&raw[i], VPX_IMG_FMT_I420, cfg[i].g_w, cfg[i].g_h, 32))
|
||||
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)
|
||||
if (raw[0].stride[VPX_PLANE_Y] == raw[0].d_w)
|
||||
read_frame_p = read_frame;
|
||||
else
|
||||
read_frame_p = read_frame_by_row;
|
||||
@ -508,11 +507,9 @@ int main(int argc, char **argv) {
|
||||
|
||||
/* Set NOISE_SENSITIVITY to do TEMPORAL_DENOISING */
|
||||
/* Enable denoising for the highest-resolution encoder. */
|
||||
if (vpx_codec_control(&codec[0], VP8E_SET_NOISE_SENSITIVITY, 1))
|
||||
if (vpx_codec_control(&codec[0], VP8E_SET_NOISE_SENSITIVITY, 4))
|
||||
die_codec(&codec[0], "Failed to set noise_sensitivity");
|
||||
if (vpx_codec_control(&codec[1], VP8E_SET_NOISE_SENSITIVITY, 1))
|
||||
die_codec(&codec[1], "Failed to set noise_sensitivity");
|
||||
for (i = 2; i < NUM_ENCODERS; i++) {
|
||||
for (i = 1; i < NUM_ENCODERS; i++) {
|
||||
if (vpx_codec_control(&codec[i], VP8E_SET_NOISE_SENSITIVITY, 0))
|
||||
die_codec(&codec[i], "Failed to set noise_sensitivity");
|
||||
}
|
||||
@ -559,8 +556,7 @@ int main(int argc, char **argv) {
|
||||
/* Write out down-sampled input. */
|
||||
length_frame = cfg[i].g_w * cfg[i].g_h * 3 / 2;
|
||||
if (fwrite(raw[i].planes[0], 1, length_frame,
|
||||
downsampled_input[NUM_ENCODERS - i - 1]) !=
|
||||
(unsigned int)length_frame) {
|
||||
downsampled_input[NUM_ENCODERS - i - 1]) != length_frame) {
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
}
|
||||
@ -621,6 +617,10 @@ int main(int argc, char **argv) {
|
||||
break;
|
||||
default: break;
|
||||
}
|
||||
printf(pkt[i]->kind == VPX_CODEC_CX_FRAME_PKT &&
|
||||
(pkt[i]->data.frame.flags & VPX_FRAME_IS_KEY)
|
||||
? "K"
|
||||
: "");
|
||||
fflush(stdout);
|
||||
}
|
||||
}
|
||||
@ -661,6 +661,7 @@ int main(int argc, char **argv) {
|
||||
write_ivf_file_header(outfile[i], &cfg[i], frame_cnt - 1);
|
||||
fclose(outfile[i]);
|
||||
}
|
||||
printf("\n");
|
||||
|
||||
return EXIT_SUCCESS;
|
||||
}
|
||||
|
@ -168,7 +168,7 @@ void usage_exit(void) {
|
||||
static void parse_command_line(int argc, const char **argv_,
|
||||
AppInput *app_input, SvcContext *svc_ctx,
|
||||
vpx_codec_enc_cfg_t *enc_cfg) {
|
||||
struct arg arg;
|
||||
struct arg arg = { 0 };
|
||||
char **argv = NULL;
|
||||
char **argi = NULL;
|
||||
char **argj = NULL;
|
||||
@ -429,9 +429,8 @@ static void set_rate_control_stats(struct RateControlStats *rc,
|
||||
rc->layer_framerate[layer] = framerate / cfg->ts_rate_decimator[tl];
|
||||
if (tl > 0) {
|
||||
rc->layer_pfb[layer] =
|
||||
1000.0 *
|
||||
(cfg->layer_target_bitrate[layer] -
|
||||
cfg->layer_target_bitrate[layer - 1]) /
|
||||
1000.0 * (cfg->layer_target_bitrate[layer] -
|
||||
cfg->layer_target_bitrate[layer - 1]) /
|
||||
(rc->layer_framerate[layer] - rc->layer_framerate[layer - 1]);
|
||||
} else {
|
||||
rc->layer_pfb[layer] = 1000.0 * cfg->layer_target_bitrate[layer] /
|
||||
@ -503,12 +502,14 @@ static void printout_rate_control_summary(struct RateControlStats *rc,
|
||||
printf("Average, rms-variance, and percent-fluct: %f %f %f \n",
|
||||
rc->avg_st_encoding_bitrate, sqrt(rc->variance_st_encoding_bitrate),
|
||||
perc_fluctuation);
|
||||
printf("Num of input, num of encoded (super) frames: %d %d \n", frame_cnt,
|
||||
tot_num_frames);
|
||||
if (frame_cnt != tot_num_frames)
|
||||
die("Error: Number of input frames not equal to output encoded frames != "
|
||||
"%d tot_num_frames = %d\n",
|
||||
frame_cnt, tot_num_frames);
|
||||
}
|
||||
|
||||
vpx_codec_err_t parse_superframe_index(const uint8_t *data, size_t data_sz,
|
||||
uint64_t sizes[8], int *count) {
|
||||
uint32_t sizes[8], int *count) {
|
||||
// A chunk ending with a byte matching 0xc0 is an invalid chunk unless
|
||||
// it is a super frame index. If the last byte of real video compression
|
||||
// data is 0xc0 the encoder must add a 0 byte. If we have the marker but
|
||||
@ -560,10 +561,9 @@ vpx_codec_err_t parse_superframe_index(const uint8_t *data, size_t data_sz,
|
||||
// bypass/flexible mode. The pattern corresponds to the pattern
|
||||
// VP9E_TEMPORAL_LAYERING_MODE_0101 (temporal_layering_mode == 2) used in
|
||||
// non-flexible mode.
|
||||
void set_frame_flags_bypass_mode(int tl, int num_spatial_layers,
|
||||
void set_frame_flags_bypass_mode(int sl, int tl, int num_spatial_layers,
|
||||
int is_key_frame,
|
||||
vpx_svc_ref_frame_config_t *ref_frame_config) {
|
||||
int sl;
|
||||
for (sl = 0; sl < num_spatial_layers; ++sl) {
|
||||
if (!tl) {
|
||||
if (!sl) {
|
||||
@ -573,8 +573,8 @@ void set_frame_flags_bypass_mode(int tl, int num_spatial_layers,
|
||||
} else {
|
||||
if (is_key_frame) {
|
||||
ref_frame_config->frame_flags[sl] =
|
||||
VP8_EFLAG_NO_REF_GF | VP8_EFLAG_NO_REF_ARF |
|
||||
VP8_EFLAG_NO_UPD_LAST | VP8_EFLAG_NO_UPD_ARF;
|
||||
VP8_EFLAG_NO_REF_LAST | VP8_EFLAG_NO_REF_ARF |
|
||||
VP8_EFLAG_NO_UPD_GF | VP8_EFLAG_NO_UPD_ARF;
|
||||
} else {
|
||||
ref_frame_config->frame_flags[sl] =
|
||||
VP8_EFLAG_NO_REF_ARF | VP8_EFLAG_NO_UPD_GF | VP8_EFLAG_NO_UPD_ARF;
|
||||
@ -588,24 +588,14 @@ void set_frame_flags_bypass_mode(int tl, int num_spatial_layers,
|
||||
} else {
|
||||
ref_frame_config->frame_flags[sl] =
|
||||
VP8_EFLAG_NO_REF_ARF | VP8_EFLAG_NO_UPD_LAST | VP8_EFLAG_NO_UPD_GF;
|
||||
if (sl == num_spatial_layers - 1)
|
||||
ref_frame_config->frame_flags[sl] =
|
||||
VP8_EFLAG_NO_UPD_ARF | VP8_EFLAG_NO_REF_ARF |
|
||||
VP8_EFLAG_NO_UPD_LAST | VP8_EFLAG_NO_UPD_GF;
|
||||
}
|
||||
}
|
||||
if (tl == 0) {
|
||||
ref_frame_config->lst_fb_idx[sl] = sl;
|
||||
if (sl) {
|
||||
if (is_key_frame) {
|
||||
ref_frame_config->lst_fb_idx[sl] = sl - 1;
|
||||
ref_frame_config->gld_fb_idx[sl] = sl;
|
||||
} else {
|
||||
ref_frame_config->gld_fb_idx[sl] = sl - 1;
|
||||
}
|
||||
} else {
|
||||
if (sl)
|
||||
ref_frame_config->gld_fb_idx[sl] = sl - 1;
|
||||
else
|
||||
ref_frame_config->gld_fb_idx[sl] = 0;
|
||||
}
|
||||
ref_frame_config->alt_fb_idx[sl] = 0;
|
||||
} else if (tl == 1) {
|
||||
ref_frame_config->lst_fb_idx[sl] = sl;
|
||||
@ -616,9 +606,9 @@ void set_frame_flags_bypass_mode(int tl, int num_spatial_layers,
|
||||
}
|
||||
|
||||
int main(int argc, const char **argv) {
|
||||
AppInput app_input;
|
||||
AppInput app_input = { 0 };
|
||||
VpxVideoWriter *writer = NULL;
|
||||
VpxVideoInfo info;
|
||||
VpxVideoInfo info = { 0 };
|
||||
vpx_codec_ctx_t codec;
|
||||
vpx_codec_enc_cfg_t enc_cfg;
|
||||
SvcContext svc_ctx;
|
||||
@ -632,7 +622,7 @@ int main(int argc, const char **argv) {
|
||||
int end_of_stream = 0;
|
||||
int frames_received = 0;
|
||||
#if OUTPUT_RC_STATS
|
||||
VpxVideoWriter *outfile[VPX_SS_MAX_LAYERS] = { NULL };
|
||||
VpxVideoWriter *outfile[VPX_TS_MAX_LAYERS] = { NULL };
|
||||
struct RateControlStats rc;
|
||||
vpx_svc_layer_id_t layer_id;
|
||||
vpx_svc_ref_frame_config_t ref_frame_config;
|
||||
@ -644,16 +634,14 @@ int main(int argc, const char **argv) {
|
||||
struct vpx_usec_timer timer;
|
||||
int64_t cx_time = 0;
|
||||
memset(&svc_ctx, 0, sizeof(svc_ctx));
|
||||
memset(&app_input, 0, sizeof(AppInput));
|
||||
memset(&info, 0, sizeof(VpxVideoInfo));
|
||||
svc_ctx.log_print = 1;
|
||||
exec_name = argv[0];
|
||||
parse_command_line(argc, argv, &app_input, &svc_ctx, &enc_cfg);
|
||||
|
||||
// Allocate image buffer
|
||||
#if CONFIG_VP9_HIGHBITDEPTH
|
||||
if (!vpx_img_alloc(&raw,
|
||||
enc_cfg.g_input_bit_depth == 8 ? VPX_IMG_FMT_I420
|
||||
: VPX_IMG_FMT_I42016,
|
||||
if (!vpx_img_alloc(&raw, enc_cfg.g_input_bit_depth == 8 ? VPX_IMG_FMT_I420
|
||||
: VPX_IMG_FMT_I42016,
|
||||
enc_cfg.g_w, enc_cfg.g_h, 32)) {
|
||||
die("Failed to allocate image %dx%d\n", enc_cfg.g_w, enc_cfg.g_h);
|
||||
}
|
||||
@ -672,10 +660,6 @@ int main(int argc, const char **argv) {
|
||||
die("Failed to initialize encoder\n");
|
||||
|
||||
#if OUTPUT_RC_STATS
|
||||
rc.window_count = 1;
|
||||
rc.window_size = 15; // Silence a static analysis warning.
|
||||
rc.avg_st_encoding_bitrate = 0.0;
|
||||
rc.variance_st_encoding_bitrate = 0.0;
|
||||
if (svc_ctx.output_rc_stat) {
|
||||
set_rate_control_stats(&rc, &enc_cfg);
|
||||
framerate = enc_cfg.g_timebase.den / enc_cfg.g_timebase.num;
|
||||
@ -694,16 +678,16 @@ int main(int argc, const char **argv) {
|
||||
die("Failed to open %s for writing\n", app_input.output_filename);
|
||||
}
|
||||
#if OUTPUT_RC_STATS
|
||||
// Write out spatial layer stream.
|
||||
// TODO(marpan/jianj): allow for writing each spatial and temporal stream.
|
||||
// For now, just write temporal layer streams.
|
||||
// TODO(wonkap): do spatial by re-writing superframe.
|
||||
if (svc_ctx.output_rc_stat) {
|
||||
for (sl = 0; sl < enc_cfg.ss_number_layers; ++sl) {
|
||||
for (tl = 0; tl < enc_cfg.ts_number_layers; ++tl) {
|
||||
char file_name[PATH_MAX];
|
||||
|
||||
snprintf(file_name, sizeof(file_name), "%s_s%d.ivf",
|
||||
app_input.output_filename, sl);
|
||||
outfile[sl] = vpx_video_writer_open(file_name, kContainerIVF, &info);
|
||||
if (!outfile[sl]) die("Failed to open %s for writing", file_name);
|
||||
snprintf(file_name, sizeof(file_name), "%s_t%d.ivf",
|
||||
app_input.output_filename, tl);
|
||||
outfile[tl] = vpx_video_writer_open(file_name, kContainerIVF, &info);
|
||||
if (!outfile[tl]) die("Failed to open %s for writing", file_name);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
@ -713,22 +697,12 @@ int main(int argc, const char **argv) {
|
||||
|
||||
if (svc_ctx.speed != -1)
|
||||
vpx_codec_control(&codec, VP8E_SET_CPUUSED, svc_ctx.speed);
|
||||
if (svc_ctx.threads) {
|
||||
vpx_codec_control(&codec, VP9E_SET_TILE_COLUMNS, get_msb(svc_ctx.threads));
|
||||
if (svc_ctx.threads > 1)
|
||||
vpx_codec_control(&codec, VP9E_SET_ROW_MT, 1);
|
||||
else
|
||||
vpx_codec_control(&codec, VP9E_SET_ROW_MT, 0);
|
||||
}
|
||||
if (svc_ctx.threads)
|
||||
vpx_codec_control(&codec, VP9E_SET_TILE_COLUMNS, (svc_ctx.threads >> 1));
|
||||
if (svc_ctx.speed >= 5 && svc_ctx.aqmode == 1)
|
||||
vpx_codec_control(&codec, VP9E_SET_AQ_MODE, 3);
|
||||
if (svc_ctx.speed >= 5)
|
||||
vpx_codec_control(&codec, VP8E_SET_STATIC_THRESHOLD, 1);
|
||||
vpx_codec_control(&codec, VP8E_SET_MAX_INTRA_BITRATE_PCT, 900);
|
||||
|
||||
vpx_codec_control(&codec, VP9E_SET_SVC_INTER_LAYER_PRED, 0);
|
||||
|
||||
vpx_codec_control(&codec, VP9E_SET_NOISE_SENSITIVITY, 0);
|
||||
|
||||
// Encode frames
|
||||
while (!end_of_stream) {
|
||||
@ -757,9 +731,7 @@ int main(int argc, const char **argv) {
|
||||
// the encode for the whole superframe. The encoder will internally loop
|
||||
// over all the spatial layers for the current superframe.
|
||||
vpx_codec_control(&codec, VP9E_SET_SVC_LAYER_ID, &layer_id);
|
||||
// TODO(jianj): Fix the parameter passing for "is_key_frame" in
|
||||
// set_frame_flags_bypass_model() for case of periodic key frames.
|
||||
set_frame_flags_bypass_mode(layer_id.temporal_layer_id,
|
||||
set_frame_flags_bypass_mode(sl, layer_id.temporal_layer_id,
|
||||
svc_ctx.spatial_layers, frame_cnt == 0,
|
||||
&ref_frame_config);
|
||||
vpx_codec_control(&codec, VP9E_SET_SVC_REF_FRAME_CONFIG,
|
||||
@ -770,17 +742,6 @@ int main(int argc, const char **argv) {
|
||||
++rc.layer_input_frames[sl * enc_cfg.ts_number_layers +
|
||||
layer_id.temporal_layer_id];
|
||||
}
|
||||
} else {
|
||||
// For the fixed pattern SVC, temporal layer is given by superframe count.
|
||||
unsigned int tl = 0;
|
||||
if (enc_cfg.ts_number_layers == 2)
|
||||
tl = (frame_cnt % 2 != 0);
|
||||
else if (enc_cfg.ts_number_layers == 3) {
|
||||
if (frame_cnt % 2 != 0) tl = 2;
|
||||
if ((frame_cnt > 1) && ((frame_cnt - 2) % 4 == 0)) tl = 1;
|
||||
}
|
||||
for (sl = 0; sl < enc_cfg.ss_number_layers; ++sl)
|
||||
++rc.layer_input_frames[sl * enc_cfg.ts_number_layers + tl];
|
||||
}
|
||||
|
||||
vpx_usec_timer_start(&timer);
|
||||
@ -790,6 +751,7 @@ int main(int argc, const char **argv) {
|
||||
vpx_usec_timer_mark(&timer);
|
||||
cx_time += vpx_usec_timer_elapsed(&timer);
|
||||
|
||||
printf("%s", vpx_svc_get_message(&svc_ctx));
|
||||
fflush(stdout);
|
||||
if (res != VPX_CODEC_OK) {
|
||||
die_codec(&codec, "Failed to encode frame");
|
||||
@ -801,64 +763,51 @@ int main(int argc, const char **argv) {
|
||||
SvcInternal_t *const si = (SvcInternal_t *)svc_ctx.internal;
|
||||
if (cx_pkt->data.frame.sz > 0) {
|
||||
#if OUTPUT_RC_STATS
|
||||
uint64_t sizes[8];
|
||||
uint64_t sizes_parsed[8];
|
||||
uint32_t sizes[8];
|
||||
int count = 0;
|
||||
vp9_zero(sizes);
|
||||
vp9_zero(sizes_parsed);
|
||||
#endif
|
||||
vpx_video_writer_write_frame(writer, cx_pkt->data.frame.buf,
|
||||
cx_pkt->data.frame.sz,
|
||||
cx_pkt->data.frame.pts);
|
||||
#if OUTPUT_RC_STATS
|
||||
// TODO(marpan): Put this (to line728) in separate function.
|
||||
// TODO(marpan/wonkap): Put this (to line728) in separate function.
|
||||
if (svc_ctx.output_rc_stat) {
|
||||
vpx_codec_control(&codec, VP9E_GET_SVC_LAYER_ID, &layer_id);
|
||||
parse_superframe_index(cx_pkt->data.frame.buf,
|
||||
cx_pkt->data.frame.sz, sizes_parsed,
|
||||
&count);
|
||||
if (enc_cfg.ss_number_layers == 1)
|
||||
sizes[0] = cx_pkt->data.frame.sz;
|
||||
cx_pkt->data.frame.sz, sizes, &count);
|
||||
// Note computing input_layer_frames here won't account for frame
|
||||
// drops in rate control stats.
|
||||
// TODO(marpan): Fix this for non-bypass mode so we can get stats
|
||||
// for dropped frames.
|
||||
if (svc_ctx.temporal_layering_mode !=
|
||||
VP9E_TEMPORAL_LAYERING_MODE_BYPASS) {
|
||||
int num_layers_encoded = 0;
|
||||
for (sl = 0; sl < enc_cfg.ss_number_layers; ++sl) {
|
||||
sizes[sl] = 0;
|
||||
if (cx_pkt->data.frame.spatial_layer_encoded[sl]) {
|
||||
sizes[sl] = sizes_parsed[num_layers_encoded];
|
||||
num_layers_encoded++;
|
||||
}
|
||||
}
|
||||
for (sl = 0; sl < enc_cfg.ss_number_layers; ++sl) {
|
||||
unsigned int sl2;
|
||||
uint64_t tot_size = 0;
|
||||
for (sl2 = 0; sl2 <= sl; ++sl2) {
|
||||
if (cx_pkt->data.frame.spatial_layer_encoded[sl2])
|
||||
tot_size += sizes[sl2];
|
||||
}
|
||||
if (tot_size > 0)
|
||||
vpx_video_writer_write_frame(
|
||||
outfile[sl], cx_pkt->data.frame.buf, (size_t)(tot_size),
|
||||
cx_pkt->data.frame.pts);
|
||||
++rc.layer_input_frames[sl * enc_cfg.ts_number_layers +
|
||||
layer_id.temporal_layer_id];
|
||||
}
|
||||
}
|
||||
for (tl = layer_id.temporal_layer_id;
|
||||
tl < enc_cfg.ts_number_layers; ++tl) {
|
||||
vpx_video_writer_write_frame(
|
||||
outfile[tl], cx_pkt->data.frame.buf, cx_pkt->data.frame.sz,
|
||||
cx_pkt->data.frame.pts);
|
||||
}
|
||||
|
||||
for (sl = 0; sl < enc_cfg.ss_number_layers; ++sl) {
|
||||
if (cx_pkt->data.frame.spatial_layer_encoded[sl]) {
|
||||
for (tl = layer_id.temporal_layer_id;
|
||||
tl < enc_cfg.ts_number_layers; ++tl) {
|
||||
const int layer = sl * enc_cfg.ts_number_layers + tl;
|
||||
++rc.layer_tot_enc_frames[layer];
|
||||
rc.layer_encoding_bitrate[layer] += 8.0 * sizes[sl];
|
||||
// Keep count of rate control stats per layer, for non-key
|
||||
// frames.
|
||||
if (tl == (unsigned int)layer_id.temporal_layer_id &&
|
||||
!(cx_pkt->data.frame.flags & VPX_FRAME_IS_KEY)) {
|
||||
rc.layer_avg_frame_size[layer] += 8.0 * sizes[sl];
|
||||
rc.layer_avg_rate_mismatch[layer] +=
|
||||
fabs(8.0 * sizes[sl] - rc.layer_pfb[layer]) /
|
||||
rc.layer_pfb[layer];
|
||||
++rc.layer_enc_frames[layer];
|
||||
}
|
||||
for (tl = layer_id.temporal_layer_id;
|
||||
tl < enc_cfg.ts_number_layers; ++tl) {
|
||||
const int layer = sl * enc_cfg.ts_number_layers + tl;
|
||||
++rc.layer_tot_enc_frames[layer];
|
||||
rc.layer_encoding_bitrate[layer] += 8.0 * sizes[sl];
|
||||
// Keep count of rate control stats per layer, for non-key
|
||||
// frames.
|
||||
if (tl == (unsigned int)layer_id.temporal_layer_id &&
|
||||
!(cx_pkt->data.frame.flags & VPX_FRAME_IS_KEY)) {
|
||||
rc.layer_avg_frame_size[layer] += 8.0 * sizes[sl];
|
||||
rc.layer_avg_rate_mismatch[layer] +=
|
||||
fabs(8.0 * sizes[sl] - rc.layer_pfb[layer]) /
|
||||
rc.layer_pfb[layer];
|
||||
++rc.layer_enc_frames[layer];
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -867,9 +816,9 @@ int main(int argc, const char **argv) {
|
||||
// window of size rc->window, shifted by rc->window / 2.
|
||||
// Ignore first window segment, due to key frame.
|
||||
if (frame_cnt > (unsigned int)rc.window_size) {
|
||||
tl = layer_id.temporal_layer_id;
|
||||
for (sl = 0; sl < enc_cfg.ss_number_layers; ++sl) {
|
||||
if (cx_pkt->data.frame.spatial_layer_encoded[sl])
|
||||
sum_bitrate += 0.001 * 8.0 * sizes[sl] * framerate;
|
||||
sum_bitrate += 0.001 * 8.0 * sizes[sl] * framerate;
|
||||
}
|
||||
if (frame_cnt % rc.window_size == 0) {
|
||||
rc.window_count += 1;
|
||||
@ -884,6 +833,7 @@ int main(int argc, const char **argv) {
|
||||
// Second shifted window.
|
||||
if (frame_cnt >
|
||||
(unsigned int)(rc.window_size + rc.window_size / 2)) {
|
||||
tl = layer_id.temporal_layer_id;
|
||||
for (sl = 0; sl < enc_cfg.ss_number_layers; ++sl) {
|
||||
sum_bitrate2 += 0.001 * 8.0 * sizes[sl] * framerate;
|
||||
}
|
||||
@ -950,8 +900,8 @@ int main(int argc, const char **argv) {
|
||||
}
|
||||
#if OUTPUT_RC_STATS
|
||||
if (svc_ctx.output_rc_stat) {
|
||||
for (sl = 0; sl < enc_cfg.ss_number_layers; ++sl) {
|
||||
vpx_video_writer_close(outfile[sl]);
|
||||
for (tl = 0; tl < enc_cfg.ts_number_layers; ++tl) {
|
||||
vpx_video_writer_close(outfile[tl]);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
@ -960,7 +910,7 @@ int main(int argc, const char **argv) {
|
||||
1000000 * (double)frame_cnt / (double)cx_time);
|
||||
vpx_img_free(&raw);
|
||||
// display average size, psnr
|
||||
vpx_svc_dump_statistics(&svc_ctx);
|
||||
printf("%s", vpx_svc_dump_statistics(&svc_ctx));
|
||||
vpx_svc_release(&svc_ctx);
|
||||
return EXIT_SUCCESS;
|
||||
}
|
||||
|
@ -22,34 +22,21 @@
|
||||
#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 ROI_MAP 0
|
||||
|
||||
#define zero(Dest) memset(&Dest, 0, sizeof(Dest));
|
||||
|
||||
static const char *exec_name;
|
||||
|
||||
void usage_exit(void) { exit(EXIT_FAILURE); }
|
||||
|
||||
// Denoiser states for vp8, for temporal denoising.
|
||||
enum denoiserStateVp8 {
|
||||
kVp8DenoiserOff,
|
||||
kVp8DenoiserOnYOnly,
|
||||
kVp8DenoiserOnYUV,
|
||||
kVp8DenoiserOnYUVAggressive,
|
||||
kVp8DenoiserOnAdaptive
|
||||
};
|
||||
|
||||
// Denoiser states for vp9, for temporal denoising.
|
||||
enum denoiserStateVp9 {
|
||||
kVp9DenoiserOff,
|
||||
kVp9DenoiserOnYOnly,
|
||||
// For SVC: denoise the top two spatial layers.
|
||||
kVp9DenoiserOnYTwoSpatialLayers
|
||||
// Denoiser states, for temporal denoising.
|
||||
enum denoiserState {
|
||||
kDenoiserOff,
|
||||
kDenoiserOnYOnly,
|
||||
kDenoiserOnYUV,
|
||||
kDenoiserOnYUVAggressive,
|
||||
kDenoiserOnAdaptive
|
||||
};
|
||||
|
||||
static int mode_to_num_layers[13] = { 1, 2, 2, 3, 3, 3, 3, 5, 2, 3, 3, 3, 3 };
|
||||
@ -102,10 +89,9 @@ static void set_rate_control_metrics(struct RateControlMetrics *rc,
|
||||
for (i = 0; i < cfg->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;
|
||||
@ -168,75 +154,6 @@ static void printout_rate_control_summary(struct RateControlMetrics *rc,
|
||||
die("Error: Number of input frames not equal to output! \n");
|
||||
}
|
||||
|
||||
#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;
|
||||
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 + 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.
|
||||
// VP8 uses the first 4 segments. VP9 uses all 8 segments.
|
||||
zero(roi->delta_q);
|
||||
roi->delta_q[1] = -63;
|
||||
|
||||
// Applies delta loopfilter strength on the segment blocks, varies from -63 to
|
||||
// 63. Setting to positive means stronger loopfilter. VP8 uses the first 4
|
||||
// segments. VP9 uses all 8 segments.
|
||||
zero(roi->delta_lf);
|
||||
|
||||
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 =
|
||||
(uint8_t *)calloc(roi->rows * roi->cols, sizeof(*roi->roi_map));
|
||||
for (i = 0; i < roi->rows; ++i) {
|
||||
for (j = 0; j < roi->cols; ++j) {
|
||||
if (i > (roi->rows >> 2) && i < ((roi->rows * 3) >> 2) &&
|
||||
j > (roi->cols >> 2) && j < ((roi->cols * 3) >> 2)) {
|
||||
roi->roi_map[i * roi->cols + j] = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
// Temporal scaling parameters:
|
||||
// NOTE: The 3 prediction frames cannot be used interchangeably due to
|
||||
// differences in the way they are handled throughout the code. The
|
||||
@ -578,7 +495,6 @@ int main(int argc, char **argv) {
|
||||
vpx_codec_err_t res;
|
||||
unsigned int width;
|
||||
unsigned int height;
|
||||
uint32_t error_resilient = 0;
|
||||
int speed;
|
||||
int frame_avail;
|
||||
int got_data;
|
||||
@ -589,15 +505,16 @@ int main(int argc, char **argv) {
|
||||
int layering_mode = 0;
|
||||
int layer_flags[VPX_TS_MAX_PERIODICITY] = { 0 };
|
||||
int flag_periodicity = 1;
|
||||
#if ROI_MAP
|
||||
vpx_roi_map_t roi;
|
||||
#endif
|
||||
#if VPX_ENCODER_ABI_VERSION > (4 + VPX_CODEC_ABI_VERSION)
|
||||
vpx_svc_layer_id_t layer_id = { 0, 0 };
|
||||
#else
|
||||
vpx_svc_layer_id_t layer_id = { 0 };
|
||||
#endif
|
||||
const VpxInterface *encoder = NULL;
|
||||
FILE *infile = NULL;
|
||||
struct RateControlMetrics rc;
|
||||
int64_t cx_time = 0;
|
||||
const int min_args_base = 13;
|
||||
const int min_args_base = 12;
|
||||
#if CONFIG_VP9_HIGHBITDEPTH
|
||||
vpx_bit_depth_t bit_depth = VPX_BITS_8;
|
||||
int input_bit_depth = 8;
|
||||
@ -609,21 +526,17 @@ int main(int argc, char **argv) {
|
||||
double sum_bitrate2 = 0.0;
|
||||
double framerate = 30.0;
|
||||
|
||||
zero(rc.layer_target_bitrate);
|
||||
|
||||
exec_name = argv[0];
|
||||
// Check usage and arguments.
|
||||
if (argc < min_args) {
|
||||
#if CONFIG_VP9_HIGHBITDEPTH
|
||||
die("Usage: %s <infile> <outfile> <codec_type(vp8/vp9)> <width> <height> "
|
||||
"<rate_num> <rate_den> <speed> <frame_drop_threshold> "
|
||||
"<error_resilient> <threads> <mode> "
|
||||
"<rate_num> <rate_den> <speed> <frame_drop_threshold> <threads> <mode> "
|
||||
"<Rate_0> ... <Rate_nlayers-1> <bit-depth> \n",
|
||||
argv[0]);
|
||||
#else
|
||||
die("Usage: %s <infile> <outfile> <codec_type(vp8/vp9)> <width> <height> "
|
||||
"<rate_num> <rate_den> <speed> <frame_drop_threshold> "
|
||||
"<error_resilient> <threads> <mode> "
|
||||
"<rate_num> <rate_den> <speed> <frame_drop_threshold> <threads> <mode> "
|
||||
"<Rate_0> ... <Rate_nlayers-1> \n",
|
||||
argv[0]);
|
||||
#endif // CONFIG_VP9_HIGHBITDEPTH
|
||||
@ -640,9 +553,9 @@ int main(int argc, char **argv) {
|
||||
die("Invalid resolution: %d x %d", width, height);
|
||||
}
|
||||
|
||||
layering_mode = (int)strtol(argv[12], NULL, 0);
|
||||
layering_mode = (int)strtol(argv[11], NULL, 0);
|
||||
if (layering_mode < 0 || layering_mode > 13) {
|
||||
die("Invalid layering mode (0..12) %s", argv[12]);
|
||||
die("Invalid layering mode (0..12) %s", argv[11]);
|
||||
}
|
||||
|
||||
if (argc != min_args + mode_to_num_layers[layering_mode]) {
|
||||
@ -706,11 +619,11 @@ int main(int argc, char **argv) {
|
||||
|
||||
for (i = min_args_base;
|
||||
(int)i < min_args_base + mode_to_num_layers[layering_mode]; ++i) {
|
||||
rc.layer_target_bitrate[i - 13] = (int)strtol(argv[i], NULL, 0);
|
||||
rc.layer_target_bitrate[i - 12] = (int)strtol(argv[i], NULL, 0);
|
||||
if (strncmp(encoder->name, "vp8", 3) == 0)
|
||||
cfg.ts_target_bitrate[i - 13] = rc.layer_target_bitrate[i - 13];
|
||||
cfg.ts_target_bitrate[i - 12] = rc.layer_target_bitrate[i - 12];
|
||||
else if (strncmp(encoder->name, "vp9", 3) == 0)
|
||||
cfg.layer_target_bitrate[i - 13] = rc.layer_target_bitrate[i - 13];
|
||||
cfg.layer_target_bitrate[i - 12] = rc.layer_target_bitrate[i - 12];
|
||||
}
|
||||
|
||||
// Real time parameters.
|
||||
@ -721,7 +634,7 @@ int main(int argc, char **argv) {
|
||||
if (strncmp(encoder->name, "vp9", 3) == 0) cfg.rc_max_quantizer = 52;
|
||||
cfg.rc_undershoot_pct = 50;
|
||||
cfg.rc_overshoot_pct = 50;
|
||||
cfg.rc_buf_initial_sz = 600;
|
||||
cfg.rc_buf_initial_sz = 500;
|
||||
cfg.rc_buf_optimal_sz = 600;
|
||||
cfg.rc_buf_sz = 1000;
|
||||
|
||||
@ -729,14 +642,10 @@ int main(int argc, char **argv) {
|
||||
cfg.rc_resize_allowed = 0;
|
||||
|
||||
// Use 1 thread as default.
|
||||
cfg.g_threads = (unsigned int)strtoul(argv[11], NULL, 0);
|
||||
cfg.g_threads = (unsigned int)strtoul(argv[10], NULL, 0);
|
||||
|
||||
error_resilient = (uint32_t)strtoul(argv[10], NULL, 0);
|
||||
if (error_resilient != 0 && error_resilient != 1) {
|
||||
die("Invalid value for error resilient (0, 1): %d.", error_resilient);
|
||||
}
|
||||
// Enable error resilient mode.
|
||||
cfg.g_error_resilient = error_resilient;
|
||||
cfg.g_error_resilient = 1;
|
||||
cfg.g_lag_in_frames = 0;
|
||||
cfg.kf_mode = VPX_KF_AUTO;
|
||||
|
||||
@ -791,39 +700,18 @@ int main(int argc, char **argv) {
|
||||
|
||||
if (strncmp(encoder->name, "vp8", 3) == 0) {
|
||||
vpx_codec_control(&codec, VP8E_SET_CPUUSED, -speed);
|
||||
vpx_codec_control(&codec, VP8E_SET_NOISE_SENSITIVITY, kVp8DenoiserOff);
|
||||
vpx_codec_control(&codec, VP8E_SET_NOISE_SENSITIVITY, kDenoiserOff);
|
||||
vpx_codec_control(&codec, VP8E_SET_STATIC_THRESHOLD, 1);
|
||||
vpx_codec_control(&codec, VP8E_SET_GF_CBR_BOOST_PCT, 0);
|
||||
#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
|
||||
|
||||
} else if (strncmp(encoder->name, "vp9", 3) == 0) {
|
||||
vpx_svc_extra_cfg_t svc_params;
|
||||
memset(&svc_params, 0, sizeof(svc_params));
|
||||
vpx_codec_control(&codec, VP8E_SET_CPUUSED, speed);
|
||||
vpx_codec_control(&codec, VP9E_SET_AQ_MODE, 3);
|
||||
vpx_codec_control(&codec, VP9E_SET_GF_CBR_BOOST_PCT, 0);
|
||||
vpx_codec_control(&codec, VP9E_SET_FRAME_PARALLEL_DECODING, 0);
|
||||
vpx_codec_control(&codec, VP9E_SET_FRAME_PERIODIC_BOOST, 0);
|
||||
vpx_codec_control(&codec, VP9E_SET_NOISE_SENSITIVITY, kVp9DenoiserOff);
|
||||
vpx_codec_control(&codec, VP9E_SET_NOISE_SENSITIVITY, kDenoiserOff);
|
||||
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, 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))
|
||||
vpx_codec_control(&codec, VP9E_SET_ROW_MT, 1);
|
||||
else
|
||||
vpx_codec_control(&codec, VP9E_SET_ROW_MT, 0);
|
||||
vpx_codec_control(&codec, VP9E_SET_TILE_COLUMNS, (cfg.g_threads >> 1));
|
||||
if (vpx_codec_control(&codec, VP9E_SET_SVC, layering_mode > 0 ? 1 : 0))
|
||||
die_codec(&codec, "Failed to set SVC");
|
||||
for (i = 0; i < cfg.ts_number_layers; ++i) {
|
||||
@ -842,7 +730,7 @@ int main(int argc, char **argv) {
|
||||
// For generating smaller key frames, use a smaller max_intra_size_pct
|
||||
// value, like 100 or 200.
|
||||
{
|
||||
const int max_intra_size_pct = 1000;
|
||||
const int max_intra_size_pct = 900;
|
||||
vpx_codec_control(&codec, VP8E_SET_MAX_INTRA_BITRATE_PCT,
|
||||
max_intra_size_pct);
|
||||
}
|
||||
@ -852,8 +740,10 @@ int main(int argc, char **argv) {
|
||||
struct vpx_usec_timer timer;
|
||||
vpx_codec_iter_t iter = NULL;
|
||||
const vpx_codec_cx_pkt_t *pkt;
|
||||
#if VPX_ENCODER_ABI_VERSION > (4 + VPX_CODEC_ABI_VERSION)
|
||||
// Update the temporal layer_id. No spatial layers in this test.
|
||||
layer_id.spatial_layer_id = 0;
|
||||
#endif
|
||||
layer_id.temporal_layer_id =
|
||||
cfg.ts_layer_id[frame_cnt % cfg.ts_periodicity];
|
||||
if (strncmp(encoder->name, "vp9", 3) == 0) {
|
||||
@ -945,8 +835,5 @@ int main(int argc, char **argv) {
|
||||
for (i = 0; i < cfg.ts_number_layers; ++i) vpx_video_writer_close(outfile[i]);
|
||||
|
||||
vpx_img_free(&raw);
|
||||
#if ROI_MAP
|
||||
free(roi.roi_map);
|
||||
#endif
|
||||
return EXIT_SUCCESS;
|
||||
}
|
||||
|
@ -943,6 +943,18 @@ 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
|
||||
|
49
libs.mk
49
libs.mk
@ -88,7 +88,7 @@ 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-yes += include/vpx/svc_context.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
|
||||
@ -149,11 +149,12 @@ CODEC_SRCS-yes += $(BUILD_PFX)vpx_config.c
|
||||
INSTALL-SRCS-no += $(BUILD_PFX)vpx_config.c
|
||||
ifeq ($(ARCH_X86)$(ARCH_X86_64),yes)
|
||||
INSTALL-SRCS-$(CONFIG_CODEC_SRCS) += third_party/x86inc/x86inc.asm
|
||||
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
|
||||
CODEC_EXPORTS-$(CONFIG_VP9_ENCODER) += vpx/exports_spatial_svc
|
||||
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
|
||||
@ -186,13 +187,6 @@ libvpx_srcs.txt:
|
||||
@echo $(CODEC_SRCS) | xargs -n1 echo | LC_ALL=C sort -u > $@
|
||||
CLEAN-OBJS += libvpx_srcs.txt
|
||||
|
||||
# Assembly files that are included, but don't define symbols themselves.
|
||||
# Filtered out to avoid Windows build warnings.
|
||||
ASM_INCLUDES := \
|
||||
third_party/x86inc/x86inc.asm \
|
||||
vpx_config.asm \
|
||||
vpx_ports/x86_abi_support.asm \
|
||||
vpx_dsp/x86/bitdepth_conversion_sse2.asm \
|
||||
|
||||
ifeq ($(CONFIG_EXTERNAL_BUILD),yes)
|
||||
ifeq ($(CONFIG_MSVS),yes)
|
||||
@ -204,7 +198,12 @@ vpx.def: $(call enabled,CODEC_EXPORTS)
|
||||
--out=$@ $^
|
||||
CLEAN-OBJS += vpx.def
|
||||
|
||||
vpx.$(VCPROJ_SFX): VCPROJ_SRCS=$(filter-out $(addprefix %, $(ASM_INCLUDES)), $^)
|
||||
# Assembly files that are included, but don't define symbols themselves.
|
||||
# Filtered out to avoid Visual Studio build warnings.
|
||||
ASM_INCLUDES := \
|
||||
third_party/x86inc/x86inc.asm \
|
||||
vpx_config.asm \
|
||||
vpx_ports/x86_abi_support.asm \
|
||||
|
||||
vpx.$(VCPROJ_SFX): $(CODEC_SRCS) vpx.def
|
||||
@echo " [CREATE] $@"
|
||||
@ -218,15 +217,7 @@ vpx.$(VCPROJ_SFX): $(CODEC_SRCS) vpx.def
|
||||
--ver=$(CONFIG_VS_VERSION) \
|
||||
--src-path-bare="$(SRC_PATH_BARE)" \
|
||||
--out=$@ $(CFLAGS) \
|
||||
$(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)) \
|
||||
$(filter-out $(addprefix %, $(ASM_INCLUDES)), $^) \
|
||||
--src-path-bare="$(SRC_PATH_BARE)" \
|
||||
|
||||
PROJECTS-yes += vpx.$(VCPROJ_SFX)
|
||||
@ -236,12 +227,12 @@ vpx.$(VCPROJ_SFX): $(RTCD)
|
||||
|
||||
endif
|
||||
else
|
||||
LIBVPX_OBJS=$(call objs, $(filter-out $(ASM_INCLUDES), $(CODEC_SRCS)))
|
||||
LIBVPX_OBJS=$(call objs,$(CODEC_SRCS))
|
||||
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_MAJOR := 4
|
||||
SO_VERSION_MINOR := 0
|
||||
SO_VERSION_PATCH := 0
|
||||
ifeq ($(filter darwin%,$(TGT_OS)),$(TGT_OS))
|
||||
@ -400,7 +391,7 @@ LIBVPX_TEST_SRCS=$(addprefix test/,$(call enabled,LIBVPX_TEST_SRCS))
|
||||
LIBVPX_TEST_BIN=./test_libvpx$(EXE_SFX)
|
||||
LIBVPX_TEST_DATA=$(addprefix $(LIBVPX_TEST_DATA_PATH)/,\
|
||||
$(call enabled,LIBVPX_TEST_DATA))
|
||||
libvpx_test_data_url=https://storage.googleapis.com/downloads.webmproject.org/test_data/libvpx/$(1)
|
||||
libvpx_test_data_url=http://downloads.webmproject.org/test_data/libvpx/$(1)
|
||||
|
||||
TEST_INTRA_PRED_SPEED_BIN=./test_intra_pred_speed$(EXE_SFX)
|
||||
TEST_INTRA_PRED_SPEED_SRCS=$(addprefix test/,$(call enabled,TEST_INTRA_PRED_SPEED_SRCS))
|
||||
@ -413,16 +404,8 @@ CLEAN-OBJS += libvpx_test_srcs.txt
|
||||
|
||||
$(LIBVPX_TEST_DATA): $(SRC_PATH_BARE)/test/test-data.sha1
|
||||
@echo " [DOWNLOAD] $@"
|
||||
# Attempt to download the file using curl, retrying once if it fails for a
|
||||
# partial file (18).
|
||||
$(qexec)( \
|
||||
trap 'rm -f $@' INT TERM; \
|
||||
curl="curl --retry 1 -L -o $@ $(call libvpx_test_data_url,$(@F))"; \
|
||||
$$curl; \
|
||||
case "$$?" in \
|
||||
18) $$curl -C -;; \
|
||||
esac \
|
||||
)
|
||||
$(qexec)trap 'rm -f $@' INT TERM &&\
|
||||
curl -L -o $@ $(call libvpx_test_data_url,$(@F))
|
||||
|
||||
testdata:: $(LIBVPX_TEST_DATA)
|
||||
$(qexec)[ -x "$$(which sha1sum)" ] && sha1sum=sha1sum;\
|
||||
|
25
rate_hist.c
25
rate_hist.c
@ -37,13 +37,7 @@ struct rate_hist {
|
||||
struct rate_hist *init_rate_histogram(const vpx_codec_enc_cfg_t *cfg,
|
||||
const vpx_rational_t *fps) {
|
||||
int i;
|
||||
struct rate_hist *hist = calloc(1, sizeof(*hist));
|
||||
|
||||
if (hist == NULL || cfg == NULL || fps == NULL || fps->num == 0 ||
|
||||
fps->den == 0) {
|
||||
destroy_rate_histogram(hist);
|
||||
return NULL;
|
||||
}
|
||||
struct rate_hist *hist = malloc(sizeof(*hist));
|
||||
|
||||
// Determine the number of samples in the buffer. Use the file's framerate
|
||||
// to determine the number of frames in rc_buf_sz milliseconds, with an
|
||||
@ -86,11 +80,7 @@ void update_rate_histogram(struct rate_hist *hist,
|
||||
(uint64_t)cfg->g_timebase.num /
|
||||
(uint64_t)cfg->g_timebase.den;
|
||||
|
||||
int idx;
|
||||
|
||||
if (hist == NULL || cfg == NULL || pkt == NULL) return;
|
||||
|
||||
idx = hist->frames++ % hist->samples;
|
||||
int idx = hist->frames++ % hist->samples;
|
||||
hist->pts[idx] = now;
|
||||
hist->sz[idx] = (int)pkt->data.frame.sz;
|
||||
|
||||
@ -126,14 +116,9 @@ void update_rate_histogram(struct rate_hist *hist,
|
||||
static int merge_hist_buckets(struct hist_bucket *bucket, int max_buckets,
|
||||
int *num_buckets) {
|
||||
int small_bucket = 0, merge_bucket = INT_MAX, big_bucket = 0;
|
||||
int buckets;
|
||||
int buckets = *num_buckets;
|
||||
int i;
|
||||
|
||||
assert(bucket != NULL);
|
||||
assert(num_buckets != NULL);
|
||||
|
||||
buckets = *num_buckets;
|
||||
|
||||
/* Find the extrema for this list of buckets */
|
||||
big_bucket = small_bucket = 0;
|
||||
for (i = 0; i < buckets; i++) {
|
||||
@ -196,8 +181,6 @@ static void show_histogram(const struct hist_bucket *bucket, int buckets,
|
||||
const char *pat1, *pat2;
|
||||
int i;
|
||||
|
||||
assert(bucket != NULL);
|
||||
|
||||
switch ((int)(log(bucket[buckets - 1].high) / log(10)) + 1) {
|
||||
case 1:
|
||||
case 2:
|
||||
@ -276,8 +259,6 @@ void show_rate_histogram(struct rate_hist *hist, const vpx_codec_enc_cfg_t *cfg,
|
||||
int i, scale;
|
||||
int buckets = 0;
|
||||
|
||||
if (hist == NULL || cfg == NULL) return;
|
||||
|
||||
for (i = 0; i < RATE_BINS; i++) {
|
||||
if (hist->bucket[i].low == INT_MAX) continue;
|
||||
hist->bucket[buckets++] = hist->bucket[i];
|
||||
|
@ -11,10 +11,6 @@
|
||||
#ifndef TEST_ACM_RANDOM_H_
|
||||
#define TEST_ACM_RANDOM_H_
|
||||
|
||||
#include <assert.h>
|
||||
|
||||
#include <limits>
|
||||
|
||||
#include "third_party/googletest/src/include/gtest/gtest.h"
|
||||
|
||||
#include "vpx/vpx_integer.h"
|
||||
@ -54,13 +50,6 @@ class ACMRandom {
|
||||
return r < 128 ? r << 4 : r >> 4;
|
||||
}
|
||||
|
||||
uint32_t RandRange(const uint32_t range) {
|
||||
// testing::internal::Random::Generate provides values in the range
|
||||
// testing::internal::Random::kMaxRange.
|
||||
assert(range <= testing::internal::Random::kMaxRange);
|
||||
return random_.Generate(range);
|
||||
}
|
||||
|
||||
int PseudoUniform(int range) { return random_.Generate(range); }
|
||||
|
||||
int operator()(int n) { return PseudoUniform(n); }
|
||||
|
@ -32,7 +32,6 @@ LOCAL_CPP_EXTENSION := .cc
|
||||
LOCAL_MODULE := gtest
|
||||
LOCAL_C_INCLUDES := $(LOCAL_PATH)/third_party/googletest/src/
|
||||
LOCAL_C_INCLUDES += $(LOCAL_PATH)/third_party/googletest/src/include/
|
||||
LOCAL_EXPORT_C_INCLUDES := $(LOCAL_PATH)/third_party/googletest/src/include/
|
||||
LOCAL_SRC_FILES := ./third_party/googletest/src/src/gtest-all.cc
|
||||
include $(BUILD_STATIC_LIBRARY)
|
||||
|
||||
|
208
test/avg_test.cc
208
test/avg_test.cc
@ -14,7 +14,6 @@
|
||||
|
||||
#include "third_party/googletest/src/include/gtest/gtest.h"
|
||||
|
||||
#include "./vp9_rtcd.h"
|
||||
#include "./vpx_config.h"
|
||||
#include "./vpx_dsp_rtcd.h"
|
||||
|
||||
@ -23,7 +22,6 @@
|
||||
#include "test/register_state_check.h"
|
||||
#include "test/util.h"
|
||||
#include "vpx_mem/vpx_mem.h"
|
||||
#include "vpx_ports/vpx_timer.h"
|
||||
|
||||
using libvpx_test::ACMRandom;
|
||||
|
||||
@ -91,7 +89,7 @@ class AverageTestBase : public ::testing::Test {
|
||||
};
|
||||
typedef unsigned int (*AverageFunction)(const uint8_t *s, int pitch);
|
||||
|
||||
typedef ::testing::tuple<int, int, int, int, AverageFunction> AvgFunc;
|
||||
typedef std::tr1::tuple<int, int, int, int, AverageFunction> AvgFunc;
|
||||
|
||||
class AverageTest : public AverageTestBase,
|
||||
public ::testing::WithParamInterface<AvgFunc> {
|
||||
@ -122,7 +120,7 @@ class AverageTest : public AverageTestBase,
|
||||
typedef void (*IntProRowFunc)(int16_t hbuf[16], uint8_t const *ref,
|
||||
const int ref_stride, const int height);
|
||||
|
||||
typedef ::testing::tuple<int, IntProRowFunc, IntProRowFunc> IntProRowParam;
|
||||
typedef std::tr1::tuple<int, IntProRowFunc, IntProRowFunc> IntProRowParam;
|
||||
|
||||
class IntProRowTest : public AverageTestBase,
|
||||
public ::testing::WithParamInterface<IntProRowParam> {
|
||||
@ -164,7 +162,7 @@ class IntProRowTest : public AverageTestBase,
|
||||
|
||||
typedef int16_t (*IntProColFunc)(uint8_t const *ref, const int width);
|
||||
|
||||
typedef ::testing::tuple<int, IntProColFunc, IntProColFunc> IntProColParam;
|
||||
typedef std::tr1::tuple<int, IntProColFunc, IntProColFunc> IntProColParam;
|
||||
|
||||
class IntProColTest : public AverageTestBase,
|
||||
public ::testing::WithParamInterface<IntProColParam> {
|
||||
@ -188,8 +186,8 @@ class IntProColTest : public AverageTestBase,
|
||||
int16_t sum_c_;
|
||||
};
|
||||
|
||||
typedef int (*SatdFunc)(const tran_low_t *coeffs, int length);
|
||||
typedef ::testing::tuple<int, SatdFunc> SatdTestParam;
|
||||
typedef int (*SatdFunc)(const int16_t *coeffs, int length);
|
||||
typedef std::tr1::tuple<int, SatdFunc> SatdTestParam;
|
||||
|
||||
class SatdTest : public ::testing::Test,
|
||||
public ::testing::WithParamInterface<SatdTestParam> {
|
||||
@ -198,7 +196,7 @@ class SatdTest : public ::testing::Test,
|
||||
satd_size_ = GET_PARAM(0);
|
||||
satd_func_ = GET_PARAM(1);
|
||||
rnd_.Reset(ACMRandom::DeterministicSeed());
|
||||
src_ = reinterpret_cast<tran_low_t *>(
|
||||
src_ = reinterpret_cast<int16_t *>(
|
||||
vpx_memalign(16, sizeof(*src_) * satd_size_));
|
||||
ASSERT_TRUE(src_ != NULL);
|
||||
}
|
||||
@ -208,15 +206,12 @@ class SatdTest : public ::testing::Test,
|
||||
vpx_free(src_);
|
||||
}
|
||||
|
||||
void FillConstant(const tran_low_t val) {
|
||||
void FillConstant(const int16_t val) {
|
||||
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;
|
||||
}
|
||||
for (int i = 0; i < satd_size_; ++i) src_[i] = rnd_.Rand16();
|
||||
}
|
||||
|
||||
void Check(const int expected) {
|
||||
@ -228,66 +223,11 @@ class SatdTest : public ::testing::Test,
|
||||
int satd_size_;
|
||||
|
||||
private:
|
||||
tran_low_t *src_;
|
||||
int16_t *src_;
|
||||
SatdFunc satd_func_;
|
||||
ACMRandom rnd_;
|
||||
};
|
||||
|
||||
typedef int64_t (*BlockErrorFunc)(const tran_low_t *coeff,
|
||||
const tran_low_t *dqcoeff, int block_size);
|
||||
typedef ::testing::tuple<int, BlockErrorFunc> BlockErrorTestFPParam;
|
||||
|
||||
class BlockErrorTestFP
|
||||
: public ::testing::Test,
|
||||
public ::testing::WithParamInterface<BlockErrorTestFPParam> {
|
||||
protected:
|
||||
virtual void SetUp() {
|
||||
txfm_size_ = GET_PARAM(0);
|
||||
block_error_func_ = GET_PARAM(1);
|
||||
rnd_.Reset(ACMRandom::DeterministicSeed());
|
||||
coeff_ = reinterpret_cast<tran_low_t *>(
|
||||
vpx_memalign(16, sizeof(*coeff_) * txfm_size_));
|
||||
dqcoeff_ = reinterpret_cast<tran_low_t *>(
|
||||
vpx_memalign(16, sizeof(*dqcoeff_) * txfm_size_));
|
||||
ASSERT_TRUE(coeff_ != NULL);
|
||||
ASSERT_TRUE(dqcoeff_ != NULL);
|
||||
}
|
||||
|
||||
virtual void TearDown() {
|
||||
libvpx_test::ClearSystemState();
|
||||
vpx_free(coeff_);
|
||||
vpx_free(dqcoeff_);
|
||||
}
|
||||
|
||||
void FillConstant(const tran_low_t coeff_val, const tran_low_t dqcoeff_val) {
|
||||
for (int i = 0; i < txfm_size_; ++i) coeff_[i] = coeff_val;
|
||||
for (int i = 0; i < txfm_size_; ++i) dqcoeff_[i] = dqcoeff_val;
|
||||
}
|
||||
|
||||
void FillRandom() {
|
||||
// Just two fixed seeds
|
||||
rnd_.Reset(0xb0b9);
|
||||
for (int i = 0; i < txfm_size_; ++i) coeff_[i] = rnd_.Rand16() >> 1;
|
||||
rnd_.Reset(0xb0c8);
|
||||
for (int i = 0; i < txfm_size_; ++i) dqcoeff_[i] = rnd_.Rand16() >> 1;
|
||||
}
|
||||
|
||||
void Check(const int64_t expected) {
|
||||
int64_t total;
|
||||
ASM_REGISTER_STATE_CHECK(
|
||||
total = block_error_func_(coeff_, dqcoeff_, txfm_size_));
|
||||
EXPECT_EQ(expected, total);
|
||||
}
|
||||
|
||||
int txfm_size_;
|
||||
|
||||
private:
|
||||
tran_low_t *coeff_;
|
||||
tran_low_t *dqcoeff_;
|
||||
BlockErrorFunc block_error_func_;
|
||||
ACMRandom rnd_;
|
||||
};
|
||||
|
||||
uint8_t *AverageTestBase::source_data_ = NULL;
|
||||
|
||||
TEST_P(AverageTest, MinValue) {
|
||||
@ -368,67 +308,7 @@ TEST_P(SatdTest, Random) {
|
||||
Check(expected);
|
||||
}
|
||||
|
||||
TEST_P(SatdTest, DISABLED_Speed) {
|
||||
const int kCountSpeedTestBlock = 20000;
|
||||
vpx_usec_timer timer;
|
||||
DECLARE_ALIGNED(16, tran_low_t, coeff[1024]);
|
||||
const int blocksize = GET_PARAM(0);
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
TEST_P(BlockErrorTestFP, MinValue) {
|
||||
const int64_t kMin = -32640;
|
||||
const int64_t expected = kMin * kMin * txfm_size_;
|
||||
FillConstant(kMin, 0);
|
||||
Check(expected);
|
||||
}
|
||||
|
||||
TEST_P(BlockErrorTestFP, MaxValue) {
|
||||
const int64_t kMax = 32640;
|
||||
const int64_t expected = kMax * kMax * txfm_size_;
|
||||
FillConstant(kMax, 0);
|
||||
Check(expected);
|
||||
}
|
||||
|
||||
TEST_P(BlockErrorTestFP, Random) {
|
||||
int64_t expected;
|
||||
switch (txfm_size_) {
|
||||
case 16: expected = 2051681432; break;
|
||||
case 64: expected = 11075114379; break;
|
||||
case 256: expected = 44386271116; break;
|
||||
case 1024: expected = 184774996089; break;
|
||||
default:
|
||||
FAIL() << "Invalid satd size (" << txfm_size_
|
||||
<< ") valid: 16/64/256/1024";
|
||||
}
|
||||
FillRandom();
|
||||
Check(expected);
|
||||
}
|
||||
|
||||
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);
|
||||
|
||||
vpx_usec_timer_start(&timer);
|
||||
for (int i = 0; i < kCountSpeedTestBlock; ++i) {
|
||||
GET_PARAM(1)(coeff, dqcoeff, 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);
|
||||
}
|
||||
|
||||
using ::testing::make_tuple;
|
||||
using std::tr1::make_tuple;
|
||||
|
||||
INSTANTIATE_TEST_CASE_P(
|
||||
C, AverageTest,
|
||||
@ -441,13 +321,6 @@ INSTANTIATE_TEST_CASE_P(C, SatdTest,
|
||||
make_tuple(256, &vpx_satd_c),
|
||||
make_tuple(1024, &vpx_satd_c)));
|
||||
|
||||
INSTANTIATE_TEST_CASE_P(
|
||||
C, BlockErrorTestFP,
|
||||
::testing::Values(make_tuple(16, &vp9_block_error_fp_c),
|
||||
make_tuple(64, &vp9_block_error_fp_c),
|
||||
make_tuple(256, &vp9_block_error_fp_c),
|
||||
make_tuple(1024, &vp9_block_error_fp_c)));
|
||||
|
||||
#if HAVE_SSE2
|
||||
INSTANTIATE_TEST_CASE_P(
|
||||
SSE2, AverageTest,
|
||||
@ -477,28 +350,6 @@ INSTANTIATE_TEST_CASE_P(SSE2, SatdTest,
|
||||
make_tuple(64, &vpx_satd_sse2),
|
||||
make_tuple(256, &vpx_satd_sse2),
|
||||
make_tuple(1024, &vpx_satd_sse2)));
|
||||
|
||||
INSTANTIATE_TEST_CASE_P(
|
||||
SSE2, BlockErrorTestFP,
|
||||
::testing::Values(make_tuple(16, &vp9_block_error_fp_sse2),
|
||||
make_tuple(64, &vp9_block_error_fp_sse2),
|
||||
make_tuple(256, &vp9_block_error_fp_sse2),
|
||||
make_tuple(1024, &vp9_block_error_fp_sse2)));
|
||||
#endif // HAVE_SSE2
|
||||
|
||||
#if HAVE_AVX2
|
||||
INSTANTIATE_TEST_CASE_P(AVX2, SatdTest,
|
||||
::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)));
|
||||
|
||||
INSTANTIATE_TEST_CASE_P(
|
||||
AVX2, BlockErrorTestFP,
|
||||
::testing::Values(make_tuple(16, &vp9_block_error_fp_avx2),
|
||||
make_tuple(64, &vp9_block_error_fp_avx2),
|
||||
make_tuple(256, &vp9_block_error_fp_avx2),
|
||||
make_tuple(1024, &vp9_block_error_fp_avx2)));
|
||||
#endif
|
||||
|
||||
#if HAVE_NEON
|
||||
@ -530,18 +381,7 @@ INSTANTIATE_TEST_CASE_P(NEON, SatdTest,
|
||||
make_tuple(64, &vpx_satd_neon),
|
||||
make_tuple(256, &vpx_satd_neon),
|
||||
make_tuple(1024, &vpx_satd_neon)));
|
||||
|
||||
// TODO(jianj): Remove the highbitdepth flag once the SIMD functions are
|
||||
// in place.
|
||||
#if !CONFIG_VP9_HIGHBITDEPTH
|
||||
INSTANTIATE_TEST_CASE_P(
|
||||
NEON, BlockErrorTestFP,
|
||||
::testing::Values(make_tuple(16, &vp9_block_error_fp_neon),
|
||||
make_tuple(64, &vp9_block_error_fp_neon),
|
||||
make_tuple(256, &vp9_block_error_fp_neon),
|
||||
make_tuple(1024, &vp9_block_error_fp_neon)));
|
||||
#endif // !CONFIG_VP9_HIGHBITDEPTH
|
||||
#endif // HAVE_NEON
|
||||
#endif
|
||||
|
||||
#if HAVE_MSA
|
||||
INSTANTIATE_TEST_CASE_P(
|
||||
@ -552,30 +392,6 @@ INSTANTIATE_TEST_CASE_P(
|
||||
make_tuple(16, 16, 0, 4, &vpx_avg_4x4_msa),
|
||||
make_tuple(16, 16, 5, 4, &vpx_avg_4x4_msa),
|
||||
make_tuple(32, 32, 15, 4, &vpx_avg_4x4_msa)));
|
||||
|
||||
INSTANTIATE_TEST_CASE_P(
|
||||
MSA, IntProRowTest,
|
||||
::testing::Values(make_tuple(16, &vpx_int_pro_row_msa, &vpx_int_pro_row_c),
|
||||
make_tuple(32, &vpx_int_pro_row_msa, &vpx_int_pro_row_c),
|
||||
make_tuple(64, &vpx_int_pro_row_msa,
|
||||
&vpx_int_pro_row_c)));
|
||||
|
||||
INSTANTIATE_TEST_CASE_P(
|
||||
MSA, IntProColTest,
|
||||
::testing::Values(make_tuple(16, &vpx_int_pro_col_msa, &vpx_int_pro_col_c),
|
||||
make_tuple(32, &vpx_int_pro_col_msa, &vpx_int_pro_col_c),
|
||||
make_tuple(64, &vpx_int_pro_col_msa,
|
||||
&vpx_int_pro_col_c)));
|
||||
|
||||
// TODO(jingning): Remove the highbitdepth flag once the SIMD functions are
|
||||
// in place.
|
||||
#if !CONFIG_VP9_HIGHBITDEPTH
|
||||
INSTANTIATE_TEST_CASE_P(MSA, SatdTest,
|
||||
::testing::Values(make_tuple(16, &vpx_satd_msa),
|
||||
make_tuple(64, &vpx_satd_msa),
|
||||
make_tuple(256, &vpx_satd_msa),
|
||||
make_tuple(1024, &vpx_satd_msa)));
|
||||
#endif // !CONFIG_VP9_HIGHBITDEPTH
|
||||
#endif // HAVE_MSA
|
||||
#endif
|
||||
|
||||
} // namespace
|
||||
|
@ -141,7 +141,7 @@ class BlockinessTestBase : public ::testing::Test {
|
||||
};
|
||||
|
||||
#if CONFIG_VP9_ENCODER
|
||||
typedef ::testing::tuple<int, int> BlockinessParam;
|
||||
typedef std::tr1::tuple<int, int> BlockinessParam;
|
||||
class BlockinessVP9Test
|
||||
: public BlockinessTestBase,
|
||||
public ::testing::WithParamInterface<BlockinessParam> {
|
||||
@ -208,14 +208,14 @@ TEST_P(BlockinessVP9Test, WorstCaseBlockiness) {
|
||||
}
|
||||
#endif // CONFIG_VP9_ENCODER
|
||||
|
||||
using ::testing::make_tuple;
|
||||
using std::tr1::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)
|
||||
make_tuple(320, 240), make_tuple(318, 242), make_tuple(318, 238),
|
||||
};
|
||||
INSTANTIATE_TEST_CASE_P(C, BlockinessVP9Test, ::testing::ValuesIn(c_vp9_tests));
|
||||
#endif
|
||||
|
382
test/buffer.h
382
test/buffer.h
@ -1,382 +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.
|
||||
*/
|
||||
|
||||
#ifndef TEST_BUFFER_H_
|
||||
#define TEST_BUFFER_H_
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
#include <limits>
|
||||
|
||||
#include "third_party/googletest/src/include/gtest/gtest.h"
|
||||
|
||||
#include "test/acm_random.h"
|
||||
#include "vpx/vpx_integer.h"
|
||||
#include "vpx_mem/vpx_mem.h"
|
||||
|
||||
namespace libvpx_test {
|
||||
|
||||
template <typename T>
|
||||
class Buffer {
|
||||
public:
|
||||
Buffer(int width, int height, int top_padding, int left_padding,
|
||||
int right_padding, int bottom_padding)
|
||||
: width_(width), height_(height), top_padding_(top_padding),
|
||||
left_padding_(left_padding), right_padding_(right_padding),
|
||||
bottom_padding_(bottom_padding), alignment_(0), padding_value_(0),
|
||||
stride_(0), raw_size_(0), num_elements_(0), raw_buffer_(NULL) {}
|
||||
|
||||
Buffer(int width, int height, int top_padding, int left_padding,
|
||||
int right_padding, int bottom_padding, unsigned int alignment)
|
||||
: width_(width), height_(height), top_padding_(top_padding),
|
||||
left_padding_(left_padding), right_padding_(right_padding),
|
||||
bottom_padding_(bottom_padding), alignment_(alignment),
|
||||
padding_value_(0), stride_(0), raw_size_(0), num_elements_(0),
|
||||
raw_buffer_(NULL) {}
|
||||
|
||||
Buffer(int width, int height, int padding)
|
||||
: width_(width), height_(height), top_padding_(padding),
|
||||
left_padding_(padding), right_padding_(padding),
|
||||
bottom_padding_(padding), alignment_(0), padding_value_(0), stride_(0),
|
||||
raw_size_(0), num_elements_(0), raw_buffer_(NULL) {}
|
||||
|
||||
Buffer(int width, int height, int padding, unsigned int alignment)
|
||||
: width_(width), height_(height), top_padding_(padding),
|
||||
left_padding_(padding), right_padding_(padding),
|
||||
bottom_padding_(padding), alignment_(alignment), padding_value_(0),
|
||||
stride_(0), raw_size_(0), num_elements_(0), raw_buffer_(NULL) {}
|
||||
|
||||
~Buffer() {
|
||||
if (alignment_) {
|
||||
vpx_free(raw_buffer_);
|
||||
} else {
|
||||
delete[] raw_buffer_;
|
||||
}
|
||||
}
|
||||
|
||||
T *TopLeftPixel() const;
|
||||
|
||||
int stride() const { return stride_; }
|
||||
|
||||
// Set the buffer (excluding padding) to 'value'.
|
||||
void Set(const T value);
|
||||
|
||||
// Set the buffer (excluding padding) to the output of ACMRandom function
|
||||
// 'rand_func'.
|
||||
void Set(ACMRandom *rand_class, T (ACMRandom::*rand_func)());
|
||||
|
||||
// Set the buffer (excluding padding) to the output of ACMRandom function
|
||||
// 'RandRange' with range 'low' to 'high' which typically must be within
|
||||
// testing::internal::Random::kMaxRange (1u << 31). However, because we want
|
||||
// to allow negative low (and high) values, it is restricted to INT32_MAX
|
||||
// here.
|
||||
void Set(ACMRandom *rand_class, const T low, const T high);
|
||||
|
||||
// Copy the contents of Buffer 'a' (excluding padding).
|
||||
void CopyFrom(const Buffer<T> &a);
|
||||
|
||||
void DumpBuffer() const;
|
||||
|
||||
// Highlight the differences between two buffers if they are the same size.
|
||||
void PrintDifference(const Buffer<T> &a) const;
|
||||
|
||||
bool HasPadding() const;
|
||||
|
||||
// Sets all the values in the buffer to 'padding_value'.
|
||||
void SetPadding(const T padding_value);
|
||||
|
||||
// Checks if all the values (excluding padding) are equal to 'value' if the
|
||||
// Buffers are the same size.
|
||||
bool CheckValues(const T value) const;
|
||||
|
||||
// Check that padding matches the expected value or there is no padding.
|
||||
bool CheckPadding() const;
|
||||
|
||||
// Compare the non-padding portion of two buffers if they are the same size.
|
||||
bool CheckValues(const Buffer<T> &a) const;
|
||||
|
||||
bool Init() {
|
||||
if (raw_buffer_ != NULL) return false;
|
||||
EXPECT_GT(width_, 0);
|
||||
EXPECT_GT(height_, 0);
|
||||
EXPECT_GE(top_padding_, 0);
|
||||
EXPECT_GE(left_padding_, 0);
|
||||
EXPECT_GE(right_padding_, 0);
|
||||
EXPECT_GE(bottom_padding_, 0);
|
||||
stride_ = left_padding_ + width_ + right_padding_;
|
||||
num_elements_ = stride_ * (top_padding_ + height_ + bottom_padding_);
|
||||
raw_size_ = num_elements_ * sizeof(T);
|
||||
if (alignment_) {
|
||||
EXPECT_GE(alignment_, sizeof(T));
|
||||
// Ensure alignment of the first value will be preserved.
|
||||
EXPECT_EQ((left_padding_ * sizeof(T)) % alignment_, 0u);
|
||||
// Ensure alignment of the subsequent rows will be preserved when there is
|
||||
// a stride.
|
||||
if (stride_ != width_) {
|
||||
EXPECT_EQ((stride_ * sizeof(T)) % alignment_, 0u);
|
||||
}
|
||||
raw_buffer_ = reinterpret_cast<T *>(vpx_memalign(alignment_, raw_size_));
|
||||
} else {
|
||||
raw_buffer_ = new (std::nothrow) T[num_elements_];
|
||||
}
|
||||
EXPECT_TRUE(raw_buffer_ != NULL);
|
||||
SetPadding(std::numeric_limits<T>::max());
|
||||
return !::testing::Test::HasFailure();
|
||||
}
|
||||
|
||||
private:
|
||||
bool BufferSizesMatch(const Buffer<T> &a) const;
|
||||
|
||||
const int width_;
|
||||
const int height_;
|
||||
const int top_padding_;
|
||||
const int left_padding_;
|
||||
const int right_padding_;
|
||||
const int bottom_padding_;
|
||||
const unsigned int alignment_;
|
||||
T padding_value_;
|
||||
int stride_;
|
||||
int raw_size_;
|
||||
int num_elements_;
|
||||
T *raw_buffer_;
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
T *Buffer<T>::TopLeftPixel() const {
|
||||
if (!raw_buffer_) return NULL;
|
||||
return raw_buffer_ + (top_padding_ * stride_) + left_padding_;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
void Buffer<T>::Set(const T value) {
|
||||
if (!raw_buffer_) return;
|
||||
T *src = TopLeftPixel();
|
||||
for (int height = 0; height < height_; ++height) {
|
||||
for (int width = 0; width < width_; ++width) {
|
||||
src[width] = value;
|
||||
}
|
||||
src += stride_;
|
||||
}
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
void Buffer<T>::Set(ACMRandom *rand_class, T (ACMRandom::*rand_func)()) {
|
||||
if (!raw_buffer_) return;
|
||||
T *src = TopLeftPixel();
|
||||
for (int height = 0; height < height_; ++height) {
|
||||
for (int width = 0; width < width_; ++width) {
|
||||
src[width] = (*rand_class.*rand_func)();
|
||||
}
|
||||
src += stride_;
|
||||
}
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
void Buffer<T>::Set(ACMRandom *rand_class, const T low, const T high) {
|
||||
if (!raw_buffer_) return;
|
||||
|
||||
EXPECT_LE(low, high);
|
||||
EXPECT_LE(static_cast<int64_t>(high) - low,
|
||||
std::numeric_limits<int32_t>::max());
|
||||
|
||||
T *src = TopLeftPixel();
|
||||
for (int height = 0; height < height_; ++height) {
|
||||
for (int width = 0; width < width_; ++width) {
|
||||
// 'low' will be promoted to unsigned given the return type of RandRange.
|
||||
// Store the value as an int to avoid unsigned overflow warnings when
|
||||
// 'low' is negative.
|
||||
const int32_t value =
|
||||
static_cast<int32_t>((*rand_class).RandRange(high - low));
|
||||
src[width] = static_cast<T>(value + low);
|
||||
}
|
||||
src += stride_;
|
||||
}
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
void Buffer<T>::CopyFrom(const Buffer<T> &a) {
|
||||
if (!raw_buffer_) return;
|
||||
if (!BufferSizesMatch(a)) return;
|
||||
|
||||
T *a_src = a.TopLeftPixel();
|
||||
T *b_src = this->TopLeftPixel();
|
||||
for (int height = 0; height < height_; ++height) {
|
||||
for (int width = 0; width < width_; ++width) {
|
||||
b_src[width] = a_src[width];
|
||||
}
|
||||
a_src += a.stride();
|
||||
b_src += this->stride();
|
||||
}
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
void Buffer<T>::DumpBuffer() const {
|
||||
if (!raw_buffer_) return;
|
||||
for (int height = 0; height < height_ + top_padding_ + bottom_padding_;
|
||||
++height) {
|
||||
for (int width = 0; width < stride_; ++width) {
|
||||
printf("%4d", raw_buffer_[height + width * stride_]);
|
||||
}
|
||||
printf("\n");
|
||||
}
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
bool Buffer<T>::HasPadding() const {
|
||||
if (!raw_buffer_) return false;
|
||||
return top_padding_ || left_padding_ || right_padding_ || bottom_padding_;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
void Buffer<T>::PrintDifference(const Buffer<T> &a) const {
|
||||
if (!raw_buffer_) return;
|
||||
if (!BufferSizesMatch(a)) return;
|
||||
|
||||
T *a_src = a.TopLeftPixel();
|
||||
T *b_src = TopLeftPixel();
|
||||
|
||||
printf("This buffer:\n");
|
||||
for (int height = 0; height < height_; ++height) {
|
||||
for (int width = 0; width < width_; ++width) {
|
||||
if (a_src[width] != b_src[width]) {
|
||||
printf("*%3d", b_src[width]);
|
||||
} else {
|
||||
printf("%4d", b_src[width]);
|
||||
}
|
||||
}
|
||||
printf("\n");
|
||||
a_src += a.stride();
|
||||
b_src += this->stride();
|
||||
}
|
||||
|
||||
a_src = a.TopLeftPixel();
|
||||
b_src = TopLeftPixel();
|
||||
|
||||
printf("Reference buffer:\n");
|
||||
for (int height = 0; height < height_; ++height) {
|
||||
for (int width = 0; width < width_; ++width) {
|
||||
if (a_src[width] != b_src[width]) {
|
||||
printf("*%3d", a_src[width]);
|
||||
} else {
|
||||
printf("%4d", a_src[width]);
|
||||
}
|
||||
}
|
||||
printf("\n");
|
||||
a_src += a.stride();
|
||||
b_src += this->stride();
|
||||
}
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
void Buffer<T>::SetPadding(const T padding_value) {
|
||||
if (!raw_buffer_) return;
|
||||
padding_value_ = padding_value;
|
||||
|
||||
T *src = raw_buffer_;
|
||||
for (int i = 0; i < num_elements_; ++i) {
|
||||
src[i] = padding_value;
|
||||
}
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
bool Buffer<T>::CheckValues(const T value) const {
|
||||
if (!raw_buffer_) return false;
|
||||
T *src = TopLeftPixel();
|
||||
for (int height = 0; height < height_; ++height) {
|
||||
for (int width = 0; width < width_; ++width) {
|
||||
if (value != src[width]) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
src += stride_;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
bool Buffer<T>::CheckPadding() const {
|
||||
if (!raw_buffer_) return false;
|
||||
if (!HasPadding()) return true;
|
||||
|
||||
// Top padding.
|
||||
T const *top = raw_buffer_;
|
||||
for (int i = 0; i < stride_ * top_padding_; ++i) {
|
||||
if (padding_value_ != top[i]) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// Left padding.
|
||||
T const *left = TopLeftPixel() - left_padding_;
|
||||
for (int height = 0; height < height_; ++height) {
|
||||
for (int width = 0; width < left_padding_; ++width) {
|
||||
if (padding_value_ != left[width]) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
left += stride_;
|
||||
}
|
||||
|
||||
// Right padding.
|
||||
T const *right = TopLeftPixel() + width_;
|
||||
for (int height = 0; height < height_; ++height) {
|
||||
for (int width = 0; width < right_padding_; ++width) {
|
||||
if (padding_value_ != right[width]) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
right += stride_;
|
||||
}
|
||||
|
||||
// Bottom padding
|
||||
T const *bottom = raw_buffer_ + (top_padding_ + height_) * stride_;
|
||||
for (int i = 0; i < stride_ * bottom_padding_; ++i) {
|
||||
if (padding_value_ != bottom[i]) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
bool Buffer<T>::CheckValues(const Buffer<T> &a) const {
|
||||
if (!raw_buffer_) return false;
|
||||
if (!BufferSizesMatch(a)) return false;
|
||||
|
||||
T *a_src = a.TopLeftPixel();
|
||||
T *b_src = this->TopLeftPixel();
|
||||
for (int height = 0; height < height_; ++height) {
|
||||
for (int width = 0; width < width_; ++width) {
|
||||
if (a_src[width] != b_src[width]) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
a_src += a.stride();
|
||||
b_src += this->stride();
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
bool Buffer<T>::BufferSizesMatch(const Buffer<T> &a) const {
|
||||
if (!raw_buffer_) return false;
|
||||
if (a.width_ != this->width_ || a.height_ != this->height_) {
|
||||
printf(
|
||||
"Reference buffer of size %dx%d does not match this buffer which is "
|
||||
"size %dx%d\n",
|
||||
a.width_, a.height_, this->width_, this->height_);
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
} // namespace libvpx_test
|
||||
#endif // TEST_BUFFER_H_
|
@ -128,8 +128,8 @@ class ByteAlignmentTest
|
||||
// TODO(fgalligan): Move the MD5 testing code into another class.
|
||||
void OpenMd5File(const std::string &md5_file_name_) {
|
||||
md5_file_ = libvpx_test::OpenTestDataFile(md5_file_name_);
|
||||
ASSERT_TRUE(md5_file_ != NULL)
|
||||
<< "MD5 file open failed. Filename: " << md5_file_name_;
|
||||
ASSERT_TRUE(md5_file_ != NULL) << "MD5 file open failed. Filename: "
|
||||
<< md5_file_name_;
|
||||
}
|
||||
|
||||
void CheckMd5(const vpx_image_t &img) {
|
||||
@ -171,9 +171,8 @@ 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,
|
||||
|
@ -11,13 +11,19 @@
|
||||
#define TEST_CLEAR_SYSTEM_STATE_H_
|
||||
|
||||
#include "./vpx_config.h"
|
||||
#include "vpx_ports/system_state.h"
|
||||
#if ARCH_X86 || ARCH_X86_64
|
||||
#include "vpx_ports/x86.h"
|
||||
#endif
|
||||
|
||||
namespace libvpx_test {
|
||||
|
||||
// Reset system to a known state. This function should be used for all non-API
|
||||
// test cases.
|
||||
inline void ClearSystemState() { vpx_clear_system_state(); }
|
||||
inline void ClearSystemState() {
|
||||
#if ARCH_X86 || ARCH_X86_64
|
||||
vpx_reset_mmx_state();
|
||||
#endif
|
||||
}
|
||||
|
||||
} // namespace libvpx_test
|
||||
#endif // TEST_CLEAR_SYSTEM_STATE_H_
|
||||
|
@ -53,22 +53,23 @@ class CodecFactory {
|
||||
template <class T1>
|
||||
class CodecTestWithParam
|
||||
: public ::testing::TestWithParam<
|
||||
::testing::tuple<const libvpx_test::CodecFactory *, T1> > {};
|
||||
std::tr1::tuple<const libvpx_test::CodecFactory *, T1> > {};
|
||||
|
||||
template <class T1, class T2>
|
||||
class CodecTestWith2Params
|
||||
: public ::testing::TestWithParam<
|
||||
::testing::tuple<const libvpx_test::CodecFactory *, T1, T2> > {};
|
||||
std::tr1::tuple<const libvpx_test::CodecFactory *, T1, T2> > {};
|
||||
|
||||
template <class T1, class T2, class T3>
|
||||
class CodecTestWith3Params
|
||||
: public ::testing::TestWithParam<
|
||||
::testing::tuple<const libvpx_test::CodecFactory *, T1, T2, T3> > {};
|
||||
std::tr1::tuple<const libvpx_test::CodecFactory *, T1, T2, T3> > {};
|
||||
|
||||
template <class T1, class T2, class T3, class T4>
|
||||
class CodecTestWith4Params
|
||||
: public ::testing::TestWithParam< ::testing::tuple<
|
||||
const libvpx_test::CodecFactory *, T1, T2, T3, T4> > {};
|
||||
: public ::testing::TestWithParam<
|
||||
std::tr1::tuple<const libvpx_test::CodecFactory *, T1, T2, T3, T4> > {
|
||||
};
|
||||
|
||||
/*
|
||||
* VP8 Codec Definitions
|
||||
|
@ -1,182 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2017 The WebM project authors. All Rights Reserved.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license
|
||||
* that can be found in the LICENSE file in the root of the source
|
||||
* tree. An additional intellectual property rights grant can be found
|
||||
* in the file PATENTS. All contributing project authors may
|
||||
* be found in the AUTHORS file in the root of the source tree.
|
||||
*/
|
||||
|
||||
#include "third_party/googletest/src/include/gtest/gtest.h"
|
||||
|
||||
#include "./vpx_dsp_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 (*AvgPredFunc)(uint8_t *a, const uint8_t *b, int w, int h,
|
||||
const uint8_t *c, int c_stride);
|
||||
|
||||
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) {
|
||||
for (int y = 0; y < height; ++y) {
|
||||
for (int x = 0; x < width; ++x) {
|
||||
avg->TopLeftPixel()[y * avg->stride() + x] =
|
||||
avg_with_rounding(pred.TopLeftPixel()[y * pred.stride() + x],
|
||||
ref.TopLeftPixel()[y * ref.stride() + x]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class AvgPredTest : public ::testing::TestWithParam<AvgPredFunc> {
|
||||
public:
|
||||
virtual void SetUp() {
|
||||
avg_pred_func_ = GetParam();
|
||||
rnd_.Reset(ACMRandom::DeterministicSeed());
|
||||
}
|
||||
|
||||
protected:
|
||||
AvgPredFunc avg_pred_func_;
|
||||
ACMRandom rnd_;
|
||||
};
|
||||
|
||||
TEST_P(AvgPredTest, SizeCombinations) {
|
||||
// This is called as part of the sub pixel variance. As such it must be one of
|
||||
// the variance block sizes.
|
||||
|
||||
for (int width_pow = 2; width_pow <= 6; ++width_pow) {
|
||||
for (int height_pow = width_pow - 1; height_pow <= width_pow + 1;
|
||||
++height_pow) {
|
||||
// Don't test 4x2 or 64x128
|
||||
if (height_pow == 1 || height_pow == 7) continue;
|
||||
|
||||
// The sse2 special-cases when ref width == stride, so make sure to test
|
||||
// it.
|
||||
for (int ref_padding = 0; ref_padding < 2; ref_padding++) {
|
||||
const int width = 1 << width_pow;
|
||||
const int height = 1 << height_pow;
|
||||
// Only the reference buffer may have a stride not equal to width.
|
||||
Buffer<uint8_t> ref =
|
||||
Buffer<uint8_t>(width, height, ref_padding ? 8 : 0);
|
||||
ASSERT_TRUE(ref.Init());
|
||||
Buffer<uint8_t> pred = Buffer<uint8_t>(width, height, 0, 16);
|
||||
ASSERT_TRUE(pred.Init());
|
||||
Buffer<uint8_t> avg_ref = Buffer<uint8_t>(width, height, 0, 16);
|
||||
ASSERT_TRUE(avg_ref.Init());
|
||||
Buffer<uint8_t> avg_chk = Buffer<uint8_t>(width, height, 0, 16);
|
||||
ASSERT_TRUE(avg_chk.Init());
|
||||
|
||||
ref.Set(&rnd_, &ACMRandom::Rand8);
|
||||
pred.Set(&rnd_, &ACMRandom::Rand8);
|
||||
|
||||
reference_pred(pred, ref, width, height, &avg_ref);
|
||||
ASM_REGISTER_STATE_CHECK(
|
||||
avg_pred_func_(avg_chk.TopLeftPixel(), pred.TopLeftPixel(), width,
|
||||
height, ref.TopLeftPixel(), ref.stride()));
|
||||
|
||||
EXPECT_TRUE(avg_chk.CheckValues(avg_ref));
|
||||
if (HasFailure()) {
|
||||
printf("Width: %d Height: %d\n", width, height);
|
||||
avg_chk.PrintDifference(avg_ref);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
TEST_P(AvgPredTest, CompareReferenceRandom) {
|
||||
const int width = 64;
|
||||
const int height = 32;
|
||||
Buffer<uint8_t> ref = Buffer<uint8_t>(width, height, 8);
|
||||
ASSERT_TRUE(ref.Init());
|
||||
Buffer<uint8_t> pred = Buffer<uint8_t>(width, height, 0, 16);
|
||||
ASSERT_TRUE(pred.Init());
|
||||
Buffer<uint8_t> avg_ref = Buffer<uint8_t>(width, height, 0, 16);
|
||||
ASSERT_TRUE(avg_ref.Init());
|
||||
Buffer<uint8_t> avg_chk = Buffer<uint8_t>(width, height, 0, 16);
|
||||
ASSERT_TRUE(avg_chk.Init());
|
||||
|
||||
for (int i = 0; i < 500; ++i) {
|
||||
ref.Set(&rnd_, &ACMRandom::Rand8);
|
||||
pred.Set(&rnd_, &ACMRandom::Rand8);
|
||||
|
||||
reference_pred(pred, ref, width, height, &avg_ref);
|
||||
ASM_REGISTER_STATE_CHECK(avg_pred_func_(avg_chk.TopLeftPixel(),
|
||||
pred.TopLeftPixel(), width, height,
|
||||
ref.TopLeftPixel(), ref.stride()));
|
||||
EXPECT_TRUE(avg_chk.CheckValues(avg_ref));
|
||||
if (HasFailure()) {
|
||||
printf("Width: %d Height: %d\n", width, height);
|
||||
avg_chk.PrintDifference(avg_ref);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
TEST_P(AvgPredTest, DISABLED_Speed) {
|
||||
for (int width_pow = 2; width_pow <= 6; ++width_pow) {
|
||||
for (int height_pow = width_pow - 1; height_pow <= width_pow + 1;
|
||||
++height_pow) {
|
||||
// Don't test 4x2 or 64x128
|
||||
if (height_pow == 1 || height_pow == 7) continue;
|
||||
|
||||
for (int ref_padding = 0; ref_padding < 2; ref_padding++) {
|
||||
const int width = 1 << width_pow;
|
||||
const int height = 1 << height_pow;
|
||||
Buffer<uint8_t> ref =
|
||||
Buffer<uint8_t>(width, height, ref_padding ? 8 : 0);
|
||||
ASSERT_TRUE(ref.Init());
|
||||
Buffer<uint8_t> pred = Buffer<uint8_t>(width, height, 0, 16);
|
||||
ASSERT_TRUE(pred.Init());
|
||||
Buffer<uint8_t> avg = Buffer<uint8_t>(width, height, 0, 16);
|
||||
ASSERT_TRUE(avg.Init());
|
||||
|
||||
ref.Set(&rnd_, &ACMRandom::Rand8);
|
||||
pred.Set(&rnd_, &ACMRandom::Rand8);
|
||||
|
||||
vpx_usec_timer timer;
|
||||
vpx_usec_timer_start(&timer);
|
||||
for (int i = 0; i < 10000000 / (width * height); ++i) {
|
||||
avg_pred_func_(avg.TopLeftPixel(), pred.TopLeftPixel(), width, height,
|
||||
ref.TopLeftPixel(), ref.stride());
|
||||
}
|
||||
vpx_usec_timer_mark(&timer);
|
||||
|
||||
const int elapsed_time =
|
||||
static_cast<int>(vpx_usec_timer_elapsed(&timer));
|
||||
printf("Average Test (ref_padding: %d) %dx%d time: %5d us\n",
|
||||
ref_padding, width, height, elapsed_time);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
INSTANTIATE_TEST_CASE_P(C, AvgPredTest,
|
||||
::testing::Values(&vpx_comp_avg_pred_c));
|
||||
|
||||
#if HAVE_SSE2
|
||||
INSTANTIATE_TEST_CASE_P(SSE2, AvgPredTest,
|
||||
::testing::Values(&vpx_comp_avg_pred_sse2));
|
||||
#endif // HAVE_SSE2
|
||||
|
||||
#if HAVE_NEON
|
||||
INSTANTIATE_TEST_CASE_P(NEON, AvgPredTest,
|
||||
::testing::Values(&vpx_comp_avg_pred_neon));
|
||||
#endif // HAVE_NEON
|
||||
|
||||
#if HAVE_VSX
|
||||
INSTANTIATE_TEST_CASE_P(VSX, AvgPredTest,
|
||||
::testing::Values(&vpx_comp_avg_pred_vsx));
|
||||
#endif // HAVE_VSX
|
||||
} // namespace
|
@ -127,7 +127,7 @@ class ConsistencyTestBase : public ::testing::Test {
|
||||
};
|
||||
|
||||
#if CONFIG_VP9_ENCODER
|
||||
typedef ::testing::tuple<int, int> ConsistencyParam;
|
||||
typedef std::tr1::tuple<int, int> ConsistencyParam;
|
||||
class ConsistencyVP9Test
|
||||
: public ConsistencyTestBase,
|
||||
public ::testing::WithParamInterface<ConsistencyParam> {
|
||||
@ -198,14 +198,14 @@ TEST_P(ConsistencyVP9Test, ConsistencyIsZero) {
|
||||
}
|
||||
#endif // CONFIG_VP9_ENCODER
|
||||
|
||||
using ::testing::make_tuple;
|
||||
using std::tr1::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)
|
||||
make_tuple(320, 240), make_tuple(318, 242), make_tuple(318, 238),
|
||||
};
|
||||
INSTANTIATE_TEST_CASE_P(C, ConsistencyVP9Test,
|
||||
::testing::ValuesIn(c_vp9_tests));
|
||||
|
@ -25,7 +25,6 @@
|
||||
#include "vpx_dsp/vpx_filter.h"
|
||||
#include "vpx_mem/vpx_mem.h"
|
||||
#include "vpx_ports/mem.h"
|
||||
#include "vpx_ports/vpx_timer.h"
|
||||
|
||||
namespace {
|
||||
|
||||
@ -33,9 +32,9 @@ static const unsigned int kMaxDimension = 64;
|
||||
|
||||
typedef void (*ConvolveFunc)(const uint8_t *src, ptrdiff_t src_stride,
|
||||
uint8_t *dst, ptrdiff_t dst_stride,
|
||||
const InterpKernel *filter, int x0_q4,
|
||||
int x_step_q4, int y0_q4, int y_step_q4, int w,
|
||||
int h);
|
||||
const int16_t *filter_x, int filter_x_stride,
|
||||
const int16_t *filter_y, int filter_y_stride,
|
||||
int w, int h);
|
||||
|
||||
typedef void (*WrapperFilterBlock2d8Func)(
|
||||
const uint8_t *src_ptr, const unsigned int src_stride,
|
||||
@ -77,7 +76,7 @@ struct ConvolveFunctions {
|
||||
int use_highbd_; // 0 if high bitdepth not used, else the actual bit depth.
|
||||
};
|
||||
|
||||
typedef ::testing::tuple<int, int, const ConvolveFunctions *> ConvolveParam;
|
||||
typedef std::tr1::tuple<int, int, const ConvolveFunctions *> ConvolveParam;
|
||||
|
||||
#define ALL_SIZES(convolve_fn) \
|
||||
make_tuple(4, 4, &convolve_fn), make_tuple(8, 4, &convolve_fn), \
|
||||
@ -301,9 +300,9 @@ void wrapper_filter_average_block2d_8_c(
|
||||
filter_average_block2d_8_c(src_ptr, src_stride, hfilter, vfilter, dst_ptr,
|
||||
dst_stride, output_width, output_height);
|
||||
} else {
|
||||
highbd_filter_average_block2d_8_c(CAST_TO_SHORTPTR(src_ptr), src_stride,
|
||||
highbd_filter_average_block2d_8_c(CONVERT_TO_SHORTPTR(src_ptr), src_stride,
|
||||
hfilter, vfilter,
|
||||
CAST_TO_SHORTPTR(dst_ptr), dst_stride,
|
||||
CONVERT_TO_SHORTPTR(dst_ptr), dst_stride,
|
||||
output_width, output_height, use_highbd);
|
||||
}
|
||||
#else
|
||||
@ -324,8 +323,8 @@ void wrapper_filter_block2d_8_c(const uint8_t *src_ptr,
|
||||
filter_block2d_8_c(src_ptr, src_stride, hfilter, vfilter, dst_ptr,
|
||||
dst_stride, output_width, output_height);
|
||||
} else {
|
||||
highbd_filter_block2d_8_c(CAST_TO_SHORTPTR(src_ptr), src_stride, hfilter,
|
||||
vfilter, CAST_TO_SHORTPTR(dst_ptr), dst_stride,
|
||||
highbd_filter_block2d_8_c(CONVERT_TO_SHORTPTR(src_ptr), src_stride, hfilter,
|
||||
vfilter, CONVERT_TO_SHORTPTR(dst_ptr), dst_stride,
|
||||
output_width, output_height, use_highbd);
|
||||
}
|
||||
#else
|
||||
@ -450,9 +449,7 @@ 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]);
|
||||
}
|
||||
}
|
||||
|
||||
@ -462,7 +459,7 @@ class ConvolveTest : public ::testing::TestWithParam<ConvolveParam> {
|
||||
if (UUT_->use_highbd_ == 0) {
|
||||
return input_ + offset;
|
||||
} else {
|
||||
return CAST_TO_BYTEPTR(input16_ + offset);
|
||||
return CONVERT_TO_BYTEPTR(input16_) + offset;
|
||||
}
|
||||
#else
|
||||
return input_ + offset;
|
||||
@ -475,7 +472,7 @@ class ConvolveTest : public ::testing::TestWithParam<ConvolveParam> {
|
||||
if (UUT_->use_highbd_ == 0) {
|
||||
return output_ + offset;
|
||||
} else {
|
||||
return CAST_TO_BYTEPTR(output16_ + offset);
|
||||
return CONVERT_TO_BYTEPTR(output16_) + offset;
|
||||
}
|
||||
#else
|
||||
return output_ + offset;
|
||||
@ -488,7 +485,7 @@ class ConvolveTest : public ::testing::TestWithParam<ConvolveParam> {
|
||||
if (UUT_->use_highbd_ == 0) {
|
||||
return output_ref_ + offset;
|
||||
} else {
|
||||
return CAST_TO_BYTEPTR(output16_ref_ + offset);
|
||||
return CONVERT_TO_BYTEPTR(output16_ref_) + offset;
|
||||
}
|
||||
#else
|
||||
return output_ref_ + offset;
|
||||
@ -500,7 +497,7 @@ class ConvolveTest : public ::testing::TestWithParam<ConvolveParam> {
|
||||
if (UUT_->use_highbd_ == 0) {
|
||||
return list[index];
|
||||
} else {
|
||||
return CAST_TO_SHORTPTR(list)[index];
|
||||
return CONVERT_TO_SHORTPTR(list)[index];
|
||||
}
|
||||
#else
|
||||
return list[index];
|
||||
@ -512,7 +509,7 @@ class ConvolveTest : public ::testing::TestWithParam<ConvolveParam> {
|
||||
if (UUT_->use_highbd_ == 0) {
|
||||
list[index] = (uint8_t)val;
|
||||
} else {
|
||||
CAST_TO_SHORTPTR(list)[index] = val;
|
||||
CONVERT_TO_SHORTPTR(list)[index] = val;
|
||||
}
|
||||
#else
|
||||
list[index] = (uint8_t)val;
|
||||
@ -542,167 +539,12 @@ uint16_t *ConvolveTest::output16_ref_ = NULL;
|
||||
|
||||
TEST_P(ConvolveTest, GuardBlocks) { CheckGuardBlocks(); }
|
||||
|
||||
TEST_P(ConvolveTest, DISABLED_Copy_Speed) {
|
||||
const uint8_t *const in = input();
|
||||
uint8_t *const out = output();
|
||||
const int kNumTests = 5000000;
|
||||
const int width = Width();
|
||||
const int height = Height();
|
||||
vpx_usec_timer timer;
|
||||
|
||||
vpx_usec_timer_start(&timer);
|
||||
for (int n = 0; n < kNumTests; ++n) {
|
||||
UUT_->copy_[0](in, kInputStride, out, kOutputStride, NULL, 0, 0, 0, 0,
|
||||
width, height);
|
||||
}
|
||||
vpx_usec_timer_mark(&timer);
|
||||
|
||||
const int elapsed_time = static_cast<int>(vpx_usec_timer_elapsed(&timer));
|
||||
printf("convolve_copy_%dx%d_%d: %d us\n", width, height,
|
||||
UUT_->use_highbd_ ? UUT_->use_highbd_ : 8, elapsed_time);
|
||||
}
|
||||
|
||||
TEST_P(ConvolveTest, DISABLED_Avg_Speed) {
|
||||
const uint8_t *const in = input();
|
||||
uint8_t *const out = output();
|
||||
const int kNumTests = 5000000;
|
||||
const int width = Width();
|
||||
const int height = Height();
|
||||
vpx_usec_timer timer;
|
||||
|
||||
vpx_usec_timer_start(&timer);
|
||||
for (int n = 0; n < kNumTests; ++n) {
|
||||
UUT_->copy_[1](in, kInputStride, out, kOutputStride, NULL, 0, 0, 0, 0,
|
||||
width, height);
|
||||
}
|
||||
vpx_usec_timer_mark(&timer);
|
||||
|
||||
const int elapsed_time = static_cast<int>(vpx_usec_timer_elapsed(&timer));
|
||||
printf("convolve_avg_%dx%d_%d: %d us\n", width, height,
|
||||
UUT_->use_highbd_ ? UUT_->use_highbd_ : 8, elapsed_time);
|
||||
}
|
||||
|
||||
TEST_P(ConvolveTest, DISABLED_Scale_Speed) {
|
||||
const uint8_t *const in = input();
|
||||
uint8_t *const out = output();
|
||||
const InterpKernel *const eighttap = vp9_filter_kernels[EIGHTTAP];
|
||||
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_->shv8_[0](in, kInputStride, out, kOutputStride, eighttap, 8, 16, 8, 16,
|
||||
width, height);
|
||||
}
|
||||
vpx_usec_timer_mark(&timer);
|
||||
|
||||
const int elapsed_time = static_cast<int>(vpx_usec_timer_elapsed(&timer));
|
||||
printf("convolve_scale_%dx%d_%d: %d us\n", width, height,
|
||||
UUT_->use_highbd_ ? UUT_->use_highbd_ : 8, elapsed_time);
|
||||
}
|
||||
|
||||
TEST_P(ConvolveTest, DISABLED_8Tap_Speed) {
|
||||
const uint8_t *const in = input();
|
||||
uint8_t *const out = output();
|
||||
const InterpKernel *const eighttap = vp9_filter_kernels[EIGHTTAP_SHARP];
|
||||
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, eighttap, 8, 16, 8, 16,
|
||||
width, height);
|
||||
}
|
||||
vpx_usec_timer_mark(&timer);
|
||||
|
||||
const int elapsed_time = static_cast<int>(vpx_usec_timer_elapsed(&timer));
|
||||
printf("convolve8_%dx%d_%d: %d us\n", width, height,
|
||||
UUT_->use_highbd_ ? UUT_->use_highbd_ : 8, elapsed_time);
|
||||
}
|
||||
|
||||
TEST_P(ConvolveTest, DISABLED_8Tap_Horiz_Speed) {
|
||||
const uint8_t *const in = input();
|
||||
uint8_t *const out = output();
|
||||
const InterpKernel *const eighttap = vp9_filter_kernels[EIGHTTAP_SHARP];
|
||||
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, eighttap, 8, 16, 8, 16,
|
||||
width, height);
|
||||
}
|
||||
vpx_usec_timer_mark(&timer);
|
||||
|
||||
const int elapsed_time = static_cast<int>(vpx_usec_timer_elapsed(&timer));
|
||||
printf("convolve8_horiz_%dx%d_%d: %d us\n", width, height,
|
||||
UUT_->use_highbd_ ? UUT_->use_highbd_ : 8, elapsed_time);
|
||||
}
|
||||
|
||||
TEST_P(ConvolveTest, DISABLED_8Tap_Vert_Speed) {
|
||||
const uint8_t *const in = input();
|
||||
uint8_t *const out = output();
|
||||
const InterpKernel *const eighttap = vp9_filter_kernels[EIGHTTAP_SHARP];
|
||||
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, eighttap, 8, 16, 8, 16,
|
||||
width, height);
|
||||
}
|
||||
vpx_usec_timer_mark(&timer);
|
||||
|
||||
const int elapsed_time = static_cast<int>(vpx_usec_timer_elapsed(&timer));
|
||||
printf("convolve8_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();
|
||||
const InterpKernel *const eighttap = vp9_filter_kernels[EIGHTTAP_SHARP];
|
||||
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_[1](in, kInputStride, out, kOutputStride, eighttap, 8, 16, 8, 16,
|
||||
width, height);
|
||||
}
|
||||
vpx_usec_timer_mark(&timer);
|
||||
|
||||
const int elapsed_time = static_cast<int>(vpx_usec_timer_elapsed(&timer));
|
||||
printf("convolve8_avg_%dx%d_%d: %d us\n", width, height,
|
||||
UUT_->use_highbd_ ? UUT_->use_highbd_ : 8, elapsed_time);
|
||||
}
|
||||
|
||||
TEST_P(ConvolveTest, Copy) {
|
||||
uint8_t *const in = input();
|
||||
uint8_t *const out = output();
|
||||
|
||||
ASM_REGISTER_STATE_CHECK(UUT_->copy_[0](in, kInputStride, out, kOutputStride,
|
||||
NULL, 0, 0, 0, 0, Width(), Height()));
|
||||
NULL, 0, NULL, 0, Width(), Height()));
|
||||
|
||||
CheckGuardBlocks();
|
||||
|
||||
@ -721,7 +563,7 @@ TEST_P(ConvolveTest, Avg) {
|
||||
CopyOutputToRef();
|
||||
|
||||
ASM_REGISTER_STATE_CHECK(UUT_->copy_[1](in, kInputStride, out, kOutputStride,
|
||||
NULL, 0, 0, 0, 0, Width(), Height()));
|
||||
NULL, 0, NULL, 0, Width(), Height()));
|
||||
|
||||
CheckGuardBlocks();
|
||||
|
||||
@ -738,10 +580,12 @@ TEST_P(ConvolveTest, Avg) {
|
||||
TEST_P(ConvolveTest, CopyHoriz) {
|
||||
uint8_t *const in = input();
|
||||
uint8_t *const out = output();
|
||||
DECLARE_ALIGNED(256, const int16_t,
|
||||
filter8[8]) = { 0, 0, 0, 128, 0, 0, 0, 0 };
|
||||
|
||||
ASM_REGISTER_STATE_CHECK(UUT_->sh8_[0](in, kInputStride, out, kOutputStride,
|
||||
vp9_filter_kernels[0], 0, 16, 0, 16,
|
||||
Width(), Height()));
|
||||
filter8, 16, filter8, 16, Width(),
|
||||
Height()));
|
||||
|
||||
CheckGuardBlocks();
|
||||
|
||||
@ -756,10 +600,12 @@ TEST_P(ConvolveTest, CopyHoriz) {
|
||||
TEST_P(ConvolveTest, CopyVert) {
|
||||
uint8_t *const in = input();
|
||||
uint8_t *const out = output();
|
||||
DECLARE_ALIGNED(256, const int16_t,
|
||||
filter8[8]) = { 0, 0, 0, 128, 0, 0, 0, 0 };
|
||||
|
||||
ASM_REGISTER_STATE_CHECK(UUT_->sv8_[0](in, kInputStride, out, kOutputStride,
|
||||
vp9_filter_kernels[0], 0, 16, 0, 16,
|
||||
Width(), Height()));
|
||||
filter8, 16, filter8, 16, Width(),
|
||||
Height()));
|
||||
|
||||
CheckGuardBlocks();
|
||||
|
||||
@ -774,10 +620,12 @@ TEST_P(ConvolveTest, CopyVert) {
|
||||
TEST_P(ConvolveTest, Copy2D) {
|
||||
uint8_t *const in = input();
|
||||
uint8_t *const out = output();
|
||||
DECLARE_ALIGNED(256, const int16_t,
|
||||
filter8[8]) = { 0, 0, 0, 128, 0, 0, 0, 0 };
|
||||
|
||||
ASM_REGISTER_STATE_CHECK(UUT_->shv8_[0](in, kInputStride, out, kOutputStride,
|
||||
vp9_filter_kernels[0], 0, 16, 0, 16,
|
||||
Width(), Height()));
|
||||
filter8, 16, filter8, 16, Width(),
|
||||
Height()));
|
||||
|
||||
CheckGuardBlocks();
|
||||
|
||||
@ -813,6 +661,7 @@ TEST(ConvolveTest, FiltersWontSaturateWhenAddedPairwise) {
|
||||
}
|
||||
}
|
||||
|
||||
const int16_t kInvalidFilter[8] = { 0 };
|
||||
const WrapperFilterBlock2d8Func wrapper_filter_block2d_8[2] = {
|
||||
wrapper_filter_block2d_8_c, wrapper_filter_average_block2d_8_c
|
||||
};
|
||||
@ -828,7 +677,7 @@ TEST_P(ConvolveTest, MatchesReferenceSubpixelFilter) {
|
||||
if (UUT_->use_highbd_ == 0) {
|
||||
ref = ref8;
|
||||
} else {
|
||||
ref = CAST_TO_BYTEPTR(ref16);
|
||||
ref = CONVERT_TO_BYTEPTR(ref16);
|
||||
}
|
||||
#else
|
||||
uint8_t ref[kOutputStride * kMaxDimension];
|
||||
@ -865,21 +714,21 @@ TEST_P(ConvolveTest, MatchesReferenceSubpixelFilter) {
|
||||
Width(), Height(), UUT_->use_highbd_);
|
||||
|
||||
if (filter_x && filter_y)
|
||||
ASM_REGISTER_STATE_CHECK(
|
||||
UUT_->hv8_[i](in, kInputStride, out, kOutputStride, filters,
|
||||
filter_x, 16, filter_y, 16, Width(), Height()));
|
||||
ASM_REGISTER_STATE_CHECK(UUT_->hv8_[i](
|
||||
in, kInputStride, out, kOutputStride, filters[filter_x], 16,
|
||||
filters[filter_y], 16, Width(), Height()));
|
||||
else if (filter_y)
|
||||
ASM_REGISTER_STATE_CHECK(
|
||||
UUT_->v8_[i](in, kInputStride, out, kOutputStride, filters, 0,
|
||||
16, filter_y, 16, Width(), Height()));
|
||||
ASM_REGISTER_STATE_CHECK(UUT_->v8_[i](
|
||||
in, kInputStride, out, kOutputStride, kInvalidFilter, 16,
|
||||
filters[filter_y], 16, Width(), Height()));
|
||||
else if (filter_x)
|
||||
ASM_REGISTER_STATE_CHECK(
|
||||
UUT_->h8_[i](in, kInputStride, out, kOutputStride, filters,
|
||||
filter_x, 16, 0, 16, Width(), Height()));
|
||||
ASM_REGISTER_STATE_CHECK(UUT_->h8_[i](
|
||||
in, kInputStride, out, kOutputStride, filters[filter_x], 16,
|
||||
kInvalidFilter, 16, Width(), Height()));
|
||||
else
|
||||
ASM_REGISTER_STATE_CHECK(UUT_->copy_[i](in, kInputStride, out,
|
||||
kOutputStride, NULL, 0, 0,
|
||||
0, 0, Width(), Height()));
|
||||
ASM_REGISTER_STATE_CHECK(UUT_->copy_[i](
|
||||
in, kInputStride, out, kOutputStride, kInvalidFilter, 0,
|
||||
kInvalidFilter, 0, Width(), Height()));
|
||||
|
||||
CheckGuardBlocks();
|
||||
|
||||
@ -907,7 +756,7 @@ TEST_P(ConvolveTest, FilterExtremes) {
|
||||
if (UUT_->use_highbd_ == 0) {
|
||||
ref = ref8;
|
||||
} else {
|
||||
ref = CAST_TO_BYTEPTR(ref16);
|
||||
ref = CONVERT_TO_BYTEPTR(ref16);
|
||||
}
|
||||
#else
|
||||
uint8_t ref[kOutputStride * kMaxDimension];
|
||||
@ -963,21 +812,21 @@ TEST_P(ConvolveTest, FilterExtremes) {
|
||||
filters[filter_y], ref, kOutputStride,
|
||||
Width(), Height(), UUT_->use_highbd_);
|
||||
if (filter_x && filter_y)
|
||||
ASM_REGISTER_STATE_CHECK(
|
||||
UUT_->hv8_[0](in, kInputStride, out, kOutputStride, filters,
|
||||
filter_x, 16, filter_y, 16, Width(), Height()));
|
||||
ASM_REGISTER_STATE_CHECK(UUT_->hv8_[0](
|
||||
in, kInputStride, out, kOutputStride, filters[filter_x], 16,
|
||||
filters[filter_y], 16, Width(), Height()));
|
||||
else if (filter_y)
|
||||
ASM_REGISTER_STATE_CHECK(
|
||||
UUT_->v8_[0](in, kInputStride, out, kOutputStride, filters, 0,
|
||||
16, filter_y, 16, Width(), Height()));
|
||||
ASM_REGISTER_STATE_CHECK(UUT_->v8_[0](
|
||||
in, kInputStride, out, kOutputStride, kInvalidFilter, 16,
|
||||
filters[filter_y], 16, Width(), Height()));
|
||||
else if (filter_x)
|
||||
ASM_REGISTER_STATE_CHECK(
|
||||
UUT_->h8_[0](in, kInputStride, out, kOutputStride, filters,
|
||||
filter_x, 16, 0, 16, Width(), Height()));
|
||||
ASM_REGISTER_STATE_CHECK(UUT_->h8_[0](
|
||||
in, kInputStride, out, kOutputStride, filters[filter_x], 16,
|
||||
kInvalidFilter, 16, Width(), Height()));
|
||||
else
|
||||
ASM_REGISTER_STATE_CHECK(UUT_->copy_[0](in, kInputStride, out,
|
||||
kOutputStride, NULL, 0, 0,
|
||||
0, 0, Width(), Height()));
|
||||
ASM_REGISTER_STATE_CHECK(UUT_->copy_[0](
|
||||
in, kInputStride, out, kOutputStride, kInvalidFilter, 0,
|
||||
kInvalidFilter, 0, Width(), Height()));
|
||||
|
||||
for (int y = 0; y < Height(); ++y) {
|
||||
for (int x = 0; x < Width(); ++x)
|
||||
@ -996,63 +845,44 @@ TEST_P(ConvolveTest, FilterExtremes) {
|
||||
|
||||
/* This test exercises that enough rows and columns are filtered with every
|
||||
possible initial fractional positions and scaling steps. */
|
||||
#if !CONFIG_VP9_HIGHBITDEPTH
|
||||
static const ConvolveFunc scaled_2d_c_funcs[2] = { vpx_scaled_2d_c,
|
||||
vpx_scaled_avg_2d_c };
|
||||
|
||||
TEST_P(ConvolveTest, CheckScalingFiltering) {
|
||||
uint8_t *const in = input();
|
||||
uint8_t *const out = output();
|
||||
uint8_t ref[kOutputStride * kMaxDimension];
|
||||
const InterpKernel *const eighttap = vp9_filter_kernels[EIGHTTAP];
|
||||
|
||||
::libvpx_test::ACMRandom prng;
|
||||
for (int y = 0; y < Height(); ++y) {
|
||||
for (int x = 0; x < Width(); ++x) {
|
||||
const uint16_t r = prng.Rand8Extremes();
|
||||
assign_val(in, y * kInputStride + x, r);
|
||||
}
|
||||
}
|
||||
SetConstantInput(127);
|
||||
|
||||
for (int i = 0; i < 2; ++i) {
|
||||
for (INTERP_FILTER filter_type = 0; filter_type < 4; ++filter_type) {
|
||||
const InterpKernel *const eighttap = vp9_filter_kernels[filter_type];
|
||||
for (int frac = 0; frac < 16; ++frac) {
|
||||
for (int step = 1; step <= 32; ++step) {
|
||||
/* Test the horizontal and vertical filters in combination. */
|
||||
scaled_2d_c_funcs[i](in, kInputStride, ref, kOutputStride, eighttap,
|
||||
frac, step, frac, step, Width(), Height());
|
||||
ASM_REGISTER_STATE_CHECK(
|
||||
UUT_->shv8_[i](in, kInputStride, out, kOutputStride, eighttap,
|
||||
frac, step, frac, step, Width(), Height()));
|
||||
for (int frac = 0; frac < 16; ++frac) {
|
||||
for (int step = 1; step <= 32; ++step) {
|
||||
/* Test the horizontal and vertical filters in combination. */
|
||||
ASM_REGISTER_STATE_CHECK(
|
||||
UUT_->shv8_[0](in, kInputStride, out, kOutputStride, eighttap[frac],
|
||||
step, eighttap[frac], step, Width(), Height()));
|
||||
|
||||
CheckGuardBlocks();
|
||||
CheckGuardBlocks();
|
||||
|
||||
for (int y = 0; y < Height(); ++y) {
|
||||
for (int x = 0; x < Width(); ++x) {
|
||||
ASSERT_EQ(lookup(ref, y * kOutputStride + x),
|
||||
lookup(out, y * kOutputStride + x))
|
||||
<< "x == " << x << ", y == " << y << ", frac == " << frac
|
||||
<< ", step == " << step;
|
||||
}
|
||||
}
|
||||
for (int y = 0; y < Height(); ++y) {
|
||||
for (int x = 0; x < Width(); ++x) {
|
||||
ASSERT_EQ(lookup(in, y * kInputStride + x),
|
||||
lookup(out, y * kOutputStride + x))
|
||||
<< "x == " << x << ", y == " << y << ", frac == " << frac
|
||||
<< ", step == " << step;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
using ::testing::make_tuple;
|
||||
using std::tr1::make_tuple;
|
||||
|
||||
#if CONFIG_VP9_HIGHBITDEPTH
|
||||
#define WRAP(func, bd) \
|
||||
void wrap_##func##_##bd( \
|
||||
const uint8_t *src, ptrdiff_t src_stride, uint8_t *dst, \
|
||||
ptrdiff_t dst_stride, const InterpKernel *filter, int x0_q4, \
|
||||
int x_step_q4, int y0_q4, int y_step_q4, int w, int h) { \
|
||||
vpx_highbd_##func(reinterpret_cast<const uint16_t *>(src), src_stride, \
|
||||
reinterpret_cast<uint16_t *>(dst), dst_stride, filter, \
|
||||
x0_q4, x_step_q4, y0_q4, y_step_q4, w, h, bd); \
|
||||
ptrdiff_t dst_stride, const int16_t *filter_x, int filter_x_stride, \
|
||||
const int16_t *filter_y, int filter_y_stride, int w, int h) { \
|
||||
vpx_highbd_##func(src, src_stride, dst, dst_stride, filter_x, \
|
||||
filter_x_stride, filter_y, filter_y_stride, w, h, bd); \
|
||||
}
|
||||
|
||||
#if HAVE_SSE2 && ARCH_X86_64
|
||||
@ -1082,35 +912,6 @@ WRAP(convolve8_sse2, 12)
|
||||
WRAP(convolve8_avg_sse2, 12)
|
||||
#endif // HAVE_SSE2 && ARCH_X86_64
|
||||
|
||||
#if HAVE_AVX2
|
||||
WRAP(convolve_copy_avx2, 8)
|
||||
WRAP(convolve_avg_avx2, 8)
|
||||
WRAP(convolve8_horiz_avx2, 8)
|
||||
WRAP(convolve8_avg_horiz_avx2, 8)
|
||||
WRAP(convolve8_vert_avx2, 8)
|
||||
WRAP(convolve8_avg_vert_avx2, 8)
|
||||
WRAP(convolve8_avx2, 8)
|
||||
WRAP(convolve8_avg_avx2, 8)
|
||||
|
||||
WRAP(convolve_copy_avx2, 10)
|
||||
WRAP(convolve_avg_avx2, 10)
|
||||
WRAP(convolve8_avx2, 10)
|
||||
WRAP(convolve8_horiz_avx2, 10)
|
||||
WRAP(convolve8_vert_avx2, 10)
|
||||
WRAP(convolve8_avg_avx2, 10)
|
||||
WRAP(convolve8_avg_horiz_avx2, 10)
|
||||
WRAP(convolve8_avg_vert_avx2, 10)
|
||||
|
||||
WRAP(convolve_copy_avx2, 12)
|
||||
WRAP(convolve_avg_avx2, 12)
|
||||
WRAP(convolve8_avx2, 12)
|
||||
WRAP(convolve8_horiz_avx2, 12)
|
||||
WRAP(convolve8_vert_avx2, 12)
|
||||
WRAP(convolve8_avg_avx2, 12)
|
||||
WRAP(convolve8_avg_horiz_avx2, 12)
|
||||
WRAP(convolve8_avg_vert_avx2, 12)
|
||||
#endif // HAVE_AVX2
|
||||
|
||||
#if HAVE_NEON
|
||||
WRAP(convolve_copy_neon, 8)
|
||||
WRAP(convolve_avg_neon, 8)
|
||||
@ -1256,48 +1057,18 @@ INSTANTIATE_TEST_CASE_P(SSSE3, ConvolveTest,
|
||||
::testing::ValuesIn(kArrayConvolve8_ssse3));
|
||||
#endif
|
||||
|
||||
#if HAVE_AVX2
|
||||
#if CONFIG_VP9_HIGHBITDEPTH
|
||||
const ConvolveFunctions convolve8_avx2(
|
||||
wrap_convolve_copy_avx2_8, wrap_convolve_avg_avx2_8,
|
||||
wrap_convolve8_horiz_avx2_8, wrap_convolve8_avg_horiz_avx2_8,
|
||||
wrap_convolve8_vert_avx2_8, wrap_convolve8_avg_vert_avx2_8,
|
||||
wrap_convolve8_avx2_8, wrap_convolve8_avg_avx2_8, wrap_convolve8_horiz_c_8,
|
||||
wrap_convolve8_avg_horiz_c_8, wrap_convolve8_vert_c_8,
|
||||
wrap_convolve8_avg_vert_c_8, wrap_convolve8_c_8, wrap_convolve8_avg_c_8, 8);
|
||||
const ConvolveFunctions convolve10_avx2(
|
||||
wrap_convolve_copy_avx2_10, wrap_convolve_avg_avx2_10,
|
||||
wrap_convolve8_horiz_avx2_10, wrap_convolve8_avg_horiz_avx2_10,
|
||||
wrap_convolve8_vert_avx2_10, wrap_convolve8_avg_vert_avx2_10,
|
||||
wrap_convolve8_avx2_10, wrap_convolve8_avg_avx2_10,
|
||||
wrap_convolve8_horiz_c_10, wrap_convolve8_avg_horiz_c_10,
|
||||
wrap_convolve8_vert_c_10, wrap_convolve8_avg_vert_c_10, wrap_convolve8_c_10,
|
||||
wrap_convolve8_avg_c_10, 10);
|
||||
const ConvolveFunctions convolve12_avx2(
|
||||
wrap_convolve_copy_avx2_12, wrap_convolve_avg_avx2_12,
|
||||
wrap_convolve8_horiz_avx2_12, wrap_convolve8_avg_horiz_avx2_12,
|
||||
wrap_convolve8_vert_avx2_12, wrap_convolve8_avg_vert_avx2_12,
|
||||
wrap_convolve8_avx2_12, wrap_convolve8_avg_avx2_12,
|
||||
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 kArrayConvolve8_avx2[] = { ALL_SIZES(convolve8_avx2),
|
||||
ALL_SIZES(convolve10_avx2),
|
||||
ALL_SIZES(convolve12_avx2) };
|
||||
INSTANTIATE_TEST_CASE_P(AVX2, ConvolveTest,
|
||||
::testing::ValuesIn(kArrayConvolve8_avx2));
|
||||
#else // !CONFIG_VP9_HIGHBITDEPTH
|
||||
#if HAVE_AVX2 && HAVE_SSSE3
|
||||
const ConvolveFunctions convolve8_avx2(
|
||||
vpx_convolve_copy_c, vpx_convolve_avg_c, vpx_convolve8_horiz_avx2,
|
||||
vpx_convolve8_avg_horiz_avx2, vpx_convolve8_vert_avx2,
|
||||
vpx_convolve8_avg_vert_avx2, vpx_convolve8_avx2, vpx_convolve8_avg_avx2,
|
||||
vpx_convolve8_avg_horiz_ssse3, vpx_convolve8_vert_avx2,
|
||||
vpx_convolve8_avg_vert_ssse3, vpx_convolve8_avx2, vpx_convolve8_avg_ssse3,
|
||||
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 kArrayConvolve8_avx2[] = { ALL_SIZES(convolve8_avx2) };
|
||||
INSTANTIATE_TEST_CASE_P(AVX2, ConvolveTest,
|
||||
::testing::ValuesIn(kArrayConvolve8_avx2));
|
||||
#endif // CONFIG_VP9_HIGHBITDEPTH
|
||||
#endif // HAVE_AVX2
|
||||
#endif // HAVE_AVX2 && HAVE_SSSE3
|
||||
|
||||
#if HAVE_NEON
|
||||
#if CONFIG_VP9_HIGHBITDEPTH
|
||||
@ -1334,7 +1105,7 @@ const ConvolveFunctions convolve8_neon(
|
||||
vpx_convolve8_avg_horiz_neon, vpx_convolve8_vert_neon,
|
||||
vpx_convolve8_avg_vert_neon, vpx_convolve8_neon, vpx_convolve8_avg_neon,
|
||||
vpx_scaled_horiz_c, vpx_scaled_avg_horiz_c, vpx_scaled_vert_c,
|
||||
vpx_scaled_avg_vert_c, vpx_scaled_2d_neon, vpx_scaled_avg_2d_c, 0);
|
||||
vpx_scaled_avg_vert_c, vpx_scaled_2d_c, vpx_scaled_avg_2d_c, 0);
|
||||
|
||||
const ConvolveParam kArrayConvolve_neon[] = { ALL_SIZES(convolve8_neon) };
|
||||
#endif // CONFIG_VP9_HIGHBITDEPTH
|
||||
@ -1361,34 +1132,10 @@ const ConvolveFunctions convolve8_msa(
|
||||
vpx_convolve8_avg_horiz_msa, vpx_convolve8_vert_msa,
|
||||
vpx_convolve8_avg_vert_msa, vpx_convolve8_msa, vpx_convolve8_avg_msa,
|
||||
vpx_scaled_horiz_c, vpx_scaled_avg_horiz_c, vpx_scaled_vert_c,
|
||||
vpx_scaled_avg_vert_c, vpx_scaled_2d_msa, vpx_scaled_avg_2d_c, 0);
|
||||
vpx_scaled_avg_vert_c, vpx_scaled_2d_c, vpx_scaled_avg_2d_c, 0);
|
||||
|
||||
const ConvolveParam kArrayConvolve8_msa[] = { ALL_SIZES(convolve8_msa) };
|
||||
INSTANTIATE_TEST_CASE_P(MSA, ConvolveTest,
|
||||
::testing::ValuesIn(kArrayConvolve8_msa));
|
||||
#endif // HAVE_MSA
|
||||
|
||||
#if HAVE_VSX
|
||||
const ConvolveFunctions convolve8_vsx(
|
||||
vpx_convolve_copy_vsx, vpx_convolve_avg_vsx, vpx_convolve8_horiz_vsx,
|
||||
vpx_convolve8_avg_horiz_vsx, vpx_convolve8_vert_vsx,
|
||||
vpx_convolve8_avg_vert_vsx, vpx_convolve8_vsx, vpx_convolve8_avg_vsx,
|
||||
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_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_c, vpx_convolve8_horiz_mmi,
|
||||
vpx_convolve8_avg_horiz_c, 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
|
||||
|
1405
test/datarate_test.cc
Normal file
1405
test/datarate_test.cc
Normal file
File diff suppressed because it is too large
Load Diff
@ -229,10 +229,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 ::testing::tuple<FdctFunc, IdctFunc, int, vpx_bit_depth_t>
|
||||
Dct16x16Param;
|
||||
typedef ::testing::tuple<FhtFunc, IhtFunc, int, vpx_bit_depth_t> Ht16x16Param;
|
||||
typedef ::testing::tuple<IdctFunc, IdctFunc, int, vpx_bit_depth_t>
|
||||
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;
|
||||
|
||||
void fdct16x16_ref(const int16_t *in, tran_low_t *out, int stride,
|
||||
@ -256,11 +255,11 @@ void iht16x16_ref(const tran_low_t *in, uint8_t *dest, int stride,
|
||||
|
||||
#if CONFIG_VP9_HIGHBITDEPTH
|
||||
void idct16x16_10(const tran_low_t *in, uint8_t *out, int stride) {
|
||||
vpx_highbd_idct16x16_256_add_c(in, CAST_TO_SHORTPTR(out), stride, 10);
|
||||
vpx_highbd_idct16x16_256_add_c(in, out, stride, 10);
|
||||
}
|
||||
|
||||
void idct16x16_12(const tran_low_t *in, uint8_t *out, int stride) {
|
||||
vpx_highbd_idct16x16_256_add_c(in, CAST_TO_SHORTPTR(out), stride, 12);
|
||||
vpx_highbd_idct16x16_256_add_c(in, out, stride, 12);
|
||||
}
|
||||
|
||||
void idct16x16_10_ref(const tran_low_t *in, uint8_t *out, int stride,
|
||||
@ -274,36 +273,36 @@ void idct16x16_12_ref(const tran_low_t *in, uint8_t *out, int stride,
|
||||
}
|
||||
|
||||
void iht16x16_10(const tran_low_t *in, uint8_t *out, int stride, int tx_type) {
|
||||
vp9_highbd_iht16x16_256_add_c(in, CAST_TO_SHORTPTR(out), stride, tx_type, 10);
|
||||
vp9_highbd_iht16x16_256_add_c(in, out, stride, tx_type, 10);
|
||||
}
|
||||
|
||||
void iht16x16_12(const tran_low_t *in, uint8_t *out, int stride, int tx_type) {
|
||||
vp9_highbd_iht16x16_256_add_c(in, CAST_TO_SHORTPTR(out), stride, tx_type, 12);
|
||||
vp9_highbd_iht16x16_256_add_c(in, out, stride, tx_type, 12);
|
||||
}
|
||||
|
||||
#if HAVE_SSE2
|
||||
void idct16x16_10_add_10_c(const tran_low_t *in, uint8_t *out, int stride) {
|
||||
vpx_highbd_idct16x16_10_add_c(in, CAST_TO_SHORTPTR(out), stride, 10);
|
||||
vpx_highbd_idct16x16_10_add_c(in, out, stride, 10);
|
||||
}
|
||||
|
||||
void idct16x16_10_add_12_c(const tran_low_t *in, uint8_t *out, int stride) {
|
||||
vpx_highbd_idct16x16_10_add_c(in, CAST_TO_SHORTPTR(out), stride, 12);
|
||||
vpx_highbd_idct16x16_10_add_c(in, out, stride, 12);
|
||||
}
|
||||
|
||||
void idct16x16_256_add_10_sse2(const tran_low_t *in, uint8_t *out, int stride) {
|
||||
vpx_highbd_idct16x16_256_add_sse2(in, CAST_TO_SHORTPTR(out), stride, 10);
|
||||
vpx_highbd_idct16x16_256_add_sse2(in, out, stride, 10);
|
||||
}
|
||||
|
||||
void idct16x16_256_add_12_sse2(const tran_low_t *in, uint8_t *out, int stride) {
|
||||
vpx_highbd_idct16x16_256_add_sse2(in, CAST_TO_SHORTPTR(out), stride, 12);
|
||||
vpx_highbd_idct16x16_256_add_sse2(in, out, stride, 12);
|
||||
}
|
||||
|
||||
void idct16x16_10_add_10_sse2(const tran_low_t *in, uint8_t *out, int stride) {
|
||||
vpx_highbd_idct16x16_10_add_sse2(in, CAST_TO_SHORTPTR(out), stride, 10);
|
||||
vpx_highbd_idct16x16_10_add_sse2(in, out, stride, 10);
|
||||
}
|
||||
|
||||
void idct16x16_10_add_12_sse2(const tran_low_t *in, uint8_t *out, int stride) {
|
||||
vpx_highbd_idct16x16_10_add_sse2(in, CAST_TO_SHORTPTR(out), stride, 12);
|
||||
vpx_highbd_idct16x16_10_add_sse2(in, out, stride, 12);
|
||||
}
|
||||
#endif // HAVE_SSE2
|
||||
#endif // CONFIG_VP9_HIGHBITDEPTH
|
||||
@ -354,7 +353,7 @@ class Trans16x16TestBase {
|
||||
#if CONFIG_VP9_HIGHBITDEPTH
|
||||
} else {
|
||||
ASM_REGISTER_STATE_CHECK(
|
||||
RunInvTxfm(test_temp_block, CAST_TO_BYTEPTR(dst16), pitch_));
|
||||
RunInvTxfm(test_temp_block, CONVERT_TO_BYTEPTR(dst16), pitch_));
|
||||
#endif
|
||||
}
|
||||
|
||||
@ -476,10 +475,10 @@ class Trans16x16TestBase {
|
||||
ASM_REGISTER_STATE_CHECK(RunInvTxfm(output_ref_block, dst, pitch_));
|
||||
#if CONFIG_VP9_HIGHBITDEPTH
|
||||
} else {
|
||||
inv_txfm_ref(output_ref_block, CAST_TO_BYTEPTR(ref16), pitch_,
|
||||
inv_txfm_ref(output_ref_block, CONVERT_TO_BYTEPTR(ref16), pitch_,
|
||||
tx_type_);
|
||||
ASM_REGISTER_STATE_CHECK(
|
||||
RunInvTxfm(output_ref_block, CAST_TO_BYTEPTR(dst16), pitch_));
|
||||
RunInvTxfm(output_ref_block, CONVERT_TO_BYTEPTR(dst16), pitch_));
|
||||
#endif
|
||||
}
|
||||
if (bit_depth_ == VPX_BITS_8) {
|
||||
@ -531,7 +530,8 @@ class Trans16x16TestBase {
|
||||
ASM_REGISTER_STATE_CHECK(RunInvTxfm(coeff, dst, 16));
|
||||
#if CONFIG_VP9_HIGHBITDEPTH
|
||||
} else {
|
||||
ASM_REGISTER_STATE_CHECK(RunInvTxfm(coeff, CAST_TO_BYTEPTR(dst16), 16));
|
||||
ASM_REGISTER_STATE_CHECK(
|
||||
RunInvTxfm(coeff, CONVERT_TO_BYTEPTR(dst16), 16));
|
||||
#endif // CONFIG_VP9_HIGHBITDEPTH
|
||||
}
|
||||
|
||||
@ -543,8 +543,8 @@ class Trans16x16TestBase {
|
||||
const uint32_t diff = dst[j] - src[j];
|
||||
#endif // CONFIG_VP9_HIGHBITDEPTH
|
||||
const uint32_t error = diff * diff;
|
||||
EXPECT_GE(1u, error)
|
||||
<< "Error: 16x16 IDCT has error " << error << " at index " << j;
|
||||
EXPECT_GE(1u, error) << "Error: 16x16 IDCT has error " << error
|
||||
<< " at index " << j;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -585,9 +585,9 @@ class Trans16x16TestBase {
|
||||
ASM_REGISTER_STATE_CHECK(RunInvTxfm(coeff, dst, pitch_));
|
||||
} else {
|
||||
#if CONFIG_VP9_HIGHBITDEPTH
|
||||
ref_txfm(coeff, CAST_TO_BYTEPTR(ref16), pitch_);
|
||||
ref_txfm(coeff, CONVERT_TO_BYTEPTR(ref16), pitch_);
|
||||
ASM_REGISTER_STATE_CHECK(
|
||||
RunInvTxfm(coeff, CAST_TO_BYTEPTR(dst16), pitch_));
|
||||
RunInvTxfm(coeff, CONVERT_TO_BYTEPTR(dst16), pitch_));
|
||||
#endif // CONFIG_VP9_HIGHBITDEPTH
|
||||
}
|
||||
|
||||
@ -745,7 +745,67 @@ TEST_P(InvTrans16x16DCT, CompareReference) {
|
||||
CompareInvReference(ref_txfm_, thresh_);
|
||||
}
|
||||
|
||||
using ::testing::make_tuple;
|
||||
class PartialTrans16x16Test : public ::testing::TestWithParam<
|
||||
std::tr1::tuple<FdctFunc, vpx_bit_depth_t> > {
|
||||
public:
|
||||
virtual ~PartialTrans16x16Test() {}
|
||||
virtual void SetUp() {
|
||||
fwd_txfm_ = GET_PARAM(0);
|
||||
bit_depth_ = GET_PARAM(1);
|
||||
}
|
||||
|
||||
virtual void TearDown() { libvpx_test::ClearSystemState(); }
|
||||
|
||||
protected:
|
||||
vpx_bit_depth_t bit_depth_;
|
||||
FdctFunc fwd_txfm_;
|
||||
};
|
||||
|
||||
TEST_P(PartialTrans16x16Test, Extremes) {
|
||||
#if CONFIG_VP9_HIGHBITDEPTH
|
||||
const int16_t maxval =
|
||||
static_cast<int16_t>(clip_pixel_highbd(1 << 30, bit_depth_));
|
||||
#else
|
||||
const int16_t maxval = 255;
|
||||
#endif
|
||||
const int minval = -maxval;
|
||||
DECLARE_ALIGNED(16, int16_t, input[kNumCoeffs]);
|
||||
DECLARE_ALIGNED(16, tran_low_t, output[kNumCoeffs]);
|
||||
|
||||
for (int i = 0; i < kNumCoeffs; ++i) input[i] = maxval;
|
||||
output[0] = 0;
|
||||
ASM_REGISTER_STATE_CHECK(fwd_txfm_(input, output, 16));
|
||||
EXPECT_EQ((maxval * kNumCoeffs) >> 1, output[0]);
|
||||
|
||||
for (int i = 0; i < kNumCoeffs; ++i) input[i] = minval;
|
||||
output[0] = 0;
|
||||
ASM_REGISTER_STATE_CHECK(fwd_txfm_(input, output, 16));
|
||||
EXPECT_EQ((minval * kNumCoeffs) >> 1, output[0]);
|
||||
}
|
||||
|
||||
TEST_P(PartialTrans16x16Test, Random) {
|
||||
#if CONFIG_VP9_HIGHBITDEPTH
|
||||
const int16_t maxval =
|
||||
static_cast<int16_t>(clip_pixel_highbd(1 << 30, bit_depth_));
|
||||
#else
|
||||
const int16_t maxval = 255;
|
||||
#endif
|
||||
DECLARE_ALIGNED(16, int16_t, input[kNumCoeffs]);
|
||||
DECLARE_ALIGNED(16, tran_low_t, output[kNumCoeffs]);
|
||||
ACMRandom rnd(ACMRandom::DeterministicSeed());
|
||||
|
||||
int sum = 0;
|
||||
for (int i = 0; i < kNumCoeffs; ++i) {
|
||||
const int val = (i & 1) ? -rnd(maxval + 1) : rnd(maxval + 1);
|
||||
input[i] = val;
|
||||
sum += val;
|
||||
}
|
||||
output[0] = 0;
|
||||
ASM_REGISTER_STATE_CHECK(fwd_txfm_(input, output, 16));
|
||||
EXPECT_EQ(sum >> 1, output[0]);
|
||||
}
|
||||
|
||||
using std::tr1::make_tuple;
|
||||
|
||||
#if CONFIG_VP9_HIGHBITDEPTH
|
||||
INSTANTIATE_TEST_CASE_P(
|
||||
@ -777,6 +837,11 @@ INSTANTIATE_TEST_CASE_P(
|
||||
make_tuple(&vp9_fht16x16_c, &vp9_iht16x16_256_add_c, 1, VPX_BITS_8),
|
||||
make_tuple(&vp9_fht16x16_c, &vp9_iht16x16_256_add_c, 2, VPX_BITS_8),
|
||||
make_tuple(&vp9_fht16x16_c, &vp9_iht16x16_256_add_c, 3, VPX_BITS_8)));
|
||||
INSTANTIATE_TEST_CASE_P(
|
||||
C, PartialTrans16x16Test,
|
||||
::testing::Values(make_tuple(&vpx_highbd_fdct16x16_1_c, VPX_BITS_8),
|
||||
make_tuple(&vpx_highbd_fdct16x16_1_c, VPX_BITS_10),
|
||||
make_tuple(&vpx_highbd_fdct16x16_1_c, VPX_BITS_12)));
|
||||
#else
|
||||
INSTANTIATE_TEST_CASE_P(
|
||||
C, Trans16x16HT,
|
||||
@ -785,14 +850,17 @@ INSTANTIATE_TEST_CASE_P(
|
||||
make_tuple(&vp9_fht16x16_c, &vp9_iht16x16_256_add_c, 1, VPX_BITS_8),
|
||||
make_tuple(&vp9_fht16x16_c, &vp9_iht16x16_256_add_c, 2, VPX_BITS_8),
|
||||
make_tuple(&vp9_fht16x16_c, &vp9_iht16x16_256_add_c, 3, VPX_BITS_8)));
|
||||
INSTANTIATE_TEST_CASE_P(C, PartialTrans16x16Test,
|
||||
::testing::Values(make_tuple(&vpx_fdct16x16_1_c,
|
||||
VPX_BITS_8)));
|
||||
#endif // CONFIG_VP9_HIGHBITDEPTH
|
||||
|
||||
#if HAVE_NEON && !CONFIG_EMULATE_HARDWARE
|
||||
#if HAVE_NEON && !CONFIG_VP9_HIGHBITDEPTH && !CONFIG_EMULATE_HARDWARE
|
||||
INSTANTIATE_TEST_CASE_P(
|
||||
NEON, Trans16x16DCT,
|
||||
::testing::Values(make_tuple(&vpx_fdct16x16_neon,
|
||||
&vpx_idct16x16_256_add_neon, 0, VPX_BITS_8)));
|
||||
#endif // HAVE_NEON && !CONFIG_EMULATE_HARDWARE
|
||||
::testing::Values(make_tuple(&vpx_fdct16x16_c, &vpx_idct16x16_256_add_neon,
|
||||
0, VPX_BITS_8)));
|
||||
#endif
|
||||
|
||||
#if HAVE_SSE2 && !CONFIG_VP9_HIGHBITDEPTH && !CONFIG_EMULATE_HARDWARE
|
||||
INSTANTIATE_TEST_CASE_P(
|
||||
@ -809,6 +877,9 @@ INSTANTIATE_TEST_CASE_P(
|
||||
2, VPX_BITS_8),
|
||||
make_tuple(&vp9_fht16x16_sse2, &vp9_iht16x16_256_add_sse2,
|
||||
3, VPX_BITS_8)));
|
||||
INSTANTIATE_TEST_CASE_P(SSE2, PartialTrans16x16Test,
|
||||
::testing::Values(make_tuple(&vpx_fdct16x16_1_sse2,
|
||||
VPX_BITS_8)));
|
||||
#endif // HAVE_SSE2 && !CONFIG_VP9_HIGHBITDEPTH && !CONFIG_EMULATE_HARDWARE
|
||||
|
||||
#if HAVE_SSE2 && CONFIG_VP9_HIGHBITDEPTH && !CONFIG_EMULATE_HARDWARE
|
||||
@ -843,6 +914,9 @@ INSTANTIATE_TEST_CASE_P(
|
||||
&idct16x16_10_add_12_sse2, 3167, VPX_BITS_12),
|
||||
make_tuple(&idct16x16_12, &idct16x16_256_add_12_sse2,
|
||||
3167, VPX_BITS_12)));
|
||||
INSTANTIATE_TEST_CASE_P(SSE2, PartialTrans16x16Test,
|
||||
::testing::Values(make_tuple(&vpx_fdct16x16_1_sse2,
|
||||
VPX_BITS_8)));
|
||||
#endif // HAVE_SSE2 && CONFIG_VP9_HIGHBITDEPTH && !CONFIG_EMULATE_HARDWARE
|
||||
|
||||
#if HAVE_MSA && !CONFIG_VP9_HIGHBITDEPTH && !CONFIG_EMULATE_HARDWARE
|
||||
@ -858,12 +932,8 @@ INSTANTIATE_TEST_CASE_P(
|
||||
make_tuple(&vp9_fht16x16_msa, &vp9_iht16x16_256_add_msa, 2, VPX_BITS_8),
|
||||
make_tuple(&vp9_fht16x16_msa, &vp9_iht16x16_256_add_msa, 3,
|
||||
VPX_BITS_8)));
|
||||
INSTANTIATE_TEST_CASE_P(MSA, PartialTrans16x16Test,
|
||||
::testing::Values(make_tuple(&vpx_fdct16x16_1_msa,
|
||||
VPX_BITS_8)));
|
||||
#endif // HAVE_MSA && !CONFIG_VP9_HIGHBITDEPTH && !CONFIG_EMULATE_HARDWARE
|
||||
|
||||
#if HAVE_VSX && !CONFIG_VP9_HIGHBITDEPTH && !CONFIG_EMULATE_HARDWARE
|
||||
INSTANTIATE_TEST_CASE_P(VSX, Trans16x16DCT,
|
||||
::testing::Values(make_tuple(&vpx_fdct16x16_c,
|
||||
&vpx_idct16x16_256_add_vsx,
|
||||
0, VPX_BITS_8)));
|
||||
#endif // HAVE_VSX && !CONFIG_VP9_HIGHBITDEPTH && !CONFIG_EMULATE_HARDWARE
|
||||
} // namespace
|
||||
|
@ -66,16 +66,16 @@ 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 ::testing::tuple<FwdTxfmFunc, InvTxfmFunc, int, vpx_bit_depth_t>
|
||||
typedef std::tr1::tuple<FwdTxfmFunc, InvTxfmFunc, int, vpx_bit_depth_t>
|
||||
Trans32x32Param;
|
||||
|
||||
#if CONFIG_VP9_HIGHBITDEPTH
|
||||
void idct32x32_10(const tran_low_t *in, uint8_t *out, int stride) {
|
||||
vpx_highbd_idct32x32_1024_add_c(in, CAST_TO_SHORTPTR(out), stride, 10);
|
||||
vpx_highbd_idct32x32_1024_add_c(in, out, stride, 10);
|
||||
}
|
||||
|
||||
void idct32x32_12(const tran_low_t *in, uint8_t *out, int stride) {
|
||||
vpx_highbd_idct32x32_1024_add_c(in, CAST_TO_SHORTPTR(out), stride, 12);
|
||||
vpx_highbd_idct32x32_1024_add_c(in, out, stride, 12);
|
||||
}
|
||||
#endif // CONFIG_VP9_HIGHBITDEPTH
|
||||
|
||||
@ -137,7 +137,7 @@ TEST_P(Trans32x32Test, AccuracyCheck) {
|
||||
#if CONFIG_VP9_HIGHBITDEPTH
|
||||
} else {
|
||||
ASM_REGISTER_STATE_CHECK(
|
||||
inv_txfm_(test_temp_block, CAST_TO_BYTEPTR(dst16), 32));
|
||||
inv_txfm_(test_temp_block, CONVERT_TO_BYTEPTR(dst16), 32));
|
||||
#endif
|
||||
}
|
||||
|
||||
@ -275,7 +275,7 @@ TEST_P(Trans32x32Test, InverseAccuracy) {
|
||||
ASM_REGISTER_STATE_CHECK(inv_txfm_(coeff, dst, 32));
|
||||
#if CONFIG_VP9_HIGHBITDEPTH
|
||||
} else {
|
||||
ASM_REGISTER_STATE_CHECK(inv_txfm_(coeff, CAST_TO_BYTEPTR(dst16), 32));
|
||||
ASM_REGISTER_STATE_CHECK(inv_txfm_(coeff, CONVERT_TO_BYTEPTR(dst16), 32));
|
||||
#endif
|
||||
}
|
||||
for (int j = 0; j < kNumCoeffs; ++j) {
|
||||
@ -292,7 +292,68 @@ TEST_P(Trans32x32Test, InverseAccuracy) {
|
||||
}
|
||||
}
|
||||
|
||||
using ::testing::make_tuple;
|
||||
class PartialTrans32x32Test
|
||||
: public ::testing::TestWithParam<
|
||||
std::tr1::tuple<FwdTxfmFunc, vpx_bit_depth_t> > {
|
||||
public:
|
||||
virtual ~PartialTrans32x32Test() {}
|
||||
virtual void SetUp() {
|
||||
fwd_txfm_ = GET_PARAM(0);
|
||||
bit_depth_ = GET_PARAM(1);
|
||||
}
|
||||
|
||||
virtual void TearDown() { libvpx_test::ClearSystemState(); }
|
||||
|
||||
protected:
|
||||
vpx_bit_depth_t bit_depth_;
|
||||
FwdTxfmFunc fwd_txfm_;
|
||||
};
|
||||
|
||||
TEST_P(PartialTrans32x32Test, Extremes) {
|
||||
#if CONFIG_VP9_HIGHBITDEPTH
|
||||
const int16_t maxval =
|
||||
static_cast<int16_t>(clip_pixel_highbd(1 << 30, bit_depth_));
|
||||
#else
|
||||
const int16_t maxval = 255;
|
||||
#endif
|
||||
const int minval = -maxval;
|
||||
DECLARE_ALIGNED(16, int16_t, input[kNumCoeffs]);
|
||||
DECLARE_ALIGNED(16, tran_low_t, output[kNumCoeffs]);
|
||||
|
||||
for (int i = 0; i < kNumCoeffs; ++i) input[i] = maxval;
|
||||
output[0] = 0;
|
||||
ASM_REGISTER_STATE_CHECK(fwd_txfm_(input, output, 32));
|
||||
EXPECT_EQ((maxval * kNumCoeffs) >> 3, output[0]);
|
||||
|
||||
for (int i = 0; i < kNumCoeffs; ++i) input[i] = minval;
|
||||
output[0] = 0;
|
||||
ASM_REGISTER_STATE_CHECK(fwd_txfm_(input, output, 32));
|
||||
EXPECT_EQ((minval * kNumCoeffs) >> 3, output[0]);
|
||||
}
|
||||
|
||||
TEST_P(PartialTrans32x32Test, Random) {
|
||||
#if CONFIG_VP9_HIGHBITDEPTH
|
||||
const int16_t maxval =
|
||||
static_cast<int16_t>(clip_pixel_highbd(1 << 30, bit_depth_));
|
||||
#else
|
||||
const int16_t maxval = 255;
|
||||
#endif
|
||||
DECLARE_ALIGNED(16, int16_t, input[kNumCoeffs]);
|
||||
DECLARE_ALIGNED(16, tran_low_t, output[kNumCoeffs]);
|
||||
ACMRandom rnd(ACMRandom::DeterministicSeed());
|
||||
|
||||
int sum = 0;
|
||||
for (int i = 0; i < kNumCoeffs; ++i) {
|
||||
const int val = (i & 1) ? -rnd(maxval + 1) : rnd(maxval + 1);
|
||||
input[i] = val;
|
||||
sum += val;
|
||||
}
|
||||
output[0] = 0;
|
||||
ASM_REGISTER_STATE_CHECK(fwd_txfm_(input, output, 32));
|
||||
EXPECT_EQ(sum >> 3, output[0]);
|
||||
}
|
||||
|
||||
using std::tr1::make_tuple;
|
||||
|
||||
#if CONFIG_VP9_HIGHBITDEPTH
|
||||
INSTANTIATE_TEST_CASE_P(
|
||||
@ -305,6 +366,11 @@ INSTANTIATE_TEST_CASE_P(
|
||||
make_tuple(&vpx_fdct32x32_c, &vpx_idct32x32_1024_add_c, 0, VPX_BITS_8),
|
||||
make_tuple(&vpx_fdct32x32_rd_c, &vpx_idct32x32_1024_add_c, 1,
|
||||
VPX_BITS_8)));
|
||||
INSTANTIATE_TEST_CASE_P(
|
||||
C, PartialTrans32x32Test,
|
||||
::testing::Values(make_tuple(&vpx_highbd_fdct32x32_1_c, VPX_BITS_8),
|
||||
make_tuple(&vpx_highbd_fdct32x32_1_c, VPX_BITS_10),
|
||||
make_tuple(&vpx_highbd_fdct32x32_1_c, VPX_BITS_12)));
|
||||
#else
|
||||
INSTANTIATE_TEST_CASE_P(
|
||||
C, Trans32x32Test,
|
||||
@ -312,16 +378,19 @@ INSTANTIATE_TEST_CASE_P(
|
||||
VPX_BITS_8),
|
||||
make_tuple(&vpx_fdct32x32_rd_c, &vpx_idct32x32_1024_add_c,
|
||||
1, VPX_BITS_8)));
|
||||
INSTANTIATE_TEST_CASE_P(C, PartialTrans32x32Test,
|
||||
::testing::Values(make_tuple(&vpx_fdct32x32_1_c,
|
||||
VPX_BITS_8)));
|
||||
#endif // CONFIG_VP9_HIGHBITDEPTH
|
||||
|
||||
#if HAVE_NEON && !CONFIG_EMULATE_HARDWARE
|
||||
#if HAVE_NEON && !CONFIG_VP9_HIGHBITDEPTH && !CONFIG_EMULATE_HARDWARE
|
||||
INSTANTIATE_TEST_CASE_P(
|
||||
NEON, Trans32x32Test,
|
||||
::testing::Values(make_tuple(&vpx_fdct32x32_neon,
|
||||
&vpx_idct32x32_1024_add_neon, 0, VPX_BITS_8),
|
||||
make_tuple(&vpx_fdct32x32_rd_neon,
|
||||
::testing::Values(make_tuple(&vpx_fdct32x32_c, &vpx_idct32x32_1024_add_neon,
|
||||
0, VPX_BITS_8),
|
||||
make_tuple(&vpx_fdct32x32_rd_c,
|
||||
&vpx_idct32x32_1024_add_neon, 1, VPX_BITS_8)));
|
||||
#endif // HAVE_NEON && !CONFIG_EMULATE_HARDWARE
|
||||
#endif // HAVE_NEON && !CONFIG_VP9_HIGHBITDEPTH && !CONFIG_EMULATE_HARDWARE
|
||||
|
||||
#if HAVE_SSE2 && !CONFIG_VP9_HIGHBITDEPTH && !CONFIG_EMULATE_HARDWARE
|
||||
INSTANTIATE_TEST_CASE_P(
|
||||
@ -330,6 +399,9 @@ INSTANTIATE_TEST_CASE_P(
|
||||
&vpx_idct32x32_1024_add_sse2, 0, VPX_BITS_8),
|
||||
make_tuple(&vpx_fdct32x32_rd_sse2,
|
||||
&vpx_idct32x32_1024_add_sse2, 1, VPX_BITS_8)));
|
||||
INSTANTIATE_TEST_CASE_P(SSE2, PartialTrans32x32Test,
|
||||
::testing::Values(make_tuple(&vpx_fdct32x32_1_sse2,
|
||||
VPX_BITS_8)));
|
||||
#endif // HAVE_SSE2 && !CONFIG_VP9_HIGHBITDEPTH && !CONFIG_EMULATE_HARDWARE
|
||||
|
||||
#if HAVE_SSE2 && CONFIG_VP9_HIGHBITDEPTH && !CONFIG_EMULATE_HARDWARE
|
||||
@ -346,6 +418,9 @@ INSTANTIATE_TEST_CASE_P(
|
||||
VPX_BITS_8),
|
||||
make_tuple(&vpx_fdct32x32_rd_sse2, &vpx_idct32x32_1024_add_c, 1,
|
||||
VPX_BITS_8)));
|
||||
INSTANTIATE_TEST_CASE_P(SSE2, PartialTrans32x32Test,
|
||||
::testing::Values(make_tuple(&vpx_fdct32x32_1_sse2,
|
||||
VPX_BITS_8)));
|
||||
#endif // HAVE_SSE2 && CONFIG_VP9_HIGHBITDEPTH && !CONFIG_EMULATE_HARDWARE
|
||||
|
||||
#if HAVE_AVX2 && !CONFIG_VP9_HIGHBITDEPTH && !CONFIG_EMULATE_HARDWARE
|
||||
@ -364,14 +439,8 @@ INSTANTIATE_TEST_CASE_P(
|
||||
&vpx_idct32x32_1024_add_msa, 0, VPX_BITS_8),
|
||||
make_tuple(&vpx_fdct32x32_rd_msa,
|
||||
&vpx_idct32x32_1024_add_msa, 1, VPX_BITS_8)));
|
||||
INSTANTIATE_TEST_CASE_P(MSA, PartialTrans32x32Test,
|
||||
::testing::Values(make_tuple(&vpx_fdct32x32_1_msa,
|
||||
VPX_BITS_8)));
|
||||
#endif // HAVE_MSA && !CONFIG_VP9_HIGHBITDEPTH && !CONFIG_EMULATE_HARDWARE
|
||||
|
||||
#if HAVE_VSX && !CONFIG_VP9_HIGHBITDEPTH && !CONFIG_EMULATE_HARDWARE
|
||||
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,
|
||||
&vpx_idct32x32_1024_add_vsx, 1, VPX_BITS_8)));
|
||||
#endif // HAVE_VSX && !CONFIG_VP9_HIGHBITDEPTH && !CONFIG_EMULATE_HARDWARE
|
||||
} // namespace
|
||||
|
@ -1,169 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2017 The WebM project authors. All Rights Reserved.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license
|
||||
* that can be found in the LICENSE file in the root of the source
|
||||
* tree. An additional intellectual property rights grant can be found
|
||||
* in the file PATENTS. All contributing project authors may
|
||||
* be found in the AUTHORS file in the root of the source tree.
|
||||
*/
|
||||
|
||||
#include <math.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <limits>
|
||||
|
||||
#include "third_party/googletest/src/include/gtest/gtest.h"
|
||||
|
||||
#include "./vpx_dsp_rtcd.h"
|
||||
#include "test/acm_random.h"
|
||||
#include "test/buffer.h"
|
||||
#include "test/clear_system_state.h"
|
||||
#include "test/register_state_check.h"
|
||||
#include "test/util.h"
|
||||
#include "vpx/vpx_codec.h"
|
||||
#include "vpx/vpx_integer.h"
|
||||
#include "vpx_dsp/vpx_dsp_common.h"
|
||||
|
||||
using ::testing::make_tuple;
|
||||
using ::testing::tuple;
|
||||
using libvpx_test::ACMRandom;
|
||||
using libvpx_test::Buffer;
|
||||
|
||||
namespace {
|
||||
typedef void (*PartialFdctFunc)(const int16_t *in, tran_low_t *out, int stride);
|
||||
|
||||
typedef tuple<PartialFdctFunc, int /* size */, vpx_bit_depth_t>
|
||||
PartialFdctParam;
|
||||
|
||||
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];
|
||||
}
|
||||
}
|
||||
|
||||
switch (size) {
|
||||
case 4: sum *= 2; break;
|
||||
case 8: /*sum = sum;*/ break;
|
||||
case 16: sum >>= 1; break;
|
||||
case 32: sum >>= 3; break;
|
||||
}
|
||||
|
||||
return static_cast<tran_low_t>(sum);
|
||||
}
|
||||
|
||||
class PartialFdctTest : public ::testing::TestWithParam<PartialFdctParam> {
|
||||
public:
|
||||
PartialFdctTest() {
|
||||
fwd_txfm_ = GET_PARAM(0);
|
||||
size_ = GET_PARAM(1);
|
||||
bit_depth_ = GET_PARAM(2);
|
||||
}
|
||||
|
||||
virtual void TearDown() { libvpx_test::ClearSystemState(); }
|
||||
|
||||
protected:
|
||||
void RunTest() {
|
||||
ACMRandom rnd(ACMRandom::DeterministicSeed());
|
||||
const int16_t maxvalue =
|
||||
clip_pixel_highbd(std::numeric_limits<int16_t>::max(), bit_depth_);
|
||||
const int16_t minvalue = -maxvalue;
|
||||
Buffer<int16_t> input_block =
|
||||
Buffer<int16_t>(size_, size_, 8, size_ == 4 ? 0 : 16);
|
||||
ASSERT_TRUE(input_block.Init());
|
||||
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);
|
||||
}
|
||||
|
||||
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]);
|
||||
}
|
||||
}
|
||||
|
||||
PartialFdctFunc fwd_txfm_;
|
||||
vpx_bit_depth_t bit_depth_;
|
||||
int size_;
|
||||
};
|
||||
|
||||
TEST_P(PartialFdctTest, PartialFdctTest) { RunTest(); }
|
||||
|
||||
#if CONFIG_VP9_HIGHBITDEPTH
|
||||
INSTANTIATE_TEST_CASE_P(
|
||||
C, PartialFdctTest,
|
||||
::testing::Values(make_tuple(&vpx_highbd_fdct32x32_1_c, 32, VPX_BITS_12),
|
||||
make_tuple(&vpx_highbd_fdct32x32_1_c, 32, VPX_BITS_10),
|
||||
make_tuple(&vpx_fdct32x32_1_c, 32, VPX_BITS_8),
|
||||
make_tuple(&vpx_highbd_fdct16x16_1_c, 16, VPX_BITS_12),
|
||||
make_tuple(&vpx_highbd_fdct16x16_1_c, 16, VPX_BITS_10),
|
||||
make_tuple(&vpx_fdct16x16_1_c, 16, VPX_BITS_8),
|
||||
make_tuple(&vpx_highbd_fdct8x8_1_c, 8, VPX_BITS_12),
|
||||
make_tuple(&vpx_highbd_fdct8x8_1_c, 8, VPX_BITS_10),
|
||||
make_tuple(&vpx_fdct8x8_1_c, 8, VPX_BITS_8),
|
||||
make_tuple(&vpx_fdct4x4_1_c, 4, VPX_BITS_8)));
|
||||
#else
|
||||
INSTANTIATE_TEST_CASE_P(
|
||||
C, PartialFdctTest,
|
||||
::testing::Values(make_tuple(&vpx_fdct32x32_1_c, 32, VPX_BITS_8),
|
||||
make_tuple(&vpx_fdct16x16_1_c, 16, VPX_BITS_8),
|
||||
make_tuple(&vpx_fdct8x8_1_c, 8, VPX_BITS_8),
|
||||
make_tuple(&vpx_fdct4x4_1_c, 4, VPX_BITS_8)));
|
||||
#endif // CONFIG_VP9_HIGHBITDEPTH
|
||||
|
||||
#if HAVE_SSE2
|
||||
INSTANTIATE_TEST_CASE_P(
|
||||
SSE2, PartialFdctTest,
|
||||
::testing::Values(make_tuple(&vpx_fdct32x32_1_sse2, 32, VPX_BITS_8),
|
||||
make_tuple(&vpx_fdct16x16_1_sse2, 16, VPX_BITS_8),
|
||||
make_tuple(&vpx_fdct8x8_1_sse2, 8, VPX_BITS_8),
|
||||
make_tuple(&vpx_fdct4x4_1_sse2, 4, VPX_BITS_8)));
|
||||
#endif // HAVE_SSE2
|
||||
|
||||
#if HAVE_NEON
|
||||
#if CONFIG_VP9_HIGHBITDEPTH
|
||||
INSTANTIATE_TEST_CASE_P(
|
||||
NEON, PartialFdctTest,
|
||||
::testing::Values(make_tuple(&vpx_fdct32x32_1_neon, 32, VPX_BITS_8),
|
||||
make_tuple(&vpx_fdct16x16_1_neon, 16, VPX_BITS_8),
|
||||
make_tuple(&vpx_fdct8x8_1_neon, 8, VPX_BITS_12),
|
||||
make_tuple(&vpx_fdct8x8_1_neon, 8, VPX_BITS_10),
|
||||
make_tuple(&vpx_fdct8x8_1_neon, 8, VPX_BITS_8),
|
||||
make_tuple(&vpx_fdct4x4_1_neon, 4, VPX_BITS_8)));
|
||||
#else
|
||||
INSTANTIATE_TEST_CASE_P(
|
||||
NEON, PartialFdctTest,
|
||||
::testing::Values(make_tuple(&vpx_fdct32x32_1_neon, 32, VPX_BITS_8),
|
||||
make_tuple(&vpx_fdct16x16_1_neon, 16, VPX_BITS_8),
|
||||
make_tuple(&vpx_fdct8x8_1_neon, 8, VPX_BITS_8),
|
||||
make_tuple(&vpx_fdct4x4_1_neon, 4, VPX_BITS_8)));
|
||||
#endif // CONFIG_VP9_HIGHBITDEPTH
|
||||
#endif // HAVE_NEON
|
||||
|
||||
#if HAVE_MSA
|
||||
#if CONFIG_VP9_HIGHBITDEPTH
|
||||
INSTANTIATE_TEST_CASE_P(MSA, PartialFdctTest,
|
||||
::testing::Values(make_tuple(&vpx_fdct8x8_1_msa, 8,
|
||||
VPX_BITS_8)));
|
||||
#else // !CONFIG_VP9_HIGHBITDEPTH
|
||||
INSTANTIATE_TEST_CASE_P(
|
||||
MSA, PartialFdctTest,
|
||||
::testing::Values(make_tuple(&vpx_fdct32x32_1_msa, 32, VPX_BITS_8),
|
||||
make_tuple(&vpx_fdct16x16_1_msa, 16, VPX_BITS_8),
|
||||
make_tuple(&vpx_fdct8x8_1_msa, 8, VPX_BITS_8)));
|
||||
#endif // CONFIG_VP9_HIGHBITDEPTH
|
||||
#endif // HAVE_MSA
|
||||
} // namespace
|
728
test/dct_test.cc
728
test/dct_test.cc
@ -1,728 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2017 The WebM project authors. All Rights Reserved.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license
|
||||
* that can be found in the LICENSE file in the root of the source
|
||||
* tree. An additional intellectual property rights grant can be found
|
||||
* in the file PATENTS. All contributing project authors may
|
||||
* be found in the AUTHORS file in the root of the source tree.
|
||||
*/
|
||||
|
||||
#include <math.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "third_party/googletest/src/include/gtest/gtest.h"
|
||||
|
||||
#include "./vp9_rtcd.h"
|
||||
#include "./vpx_dsp_rtcd.h"
|
||||
#include "test/acm_random.h"
|
||||
#include "test/buffer.h"
|
||||
#include "test/clear_system_state.h"
|
||||
#include "test/register_state_check.h"
|
||||
#include "test/util.h"
|
||||
#include "vp9/common/vp9_entropy.h"
|
||||
#include "vpx/vpx_codec.h"
|
||||
#include "vpx/vpx_integer.h"
|
||||
#include "vpx_ports/mem.h"
|
||||
|
||||
using ::testing::make_tuple;
|
||||
using ::testing::tuple;
|
||||
using libvpx_test::ACMRandom;
|
||||
using libvpx_test::Buffer;
|
||||
|
||||
namespace {
|
||||
typedef void (*FdctFunc)(const int16_t *in, tran_low_t *out, int stride);
|
||||
typedef void (*IdctFunc)(const tran_low_t *in, uint8_t *out, int stride);
|
||||
typedef void (*FhtFunc)(const int16_t *in, tran_low_t *out, int stride,
|
||||
int tx_type);
|
||||
typedef void (*FhtFuncRef)(const Buffer<int16_t> &in, Buffer<tran_low_t> *out,
|
||||
int size, int tx_type);
|
||||
typedef void (*IhtFunc)(const tran_low_t *in, uint8_t *out, int stride,
|
||||
int tx_type);
|
||||
typedef void (*IhtWithBdFunc)(const tran_low_t *in, uint8_t *out, int stride,
|
||||
int tx_type, int bd);
|
||||
|
||||
template <FdctFunc fn>
|
||||
void fdct_wrapper(const int16_t *in, tran_low_t *out, int stride, int tx_type) {
|
||||
(void)tx_type;
|
||||
fn(in, out, stride);
|
||||
}
|
||||
|
||||
template <IdctFunc fn>
|
||||
void idct_wrapper(const tran_low_t *in, uint8_t *out, int stride, int tx_type,
|
||||
int bd) {
|
||||
(void)tx_type;
|
||||
(void)bd;
|
||||
fn(in, out, stride);
|
||||
}
|
||||
|
||||
template <IhtFunc fn>
|
||||
void iht_wrapper(const tran_low_t *in, uint8_t *out, int stride, int tx_type,
|
||||
int bd) {
|
||||
(void)bd;
|
||||
fn(in, out, stride, tx_type);
|
||||
}
|
||||
|
||||
#if CONFIG_VP9_HIGHBITDEPTH
|
||||
typedef void (*HighbdIdctFunc)(const tran_low_t *in, uint16_t *out, int stride,
|
||||
int bd);
|
||||
|
||||
typedef void (*HighbdIhtFunc)(const tran_low_t *in, uint16_t *out, int stride,
|
||||
int tx_type, int bd);
|
||||
|
||||
template <HighbdIdctFunc fn>
|
||||
void highbd_idct_wrapper(const tran_low_t *in, uint8_t *out, int stride,
|
||||
int tx_type, int bd) {
|
||||
(void)tx_type;
|
||||
fn(in, CAST_TO_SHORTPTR(out), stride, bd);
|
||||
}
|
||||
|
||||
template <HighbdIhtFunc fn>
|
||||
void highbd_iht_wrapper(const tran_low_t *in, uint8_t *out, int stride,
|
||||
int tx_type, int bd) {
|
||||
fn(in, CAST_TO_SHORTPTR(out), stride, tx_type, bd);
|
||||
}
|
||||
#endif // CONFIG_VP9_HIGHBITDEPTH
|
||||
|
||||
struct FuncInfo {
|
||||
FhtFunc ft_func;
|
||||
IhtWithBdFunc it_func;
|
||||
int size;
|
||||
int pixel_size;
|
||||
};
|
||||
|
||||
/* forward transform, inverse transform, size, transform type, bit depth */
|
||||
typedef tuple<int, const FuncInfo *, int, vpx_bit_depth_t> DctParam;
|
||||
|
||||
void fdct_ref(const Buffer<int16_t> &in, Buffer<tran_low_t> *out, int size,
|
||||
int /*tx_type*/) {
|
||||
const int16_t *i = in.TopLeftPixel();
|
||||
const int i_stride = in.stride();
|
||||
tran_low_t *o = out->TopLeftPixel();
|
||||
if (size == 4) {
|
||||
vpx_fdct4x4_c(i, o, i_stride);
|
||||
} else if (size == 8) {
|
||||
vpx_fdct8x8_c(i, o, i_stride);
|
||||
} else if (size == 16) {
|
||||
vpx_fdct16x16_c(i, o, i_stride);
|
||||
} else if (size == 32) {
|
||||
vpx_fdct32x32_c(i, o, i_stride);
|
||||
}
|
||||
}
|
||||
|
||||
void fht_ref(const Buffer<int16_t> &in, Buffer<tran_low_t> *out, int size,
|
||||
int tx_type) {
|
||||
const int16_t *i = in.TopLeftPixel();
|
||||
const int i_stride = in.stride();
|
||||
tran_low_t *o = out->TopLeftPixel();
|
||||
if (size == 4) {
|
||||
vp9_fht4x4_c(i, o, i_stride, tx_type);
|
||||
} else if (size == 8) {
|
||||
vp9_fht8x8_c(i, o, i_stride, tx_type);
|
||||
} else if (size == 16) {
|
||||
vp9_fht16x16_c(i, o, i_stride, tx_type);
|
||||
}
|
||||
}
|
||||
|
||||
void fwht_ref(const Buffer<int16_t> &in, Buffer<tran_low_t> *out, int size,
|
||||
int /*tx_type*/) {
|
||||
ASSERT_EQ(size, 4);
|
||||
vp9_fwht4x4_c(in.TopLeftPixel(), out->TopLeftPixel(), in.stride());
|
||||
}
|
||||
|
||||
class TransTestBase : public ::testing::TestWithParam<DctParam> {
|
||||
public:
|
||||
virtual void SetUp() {
|
||||
rnd_.Reset(ACMRandom::DeterministicSeed());
|
||||
const int idx = GET_PARAM(0);
|
||||
const FuncInfo *func_info = &(GET_PARAM(1)[idx]);
|
||||
tx_type_ = GET_PARAM(2);
|
||||
bit_depth_ = GET_PARAM(3);
|
||||
fwd_txfm_ = func_info->ft_func;
|
||||
inv_txfm_ = func_info->it_func;
|
||||
size_ = func_info->size;
|
||||
pixel_size_ = func_info->pixel_size;
|
||||
max_pixel_value_ = (1 << bit_depth_) - 1;
|
||||
|
||||
// Randomize stride_ to a value less than or equal to 1024
|
||||
stride_ = rnd_(1024) + 1;
|
||||
if (stride_ < size_) {
|
||||
stride_ = size_;
|
||||
}
|
||||
// Align stride_ to 16 if it's bigger than 16.
|
||||
if (stride_ > 16) {
|
||||
stride_ &= ~15;
|
||||
}
|
||||
|
||||
block_size_ = size_ * stride_;
|
||||
|
||||
src_ = reinterpret_cast<uint8_t *>(
|
||||
vpx_memalign(16, pixel_size_ * block_size_));
|
||||
ASSERT_TRUE(src_ != NULL);
|
||||
dst_ = reinterpret_cast<uint8_t *>(
|
||||
vpx_memalign(16, pixel_size_ * block_size_));
|
||||
ASSERT_TRUE(dst_ != NULL);
|
||||
}
|
||||
|
||||
virtual void TearDown() {
|
||||
vpx_free(src_);
|
||||
src_ = NULL;
|
||||
vpx_free(dst_);
|
||||
dst_ = NULL;
|
||||
libvpx_test::ClearSystemState();
|
||||
}
|
||||
|
||||
void InitMem() {
|
||||
if (pixel_size_ == 1 && bit_depth_ > VPX_BITS_8) return;
|
||||
if (pixel_size_ == 1) {
|
||||
for (int j = 0; j < block_size_; ++j) {
|
||||
src_[j] = rnd_.Rand16() & max_pixel_value_;
|
||||
}
|
||||
for (int j = 0; j < block_size_; ++j) {
|
||||
dst_[j] = rnd_.Rand16() & max_pixel_value_;
|
||||
}
|
||||
} else {
|
||||
ASSERT_EQ(pixel_size_, 2);
|
||||
uint16_t *const src = reinterpret_cast<uint16_t *>(src_);
|
||||
uint16_t *const dst = reinterpret_cast<uint16_t *>(dst_);
|
||||
for (int j = 0; j < block_size_; ++j) {
|
||||
src[j] = rnd_.Rand16() & max_pixel_value_;
|
||||
}
|
||||
for (int j = 0; j < block_size_; ++j) {
|
||||
dst[j] = rnd_.Rand16() & max_pixel_value_;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void RunFwdTxfm(const Buffer<int16_t> &in, Buffer<tran_low_t> *out) {
|
||||
fwd_txfm_(in.TopLeftPixel(), out->TopLeftPixel(), in.stride(), tx_type_);
|
||||
}
|
||||
|
||||
void RunInvTxfm(const Buffer<tran_low_t> &in, uint8_t *out) {
|
||||
inv_txfm_(in.TopLeftPixel(), out, stride_, tx_type_, bit_depth_);
|
||||
}
|
||||
|
||||
protected:
|
||||
void RunAccuracyCheck(int limit) {
|
||||
if (pixel_size_ == 1 && bit_depth_ > VPX_BITS_8) return;
|
||||
ACMRandom rnd(ACMRandom::DeterministicSeed());
|
||||
Buffer<int16_t> test_input_block =
|
||||
Buffer<int16_t>(size_, size_, 8, size_ == 4 ? 0 : 16);
|
||||
ASSERT_TRUE(test_input_block.Init());
|
||||
Buffer<tran_low_t> test_temp_block =
|
||||
Buffer<tran_low_t>(size_, size_, 0, 16);
|
||||
ASSERT_TRUE(test_temp_block.Init());
|
||||
uint32_t max_error = 0;
|
||||
int64_t total_error = 0;
|
||||
const int count_test_block = 10000;
|
||||
for (int i = 0; i < count_test_block; ++i) {
|
||||
InitMem();
|
||||
for (int h = 0; h < size_; ++h) {
|
||||
for (int w = 0; w < size_; ++w) {
|
||||
if (pixel_size_ == 1) {
|
||||
test_input_block.TopLeftPixel()[h * test_input_block.stride() + w] =
|
||||
src_[h * stride_ + w] - dst_[h * stride_ + w];
|
||||
} else {
|
||||
ASSERT_EQ(pixel_size_, 2);
|
||||
const uint16_t *const src = reinterpret_cast<uint16_t *>(src_);
|
||||
const uint16_t *const dst = reinterpret_cast<uint16_t *>(dst_);
|
||||
test_input_block.TopLeftPixel()[h * test_input_block.stride() + w] =
|
||||
src[h * stride_ + w] - dst[h * stride_ + w];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ASM_REGISTER_STATE_CHECK(RunFwdTxfm(test_input_block, &test_temp_block));
|
||||
ASM_REGISTER_STATE_CHECK(RunInvTxfm(test_temp_block, dst_));
|
||||
|
||||
for (int h = 0; h < size_; ++h) {
|
||||
for (int w = 0; w < size_; ++w) {
|
||||
int diff;
|
||||
if (pixel_size_ == 1) {
|
||||
diff = dst_[h * stride_ + w] - src_[h * stride_ + w];
|
||||
} else {
|
||||
ASSERT_EQ(pixel_size_, 2);
|
||||
const uint16_t *const src = reinterpret_cast<uint16_t *>(src_);
|
||||
const uint16_t *const dst = reinterpret_cast<uint16_t *>(dst_);
|
||||
diff = dst[h * stride_ + w] - src[h * stride_ + w];
|
||||
}
|
||||
const uint32_t error = diff * diff;
|
||||
if (max_error < error) max_error = error;
|
||||
total_error += error;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
EXPECT_GE(static_cast<uint32_t>(limit), max_error)
|
||||
<< "Error: " << size_ << "x" << size_
|
||||
<< " transform/inverse transform has an individual round trip error > "
|
||||
<< limit;
|
||||
|
||||
EXPECT_GE(count_test_block * limit, total_error)
|
||||
<< "Error: " << size_ << "x" << size_
|
||||
<< " transform/inverse transform has average round trip error > "
|
||||
<< limit << " per block";
|
||||
}
|
||||
|
||||
void RunCoeffCheck() {
|
||||
if (pixel_size_ == 1 && bit_depth_ > VPX_BITS_8) return;
|
||||
ACMRandom rnd(ACMRandom::DeterministicSeed());
|
||||
const int count_test_block = 5000;
|
||||
Buffer<int16_t> input_block =
|
||||
Buffer<int16_t>(size_, size_, 8, size_ == 4 ? 0 : 16);
|
||||
ASSERT_TRUE(input_block.Init());
|
||||
Buffer<tran_low_t> output_ref_block = Buffer<tran_low_t>(size_, size_, 0);
|
||||
ASSERT_TRUE(output_ref_block.Init());
|
||||
Buffer<tran_low_t> output_block = Buffer<tran_low_t>(size_, size_, 0, 16);
|
||||
ASSERT_TRUE(output_block.Init());
|
||||
|
||||
for (int i = 0; i < count_test_block; ++i) {
|
||||
// Initialize a test block with input range [-max_pixel_value_,
|
||||
// max_pixel_value_].
|
||||
input_block.Set(&rnd, -max_pixel_value_, max_pixel_value_);
|
||||
|
||||
fwd_txfm_ref(input_block, &output_ref_block, size_, tx_type_);
|
||||
ASM_REGISTER_STATE_CHECK(RunFwdTxfm(input_block, &output_block));
|
||||
|
||||
// The minimum quant value is 4.
|
||||
EXPECT_TRUE(output_block.CheckValues(output_ref_block));
|
||||
if (::testing::Test::HasFailure()) {
|
||||
printf("Size: %d Transform type: %d\n", size_, tx_type_);
|
||||
output_block.PrintDifference(output_ref_block);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void RunMemCheck() {
|
||||
if (pixel_size_ == 1 && bit_depth_ > VPX_BITS_8) return;
|
||||
ACMRandom rnd(ACMRandom::DeterministicSeed());
|
||||
const int count_test_block = 5000;
|
||||
Buffer<int16_t> input_extreme_block =
|
||||
Buffer<int16_t>(size_, size_, 8, size_ == 4 ? 0 : 16);
|
||||
ASSERT_TRUE(input_extreme_block.Init());
|
||||
Buffer<tran_low_t> output_ref_block = Buffer<tran_low_t>(size_, size_, 0);
|
||||
ASSERT_TRUE(output_ref_block.Init());
|
||||
Buffer<tran_low_t> output_block = Buffer<tran_low_t>(size_, size_, 0, 16);
|
||||
ASSERT_TRUE(output_block.Init());
|
||||
|
||||
for (int i = 0; i < count_test_block; ++i) {
|
||||
// Initialize a test block with -max_pixel_value_ or max_pixel_value_.
|
||||
if (i == 0) {
|
||||
input_extreme_block.Set(max_pixel_value_);
|
||||
} else if (i == 1) {
|
||||
input_extreme_block.Set(-max_pixel_value_);
|
||||
} else {
|
||||
for (int h = 0; h < size_; ++h) {
|
||||
for (int w = 0; w < size_; ++w) {
|
||||
input_extreme_block
|
||||
.TopLeftPixel()[h * input_extreme_block.stride() + w] =
|
||||
rnd.Rand8() % 2 ? max_pixel_value_ : -max_pixel_value_;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fwd_txfm_ref(input_extreme_block, &output_ref_block, size_, tx_type_);
|
||||
ASM_REGISTER_STATE_CHECK(RunFwdTxfm(input_extreme_block, &output_block));
|
||||
|
||||
// The minimum quant value is 4.
|
||||
EXPECT_TRUE(output_block.CheckValues(output_ref_block));
|
||||
for (int h = 0; h < size_; ++h) {
|
||||
for (int w = 0; w < size_; ++w) {
|
||||
EXPECT_GE(
|
||||
4 * DCT_MAX_VALUE << (bit_depth_ - 8),
|
||||
abs(output_block.TopLeftPixel()[h * output_block.stride() + w]))
|
||||
<< "Error: " << size_ << "x" << size_
|
||||
<< " transform has coefficient larger than 4*DCT_MAX_VALUE"
|
||||
<< " at " << w << "," << h;
|
||||
if (::testing::Test::HasFailure()) {
|
||||
printf("Size: %d Transform type: %d\n", size_, tx_type_);
|
||||
output_block.DumpBuffer();
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void RunInvAccuracyCheck(int limit) {
|
||||
if (pixel_size_ == 1 && bit_depth_ > VPX_BITS_8) return;
|
||||
ACMRandom rnd(ACMRandom::DeterministicSeed());
|
||||
const int count_test_block = 1000;
|
||||
Buffer<int16_t> in = Buffer<int16_t>(size_, size_, 4);
|
||||
ASSERT_TRUE(in.Init());
|
||||
Buffer<tran_low_t> coeff = Buffer<tran_low_t>(size_, size_, 0, 16);
|
||||
ASSERT_TRUE(coeff.Init());
|
||||
Buffer<uint8_t> dst = Buffer<uint8_t>(size_, size_, 0, 16);
|
||||
ASSERT_TRUE(dst.Init());
|
||||
Buffer<uint8_t> src = Buffer<uint8_t>(size_, size_, 0);
|
||||
ASSERT_TRUE(src.Init());
|
||||
Buffer<uint16_t> dst16 = Buffer<uint16_t>(size_, size_, 0, 16);
|
||||
ASSERT_TRUE(dst16.Init());
|
||||
Buffer<uint16_t> src16 = Buffer<uint16_t>(size_, size_, 0);
|
||||
ASSERT_TRUE(src16.Init());
|
||||
|
||||
for (int i = 0; i < count_test_block; ++i) {
|
||||
InitMem();
|
||||
// Initialize a test block with input range [-max_pixel_value_,
|
||||
// max_pixel_value_].
|
||||
for (int h = 0; h < size_; ++h) {
|
||||
for (int w = 0; w < size_; ++w) {
|
||||
if (pixel_size_ == 1) {
|
||||
in.TopLeftPixel()[h * in.stride() + w] =
|
||||
src_[h * stride_ + w] - dst_[h * stride_ + w];
|
||||
} else {
|
||||
ASSERT_EQ(pixel_size_, 2);
|
||||
const uint16_t *const src = reinterpret_cast<uint16_t *>(src_);
|
||||
const uint16_t *const dst = reinterpret_cast<uint16_t *>(dst_);
|
||||
in.TopLeftPixel()[h * in.stride() + w] =
|
||||
src[h * stride_ + w] - dst[h * stride_ + w];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fwd_txfm_ref(in, &coeff, size_, tx_type_);
|
||||
|
||||
ASM_REGISTER_STATE_CHECK(RunInvTxfm(coeff, dst_));
|
||||
|
||||
for (int h = 0; h < size_; ++h) {
|
||||
for (int w = 0; w < size_; ++w) {
|
||||
int diff;
|
||||
if (pixel_size_ == 1) {
|
||||
diff = dst_[h * stride_ + w] - src_[h * stride_ + w];
|
||||
} else {
|
||||
ASSERT_EQ(pixel_size_, 2);
|
||||
const uint16_t *const src = reinterpret_cast<uint16_t *>(src_);
|
||||
const uint16_t *const dst = reinterpret_cast<uint16_t *>(dst_);
|
||||
diff = dst[h * stride_ + w] - src[h * stride_ + w];
|
||||
}
|
||||
const uint32_t error = diff * diff;
|
||||
EXPECT_GE(static_cast<uint32_t>(limit), error)
|
||||
<< "Error: " << size_ << "x" << size_
|
||||
<< " inverse transform has error " << error << " at " << w << ","
|
||||
<< h;
|
||||
if (::testing::Test::HasFailure()) {
|
||||
printf("Size: %d Transform type: %d\n", size_, tx_type_);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
FhtFunc fwd_txfm_;
|
||||
FhtFuncRef fwd_txfm_ref;
|
||||
IhtWithBdFunc inv_txfm_;
|
||||
ACMRandom rnd_;
|
||||
uint8_t *src_;
|
||||
uint8_t *dst_;
|
||||
vpx_bit_depth_t bit_depth_;
|
||||
int tx_type_;
|
||||
int max_pixel_value_;
|
||||
int size_;
|
||||
int stride_;
|
||||
int pixel_size_;
|
||||
int block_size_;
|
||||
};
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
|
||||
class TransDCT : public TransTestBase {
|
||||
public:
|
||||
TransDCT() { fwd_txfm_ref = fdct_ref; }
|
||||
};
|
||||
|
||||
TEST_P(TransDCT, AccuracyCheck) {
|
||||
int t = 1;
|
||||
if (size_ == 16 && bit_depth_ > 10 && pixel_size_ == 2) {
|
||||
t = 2;
|
||||
} else if (size_ == 32 && bit_depth_ > 10 && pixel_size_ == 2) {
|
||||
t = 7;
|
||||
}
|
||||
RunAccuracyCheck(t);
|
||||
}
|
||||
|
||||
TEST_P(TransDCT, CoeffCheck) { RunCoeffCheck(); }
|
||||
|
||||
TEST_P(TransDCT, MemCheck) { RunMemCheck(); }
|
||||
|
||||
TEST_P(TransDCT, InvAccuracyCheck) { RunInvAccuracyCheck(1); }
|
||||
|
||||
static const FuncInfo dct_c_func_info[] = {
|
||||
#if CONFIG_VP9_HIGHBITDEPTH
|
||||
{ &fdct_wrapper<vpx_highbd_fdct4x4_c>,
|
||||
&highbd_idct_wrapper<vpx_highbd_idct4x4_16_add_c>, 4, 2 },
|
||||
{ &fdct_wrapper<vpx_highbd_fdct8x8_c>,
|
||||
&highbd_idct_wrapper<vpx_highbd_idct8x8_64_add_c>, 8, 2 },
|
||||
{ &fdct_wrapper<vpx_highbd_fdct16x16_c>,
|
||||
&highbd_idct_wrapper<vpx_highbd_idct16x16_256_add_c>, 16, 2 },
|
||||
{ &fdct_wrapper<vpx_highbd_fdct32x32_c>,
|
||||
&highbd_idct_wrapper<vpx_highbd_idct32x32_1024_add_c>, 32, 2 },
|
||||
#endif
|
||||
{ &fdct_wrapper<vpx_fdct4x4_c>, &idct_wrapper<vpx_idct4x4_16_add_c>, 4, 1 },
|
||||
{ &fdct_wrapper<vpx_fdct8x8_c>, &idct_wrapper<vpx_idct8x8_64_add_c>, 8, 1 },
|
||||
{ &fdct_wrapper<vpx_fdct16x16_c>, &idct_wrapper<vpx_idct16x16_256_add_c>, 16,
|
||||
1 },
|
||||
{ &fdct_wrapper<vpx_fdct32x32_c>, &idct_wrapper<vpx_idct32x32_1024_add_c>, 32,
|
||||
1 }
|
||||
};
|
||||
|
||||
INSTANTIATE_TEST_CASE_P(
|
||||
C, TransDCT,
|
||||
::testing::Combine(
|
||||
::testing::Range(0, static_cast<int>(sizeof(dct_c_func_info) /
|
||||
sizeof(dct_c_func_info[0]))),
|
||||
::testing::Values(dct_c_func_info), ::testing::Values(0),
|
||||
::testing::Values(VPX_BITS_8, VPX_BITS_10, VPX_BITS_12)));
|
||||
|
||||
#if !CONFIG_EMULATE_HARDWARE
|
||||
|
||||
#if HAVE_SSE2
|
||||
static const FuncInfo dct_sse2_func_info[] = {
|
||||
#if CONFIG_VP9_HIGHBITDEPTH
|
||||
{ &fdct_wrapper<vpx_highbd_fdct4x4_sse2>,
|
||||
&highbd_idct_wrapper<vpx_highbd_idct4x4_16_add_sse2>, 4, 2 },
|
||||
{ &fdct_wrapper<vpx_highbd_fdct8x8_sse2>,
|
||||
&highbd_idct_wrapper<vpx_highbd_idct8x8_64_add_sse2>, 8, 2 },
|
||||
{ &fdct_wrapper<vpx_highbd_fdct16x16_sse2>,
|
||||
&highbd_idct_wrapper<vpx_highbd_idct16x16_256_add_sse2>, 16, 2 },
|
||||
{ &fdct_wrapper<vpx_highbd_fdct32x32_sse2>,
|
||||
&highbd_idct_wrapper<vpx_highbd_idct32x32_1024_add_sse2>, 32, 2 },
|
||||
#endif
|
||||
{ &fdct_wrapper<vpx_fdct4x4_sse2>, &idct_wrapper<vpx_idct4x4_16_add_sse2>, 4,
|
||||
1 },
|
||||
{ &fdct_wrapper<vpx_fdct8x8_sse2>, &idct_wrapper<vpx_idct8x8_64_add_sse2>, 8,
|
||||
1 },
|
||||
{ &fdct_wrapper<vpx_fdct16x16_sse2>,
|
||||
&idct_wrapper<vpx_idct16x16_256_add_sse2>, 16, 1 },
|
||||
{ &fdct_wrapper<vpx_fdct32x32_sse2>,
|
||||
&idct_wrapper<vpx_idct32x32_1024_add_sse2>, 32, 1 }
|
||||
};
|
||||
|
||||
INSTANTIATE_TEST_CASE_P(
|
||||
SSE2, TransDCT,
|
||||
::testing::Combine(
|
||||
::testing::Range(0, static_cast<int>(sizeof(dct_sse2_func_info) /
|
||||
sizeof(dct_sse2_func_info[0]))),
|
||||
::testing::Values(dct_sse2_func_info), ::testing::Values(0),
|
||||
::testing::Values(VPX_BITS_8, VPX_BITS_10, VPX_BITS_12)));
|
||||
#endif // HAVE_SSE2
|
||||
|
||||
#if HAVE_SSSE3 && !CONFIG_VP9_HIGHBITDEPTH && ARCH_X86_64
|
||||
// vpx_fdct8x8_ssse3 is only available in 64 bit builds.
|
||||
static const FuncInfo dct_ssse3_func_info = {
|
||||
&fdct_wrapper<vpx_fdct8x8_ssse3>, &idct_wrapper<vpx_idct8x8_64_add_sse2>, 8, 1
|
||||
};
|
||||
|
||||
// TODO(johannkoenig): high bit depth fdct8x8.
|
||||
INSTANTIATE_TEST_CASE_P(SSSE3, TransDCT,
|
||||
::testing::Values(make_tuple(0, &dct_ssse3_func_info, 0,
|
||||
VPX_BITS_8)));
|
||||
#endif // HAVE_SSSE3 && !CONFIG_VP9_HIGHBITDEPTH && ARCH_X86_64
|
||||
|
||||
#if HAVE_AVX2 && !CONFIG_VP9_HIGHBITDEPTH
|
||||
static const FuncInfo dct_avx2_func_info = {
|
||||
&fdct_wrapper<vpx_fdct32x32_avx2>, &idct_wrapper<vpx_idct32x32_1024_add_sse2>,
|
||||
32, 1
|
||||
};
|
||||
|
||||
// TODO(johannkoenig): high bit depth fdct32x32.
|
||||
INSTANTIATE_TEST_CASE_P(AVX2, TransDCT,
|
||||
::testing::Values(make_tuple(0, &dct_avx2_func_info, 0,
|
||||
VPX_BITS_8)));
|
||||
#endif // HAVE_AVX2 && !CONFIG_VP9_HIGHBITDEPTH
|
||||
|
||||
#if HAVE_NEON
|
||||
static const FuncInfo dct_neon_func_info[4] = {
|
||||
{ &fdct_wrapper<vpx_fdct4x4_neon>, &idct_wrapper<vpx_idct4x4_16_add_neon>, 4,
|
||||
1 },
|
||||
{ &fdct_wrapper<vpx_fdct8x8_neon>, &idct_wrapper<vpx_idct8x8_64_add_neon>, 8,
|
||||
1 },
|
||||
{ &fdct_wrapper<vpx_fdct16x16_neon>,
|
||||
&idct_wrapper<vpx_idct16x16_256_add_neon>, 16, 1 },
|
||||
{ &fdct_wrapper<vpx_fdct32x32_neon>,
|
||||
&idct_wrapper<vpx_idct32x32_1024_add_neon>, 32, 1 }
|
||||
};
|
||||
|
||||
INSTANTIATE_TEST_CASE_P(
|
||||
NEON, TransDCT,
|
||||
::testing::Combine(::testing::Range(0, 4),
|
||||
::testing::Values(dct_neon_func_info),
|
||||
::testing::Values(0), ::testing::Values(VPX_BITS_8)));
|
||||
#endif // HAVE_NEON
|
||||
|
||||
#if HAVE_MSA && !CONFIG_VP9_HIGHBITDEPTH
|
||||
static const FuncInfo dct_msa_func_info[4] = {
|
||||
{ &fdct_wrapper<vpx_fdct4x4_msa>, &idct_wrapper<vpx_idct4x4_16_add_msa>, 4,
|
||||
1 },
|
||||
{ &fdct_wrapper<vpx_fdct8x8_msa>, &idct_wrapper<vpx_idct8x8_64_add_msa>, 8,
|
||||
1 },
|
||||
{ &fdct_wrapper<vpx_fdct16x16_msa>, &idct_wrapper<vpx_idct16x16_256_add_msa>,
|
||||
16, 1 },
|
||||
{ &fdct_wrapper<vpx_fdct32x32_msa>, &idct_wrapper<vpx_idct32x32_1024_add_msa>,
|
||||
32, 1 }
|
||||
};
|
||||
|
||||
INSTANTIATE_TEST_CASE_P(MSA, TransDCT,
|
||||
::testing::Combine(::testing::Range(0, 4),
|
||||
::testing::Values(dct_msa_func_info),
|
||||
::testing::Values(0),
|
||||
::testing::Values(VPX_BITS_8)));
|
||||
#endif // HAVE_MSA && !CONFIG_VP9_HIGHBITDEPTH
|
||||
|
||||
#if HAVE_VSX && !CONFIG_VP9_HIGHBITDEPTH
|
||||
static const FuncInfo dct_vsx_func_info = {
|
||||
&fdct_wrapper<vpx_fdct4x4_c>, &idct_wrapper<vpx_idct4x4_16_add_vsx>, 4, 1
|
||||
};
|
||||
|
||||
INSTANTIATE_TEST_CASE_P(VSX, TransDCT,
|
||||
::testing::Values(make_tuple(0, &dct_vsx_func_info, 0,
|
||||
VPX_BITS_8)));
|
||||
#endif // HAVE_VSX && !CONFIG_VP9_HIGHBITDEPTH &&
|
||||
|
||||
#endif // !CONFIG_EMULATE_HARDWARE
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
|
||||
class TransHT : public TransTestBase {
|
||||
public:
|
||||
TransHT() { fwd_txfm_ref = fht_ref; }
|
||||
};
|
||||
|
||||
TEST_P(TransHT, AccuracyCheck) {
|
||||
RunAccuracyCheck(size_ == 16 && bit_depth_ > 10 && pixel_size_ == 2 ? 2 : 1);
|
||||
}
|
||||
|
||||
TEST_P(TransHT, CoeffCheck) { RunCoeffCheck(); }
|
||||
|
||||
TEST_P(TransHT, MemCheck) { RunMemCheck(); }
|
||||
|
||||
TEST_P(TransHT, InvAccuracyCheck) { RunInvAccuracyCheck(1); }
|
||||
|
||||
static const FuncInfo ht_c_func_info[] = {
|
||||
#if CONFIG_VP9_HIGHBITDEPTH
|
||||
{ &vp9_highbd_fht4x4_c, &highbd_iht_wrapper<vp9_highbd_iht4x4_16_add_c>, 4,
|
||||
2 },
|
||||
{ &vp9_highbd_fht8x8_c, &highbd_iht_wrapper<vp9_highbd_iht8x8_64_add_c>, 8,
|
||||
2 },
|
||||
{ &vp9_highbd_fht16x16_c, &highbd_iht_wrapper<vp9_highbd_iht16x16_256_add_c>,
|
||||
16, 2 },
|
||||
#endif
|
||||
{ &vp9_fht4x4_c, &iht_wrapper<vp9_iht4x4_16_add_c>, 4, 1 },
|
||||
{ &vp9_fht8x8_c, &iht_wrapper<vp9_iht8x8_64_add_c>, 8, 1 },
|
||||
{ &vp9_fht16x16_c, &iht_wrapper<vp9_iht16x16_256_add_c>, 16, 1 }
|
||||
};
|
||||
|
||||
INSTANTIATE_TEST_CASE_P(
|
||||
C, TransHT,
|
||||
::testing::Combine(
|
||||
::testing::Range(0, static_cast<int>(sizeof(ht_c_func_info) /
|
||||
sizeof(ht_c_func_info[0]))),
|
||||
::testing::Values(ht_c_func_info), ::testing::Range(0, 4),
|
||||
::testing::Values(VPX_BITS_8, VPX_BITS_10, VPX_BITS_12)));
|
||||
|
||||
#if !CONFIG_EMULATE_HARDWARE
|
||||
|
||||
#if HAVE_NEON
|
||||
|
||||
static const FuncInfo ht_neon_func_info[] = {
|
||||
#if CONFIG_VP9_HIGHBITDEPTH
|
||||
{ &vp9_highbd_fht4x4_c, &highbd_iht_wrapper<vp9_highbd_iht4x4_16_add_neon>, 4,
|
||||
2 },
|
||||
{ &vp9_highbd_fht8x8_c, &highbd_iht_wrapper<vp9_highbd_iht8x8_64_add_neon>, 8,
|
||||
2 },
|
||||
{ &vp9_highbd_fht16x16_c,
|
||||
&highbd_iht_wrapper<vp9_highbd_iht16x16_256_add_neon>, 16, 2 },
|
||||
#endif
|
||||
{ &vp9_fht4x4_c, &iht_wrapper<vp9_iht4x4_16_add_neon>, 4, 1 },
|
||||
{ &vp9_fht8x8_c, &iht_wrapper<vp9_iht8x8_64_add_neon>, 8, 1 },
|
||||
{ &vp9_fht16x16_c, &iht_wrapper<vp9_iht16x16_256_add_neon>, 16, 1 }
|
||||
};
|
||||
|
||||
INSTANTIATE_TEST_CASE_P(
|
||||
NEON, TransHT,
|
||||
::testing::Combine(
|
||||
::testing::Range(0, static_cast<int>(sizeof(ht_neon_func_info) /
|
||||
sizeof(ht_neon_func_info[0]))),
|
||||
::testing::Values(ht_neon_func_info), ::testing::Range(0, 4),
|
||||
::testing::Values(VPX_BITS_8, VPX_BITS_10, VPX_BITS_12)));
|
||||
#endif // HAVE_NEON
|
||||
|
||||
#if HAVE_SSE2
|
||||
|
||||
static const FuncInfo ht_sse2_func_info[3] = {
|
||||
{ &vp9_fht4x4_sse2, &iht_wrapper<vp9_iht4x4_16_add_sse2>, 4, 1 },
|
||||
{ &vp9_fht8x8_sse2, &iht_wrapper<vp9_iht8x8_64_add_sse2>, 8, 1 },
|
||||
{ &vp9_fht16x16_sse2, &iht_wrapper<vp9_iht16x16_256_add_sse2>, 16, 1 }
|
||||
};
|
||||
|
||||
INSTANTIATE_TEST_CASE_P(SSE2, TransHT,
|
||||
::testing::Combine(::testing::Range(0, 3),
|
||||
::testing::Values(ht_sse2_func_info),
|
||||
::testing::Range(0, 4),
|
||||
::testing::Values(VPX_BITS_8)));
|
||||
#endif // HAVE_SSE2
|
||||
|
||||
#if HAVE_SSE4_1 && CONFIG_VP9_HIGHBITDEPTH
|
||||
static const FuncInfo ht_sse4_1_func_info[3] = {
|
||||
{ &vp9_highbd_fht4x4_c, &highbd_iht_wrapper<vp9_highbd_iht4x4_16_add_sse4_1>,
|
||||
4, 2 },
|
||||
{ vp9_highbd_fht8x8_c, &highbd_iht_wrapper<vp9_highbd_iht8x8_64_add_sse4_1>,
|
||||
8, 2 },
|
||||
{ &vp9_highbd_fht16x16_c,
|
||||
&highbd_iht_wrapper<vp9_highbd_iht16x16_256_add_sse4_1>, 16, 2 }
|
||||
};
|
||||
|
||||
INSTANTIATE_TEST_CASE_P(
|
||||
SSE4_1, TransHT,
|
||||
::testing::Combine(::testing::Range(0, 3),
|
||||
::testing::Values(ht_sse4_1_func_info),
|
||||
::testing::Range(0, 4),
|
||||
::testing::Values(VPX_BITS_8, VPX_BITS_10,
|
||||
VPX_BITS_12)));
|
||||
#endif // HAVE_SSE4_1 && CONFIG_VP9_HIGHBITDEPTH
|
||||
|
||||
#endif // !CONFIG_EMULATE_HARDWARE
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
|
||||
class TransWHT : public TransTestBase {
|
||||
public:
|
||||
TransWHT() { fwd_txfm_ref = fwht_ref; }
|
||||
};
|
||||
|
||||
TEST_P(TransWHT, AccuracyCheck) { RunAccuracyCheck(0); }
|
||||
|
||||
TEST_P(TransWHT, CoeffCheck) { RunCoeffCheck(); }
|
||||
|
||||
TEST_P(TransWHT, MemCheck) { RunMemCheck(); }
|
||||
|
||||
TEST_P(TransWHT, InvAccuracyCheck) { RunInvAccuracyCheck(0); }
|
||||
|
||||
static const FuncInfo wht_c_func_info[] = {
|
||||
#if CONFIG_VP9_HIGHBITDEPTH
|
||||
{ &fdct_wrapper<vp9_highbd_fwht4x4_c>,
|
||||
&highbd_idct_wrapper<vpx_highbd_iwht4x4_16_add_c>, 4, 2 },
|
||||
#endif
|
||||
{ &fdct_wrapper<vp9_fwht4x4_c>, &idct_wrapper<vpx_iwht4x4_16_add_c>, 4, 1 }
|
||||
};
|
||||
|
||||
INSTANTIATE_TEST_CASE_P(
|
||||
C, TransWHT,
|
||||
::testing::Combine(
|
||||
::testing::Range(0, static_cast<int>(sizeof(wht_c_func_info) /
|
||||
sizeof(wht_c_func_info[0]))),
|
||||
::testing::Values(wht_c_func_info), ::testing::Values(0),
|
||||
::testing::Values(VPX_BITS_8, VPX_BITS_10, VPX_BITS_12)));
|
||||
|
||||
#if HAVE_SSE2 && !CONFIG_EMULATE_HARDWARE
|
||||
static const FuncInfo wht_sse2_func_info = {
|
||||
&fdct_wrapper<vp9_fwht4x4_sse2>, &idct_wrapper<vpx_iwht4x4_16_add_sse2>, 4, 1
|
||||
};
|
||||
|
||||
INSTANTIATE_TEST_CASE_P(SSE2, TransWHT,
|
||||
::testing::Values(make_tuple(0, &wht_sse2_func_info, 0,
|
||||
VPX_BITS_8)));
|
||||
#endif // HAVE_SSE2 && !CONFIG_EMULATE_HARDWARE
|
||||
} // namespace
|
@ -172,21 +172,4 @@ TEST(DecodeAPI, Vp9PeekSI) {
|
||||
}
|
||||
#endif // CONFIG_VP9_DECODER
|
||||
|
||||
TEST(DecodeAPI, HighBitDepthCapability) {
|
||||
// VP8 should not claim VP9 HBD as a capability.
|
||||
#if CONFIG_VP8_DECODER
|
||||
const vpx_codec_caps_t vp8_caps = vpx_codec_get_caps(&vpx_codec_vp8_dx_algo);
|
||||
EXPECT_EQ(vp8_caps & VPX_CODEC_CAP_HIGHBITDEPTH, 0);
|
||||
#endif
|
||||
|
||||
#if CONFIG_VP9_DECODER
|
||||
const vpx_codec_caps_t vp9_caps = vpx_codec_get_caps(&vpx_codec_vp9_dx_algo);
|
||||
#if CONFIG_VP9_HIGHBITDEPTH
|
||||
EXPECT_EQ(vp9_caps & VPX_CODEC_CAP_HIGHBITDEPTH, VPX_CODEC_CAP_HIGHBITDEPTH);
|
||||
#else
|
||||
EXPECT_EQ(vp9_caps & VPX_CODEC_CAP_HIGHBITDEPTH, 0);
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
@ -21,7 +21,7 @@
|
||||
#include "./ivfenc.h"
|
||||
#include "./vpx_version.h"
|
||||
|
||||
using ::testing::make_tuple;
|
||||
using std::tr1::make_tuple;
|
||||
|
||||
namespace {
|
||||
|
||||
@ -34,7 +34,7 @@ const char kNewEncodeOutputFile[] = "new_encode.ivf";
|
||||
/*
|
||||
DecodePerfTest takes a tuple of filename + number of threads to decode with
|
||||
*/
|
||||
typedef ::testing::tuple<const char *, unsigned> DecodePerfParam;
|
||||
typedef std::tr1::tuple<const char *, unsigned> DecodePerfParam;
|
||||
|
||||
const DecodePerfParam kVP9DecodePerfVectors[] = {
|
||||
make_tuple("vp90-2-bbb_426x240_tile_1x1_180kbps.webm", 1),
|
||||
|
@ -52,15 +52,14 @@ 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) {
|
||||
ASSERT_EQ(VPX_CODEC_OK, res_peek)
|
||||
<< "Peek return failed: " << vpx_codec_err_to_string(res_peek);
|
||||
}
|
||||
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. */
|
||||
ASSERT_EQ(VPX_CODEC_OK, res_peek)
|
||||
<< "Peek return failed: " << vpx_codec_err_to_string(res_peek);
|
||||
ASSERT_EQ(VPX_CODEC_OK, res_peek) << "Peek return failed: "
|
||||
<< vpx_codec_err_to_string(res_peek);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -62,134 +62,4 @@ TEST(EncodeAPI, InvalidParams) {
|
||||
}
|
||||
}
|
||||
|
||||
TEST(EncodeAPI, HighBitDepthCapability) {
|
||||
// VP8 should not claim VP9 HBD as a capability.
|
||||
#if CONFIG_VP8_ENCODER
|
||||
const vpx_codec_caps_t vp8_caps = vpx_codec_get_caps(&vpx_codec_vp8_cx_algo);
|
||||
EXPECT_EQ(vp8_caps & VPX_CODEC_CAP_HIGHBITDEPTH, 0);
|
||||
#endif
|
||||
|
||||
#if CONFIG_VP9_ENCODER
|
||||
const vpx_codec_caps_t vp9_caps = vpx_codec_get_caps(&vpx_codec_vp9_cx_algo);
|
||||
#if CONFIG_VP9_HIGHBITDEPTH
|
||||
EXPECT_EQ(vp9_caps & VPX_CODEC_CAP_HIGHBITDEPTH, VPX_CODEC_CAP_HIGHBITDEPTH);
|
||||
#else
|
||||
EXPECT_EQ(vp9_caps & VPX_CODEC_CAP_HIGHBITDEPTH, 0);
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
|
||||
#if CONFIG_VP8_ENCODER
|
||||
TEST(EncodeAPI, ImageSizeSetting) {
|
||||
const int width = 711;
|
||||
const int height = 360;
|
||||
const int bps = 12;
|
||||
vpx_image_t img;
|
||||
vpx_codec_ctx_t enc;
|
||||
vpx_codec_enc_cfg_t cfg;
|
||||
uint8_t *img_buf = reinterpret_cast<uint8_t *>(
|
||||
calloc(width * height * bps / 8, sizeof(*img_buf)));
|
||||
vpx_codec_enc_config_default(vpx_codec_vp8_cx(), &cfg, 0);
|
||||
|
||||
cfg.g_w = width;
|
||||
cfg.g_h = height;
|
||||
|
||||
vpx_img_wrap(&img, VPX_IMG_FMT_I420, width, height, 1, img_buf);
|
||||
|
||||
vpx_codec_enc_init(&enc, vpx_codec_vp8_cx(), &cfg, 0);
|
||||
|
||||
EXPECT_EQ(VPX_CODEC_OK, vpx_codec_encode(&enc, &img, 0, 1, 0, 0));
|
||||
|
||||
free(img_buf);
|
||||
|
||||
vpx_codec_destroy(&enc);
|
||||
}
|
||||
#endif
|
||||
|
||||
// Set up 2 spatial streams with 2 temporal layers per stream, and generate
|
||||
// invalid configuration by setting the temporal layer rate allocation
|
||||
// (ts_target_bitrate[]) to 0 for both layers. This should fail independent of
|
||||
// CONFIG_MULTI_RES_ENCODING.
|
||||
TEST(EncodeAPI, MultiResEncode) {
|
||||
static const vpx_codec_iface_t *kCodecs[] = {
|
||||
#if CONFIG_VP8_ENCODER
|
||||
&vpx_codec_vp8_cx_algo,
|
||||
#endif
|
||||
#if CONFIG_VP9_ENCODER
|
||||
&vpx_codec_vp9_cx_algo,
|
||||
#endif
|
||||
};
|
||||
const int width = 1280;
|
||||
const int height = 720;
|
||||
const int width_down = width / 2;
|
||||
const int height_down = height / 2;
|
||||
const int target_bitrate = 1000;
|
||||
const int framerate = 30;
|
||||
|
||||
for (int c = 0; c < NELEMENTS(kCodecs); ++c) {
|
||||
const vpx_codec_iface_t *const iface = kCodecs[c];
|
||||
vpx_codec_ctx_t enc[2];
|
||||
vpx_codec_enc_cfg_t cfg[2];
|
||||
vpx_rational_t dsf[2] = { { 2, 1 }, { 2, 1 } };
|
||||
|
||||
memset(enc, 0, sizeof(enc));
|
||||
|
||||
for (int i = 0; i < 2; i++) {
|
||||
vpx_codec_enc_config_default(iface, &cfg[i], 0);
|
||||
}
|
||||
|
||||
/* Highest-resolution encoder settings */
|
||||
cfg[0].g_w = width;
|
||||
cfg[0].g_h = height;
|
||||
cfg[0].rc_dropframe_thresh = 0;
|
||||
cfg[0].rc_end_usage = VPX_CBR;
|
||||
cfg[0].rc_resize_allowed = 0;
|
||||
cfg[0].rc_min_quantizer = 2;
|
||||
cfg[0].rc_max_quantizer = 56;
|
||||
cfg[0].rc_undershoot_pct = 100;
|
||||
cfg[0].rc_overshoot_pct = 15;
|
||||
cfg[0].rc_buf_initial_sz = 500;
|
||||
cfg[0].rc_buf_optimal_sz = 600;
|
||||
cfg[0].rc_buf_sz = 1000;
|
||||
cfg[0].g_error_resilient = 1; /* Enable error resilient mode */
|
||||
cfg[0].g_lag_in_frames = 0;
|
||||
|
||||
cfg[0].kf_mode = VPX_KF_AUTO;
|
||||
cfg[0].kf_min_dist = 3000;
|
||||
cfg[0].kf_max_dist = 3000;
|
||||
|
||||
cfg[0].rc_target_bitrate = target_bitrate; /* Set target bitrate */
|
||||
cfg[0].g_timebase.num = 1; /* Set fps */
|
||||
cfg[0].g_timebase.den = framerate;
|
||||
|
||||
memcpy(&cfg[1], &cfg[0], sizeof(cfg[0]));
|
||||
cfg[1].rc_target_bitrate = 500;
|
||||
cfg[1].g_w = width_down;
|
||||
cfg[1].g_h = height_down;
|
||||
|
||||
for (int i = 0; i < 2; i++) {
|
||||
cfg[i].ts_number_layers = 2;
|
||||
cfg[i].ts_periodicity = 2;
|
||||
cfg[i].ts_rate_decimator[0] = 2;
|
||||
cfg[i].ts_rate_decimator[1] = 1;
|
||||
cfg[i].ts_layer_id[0] = 0;
|
||||
cfg[i].ts_layer_id[1] = 1;
|
||||
// Invalid parameters.
|
||||
cfg[i].ts_target_bitrate[0] = 0;
|
||||
cfg[i].ts_target_bitrate[1] = 0;
|
||||
}
|
||||
|
||||
// VP9 should report incapable, VP8 invalid for all configurations.
|
||||
const char kVP9Name[] = "WebM Project VP9";
|
||||
const bool is_vp9 = strncmp(kVP9Name, vpx_codec_iface_name(iface),
|
||||
sizeof(kVP9Name) - 1) == 0;
|
||||
EXPECT_EQ(is_vp9 ? VPX_CODEC_INCAPABLE : VPX_CODEC_INVALID_PARAM,
|
||||
vpx_codec_enc_init_multi(&enc[0], iface, &cfg[0], 2, 0, &dsf[0]));
|
||||
|
||||
for (int i = 0; i < 2; i++) {
|
||||
vpx_codec_destroy(&enc[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
@ -201,8 +201,6 @@ void EncoderTest::RunLoop(VideoSource *video) {
|
||||
PreEncodeFrameHook(video, encoder.get());
|
||||
encoder->EncodeFrame(video, frame_flags_);
|
||||
|
||||
PostEncodeFrameHook();
|
||||
|
||||
CxDataIterator iter = encoder->GetCxData();
|
||||
|
||||
bool has_cxdata = false;
|
||||
@ -228,8 +226,6 @@ void EncoderTest::RunLoop(VideoSource *video) {
|
||||
|
||||
case VPX_CODEC_PSNR_PKT: PSNRPktHook(pkt); break;
|
||||
|
||||
case VPX_CODEC_STATS_PKT: StatsPktHook(pkt); break;
|
||||
|
||||
default: break;
|
||||
}
|
||||
}
|
||||
|
@ -128,31 +128,17 @@ 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();
|
||||
}
|
||||
#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();
|
||||
}
|
||||
|
||||
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();
|
||||
@ -226,17 +212,12 @@ class EncoderTest {
|
||||
virtual void PreEncodeFrameHook(VideoSource * /*video*/,
|
||||
Encoder * /*encoder*/) {}
|
||||
|
||||
virtual void PostEncodeFrameHook() {}
|
||||
|
||||
// Hook to be called on every compressed data packet.
|
||||
virtual void FramePktHook(const vpx_codec_cx_pkt_t * /*pkt*/) {}
|
||||
|
||||
// Hook to be called on every PSNR packet.
|
||||
virtual void PSNRPktHook(const vpx_codec_cx_pkt_t * /*pkt*/) {}
|
||||
|
||||
// Hook to be called on every first pass stats packet.
|
||||
virtual void StatsPktHook(const vpx_codec_cx_pkt_t * /*pkt*/) {}
|
||||
|
||||
// Hook to determine whether the encode loop should continue.
|
||||
virtual bool Continue() const {
|
||||
return !(::testing::Test::HasFatalFailure() || abort_);
|
||||
|
@ -15,7 +15,7 @@
|
||||
example_tests=$(ls $(dirname $0)/*.sh)
|
||||
|
||||
# List of script names to exclude.
|
||||
exclude_list="examples stress tools_common"
|
||||
exclude_list="examples tools_common"
|
||||
|
||||
# Filter out the scripts in $exclude_list.
|
||||
for word in ${exclude_list}; do
|
||||
|
@ -34,8 +34,7 @@ struct ExternalFrameBuffer {
|
||||
// Class to manipulate a list of external frame buffers.
|
||||
class ExternalFrameBufferList {
|
||||
public:
|
||||
ExternalFrameBufferList()
|
||||
: num_buffers_(0), num_used_buffers_(0), ext_fb_list_(NULL) {}
|
||||
ExternalFrameBufferList() : num_buffers_(0), ext_fb_list_(NULL) {}
|
||||
|
||||
virtual ~ExternalFrameBufferList() {
|
||||
for (int i = 0; i < num_buffers_; ++i) {
|
||||
@ -72,8 +71,6 @@ class ExternalFrameBufferList {
|
||||
}
|
||||
|
||||
SetFrameBuffer(idx, fb);
|
||||
|
||||
num_used_buffers_++;
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -109,7 +106,6 @@ class ExternalFrameBufferList {
|
||||
}
|
||||
EXPECT_EQ(1, ext_fb->in_use);
|
||||
ext_fb->in_use = 0;
|
||||
num_used_buffers_--;
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -125,8 +121,6 @@ class ExternalFrameBufferList {
|
||||
}
|
||||
}
|
||||
|
||||
int num_used_buffers() const { return num_used_buffers_; }
|
||||
|
||||
private:
|
||||
// Returns the index of the first free frame buffer. Returns |num_buffers_|
|
||||
// if there are no free frame buffers.
|
||||
@ -151,7 +145,6 @@ class ExternalFrameBufferList {
|
||||
}
|
||||
|
||||
int num_buffers_;
|
||||
int num_used_buffers_;
|
||||
ExternalFrameBuffer *ext_fb_list_;
|
||||
};
|
||||
|
||||
@ -227,8 +220,8 @@ class ExternalFrameBufferMD5Test
|
||||
|
||||
void OpenMD5File(const std::string &md5_file_name_) {
|
||||
md5_file_ = libvpx_test::OpenTestDataFile(md5_file_name_);
|
||||
ASSERT_TRUE(md5_file_ != NULL)
|
||||
<< "Md5 file open failed. Filename: " << md5_file_name_;
|
||||
ASSERT_TRUE(md5_file_ != NULL) << "Md5 file open failed. Filename: "
|
||||
<< md5_file_name_;
|
||||
}
|
||||
|
||||
virtual void DecompressedFrameHook(const vpx_image_t &img,
|
||||
@ -280,7 +273,6 @@ class ExternalFrameBufferMD5Test
|
||||
|
||||
#if CONFIG_WEBM_IO
|
||||
const char kVP9TestFile[] = "vp90-2-02-size-lf-1920x1080.webm";
|
||||
const char kVP9NonRefTestFile[] = "vp90-2-22-svc_1280x720_1.webm";
|
||||
|
||||
// Class for testing passing in external frame buffers to libvpx.
|
||||
class ExternalFrameBufferTest : public ::testing::Test {
|
||||
@ -300,9 +292,7 @@ class ExternalFrameBufferTest : public ::testing::Test {
|
||||
|
||||
virtual void TearDown() {
|
||||
delete decoder_;
|
||||
decoder_ = NULL;
|
||||
delete video_;
|
||||
video_ = NULL;
|
||||
}
|
||||
|
||||
// Passes the external frame buffer information to libvpx.
|
||||
@ -335,7 +325,7 @@ class ExternalFrameBufferTest : public ::testing::Test {
|
||||
return VPX_CODEC_OK;
|
||||
}
|
||||
|
||||
protected:
|
||||
private:
|
||||
void CheckDecodedFrames() {
|
||||
libvpx_test::DxDataIterator dec_iter = decoder_->GetDxData();
|
||||
const vpx_image_t *img = NULL;
|
||||
@ -351,25 +341,6 @@ class ExternalFrameBufferTest : public ::testing::Test {
|
||||
int num_buffers_;
|
||||
ExternalFrameBufferList fb_list_;
|
||||
};
|
||||
|
||||
class ExternalFrameBufferNonRefTest : public ExternalFrameBufferTest {
|
||||
protected:
|
||||
virtual void SetUp() {
|
||||
video_ = new libvpx_test::WebMVideoSource(kVP9NonRefTestFile);
|
||||
ASSERT_TRUE(video_ != NULL);
|
||||
video_->Init();
|
||||
video_->Begin();
|
||||
|
||||
vpx_codec_dec_cfg_t cfg = vpx_codec_dec_cfg_t();
|
||||
decoder_ = new libvpx_test::VP9Decoder(cfg, 0);
|
||||
ASSERT_TRUE(decoder_ != NULL);
|
||||
}
|
||||
|
||||
virtual void CheckFrameBufferRelease() {
|
||||
TearDown();
|
||||
ASSERT_EQ(0, fb_list_.num_used_buffers());
|
||||
}
|
||||
};
|
||||
#endif // CONFIG_WEBM_IO
|
||||
|
||||
// This test runs through the set of test vectors, and decodes them.
|
||||
@ -448,8 +419,6 @@ TEST_F(ExternalFrameBufferTest, NotEnoughBuffers) {
|
||||
SetFrameBufferFunctions(num_buffers, get_vp9_frame_buffer,
|
||||
release_vp9_frame_buffer));
|
||||
ASSERT_EQ(VPX_CODEC_OK, DecodeOneFrame());
|
||||
// Only run this on long clips. Decoding a very short clip will return
|
||||
// VPX_CODEC_OK even with only 2 buffers.
|
||||
ASSERT_EQ(VPX_CODEC_MEM_ERROR, DecodeRemainingFrames());
|
||||
}
|
||||
|
||||
@ -498,15 +467,6 @@ TEST_F(ExternalFrameBufferTest, SetAfterDecode) {
|
||||
SetFrameBufferFunctions(num_buffers, get_vp9_frame_buffer,
|
||||
release_vp9_frame_buffer));
|
||||
}
|
||||
|
||||
TEST_F(ExternalFrameBufferNonRefTest, ReleaseNonRefFrameBuffer) {
|
||||
const int num_buffers = VP9_MAXIMUM_REF_BUFFERS + VPX_MAXIMUM_WORK_BUFFERS;
|
||||
ASSERT_EQ(VPX_CODEC_OK,
|
||||
SetFrameBufferFunctions(num_buffers, get_vp9_frame_buffer,
|
||||
release_vp9_frame_buffer));
|
||||
ASSERT_EQ(VPX_CODEC_OK, DecodeRemainingFrames());
|
||||
CheckFrameBufferRelease();
|
||||
}
|
||||
#endif // CONFIG_WEBM_IO
|
||||
|
||||
VP9_INSTANTIATE_TEST_CASE(
|
||||
|
512
test/fdct4x4_test.cc
Normal file
512
test/fdct4x4_test.cc
Normal file
@ -0,0 +1,512 @@
|
||||
/*
|
||||
* Copyright (c) 2012 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 <math.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "third_party/googletest/src/include/gtest/gtest.h"
|
||||
|
||||
#include "./vp9_rtcd.h"
|
||||
#include "./vpx_dsp_rtcd.h"
|
||||
#include "test/acm_random.h"
|
||||
#include "test/clear_system_state.h"
|
||||
#include "test/register_state_check.h"
|
||||
#include "test/util.h"
|
||||
#include "vp9/common/vp9_entropy.h"
|
||||
#include "vpx/vpx_codec.h"
|
||||
#include "vpx/vpx_integer.h"
|
||||
#include "vpx_ports/mem.h"
|
||||
|
||||
using libvpx_test::ACMRandom;
|
||||
|
||||
namespace {
|
||||
const int kNumCoeffs = 16;
|
||||
typedef void (*FdctFunc)(const int16_t *in, tran_low_t *out, int stride);
|
||||
typedef void (*IdctFunc)(const tran_low_t *in, uint8_t *out, int stride);
|
||||
typedef void (*FhtFunc)(const int16_t *in, tran_low_t *out, int stride,
|
||||
int tx_type);
|
||||
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> Dct4x4Param;
|
||||
typedef std::tr1::tuple<FhtFunc, IhtFunc, int, vpx_bit_depth_t> Ht4x4Param;
|
||||
|
||||
void fdct4x4_ref(const int16_t *in, tran_low_t *out, int stride,
|
||||
int /*tx_type*/) {
|
||||
vpx_fdct4x4_c(in, out, stride);
|
||||
}
|
||||
|
||||
void fht4x4_ref(const int16_t *in, tran_low_t *out, int stride, int tx_type) {
|
||||
vp9_fht4x4_c(in, out, stride, tx_type);
|
||||
}
|
||||
|
||||
void fwht4x4_ref(const int16_t *in, tran_low_t *out, int stride,
|
||||
int /*tx_type*/) {
|
||||
vp9_fwht4x4_c(in, out, stride);
|
||||
}
|
||||
|
||||
#if CONFIG_VP9_HIGHBITDEPTH
|
||||
void idct4x4_10(const tran_low_t *in, uint8_t *out, int stride) {
|
||||
vpx_highbd_idct4x4_16_add_c(in, out, stride, 10);
|
||||
}
|
||||
|
||||
void idct4x4_12(const tran_low_t *in, uint8_t *out, int stride) {
|
||||
vpx_highbd_idct4x4_16_add_c(in, out, stride, 12);
|
||||
}
|
||||
|
||||
void iht4x4_10(const tran_low_t *in, uint8_t *out, int stride, int tx_type) {
|
||||
vp9_highbd_iht4x4_16_add_c(in, out, stride, tx_type, 10);
|
||||
}
|
||||
|
||||
void iht4x4_12(const tran_low_t *in, uint8_t *out, int stride, int tx_type) {
|
||||
vp9_highbd_iht4x4_16_add_c(in, out, stride, tx_type, 12);
|
||||
}
|
||||
|
||||
void iwht4x4_10(const tran_low_t *in, uint8_t *out, int stride) {
|
||||
vpx_highbd_iwht4x4_16_add_c(in, out, stride, 10);
|
||||
}
|
||||
|
||||
void iwht4x4_12(const tran_low_t *in, uint8_t *out, int stride) {
|
||||
vpx_highbd_iwht4x4_16_add_c(in, out, stride, 12);
|
||||
}
|
||||
|
||||
#if HAVE_SSE2
|
||||
void idct4x4_10_sse2(const tran_low_t *in, uint8_t *out, int stride) {
|
||||
vpx_highbd_idct4x4_16_add_sse2(in, out, stride, 10);
|
||||
}
|
||||
|
||||
void idct4x4_12_sse2(const tran_low_t *in, uint8_t *out, int stride) {
|
||||
vpx_highbd_idct4x4_16_add_sse2(in, out, stride, 12);
|
||||
}
|
||||
#endif // HAVE_SSE2
|
||||
#endif // CONFIG_VP9_HIGHBITDEPTH
|
||||
|
||||
class Trans4x4TestBase {
|
||||
public:
|
||||
virtual ~Trans4x4TestBase() {}
|
||||
|
||||
protected:
|
||||
virtual void RunFwdTxfm(const int16_t *in, tran_low_t *out, int stride) = 0;
|
||||
|
||||
virtual void RunInvTxfm(const tran_low_t *out, uint8_t *dst, int stride) = 0;
|
||||
|
||||
void RunAccuracyCheck(int limit) {
|
||||
ACMRandom rnd(ACMRandom::DeterministicSeed());
|
||||
uint32_t max_error = 0;
|
||||
int64_t total_error = 0;
|
||||
const int count_test_block = 10000;
|
||||
for (int i = 0; i < count_test_block; ++i) {
|
||||
DECLARE_ALIGNED(16, int16_t, test_input_block[kNumCoeffs]);
|
||||
DECLARE_ALIGNED(16, tran_low_t, test_temp_block[kNumCoeffs]);
|
||||
DECLARE_ALIGNED(16, uint8_t, dst[kNumCoeffs]);
|
||||
DECLARE_ALIGNED(16, uint8_t, src[kNumCoeffs]);
|
||||
#if CONFIG_VP9_HIGHBITDEPTH
|
||||
DECLARE_ALIGNED(16, uint16_t, dst16[kNumCoeffs]);
|
||||
DECLARE_ALIGNED(16, uint16_t, src16[kNumCoeffs]);
|
||||
#endif
|
||||
|
||||
// Initialize a test block with input range [-255, 255].
|
||||
for (int j = 0; j < kNumCoeffs; ++j) {
|
||||
if (bit_depth_ == VPX_BITS_8) {
|
||||
src[j] = rnd.Rand8();
|
||||
dst[j] = rnd.Rand8();
|
||||
test_input_block[j] = src[j] - dst[j];
|
||||
#if CONFIG_VP9_HIGHBITDEPTH
|
||||
} else {
|
||||
src16[j] = rnd.Rand16() & mask_;
|
||||
dst16[j] = rnd.Rand16() & mask_;
|
||||
test_input_block[j] = src16[j] - dst16[j];
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
ASM_REGISTER_STATE_CHECK(
|
||||
RunFwdTxfm(test_input_block, test_temp_block, pitch_));
|
||||
if (bit_depth_ == VPX_BITS_8) {
|
||||
ASM_REGISTER_STATE_CHECK(RunInvTxfm(test_temp_block, dst, pitch_));
|
||||
#if CONFIG_VP9_HIGHBITDEPTH
|
||||
} else {
|
||||
ASM_REGISTER_STATE_CHECK(
|
||||
RunInvTxfm(test_temp_block, CONVERT_TO_BYTEPTR(dst16), pitch_));
|
||||
#endif
|
||||
}
|
||||
|
||||
for (int j = 0; j < kNumCoeffs; ++j) {
|
||||
#if CONFIG_VP9_HIGHBITDEPTH
|
||||
const int diff =
|
||||
bit_depth_ == VPX_BITS_8 ? dst[j] - src[j] : dst16[j] - src16[j];
|
||||
#else
|
||||
ASSERT_EQ(VPX_BITS_8, bit_depth_);
|
||||
const int diff = dst[j] - src[j];
|
||||
#endif
|
||||
const uint32_t error = diff * diff;
|
||||
if (max_error < error) max_error = error;
|
||||
total_error += error;
|
||||
}
|
||||
}
|
||||
|
||||
EXPECT_GE(static_cast<uint32_t>(limit), max_error)
|
||||
<< "Error: 4x4 FHT/IHT has an individual round trip error > " << limit;
|
||||
|
||||
EXPECT_GE(count_test_block * limit, total_error)
|
||||
<< "Error: 4x4 FHT/IHT has average round trip error > " << limit
|
||||
<< " per block";
|
||||
}
|
||||
|
||||
void RunCoeffCheck() {
|
||||
ACMRandom rnd(ACMRandom::DeterministicSeed());
|
||||
const int count_test_block = 5000;
|
||||
DECLARE_ALIGNED(16, int16_t, input_block[kNumCoeffs]);
|
||||
DECLARE_ALIGNED(16, tran_low_t, output_ref_block[kNumCoeffs]);
|
||||
DECLARE_ALIGNED(16, tran_low_t, output_block[kNumCoeffs]);
|
||||
|
||||
for (int i = 0; i < count_test_block; ++i) {
|
||||
// Initialize a test block with input range [-mask_, mask_].
|
||||
for (int j = 0; j < kNumCoeffs; ++j) {
|
||||
input_block[j] = (rnd.Rand16() & mask_) - (rnd.Rand16() & mask_);
|
||||
}
|
||||
|
||||
fwd_txfm_ref(input_block, output_ref_block, pitch_, tx_type_);
|
||||
ASM_REGISTER_STATE_CHECK(RunFwdTxfm(input_block, output_block, pitch_));
|
||||
|
||||
// The minimum quant value is 4.
|
||||
for (int j = 0; j < kNumCoeffs; ++j)
|
||||
EXPECT_EQ(output_block[j], output_ref_block[j]);
|
||||
}
|
||||
}
|
||||
|
||||
void RunMemCheck() {
|
||||
ACMRandom rnd(ACMRandom::DeterministicSeed());
|
||||
const int count_test_block = 5000;
|
||||
DECLARE_ALIGNED(16, int16_t, input_extreme_block[kNumCoeffs]);
|
||||
DECLARE_ALIGNED(16, tran_low_t, output_ref_block[kNumCoeffs]);
|
||||
DECLARE_ALIGNED(16, tran_low_t, output_block[kNumCoeffs]);
|
||||
|
||||
for (int i = 0; i < count_test_block; ++i) {
|
||||
// Initialize a test block with input range [-mask_, mask_].
|
||||
for (int j = 0; j < kNumCoeffs; ++j) {
|
||||
input_extreme_block[j] = rnd.Rand8() % 2 ? mask_ : -mask_;
|
||||
}
|
||||
if (i == 0) {
|
||||
for (int j = 0; j < kNumCoeffs; ++j) input_extreme_block[j] = mask_;
|
||||
} else if (i == 1) {
|
||||
for (int j = 0; j < kNumCoeffs; ++j) input_extreme_block[j] = -mask_;
|
||||
}
|
||||
|
||||
fwd_txfm_ref(input_extreme_block, output_ref_block, pitch_, tx_type_);
|
||||
ASM_REGISTER_STATE_CHECK(
|
||||
RunFwdTxfm(input_extreme_block, output_block, pitch_));
|
||||
|
||||
// The minimum quant value is 4.
|
||||
for (int j = 0; j < kNumCoeffs; ++j) {
|
||||
EXPECT_EQ(output_block[j], output_ref_block[j]);
|
||||
EXPECT_GE(4 * DCT_MAX_VALUE << (bit_depth_ - 8), abs(output_block[j]))
|
||||
<< "Error: 4x4 FDCT has coefficient larger than 4*DCT_MAX_VALUE";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void RunInvAccuracyCheck(int limit) {
|
||||
ACMRandom rnd(ACMRandom::DeterministicSeed());
|
||||
const int count_test_block = 1000;
|
||||
DECLARE_ALIGNED(16, int16_t, in[kNumCoeffs]);
|
||||
DECLARE_ALIGNED(16, tran_low_t, coeff[kNumCoeffs]);
|
||||
DECLARE_ALIGNED(16, uint8_t, dst[kNumCoeffs]);
|
||||
DECLARE_ALIGNED(16, uint8_t, src[kNumCoeffs]);
|
||||
#if CONFIG_VP9_HIGHBITDEPTH
|
||||
DECLARE_ALIGNED(16, uint16_t, dst16[kNumCoeffs]);
|
||||
DECLARE_ALIGNED(16, uint16_t, src16[kNumCoeffs]);
|
||||
#endif
|
||||
|
||||
for (int i = 0; i < count_test_block; ++i) {
|
||||
// Initialize a test block with input range [-mask_, mask_].
|
||||
for (int j = 0; j < kNumCoeffs; ++j) {
|
||||
if (bit_depth_ == VPX_BITS_8) {
|
||||
src[j] = rnd.Rand8();
|
||||
dst[j] = rnd.Rand8();
|
||||
in[j] = src[j] - dst[j];
|
||||
#if CONFIG_VP9_HIGHBITDEPTH
|
||||
} else {
|
||||
src16[j] = rnd.Rand16() & mask_;
|
||||
dst16[j] = rnd.Rand16() & mask_;
|
||||
in[j] = src16[j] - dst16[j];
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
fwd_txfm_ref(in, coeff, pitch_, tx_type_);
|
||||
|
||||
if (bit_depth_ == VPX_BITS_8) {
|
||||
ASM_REGISTER_STATE_CHECK(RunInvTxfm(coeff, dst, pitch_));
|
||||
#if CONFIG_VP9_HIGHBITDEPTH
|
||||
} else {
|
||||
ASM_REGISTER_STATE_CHECK(
|
||||
RunInvTxfm(coeff, CONVERT_TO_BYTEPTR(dst16), pitch_));
|
||||
#endif
|
||||
}
|
||||
|
||||
for (int j = 0; j < kNumCoeffs; ++j) {
|
||||
#if CONFIG_VP9_HIGHBITDEPTH
|
||||
const int diff =
|
||||
bit_depth_ == VPX_BITS_8 ? dst[j] - src[j] : dst16[j] - src16[j];
|
||||
#else
|
||||
const int diff = dst[j] - src[j];
|
||||
#endif
|
||||
const uint32_t error = diff * diff;
|
||||
EXPECT_GE(static_cast<uint32_t>(limit), error)
|
||||
<< "Error: 4x4 IDCT has error " << error << " at index " << j;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int pitch_;
|
||||
int tx_type_;
|
||||
FhtFunc fwd_txfm_ref;
|
||||
vpx_bit_depth_t bit_depth_;
|
||||
int mask_;
|
||||
};
|
||||
|
||||
class Trans4x4DCT : public Trans4x4TestBase,
|
||||
public ::testing::TestWithParam<Dct4x4Param> {
|
||||
public:
|
||||
virtual ~Trans4x4DCT() {}
|
||||
|
||||
virtual void SetUp() {
|
||||
fwd_txfm_ = GET_PARAM(0);
|
||||
inv_txfm_ = GET_PARAM(1);
|
||||
tx_type_ = GET_PARAM(2);
|
||||
pitch_ = 4;
|
||||
fwd_txfm_ref = fdct4x4_ref;
|
||||
bit_depth_ = GET_PARAM(3);
|
||||
mask_ = (1 << bit_depth_) - 1;
|
||||
}
|
||||
virtual void TearDown() { libvpx_test::ClearSystemState(); }
|
||||
|
||||
protected:
|
||||
void RunFwdTxfm(const int16_t *in, tran_low_t *out, int stride) {
|
||||
fwd_txfm_(in, out, stride);
|
||||
}
|
||||
void RunInvTxfm(const tran_low_t *out, uint8_t *dst, int stride) {
|
||||
inv_txfm_(out, dst, stride);
|
||||
}
|
||||
|
||||
FdctFunc fwd_txfm_;
|
||||
IdctFunc inv_txfm_;
|
||||
};
|
||||
|
||||
TEST_P(Trans4x4DCT, AccuracyCheck) { RunAccuracyCheck(1); }
|
||||
|
||||
TEST_P(Trans4x4DCT, CoeffCheck) { RunCoeffCheck(); }
|
||||
|
||||
TEST_P(Trans4x4DCT, MemCheck) { RunMemCheck(); }
|
||||
|
||||
TEST_P(Trans4x4DCT, InvAccuracyCheck) { RunInvAccuracyCheck(1); }
|
||||
|
||||
class Trans4x4HT : public Trans4x4TestBase,
|
||||
public ::testing::TestWithParam<Ht4x4Param> {
|
||||
public:
|
||||
virtual ~Trans4x4HT() {}
|
||||
|
||||
virtual void SetUp() {
|
||||
fwd_txfm_ = GET_PARAM(0);
|
||||
inv_txfm_ = GET_PARAM(1);
|
||||
tx_type_ = GET_PARAM(2);
|
||||
pitch_ = 4;
|
||||
fwd_txfm_ref = fht4x4_ref;
|
||||
bit_depth_ = GET_PARAM(3);
|
||||
mask_ = (1 << bit_depth_) - 1;
|
||||
}
|
||||
virtual void TearDown() { libvpx_test::ClearSystemState(); }
|
||||
|
||||
protected:
|
||||
void RunFwdTxfm(const int16_t *in, tran_low_t *out, int stride) {
|
||||
fwd_txfm_(in, out, stride, tx_type_);
|
||||
}
|
||||
|
||||
void RunInvTxfm(const tran_low_t *out, uint8_t *dst, int stride) {
|
||||
inv_txfm_(out, dst, stride, tx_type_);
|
||||
}
|
||||
|
||||
FhtFunc fwd_txfm_;
|
||||
IhtFunc inv_txfm_;
|
||||
};
|
||||
|
||||
TEST_P(Trans4x4HT, AccuracyCheck) { RunAccuracyCheck(1); }
|
||||
|
||||
TEST_P(Trans4x4HT, CoeffCheck) { RunCoeffCheck(); }
|
||||
|
||||
TEST_P(Trans4x4HT, MemCheck) { RunMemCheck(); }
|
||||
|
||||
TEST_P(Trans4x4HT, InvAccuracyCheck) { RunInvAccuracyCheck(1); }
|
||||
|
||||
class Trans4x4WHT : public Trans4x4TestBase,
|
||||
public ::testing::TestWithParam<Dct4x4Param> {
|
||||
public:
|
||||
virtual ~Trans4x4WHT() {}
|
||||
|
||||
virtual void SetUp() {
|
||||
fwd_txfm_ = GET_PARAM(0);
|
||||
inv_txfm_ = GET_PARAM(1);
|
||||
tx_type_ = GET_PARAM(2);
|
||||
pitch_ = 4;
|
||||
fwd_txfm_ref = fwht4x4_ref;
|
||||
bit_depth_ = GET_PARAM(3);
|
||||
mask_ = (1 << bit_depth_) - 1;
|
||||
}
|
||||
virtual void TearDown() { libvpx_test::ClearSystemState(); }
|
||||
|
||||
protected:
|
||||
void RunFwdTxfm(const int16_t *in, tran_low_t *out, int stride) {
|
||||
fwd_txfm_(in, out, stride);
|
||||
}
|
||||
void RunInvTxfm(const tran_low_t *out, uint8_t *dst, int stride) {
|
||||
inv_txfm_(out, dst, stride);
|
||||
}
|
||||
|
||||
FdctFunc fwd_txfm_;
|
||||
IdctFunc inv_txfm_;
|
||||
};
|
||||
|
||||
TEST_P(Trans4x4WHT, AccuracyCheck) { RunAccuracyCheck(0); }
|
||||
|
||||
TEST_P(Trans4x4WHT, CoeffCheck) { RunCoeffCheck(); }
|
||||
|
||||
TEST_P(Trans4x4WHT, MemCheck) { RunMemCheck(); }
|
||||
|
||||
TEST_P(Trans4x4WHT, InvAccuracyCheck) { RunInvAccuracyCheck(0); }
|
||||
using std::tr1::make_tuple;
|
||||
|
||||
#if CONFIG_VP9_HIGHBITDEPTH
|
||||
INSTANTIATE_TEST_CASE_P(
|
||||
C, Trans4x4DCT,
|
||||
::testing::Values(
|
||||
make_tuple(&vpx_highbd_fdct4x4_c, &idct4x4_10, 0, VPX_BITS_10),
|
||||
make_tuple(&vpx_highbd_fdct4x4_c, &idct4x4_12, 0, VPX_BITS_12),
|
||||
make_tuple(&vpx_fdct4x4_c, &vpx_idct4x4_16_add_c, 0, VPX_BITS_8)));
|
||||
#else
|
||||
INSTANTIATE_TEST_CASE_P(C, Trans4x4DCT,
|
||||
::testing::Values(make_tuple(&vpx_fdct4x4_c,
|
||||
&vpx_idct4x4_16_add_c, 0,
|
||||
VPX_BITS_8)));
|
||||
#endif // CONFIG_VP9_HIGHBITDEPTH
|
||||
|
||||
#if CONFIG_VP9_HIGHBITDEPTH
|
||||
INSTANTIATE_TEST_CASE_P(
|
||||
C, Trans4x4HT,
|
||||
::testing::Values(
|
||||
make_tuple(&vp9_highbd_fht4x4_c, &iht4x4_10, 0, VPX_BITS_10),
|
||||
make_tuple(&vp9_highbd_fht4x4_c, &iht4x4_10, 1, VPX_BITS_10),
|
||||
make_tuple(&vp9_highbd_fht4x4_c, &iht4x4_10, 2, VPX_BITS_10),
|
||||
make_tuple(&vp9_highbd_fht4x4_c, &iht4x4_10, 3, VPX_BITS_10),
|
||||
make_tuple(&vp9_highbd_fht4x4_c, &iht4x4_12, 0, VPX_BITS_12),
|
||||
make_tuple(&vp9_highbd_fht4x4_c, &iht4x4_12, 1, VPX_BITS_12),
|
||||
make_tuple(&vp9_highbd_fht4x4_c, &iht4x4_12, 2, VPX_BITS_12),
|
||||
make_tuple(&vp9_highbd_fht4x4_c, &iht4x4_12, 3, VPX_BITS_12),
|
||||
make_tuple(&vp9_fht4x4_c, &vp9_iht4x4_16_add_c, 0, VPX_BITS_8),
|
||||
make_tuple(&vp9_fht4x4_c, &vp9_iht4x4_16_add_c, 1, VPX_BITS_8),
|
||||
make_tuple(&vp9_fht4x4_c, &vp9_iht4x4_16_add_c, 2, VPX_BITS_8),
|
||||
make_tuple(&vp9_fht4x4_c, &vp9_iht4x4_16_add_c, 3, VPX_BITS_8)));
|
||||
#else
|
||||
INSTANTIATE_TEST_CASE_P(
|
||||
C, Trans4x4HT,
|
||||
::testing::Values(
|
||||
make_tuple(&vp9_fht4x4_c, &vp9_iht4x4_16_add_c, 0, VPX_BITS_8),
|
||||
make_tuple(&vp9_fht4x4_c, &vp9_iht4x4_16_add_c, 1, VPX_BITS_8),
|
||||
make_tuple(&vp9_fht4x4_c, &vp9_iht4x4_16_add_c, 2, VPX_BITS_8),
|
||||
make_tuple(&vp9_fht4x4_c, &vp9_iht4x4_16_add_c, 3, VPX_BITS_8)));
|
||||
#endif // CONFIG_VP9_HIGHBITDEPTH
|
||||
|
||||
#if CONFIG_VP9_HIGHBITDEPTH
|
||||
INSTANTIATE_TEST_CASE_P(
|
||||
C, Trans4x4WHT,
|
||||
::testing::Values(
|
||||
make_tuple(&vp9_highbd_fwht4x4_c, &iwht4x4_10, 0, VPX_BITS_10),
|
||||
make_tuple(&vp9_highbd_fwht4x4_c, &iwht4x4_12, 0, VPX_BITS_12),
|
||||
make_tuple(&vp9_fwht4x4_c, &vpx_iwht4x4_16_add_c, 0, VPX_BITS_8)));
|
||||
#else
|
||||
INSTANTIATE_TEST_CASE_P(C, Trans4x4WHT,
|
||||
::testing::Values(make_tuple(&vp9_fwht4x4_c,
|
||||
&vpx_iwht4x4_16_add_c, 0,
|
||||
VPX_BITS_8)));
|
||||
#endif // CONFIG_VP9_HIGHBITDEPTH
|
||||
|
||||
#if HAVE_NEON_ASM && !CONFIG_VP9_HIGHBITDEPTH && !CONFIG_EMULATE_HARDWARE
|
||||
INSTANTIATE_TEST_CASE_P(NEON, Trans4x4DCT,
|
||||
::testing::Values(make_tuple(&vpx_fdct4x4_c,
|
||||
&vpx_idct4x4_16_add_neon,
|
||||
0, VPX_BITS_8)));
|
||||
#endif // HAVE_NEON_ASM && !CONFIG_VP9_HIGHBITDEPTH && !CONFIG_EMULATE_HARDWARE
|
||||
|
||||
#if HAVE_NEON && !CONFIG_VP9_HIGHBITDEPTH && !CONFIG_EMULATE_HARDWARE
|
||||
INSTANTIATE_TEST_CASE_P(
|
||||
NEON, Trans4x4HT,
|
||||
::testing::Values(
|
||||
make_tuple(&vp9_fht4x4_c, &vp9_iht4x4_16_add_neon, 0, VPX_BITS_8),
|
||||
make_tuple(&vp9_fht4x4_c, &vp9_iht4x4_16_add_neon, 1, VPX_BITS_8),
|
||||
make_tuple(&vp9_fht4x4_c, &vp9_iht4x4_16_add_neon, 2, VPX_BITS_8),
|
||||
make_tuple(&vp9_fht4x4_c, &vp9_iht4x4_16_add_neon, 3, VPX_BITS_8)));
|
||||
#endif // HAVE_NEON && !CONFIG_VP9_HIGHBITDEPTH && !CONFIG_EMULATE_HARDWARE
|
||||
|
||||
#if HAVE_SSE2 && !CONFIG_EMULATE_HARDWARE
|
||||
INSTANTIATE_TEST_CASE_P(
|
||||
SSE2, Trans4x4WHT,
|
||||
::testing::Values(
|
||||
make_tuple(&vp9_fwht4x4_sse2, &vpx_iwht4x4_16_add_c, 0, VPX_BITS_8),
|
||||
make_tuple(&vp9_fwht4x4_c, &vpx_iwht4x4_16_add_sse2, 0, VPX_BITS_8)));
|
||||
#endif
|
||||
|
||||
#if HAVE_SSE2 && !CONFIG_VP9_HIGHBITDEPTH && !CONFIG_EMULATE_HARDWARE
|
||||
INSTANTIATE_TEST_CASE_P(SSE2, Trans4x4DCT,
|
||||
::testing::Values(make_tuple(&vpx_fdct4x4_sse2,
|
||||
&vpx_idct4x4_16_add_sse2,
|
||||
0, VPX_BITS_8)));
|
||||
INSTANTIATE_TEST_CASE_P(
|
||||
SSE2, Trans4x4HT,
|
||||
::testing::Values(
|
||||
make_tuple(&vp9_fht4x4_sse2, &vp9_iht4x4_16_add_sse2, 0, VPX_BITS_8),
|
||||
make_tuple(&vp9_fht4x4_sse2, &vp9_iht4x4_16_add_sse2, 1, VPX_BITS_8),
|
||||
make_tuple(&vp9_fht4x4_sse2, &vp9_iht4x4_16_add_sse2, 2, VPX_BITS_8),
|
||||
make_tuple(&vp9_fht4x4_sse2, &vp9_iht4x4_16_add_sse2, 3, VPX_BITS_8)));
|
||||
#endif // HAVE_SSE2 && !CONFIG_VP9_HIGHBITDEPTH && !CONFIG_EMULATE_HARDWARE
|
||||
|
||||
#if HAVE_SSE2 && CONFIG_VP9_HIGHBITDEPTH && !CONFIG_EMULATE_HARDWARE
|
||||
INSTANTIATE_TEST_CASE_P(
|
||||
SSE2, Trans4x4DCT,
|
||||
::testing::Values(
|
||||
make_tuple(&vpx_highbd_fdct4x4_c, &idct4x4_10_sse2, 0, VPX_BITS_10),
|
||||
make_tuple(&vpx_highbd_fdct4x4_sse2, &idct4x4_10_sse2, 0, VPX_BITS_10),
|
||||
make_tuple(&vpx_highbd_fdct4x4_c, &idct4x4_12_sse2, 0, VPX_BITS_12),
|
||||
make_tuple(&vpx_highbd_fdct4x4_sse2, &idct4x4_12_sse2, 0, VPX_BITS_12),
|
||||
make_tuple(&vpx_fdct4x4_sse2, &vpx_idct4x4_16_add_c, 0, VPX_BITS_8)));
|
||||
|
||||
INSTANTIATE_TEST_CASE_P(
|
||||
SSE2, Trans4x4HT,
|
||||
::testing::Values(
|
||||
make_tuple(&vp9_fht4x4_sse2, &vp9_iht4x4_16_add_c, 0, VPX_BITS_8),
|
||||
make_tuple(&vp9_fht4x4_sse2, &vp9_iht4x4_16_add_c, 1, VPX_BITS_8),
|
||||
make_tuple(&vp9_fht4x4_sse2, &vp9_iht4x4_16_add_c, 2, VPX_BITS_8),
|
||||
make_tuple(&vp9_fht4x4_sse2, &vp9_iht4x4_16_add_c, 3, VPX_BITS_8)));
|
||||
#endif // HAVE_SSE2 && CONFIG_VP9_HIGHBITDEPTH && !CONFIG_EMULATE_HARDWARE
|
||||
|
||||
#if HAVE_MSA && !CONFIG_VP9_HIGHBITDEPTH && !CONFIG_EMULATE_HARDWARE
|
||||
INSTANTIATE_TEST_CASE_P(MSA, Trans4x4DCT,
|
||||
::testing::Values(make_tuple(&vpx_fdct4x4_msa,
|
||||
&vpx_idct4x4_16_add_msa, 0,
|
||||
VPX_BITS_8)));
|
||||
INSTANTIATE_TEST_CASE_P(
|
||||
MSA, Trans4x4HT,
|
||||
::testing::Values(
|
||||
make_tuple(&vp9_fht4x4_msa, &vp9_iht4x4_16_add_msa, 0, VPX_BITS_8),
|
||||
make_tuple(&vp9_fht4x4_msa, &vp9_iht4x4_16_add_msa, 1, VPX_BITS_8),
|
||||
make_tuple(&vp9_fht4x4_msa, &vp9_iht4x4_16_add_msa, 2, VPX_BITS_8),
|
||||
make_tuple(&vp9_fht4x4_msa, &vp9_iht4x4_16_add_msa, 3, VPX_BITS_8)));
|
||||
#endif // HAVE_MSA && !CONFIG_VP9_HIGHBITDEPTH && !CONFIG_EMULATE_HARDWARE
|
||||
} // namespace
|
@ -43,9 +43,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 ::testing::tuple<FdctFunc, IdctFunc, int, vpx_bit_depth_t> Dct8x8Param;
|
||||
typedef ::testing::tuple<FhtFunc, IhtFunc, int, vpx_bit_depth_t> Ht8x8Param;
|
||||
typedef ::testing::tuple<IdctFunc, IdctFunc, int, vpx_bit_depth_t> Idct8x8Param;
|
||||
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;
|
||||
|
||||
void reference_8x8_dct_1d(const double in[8], double out[8]) {
|
||||
const double kInvSqrt2 = 0.707106781186547524400844362104;
|
||||
@ -88,45 +88,45 @@ void fht8x8_ref(const int16_t *in, tran_low_t *out, int stride, int tx_type) {
|
||||
|
||||
#if CONFIG_VP9_HIGHBITDEPTH
|
||||
void idct8x8_10(const tran_low_t *in, uint8_t *out, int stride) {
|
||||
vpx_highbd_idct8x8_64_add_c(in, CAST_TO_SHORTPTR(out), stride, 10);
|
||||
vpx_highbd_idct8x8_64_add_c(in, out, stride, 10);
|
||||
}
|
||||
|
||||
void idct8x8_12(const tran_low_t *in, uint8_t *out, int stride) {
|
||||
vpx_highbd_idct8x8_64_add_c(in, CAST_TO_SHORTPTR(out), stride, 12);
|
||||
vpx_highbd_idct8x8_64_add_c(in, out, stride, 12);
|
||||
}
|
||||
|
||||
void iht8x8_10(const tran_low_t *in, uint8_t *out, int stride, int tx_type) {
|
||||
vp9_highbd_iht8x8_64_add_c(in, CAST_TO_SHORTPTR(out), stride, tx_type, 10);
|
||||
vp9_highbd_iht8x8_64_add_c(in, out, stride, tx_type, 10);
|
||||
}
|
||||
|
||||
void iht8x8_12(const tran_low_t *in, uint8_t *out, int stride, int tx_type) {
|
||||
vp9_highbd_iht8x8_64_add_c(in, CAST_TO_SHORTPTR(out), stride, tx_type, 12);
|
||||
vp9_highbd_iht8x8_64_add_c(in, out, stride, tx_type, 12);
|
||||
}
|
||||
|
||||
#if HAVE_SSE2
|
||||
|
||||
void idct8x8_12_add_10_c(const tran_low_t *in, uint8_t *out, int stride) {
|
||||
vpx_highbd_idct8x8_12_add_c(in, CAST_TO_SHORTPTR(out), stride, 10);
|
||||
vpx_highbd_idct8x8_12_add_c(in, out, stride, 10);
|
||||
}
|
||||
|
||||
void idct8x8_12_add_12_c(const tran_low_t *in, uint8_t *out, int stride) {
|
||||
vpx_highbd_idct8x8_12_add_c(in, CAST_TO_SHORTPTR(out), stride, 12);
|
||||
vpx_highbd_idct8x8_12_add_c(in, out, stride, 12);
|
||||
}
|
||||
|
||||
void idct8x8_12_add_10_sse2(const tran_low_t *in, uint8_t *out, int stride) {
|
||||
vpx_highbd_idct8x8_12_add_sse2(in, CAST_TO_SHORTPTR(out), stride, 10);
|
||||
vpx_highbd_idct8x8_12_add_sse2(in, out, stride, 10);
|
||||
}
|
||||
|
||||
void idct8x8_12_add_12_sse2(const tran_low_t *in, uint8_t *out, int stride) {
|
||||
vpx_highbd_idct8x8_12_add_sse2(in, CAST_TO_SHORTPTR(out), stride, 12);
|
||||
vpx_highbd_idct8x8_12_add_sse2(in, out, stride, 12);
|
||||
}
|
||||
|
||||
void idct8x8_64_add_10_sse2(const tran_low_t *in, uint8_t *out, int stride) {
|
||||
vpx_highbd_idct8x8_64_add_sse2(in, CAST_TO_SHORTPTR(out), stride, 10);
|
||||
vpx_highbd_idct8x8_64_add_sse2(in, out, stride, 10);
|
||||
}
|
||||
|
||||
void idct8x8_64_add_12_sse2(const tran_low_t *in, uint8_t *out, int stride) {
|
||||
vpx_highbd_idct8x8_64_add_sse2(in, CAST_TO_SHORTPTR(out), stride, 12);
|
||||
vpx_highbd_idct8x8_64_add_sse2(in, out, stride, 12);
|
||||
}
|
||||
#endif // HAVE_SSE2
|
||||
#endif // CONFIG_VP9_HIGHBITDEPTH
|
||||
@ -257,7 +257,7 @@ class FwdTrans8x8TestBase {
|
||||
#if CONFIG_VP9_HIGHBITDEPTH
|
||||
} else {
|
||||
ASM_REGISTER_STATE_CHECK(
|
||||
RunInvTxfm(test_temp_block, CAST_TO_BYTEPTR(dst16), pitch_));
|
||||
RunInvTxfm(test_temp_block, CONVERT_TO_BYTEPTR(dst16), pitch_));
|
||||
#endif
|
||||
}
|
||||
|
||||
@ -340,7 +340,7 @@ class FwdTrans8x8TestBase {
|
||||
#if CONFIG_VP9_HIGHBITDEPTH
|
||||
} else {
|
||||
ASM_REGISTER_STATE_CHECK(
|
||||
RunInvTxfm(test_temp_block, CAST_TO_BYTEPTR(dst16), pitch_));
|
||||
RunInvTxfm(test_temp_block, CONVERT_TO_BYTEPTR(dst16), pitch_));
|
||||
#endif
|
||||
}
|
||||
|
||||
@ -413,7 +413,7 @@ class FwdTrans8x8TestBase {
|
||||
#if CONFIG_VP9_HIGHBITDEPTH
|
||||
} else {
|
||||
ASM_REGISTER_STATE_CHECK(
|
||||
RunInvTxfm(coeff, CAST_TO_BYTEPTR(dst16), pitch_));
|
||||
RunInvTxfm(coeff, CONVERT_TO_BYTEPTR(dst16), pitch_));
|
||||
#endif
|
||||
}
|
||||
|
||||
@ -497,9 +497,9 @@ class FwdTrans8x8TestBase {
|
||||
ASM_REGISTER_STATE_CHECK(RunInvTxfm(coeff, dst, pitch_));
|
||||
#if CONFIG_VP9_HIGHBITDEPTH
|
||||
} else {
|
||||
ref_txfm(coeff, CAST_TO_BYTEPTR(ref16), pitch_);
|
||||
ref_txfm(coeff, CONVERT_TO_BYTEPTR(ref16), pitch_);
|
||||
ASM_REGISTER_STATE_CHECK(
|
||||
RunInvTxfm(coeff, CAST_TO_BYTEPTR(dst16), pitch_));
|
||||
RunInvTxfm(coeff, CONVERT_TO_BYTEPTR(dst16), pitch_));
|
||||
#endif
|
||||
}
|
||||
|
||||
@ -511,8 +511,8 @@ class FwdTrans8x8TestBase {
|
||||
const int diff = dst[j] - ref[j];
|
||||
#endif
|
||||
const uint32_t error = diff * diff;
|
||||
EXPECT_EQ(0u, error)
|
||||
<< "Error: 8x8 IDCT has error " << error << " at index " << j;
|
||||
EXPECT_EQ(0u, error) << "Error: 8x8 IDCT has error " << error
|
||||
<< " at index " << j;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -628,7 +628,7 @@ TEST_P(InvTrans8x8DCT, CompareReference) {
|
||||
CompareInvReference(ref_txfm_, thresh_);
|
||||
}
|
||||
|
||||
using ::testing::make_tuple;
|
||||
using std::tr1::make_tuple;
|
||||
|
||||
#if CONFIG_VP9_HIGHBITDEPTH
|
||||
INSTANTIATE_TEST_CASE_P(
|
||||
@ -670,13 +670,14 @@ INSTANTIATE_TEST_CASE_P(
|
||||
make_tuple(&vp9_fht8x8_c, &vp9_iht8x8_64_add_c, 3, VPX_BITS_8)));
|
||||
#endif // CONFIG_VP9_HIGHBITDEPTH
|
||||
|
||||
#if HAVE_NEON && !CONFIG_EMULATE_HARDWARE
|
||||
#if HAVE_NEON_ASM && !CONFIG_VP9_HIGHBITDEPTH && !CONFIG_EMULATE_HARDWARE
|
||||
INSTANTIATE_TEST_CASE_P(NEON, FwdTrans8x8DCT,
|
||||
::testing::Values(make_tuple(&vpx_fdct8x8_neon,
|
||||
&vpx_idct8x8_64_add_neon,
|
||||
0, VPX_BITS_8)));
|
||||
#endif // HAVE_NEON_ASM && !CONFIG_VP9_HIGHBITDEPTH && !CONFIG_EMULATE_HARDWARE
|
||||
|
||||
#if !CONFIG_VP9_HIGHBITDEPTH
|
||||
#if HAVE_NEON && !CONFIG_VP9_HIGHBITDEPTH && !CONFIG_EMULATE_HARDWARE
|
||||
INSTANTIATE_TEST_CASE_P(
|
||||
NEON, FwdTrans8x8HT,
|
||||
::testing::Values(
|
||||
@ -684,8 +685,7 @@ INSTANTIATE_TEST_CASE_P(
|
||||
make_tuple(&vp9_fht8x8_c, &vp9_iht8x8_64_add_neon, 1, VPX_BITS_8),
|
||||
make_tuple(&vp9_fht8x8_c, &vp9_iht8x8_64_add_neon, 2, VPX_BITS_8),
|
||||
make_tuple(&vp9_fht8x8_c, &vp9_iht8x8_64_add_neon, 3, VPX_BITS_8)));
|
||||
#endif // !CONFIG_VP9_HIGHBITDEPTH
|
||||
#endif // HAVE_NEON && !CONFIG_EMULATE_HARDWARE
|
||||
#endif // HAVE_NEON && !CONFIG_VP9_HIGHBITDEPTH && !CONFIG_EMULATE_HARDWARE
|
||||
|
||||
#if HAVE_SSE2 && !CONFIG_VP9_HIGHBITDEPTH && !CONFIG_EMULATE_HARDWARE
|
||||
INSTANTIATE_TEST_CASE_P(SSE2, FwdTrans8x8DCT,
|
||||
@ -740,7 +740,7 @@ INSTANTIATE_TEST_CASE_P(
|
||||
!CONFIG_EMULATE_HARDWARE
|
||||
INSTANTIATE_TEST_CASE_P(SSSE3, FwdTrans8x8DCT,
|
||||
::testing::Values(make_tuple(&vpx_fdct8x8_ssse3,
|
||||
&vpx_idct8x8_64_add_sse2,
|
||||
&vpx_idct8x8_64_add_ssse3,
|
||||
0, VPX_BITS_8)));
|
||||
#endif
|
||||
|
||||
@ -757,11 +757,4 @@ INSTANTIATE_TEST_CASE_P(
|
||||
make_tuple(&vp9_fht8x8_msa, &vp9_iht8x8_64_add_msa, 2, VPX_BITS_8),
|
||||
make_tuple(&vp9_fht8x8_msa, &vp9_iht8x8_64_add_msa, 3, VPX_BITS_8)));
|
||||
#endif // HAVE_MSA && !CONFIG_VP9_HIGHBITDEPTH && !CONFIG_EMULATE_HARDWARE
|
||||
|
||||
#if HAVE_VSX && !CONFIG_VP9_HIGHBITDEPTH && !CONFIG_EMULATE_HARDWARE
|
||||
INSTANTIATE_TEST_CASE_P(VSX, FwdTrans8x8DCT,
|
||||
::testing::Values(make_tuple(&vpx_fdct8x8_c,
|
||||
&vpx_idct8x8_64_add_vsx, 0,
|
||||
VPX_BITS_8)));
|
||||
#endif // HAVE_VSX && !CONFIG_VP9_HIGHBITDEPTH && !CONFIG_EMULATE_HARDWARE
|
||||
} // namespace
|
||||
|
@ -13,7 +13,6 @@
|
||||
#include "third_party/googletest/src/include/gtest/gtest.h"
|
||||
|
||||
#include "./vpx_dsp_rtcd.h"
|
||||
#include "vpx_ports/vpx_timer.h"
|
||||
|
||||
#include "test/acm_random.h"
|
||||
#include "test/register_state_check.h"
|
||||
@ -22,8 +21,7 @@ namespace {
|
||||
|
||||
using ::libvpx_test::ACMRandom;
|
||||
|
||||
typedef void (*HadamardFunc)(const int16_t *a, ptrdiff_t a_stride,
|
||||
tran_low_t *b);
|
||||
typedef void (*HadamardFunc)(const int16_t *a, int a_stride, int16_t *b);
|
||||
|
||||
void hadamard_loop(const int16_t *a, int a_stride, int16_t *out) {
|
||||
int16_t b[8];
|
||||
@ -48,16 +46,18 @@ void hadamard_loop(const int16_t *a, int a_stride, int16_t *out) {
|
||||
out[5] = c[3] - c[7];
|
||||
}
|
||||
|
||||
void reference_hadamard8x8(const int16_t *a, int a_stride, tran_low_t *b) {
|
||||
void reference_hadamard8x8(const int16_t *a, int a_stride, int16_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 < 8; ++i) {
|
||||
hadamard_loop(a + i, a_stride, buf + i * 8);
|
||||
}
|
||||
|
||||
for (int i = 0; i < 64; ++i) b[i] = (tran_low_t)buf2[i];
|
||||
for (int i = 0; i < 8; ++i) {
|
||||
hadamard_loop(buf + i, 8, b + i * 8);
|
||||
}
|
||||
}
|
||||
|
||||
void reference_hadamard16x16(const int16_t *a, int a_stride, tran_low_t *b) {
|
||||
void reference_hadamard16x16(const int16_t *a, int a_stride, int16_t *b) {
|
||||
/* The source is a 16x16 block. The destination is rearranged to 8x32.
|
||||
* Input is 9 bit. */
|
||||
reference_hadamard8x8(a + 0 + 0 * a_stride, a_stride, b + 0);
|
||||
@ -68,16 +68,16 @@ void reference_hadamard16x16(const int16_t *a, int a_stride, tran_low_t *b) {
|
||||
/* Overlay the 8x8 blocks and combine. */
|
||||
for (int i = 0; i < 64; ++i) {
|
||||
/* 8x8 steps the range up to 15 bits. */
|
||||
const tran_low_t a0 = b[0];
|
||||
const tran_low_t a1 = b[64];
|
||||
const tran_low_t a2 = b[128];
|
||||
const tran_low_t a3 = b[192];
|
||||
const int16_t a0 = b[0];
|
||||
const int16_t a1 = b[64];
|
||||
const int16_t a2 = b[128];
|
||||
const int16_t a3 = b[192];
|
||||
|
||||
/* Prevent the result from escaping int16_t. */
|
||||
const tran_low_t b0 = (a0 + a1) >> 1;
|
||||
const tran_low_t b1 = (a0 - a1) >> 1;
|
||||
const tran_low_t b2 = (a2 + a3) >> 1;
|
||||
const tran_low_t b3 = (a2 - a3) >> 1;
|
||||
const int16_t b0 = (a0 + a1) >> 1;
|
||||
const int16_t b1 = (a0 - a1) >> 1;
|
||||
const int16_t b2 = (a2 + a3) >> 1;
|
||||
const int16_t b3 = (a2 - a3) >> 1;
|
||||
|
||||
/* Store a 16 bit value. */
|
||||
b[0] = b0 + b2;
|
||||
@ -101,35 +101,12 @@ class HadamardTestBase : public ::testing::TestWithParam<HadamardFunc> {
|
||||
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;
|
||||
|
||||
vpx_usec_timer_start(&timer);
|
||||
for (i = 0; i < times; ++i) {
|
||||
func(input, stride, output);
|
||||
}
|
||||
vpx_usec_timer_mark(&timer);
|
||||
|
||||
const int elapsed_time = static_cast<int>(vpx_usec_timer_elapsed(&timer));
|
||||
printf("%s[%12d runs]: %d us\n", name, times, elapsed_time);
|
||||
}
|
||||
|
||||
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];
|
||||
DECLARE_ALIGNED(16, int16_t, b[64]);
|
||||
int16_t b_ref[64];
|
||||
for (int i = 0; i < 64; ++i) {
|
||||
a[i] = rnd_.Rand9Signed();
|
||||
}
|
||||
@ -147,8 +124,8 @@ TEST_P(Hadamard8x8Test, CompareReferenceRandom) {
|
||||
|
||||
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];
|
||||
DECLARE_ALIGNED(16, int16_t, b[64]);
|
||||
int16_t b_ref[64];
|
||||
for (int i = 0; i < 64 * 8; ++i) {
|
||||
a[i] = rnd_.Rand9Signed();
|
||||
}
|
||||
@ -167,12 +144,6 @@ TEST_P(Hadamard8x8Test, VaryStride) {
|
||||
}
|
||||
}
|
||||
|
||||
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));
|
||||
|
||||
@ -191,33 +162,12 @@ INSTANTIATE_TEST_CASE_P(NEON, Hadamard8x8Test,
|
||||
::testing::Values(&vpx_hadamard_8x8_neon));
|
||||
#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));
|
||||
#endif // HAVE_MSA
|
||||
#endif // !CONFIG_VP9_HIGHBITDEPTH
|
||||
|
||||
#if HAVE_VSX
|
||||
INSTANTIATE_TEST_CASE_P(VSX, Hadamard8x8Test,
|
||||
::testing::Values(&vpx_hadamard_8x8_vsx));
|
||||
#endif // HAVE_VSX
|
||||
|
||||
class Hadamard16x16Test : public HadamardTestBase {};
|
||||
|
||||
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(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];
|
||||
DECLARE_ALIGNED(16, int16_t, b[16 * 16]);
|
||||
int16_t b_ref[16 * 16];
|
||||
for (int i = 0; i < 16 * 16; ++i) {
|
||||
a[i] = rnd_.Rand9Signed();
|
||||
}
|
||||
@ -235,8 +185,8 @@ TEST_P(Hadamard16x16Test, CompareReferenceRandom) {
|
||||
|
||||
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];
|
||||
DECLARE_ALIGNED(16, int16_t, b[16 * 16]);
|
||||
int16_t b_ref[16 * 16];
|
||||
for (int i = 0; i < 16 * 16 * 8; ++i) {
|
||||
a[i] = rnd_.Rand9Signed();
|
||||
}
|
||||
@ -255,12 +205,6 @@ TEST_P(Hadamard16x16Test, VaryStride) {
|
||||
}
|
||||
}
|
||||
|
||||
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));
|
||||
|
||||
@ -269,25 +213,8 @@ INSTANTIATE_TEST_CASE_P(SSE2, Hadamard16x16Test,
|
||||
::testing::Values(&vpx_hadamard_16x16_sse2));
|
||||
#endif // HAVE_SSE2
|
||||
|
||||
#if HAVE_AVX2
|
||||
INSTANTIATE_TEST_CASE_P(AVX2, Hadamard16x16Test,
|
||||
::testing::Values(&vpx_hadamard_16x16_avx2));
|
||||
#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
|
||||
} // namespace
|
||||
|
@ -13,7 +13,6 @@
|
||||
|
||||
#include "third_party/googletest/src/include/gtest/gtest.h"
|
||||
|
||||
#include "test/buffer.h"
|
||||
#include "test/clear_system_state.h"
|
||||
#include "test/register_state_check.h"
|
||||
#include "vpx/vpx_integer.h"
|
||||
@ -22,156 +21,110 @@ typedef void (*IdctFunc)(int16_t *input, unsigned char *pred_ptr,
|
||||
int pred_stride, unsigned char *dst_ptr,
|
||||
int dst_stride);
|
||||
namespace {
|
||||
|
||||
using libvpx_test::Buffer;
|
||||
|
||||
class IDCTTest : public ::testing::TestWithParam<IdctFunc> {
|
||||
protected:
|
||||
virtual void SetUp() {
|
||||
int i;
|
||||
|
||||
UUT = GetParam();
|
||||
|
||||
input = new Buffer<int16_t>(4, 4, 0);
|
||||
ASSERT_TRUE(input != NULL);
|
||||
ASSERT_TRUE(input->Init());
|
||||
predict = new Buffer<uint8_t>(4, 4, 3);
|
||||
ASSERT_TRUE(predict != NULL);
|
||||
ASSERT_TRUE(predict->Init());
|
||||
output = new Buffer<uint8_t>(4, 4, 3);
|
||||
ASSERT_TRUE(output != NULL);
|
||||
ASSERT_TRUE(output->Init());
|
||||
memset(input, 0, sizeof(input));
|
||||
/* Set up guard blocks */
|
||||
for (i = 0; i < 256; i++) output[i] = ((i & 0xF) < 4 && (i < 64)) ? 0 : -1;
|
||||
}
|
||||
|
||||
virtual void TearDown() {
|
||||
delete input;
|
||||
delete predict;
|
||||
delete output;
|
||||
libvpx_test::ClearSystemState();
|
||||
}
|
||||
virtual void TearDown() { libvpx_test::ClearSystemState(); }
|
||||
|
||||
IdctFunc UUT;
|
||||
Buffer<int16_t> *input;
|
||||
Buffer<uint8_t> *predict;
|
||||
Buffer<uint8_t> *output;
|
||||
int16_t input[16];
|
||||
unsigned char output[256];
|
||||
unsigned char predict[256];
|
||||
};
|
||||
|
||||
TEST_P(IDCTTest, TestGuardBlocks) {
|
||||
int i;
|
||||
|
||||
for (i = 0; i < 256; i++) {
|
||||
if ((i & 0xF) < 4 && i < 64)
|
||||
EXPECT_EQ(0, output[i]) << i;
|
||||
else
|
||||
EXPECT_EQ(255, output[i]);
|
||||
}
|
||||
}
|
||||
|
||||
TEST_P(IDCTTest, TestAllZeros) {
|
||||
// When the input is '0' the output will be '0'.
|
||||
input->Set(0);
|
||||
predict->Set(0);
|
||||
output->Set(0);
|
||||
int i;
|
||||
|
||||
ASM_REGISTER_STATE_CHECK(UUT(input->TopLeftPixel(), predict->TopLeftPixel(),
|
||||
predict->stride(), output->TopLeftPixel(),
|
||||
output->stride()));
|
||||
ASM_REGISTER_STATE_CHECK(UUT(input, output, 16, output, 16));
|
||||
|
||||
ASSERT_TRUE(input->CheckValues(0));
|
||||
ASSERT_TRUE(input->CheckPadding());
|
||||
ASSERT_TRUE(output->CheckValues(0));
|
||||
ASSERT_TRUE(output->CheckPadding());
|
||||
for (i = 0; i < 256; i++) {
|
||||
if ((i & 0xF) < 4 && i < 64)
|
||||
EXPECT_EQ(0, output[i]) << "i==" << i;
|
||||
else
|
||||
EXPECT_EQ(255, output[i]) << "i==" << i;
|
||||
}
|
||||
}
|
||||
|
||||
TEST_P(IDCTTest, TestAllOnes) {
|
||||
input->Set(0);
|
||||
// When the first element is '4' it will fill the output buffer with '1'.
|
||||
input->TopLeftPixel()[0] = 4;
|
||||
predict->Set(0);
|
||||
output->Set(0);
|
||||
int i;
|
||||
|
||||
ASM_REGISTER_STATE_CHECK(UUT(input->TopLeftPixel(), predict->TopLeftPixel(),
|
||||
predict->stride(), output->TopLeftPixel(),
|
||||
output->stride()));
|
||||
input[0] = 4;
|
||||
ASM_REGISTER_STATE_CHECK(UUT(input, output, 16, output, 16));
|
||||
|
||||
ASSERT_TRUE(output->CheckValues(1));
|
||||
ASSERT_TRUE(output->CheckPadding());
|
||||
for (i = 0; i < 256; i++) {
|
||||
if ((i & 0xF) < 4 && i < 64)
|
||||
EXPECT_EQ(1, output[i]) << "i==" << i;
|
||||
else
|
||||
EXPECT_EQ(255, output[i]) << "i==" << i;
|
||||
}
|
||||
}
|
||||
|
||||
TEST_P(IDCTTest, TestAddOne) {
|
||||
// Set the transform output to '1' and make sure it gets added to the
|
||||
// prediction buffer.
|
||||
input->Set(0);
|
||||
input->TopLeftPixel()[0] = 4;
|
||||
output->Set(0);
|
||||
int i;
|
||||
|
||||
uint8_t *pred = predict->TopLeftPixel();
|
||||
for (int y = 0; y < 4; ++y) {
|
||||
for (int x = 0; x < 4; ++x) {
|
||||
pred[y * predict->stride() + x] = y * 4 + x;
|
||||
}
|
||||
for (i = 0; i < 256; i++) predict[i] = i;
|
||||
input[0] = 4;
|
||||
ASM_REGISTER_STATE_CHECK(UUT(input, predict, 16, output, 16));
|
||||
|
||||
for (i = 0; i < 256; i++) {
|
||||
if ((i & 0xF) < 4 && i < 64)
|
||||
EXPECT_EQ(i + 1, output[i]) << "i==" << i;
|
||||
else
|
||||
EXPECT_EQ(255, output[i]) << "i==" << i;
|
||||
}
|
||||
|
||||
ASM_REGISTER_STATE_CHECK(UUT(input->TopLeftPixel(), predict->TopLeftPixel(),
|
||||
predict->stride(), output->TopLeftPixel(),
|
||||
output->stride()));
|
||||
|
||||
uint8_t const *out = output->TopLeftPixel();
|
||||
for (int y = 0; y < 4; ++y) {
|
||||
for (int x = 0; x < 4; ++x) {
|
||||
EXPECT_EQ(1 + y * 4 + x, out[y * output->stride() + x]);
|
||||
}
|
||||
}
|
||||
|
||||
if (HasFailure()) {
|
||||
output->DumpBuffer();
|
||||
}
|
||||
|
||||
ASSERT_TRUE(output->CheckPadding());
|
||||
}
|
||||
|
||||
TEST_P(IDCTTest, TestWithData) {
|
||||
// Test a single known input.
|
||||
predict->Set(0);
|
||||
int i;
|
||||
|
||||
int16_t *in = input->TopLeftPixel();
|
||||
for (int y = 0; y < 4; ++y) {
|
||||
for (int x = 0; x < 4; ++x) {
|
||||
in[y * input->stride() + x] = y * 4 + x;
|
||||
}
|
||||
for (i = 0; i < 16; i++) input[i] = i;
|
||||
|
||||
ASM_REGISTER_STATE_CHECK(UUT(input, output, 16, output, 16));
|
||||
|
||||
for (i = 0; i < 256; i++) {
|
||||
if ((i & 0xF) > 3 || i > 63)
|
||||
EXPECT_EQ(255, output[i]) << "i==" << i;
|
||||
else if (i == 0)
|
||||
EXPECT_EQ(11, output[i]) << "i==" << i;
|
||||
else if (i == 34)
|
||||
EXPECT_EQ(1, output[i]) << "i==" << i;
|
||||
else if (i == 2 || i == 17 || i == 32)
|
||||
EXPECT_EQ(3, output[i]) << "i==" << i;
|
||||
else
|
||||
EXPECT_EQ(0, output[i]) << "i==" << i;
|
||||
}
|
||||
|
||||
ASM_REGISTER_STATE_CHECK(UUT(input->TopLeftPixel(), predict->TopLeftPixel(),
|
||||
predict->stride(), output->TopLeftPixel(),
|
||||
output->stride()));
|
||||
|
||||
uint8_t *out = output->TopLeftPixel();
|
||||
for (int y = 0; y < 4; ++y) {
|
||||
for (int x = 0; x < 4; ++x) {
|
||||
switch (y * 4 + x) {
|
||||
case 0: EXPECT_EQ(11, out[y * output->stride() + x]); break;
|
||||
case 2:
|
||||
case 5:
|
||||
case 8: EXPECT_EQ(3, out[y * output->stride() + x]); break;
|
||||
case 10: EXPECT_EQ(1, out[y * output->stride() + x]); break;
|
||||
default: EXPECT_EQ(0, out[y * output->stride() + x]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (HasFailure()) {
|
||||
output->DumpBuffer();
|
||||
}
|
||||
|
||||
ASSERT_TRUE(output->CheckPadding());
|
||||
}
|
||||
|
||||
INSTANTIATE_TEST_CASE_P(C, IDCTTest, ::testing::Values(vp8_short_idct4x4llm_c));
|
||||
|
||||
#if HAVE_NEON
|
||||
INSTANTIATE_TEST_CASE_P(NEON, IDCTTest,
|
||||
::testing::Values(vp8_short_idct4x4llm_neon));
|
||||
#endif // HAVE_NEON
|
||||
|
||||
#endif
|
||||
#if HAVE_MMX
|
||||
INSTANTIATE_TEST_CASE_P(MMX, IDCTTest,
|
||||
::testing::Values(vp8_short_idct4x4llm_mmx));
|
||||
#endif // HAVE_MMX
|
||||
|
||||
#endif
|
||||
#if HAVE_MSA
|
||||
INSTANTIATE_TEST_CASE_P(MSA, IDCTTest,
|
||||
::testing::Values(vp8_short_idct4x4llm_msa));
|
||||
#endif // HAVE_MSA
|
||||
|
||||
#if HAVE_MMI
|
||||
INSTANTIATE_TEST_CASE_P(MMI, IDCTTest,
|
||||
::testing::Values(vp8_short_idct4x4llm_mmi));
|
||||
#endif // HAVE_MMI
|
||||
} // namespace
|
||||
#endif
|
||||
}
|
||||
|
@ -45,8 +45,8 @@ class InvalidFileTest : public ::libvpx_test::DecoderTest,
|
||||
|
||||
void OpenResFile(const std::string &res_file_name_) {
|
||||
res_file_ = libvpx_test::OpenTestDataFile(res_file_name_);
|
||||
ASSERT_TRUE(res_file_ != NULL)
|
||||
<< "Result file open failed. Filename: " << res_file_name_;
|
||||
ASSERT_TRUE(res_file_ != NULL) << "Result file open failed. Filename: "
|
||||
<< res_file_name_;
|
||||
}
|
||||
|
||||
virtual bool HandleDecodeResult(
|
||||
@ -120,24 +120,11 @@ class InvalidFileTest : public ::libvpx_test::DecoderTest,
|
||||
|
||||
TEST_P(InvalidFileTest, ReturnCode) { RunTest(); }
|
||||
|
||||
#if CONFIG_VP8_DECODER
|
||||
const DecodeParam kVP8InvalidFileTests[] = {
|
||||
{ 1, "invalid-bug-1443.ivf" },
|
||||
{ 1, "invalid-token-partition.ivf" },
|
||||
};
|
||||
|
||||
VP8_INSTANTIATE_TEST_CASE(InvalidFileTest,
|
||||
::testing::ValuesIn(kVP8InvalidFileTests));
|
||||
#endif // CONFIG_VP8_DECODER
|
||||
|
||||
#if CONFIG_VP9_DECODER
|
||||
const DecodeParam kVP9InvalidFileTests[] = {
|
||||
{ 1, "invalid-vp90-02-v2.webm" },
|
||||
#if CONFIG_VP9_HIGHBITDEPTH
|
||||
{ 1, "invalid-vp90-2-00-quantizer-00.webm.ivf.s5861_r01-05_b6-.v2.ivf" },
|
||||
{ 1,
|
||||
"invalid-vp90-2-21-resize_inter_320x180_5_3-4.webm.ivf.s45551_r01-05_b6-."
|
||||
"ivf" },
|
||||
#endif
|
||||
{ 1, "invalid-vp90-03-v3.webm" },
|
||||
{ 1, "invalid-vp90-2-00-quantizer-11.webm.ivf.s52984_r01-05_b6-.ivf" },
|
||||
@ -177,12 +164,12 @@ class InvalidFileInvalidPeekTest : public InvalidFileTest {
|
||||
TEST_P(InvalidFileInvalidPeekTest, ReturnCode) { RunTest(); }
|
||||
|
||||
#if CONFIG_VP8_DECODER
|
||||
const DecodeParam kVP8InvalidPeekTests[] = {
|
||||
const DecodeParam kVP8InvalidFileTests[] = {
|
||||
{ 1, "invalid-vp80-00-comprehensive-018.ivf.2kf_0x6.ivf" },
|
||||
};
|
||||
|
||||
VP8_INSTANTIATE_TEST_CASE(InvalidFileInvalidPeekTest,
|
||||
::testing::ValuesIn(kVP8InvalidPeekTests));
|
||||
::testing::ValuesIn(kVP8InvalidFileTests));
|
||||
#endif // CONFIG_VP8_DECODER
|
||||
|
||||
#if CONFIG_VP9_DECODER
|
||||
|
@ -47,8 +47,8 @@ class IVFVideoSource : public CompressedVideoSource {
|
||||
|
||||
virtual void Begin() {
|
||||
input_file_ = OpenTestDataFile(file_name_);
|
||||
ASSERT_TRUE(input_file_ != NULL)
|
||||
<< "Input file open failed. Filename: " << file_name_;
|
||||
ASSERT_TRUE(input_file_ != NULL) << "Input file open failed. Filename: "
|
||||
<< file_name_;
|
||||
|
||||
// Read file header
|
||||
uint8_t file_hdr[kIvfFileHdrSize];
|
||||
|
@ -68,9 +68,7 @@ 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) {
|
||||
@ -130,16 +128,15 @@ 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();
|
||||
iter != kf_pts_list_.end(); ++iter) {
|
||||
if (deadline_ == VPX_DL_REALTIME && *iter > 0)
|
||||
EXPECT_EQ(0, (*iter - 1) % 30)
|
||||
<< "Unexpected keyframe at frame " << *iter;
|
||||
EXPECT_EQ(0, (*iter - 1) % 30) << "Unexpected keyframe at frame "
|
||||
<< *iter;
|
||||
else
|
||||
EXPECT_EQ(0, *iter % 30) << "Unexpected keyframe at frame " << *iter;
|
||||
}
|
||||
|
@ -66,36 +66,6 @@ class LevelTest
|
||||
int level_;
|
||||
};
|
||||
|
||||
TEST_P(LevelTest, TestTargetLevel11Large) {
|
||||
ASSERT_NE(encoding_mode_, ::libvpx_test::kRealTime);
|
||||
::libvpx_test::I420VideoSource video("hantro_odd.yuv", 208, 144, 30, 1, 0,
|
||||
60);
|
||||
target_level_ = 11;
|
||||
cfg_.rc_target_bitrate = 150;
|
||||
ASSERT_NO_FATAL_FAILURE(RunLoop(&video));
|
||||
ASSERT_GE(target_level_, level_);
|
||||
}
|
||||
|
||||
TEST_P(LevelTest, TestTargetLevel20Large) {
|
||||
ASSERT_NE(encoding_mode_, ::libvpx_test::kRealTime);
|
||||
::libvpx_test::I420VideoSource video("hantro_collage_w352h288.yuv", 352, 288,
|
||||
30, 1, 0, 60);
|
||||
target_level_ = 20;
|
||||
cfg_.rc_target_bitrate = 1200;
|
||||
ASSERT_NO_FATAL_FAILURE(RunLoop(&video));
|
||||
ASSERT_GE(target_level_, level_);
|
||||
}
|
||||
|
||||
TEST_P(LevelTest, TestTargetLevel31Large) {
|
||||
ASSERT_NE(encoding_mode_, ::libvpx_test::kRealTime);
|
||||
::libvpx_test::I420VideoSource video("niklas_1280_720_30.y4m", 1280, 720, 30,
|
||||
1, 0, 60);
|
||||
target_level_ = 31;
|
||||
cfg_.rc_target_bitrate = 8000;
|
||||
ASSERT_NO_FATAL_FAILURE(RunLoop(&video));
|
||||
ASSERT_GE(target_level_, level_);
|
||||
}
|
||||
|
||||
// Test for keeping level stats only
|
||||
TEST_P(LevelTest, TestTargetLevel0) {
|
||||
::libvpx_test::I420VideoSource video("hantro_odd.yuv", 208, 144, 30, 1, 0,
|
||||
@ -103,11 +73,11 @@ TEST_P(LevelTest, TestTargetLevel0) {
|
||||
target_level_ = 0;
|
||||
min_gf_internal_ = 4;
|
||||
ASSERT_NO_FATAL_FAILURE(RunLoop(&video));
|
||||
ASSERT_GE(11, level_);
|
||||
ASSERT_EQ(11, level_);
|
||||
|
||||
cfg_.rc_target_bitrate = 1600;
|
||||
ASSERT_NO_FATAL_FAILURE(RunLoop(&video));
|
||||
ASSERT_GE(20, level_);
|
||||
ASSERT_EQ(20, level_);
|
||||
}
|
||||
|
||||
// Test for level control being turned off
|
||||
@ -124,13 +94,12 @@ TEST_P(LevelTest, TestTargetLevelApi) {
|
||||
vpx_codec_ctx_t enc;
|
||||
vpx_codec_enc_cfg_t cfg;
|
||||
EXPECT_EQ(VPX_CODEC_OK, vpx_codec_enc_config_default(codec, &cfg, 0));
|
||||
cfg.rc_target_bitrate = 100;
|
||||
EXPECT_EQ(VPX_CODEC_OK, vpx_codec_enc_init(&enc, codec, &cfg, 0));
|
||||
for (int level = 0; level <= 256; ++level) {
|
||||
if (level == 10 || level == 11 || level == 20 || level == 21 ||
|
||||
level == 30 || level == 31 || level == 40 || level == 41 ||
|
||||
level == 50 || level == 51 || level == 52 || level == 60 ||
|
||||
level == 61 || level == 62 || level == 0 || level == 1 || level == 255)
|
||||
level == 61 || level == 62 || level == 0 || level == 255)
|
||||
EXPECT_EQ(VPX_CODEC_OK,
|
||||
vpx_codec_control(&enc, VP9E_SET_TARGET_LEVEL, level));
|
||||
else
|
||||
|
@ -56,8 +56,8 @@ typedef void (*dual_loop_op_t)(Pixel *s, int p, const uint8_t *blimit0,
|
||||
const uint8_t *thresh1);
|
||||
#endif // CONFIG_VP9_HIGHBITDEPTH
|
||||
|
||||
typedef ::testing::tuple<loop_op_t, loop_op_t, int> loop8_param_t;
|
||||
typedef ::testing::tuple<dual_loop_op_t, dual_loop_op_t, int> dualloop8_param_t;
|
||||
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;
|
||||
|
||||
void InitInput(Pixel *s, Pixel *ref_s, ACMRandom *rnd, const uint8_t limit,
|
||||
const int mask, const int32_t p, const int i) {
|
||||
@ -114,18 +114,6 @@ void InitInput(Pixel *s, Pixel *ref_s, ACMRandom *rnd, const uint8_t limit,
|
||||
}
|
||||
}
|
||||
|
||||
uint8_t GetOuterThresh(ACMRandom *rnd) {
|
||||
return static_cast<uint8_t>(rnd->RandRange(3 * MAX_LOOP_FILTER + 5));
|
||||
}
|
||||
|
||||
uint8_t GetInnerThresh(ACMRandom *rnd) {
|
||||
return static_cast<uint8_t>(rnd->RandRange(MAX_LOOP_FILTER + 1));
|
||||
}
|
||||
|
||||
uint8_t GetHevThresh(ACMRandom *rnd) {
|
||||
return static_cast<uint8_t>(rnd->RandRange(MAX_LOOP_FILTER + 1) >> 4);
|
||||
}
|
||||
|
||||
class Loop8Test6Param : public ::testing::TestWithParam<loop8_param_t> {
|
||||
public:
|
||||
virtual ~Loop8Test6Param() {}
|
||||
@ -174,15 +162,15 @@ TEST_P(Loop8Test6Param, OperationCheck) {
|
||||
int first_failure = -1;
|
||||
for (int i = 0; i < count_test_block; ++i) {
|
||||
int err_count = 0;
|
||||
uint8_t tmp = GetOuterThresh(&rnd);
|
||||
uint8_t tmp = static_cast<uint8_t>(rnd(3 * MAX_LOOP_FILTER + 4));
|
||||
DECLARE_ALIGNED(16, const uint8_t,
|
||||
blimit[16]) = { tmp, tmp, tmp, tmp, tmp, tmp, tmp, tmp,
|
||||
tmp, tmp, tmp, tmp, tmp, tmp, tmp, tmp };
|
||||
tmp = GetInnerThresh(&rnd);
|
||||
tmp = static_cast<uint8_t>(rnd(MAX_LOOP_FILTER));
|
||||
DECLARE_ALIGNED(16, const uint8_t,
|
||||
limit[16]) = { tmp, tmp, tmp, tmp, tmp, tmp, tmp, tmp,
|
||||
tmp, tmp, tmp, tmp, tmp, tmp, tmp, tmp };
|
||||
tmp = GetHevThresh(&rnd);
|
||||
tmp = rnd.Rand8();
|
||||
DECLARE_ALIGNED(16, const uint8_t,
|
||||
thresh[16]) = { tmp, tmp, tmp, tmp, tmp, tmp, tmp, tmp,
|
||||
tmp, tmp, tmp, tmp, tmp, tmp, tmp, tmp };
|
||||
@ -233,15 +221,15 @@ TEST_P(Loop8Test6Param, ValueCheck) {
|
||||
|
||||
for (int i = 0; i < count_test_block; ++i) {
|
||||
int err_count = 0;
|
||||
uint8_t tmp = GetOuterThresh(&rnd);
|
||||
uint8_t tmp = static_cast<uint8_t>(rnd(3 * MAX_LOOP_FILTER + 4));
|
||||
DECLARE_ALIGNED(16, const uint8_t,
|
||||
blimit[16]) = { tmp, tmp, tmp, tmp, tmp, tmp, tmp, tmp,
|
||||
tmp, tmp, tmp, tmp, tmp, tmp, tmp, tmp };
|
||||
tmp = GetInnerThresh(&rnd);
|
||||
tmp = static_cast<uint8_t>(rnd(MAX_LOOP_FILTER));
|
||||
DECLARE_ALIGNED(16, const uint8_t,
|
||||
limit[16]) = { tmp, tmp, tmp, tmp, tmp, tmp, tmp, tmp,
|
||||
tmp, tmp, tmp, tmp, tmp, tmp, tmp, tmp };
|
||||
tmp = GetHevThresh(&rnd);
|
||||
tmp = rnd.Rand8();
|
||||
DECLARE_ALIGNED(16, const uint8_t,
|
||||
thresh[16]) = { tmp, tmp, tmp, tmp, tmp, tmp, tmp, tmp,
|
||||
tmp, tmp, tmp, tmp, tmp, tmp, tmp, tmp };
|
||||
@ -283,27 +271,27 @@ TEST_P(Loop8Test9Param, OperationCheck) {
|
||||
int first_failure = -1;
|
||||
for (int i = 0; i < count_test_block; ++i) {
|
||||
int err_count = 0;
|
||||
uint8_t tmp = GetOuterThresh(&rnd);
|
||||
uint8_t tmp = static_cast<uint8_t>(rnd(3 * MAX_LOOP_FILTER + 4));
|
||||
DECLARE_ALIGNED(16, const uint8_t,
|
||||
blimit0[16]) = { tmp, tmp, tmp, tmp, tmp, tmp, tmp, tmp,
|
||||
tmp, tmp, tmp, tmp, tmp, tmp, tmp, tmp };
|
||||
tmp = GetInnerThresh(&rnd);
|
||||
tmp = static_cast<uint8_t>(rnd(MAX_LOOP_FILTER));
|
||||
DECLARE_ALIGNED(16, const uint8_t,
|
||||
limit0[16]) = { tmp, tmp, tmp, tmp, tmp, tmp, tmp, tmp,
|
||||
tmp, tmp, tmp, tmp, tmp, tmp, tmp, tmp };
|
||||
tmp = GetHevThresh(&rnd);
|
||||
tmp = rnd.Rand8();
|
||||
DECLARE_ALIGNED(16, const uint8_t,
|
||||
thresh0[16]) = { tmp, tmp, tmp, tmp, tmp, tmp, tmp, tmp,
|
||||
tmp, tmp, tmp, tmp, tmp, tmp, tmp, tmp };
|
||||
tmp = GetOuterThresh(&rnd);
|
||||
tmp = static_cast<uint8_t>(rnd(3 * MAX_LOOP_FILTER + 4));
|
||||
DECLARE_ALIGNED(16, const uint8_t,
|
||||
blimit1[16]) = { tmp, tmp, tmp, tmp, tmp, tmp, tmp, tmp,
|
||||
tmp, tmp, tmp, tmp, tmp, tmp, tmp, tmp };
|
||||
tmp = GetInnerThresh(&rnd);
|
||||
tmp = static_cast<uint8_t>(rnd(MAX_LOOP_FILTER));
|
||||
DECLARE_ALIGNED(16, const uint8_t,
|
||||
limit1[16]) = { tmp, tmp, tmp, tmp, tmp, tmp, tmp, tmp,
|
||||
tmp, tmp, tmp, tmp, tmp, tmp, tmp, tmp };
|
||||
tmp = GetHevThresh(&rnd);
|
||||
tmp = rnd.Rand8();
|
||||
DECLARE_ALIGNED(16, const uint8_t,
|
||||
thresh1[16]) = { tmp, tmp, tmp, tmp, tmp, tmp, tmp, tmp,
|
||||
tmp, tmp, tmp, tmp, tmp, tmp, tmp, tmp };
|
||||
@ -346,27 +334,27 @@ TEST_P(Loop8Test9Param, ValueCheck) {
|
||||
int first_failure = -1;
|
||||
for (int i = 0; i < count_test_block; ++i) {
|
||||
int err_count = 0;
|
||||
uint8_t tmp = GetOuterThresh(&rnd);
|
||||
uint8_t tmp = static_cast<uint8_t>(rnd(3 * MAX_LOOP_FILTER + 4));
|
||||
DECLARE_ALIGNED(16, const uint8_t,
|
||||
blimit0[16]) = { tmp, tmp, tmp, tmp, tmp, tmp, tmp, tmp,
|
||||
tmp, tmp, tmp, tmp, tmp, tmp, tmp, tmp };
|
||||
tmp = GetInnerThresh(&rnd);
|
||||
tmp = static_cast<uint8_t>(rnd(MAX_LOOP_FILTER));
|
||||
DECLARE_ALIGNED(16, const uint8_t,
|
||||
limit0[16]) = { tmp, tmp, tmp, tmp, tmp, tmp, tmp, tmp,
|
||||
tmp, tmp, tmp, tmp, tmp, tmp, tmp, tmp };
|
||||
tmp = GetHevThresh(&rnd);
|
||||
tmp = rnd.Rand8();
|
||||
DECLARE_ALIGNED(16, const uint8_t,
|
||||
thresh0[16]) = { tmp, tmp, tmp, tmp, tmp, tmp, tmp, tmp,
|
||||
tmp, tmp, tmp, tmp, tmp, tmp, tmp, tmp };
|
||||
tmp = GetOuterThresh(&rnd);
|
||||
tmp = static_cast<uint8_t>(rnd(3 * MAX_LOOP_FILTER + 4));
|
||||
DECLARE_ALIGNED(16, const uint8_t,
|
||||
blimit1[16]) = { tmp, tmp, tmp, tmp, tmp, tmp, tmp, tmp,
|
||||
tmp, tmp, tmp, tmp, tmp, tmp, tmp, tmp };
|
||||
tmp = GetInnerThresh(&rnd);
|
||||
tmp = static_cast<uint8_t>(rnd(MAX_LOOP_FILTER));
|
||||
DECLARE_ALIGNED(16, const uint8_t,
|
||||
limit1[16]) = { tmp, tmp, tmp, tmp, tmp, tmp, tmp, tmp,
|
||||
tmp, tmp, tmp, tmp, tmp, tmp, tmp, tmp };
|
||||
tmp = GetHevThresh(&rnd);
|
||||
tmp = rnd.Rand8();
|
||||
DECLARE_ALIGNED(16, const uint8_t,
|
||||
thresh1[16]) = { tmp, tmp, tmp, tmp, tmp, tmp, tmp, tmp,
|
||||
tmp, tmp, tmp, tmp, tmp, tmp, tmp, tmp };
|
||||
@ -402,7 +390,7 @@ TEST_P(Loop8Test9Param, ValueCheck) {
|
||||
<< "First failed at test case " << first_failure;
|
||||
}
|
||||
|
||||
using ::testing::make_tuple;
|
||||
using std::tr1::make_tuple;
|
||||
|
||||
#if HAVE_SSE2
|
||||
#if CONFIG_VP9_HIGHBITDEPTH
|
||||
|
@ -107,10 +107,10 @@ TEST_P(MinMaxTest, CompareReferenceAndVaryStride) {
|
||||
int min_ref, max_ref, min, max;
|
||||
reference_minmax(a, a_stride, b, b_stride, &min_ref, &max_ref);
|
||||
ASM_REGISTER_STATE_CHECK(mm_func_(a, a_stride, b, b_stride, &min, &max));
|
||||
EXPECT_EQ(max_ref, max)
|
||||
<< "when a_stride = " << a_stride << " and b_stride = " << b_stride;
|
||||
EXPECT_EQ(min_ref, min)
|
||||
<< "when a_stride = " << a_stride << " and b_stride = " << b_stride;
|
||||
EXPECT_EQ(max_ref, max) << "when a_stride = " << a_stride
|
||||
<< " and b_stride = " << b_stride;
|
||||
EXPECT_EQ(min_ref, min) << "when a_stride = " << a_stride
|
||||
<< " and b_stride = " << b_stride;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -127,9 +127,4 @@ INSTANTIATE_TEST_CASE_P(NEON, MinMaxTest,
|
||||
::testing::Values(&vpx_minmax_8x8_neon));
|
||||
#endif
|
||||
|
||||
#if HAVE_MSA
|
||||
INSTANTIATE_TEST_CASE_P(MSA, MinMaxTest,
|
||||
::testing::Values(&vpx_minmax_8x8_msa));
|
||||
#endif
|
||||
|
||||
} // namespace
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -7,40 +7,21 @@
|
||||
* in the file PATENTS. All contributing project authors may
|
||||
* be found in the AUTHORS file in the root of the source tree.
|
||||
*/
|
||||
#include <limits.h>
|
||||
#include "./vpx_config.h"
|
||||
#include "./vpx_dsp_rtcd.h"
|
||||
#include "test/acm_random.h"
|
||||
#include "test/buffer.h"
|
||||
#include "test/clear_system_state.h"
|
||||
#include "test/register_state_check.h"
|
||||
#include "third_party/googletest/src/include/gtest/gtest.h"
|
||||
#include "vpx/vpx_integer.h"
|
||||
#include "vpx_mem/vpx_mem.h"
|
||||
|
||||
using libvpx_test::ACMRandom;
|
||||
using libvpx_test::Buffer;
|
||||
|
||||
typedef void (*VpxPostProcDownAndAcrossMbRowFunc)(
|
||||
unsigned char *src_ptr, unsigned char *dst_ptr, int src_pixels_per_line,
|
||||
int dst_pixels_per_line, int cols, unsigned char *flimit, int size);
|
||||
|
||||
typedef void (*VpxMbPostProcAcrossIpFunc)(unsigned char *src, int pitch,
|
||||
int rows, int cols, int flimit);
|
||||
|
||||
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;
|
||||
|
||||
x = 50 + (x - 50) * 10 / 8;
|
||||
return x * x / 3;
|
||||
}
|
||||
|
||||
class VpxPostProcDownAndAcrossMbRowTest
|
||||
: public ::testing::TestWithParam<VpxPostProcDownAndAcrossMbRowFunc> {
|
||||
public:
|
||||
@ -56,16 +37,25 @@ TEST_P(VpxPostProcDownAndAcrossMbRowTest, CheckFilterOutput) {
|
||||
const int 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());
|
||||
const int input_width = block_width;
|
||||
const int input_height = block_height + 4;
|
||||
const int input_stride = input_width;
|
||||
const int input_size = input_width * input_height;
|
||||
|
||||
// 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());
|
||||
const int output_width = block_width + 16;
|
||||
const int output_height = block_height;
|
||||
const int output_stride = output_width;
|
||||
const int output_size = output_width * output_height;
|
||||
|
||||
uint8_t *const src_image =
|
||||
reinterpret_cast<uint8_t *>(vpx_calloc(input_size, 1));
|
||||
uint8_t *const dst_image =
|
||||
reinterpret_cast<uint8_t *>(vpx_calloc(output_size, 1));
|
||||
|
||||
// Pointers to top-left pixel of block in the input and output images.
|
||||
uint8_t *const src_image_ptr = src_image + (input_stride << 1);
|
||||
uint8_t *const dst_image_ptr = dst_image + 8;
|
||||
uint8_t *const flimits =
|
||||
reinterpret_cast<uint8_t *>(vpx_memalign(16, block_width));
|
||||
(void)memset(flimits, 255, block_width);
|
||||
@ -73,412 +63,53 @@ TEST_P(VpxPostProcDownAndAcrossMbRowTest, CheckFilterOutput) {
|
||||
// Initialize pixels in the input:
|
||||
// block pixels to value 1,
|
||||
// border pixels to value 10.
|
||||
src_image.SetPadding(10);
|
||||
src_image.Set(1);
|
||||
(void)memset(src_image, 10, input_size);
|
||||
uint8_t *pixel_ptr = src_image_ptr;
|
||||
for (int i = 0; i < block_height; ++i) {
|
||||
for (int j = 0; j < block_width; ++j) {
|
||||
pixel_ptr[j] = 1;
|
||||
}
|
||||
pixel_ptr += input_stride;
|
||||
}
|
||||
|
||||
// Initialize pixels in the output to 99.
|
||||
dst_image.Set(99);
|
||||
(void)memset(dst_image, 99, output_size);
|
||||
|
||||
ASM_REGISTER_STATE_CHECK(GetParam()(
|
||||
src_image.TopLeftPixel(), dst_image.TopLeftPixel(), src_image.stride(),
|
||||
dst_image.stride(), block_width, flimits, 16));
|
||||
ASM_REGISTER_STATE_CHECK(GetParam()(src_image_ptr, dst_image_ptr,
|
||||
input_stride, output_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
|
||||
};
|
||||
|
||||
uint8_t *pixel_ptr = dst_image.TopLeftPixel();
|
||||
pixel_ptr = dst_image_ptr;
|
||||
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 << ")";
|
||||
ASSERT_EQ(kExpectedOutput[i], pixel_ptr[j]);
|
||||
}
|
||||
pixel_ptr += dst_image.stride();
|
||||
pixel_ptr += output_stride;
|
||||
}
|
||||
|
||||
vpx_free(src_image);
|
||||
vpx_free(dst_image);
|
||||
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;
|
||||
|
||||
// 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);
|
||||
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, there is 'above' padding as well
|
||||
// so when the assembly code tries to read 16 bytes before the pointer it is
|
||||
// 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);
|
||||
ASSERT_TRUE(dst_image.Init());
|
||||
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));
|
||||
|
||||
ACMRandom rnd;
|
||||
rnd.Reset(ACMRandom::DeterministicSeed());
|
||||
// Initialize pixels in the input:
|
||||
// block pixels to random values.
|
||||
// border pixels to value 10.
|
||||
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 f = 0; f < 255; f++) {
|
||||
(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));
|
||||
|
||||
ASSERT_TRUE(dst_image.CheckValues(dst_image_ref));
|
||||
}
|
||||
}
|
||||
|
||||
vpx_free(flimits);
|
||||
}
|
||||
|
||||
class VpxMbPostProcAcrossIpTest
|
||||
: public ::testing::TestWithParam<VpxMbPostProcAcrossIpFunc> {
|
||||
public:
|
||||
virtual void TearDown() { libvpx_test::ClearSystemState(); }
|
||||
|
||||
protected:
|
||||
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++) {
|
||||
s[c] = c;
|
||||
}
|
||||
s += src_width;
|
||||
}
|
||||
}
|
||||
|
||||
void RunComparison(const unsigned char *expected_output, unsigned char *src_c,
|
||||
int rows, int cols, int src_pitch) {
|
||||
for (int r = 0; r < rows; r++) {
|
||||
for (int c = 0; c < cols; c++) {
|
||||
ASSERT_EQ(expected_output[c], src_c[c])
|
||||
<< "at (" << r << ", " << c << ")";
|
||||
}
|
||||
src_c += src_pitch;
|
||||
}
|
||||
}
|
||||
|
||||
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));
|
||||
RunComparison(expected_output, s, rows, cols, src_width);
|
||||
}
|
||||
};
|
||||
|
||||
TEST_P(VpxMbPostProcAcrossIpTest, CheckLowFilterOutput) {
|
||||
const int rows = 16;
|
||||
const int cols = 16;
|
||||
|
||||
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);
|
||||
ASSERT_TRUE(expected_output.Init());
|
||||
SetCols(expected_output.TopLeftPixel(), rows, cols, expected_output.stride());
|
||||
|
||||
RunFilterLevel(src.TopLeftPixel(), rows, cols, src.stride(), q2mbl(0),
|
||||
expected_output.TopLeftPixel());
|
||||
}
|
||||
|
||||
TEST_P(VpxMbPostProcAcrossIpTest, CheckMediumFilterOutput) {
|
||||
const int rows = 16;
|
||||
const int cols = 16;
|
||||
|
||||
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] = {
|
||||
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),
|
||||
kExpectedOutput);
|
||||
}
|
||||
|
||||
TEST_P(VpxMbPostProcAcrossIpTest, CheckHighFilterOutput) {
|
||||
const int rows = 16;
|
||||
const int cols = 16;
|
||||
|
||||
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] = {
|
||||
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,
|
||||
kExpectedOutput);
|
||||
|
||||
SetCols(src.TopLeftPixel(), rows, cols, src.stride());
|
||||
|
||||
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);
|
||||
ASSERT_TRUE(c_mem.Init());
|
||||
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
|
||||
// When level < 20, it behaves the same as the level = 0
|
||||
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());
|
||||
|
||||
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)));
|
||||
|
||||
ASSERT_TRUE(asm_mem.CheckValues(c_mem));
|
||||
}
|
||||
}
|
||||
|
||||
class VpxMbPostProcDownTest
|
||||
: public ::testing::TestWithParam<VpxMbPostProcDownFunc> {
|
||||
public:
|
||||
virtual void TearDown() { libvpx_test::ClearSystemState(); }
|
||||
|
||||
protected:
|
||||
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);
|
||||
src_c += src_width;
|
||||
}
|
||||
}
|
||||
|
||||
void RunComparison(const unsigned char *expected_output, unsigned char *src_c,
|
||||
int rows, int cols, int src_pitch) {
|
||||
for (int r = 0; r < rows; r++) {
|
||||
for (int c = 0; c < cols; c++) {
|
||||
ASSERT_EQ(expected_output[r * rows + c], src_c[c])
|
||||
<< "at (" << r << ", " << c << ")";
|
||||
}
|
||||
src_c += src_pitch;
|
||||
}
|
||||
}
|
||||
|
||||
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));
|
||||
RunComparison(expected_output, s, rows, cols, src_width);
|
||||
}
|
||||
};
|
||||
|
||||
TEST_P(VpxMbPostProcDownTest, CheckHighFilterOutput) {
|
||||
const int rows = 16;
|
||||
const int cols = 16;
|
||||
|
||||
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());
|
||||
|
||||
static const unsigned char kExpectedOutput[rows * cols] = {
|
||||
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,
|
||||
4, 4, 3, 4, 4, 3, 3, 4, 5, 4, 4, 4, 4, 4, 4, 4, 5, 4, 4,
|
||||
4, 4, 4, 4, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
|
||||
5, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 7, 7,
|
||||
7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 8, 8, 8, 8, 8,
|
||||
8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 9, 8, 9, 9, 8, 8, 8, 9,
|
||||
9, 8, 9, 9, 8, 8, 8, 9, 9, 10, 10, 9, 9, 9, 10, 10, 9, 10, 10,
|
||||
9, 9, 9, 10, 10, 10, 11, 10, 10, 10, 11, 10, 11, 10, 11, 10, 10, 10, 11,
|
||||
10, 11, 11, 11, 11, 11, 11, 11, 12, 11, 11, 11, 11, 11, 11, 11, 12, 11, 12,
|
||||
12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 13, 12,
|
||||
13, 12, 13, 12, 12, 12, 13, 12, 13, 12, 13, 12, 13, 13, 13, 14, 13, 13, 13,
|
||||
13, 13, 13, 13, 14, 13, 13, 13, 13
|
||||
};
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
TEST_P(VpxMbPostProcDownTest, CheckMediumFilterOutput) {
|
||||
const int rows = 16;
|
||||
const int cols = 16;
|
||||
|
||||
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());
|
||||
|
||||
static const unsigned char kExpectedOutput[rows * cols] = {
|
||||
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,
|
||||
3, 3, 3, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
|
||||
4, 4, 4, 4, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
|
||||
5, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 7, 7,
|
||||
7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 8, 8, 8, 8, 8,
|
||||
8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 9, 9, 9, 9, 9, 9, 9, 9,
|
||||
9, 9, 9, 9, 9, 9, 9, 9, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10,
|
||||
10, 10, 10, 10, 10, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11,
|
||||
11, 11, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 13,
|
||||
13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 12, 12, 13, 12,
|
||||
13, 12, 13, 12, 12, 12, 13, 12, 13, 12, 13, 12, 13, 13, 13, 14, 13, 13, 13,
|
||||
13, 13, 13, 13, 14, 13, 13, 13, 13
|
||||
};
|
||||
|
||||
RunFilterLevel(src_c.TopLeftPixel(), rows, cols, src_c.stride(), q2mbl(70),
|
||||
kExpectedOutput);
|
||||
}
|
||||
|
||||
TEST_P(VpxMbPostProcDownTest, CheckLowFilterOutput) {
|
||||
const int rows = 16;
|
||||
const int cols = 16;
|
||||
|
||||
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());
|
||||
|
||||
unsigned char *expected_output = new unsigned char[rows * cols];
|
||||
ASSERT_TRUE(expected_output != NULL);
|
||||
SetRows(expected_output, rows, cols, cols);
|
||||
|
||||
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_asm.Init());
|
||||
|
||||
for (int level = 0; level < 100; level++) {
|
||||
src_c.SetPadding(10);
|
||||
src_asm.SetPadding(10);
|
||||
src_c.Set(&rnd, &ACMRandom::Rand8);
|
||||
src_asm.CopyFrom(src_c);
|
||||
|
||||
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));
|
||||
|
||||
src_c.SetPadding(10);
|
||||
src_asm.SetPadding(10);
|
||||
src_c.Set(&rnd, &ACMRandom::Rand8Extremes);
|
||||
src_asm.CopyFrom(src_c);
|
||||
|
||||
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));
|
||||
}
|
||||
}
|
||||
|
||||
INSTANTIATE_TEST_CASE_P(
|
||||
C, VpxPostProcDownAndAcrossMbRowTest,
|
||||
::testing::Values(vpx_post_proc_down_and_across_mb_row_c));
|
||||
|
||||
INSTANTIATE_TEST_CASE_P(C, VpxMbPostProcAcrossIpTest,
|
||||
::testing::Values(vpx_mbpost_proc_across_ip_c));
|
||||
|
||||
INSTANTIATE_TEST_CASE_P(C, VpxMbPostProcDownTest,
|
||||
::testing::Values(vpx_mbpost_proc_down_c));
|
||||
|
||||
#if HAVE_SSE2
|
||||
INSTANTIATE_TEST_CASE_P(
|
||||
SSE2, VpxPostProcDownAndAcrossMbRowTest,
|
||||
::testing::Values(vpx_post_proc_down_and_across_mb_row_sse2));
|
||||
|
||||
INSTANTIATE_TEST_CASE_P(SSE2, VpxMbPostProcAcrossIpTest,
|
||||
::testing::Values(vpx_mbpost_proc_across_ip_sse2));
|
||||
|
||||
INSTANTIATE_TEST_CASE_P(SSE2, VpxMbPostProcDownTest,
|
||||
::testing::Values(vpx_mbpost_proc_down_sse2));
|
||||
#endif // HAVE_SSE2
|
||||
|
||||
#if HAVE_NEON
|
||||
INSTANTIATE_TEST_CASE_P(
|
||||
NEON, VpxPostProcDownAndAcrossMbRowTest,
|
||||
::testing::Values(vpx_post_proc_down_and_across_mb_row_neon));
|
||||
|
||||
INSTANTIATE_TEST_CASE_P(NEON, VpxMbPostProcAcrossIpTest,
|
||||
::testing::Values(vpx_mbpost_proc_across_ip_neon));
|
||||
|
||||
INSTANTIATE_TEST_CASE_P(NEON, VpxMbPostProcDownTest,
|
||||
::testing::Values(vpx_mbpost_proc_down_neon));
|
||||
#endif // HAVE_NEON
|
||||
#endif
|
||||
|
||||
#if HAVE_MSA
|
||||
INSTANTIATE_TEST_CASE_P(
|
||||
MSA, VpxPostProcDownAndAcrossMbRowTest,
|
||||
::testing::Values(vpx_post_proc_down_and_across_mb_row_msa));
|
||||
|
||||
INSTANTIATE_TEST_CASE_P(MSA, VpxMbPostProcAcrossIpTest,
|
||||
::testing::Values(vpx_mbpost_proc_across_ip_msa));
|
||||
|
||||
INSTANTIATE_TEST_CASE_P(MSA, VpxMbPostProcDownTest,
|
||||
::testing::Values(vpx_mbpost_proc_down_msa));
|
||||
#endif // HAVE_MSA
|
||||
#endif
|
||||
|
||||
} // namespace
|
||||
|
@ -24,14 +24,14 @@
|
||||
|
||||
namespace {
|
||||
|
||||
using ::testing::make_tuple;
|
||||
using libvpx_test::ACMRandom;
|
||||
using std::tr1::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 ::testing::tuple<int, int, PredictFunc> PredictParam;
|
||||
typedef std::tr1::tuple<int, int, PredictFunc> PredictParam;
|
||||
|
||||
class PredictTestBase : public ::testing::TestWithParam<PredictParam> {
|
||||
public:
|
||||
@ -324,15 +324,6 @@ INSTANTIATE_TEST_CASE_P(
|
||||
make_tuple(4, 4, &vp8_sixtap_predict4x4_msa)));
|
||||
#endif
|
||||
|
||||
#if HAVE_MMI
|
||||
INSTANTIATE_TEST_CASE_P(
|
||||
MMI, SixtapPredictTest,
|
||||
::testing::Values(make_tuple(16, 16, &vp8_sixtap_predict16x16_mmi),
|
||||
make_tuple(8, 8, &vp8_sixtap_predict8x8_mmi),
|
||||
make_tuple(8, 4, &vp8_sixtap_predict8x4_mmi),
|
||||
make_tuple(4, 4, &vp8_sixtap_predict4x4_mmi)));
|
||||
#endif
|
||||
|
||||
class BilinearPredictTest : public PredictTestBase {};
|
||||
|
||||
TEST_P(BilinearPredictTest, TestWithRandomData) {
|
||||
|
@ -33,10 +33,10 @@ const int kNumBlockEntries = 16;
|
||||
|
||||
typedef void (*VP8Quantize)(BLOCK *b, BLOCKD *d);
|
||||
|
||||
typedef ::testing::tuple<VP8Quantize, VP8Quantize> VP8QuantizeParam;
|
||||
typedef std::tr1::tuple<VP8Quantize, VP8Quantize> VP8QuantizeParam;
|
||||
|
||||
using ::testing::make_tuple;
|
||||
using libvpx_test::ACMRandom;
|
||||
using std::tr1::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.
|
||||
@ -200,12 +200,4 @@ INSTANTIATE_TEST_CASE_P(
|
||||
make_tuple(&vp8_fast_quantize_b_msa, &vp8_fast_quantize_b_c),
|
||||
make_tuple(&vp8_regular_quantize_b_msa, &vp8_regular_quantize_b_c)));
|
||||
#endif // HAVE_MSA
|
||||
|
||||
#if HAVE_MMI
|
||||
INSTANTIATE_TEST_CASE_P(
|
||||
MMI, QuantizeTest,
|
||||
::testing::Values(
|
||||
make_tuple(&vp8_fast_quantize_b_mmi, &vp8_fast_quantize_b_c),
|
||||
make_tuple(&vp8_regular_quantize_b_mmi, &vp8_regular_quantize_b_c)));
|
||||
#endif // HAVE_MMI
|
||||
} // namespace
|
||||
|
@ -28,13 +28,11 @@
|
||||
// See platform implementations of RegisterStateCheckXXX for details.
|
||||
//
|
||||
|
||||
#if defined(_WIN64) && ARCH_X86_64
|
||||
#if defined(_WIN64)
|
||||
|
||||
#undef NOMINMAX
|
||||
#define NOMINMAX
|
||||
#ifndef WIN32_LEAN_AND_MEAN
|
||||
#define WIN32_LEAN_AND_MEAN
|
||||
#endif
|
||||
#include <windows.h>
|
||||
#include <winnt.h>
|
||||
|
||||
@ -113,8 +111,8 @@ class RegisterStateCheck {
|
||||
int64_t post_store[8];
|
||||
vpx_push_neon(post_store);
|
||||
for (int i = 0; i < 8; ++i) {
|
||||
EXPECT_EQ(pre_store_[i], post_store[i])
|
||||
<< "d" << i + 8 << " has been modified";
|
||||
EXPECT_EQ(pre_store_[i], post_store[i]) << "d" << i + 8
|
||||
<< " has been modified";
|
||||
}
|
||||
}
|
||||
|
||||
@ -138,7 +136,7 @@ class RegisterStateCheck {};
|
||||
|
||||
} // namespace libvpx_test
|
||||
|
||||
#endif // _WIN64 && ARCH_X86_64
|
||||
#endif // _WIN64
|
||||
|
||||
#if ARCH_X86 || ARCH_X86_64
|
||||
#if defined(__GNUC__)
|
||||
|
@ -277,29 +277,12 @@ 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) {
|
||||
@ -313,15 +296,12 @@ 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)
|
||||
<< "Frame " << frame << " had unexpected width";
|
||||
EXPECT_EQ(expected_h, info->h)
|
||||
<< "Frame " << frame << " had unexpected height";
|
||||
EXPECT_EQ(expected_w, info->w) << "Frame " << frame
|
||||
<< " had unexpected width";
|
||||
EXPECT_EQ(expected_h, info->h) << "Frame " << frame
|
||||
<< " had unexpected height";
|
||||
}
|
||||
}
|
||||
|
||||
@ -484,23 +464,8 @@ 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;
|
||||
@ -528,8 +493,6 @@ 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) {
|
||||
@ -550,10 +513,10 @@ TEST_P(ResizeRealtimeTest, TestExternalResizeWorks) {
|
||||
unsigned int expected_h;
|
||||
ScaleForFrameNumber(frame, kInitialWidth, kInitialHeight, &expected_w,
|
||||
&expected_h, 1);
|
||||
EXPECT_EQ(expected_w, info->w)
|
||||
<< "Frame " << frame << " had unexpected width";
|
||||
EXPECT_EQ(expected_h, info->h)
|
||||
<< "Frame " << frame << " had unexpected height";
|
||||
EXPECT_EQ(expected_w, info->w) << "Frame " << frame
|
||||
<< " had unexpected width";
|
||||
EXPECT_EQ(expected_h, info->h) << "Frame " << frame
|
||||
<< " had unexpected height";
|
||||
EXPECT_EQ(static_cast<unsigned int>(0), GetMismatchFrames());
|
||||
}
|
||||
}
|
||||
@ -619,9 +582,6 @@ 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) {
|
||||
|
170
test/sad_test.cc
170
test/sad_test.cc
@ -23,7 +23,6 @@
|
||||
#include "vpx/vpx_codec.h"
|
||||
#include "vpx_mem/vpx_mem.h"
|
||||
#include "vpx_ports/mem.h"
|
||||
#include "vpx_ports/vpx_timer.h"
|
||||
|
||||
template <typename Function>
|
||||
struct TestParams {
|
||||
@ -85,7 +84,7 @@ class SADTestBase : public ::testing::TestWithParam<ParamType> {
|
||||
#endif // CONFIG_VP9_HIGHBITDEPTH
|
||||
}
|
||||
mask_ = (1 << bit_depth_) - 1;
|
||||
source_stride_ = (params_.width + 63) & ~63;
|
||||
source_stride_ = (params_.width + 31) & ~31;
|
||||
reference_stride_ = params_.width * 2;
|
||||
rnd_.Reset(ACMRandom::DeterministicSeed());
|
||||
}
|
||||
@ -109,7 +108,7 @@ class SADTestBase : public ::testing::TestWithParam<ParamType> {
|
||||
|
||||
protected:
|
||||
// Handle blocks up to 4 blocks 64x64 with stride up to 128
|
||||
static const int kDataAlignment = 32;
|
||||
static const int kDataAlignment = 16;
|
||||
static const int kDataBlockSize = 64 * 128;
|
||||
static const int kDataBufferSize = 4 * kDataBlockSize;
|
||||
|
||||
@ -464,38 +463,6 @@ 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[] = {
|
||||
@ -677,50 +644,19 @@ INSTANTIATE_TEST_CASE_P(C, SADx4Test, ::testing::ValuesIn(x4d_c_tests));
|
||||
#if HAVE_NEON
|
||||
const SadMxNParam neon_tests[] = {
|
||||
SadMxNParam(64, 64, &vpx_sad64x64_neon),
|
||||
SadMxNParam(64, 32, &vpx_sad64x32_neon),
|
||||
SadMxNParam(32, 32, &vpx_sad32x32_neon),
|
||||
SadMxNParam(16, 32, &vpx_sad16x32_neon),
|
||||
SadMxNParam(16, 16, &vpx_sad16x16_neon),
|
||||
SadMxNParam(16, 8, &vpx_sad16x8_neon),
|
||||
SadMxNParam(8, 16, &vpx_sad8x16_neon),
|
||||
SadMxNParam(8, 8, &vpx_sad8x8_neon),
|
||||
SadMxNParam(8, 4, &vpx_sad8x4_neon),
|
||||
SadMxNParam(4, 8, &vpx_sad4x8_neon),
|
||||
SadMxNParam(4, 4, &vpx_sad4x4_neon),
|
||||
};
|
||||
INSTANTIATE_TEST_CASE_P(NEON, SADTest, ::testing::ValuesIn(neon_tests));
|
||||
|
||||
const SadMxNAvgParam avg_neon_tests[] = {
|
||||
SadMxNAvgParam(64, 64, &vpx_sad64x64_avg_neon),
|
||||
SadMxNAvgParam(64, 32, &vpx_sad64x32_avg_neon),
|
||||
SadMxNAvgParam(32, 64, &vpx_sad32x64_avg_neon),
|
||||
SadMxNAvgParam(32, 32, &vpx_sad32x32_avg_neon),
|
||||
SadMxNAvgParam(32, 16, &vpx_sad32x16_avg_neon),
|
||||
SadMxNAvgParam(16, 32, &vpx_sad16x32_avg_neon),
|
||||
SadMxNAvgParam(16, 16, &vpx_sad16x16_avg_neon),
|
||||
SadMxNAvgParam(16, 8, &vpx_sad16x8_avg_neon),
|
||||
SadMxNAvgParam(8, 16, &vpx_sad8x16_avg_neon),
|
||||
SadMxNAvgParam(8, 8, &vpx_sad8x8_avg_neon),
|
||||
SadMxNAvgParam(8, 4, &vpx_sad8x4_avg_neon),
|
||||
SadMxNAvgParam(4, 8, &vpx_sad4x8_avg_neon),
|
||||
SadMxNAvgParam(4, 4, &vpx_sad4x4_avg_neon),
|
||||
};
|
||||
INSTANTIATE_TEST_CASE_P(NEON, SADavgTest, ::testing::ValuesIn(avg_neon_tests));
|
||||
|
||||
const SadMxNx4Param x4d_neon_tests[] = {
|
||||
SadMxNx4Param(64, 64, &vpx_sad64x64x4d_neon),
|
||||
SadMxNx4Param(64, 32, &vpx_sad64x32x4d_neon),
|
||||
SadMxNx4Param(32, 64, &vpx_sad32x64x4d_neon),
|
||||
SadMxNx4Param(32, 32, &vpx_sad32x32x4d_neon),
|
||||
SadMxNx4Param(32, 16, &vpx_sad32x16x4d_neon),
|
||||
SadMxNx4Param(16, 32, &vpx_sad16x32x4d_neon),
|
||||
SadMxNx4Param(16, 16, &vpx_sad16x16x4d_neon),
|
||||
SadMxNx4Param(16, 8, &vpx_sad16x8x4d_neon),
|
||||
SadMxNx4Param(8, 16, &vpx_sad8x16x4d_neon),
|
||||
SadMxNx4Param(8, 8, &vpx_sad8x8x4d_neon),
|
||||
SadMxNx4Param(8, 4, &vpx_sad8x4x4d_neon),
|
||||
SadMxNx4Param(4, 8, &vpx_sad4x8x4d_neon),
|
||||
SadMxNx4Param(4, 4, &vpx_sad4x4x4d_neon),
|
||||
};
|
||||
INSTANTIATE_TEST_CASE_P(NEON, SADx4Test, ::testing::ValuesIn(x4d_neon_tests));
|
||||
#endif // HAVE_NEON
|
||||
@ -929,14 +865,6 @@ const SadMxNx4Param x4d_avx2_tests[] = {
|
||||
INSTANTIATE_TEST_CASE_P(AVX2, SADx4Test, ::testing::ValuesIn(x4d_avx2_tests));
|
||||
#endif // HAVE_AVX2
|
||||
|
||||
#if HAVE_AVX512
|
||||
const SadMxNx4Param x4d_avx512_tests[] = {
|
||||
SadMxNx4Param(64, 64, &vpx_sad64x64x4d_avx512),
|
||||
};
|
||||
INSTANTIATE_TEST_CASE_P(AVX512, SADx4Test,
|
||||
::testing::ValuesIn(x4d_avx512_tests));
|
||||
#endif // HAVE_AVX512
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// MIPS functions
|
||||
#if HAVE_MSA
|
||||
@ -992,98 +920,4 @@ const SadMxNx4Param x4d_msa_tests[] = {
|
||||
INSTANTIATE_TEST_CASE_P(MSA, SADx4Test, ::testing::ValuesIn(x4d_msa_tests));
|
||||
#endif // HAVE_MSA
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// VSX functions
|
||||
#if HAVE_VSX
|
||||
const SadMxNParam vsx_tests[] = {
|
||||
SadMxNParam(64, 64, &vpx_sad64x64_vsx),
|
||||
SadMxNParam(64, 32, &vpx_sad64x32_vsx),
|
||||
SadMxNParam(32, 64, &vpx_sad32x64_vsx),
|
||||
SadMxNParam(32, 32, &vpx_sad32x32_vsx),
|
||||
SadMxNParam(32, 16, &vpx_sad32x16_vsx),
|
||||
SadMxNParam(16, 32, &vpx_sad16x32_vsx),
|
||||
SadMxNParam(16, 16, &vpx_sad16x16_vsx),
|
||||
SadMxNParam(16, 8, &vpx_sad16x8_vsx),
|
||||
};
|
||||
INSTANTIATE_TEST_CASE_P(VSX, SADTest, ::testing::ValuesIn(vsx_tests));
|
||||
|
||||
const SadMxNAvgParam avg_vsx_tests[] = {
|
||||
SadMxNAvgParam(64, 64, &vpx_sad64x64_avg_vsx),
|
||||
SadMxNAvgParam(64, 32, &vpx_sad64x32_avg_vsx),
|
||||
SadMxNAvgParam(32, 64, &vpx_sad32x64_avg_vsx),
|
||||
SadMxNAvgParam(32, 32, &vpx_sad32x32_avg_vsx),
|
||||
SadMxNAvgParam(32, 16, &vpx_sad32x16_avg_vsx),
|
||||
SadMxNAvgParam(16, 32, &vpx_sad16x32_avg_vsx),
|
||||
SadMxNAvgParam(16, 16, &vpx_sad16x16_avg_vsx),
|
||||
SadMxNAvgParam(16, 8, &vpx_sad16x8_avg_vsx),
|
||||
};
|
||||
INSTANTIATE_TEST_CASE_P(VSX, SADavgTest, ::testing::ValuesIn(avg_vsx_tests));
|
||||
|
||||
const SadMxNx4Param x4d_vsx_tests[] = {
|
||||
SadMxNx4Param(64, 64, &vpx_sad64x64x4d_vsx),
|
||||
SadMxNx4Param(64, 32, &vpx_sad64x32x4d_vsx),
|
||||
SadMxNx4Param(32, 64, &vpx_sad32x64x4d_vsx),
|
||||
SadMxNx4Param(32, 32, &vpx_sad32x32x4d_vsx),
|
||||
SadMxNx4Param(32, 16, &vpx_sad32x16x4d_vsx),
|
||||
SadMxNx4Param(16, 32, &vpx_sad16x32x4d_vsx),
|
||||
SadMxNx4Param(16, 16, &vpx_sad16x16x4d_vsx),
|
||||
SadMxNx4Param(16, 8, &vpx_sad16x8x4d_vsx),
|
||||
};
|
||||
INSTANTIATE_TEST_CASE_P(VSX, SADx4Test, ::testing::ValuesIn(x4d_vsx_tests));
|
||||
#endif // HAVE_VSX
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Loongson functions
|
||||
#if HAVE_MMI
|
||||
const SadMxNParam mmi_tests[] = {
|
||||
SadMxNParam(64, 64, &vpx_sad64x64_mmi),
|
||||
SadMxNParam(64, 32, &vpx_sad64x32_mmi),
|
||||
SadMxNParam(32, 64, &vpx_sad32x64_mmi),
|
||||
SadMxNParam(32, 32, &vpx_sad32x32_mmi),
|
||||
SadMxNParam(32, 16, &vpx_sad32x16_mmi),
|
||||
SadMxNParam(16, 32, &vpx_sad16x32_mmi),
|
||||
SadMxNParam(16, 16, &vpx_sad16x16_mmi),
|
||||
SadMxNParam(16, 8, &vpx_sad16x8_mmi),
|
||||
SadMxNParam(8, 16, &vpx_sad8x16_mmi),
|
||||
SadMxNParam(8, 8, &vpx_sad8x8_mmi),
|
||||
SadMxNParam(8, 4, &vpx_sad8x4_mmi),
|
||||
SadMxNParam(4, 8, &vpx_sad4x8_mmi),
|
||||
SadMxNParam(4, 4, &vpx_sad4x4_mmi),
|
||||
};
|
||||
INSTANTIATE_TEST_CASE_P(MMI, SADTest, ::testing::ValuesIn(mmi_tests));
|
||||
|
||||
const SadMxNAvgParam avg_mmi_tests[] = {
|
||||
SadMxNAvgParam(64, 64, &vpx_sad64x64_avg_mmi),
|
||||
SadMxNAvgParam(64, 32, &vpx_sad64x32_avg_mmi),
|
||||
SadMxNAvgParam(32, 64, &vpx_sad32x64_avg_mmi),
|
||||
SadMxNAvgParam(32, 32, &vpx_sad32x32_avg_mmi),
|
||||
SadMxNAvgParam(32, 16, &vpx_sad32x16_avg_mmi),
|
||||
SadMxNAvgParam(16, 32, &vpx_sad16x32_avg_mmi),
|
||||
SadMxNAvgParam(16, 16, &vpx_sad16x16_avg_mmi),
|
||||
SadMxNAvgParam(16, 8, &vpx_sad16x8_avg_mmi),
|
||||
SadMxNAvgParam(8, 16, &vpx_sad8x16_avg_mmi),
|
||||
SadMxNAvgParam(8, 8, &vpx_sad8x8_avg_mmi),
|
||||
SadMxNAvgParam(8, 4, &vpx_sad8x4_avg_mmi),
|
||||
SadMxNAvgParam(4, 8, &vpx_sad4x8_avg_mmi),
|
||||
SadMxNAvgParam(4, 4, &vpx_sad4x4_avg_mmi),
|
||||
};
|
||||
INSTANTIATE_TEST_CASE_P(MMI, SADavgTest, ::testing::ValuesIn(avg_mmi_tests));
|
||||
|
||||
const SadMxNx4Param x4d_mmi_tests[] = {
|
||||
SadMxNx4Param(64, 64, &vpx_sad64x64x4d_mmi),
|
||||
SadMxNx4Param(64, 32, &vpx_sad64x32x4d_mmi),
|
||||
SadMxNx4Param(32, 64, &vpx_sad32x64x4d_mmi),
|
||||
SadMxNx4Param(32, 32, &vpx_sad32x32x4d_mmi),
|
||||
SadMxNx4Param(32, 16, &vpx_sad32x16x4d_mmi),
|
||||
SadMxNx4Param(16, 32, &vpx_sad16x32x4d_mmi),
|
||||
SadMxNx4Param(16, 16, &vpx_sad16x16x4d_mmi),
|
||||
SadMxNx4Param(16, 8, &vpx_sad16x8x4d_mmi),
|
||||
SadMxNx4Param(8, 16, &vpx_sad8x16x4d_mmi),
|
||||
SadMxNx4Param(8, 8, &vpx_sad8x8x4d_mmi),
|
||||
SadMxNx4Param(8, 4, &vpx_sad8x4x4d_mmi),
|
||||
SadMxNx4Param(4, 8, &vpx_sad4x8x4d_mmi),
|
||||
SadMxNx4Param(4, 4, &vpx_sad4x4x4d_mmi),
|
||||
};
|
||||
INSTANTIATE_TEST_CASE_P(MMI, SADx4Test, ::testing::ValuesIn(x4d_mmi_tests));
|
||||
#endif // HAVE_MMI
|
||||
} // namespace
|
||||
|
@ -146,6 +146,14 @@ TEST(VP8RoiMapTest, ParameterCheck) {
|
||||
if (deltas_valid != roi_retval) break;
|
||||
}
|
||||
|
||||
// Test that we report and error if cyclic refresh is enabled.
|
||||
cpi.cyclic_refresh_mode_enabled = 1;
|
||||
roi_retval =
|
||||
vp8_set_roimap(&cpi, roi_map, cpi.common.mb_rows, cpi.common.mb_cols,
|
||||
delta_q, delta_lf, threshold);
|
||||
EXPECT_EQ(-1, roi_retval) << "cyclic refresh check error";
|
||||
cpi.cyclic_refresh_mode_enabled = 0;
|
||||
|
||||
// Test invalid number of rows or colums.
|
||||
roi_retval =
|
||||
vp8_set_roimap(&cpi, roi_map, cpi.common.mb_rows + 1,
|
||||
|
169
test/stress.sh
169
test/stress.sh
@ -1,169 +0,0 @@
|
||||
#!/bin/sh
|
||||
##
|
||||
## 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.
|
||||
##
|
||||
## This file performs a stress test. It runs (STRESS_ONEPASS_MAX_JOBS,
|
||||
## default=5) one, (STRESS_TWOPASS_MAX_JOBS, default=5) two pass &
|
||||
## (STRESS_RT_MAX_JOBS, default=5) encodes and (STRESS_<codec>_DECODE_MAX_JOBS,
|
||||
## default=30) decodes in parallel.
|
||||
|
||||
. $(dirname $0)/tools_common.sh
|
||||
|
||||
YUV="${LIBVPX_TEST_DATA_PATH}/niklas_1280_720_30.yuv"
|
||||
VP8="${LIBVPX_TEST_DATA_PATH}/tos_vp8.webm"
|
||||
VP9="${LIBVPX_TEST_DATA_PATH}/vp90-2-sintel_1920x818_tile_1x4_fpm_2279kbps.webm"
|
||||
DATA_URL="http://downloads.webmproject.org/test_data/libvpx/"
|
||||
SHA1_FILE="$(dirname $0)/test-data.sha1"
|
||||
|
||||
# Set sha1sum to proper sha program (sha1sum, shasum, sha1). This code is
|
||||
# cribbed from libs.mk.
|
||||
[ -x "$(which sha1sum)" ] && sha1sum=sha1sum
|
||||
[ -x "$(which shasum)" ] && sha1sum=shasum
|
||||
[ -x "$(which sha1)" ] && sha1sum=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}/}"
|
||||
|
||||
# Download the file using curl. Trap to insure non partial file.
|
||||
(trap "rm -f $1" INT TERM \
|
||||
&& eval "curl --retry 1 -L -o $1 ${DATA_URL}${root} ${devnull}")
|
||||
|
||||
# Check the sha1 sum of the file.
|
||||
if [ -n "${sha1sum}" ]; then
|
||||
set -e
|
||||
grep ${root} ${SHA1_FILE} \
|
||||
| (cd ${LIBVPX_TEST_DATA_PATH}; ${sha1sum} -c);
|
||||
fi
|
||||
}
|
||||
|
||||
# Environment check: Make sure input is available.
|
||||
stress_verify_environment() {
|
||||
if [ ! -e "${SHA1_FILE}" ] ; then
|
||||
echo "Missing ${SHA1_FILE}"
|
||||
return 1
|
||||
fi
|
||||
for file in "${YUV}" "${VP8}" "${VP9}"; do
|
||||
if [ ! -e "${file}" ] ; then
|
||||
download_and_check_file "${file}"
|
||||
fi
|
||||
done
|
||||
if [ ! -e "${YUV}" ] || [ ! -e "${VP8}" ] || [ ! -e "${VP9}" ] ; then
|
||||
elog "Libvpx test data must exist in LIBVPX_TEST_DATA_PATH."
|
||||
return 1
|
||||
fi
|
||||
if [ -z "$(vpx_tool_path vpxenc)" ]; then
|
||||
elog "vpxenc not found. It must exist in LIBVPX_BIN_PATH or its parent."
|
||||
return 1
|
||||
fi
|
||||
if [ -z "$(vpx_tool_path vpxdec)" ]; then
|
||||
elog "vpxdec not found. It must exist in LIBVPX_BIN_PATH or its parent."
|
||||
return 1
|
||||
fi
|
||||
}
|
||||
|
||||
# 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 pids=""
|
||||
local rt_max_jobs=${STRESS_RT_MAX_JOBS:-5}
|
||||
local onepass_max_jobs=${STRESS_ONEPASS_MAX_JOBS:-5}
|
||||
local twopass_max_jobs=${STRESS_TWOPASS_MAX_JOBS:-5}
|
||||
|
||||
# Enable job control, so we can run multiple processes.
|
||||
set -m
|
||||
|
||||
# Start $onepass_max_jobs encode jobs in parallel.
|
||||
for i in $(seq ${onepass_max_jobs}); do
|
||||
bitrate=$(($i * 20 + 300))
|
||||
eval "${VPX_TEST_PREFIX}" "${encoder}" "--codec=${codec} -w 1280 -h 720" \
|
||||
"${YUV}" "-t ${threads} --limit=150 --test-decode=fatal --passes=1" \
|
||||
"--target-bitrate=${bitrate} -o ${VPX_TEST_OUTPUT_DIR}/${i}.1pass.webm" \
|
||||
"${enc_args}" ${devnull} &
|
||||
pids="${pids} $!"
|
||||
done
|
||||
|
||||
# Start $twopass_max_jobs encode jobs in parallel.
|
||||
for i in $(seq ${twopass_max_jobs}); do
|
||||
bitrate=$(($i * 20 + 300))
|
||||
eval "${VPX_TEST_PREFIX}" "${encoder}" "--codec=${codec} -w 1280 -h 720" \
|
||||
"${YUV}" "-t ${threads} --limit=150 --test-decode=fatal --passes=2" \
|
||||
"--target-bitrate=${bitrate} -o ${VPX_TEST_OUTPUT_DIR}/${i}.2pass.webm" \
|
||||
"${enc_args}" ${devnull} &
|
||||
pids="${pids} $!"
|
||||
done
|
||||
|
||||
# Start $rt_max_jobs rt encode jobs in parallel.
|
||||
for i in $(seq ${rt_max_jobs}); do
|
||||
bitrate=$(($i * 20 + 300))
|
||||
eval "${VPX_TEST_PREFIX}" "${encoder}" "--codec=${codec} -w 1280 -h 720" \
|
||||
"${YUV}" "-t ${threads} --limit=150 --test-decode=fatal " \
|
||||
"--target-bitrate=${bitrate} --lag-in-frames=0 --error-resilient=1" \
|
||||
"--kf-min-dist=3000 --kf-max-dist=3000 --cpu-used=-6 --static-thresh=1" \
|
||||
"--end-usage=cbr --min-q=2 --max-q=56 --undershoot-pct=100" \
|
||||
"--overshoot-pct=15 --buf-sz=1000 --buf-initial-sz=500" \
|
||||
"--buf-optimal-sz=600 --max-intra-rate=900 --resize-allowed=0" \
|
||||
"--drop-frame=0 --passes=1 --rt --noise-sensitivity=4" \
|
||||
"-o ${VPX_TEST_OUTPUT_DIR}/${i}.rt.webm" ${devnull} &
|
||||
pids="${pids} $!"
|
||||
done
|
||||
|
||||
# Start $decode_count decode jobs in parallel.
|
||||
for i in $(seq "${decode_count}"); do
|
||||
eval "${decoder}" "-t ${threads}" "${webm}" "--noblit" ${devnull} &
|
||||
pids="${pids} $!"
|
||||
done
|
||||
|
||||
# Wait for all parallel jobs to finish.
|
||||
fail=0
|
||||
for job in "${pids}"; do
|
||||
wait $job || fail=$(($fail + 1))
|
||||
done
|
||||
return $fail
|
||||
}
|
||||
|
||||
vp8_stress_test() {
|
||||
local vp8_max_jobs=${STRESS_VP8_DECODE_MAX_JOBS:-40}
|
||||
if [ "$(vp8_decode_available)" = "yes" -a \
|
||||
"$(vp8_encode_available)" = "yes" ]; then
|
||||
stress vp8 "${VP8}" "${vp8_max_jobs}" 4
|
||||
fi
|
||||
}
|
||||
|
||||
vp9_stress() {
|
||||
local vp9_max_jobs=${STRESS_VP9_DECODE_MAX_JOBS:-25}
|
||||
|
||||
if [ "$(vp9_decode_available)" = "yes" -a \
|
||||
"$(vp9_encode_available)" = "yes" ]; then
|
||||
stress vp9 "${VP9}" "${vp9_max_jobs}" "$@"
|
||||
fi
|
||||
}
|
||||
|
||||
vp9_stress_test() {
|
||||
for threads in 4 8 100; do
|
||||
vp9_stress "$threads" "--row-mt=0"
|
||||
done
|
||||
}
|
||||
|
||||
vp9_stress_test_row_mt() {
|
||||
for threads in 4 8 100; do
|
||||
vp9_stress "$threads" "--row-mt=1"
|
||||
done
|
||||
}
|
||||
|
||||
run_tests stress_verify_environment \
|
||||
"vp8_stress_test vp9_stress_test vp9_stress_test_row_mt"
|
@ -28,7 +28,7 @@ namespace {
|
||||
const int kNumIterations = 10000;
|
||||
|
||||
typedef uint64_t (*SSI16Func)(const int16_t *src, int stride, int size);
|
||||
typedef ::testing::tuple<SSI16Func, SSI16Func> SumSquaresParam;
|
||||
typedef std::tr1::tuple<SSI16Func, SSI16Func> SumSquaresParam;
|
||||
|
||||
class SumSquaresTest : public ::testing::TestWithParam<SumSquaresParam> {
|
||||
public:
|
||||
@ -102,7 +102,7 @@ TEST_P(SumSquaresTest, ExtremeValues) {
|
||||
}
|
||||
}
|
||||
|
||||
using ::testing::make_tuple;
|
||||
using std::tr1::make_tuple;
|
||||
|
||||
#if HAVE_SSE2
|
||||
INSTANTIATE_TEST_CASE_P(
|
||||
@ -110,11 +110,4 @@ INSTANTIATE_TEST_CASE_P(
|
||||
::testing::Values(make_tuple(&vpx_sum_squares_2d_i16_c,
|
||||
&vpx_sum_squares_2d_i16_sse2)));
|
||||
#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)));
|
||||
#endif // HAVE_MSA
|
||||
} // namespace
|
||||
|
@ -18,7 +18,7 @@ namespace {
|
||||
|
||||
const int kTestMode = 0;
|
||||
|
||||
typedef ::testing::tuple<libvpx_test::TestMode, int> SuperframeTestParam;
|
||||
typedef std::tr1::tuple<libvpx_test::TestMode, int> SuperframeTestParam;
|
||||
|
||||
class SuperframeTest
|
||||
: public ::libvpx_test::EncoderTest,
|
||||
@ -31,7 +31,7 @@ class SuperframeTest
|
||||
virtual void SetUp() {
|
||||
InitializeConfig();
|
||||
const SuperframeTestParam input = GET_PARAM(1);
|
||||
const libvpx_test::TestMode mode = ::testing::get<kTestMode>(input);
|
||||
const libvpx_test::TestMode mode = std::tr1::get<kTestMode>(input);
|
||||
SetMode(mode);
|
||||
sf_count_ = 0;
|
||||
sf_count_max_ = INT_MAX;
|
||||
|
File diff suppressed because it is too large
Load Diff
789
test/svc_test.cc
Normal file
789
test/svc_test.cc
Normal file
@ -0,0 +1,789 @@
|
||||
/*
|
||||
* Copyright (c) 2013 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 <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 "vp9/decoder/vp9_decoder.h"
|
||||
|
||||
#include "vpx/svc_context.h"
|
||||
#include "vpx/vp8cx.h"
|
||||
#include "vpx/vpx_encoder.h"
|
||||
|
||||
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_));
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Pass1EncodeNFrames(const int n, const int layers,
|
||||
std::string *const stats_buf) {
|
||||
vpx_codec_err_t res;
|
||||
|
||||
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 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 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;
|
||||
}
|
||||
}
|
||||
|
||||
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 = { 0 };
|
||||
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
|
@ -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
|
@ -20,10 +20,8 @@ LIBVPX_TEST_DATA-$(CONFIG_ENCODERS) += park_joy_90p_8_440.yuv
|
||||
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_ENCODER) += desktop_credits.y4m
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_ENCODER) += niklas_1280_720_30.y4m
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_ENCODER) += noisy_clip_640_360.y4m
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_ENCODER) += rush_hour_444.y4m
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_ENCODER) += screendata.y4m
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_ENCODER) += niklas_640_480_30.yuv
|
||||
|
||||
# Test vectors
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP8_DECODER) += vp80-00-comprehensive-001.ivf
|
||||
@ -732,10 +730,6 @@ LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp93-2-20-12bit-yuv444.webm.md5
|
||||
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_VP9_DECODER) += invalid-vp90-01-v3.webm
|
||||
@ -776,8 +770,6 @@ LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += invalid-vp90-2-12-droppable_1.ivf.s367
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += invalid-vp90-2-12-droppable_1.ivf.s3676_r01-05_b6-.ivf.res
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += invalid-vp90-2-12-droppable_1.ivf.s73804_r01-05_b6-.ivf
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += invalid-vp90-2-12-droppable_1.ivf.s73804_r01-05_b6-.ivf.res
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += invalid-vp90-2-21-resize_inter_320x180_5_3-4.webm.ivf.s45551_r01-05_b6-.ivf
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += invalid-vp90-2-21-resize_inter_320x180_5_3-4.webm.ivf.s45551_r01-05_b6-.ivf.res
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += invalid-vp91-2-mixedrefcsp-444to420.ivf
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += invalid-vp91-2-mixedrefcsp-444to420.ivf.res
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += invalid-vp90-2-07-frame_parallel-1.webm
|
||||
@ -821,6 +813,7 @@ LIBVPX_TEST_DATA-$(CONFIG_VP9_ENCODER) += kirland_640_480_30.yuv
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_ENCODER) += macmarcomoving_640_480_30.yuv
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_ENCODER) += macmarcostationary_640_480_30.yuv
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_ENCODER) += niklas_1280_720_30.yuv
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_ENCODER) += niklas_640_480_30.yuv
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_ENCODER) += tacomanarrows_640_480_30.yuv
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_ENCODER) += tacomasmallcameramovement_640_480_30.yuv
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_ENCODER) += thaloundeskmtg_640_480_30.yuv
|
||||
@ -880,5 +873,3 @@ LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-21-resize_inter_1920x1080_7_3-4
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-21-resize_inter_1920x1080_7_3-4.webm.md5
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-22-svc_1280x720_3.ivf
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-22-svc_1280x720_3.ivf.md5
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-22-svc_1280x720_1.webm
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-22-svc_1280x720_1.webm.md5
|
||||
|
@ -6,8 +6,6 @@ b87815bf86020c592ccc7a846ba2e28ec8043902 *hantro_odd.yuv
|
||||
456d1493e52d32a5c30edf44a27debc1fa6b253a *invalid-vp90-2-00-quantizer-11.webm.ivf.s52984_r01-05_b6-.ivf.res
|
||||
c123d1f9f02fb4143abb5e271916e3a3080de8f6 *invalid-vp90-2-00-quantizer-11.webm.ivf.s52984_r01-05_b6-z.ivf
|
||||
456d1493e52d32a5c30edf44a27debc1fa6b253a *invalid-vp90-2-00-quantizer-11.webm.ivf.s52984_r01-05_b6-z.ivf.res
|
||||
efafb92b7567bc04c3f1432ea6c268c1c31affd5 *invalid-vp90-2-21-resize_inter_320x180_5_3-4.webm.ivf.s45551_r01-05_b6-.ivf
|
||||
5d9474c0309b7ca09a182d888f73b37a8fe1362c *invalid-vp90-2-21-resize_inter_320x180_5_3-4.webm.ivf.s45551_r01-05_b6-.ivf.res
|
||||
fe346136b9b8c1e6f6084cc106485706915795e4 *invalid-vp90-01-v3.webm
|
||||
5d9474c0309b7ca09a182d888f73b37a8fe1362c *invalid-vp90-01-v3.webm.res
|
||||
d78e2fceba5ac942246503ec8366f879c4775ca5 *invalid-vp90-02-v2.webm
|
||||
@ -16,7 +14,6 @@ df1a1453feb3c00d7d89746c7003b4163523bff3 *invalid-vp90-03-v3.webm
|
||||
4935c62becc68c13642a03db1e6d3e2331c1c612 *invalid-vp90-03-v3.webm.res
|
||||
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
|
||||
@ -847,12 +844,5 @@ a000d568431d07379dd5a8ec066061c07e560b47 *invalid-vp90-2-00-quantizer-63.ivf.kf_
|
||||
5d9474c0309b7ca09a182d888f73b37a8fe1362c *invalid-crbug-629481.webm.res
|
||||
7602e00378161ca36ae93cc6ee12dd30b5ba1e1d *vp90-2-22-svc_1280x720_3.ivf
|
||||
02e53e3eefbf25ec0929047fe50876acdeb040bd *vp90-2-22-svc_1280x720_3.ivf.md5
|
||||
6fa3d3ac306a3d9ce1d610b78441dc00d2c2d4b9 *tos_vp8.webm
|
||||
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
|
||||
|
21
test/test.mk
21
test/test.mk
@ -1,5 +1,4 @@
|
||||
LIBVPX_TEST_SRCS-yes += acm_random.h
|
||||
LIBVPX_TEST_SRCS-yes += buffer.h
|
||||
LIBVPX_TEST_SRCS-yes += clear_system_state.h
|
||||
LIBVPX_TEST_SRCS-yes += codec_factory.h
|
||||
LIBVPX_TEST_SRCS-yes += md5_helper.h
|
||||
@ -22,9 +21,7 @@ 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) += vp8_datarate_test.cc
|
||||
LIBVPX_TEST_SRCS-$(CONFIG_ENCODERS) += vp9_datarate_test.cc
|
||||
LIBVPX_TEST_SRCS-$(CONFIG_ENCODERS) += svc_datarate_test.cc
|
||||
LIBVPX_TEST_SRCS-$(CONFIG_ENCODERS) += 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
|
||||
@ -41,6 +38,7 @@ LIBVPX_TEST_SRCS-$(CONFIG_VP9_DECODER) += byte_alignment_test.cc
|
||||
LIBVPX_TEST_SRCS-$(CONFIG_VP9_DECODER) += decode_svc_test.cc
|
||||
LIBVPX_TEST_SRCS-$(CONFIG_VP9_DECODER) += external_frame_buffer_test.cc
|
||||
LIBVPX_TEST_SRCS-$(CONFIG_VP9_DECODER) += user_priv_test.cc
|
||||
LIBVPX_TEST_SRCS-$(CONFIG_VP9_DECODER) += vp9_frame_parallel_test.cc
|
||||
LIBVPX_TEST_SRCS-$(CONFIG_VP9_ENCODER) += active_map_refresh_test.cc
|
||||
LIBVPX_TEST_SRCS-$(CONFIG_VP9_ENCODER) += active_map_test.cc
|
||||
LIBVPX_TEST_SRCS-$(CONFIG_VP9_ENCODER) += borders_test.cc
|
||||
@ -49,7 +47,6 @@ 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) += 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-yes += decode_test_driver.cc
|
||||
@ -125,7 +122,6 @@ LIBVPX_TEST_SRCS-$(CONFIG_VP8_ENCODER) += vp8_fdct4x4_test.cc
|
||||
LIBVPX_TEST_SRCS-yes += idct_test.cc
|
||||
LIBVPX_TEST_SRCS-yes += predict_test.cc
|
||||
LIBVPX_TEST_SRCS-yes += vpx_scale_test.cc
|
||||
LIBVPX_TEST_SRCS-yes += vpx_scale_test.h
|
||||
|
||||
ifeq ($(CONFIG_VP8_ENCODER)$(CONFIG_TEMPORAL_DENOISING),yesyes)
|
||||
LIBVPX_TEST_SRCS-$(HAVE_SSE2) += vp8_denoiser_sse2_test.cc
|
||||
@ -153,30 +149,25 @@ LIBVPX_TEST_SRCS-yes += vp9_intrapred_test.cc
|
||||
LIBVPX_TEST_SRCS-$(CONFIG_VP9_DECODER) += vp9_decrypt_test.cc
|
||||
LIBVPX_TEST_SRCS-$(CONFIG_VP9_DECODER) += vp9_thread_test.cc
|
||||
LIBVPX_TEST_SRCS-$(CONFIG_VP9_ENCODER) += avg_test.cc
|
||||
LIBVPX_TEST_SRCS-$(CONFIG_VP9_ENCODER) += comp_avg_pred_test.cc
|
||||
LIBVPX_TEST_SRCS-$(CONFIG_VP9_ENCODER) += dct16x16_test.cc
|
||||
LIBVPX_TEST_SRCS-$(CONFIG_VP9_ENCODER) += dct32x32_test.cc
|
||||
LIBVPX_TEST_SRCS-$(CONFIG_VP9_ENCODER) += dct_partial_test.cc
|
||||
LIBVPX_TEST_SRCS-$(CONFIG_VP9_ENCODER) += dct_test.cc
|
||||
LIBVPX_TEST_SRCS-$(CONFIG_VP9_ENCODER) += fdct4x4_test.cc
|
||||
LIBVPX_TEST_SRCS-$(CONFIG_VP9_ENCODER) += fdct8x8_test.cc
|
||||
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
|
||||
endif
|
||||
LIBVPX_TEST_SRCS-$(CONFIG_VP9_ENCODER) += variance_test.cc
|
||||
LIBVPX_TEST_SRCS-$(CONFIG_VP9_ENCODER) += vp9_block_error_test.cc
|
||||
LIBVPX_TEST_SRCS-$(CONFIG_VP9_ENCODER) += vp9_error_block_test.cc
|
||||
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
|
||||
|
||||
ifeq ($(CONFIG_VP9_ENCODER)$(CONFIG_VP9_TEMPORAL_DENOISING),yesyes)
|
||||
LIBVPX_TEST_SRCS-yes += vp9_denoiser_test.cc
|
||||
LIBVPX_TEST_SRCS-$(HAVE_SSE2) += vp9_denoiser_sse2_test.cc
|
||||
endif
|
||||
LIBVPX_TEST_SRCS-$(CONFIG_VP9_ENCODER) += vp9_arf_freq_test.cc
|
||||
|
||||
|
@ -270,22 +270,19 @@ INTRA_PRED_TEST(NEON, TestIntraPred4, vpx_dc_predictor_4x4_neon,
|
||||
INTRA_PRED_TEST(NEON, TestIntraPred8, vpx_dc_predictor_8x8_neon,
|
||||
vpx_dc_left_predictor_8x8_neon, vpx_dc_top_predictor_8x8_neon,
|
||||
vpx_dc_128_predictor_8x8_neon, vpx_v_predictor_8x8_neon,
|
||||
vpx_h_predictor_8x8_neon, vpx_d45_predictor_8x8_neon,
|
||||
vpx_d135_predictor_8x8_neon, NULL, NULL, NULL, NULL,
|
||||
vpx_tm_predictor_8x8_neon)
|
||||
vpx_h_predictor_8x8_neon, vpx_d45_predictor_8x8_neon, NULL,
|
||||
NULL, NULL, NULL, NULL, vpx_tm_predictor_8x8_neon)
|
||||
INTRA_PRED_TEST(NEON, TestIntraPred16, vpx_dc_predictor_16x16_neon,
|
||||
vpx_dc_left_predictor_16x16_neon,
|
||||
vpx_dc_top_predictor_16x16_neon,
|
||||
vpx_dc_128_predictor_16x16_neon, vpx_v_predictor_16x16_neon,
|
||||
vpx_h_predictor_16x16_neon, vpx_d45_predictor_16x16_neon,
|
||||
vpx_d135_predictor_16x16_neon, NULL, NULL, NULL, NULL,
|
||||
vpx_tm_predictor_16x16_neon)
|
||||
vpx_h_predictor_16x16_neon, vpx_d45_predictor_16x16_neon, NULL,
|
||||
NULL, NULL, NULL, NULL, vpx_tm_predictor_16x16_neon)
|
||||
INTRA_PRED_TEST(NEON, TestIntraPred32, vpx_dc_predictor_32x32_neon,
|
||||
vpx_dc_left_predictor_32x32_neon,
|
||||
vpx_dc_top_predictor_32x32_neon,
|
||||
vpx_dc_128_predictor_32x32_neon, vpx_v_predictor_32x32_neon,
|
||||
vpx_h_predictor_32x32_neon, vpx_d45_predictor_32x32_neon,
|
||||
vpx_d135_predictor_32x32_neon, NULL, NULL, NULL, NULL,
|
||||
vpx_h_predictor_32x32_neon, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
vpx_tm_predictor_32x32_neon)
|
||||
#endif // HAVE_NEON
|
||||
|
||||
@ -312,31 +309,6 @@ INTRA_PRED_TEST(MSA, TestIntraPred32, vpx_dc_predictor_32x32_msa,
|
||||
vpx_tm_predictor_32x32_msa)
|
||||
#endif // HAVE_MSA
|
||||
|
||||
#if HAVE_VSX
|
||||
INTRA_PRED_TEST(VSX, TestIntraPred4, NULL, NULL, NULL, NULL, NULL,
|
||||
vpx_h_predictor_4x4_vsx, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
vpx_tm_predictor_4x4_vsx)
|
||||
|
||||
INTRA_PRED_TEST(VSX, TestIntraPred8, vpx_dc_predictor_8x8_vsx, NULL, NULL, NULL,
|
||||
NULL, vpx_h_predictor_8x8_vsx, vpx_d45_predictor_8x8_vsx, NULL,
|
||||
NULL, NULL, NULL, vpx_d63_predictor_8x8_vsx,
|
||||
vpx_tm_predictor_8x8_vsx)
|
||||
|
||||
INTRA_PRED_TEST(VSX, TestIntraPred16, vpx_dc_predictor_16x16_vsx,
|
||||
vpx_dc_left_predictor_16x16_vsx, vpx_dc_top_predictor_16x16_vsx,
|
||||
vpx_dc_128_predictor_16x16_vsx, vpx_v_predictor_16x16_vsx,
|
||||
vpx_h_predictor_16x16_vsx, vpx_d45_predictor_16x16_vsx, NULL,
|
||||
NULL, NULL, NULL, vpx_d63_predictor_16x16_vsx,
|
||||
vpx_tm_predictor_16x16_vsx)
|
||||
|
||||
INTRA_PRED_TEST(VSX, TestIntraPred32, vpx_dc_predictor_32x32_vsx,
|
||||
vpx_dc_left_predictor_32x32_vsx, vpx_dc_top_predictor_32x32_vsx,
|
||||
vpx_dc_128_predictor_32x32_vsx, vpx_v_predictor_32x32_vsx,
|
||||
vpx_h_predictor_32x32_vsx, vpx_d45_predictor_32x32_vsx, NULL,
|
||||
NULL, NULL, NULL, vpx_d63_predictor_32x32_vsx,
|
||||
vpx_tm_predictor_32x32_vsx)
|
||||
#endif // HAVE_VSX
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
#if CONFIG_VP9_HIGHBITDEPTH
|
||||
@ -480,107 +452,29 @@ HIGHBD_INTRA_PRED_TEST(
|
||||
vpx_highbd_d63_predictor_32x32_c, vpx_highbd_tm_predictor_32x32_c)
|
||||
|
||||
#if HAVE_SSE2
|
||||
HIGHBD_INTRA_PRED_TEST(
|
||||
SSE2, TestHighbdIntraPred4, vpx_highbd_dc_predictor_4x4_sse2,
|
||||
vpx_highbd_dc_left_predictor_4x4_sse2, vpx_highbd_dc_top_predictor_4x4_sse2,
|
||||
vpx_highbd_dc_128_predictor_4x4_sse2, vpx_highbd_v_predictor_4x4_sse2,
|
||||
vpx_highbd_h_predictor_4x4_sse2, NULL, vpx_highbd_d135_predictor_4x4_sse2,
|
||||
vpx_highbd_d117_predictor_4x4_sse2, vpx_highbd_d153_predictor_4x4_sse2,
|
||||
vpx_highbd_d207_predictor_4x4_sse2, vpx_highbd_d63_predictor_4x4_sse2,
|
||||
vpx_highbd_tm_predictor_4x4_c)
|
||||
HIGHBD_INTRA_PRED_TEST(SSE2, TestHighbdIntraPred4,
|
||||
vpx_highbd_dc_predictor_4x4_sse2, NULL, NULL, NULL,
|
||||
vpx_highbd_v_predictor_4x4_sse2, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, vpx_highbd_tm_predictor_4x4_c)
|
||||
|
||||
HIGHBD_INTRA_PRED_TEST(SSE2, TestHighbdIntraPred8,
|
||||
vpx_highbd_dc_predictor_8x8_sse2,
|
||||
vpx_highbd_dc_left_predictor_8x8_sse2,
|
||||
vpx_highbd_dc_top_predictor_8x8_sse2,
|
||||
vpx_highbd_dc_128_predictor_8x8_sse2,
|
||||
vpx_highbd_v_predictor_8x8_sse2,
|
||||
vpx_highbd_h_predictor_8x8_sse2, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, vpx_highbd_tm_predictor_8x8_sse2)
|
||||
vpx_highbd_dc_predictor_8x8_sse2, NULL, NULL, NULL,
|
||||
vpx_highbd_v_predictor_8x8_sse2, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, vpx_highbd_tm_predictor_8x8_sse2)
|
||||
|
||||
HIGHBD_INTRA_PRED_TEST(SSE2, TestHighbdIntraPred16,
|
||||
vpx_highbd_dc_predictor_16x16_sse2,
|
||||
vpx_highbd_dc_left_predictor_16x16_sse2,
|
||||
vpx_highbd_dc_top_predictor_16x16_sse2,
|
||||
vpx_highbd_dc_128_predictor_16x16_sse2,
|
||||
vpx_highbd_v_predictor_16x16_sse2,
|
||||
vpx_highbd_h_predictor_16x16_sse2, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, vpx_highbd_tm_predictor_16x16_sse2)
|
||||
vpx_highbd_dc_predictor_16x16_sse2, NULL, NULL, NULL,
|
||||
vpx_highbd_v_predictor_16x16_sse2, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL,
|
||||
vpx_highbd_tm_predictor_16x16_sse2)
|
||||
|
||||
HIGHBD_INTRA_PRED_TEST(SSE2, TestHighbdIntraPred32,
|
||||
vpx_highbd_dc_predictor_32x32_sse2,
|
||||
vpx_highbd_dc_left_predictor_32x32_sse2,
|
||||
vpx_highbd_dc_top_predictor_32x32_sse2,
|
||||
vpx_highbd_dc_128_predictor_32x32_sse2,
|
||||
vpx_highbd_v_predictor_32x32_sse2,
|
||||
vpx_highbd_h_predictor_32x32_sse2, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, vpx_highbd_tm_predictor_32x32_sse2)
|
||||
vpx_highbd_dc_predictor_32x32_sse2, NULL, NULL, NULL,
|
||||
vpx_highbd_v_predictor_32x32_sse2, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL,
|
||||
vpx_highbd_tm_predictor_32x32_sse2)
|
||||
#endif // HAVE_SSE2
|
||||
|
||||
#if HAVE_SSSE3
|
||||
HIGHBD_INTRA_PRED_TEST(SSSE3, TestHighbdIntraPred4, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, vpx_highbd_d45_predictor_4x4_ssse3, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL)
|
||||
HIGHBD_INTRA_PRED_TEST(SSSE3, TestHighbdIntraPred8, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, vpx_highbd_d45_predictor_8x8_ssse3,
|
||||
vpx_highbd_d135_predictor_8x8_ssse3,
|
||||
vpx_highbd_d117_predictor_8x8_ssse3,
|
||||
vpx_highbd_d153_predictor_8x8_ssse3,
|
||||
vpx_highbd_d207_predictor_8x8_ssse3,
|
||||
vpx_highbd_d63_predictor_8x8_ssse3, NULL)
|
||||
HIGHBD_INTRA_PRED_TEST(SSSE3, TestHighbdIntraPred16, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, vpx_highbd_d45_predictor_16x16_ssse3,
|
||||
vpx_highbd_d135_predictor_16x16_ssse3,
|
||||
vpx_highbd_d117_predictor_16x16_ssse3,
|
||||
vpx_highbd_d153_predictor_16x16_ssse3,
|
||||
vpx_highbd_d207_predictor_16x16_ssse3,
|
||||
vpx_highbd_d63_predictor_16x16_ssse3, NULL)
|
||||
HIGHBD_INTRA_PRED_TEST(SSSE3, TestHighbdIntraPred32, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, vpx_highbd_d45_predictor_32x32_ssse3,
|
||||
vpx_highbd_d135_predictor_32x32_ssse3,
|
||||
vpx_highbd_d117_predictor_32x32_ssse3,
|
||||
vpx_highbd_d153_predictor_32x32_ssse3,
|
||||
vpx_highbd_d207_predictor_32x32_ssse3,
|
||||
vpx_highbd_d63_predictor_32x32_ssse3, NULL)
|
||||
#endif // HAVE_SSSE3
|
||||
|
||||
#if HAVE_NEON
|
||||
HIGHBD_INTRA_PRED_TEST(
|
||||
NEON, TestHighbdIntraPred4, vpx_highbd_dc_predictor_4x4_neon,
|
||||
vpx_highbd_dc_left_predictor_4x4_neon, vpx_highbd_dc_top_predictor_4x4_neon,
|
||||
vpx_highbd_dc_128_predictor_4x4_neon, vpx_highbd_v_predictor_4x4_neon,
|
||||
vpx_highbd_h_predictor_4x4_neon, vpx_highbd_d45_predictor_4x4_neon,
|
||||
vpx_highbd_d135_predictor_4x4_neon, NULL, NULL, NULL, NULL,
|
||||
vpx_highbd_tm_predictor_4x4_neon)
|
||||
HIGHBD_INTRA_PRED_TEST(
|
||||
NEON, TestHighbdIntraPred8, vpx_highbd_dc_predictor_8x8_neon,
|
||||
vpx_highbd_dc_left_predictor_8x8_neon, vpx_highbd_dc_top_predictor_8x8_neon,
|
||||
vpx_highbd_dc_128_predictor_8x8_neon, vpx_highbd_v_predictor_8x8_neon,
|
||||
vpx_highbd_h_predictor_8x8_neon, vpx_highbd_d45_predictor_8x8_neon,
|
||||
vpx_highbd_d135_predictor_8x8_neon, NULL, NULL, NULL, NULL,
|
||||
vpx_highbd_tm_predictor_8x8_neon)
|
||||
HIGHBD_INTRA_PRED_TEST(NEON, TestHighbdIntraPred16,
|
||||
vpx_highbd_dc_predictor_16x16_neon,
|
||||
vpx_highbd_dc_left_predictor_16x16_neon,
|
||||
vpx_highbd_dc_top_predictor_16x16_neon,
|
||||
vpx_highbd_dc_128_predictor_16x16_neon,
|
||||
vpx_highbd_v_predictor_16x16_neon,
|
||||
vpx_highbd_h_predictor_16x16_neon,
|
||||
vpx_highbd_d45_predictor_16x16_neon,
|
||||
vpx_highbd_d135_predictor_16x16_neon, NULL, NULL, NULL,
|
||||
NULL, vpx_highbd_tm_predictor_16x16_neon)
|
||||
HIGHBD_INTRA_PRED_TEST(NEON, TestHighbdIntraPred32,
|
||||
vpx_highbd_dc_predictor_32x32_neon,
|
||||
vpx_highbd_dc_left_predictor_32x32_neon,
|
||||
vpx_highbd_dc_top_predictor_32x32_neon,
|
||||
vpx_highbd_dc_128_predictor_32x32_neon,
|
||||
vpx_highbd_v_predictor_32x32_neon,
|
||||
vpx_highbd_h_predictor_32x32_neon,
|
||||
vpx_highbd_d45_predictor_32x32_neon,
|
||||
vpx_highbd_d135_predictor_32x32_neon, NULL, NULL, NULL,
|
||||
NULL, vpx_highbd_tm_predictor_32x32_neon)
|
||||
#endif // HAVE_NEON
|
||||
|
||||
#endif // CONFIG_VP9_HIGHBITDEPTH
|
||||
|
||||
#include "test/test_libvpx.cc"
|
||||
|
@ -53,14 +53,12 @@ int main(int argc, char **argv) {
|
||||
}
|
||||
if (!(simd_caps & HAS_AVX)) append_negative_gtest_filter(":AVX.*:AVX/*");
|
||||
if (!(simd_caps & HAS_AVX2)) append_negative_gtest_filter(":AVX2.*:AVX2/*");
|
||||
if (!(simd_caps & HAS_AVX512)) {
|
||||
append_negative_gtest_filter(":AVX512.*:AVX512/*");
|
||||
}
|
||||
#endif // ARCH_X86 || ARCH_X86_64
|
||||
|
||||
#if !CONFIG_SHARED
|
||||
// Shared library builds don't support whitebox tests
|
||||
// that exercise internal symbols.
|
||||
|
||||
#if CONFIG_VP8
|
||||
vp8_rtcd();
|
||||
#endif // CONFIG_VP8
|
||||
|
@ -28,10 +28,13 @@
|
||||
|
||||
namespace {
|
||||
|
||||
const int kThreads = 0;
|
||||
const int kFileName = 1;
|
||||
enum DecodeMode { kSerialMode, kFrameParallelMode };
|
||||
|
||||
typedef ::testing::tuple<int, const char *> DecodeParam;
|
||||
const int kDecodeMode = 0;
|
||||
const int kThreads = 1;
|
||||
const int kFileName = 2;
|
||||
|
||||
typedef std::tr1::tuple<int, int, const char *> DecodeParam;
|
||||
|
||||
class TestVectorTest : public ::libvpx_test::DecoderTest,
|
||||
public ::libvpx_test::CodecTestWithParam<DecodeParam> {
|
||||
@ -50,8 +53,8 @@ class TestVectorTest : public ::libvpx_test::DecoderTest,
|
||||
|
||||
void OpenMD5File(const std::string &md5_file_name_) {
|
||||
md5_file_ = libvpx_test::OpenTestDataFile(md5_file_name_);
|
||||
ASSERT_TRUE(md5_file_ != NULL)
|
||||
<< "Md5 file open failed. Filename: " << md5_file_name_;
|
||||
ASSERT_TRUE(md5_file_ != NULL) << "Md5 file open failed. Filename: "
|
||||
<< md5_file_name_;
|
||||
}
|
||||
|
||||
virtual void DecompressedFrameHook(const vpx_image_t &img,
|
||||
@ -88,15 +91,30 @@ class TestVectorTest : public ::libvpx_test::DecoderTest,
|
||||
// the test failed.
|
||||
TEST_P(TestVectorTest, MD5Match) {
|
||||
const DecodeParam input = GET_PARAM(1);
|
||||
const std::string filename = ::testing::get<kFileName>(input);
|
||||
const std::string filename = std::tr1::get<kFileName>(input);
|
||||
const int threads = std::tr1::get<kThreads>(input);
|
||||
const int mode = std::tr1::get<kDecodeMode>(input);
|
||||
vpx_codec_flags_t flags = 0;
|
||||
vpx_codec_dec_cfg_t cfg = vpx_codec_dec_cfg_t();
|
||||
char str[256];
|
||||
|
||||
cfg.threads = ::testing::get<kThreads>(input);
|
||||
if (mode == kFrameParallelMode) {
|
||||
flags |= VPX_CODEC_USE_FRAME_THREADING;
|
||||
#if CONFIG_VP9_DECODER
|
||||
// TODO(hkuang): Fix frame parallel decode bug. See issue 1086.
|
||||
if (resize_clips_.find(filename) != resize_clips_.end()) {
|
||||
printf("Skipping the test file: %s, due to frame parallel decode bug.\n",
|
||||
filename.c_str());
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
snprintf(str, sizeof(str) / sizeof(str[0]) - 1, "file: %s threads: %d",
|
||||
filename.c_str(), cfg.threads);
|
||||
cfg.threads = threads;
|
||||
|
||||
snprintf(str, sizeof(str) / sizeof(str[0]) - 1,
|
||||
"file: %s mode: %s threads: %d", filename.c_str(),
|
||||
mode == 0 ? "Serial" : "Parallel", threads);
|
||||
SCOPED_TRACE(str);
|
||||
|
||||
// Open compressed video file.
|
||||
@ -127,44 +145,38 @@ TEST_P(TestVectorTest, MD5Match) {
|
||||
ASSERT_NO_FATAL_FAILURE(RunLoop(video.get(), cfg));
|
||||
}
|
||||
|
||||
// Test VP8 decode in serial mode with single thread.
|
||||
// NOTE: VP8 only support serial mode.
|
||||
#if CONFIG_VP8_DECODER
|
||||
VP8_INSTANTIATE_TEST_CASE(
|
||||
TestVectorTest,
|
||||
::testing::Combine(
|
||||
::testing::Values(0), // Serial Mode.
|
||||
::testing::Values(1), // Single thread.
|
||||
::testing::ValuesIn(libvpx_test::kVP8TestVectors,
|
||||
libvpx_test::kVP8TestVectors +
|
||||
libvpx_test::kNumVP8TestVectors)));
|
||||
|
||||
// Test VP8 decode in with different numbers of threads.
|
||||
INSTANTIATE_TEST_CASE_P(
|
||||
VP8MultiThreaded, TestVectorTest,
|
||||
::testing::Combine(
|
||||
::testing::Values(
|
||||
static_cast<const libvpx_test::CodecFactory *>(&libvpx_test::kVP8)),
|
||||
::testing::Combine(
|
||||
::testing::Range(2, 9), // With 2 ~ 8 threads.
|
||||
::testing::ValuesIn(libvpx_test::kVP8TestVectors,
|
||||
libvpx_test::kVP8TestVectors +
|
||||
libvpx_test::kNumVP8TestVectors))));
|
||||
|
||||
#endif // CONFIG_VP8_DECODER
|
||||
|
||||
// Test VP9 decode in serial mode with single thread.
|
||||
#if CONFIG_VP9_DECODER
|
||||
VP9_INSTANTIATE_TEST_CASE(
|
||||
TestVectorTest,
|
||||
::testing::Combine(
|
||||
::testing::Values(0), // Serial Mode.
|
||||
::testing::Values(1), // Single thread.
|
||||
::testing::ValuesIn(libvpx_test::kVP9TestVectors,
|
||||
libvpx_test::kVP9TestVectors +
|
||||
libvpx_test::kNumVP9TestVectors)));
|
||||
|
||||
// Test VP9 decode in frame parallel mode with different number of threads.
|
||||
INSTANTIATE_TEST_CASE_P(
|
||||
VP9MultiThreaded, TestVectorTest,
|
||||
VP9MultiThreadedFrameParallel, TestVectorTest,
|
||||
::testing::Combine(
|
||||
::testing::Values(
|
||||
static_cast<const libvpx_test::CodecFactory *>(&libvpx_test::kVP9)),
|
||||
::testing::Combine(
|
||||
::testing::Values(1), // Frame Parallel mode.
|
||||
::testing::Range(2, 9), // With 2 ~ 8 threads.
|
||||
::testing::ValuesIn(libvpx_test::kVP9TestVectors,
|
||||
libvpx_test::kVP9TestVectors +
|
||||
|
@ -371,7 +371,6 @@ const char *const kVP9TestVectors[] = {
|
||||
#endif // CONFIG_VP9_HIGHBITDEPTH
|
||||
"vp90-2-20-big_superframe-01.webm",
|
||||
"vp90-2-20-big_superframe-02.webm",
|
||||
"vp90-2-22-svc_1280x720_1.webm",
|
||||
RESIZE_TEST_VECTORS
|
||||
};
|
||||
const char *const kVP9TestVectorsSvc[] = { "vp90-2-22-svc_1280x720_3.ivf" };
|
||||
|
@ -54,10 +54,7 @@ twopass_encoder_vp9() {
|
||||
fi
|
||||
}
|
||||
|
||||
twopass_encoder_tests="twopass_encoder_vp8
|
||||
twopass_encoder_vp9"
|
||||
|
||||
if [ "$(vpx_config_option_enabled CONFIG_REALTIME_ONLY)" != "yes" ]; then
|
||||
twopass_encoder_tests="twopass_encoder_vp8
|
||||
twopass_encoder_vp9"
|
||||
|
||||
run_tests twopass_encoder_verify_environment "${twopass_encoder_tests}"
|
||||
fi
|
||||
run_tests twopass_encoder_verify_environment "${twopass_encoder_tests}"
|
||||
|
@ -27,8 +27,8 @@
|
||||
|
||||
namespace {
|
||||
|
||||
using libvpx_test::ACMRandom;
|
||||
using std::string;
|
||||
using libvpx_test::ACMRandom;
|
||||
|
||||
#if CONFIG_WEBM_IO
|
||||
|
||||
|
@ -17,7 +17,7 @@
|
||||
#include "vpx/vpx_image.h"
|
||||
|
||||
// Macros
|
||||
#define GET_PARAM(k) ::testing::get<k>(GetParam())
|
||||
#define GET_PARAM(k) std::tr1::get<k>(GetParam())
|
||||
|
||||
inline double compute_psnr(const vpx_image_t *img1, const vpx_image_t *img2) {
|
||||
assert((img1->fmt == img2->fmt) && (img1->d_w == img2->d_w) &&
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -13,9 +13,7 @@
|
||||
#if defined(_WIN32)
|
||||
#undef NOMINMAX
|
||||
#define NOMINMAX
|
||||
#ifndef WIN32_LEAN_AND_MEAN
|
||||
#define WIN32_LEAN_AND_MEAN
|
||||
#endif
|
||||
#include <windows.h>
|
||||
#endif
|
||||
#include <cstdio>
|
||||
|
@ -1,513 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2012 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/util.h"
|
||||
#include "test/y4m_video_source.h"
|
||||
#include "vpx/vpx_codec.h"
|
||||
|
||||
namespace {
|
||||
|
||||
class DatarateTestLarge
|
||||
: public ::libvpx_test::EncoderTest,
|
||||
public ::libvpx_test::CodecTestWith2Params<libvpx_test::TestMode, int> {
|
||||
public:
|
||||
DatarateTestLarge() : EncoderTest(GET_PARAM(0)) {}
|
||||
|
||||
virtual ~DatarateTestLarge() {}
|
||||
|
||||
protected:
|
||||
virtual void SetUp() {
|
||||
InitializeConfig();
|
||||
SetMode(GET_PARAM(1));
|
||||
set_cpu_used_ = GET_PARAM(2);
|
||||
ResetModel();
|
||||
}
|
||||
|
||||
virtual void ResetModel() {
|
||||
last_pts_ = 0;
|
||||
bits_in_buffer_model_ = cfg_.rc_target_bitrate * cfg_.rc_buf_initial_sz;
|
||||
frame_number_ = 0;
|
||||
first_drop_ = 0;
|
||||
bits_total_ = 0;
|
||||
duration_ = 0.0;
|
||||
denoiser_offon_test_ = 0;
|
||||
denoiser_offon_period_ = -1;
|
||||
gf_boost_ = 0;
|
||||
use_roi_ = false;
|
||||
}
|
||||
|
||||
virtual void PreEncodeFrameHook(::libvpx_test::VideoSource *video,
|
||||
::libvpx_test::Encoder *encoder) {
|
||||
if (video->frame() == 0) {
|
||||
encoder->Control(VP8E_SET_NOISE_SENSITIVITY, denoiser_on_);
|
||||
encoder->Control(VP8E_SET_CPUUSED, set_cpu_used_);
|
||||
encoder->Control(VP8E_SET_GF_CBR_BOOST_PCT, gf_boost_);
|
||||
}
|
||||
|
||||
if (use_roi_) {
|
||||
encoder->Control(VP8E_SET_ROI_MAP, &roi_);
|
||||
}
|
||||
|
||||
if (denoiser_offon_test_) {
|
||||
ASSERT_GT(denoiser_offon_period_, 0)
|
||||
<< "denoiser_offon_period_ is not positive.";
|
||||
if ((video->frame() + 1) % denoiser_offon_period_ == 0) {
|
||||
// Flip denoiser_on_ periodically
|
||||
denoiser_on_ ^= 1;
|
||||
}
|
||||
encoder->Control(VP8E_SET_NOISE_SENSITIVITY, denoiser_on_);
|
||||
}
|
||||
|
||||
const vpx_rational_t tb = video->timebase();
|
||||
timebase_ = static_cast<double>(tb.num) / tb.den;
|
||||
duration_ = 0;
|
||||
}
|
||||
|
||||
virtual void FramePktHook(const vpx_codec_cx_pkt_t *pkt) {
|
||||
// Time since last timestamp = duration.
|
||||
vpx_codec_pts_t duration = pkt->data.frame.pts - last_pts_;
|
||||
|
||||
// TODO(jimbankoski): Remove these lines when the issue:
|
||||
// http://code.google.com/p/webm/issues/detail?id=496 is fixed.
|
||||
// For now the codec assumes buffer starts at starting buffer rate
|
||||
// plus one frame's time.
|
||||
if (last_pts_ == 0) duration = 1;
|
||||
|
||||
// Add to the buffer the bits we'd expect from a constant bitrate server.
|
||||
bits_in_buffer_model_ += static_cast<int64_t>(
|
||||
duration * timebase_ * cfg_.rc_target_bitrate * 1000);
|
||||
|
||||
/* Test the buffer model here before subtracting the frame. Do so because
|
||||
* the way the leaky bucket model works in libvpx is to allow the buffer to
|
||||
* empty - and then stop showing frames until we've got enough bits to
|
||||
* show one. As noted in comment below (issue 495), this does not currently
|
||||
* apply to key frames. For now exclude key frames in condition below. */
|
||||
const bool key_frame =
|
||||
(pkt->data.frame.flags & VPX_FRAME_IS_KEY) ? true : false;
|
||||
if (!key_frame) {
|
||||
ASSERT_GE(bits_in_buffer_model_, 0)
|
||||
<< "Buffer Underrun at frame " << pkt->data.frame.pts;
|
||||
}
|
||||
|
||||
const int64_t frame_size_in_bits = pkt->data.frame.sz * 8;
|
||||
|
||||
// Subtract from the buffer the bits associated with a played back frame.
|
||||
bits_in_buffer_model_ -= frame_size_in_bits;
|
||||
|
||||
// Update the running total of bits for end of test datarate checks.
|
||||
bits_total_ += frame_size_in_bits;
|
||||
|
||||
// If first drop not set and we have a drop set it to this time.
|
||||
if (!first_drop_ && duration > 1) first_drop_ = last_pts_ + 1;
|
||||
|
||||
// Update the most recent pts.
|
||||
last_pts_ = pkt->data.frame.pts;
|
||||
|
||||
// We update this so that we can calculate the datarate minus the last
|
||||
// frame encoded in the file.
|
||||
bits_in_last_frame_ = frame_size_in_bits;
|
||||
|
||||
++frame_number_;
|
||||
}
|
||||
|
||||
virtual void EndPassHook(void) {
|
||||
if (bits_total_) {
|
||||
const double file_size_in_kb = bits_total_ / 1000.; // bits per kilobit
|
||||
|
||||
duration_ = (last_pts_ + 1) * timebase_;
|
||||
|
||||
// Effective file datarate includes the time spent prebuffering.
|
||||
effective_datarate_ = (bits_total_ - bits_in_last_frame_) / 1000.0 /
|
||||
(cfg_.rc_buf_initial_sz / 1000.0 + duration_);
|
||||
|
||||
file_datarate_ = file_size_in_kb / duration_;
|
||||
}
|
||||
}
|
||||
|
||||
vpx_codec_pts_t last_pts_;
|
||||
int64_t bits_in_buffer_model_;
|
||||
double timebase_;
|
||||
int frame_number_;
|
||||
vpx_codec_pts_t first_drop_;
|
||||
int64_t bits_total_;
|
||||
double duration_;
|
||||
double file_datarate_;
|
||||
double effective_datarate_;
|
||||
int64_t bits_in_last_frame_;
|
||||
int denoiser_on_;
|
||||
int denoiser_offon_test_;
|
||||
int denoiser_offon_period_;
|
||||
int set_cpu_used_;
|
||||
int gf_boost_;
|
||||
bool use_roi_;
|
||||
vpx_roi_map_t roi_;
|
||||
};
|
||||
|
||||
#if CONFIG_TEMPORAL_DENOISING
|
||||
// Check basic datarate targeting, for a single bitrate, but loop over the
|
||||
// various denoiser settings.
|
||||
TEST_P(DatarateTestLarge, DenoiserLevels) {
|
||||
cfg_.rc_buf_initial_sz = 500;
|
||||
cfg_.rc_dropframe_thresh = 1;
|
||||
cfg_.rc_max_quantizer = 56;
|
||||
cfg_.rc_end_usage = VPX_CBR;
|
||||
::libvpx_test::I420VideoSource video("hantro_collage_w352h288.yuv", 352, 288,
|
||||
30, 1, 0, 140);
|
||||
for (int j = 1; j < 5; ++j) {
|
||||
// Run over the denoiser levels.
|
||||
// For the temporal denoiser (#if CONFIG_TEMPORAL_DENOISING) the level j
|
||||
// refers to the 4 denoiser modes: denoiserYonly, denoiserOnYUV,
|
||||
// denoiserOnAggressive, and denoiserOnAdaptive.
|
||||
denoiser_on_ = j;
|
||||
cfg_.rc_target_bitrate = 300;
|
||||
ResetModel();
|
||||
ASSERT_NO_FATAL_FAILURE(RunLoop(&video));
|
||||
ASSERT_GE(cfg_.rc_target_bitrate, effective_datarate_ * 0.95)
|
||||
<< " The datarate for the file exceeds the target!";
|
||||
|
||||
ASSERT_LE(cfg_.rc_target_bitrate, file_datarate_ * 1.4)
|
||||
<< " The datarate for the file missed the target!";
|
||||
}
|
||||
}
|
||||
|
||||
// Check basic datarate targeting, for a single bitrate, when denoiser is off
|
||||
// and on.
|
||||
TEST_P(DatarateTestLarge, DenoiserOffOn) {
|
||||
cfg_.rc_buf_initial_sz = 500;
|
||||
cfg_.rc_dropframe_thresh = 1;
|
||||
cfg_.rc_max_quantizer = 56;
|
||||
cfg_.rc_end_usage = VPX_CBR;
|
||||
::libvpx_test::I420VideoSource video("hantro_collage_w352h288.yuv", 352, 288,
|
||||
30, 1, 0, 299);
|
||||
cfg_.rc_target_bitrate = 300;
|
||||
ResetModel();
|
||||
// The denoiser is off by default.
|
||||
denoiser_on_ = 0;
|
||||
// Set the offon test flag.
|
||||
denoiser_offon_test_ = 1;
|
||||
denoiser_offon_period_ = 100;
|
||||
ASSERT_NO_FATAL_FAILURE(RunLoop(&video));
|
||||
ASSERT_GE(cfg_.rc_target_bitrate, effective_datarate_ * 0.95)
|
||||
<< " The datarate for the file exceeds the target!";
|
||||
ASSERT_LE(cfg_.rc_target_bitrate, file_datarate_ * 1.4)
|
||||
<< " The datarate for the file missed the target!";
|
||||
}
|
||||
#endif // CONFIG_TEMPORAL_DENOISING
|
||||
|
||||
TEST_P(DatarateTestLarge, BasicBufferModel) {
|
||||
denoiser_on_ = 0;
|
||||
cfg_.rc_buf_initial_sz = 500;
|
||||
cfg_.rc_dropframe_thresh = 1;
|
||||
cfg_.rc_max_quantizer = 56;
|
||||
cfg_.rc_end_usage = VPX_CBR;
|
||||
// 2 pass cbr datarate control has a bug hidden by the small # of
|
||||
// frames selected in this encode. The problem is that even if the buffer is
|
||||
// negative we produce a keyframe on a cutscene. Ignoring datarate
|
||||
// constraints
|
||||
// TODO(jimbankoski): ( Fix when issue
|
||||
// http://code.google.com/p/webm/issues/detail?id=495 is addressed. )
|
||||
::libvpx_test::I420VideoSource video("hantro_collage_w352h288.yuv", 352, 288,
|
||||
30, 1, 0, 140);
|
||||
|
||||
// There is an issue for low bitrates in real-time mode, where the
|
||||
// effective_datarate slightly overshoots the target bitrate.
|
||||
// This is same the issue as noted about (#495).
|
||||
// TODO(jimbankoski/marpan): Update test to run for lower bitrates (< 100),
|
||||
// when the issue is resolved.
|
||||
for (int i = 100; i < 800; i += 200) {
|
||||
cfg_.rc_target_bitrate = i;
|
||||
ResetModel();
|
||||
ASSERT_NO_FATAL_FAILURE(RunLoop(&video));
|
||||
ASSERT_GE(cfg_.rc_target_bitrate, effective_datarate_ * 0.95)
|
||||
<< " The datarate for the file exceeds the target!";
|
||||
ASSERT_LE(cfg_.rc_target_bitrate, file_datarate_ * 1.4)
|
||||
<< " The datarate for the file missed the target!";
|
||||
}
|
||||
}
|
||||
|
||||
TEST_P(DatarateTestLarge, ChangingDropFrameThresh) {
|
||||
denoiser_on_ = 0;
|
||||
cfg_.rc_buf_initial_sz = 500;
|
||||
cfg_.rc_max_quantizer = 36;
|
||||
cfg_.rc_end_usage = VPX_CBR;
|
||||
cfg_.rc_target_bitrate = 200;
|
||||
cfg_.kf_mode = VPX_KF_DISABLED;
|
||||
|
||||
const int frame_count = 40;
|
||||
::libvpx_test::I420VideoSource video("hantro_collage_w352h288.yuv", 352, 288,
|
||||
30, 1, 0, frame_count);
|
||||
|
||||
// Here we check that the first dropped frame gets earlier and earlier
|
||||
// as the drop frame threshold is increased.
|
||||
|
||||
const int kDropFrameThreshTestStep = 30;
|
||||
vpx_codec_pts_t last_drop = frame_count;
|
||||
for (int i = 1; i < 91; i += kDropFrameThreshTestStep) {
|
||||
cfg_.rc_dropframe_thresh = i;
|
||||
ResetModel();
|
||||
ASSERT_NO_FATAL_FAILURE(RunLoop(&video));
|
||||
ASSERT_LE(first_drop_, last_drop)
|
||||
<< " The first dropped frame for drop_thresh " << i
|
||||
<< " > first dropped frame for drop_thresh "
|
||||
<< i - kDropFrameThreshTestStep;
|
||||
last_drop = first_drop_;
|
||||
}
|
||||
}
|
||||
|
||||
TEST_P(DatarateTestLarge, DropFramesMultiThreads) {
|
||||
denoiser_on_ = 0;
|
||||
cfg_.rc_buf_initial_sz = 500;
|
||||
cfg_.rc_dropframe_thresh = 30;
|
||||
cfg_.rc_max_quantizer = 56;
|
||||
cfg_.rc_end_usage = VPX_CBR;
|
||||
cfg_.g_threads = 2;
|
||||
|
||||
::libvpx_test::I420VideoSource video("hantro_collage_w352h288.yuv", 352, 288,
|
||||
30, 1, 0, 140);
|
||||
cfg_.rc_target_bitrate = 200;
|
||||
ResetModel();
|
||||
ASSERT_NO_FATAL_FAILURE(RunLoop(&video));
|
||||
ASSERT_GE(cfg_.rc_target_bitrate, effective_datarate_ * 0.95)
|
||||
<< " The datarate for the file exceeds the target!";
|
||||
|
||||
ASSERT_LE(cfg_.rc_target_bitrate, file_datarate_ * 1.4)
|
||||
<< " The datarate for the file missed the target!";
|
||||
}
|
||||
|
||||
class DatarateTestRealTime : public DatarateTestLarge {
|
||||
public:
|
||||
virtual ~DatarateTestRealTime() {}
|
||||
};
|
||||
|
||||
#if CONFIG_TEMPORAL_DENOISING
|
||||
// Check basic datarate targeting, for a single bitrate, but loop over the
|
||||
// various denoiser settings.
|
||||
TEST_P(DatarateTestRealTime, DenoiserLevels) {
|
||||
cfg_.rc_buf_initial_sz = 500;
|
||||
cfg_.rc_dropframe_thresh = 1;
|
||||
cfg_.rc_max_quantizer = 56;
|
||||
cfg_.rc_end_usage = VPX_CBR;
|
||||
::libvpx_test::I420VideoSource video("hantro_collage_w352h288.yuv", 352, 288,
|
||||
30, 1, 0, 140);
|
||||
for (int j = 1; j < 5; ++j) {
|
||||
// Run over the denoiser levels.
|
||||
// For the temporal denoiser (#if CONFIG_TEMPORAL_DENOISING) the level j
|
||||
// refers to the 4 denoiser modes: denoiserYonly, denoiserOnYUV,
|
||||
// denoiserOnAggressive, and denoiserOnAdaptive.
|
||||
denoiser_on_ = j;
|
||||
cfg_.rc_target_bitrate = 300;
|
||||
ResetModel();
|
||||
ASSERT_NO_FATAL_FAILURE(RunLoop(&video));
|
||||
ASSERT_GE(cfg_.rc_target_bitrate, effective_datarate_ * 0.95)
|
||||
<< " The datarate for the file exceeds the target!";
|
||||
ASSERT_LE(cfg_.rc_target_bitrate, file_datarate_ * 1.4)
|
||||
<< " The datarate for the file missed the target!";
|
||||
}
|
||||
}
|
||||
|
||||
// Check basic datarate targeting, for a single bitrate, when denoiser is off
|
||||
// and on.
|
||||
TEST_P(DatarateTestRealTime, DenoiserOffOn) {
|
||||
cfg_.rc_buf_initial_sz = 500;
|
||||
cfg_.rc_dropframe_thresh = 1;
|
||||
cfg_.rc_max_quantizer = 56;
|
||||
cfg_.rc_end_usage = VPX_CBR;
|
||||
::libvpx_test::I420VideoSource video("hantro_collage_w352h288.yuv", 352, 288,
|
||||
30, 1, 0, 299);
|
||||
cfg_.rc_target_bitrate = 300;
|
||||
ResetModel();
|
||||
// The denoiser is off by default.
|
||||
denoiser_on_ = 0;
|
||||
// Set the offon test flag.
|
||||
denoiser_offon_test_ = 1;
|
||||
denoiser_offon_period_ = 100;
|
||||
ASSERT_NO_FATAL_FAILURE(RunLoop(&video));
|
||||
ASSERT_GE(cfg_.rc_target_bitrate, effective_datarate_ * 0.95)
|
||||
<< " The datarate for the file exceeds the target!";
|
||||
ASSERT_LE(cfg_.rc_target_bitrate, file_datarate_ * 1.4)
|
||||
<< " The datarate for the file missed the target!";
|
||||
}
|
||||
#endif // CONFIG_TEMPORAL_DENOISING
|
||||
|
||||
TEST_P(DatarateTestRealTime, BasicBufferModel) {
|
||||
denoiser_on_ = 0;
|
||||
cfg_.rc_buf_initial_sz = 500;
|
||||
cfg_.rc_dropframe_thresh = 1;
|
||||
cfg_.rc_max_quantizer = 56;
|
||||
cfg_.rc_end_usage = VPX_CBR;
|
||||
// 2 pass cbr datarate control has a bug hidden by the small # of
|
||||
// frames selected in this encode. The problem is that even if the buffer is
|
||||
// negative we produce a keyframe on a cutscene, ignoring datarate
|
||||
// constraints
|
||||
// TODO(jimbankoski): Fix when issue
|
||||
// http://bugs.chromium.org/p/webm/issues/detail?id=495 is addressed.
|
||||
::libvpx_test::I420VideoSource video("hantro_collage_w352h288.yuv", 352, 288,
|
||||
30, 1, 0, 140);
|
||||
|
||||
// There is an issue for low bitrates in real-time mode, where the
|
||||
// effective_datarate slightly overshoots the target bitrate.
|
||||
// This is same the issue as noted above (#495).
|
||||
// TODO(jimbankoski/marpan): Update test to run for lower bitrates (< 100),
|
||||
// when the issue is resolved.
|
||||
for (int i = 100; i <= 700; i += 200) {
|
||||
cfg_.rc_target_bitrate = i;
|
||||
ResetModel();
|
||||
ASSERT_NO_FATAL_FAILURE(RunLoop(&video));
|
||||
ASSERT_GE(cfg_.rc_target_bitrate, effective_datarate_ * 0.95)
|
||||
<< " The datarate for the file exceeds the target!";
|
||||
ASSERT_LE(cfg_.rc_target_bitrate, file_datarate_ * 1.4)
|
||||
<< " The datarate for the file missed the target!";
|
||||
}
|
||||
}
|
||||
|
||||
TEST_P(DatarateTestRealTime, ChangingDropFrameThresh) {
|
||||
denoiser_on_ = 0;
|
||||
cfg_.rc_buf_initial_sz = 500;
|
||||
cfg_.rc_max_quantizer = 36;
|
||||
cfg_.rc_end_usage = VPX_CBR;
|
||||
cfg_.rc_target_bitrate = 200;
|
||||
cfg_.kf_mode = VPX_KF_DISABLED;
|
||||
|
||||
const int frame_count = 40;
|
||||
::libvpx_test::I420VideoSource video("hantro_collage_w352h288.yuv", 352, 288,
|
||||
30, 1, 0, frame_count);
|
||||
|
||||
// Check that the first dropped frame gets earlier and earlier
|
||||
// as the drop frame threshold is increased.
|
||||
|
||||
const int kDropFrameThreshTestStep = 30;
|
||||
vpx_codec_pts_t last_drop = frame_count;
|
||||
for (int i = 1; i < 91; i += kDropFrameThreshTestStep) {
|
||||
cfg_.rc_dropframe_thresh = i;
|
||||
ResetModel();
|
||||
ASSERT_NO_FATAL_FAILURE(RunLoop(&video));
|
||||
ASSERT_LE(first_drop_, last_drop)
|
||||
<< " The first dropped frame for drop_thresh " << i
|
||||
<< " > first dropped frame for drop_thresh "
|
||||
<< i - kDropFrameThreshTestStep;
|
||||
last_drop = first_drop_;
|
||||
}
|
||||
}
|
||||
|
||||
TEST_P(DatarateTestRealTime, DropFramesMultiThreads) {
|
||||
denoiser_on_ = 0;
|
||||
cfg_.rc_buf_initial_sz = 500;
|
||||
cfg_.rc_dropframe_thresh = 30;
|
||||
cfg_.rc_max_quantizer = 56;
|
||||
cfg_.rc_end_usage = VPX_CBR;
|
||||
// Encode using multiple threads.
|
||||
cfg_.g_threads = 2;
|
||||
|
||||
::libvpx_test::I420VideoSource video("hantro_collage_w352h288.yuv", 352, 288,
|
||||
30, 1, 0, 140);
|
||||
cfg_.rc_target_bitrate = 200;
|
||||
ResetModel();
|
||||
ASSERT_NO_FATAL_FAILURE(RunLoop(&video));
|
||||
ASSERT_GE(cfg_.rc_target_bitrate, effective_datarate_ * 0.95)
|
||||
<< " The datarate for the file exceeds the target!";
|
||||
|
||||
ASSERT_LE(cfg_.rc_target_bitrate, file_datarate_ * 1.4)
|
||||
<< " The datarate for the file missed the target!";
|
||||
}
|
||||
|
||||
TEST_P(DatarateTestRealTime, RegionOfInterest) {
|
||||
denoiser_on_ = 0;
|
||||
cfg_.rc_buf_initial_sz = 500;
|
||||
cfg_.rc_dropframe_thresh = 0;
|
||||
cfg_.rc_max_quantizer = 56;
|
||||
cfg_.rc_end_usage = VPX_CBR;
|
||||
// Encode using multiple threads.
|
||||
cfg_.g_threads = 2;
|
||||
|
||||
::libvpx_test::I420VideoSource video("hantro_collage_w352h288.yuv", 352, 288,
|
||||
30, 1, 0, 300);
|
||||
cfg_.rc_target_bitrate = 450;
|
||||
cfg_.g_w = 352;
|
||||
cfg_.g_h = 288;
|
||||
|
||||
ResetModel();
|
||||
|
||||
// Set ROI parameters
|
||||
use_roi_ = true;
|
||||
memset(&roi_, 0, sizeof(roi_));
|
||||
|
||||
roi_.rows = (cfg_.g_h + 15) / 16;
|
||||
roi_.cols = (cfg_.g_w + 15) / 16;
|
||||
|
||||
roi_.delta_q[0] = 0;
|
||||
roi_.delta_q[1] = -20;
|
||||
roi_.delta_q[2] = 0;
|
||||
roi_.delta_q[3] = 0;
|
||||
|
||||
roi_.delta_lf[0] = 0;
|
||||
roi_.delta_lf[1] = -20;
|
||||
roi_.delta_lf[2] = 0;
|
||||
roi_.delta_lf[3] = 0;
|
||||
|
||||
roi_.static_threshold[0] = 0;
|
||||
roi_.static_threshold[1] = 1000;
|
||||
roi_.static_threshold[2] = 0;
|
||||
roi_.static_threshold[3] = 0;
|
||||
|
||||
// Use 2 states: 1 is center square, 0 is the rest.
|
||||
roi_.roi_map =
|
||||
(uint8_t *)calloc(roi_.rows * roi_.cols, sizeof(*roi_.roi_map));
|
||||
for (unsigned int i = 0; i < roi_.rows; ++i) {
|
||||
for (unsigned int j = 0; j < roi_.cols; ++j) {
|
||||
if (i > (roi_.rows >> 2) && i < ((roi_.rows * 3) >> 2) &&
|
||||
j > (roi_.cols >> 2) && j < ((roi_.cols * 3) >> 2)) {
|
||||
roi_.roi_map[i * roi_.cols + j] = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ASSERT_NO_FATAL_FAILURE(RunLoop(&video));
|
||||
ASSERT_GE(cfg_.rc_target_bitrate, effective_datarate_ * 0.95)
|
||||
<< " The datarate for the file exceeds the target!";
|
||||
|
||||
ASSERT_LE(cfg_.rc_target_bitrate, file_datarate_ * 1.4)
|
||||
<< " The datarate for the file missed the target!";
|
||||
|
||||
free(roi_.roi_map);
|
||||
}
|
||||
|
||||
TEST_P(DatarateTestRealTime, GFBoost) {
|
||||
denoiser_on_ = 0;
|
||||
cfg_.rc_buf_initial_sz = 500;
|
||||
cfg_.rc_dropframe_thresh = 0;
|
||||
cfg_.rc_max_quantizer = 56;
|
||||
cfg_.rc_end_usage = VPX_CBR;
|
||||
cfg_.g_error_resilient = 0;
|
||||
|
||||
::libvpx_test::I420VideoSource video("hantro_collage_w352h288.yuv", 352, 288,
|
||||
30, 1, 0, 300);
|
||||
cfg_.rc_target_bitrate = 300;
|
||||
ResetModel();
|
||||
// Apply a gf boost.
|
||||
gf_boost_ = 50;
|
||||
|
||||
ASSERT_NO_FATAL_FAILURE(RunLoop(&video));
|
||||
ASSERT_GE(cfg_.rc_target_bitrate, effective_datarate_ * 0.95)
|
||||
<< " The datarate for the file exceeds the target!";
|
||||
|
||||
ASSERT_LE(cfg_.rc_target_bitrate, file_datarate_ * 1.4)
|
||||
<< " The datarate for the file missed the target!";
|
||||
}
|
||||
|
||||
VP8_INSTANTIATE_TEST_CASE(DatarateTestLarge, ALL_TEST_MODES,
|
||||
::testing::Values(0));
|
||||
VP8_INSTANTIATE_TEST_CASE(DatarateTestRealTime,
|
||||
::testing::Values(::libvpx_test::kRealTime),
|
||||
::testing::Values(-6, -12));
|
||||
} // namespace
|
@ -17,16 +17,12 @@
|
||||
|
||||
#include "third_party/googletest/src/include/gtest/gtest.h"
|
||||
|
||||
#include "./vpx_config.h"
|
||||
#include "./vp8_rtcd.h"
|
||||
#include "test/acm_random.h"
|
||||
#include "vpx/vpx_integer.h"
|
||||
#include "vpx_ports/mem.h"
|
||||
|
||||
namespace {
|
||||
|
||||
typedef void (*FdctFunc)(int16_t *a, int16_t *b, int a_stride);
|
||||
|
||||
const int cospi8sqrt2minus1 = 20091;
|
||||
const int sinpi8sqrt2 = 35468;
|
||||
|
||||
@ -72,21 +68,10 @@ void reference_idct4x4(const int16_t *input, int16_t *output) {
|
||||
|
||||
using libvpx_test::ACMRandom;
|
||||
|
||||
class FdctTest : public ::testing::TestWithParam<FdctFunc> {
|
||||
public:
|
||||
virtual void SetUp() {
|
||||
fdct_func_ = GetParam();
|
||||
rnd_.Reset(ACMRandom::DeterministicSeed());
|
||||
}
|
||||
|
||||
protected:
|
||||
FdctFunc fdct_func_;
|
||||
ACMRandom rnd_;
|
||||
};
|
||||
|
||||
TEST_P(FdctTest, SignBiasCheck) {
|
||||
TEST(VP8FdctTest, SignBiasCheck) {
|
||||
ACMRandom rnd(ACMRandom::DeterministicSeed());
|
||||
int16_t test_input_block[16];
|
||||
DECLARE_ALIGNED(16, int16_t, test_output_block[16]);
|
||||
int16_t test_output_block[16];
|
||||
const int pitch = 8;
|
||||
int count_sign_block[16][2];
|
||||
const int count_test_block = 1000000;
|
||||
@ -96,10 +81,10 @@ TEST_P(FdctTest, SignBiasCheck) {
|
||||
for (int i = 0; i < count_test_block; ++i) {
|
||||
// Initialize a test block with input range [-255, 255].
|
||||
for (int j = 0; j < 16; ++j) {
|
||||
test_input_block[j] = rnd_.Rand8() - rnd_.Rand8();
|
||||
test_input_block[j] = rnd.Rand8() - rnd.Rand8();
|
||||
}
|
||||
|
||||
fdct_func_(test_input_block, test_output_block, pitch);
|
||||
vp8_short_fdct4x4_c(test_input_block, test_output_block, pitch);
|
||||
|
||||
for (int j = 0; j < 16; ++j) {
|
||||
if (test_output_block[j] < 0) {
|
||||
@ -125,10 +110,10 @@ TEST_P(FdctTest, SignBiasCheck) {
|
||||
for (int i = 0; i < count_test_block; ++i) {
|
||||
// Initialize a test block with input range [-15, 15].
|
||||
for (int j = 0; j < 16; ++j) {
|
||||
test_input_block[j] = (rnd_.Rand8() >> 4) - (rnd_.Rand8() >> 4);
|
||||
test_input_block[j] = (rnd.Rand8() >> 4) - (rnd.Rand8() >> 4);
|
||||
}
|
||||
|
||||
fdct_func_(test_input_block, test_output_block, pitch);
|
||||
vp8_short_fdct4x4_c(test_input_block, test_output_block, pitch);
|
||||
|
||||
for (int j = 0; j < 16; ++j) {
|
||||
if (test_output_block[j] < 0) {
|
||||
@ -150,22 +135,23 @@ TEST_P(FdctTest, SignBiasCheck) {
|
||||
<< "Error: 4x4 FDCT has a sign bias > 10% for input range [-15, 15]";
|
||||
};
|
||||
|
||||
TEST_P(FdctTest, RoundTripErrorCheck) {
|
||||
TEST(VP8FdctTest, RoundTripErrorCheck) {
|
||||
ACMRandom rnd(ACMRandom::DeterministicSeed());
|
||||
int max_error = 0;
|
||||
double total_error = 0;
|
||||
const int count_test_block = 1000000;
|
||||
for (int i = 0; i < count_test_block; ++i) {
|
||||
int16_t test_input_block[16];
|
||||
int16_t test_temp_block[16];
|
||||
int16_t test_output_block[16];
|
||||
DECLARE_ALIGNED(16, int16_t, test_temp_block[16]);
|
||||
|
||||
// Initialize a test block with input range [-255, 255].
|
||||
for (int j = 0; j < 16; ++j) {
|
||||
test_input_block[j] = rnd_.Rand8() - rnd_.Rand8();
|
||||
test_input_block[j] = rnd.Rand8() - rnd.Rand8();
|
||||
}
|
||||
|
||||
const int pitch = 8;
|
||||
fdct_func_(test_input_block, test_temp_block, pitch);
|
||||
vp8_short_fdct4x4_c(test_input_block, test_temp_block, pitch);
|
||||
reference_idct4x4(test_temp_block, test_output_block);
|
||||
|
||||
for (int j = 0; j < 16; ++j) {
|
||||
@ -183,24 +169,4 @@ TEST_P(FdctTest, RoundTripErrorCheck) {
|
||||
<< "Error: FDCT/IDCT has average roundtrip error > 1 per block";
|
||||
};
|
||||
|
||||
INSTANTIATE_TEST_CASE_P(C, FdctTest, ::testing::Values(vp8_short_fdct4x4_c));
|
||||
|
||||
#if HAVE_NEON
|
||||
INSTANTIATE_TEST_CASE_P(NEON, FdctTest,
|
||||
::testing::Values(vp8_short_fdct4x4_neon));
|
||||
#endif // HAVE_NEON
|
||||
|
||||
#if HAVE_SSE2
|
||||
INSTANTIATE_TEST_CASE_P(SSE2, FdctTest,
|
||||
::testing::Values(vp8_short_fdct4x4_sse2));
|
||||
#endif // HAVE_SSE2
|
||||
|
||||
#if HAVE_MSA
|
||||
INSTANTIATE_TEST_CASE_P(MSA, FdctTest,
|
||||
::testing::Values(vp8_short_fdct4x4_msa));
|
||||
#endif // HAVE_MSA
|
||||
#if HAVE_MMI
|
||||
INSTANTIATE_TEST_CASE_P(MMI, FdctTest,
|
||||
::testing::Values(vp8_short_fdct4x4_mmi));
|
||||
#endif // HAVE_MMI
|
||||
} // namespace
|
||||
|
@ -1,839 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2012 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/util.h"
|
||||
#include "test/y4m_video_source.h"
|
||||
#include "vpx/vpx_codec.h"
|
||||
#include "vpx_ports/bitops.h"
|
||||
|
||||
namespace {
|
||||
|
||||
class DatarateTestVP9 : public ::libvpx_test::EncoderTest {
|
||||
public:
|
||||
explicit DatarateTestVP9(const ::libvpx_test::CodecFactory *codec)
|
||||
: EncoderTest(codec) {}
|
||||
|
||||
protected:
|
||||
virtual ~DatarateTestVP9() {}
|
||||
|
||||
virtual void ResetModel() {
|
||||
last_pts_ = 0;
|
||||
bits_in_buffer_model_ = cfg_.rc_target_bitrate * cfg_.rc_buf_initial_sz;
|
||||
frame_number_ = 0;
|
||||
tot_frame_number_ = 0;
|
||||
first_drop_ = 0;
|
||||
num_drops_ = 0;
|
||||
// Denoiser is off by default.
|
||||
denoiser_on_ = 0;
|
||||
// For testing up to 3 layers.
|
||||
for (int i = 0; i < 3; ++i) {
|
||||
bits_total_[i] = 0;
|
||||
}
|
||||
denoiser_offon_test_ = 0;
|
||||
denoiser_offon_period_ = -1;
|
||||
frame_parallel_decoding_mode_ = 1;
|
||||
use_roi_ = false;
|
||||
}
|
||||
|
||||
//
|
||||
// Frame flags and layer id for temporal layers.
|
||||
//
|
||||
|
||||
// For two layers, test pattern is:
|
||||
// 1 3
|
||||
// 0 2 .....
|
||||
// For three layers, test pattern is:
|
||||
// 1 3 5 7
|
||||
// 2 6
|
||||
// 0 4 ....
|
||||
// LAST is always update on base/layer 0, GOLDEN is updated on layer 1.
|
||||
// For this 3 layer example, the 2nd enhancement layer (layer 2) updates
|
||||
// the altref frame.
|
||||
static int GetFrameFlags(int frame_num, int num_temp_layers) {
|
||||
int frame_flags = 0;
|
||||
if (num_temp_layers == 2) {
|
||||
if (frame_num % 2 == 0) {
|
||||
// Layer 0: predict from L and ARF, update L.
|
||||
frame_flags =
|
||||
VP8_EFLAG_NO_REF_GF | VP8_EFLAG_NO_UPD_GF | VP8_EFLAG_NO_UPD_ARF;
|
||||
} else {
|
||||
// Layer 1: predict from L, G and ARF, and update G.
|
||||
frame_flags = VP8_EFLAG_NO_UPD_ARF | VP8_EFLAG_NO_UPD_LAST |
|
||||
VP8_EFLAG_NO_UPD_ENTROPY;
|
||||
}
|
||||
} else if (num_temp_layers == 3) {
|
||||
if (frame_num % 4 == 0) {
|
||||
// Layer 0: predict from L and ARF; update L.
|
||||
frame_flags =
|
||||
VP8_EFLAG_NO_UPD_GF | VP8_EFLAG_NO_UPD_ARF | VP8_EFLAG_NO_REF_GF;
|
||||
} else if ((frame_num - 2) % 4 == 0) {
|
||||
// Layer 1: predict from L, G, ARF; update G.
|
||||
frame_flags = VP8_EFLAG_NO_UPD_ARF | VP8_EFLAG_NO_UPD_LAST;
|
||||
} else if ((frame_num - 1) % 2 == 0) {
|
||||
// Layer 2: predict from L, G, ARF; update ARF.
|
||||
frame_flags = VP8_EFLAG_NO_UPD_GF | VP8_EFLAG_NO_UPD_LAST;
|
||||
}
|
||||
}
|
||||
return frame_flags;
|
||||
}
|
||||
|
||||
static int SetLayerId(int frame_num, int num_temp_layers) {
|
||||
int layer_id = 0;
|
||||
if (num_temp_layers == 2) {
|
||||
if (frame_num % 2 == 0) {
|
||||
layer_id = 0;
|
||||
} else {
|
||||
layer_id = 1;
|
||||
}
|
||||
} else if (num_temp_layers == 3) {
|
||||
if (frame_num % 4 == 0) {
|
||||
layer_id = 0;
|
||||
} else if ((frame_num - 2) % 4 == 0) {
|
||||
layer_id = 1;
|
||||
} else if ((frame_num - 1) % 2 == 0) {
|
||||
layer_id = 2;
|
||||
}
|
||||
}
|
||||
return layer_id;
|
||||
}
|
||||
|
||||
virtual void PreEncodeFrameHook(::libvpx_test::VideoSource *video,
|
||||
::libvpx_test::Encoder *encoder) {
|
||||
if (video->frame() == 0) encoder->Control(VP8E_SET_CPUUSED, set_cpu_used_);
|
||||
|
||||
if (denoiser_offon_test_) {
|
||||
ASSERT_GT(denoiser_offon_period_, 0)
|
||||
<< "denoiser_offon_period_ is not positive.";
|
||||
if ((video->frame() + 1) % denoiser_offon_period_ == 0) {
|
||||
// Flip denoiser_on_ periodically
|
||||
denoiser_on_ ^= 1;
|
||||
}
|
||||
}
|
||||
|
||||
encoder->Control(VP9E_SET_NOISE_SENSITIVITY, denoiser_on_);
|
||||
encoder->Control(VP9E_SET_TILE_COLUMNS, get_msb(cfg_.g_threads));
|
||||
encoder->Control(VP9E_SET_FRAME_PARALLEL_DECODING,
|
||||
frame_parallel_decoding_mode_);
|
||||
|
||||
if (use_roi_) {
|
||||
encoder->Control(VP9E_SET_ROI_MAP, &roi_);
|
||||
}
|
||||
|
||||
if (cfg_.ts_number_layers > 1) {
|
||||
if (video->frame() == 0) {
|
||||
encoder->Control(VP9E_SET_SVC, 1);
|
||||
}
|
||||
vpx_svc_layer_id_t layer_id;
|
||||
layer_id.spatial_layer_id = 0;
|
||||
frame_flags_ = GetFrameFlags(video->frame(), cfg_.ts_number_layers);
|
||||
layer_id.temporal_layer_id =
|
||||
SetLayerId(video->frame(), cfg_.ts_number_layers);
|
||||
encoder->Control(VP9E_SET_SVC_LAYER_ID, &layer_id);
|
||||
}
|
||||
const vpx_rational_t tb = video->timebase();
|
||||
timebase_ = static_cast<double>(tb.num) / tb.den;
|
||||
duration_ = 0;
|
||||
}
|
||||
|
||||
virtual void FramePktHook(const vpx_codec_cx_pkt_t *pkt) {
|
||||
// Time since last timestamp = duration.
|
||||
vpx_codec_pts_t duration = pkt->data.frame.pts - last_pts_;
|
||||
|
||||
if (duration > 1) {
|
||||
// If first drop not set and we have a drop set it to this time.
|
||||
if (!first_drop_) first_drop_ = last_pts_ + 1;
|
||||
// Update the number of frame drops.
|
||||
num_drops_ += static_cast<int>(duration - 1);
|
||||
// Update counter for total number of frames (#frames input to encoder).
|
||||
// Needed for setting the proper layer_id below.
|
||||
tot_frame_number_ += static_cast<int>(duration - 1);
|
||||
}
|
||||
|
||||
int layer = SetLayerId(tot_frame_number_, cfg_.ts_number_layers);
|
||||
|
||||
// Add to the buffer the bits we'd expect from a constant bitrate server.
|
||||
bits_in_buffer_model_ += static_cast<int64_t>(
|
||||
duration * timebase_ * cfg_.rc_target_bitrate * 1000);
|
||||
|
||||
// Buffer should not go negative.
|
||||
ASSERT_GE(bits_in_buffer_model_, 0)
|
||||
<< "Buffer Underrun at frame " << pkt->data.frame.pts;
|
||||
|
||||
const size_t frame_size_in_bits = pkt->data.frame.sz * 8;
|
||||
|
||||
// Update the total encoded bits. For temporal layers, update the cumulative
|
||||
// encoded bits per layer.
|
||||
for (int i = layer; i < static_cast<int>(cfg_.ts_number_layers); ++i) {
|
||||
bits_total_[i] += frame_size_in_bits;
|
||||
}
|
||||
|
||||
// Update the most recent pts.
|
||||
last_pts_ = pkt->data.frame.pts;
|
||||
++frame_number_;
|
||||
++tot_frame_number_;
|
||||
}
|
||||
|
||||
virtual void EndPassHook(void) {
|
||||
for (int layer = 0; layer < static_cast<int>(cfg_.ts_number_layers);
|
||||
++layer) {
|
||||
duration_ = (last_pts_ + 1) * timebase_;
|
||||
if (bits_total_[layer]) {
|
||||
// Effective file datarate:
|
||||
effective_datarate_[layer] = (bits_total_[layer] / 1000.0) / duration_;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
vpx_codec_pts_t last_pts_;
|
||||
double timebase_;
|
||||
int frame_number_; // Counter for number of non-dropped/encoded frames.
|
||||
int tot_frame_number_; // Counter for total number of input frames.
|
||||
int64_t bits_total_[3];
|
||||
double duration_;
|
||||
double effective_datarate_[3];
|
||||
int set_cpu_used_;
|
||||
int64_t bits_in_buffer_model_;
|
||||
vpx_codec_pts_t first_drop_;
|
||||
int num_drops_;
|
||||
int denoiser_on_;
|
||||
int denoiser_offon_test_;
|
||||
int denoiser_offon_period_;
|
||||
int frame_parallel_decoding_mode_;
|
||||
bool use_roi_;
|
||||
vpx_roi_map_t roi_;
|
||||
};
|
||||
|
||||
// Params: test mode, speed setting and index for bitrate array.
|
||||
class DatarateTestVP9Large
|
||||
: public DatarateTestVP9,
|
||||
public ::libvpx_test::CodecTestWith3Params<libvpx_test::TestMode, int,
|
||||
int> {
|
||||
public:
|
||||
DatarateTestVP9Large() : DatarateTestVP9(GET_PARAM(0)) {}
|
||||
|
||||
protected:
|
||||
virtual void SetUp() {
|
||||
InitializeConfig();
|
||||
SetMode(GET_PARAM(1));
|
||||
set_cpu_used_ = GET_PARAM(2);
|
||||
ResetModel();
|
||||
}
|
||||
};
|
||||
|
||||
// Params: test mode, speed setting.
|
||||
class DatarateTestVP9LargeOneBR
|
||||
: public DatarateTestVP9,
|
||||
public ::libvpx_test::CodecTestWith2Params<libvpx_test::TestMode, int> {
|
||||
public:
|
||||
DatarateTestVP9LargeOneBR() : DatarateTestVP9(GET_PARAM(0)) {}
|
||||
|
||||
protected:
|
||||
virtual void SetUp() {
|
||||
InitializeConfig();
|
||||
SetMode(GET_PARAM(1));
|
||||
set_cpu_used_ = GET_PARAM(2);
|
||||
ResetModel();
|
||||
}
|
||||
};
|
||||
|
||||
// Check basic rate targeting for VBR mode with 0 lag.
|
||||
TEST_P(DatarateTestVP9Large, BasicRateTargetingVBRLagZero) {
|
||||
cfg_.rc_min_quantizer = 0;
|
||||
cfg_.rc_max_quantizer = 63;
|
||||
cfg_.g_error_resilient = 0;
|
||||
cfg_.rc_end_usage = VPX_VBR;
|
||||
cfg_.g_lag_in_frames = 0;
|
||||
|
||||
::libvpx_test::I420VideoSource video("hantro_collage_w352h288.yuv", 352, 288,
|
||||
30, 1, 0, 300);
|
||||
|
||||
const int bitrates[2] = { 400, 800 };
|
||||
const int bitrate_index = GET_PARAM(3);
|
||||
if (bitrate_index > 1) return;
|
||||
cfg_.rc_target_bitrate = bitrates[bitrate_index];
|
||||
ResetModel();
|
||||
ASSERT_NO_FATAL_FAILURE(RunLoop(&video));
|
||||
ASSERT_GE(effective_datarate_[0], cfg_.rc_target_bitrate * 0.75)
|
||||
<< " The datarate for the file is lower than target by too much!";
|
||||
ASSERT_LE(effective_datarate_[0], cfg_.rc_target_bitrate * 1.35)
|
||||
<< " The datarate for the file is greater than target by too much!";
|
||||
}
|
||||
|
||||
// Check basic rate targeting for VBR mode with non-zero lag.
|
||||
TEST_P(DatarateTestVP9Large, BasicRateTargetingVBRLagNonZero) {
|
||||
cfg_.rc_min_quantizer = 0;
|
||||
cfg_.rc_max_quantizer = 63;
|
||||
cfg_.g_error_resilient = 0;
|
||||
cfg_.rc_end_usage = VPX_VBR;
|
||||
// For non-zero lag, rate control will work (be within bounds) for
|
||||
// real-time mode.
|
||||
if (deadline_ == VPX_DL_REALTIME) {
|
||||
cfg_.g_lag_in_frames = 15;
|
||||
} else {
|
||||
cfg_.g_lag_in_frames = 0;
|
||||
}
|
||||
|
||||
::libvpx_test::I420VideoSource video("hantro_collage_w352h288.yuv", 352, 288,
|
||||
30, 1, 0, 300);
|
||||
const int bitrates[2] = { 400, 800 };
|
||||
const int bitrate_index = GET_PARAM(3);
|
||||
if (bitrate_index > 1) return;
|
||||
cfg_.rc_target_bitrate = bitrates[bitrate_index];
|
||||
ResetModel();
|
||||
ASSERT_NO_FATAL_FAILURE(RunLoop(&video));
|
||||
ASSERT_GE(effective_datarate_[0], cfg_.rc_target_bitrate * 0.75)
|
||||
<< " The datarate for the file is lower than target by too much!";
|
||||
ASSERT_LE(effective_datarate_[0], cfg_.rc_target_bitrate * 1.30)
|
||||
<< " The datarate for the file is greater than target by too much!";
|
||||
}
|
||||
|
||||
// Check basic rate targeting for VBR mode with non-zero lag, with
|
||||
// frame_parallel_decoding_mode off. This enables the adapt_coeff/mode/mv probs
|
||||
// since error_resilience is off.
|
||||
TEST_P(DatarateTestVP9Large, BasicRateTargetingVBRLagNonZeroFrameParDecOff) {
|
||||
cfg_.rc_min_quantizer = 0;
|
||||
cfg_.rc_max_quantizer = 63;
|
||||
cfg_.g_error_resilient = 0;
|
||||
cfg_.rc_end_usage = VPX_VBR;
|
||||
// For non-zero lag, rate control will work (be within bounds) for
|
||||
// real-time mode.
|
||||
if (deadline_ == VPX_DL_REALTIME) {
|
||||
cfg_.g_lag_in_frames = 15;
|
||||
} else {
|
||||
cfg_.g_lag_in_frames = 0;
|
||||
}
|
||||
|
||||
::libvpx_test::I420VideoSource video("hantro_collage_w352h288.yuv", 352, 288,
|
||||
30, 1, 0, 300);
|
||||
const int bitrates[2] = { 400, 800 };
|
||||
const int bitrate_index = GET_PARAM(3);
|
||||
if (bitrate_index > 1) return;
|
||||
cfg_.rc_target_bitrate = bitrates[bitrate_index];
|
||||
ResetModel();
|
||||
frame_parallel_decoding_mode_ = 0;
|
||||
ASSERT_NO_FATAL_FAILURE(RunLoop(&video));
|
||||
ASSERT_GE(effective_datarate_[0], cfg_.rc_target_bitrate * 0.75)
|
||||
<< " The datarate for the file is lower than target by too much!";
|
||||
ASSERT_LE(effective_datarate_[0], cfg_.rc_target_bitrate * 1.35)
|
||||
<< " The datarate for the file is greater than target by too much!";
|
||||
}
|
||||
|
||||
// Check basic rate targeting for CBR mode.
|
||||
TEST_P(DatarateTestVP9Large, BasicRateTargeting) {
|
||||
cfg_.rc_buf_initial_sz = 500;
|
||||
cfg_.rc_buf_optimal_sz = 500;
|
||||
cfg_.rc_buf_sz = 1000;
|
||||
cfg_.rc_dropframe_thresh = 1;
|
||||
cfg_.rc_min_quantizer = 0;
|
||||
cfg_.rc_max_quantizer = 63;
|
||||
cfg_.rc_end_usage = VPX_CBR;
|
||||
cfg_.g_lag_in_frames = 0;
|
||||
|
||||
::libvpx_test::I420VideoSource video("hantro_collage_w352h288.yuv", 352, 288,
|
||||
30, 1, 0, 140);
|
||||
const int bitrates[4] = { 150, 350, 550, 750 };
|
||||
const int bitrate_index = GET_PARAM(3);
|
||||
cfg_.rc_target_bitrate = bitrates[bitrate_index];
|
||||
ResetModel();
|
||||
ASSERT_NO_FATAL_FAILURE(RunLoop(&video));
|
||||
ASSERT_GE(effective_datarate_[0], cfg_.rc_target_bitrate * 0.85)
|
||||
<< " The datarate for the file is lower than target by too much!";
|
||||
ASSERT_LE(effective_datarate_[0], cfg_.rc_target_bitrate * 1.15)
|
||||
<< " The datarate for the file is greater than target by too much!";
|
||||
}
|
||||
|
||||
// Check basic rate targeting for CBR mode, with frame_parallel_decoding_mode
|
||||
// off( and error_resilience off).
|
||||
TEST_P(DatarateTestVP9Large, BasicRateTargetingFrameParDecOff) {
|
||||
cfg_.rc_buf_initial_sz = 500;
|
||||
cfg_.rc_buf_optimal_sz = 500;
|
||||
cfg_.rc_buf_sz = 1000;
|
||||
cfg_.rc_dropframe_thresh = 1;
|
||||
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 = 0;
|
||||
|
||||
::libvpx_test::I420VideoSource video("hantro_collage_w352h288.yuv", 352, 288,
|
||||
30, 1, 0, 140);
|
||||
const int bitrates[4] = { 150, 350, 550, 750 };
|
||||
const int bitrate_index = GET_PARAM(3);
|
||||
cfg_.rc_target_bitrate = bitrates[bitrate_index];
|
||||
ResetModel();
|
||||
frame_parallel_decoding_mode_ = 0;
|
||||
ASSERT_NO_FATAL_FAILURE(RunLoop(&video));
|
||||
ASSERT_GE(effective_datarate_[0], cfg_.rc_target_bitrate * 0.85)
|
||||
<< " The datarate for the file is lower than target by too much!";
|
||||
ASSERT_LE(effective_datarate_[0], cfg_.rc_target_bitrate * 1.15)
|
||||
<< " The datarate for the file is greater than target by too much!";
|
||||
}
|
||||
|
||||
// Check basic rate targeting for CBR mode, with 2 threads and dropped frames.
|
||||
TEST_P(DatarateTestVP9LargeOneBR, BasicRateTargetingDropFramesMultiThreads) {
|
||||
cfg_.rc_buf_initial_sz = 500;
|
||||
cfg_.rc_buf_optimal_sz = 500;
|
||||
cfg_.rc_buf_sz = 1000;
|
||||
cfg_.rc_dropframe_thresh = 30;
|
||||
cfg_.rc_min_quantizer = 0;
|
||||
cfg_.rc_max_quantizer = 63;
|
||||
cfg_.rc_end_usage = VPX_CBR;
|
||||
cfg_.g_lag_in_frames = 0;
|
||||
// Encode using multiple threads.
|
||||
cfg_.g_threads = 2;
|
||||
|
||||
::libvpx_test::I420VideoSource video("hantro_collage_w352h288.yuv", 352, 288,
|
||||
30, 1, 0, 140);
|
||||
cfg_.rc_target_bitrate = 200;
|
||||
ResetModel();
|
||||
ASSERT_NO_FATAL_FAILURE(RunLoop(&video));
|
||||
ASSERT_GE(effective_datarate_[0], cfg_.rc_target_bitrate * 0.85)
|
||||
<< " The datarate for the file is lower than target by too much!";
|
||||
ASSERT_LE(effective_datarate_[0], cfg_.rc_target_bitrate * 1.15)
|
||||
<< " The datarate for the file is greater than target by too much!";
|
||||
}
|
||||
|
||||
// Check basic rate targeting for CBR.
|
||||
TEST_P(DatarateTestVP9Large, BasicRateTargeting444) {
|
||||
::libvpx_test::Y4mVideoSource video("rush_hour_444.y4m", 0, 140);
|
||||
|
||||
cfg_.g_profile = 1;
|
||||
cfg_.g_timebase = video.timebase();
|
||||
|
||||
cfg_.rc_buf_initial_sz = 500;
|
||||
cfg_.rc_buf_optimal_sz = 500;
|
||||
cfg_.rc_buf_sz = 1000;
|
||||
cfg_.rc_dropframe_thresh = 1;
|
||||
cfg_.rc_min_quantizer = 0;
|
||||
cfg_.rc_max_quantizer = 63;
|
||||
cfg_.rc_end_usage = VPX_CBR;
|
||||
const int bitrates[4] = { 250, 450, 650, 850 };
|
||||
const int bitrate_index = GET_PARAM(3);
|
||||
cfg_.rc_target_bitrate = bitrates[bitrate_index];
|
||||
ResetModel();
|
||||
ASSERT_NO_FATAL_FAILURE(RunLoop(&video));
|
||||
ASSERT_GE(static_cast<double>(cfg_.rc_target_bitrate),
|
||||
effective_datarate_[0] * 0.80)
|
||||
<< " The datarate for the file exceeds the target by too much!";
|
||||
ASSERT_LE(static_cast<double>(cfg_.rc_target_bitrate),
|
||||
effective_datarate_[0] * 1.15)
|
||||
<< " The datarate for the file missed the target!"
|
||||
<< cfg_.rc_target_bitrate << " " << effective_datarate_;
|
||||
}
|
||||
|
||||
// Check that (1) the first dropped frame gets earlier and earlier
|
||||
// as the drop frame threshold is increased, and (2) that the total number of
|
||||
// frame drops does not decrease as we increase frame drop threshold.
|
||||
// Use a lower qp-max to force some frame drops.
|
||||
TEST_P(DatarateTestVP9Large, ChangingDropFrameThresh) {
|
||||
cfg_.rc_buf_initial_sz = 500;
|
||||
cfg_.rc_buf_optimal_sz = 500;
|
||||
cfg_.rc_buf_sz = 1000;
|
||||
cfg_.rc_undershoot_pct = 20;
|
||||
cfg_.rc_undershoot_pct = 20;
|
||||
cfg_.rc_dropframe_thresh = 10;
|
||||
cfg_.rc_min_quantizer = 0;
|
||||
cfg_.rc_max_quantizer = 50;
|
||||
cfg_.rc_end_usage = VPX_CBR;
|
||||
cfg_.rc_target_bitrate = 200;
|
||||
cfg_.g_lag_in_frames = 0;
|
||||
// TODO(marpan): Investigate datarate target failures with a smaller keyframe
|
||||
// interval (128).
|
||||
cfg_.kf_max_dist = 9999;
|
||||
|
||||
::libvpx_test::I420VideoSource video("hantro_collage_w352h288.yuv", 352, 288,
|
||||
30, 1, 0, 140);
|
||||
|
||||
const int kDropFrameThreshTestStep = 30;
|
||||
const int bitrates[2] = { 50, 150 };
|
||||
const int bitrate_index = GET_PARAM(3);
|
||||
if (bitrate_index > 1) return;
|
||||
cfg_.rc_target_bitrate = bitrates[bitrate_index];
|
||||
vpx_codec_pts_t last_drop = 140;
|
||||
int last_num_drops = 0;
|
||||
for (int i = 10; i < 100; i += kDropFrameThreshTestStep) {
|
||||
cfg_.rc_dropframe_thresh = i;
|
||||
ResetModel();
|
||||
ASSERT_NO_FATAL_FAILURE(RunLoop(&video));
|
||||
ASSERT_GE(effective_datarate_[0], cfg_.rc_target_bitrate * 0.85)
|
||||
<< " The datarate for the file is lower than target by too much!";
|
||||
ASSERT_LE(effective_datarate_[0], cfg_.rc_target_bitrate * 1.25)
|
||||
<< " The datarate for the file is greater than target by too much!";
|
||||
ASSERT_LE(first_drop_, last_drop)
|
||||
<< " The first dropped frame for drop_thresh " << i
|
||||
<< " > first dropped frame for drop_thresh "
|
||||
<< i - kDropFrameThreshTestStep;
|
||||
ASSERT_GE(num_drops_, last_num_drops * 0.85)
|
||||
<< " The number of dropped frames for drop_thresh " << i
|
||||
<< " < number of dropped frames for drop_thresh "
|
||||
<< i - kDropFrameThreshTestStep;
|
||||
last_drop = first_drop_;
|
||||
last_num_drops = num_drops_;
|
||||
}
|
||||
} // namespace
|
||||
|
||||
// Check basic rate targeting for 2 temporal layers.
|
||||
TEST_P(DatarateTestVP9Large, BasicRateTargeting2TemporalLayers) {
|
||||
cfg_.rc_buf_initial_sz = 500;
|
||||
cfg_.rc_buf_optimal_sz = 500;
|
||||
cfg_.rc_buf_sz = 1000;
|
||||
cfg_.rc_dropframe_thresh = 1;
|
||||
cfg_.rc_min_quantizer = 0;
|
||||
cfg_.rc_max_quantizer = 63;
|
||||
cfg_.rc_end_usage = VPX_CBR;
|
||||
cfg_.g_lag_in_frames = 0;
|
||||
|
||||
// 2 Temporal layers, no spatial layers: Framerate decimation (2, 1).
|
||||
cfg_.ss_number_layers = 1;
|
||||
cfg_.ts_number_layers = 2;
|
||||
cfg_.ts_rate_decimator[0] = 2;
|
||||
cfg_.ts_rate_decimator[1] = 1;
|
||||
|
||||
cfg_.temporal_layering_mode = VP9E_TEMPORAL_LAYERING_MODE_BYPASS;
|
||||
|
||||
if (deadline_ == VPX_DL_REALTIME) cfg_.g_error_resilient = 1;
|
||||
|
||||
::libvpx_test::I420VideoSource video("hantro_collage_w352h288.yuv", 352, 288,
|
||||
30, 1, 0, 200);
|
||||
const int bitrates[4] = { 200, 400, 600, 800 };
|
||||
const int bitrate_index = GET_PARAM(3);
|
||||
cfg_.rc_target_bitrate = bitrates[bitrate_index];
|
||||
ResetModel();
|
||||
// 60-40 bitrate allocation for 2 temporal layers.
|
||||
cfg_.layer_target_bitrate[0] = 60 * cfg_.rc_target_bitrate / 100;
|
||||
cfg_.layer_target_bitrate[1] = cfg_.rc_target_bitrate;
|
||||
ASSERT_NO_FATAL_FAILURE(RunLoop(&video));
|
||||
for (int j = 0; j < static_cast<int>(cfg_.ts_number_layers); ++j) {
|
||||
ASSERT_GE(effective_datarate_[j], cfg_.layer_target_bitrate[j] * 0.85)
|
||||
<< " The datarate for the file is lower than target by too much, "
|
||||
"for layer: "
|
||||
<< j;
|
||||
ASSERT_LE(effective_datarate_[j], cfg_.layer_target_bitrate[j] * 1.15)
|
||||
<< " The datarate for the file is greater than target by too much, "
|
||||
"for layer: "
|
||||
<< j;
|
||||
}
|
||||
}
|
||||
|
||||
// Check basic rate targeting for 3 temporal layers.
|
||||
TEST_P(DatarateTestVP9Large, BasicRateTargeting3TemporalLayers) {
|
||||
cfg_.rc_buf_initial_sz = 500;
|
||||
cfg_.rc_buf_optimal_sz = 500;
|
||||
cfg_.rc_buf_sz = 1000;
|
||||
cfg_.rc_dropframe_thresh = 1;
|
||||
cfg_.rc_min_quantizer = 0;
|
||||
cfg_.rc_max_quantizer = 63;
|
||||
cfg_.rc_end_usage = VPX_CBR;
|
||||
cfg_.g_lag_in_frames = 0;
|
||||
|
||||
// 3 Temporal layers, no spatial layers: Framerate decimation (4, 2, 1).
|
||||
cfg_.ss_number_layers = 1;
|
||||
cfg_.ts_number_layers = 3;
|
||||
cfg_.ts_rate_decimator[0] = 4;
|
||||
cfg_.ts_rate_decimator[1] = 2;
|
||||
cfg_.ts_rate_decimator[2] = 1;
|
||||
|
||||
cfg_.temporal_layering_mode = VP9E_TEMPORAL_LAYERING_MODE_BYPASS;
|
||||
|
||||
::libvpx_test::I420VideoSource video("hantro_collage_w352h288.yuv", 352, 288,
|
||||
30, 1, 0, 200);
|
||||
const int bitrates[4] = { 200, 400, 600, 800 };
|
||||
const int bitrate_index = GET_PARAM(3);
|
||||
cfg_.rc_target_bitrate = bitrates[bitrate_index];
|
||||
ResetModel();
|
||||
// 40-20-40 bitrate allocation for 3 temporal layers.
|
||||
cfg_.layer_target_bitrate[0] = 40 * cfg_.rc_target_bitrate / 100;
|
||||
cfg_.layer_target_bitrate[1] = 60 * cfg_.rc_target_bitrate / 100;
|
||||
cfg_.layer_target_bitrate[2] = cfg_.rc_target_bitrate;
|
||||
ASSERT_NO_FATAL_FAILURE(RunLoop(&video));
|
||||
for (int j = 0; j < static_cast<int>(cfg_.ts_number_layers); ++j) {
|
||||
// TODO(yaowu): Work out more stable rc control strategy and
|
||||
// Adjust the thresholds to be tighter than .75.
|
||||
ASSERT_GE(effective_datarate_[j], cfg_.layer_target_bitrate[j] * 0.75)
|
||||
<< " The datarate for the file is lower than target by too much, "
|
||||
"for layer: "
|
||||
<< j;
|
||||
// TODO(yaowu): Work out more stable rc control strategy and
|
||||
// Adjust the thresholds to be tighter than 1.25.
|
||||
ASSERT_LE(effective_datarate_[j], cfg_.layer_target_bitrate[j] * 1.25)
|
||||
<< " The datarate for the file is greater than target by too much, "
|
||||
"for layer: "
|
||||
<< j;
|
||||
}
|
||||
}
|
||||
|
||||
// Check basic rate targeting for 3 temporal layers, with frame dropping.
|
||||
// Only for one (low) bitrate with lower max_quantizer, and somewhat higher
|
||||
// frame drop threshold, to force frame dropping.
|
||||
TEST_P(DatarateTestVP9LargeOneBR,
|
||||
BasicRateTargeting3TemporalLayersFrameDropping) {
|
||||
cfg_.rc_buf_initial_sz = 500;
|
||||
cfg_.rc_buf_optimal_sz = 500;
|
||||
cfg_.rc_buf_sz = 1000;
|
||||
// Set frame drop threshold and rc_max_quantizer to force some frame drops.
|
||||
cfg_.rc_dropframe_thresh = 20;
|
||||
cfg_.rc_max_quantizer = 45;
|
||||
cfg_.rc_min_quantizer = 0;
|
||||
cfg_.rc_end_usage = VPX_CBR;
|
||||
cfg_.g_lag_in_frames = 0;
|
||||
|
||||
// 3 Temporal layers, no spatial layers: Framerate decimation (4, 2, 1).
|
||||
cfg_.ss_number_layers = 1;
|
||||
cfg_.ts_number_layers = 3;
|
||||
cfg_.ts_rate_decimator[0] = 4;
|
||||
cfg_.ts_rate_decimator[1] = 2;
|
||||
cfg_.ts_rate_decimator[2] = 1;
|
||||
|
||||
cfg_.temporal_layering_mode = VP9E_TEMPORAL_LAYERING_MODE_BYPASS;
|
||||
|
||||
::libvpx_test::I420VideoSource video("hantro_collage_w352h288.yuv", 352, 288,
|
||||
30, 1, 0, 200);
|
||||
cfg_.rc_target_bitrate = 200;
|
||||
ResetModel();
|
||||
// 40-20-40 bitrate allocation for 3 temporal layers.
|
||||
cfg_.layer_target_bitrate[0] = 40 * cfg_.rc_target_bitrate / 100;
|
||||
cfg_.layer_target_bitrate[1] = 60 * cfg_.rc_target_bitrate / 100;
|
||||
cfg_.layer_target_bitrate[2] = cfg_.rc_target_bitrate;
|
||||
ASSERT_NO_FATAL_FAILURE(RunLoop(&video));
|
||||
for (int j = 0; j < static_cast<int>(cfg_.ts_number_layers); ++j) {
|
||||
ASSERT_GE(effective_datarate_[j], cfg_.layer_target_bitrate[j] * 0.85)
|
||||
<< " The datarate for the file is lower than target by too much, "
|
||||
"for layer: "
|
||||
<< j;
|
||||
ASSERT_LE(effective_datarate_[j], cfg_.layer_target_bitrate[j] * 1.15)
|
||||
<< " The datarate for the file is greater than target by too much, "
|
||||
"for layer: "
|
||||
<< j;
|
||||
// Expect some frame drops in this test: for this 200 frames test,
|
||||
// expect at least 10% and not more than 60% drops.
|
||||
ASSERT_GE(num_drops_, 20);
|
||||
ASSERT_LE(num_drops_, 130);
|
||||
}
|
||||
}
|
||||
|
||||
// Params: speed setting.
|
||||
class DatarateTestVP9RealTime : public DatarateTestVP9,
|
||||
public ::libvpx_test::CodecTestWithParam<int> {
|
||||
public:
|
||||
DatarateTestVP9RealTime() : DatarateTestVP9(GET_PARAM(0)) {}
|
||||
virtual ~DatarateTestVP9RealTime() {}
|
||||
|
||||
protected:
|
||||
virtual void SetUp() {
|
||||
InitializeConfig();
|
||||
SetMode(::libvpx_test::kRealTime);
|
||||
set_cpu_used_ = GET_PARAM(1);
|
||||
ResetModel();
|
||||
}
|
||||
};
|
||||
|
||||
// Check VP9 region of interest feature.
|
||||
TEST_P(DatarateTestVP9RealTime, RegionOfInterest) {
|
||||
if (deadline_ != VPX_DL_REALTIME || set_cpu_used_ < 5) return;
|
||||
cfg_.rc_buf_initial_sz = 500;
|
||||
cfg_.rc_buf_optimal_sz = 500;
|
||||
cfg_.rc_buf_sz = 1000;
|
||||
cfg_.rc_dropframe_thresh = 0;
|
||||
cfg_.rc_min_quantizer = 0;
|
||||
cfg_.rc_max_quantizer = 63;
|
||||
cfg_.rc_end_usage = VPX_CBR;
|
||||
cfg_.g_lag_in_frames = 0;
|
||||
|
||||
::libvpx_test::I420VideoSource video("hantro_collage_w352h288.yuv", 352, 288,
|
||||
30, 1, 0, 300);
|
||||
|
||||
cfg_.rc_target_bitrate = 450;
|
||||
cfg_.g_w = 352;
|
||||
cfg_.g_h = 288;
|
||||
|
||||
ResetModel();
|
||||
|
||||
// Set ROI parameters
|
||||
use_roi_ = true;
|
||||
memset(&roi_, 0, sizeof(roi_));
|
||||
|
||||
roi_.rows = (cfg_.g_h + 7) / 8;
|
||||
roi_.cols = (cfg_.g_w + 7) / 8;
|
||||
|
||||
roi_.delta_q[1] = -20;
|
||||
roi_.delta_lf[1] = -20;
|
||||
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 = reinterpret_cast<uint8_t *>(
|
||||
calloc(roi_.rows * roi_.cols, sizeof(*roi_.roi_map)));
|
||||
ASSERT_TRUE(roi_.roi_map != NULL);
|
||||
|
||||
for (unsigned int i = 0; i < roi_.rows; ++i) {
|
||||
for (unsigned int j = 0; j < roi_.cols; ++j) {
|
||||
if (i > (roi_.rows >> 2) && i < ((roi_.rows * 3) >> 2) &&
|
||||
j > (roi_.cols >> 2) && j < ((roi_.cols * 3) >> 2)) {
|
||||
roi_.roi_map[i * roi_.cols + j] = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ASSERT_NO_FATAL_FAILURE(RunLoop(&video));
|
||||
ASSERT_GE(cfg_.rc_target_bitrate, effective_datarate_[0] * 0.90)
|
||||
<< " The datarate for the file exceeds the target!";
|
||||
|
||||
ASSERT_LE(cfg_.rc_target_bitrate, effective_datarate_[0] * 1.4)
|
||||
<< " The datarate for the file missed the target!";
|
||||
|
||||
free(roi_.roi_map);
|
||||
}
|
||||
|
||||
#if CONFIG_VP9_TEMPORAL_DENOISING
|
||||
// Params: speed setting.
|
||||
class DatarateTestVP9LargeDenoiser : public DatarateTestVP9RealTime {
|
||||
public:
|
||||
virtual ~DatarateTestVP9LargeDenoiser() {}
|
||||
};
|
||||
|
||||
// Check basic datarate targeting, for a single bitrate, when denoiser is on.
|
||||
TEST_P(DatarateTestVP9LargeDenoiser, LowNoise) {
|
||||
cfg_.rc_buf_initial_sz = 500;
|
||||
cfg_.rc_buf_optimal_sz = 500;
|
||||
cfg_.rc_buf_sz = 1000;
|
||||
cfg_.rc_dropframe_thresh = 1;
|
||||
cfg_.rc_min_quantizer = 2;
|
||||
cfg_.rc_max_quantizer = 56;
|
||||
cfg_.rc_end_usage = VPX_CBR;
|
||||
cfg_.g_lag_in_frames = 0;
|
||||
|
||||
::libvpx_test::I420VideoSource video("hantro_collage_w352h288.yuv", 352, 288,
|
||||
30, 1, 0, 140);
|
||||
|
||||
// For the temporal denoiser (#if CONFIG_VP9_TEMPORAL_DENOISING),
|
||||
// there is only one denoiser mode: denoiserYonly(which is 1),
|
||||
// but may add more modes in the future.
|
||||
cfg_.rc_target_bitrate = 300;
|
||||
ResetModel();
|
||||
// Turn on the denoiser.
|
||||
denoiser_on_ = 1;
|
||||
ASSERT_NO_FATAL_FAILURE(RunLoop(&video));
|
||||
ASSERT_GE(effective_datarate_[0], cfg_.rc_target_bitrate * 0.85)
|
||||
<< " The datarate for the file is lower than target by too much!";
|
||||
ASSERT_LE(effective_datarate_[0], cfg_.rc_target_bitrate * 1.15)
|
||||
<< " The datarate for the file is greater than target by too much!";
|
||||
}
|
||||
|
||||
// Check basic datarate targeting, for a single bitrate, when denoiser is on,
|
||||
// for clip with high noise level. Use 2 threads.
|
||||
TEST_P(DatarateTestVP9LargeDenoiser, HighNoise) {
|
||||
cfg_.rc_buf_initial_sz = 500;
|
||||
cfg_.rc_buf_optimal_sz = 500;
|
||||
cfg_.rc_buf_sz = 1000;
|
||||
cfg_.rc_dropframe_thresh = 1;
|
||||
cfg_.rc_min_quantizer = 2;
|
||||
cfg_.rc_max_quantizer = 56;
|
||||
cfg_.rc_end_usage = VPX_CBR;
|
||||
cfg_.g_lag_in_frames = 0;
|
||||
cfg_.g_threads = 2;
|
||||
|
||||
::libvpx_test::Y4mVideoSource video("noisy_clip_640_360.y4m", 0, 200);
|
||||
|
||||
// For the temporal denoiser (#if CONFIG_VP9_TEMPORAL_DENOISING),
|
||||
// there is only one denoiser mode: kDenoiserOnYOnly(which is 1),
|
||||
// but may add more modes in the future.
|
||||
cfg_.rc_target_bitrate = 1000;
|
||||
ResetModel();
|
||||
// Turn on the denoiser.
|
||||
denoiser_on_ = 1;
|
||||
ASSERT_NO_FATAL_FAILURE(RunLoop(&video));
|
||||
ASSERT_GE(effective_datarate_[0], cfg_.rc_target_bitrate * 0.85)
|
||||
<< " The datarate for the file is lower than target by too much!";
|
||||
ASSERT_LE(effective_datarate_[0], cfg_.rc_target_bitrate * 1.15)
|
||||
<< " The datarate for the file is greater than target by too much!";
|
||||
}
|
||||
|
||||
// Check basic datarate targeting, for a single bitrate, when denoiser is on,
|
||||
// for 1280x720 clip with 4 threads.
|
||||
TEST_P(DatarateTestVP9LargeDenoiser, 4threads) {
|
||||
cfg_.rc_buf_initial_sz = 500;
|
||||
cfg_.rc_buf_optimal_sz = 500;
|
||||
cfg_.rc_buf_sz = 1000;
|
||||
cfg_.rc_dropframe_thresh = 1;
|
||||
cfg_.rc_min_quantizer = 2;
|
||||
cfg_.rc_max_quantizer = 56;
|
||||
cfg_.rc_end_usage = VPX_CBR;
|
||||
cfg_.g_lag_in_frames = 0;
|
||||
cfg_.g_threads = 4;
|
||||
|
||||
::libvpx_test::Y4mVideoSource video("niklas_1280_720_30.y4m", 0, 300);
|
||||
|
||||
// For the temporal denoiser (#if CONFIG_VP9_TEMPORAL_DENOISING),
|
||||
// there is only one denoiser mode: denoiserYonly(which is 1),
|
||||
// but may add more modes in the future.
|
||||
cfg_.rc_target_bitrate = 1000;
|
||||
ResetModel();
|
||||
// Turn on the denoiser.
|
||||
denoiser_on_ = 1;
|
||||
ASSERT_NO_FATAL_FAILURE(RunLoop(&video));
|
||||
ASSERT_GE(effective_datarate_[0], cfg_.rc_target_bitrate * 0.85)
|
||||
<< " The datarate for the file is lower than target by too much!";
|
||||
ASSERT_LE(effective_datarate_[0], cfg_.rc_target_bitrate * 1.29)
|
||||
<< " The datarate for the file is greater than target by too much!";
|
||||
}
|
||||
|
||||
// Check basic datarate targeting, for a single bitrate, when denoiser is off
|
||||
// and on.
|
||||
TEST_P(DatarateTestVP9LargeDenoiser, DenoiserOffOn) {
|
||||
cfg_.rc_buf_initial_sz = 500;
|
||||
cfg_.rc_buf_optimal_sz = 500;
|
||||
cfg_.rc_buf_sz = 1000;
|
||||
cfg_.rc_dropframe_thresh = 1;
|
||||
cfg_.rc_min_quantizer = 2;
|
||||
cfg_.rc_max_quantizer = 56;
|
||||
cfg_.rc_end_usage = VPX_CBR;
|
||||
cfg_.g_lag_in_frames = 0;
|
||||
|
||||
::libvpx_test::I420VideoSource video("hantro_collage_w352h288.yuv", 352, 288,
|
||||
30, 1, 0, 299);
|
||||
|
||||
// For the temporal denoiser (#if CONFIG_VP9_TEMPORAL_DENOISING),
|
||||
// there is only one denoiser mode: denoiserYonly(which is 1),
|
||||
// but may add more modes in the future.
|
||||
cfg_.rc_target_bitrate = 300;
|
||||
ResetModel();
|
||||
// The denoiser is off by default.
|
||||
denoiser_on_ = 0;
|
||||
// Set the offon test flag.
|
||||
denoiser_offon_test_ = 1;
|
||||
denoiser_offon_period_ = 100;
|
||||
ASSERT_NO_FATAL_FAILURE(RunLoop(&video));
|
||||
ASSERT_GE(effective_datarate_[0], cfg_.rc_target_bitrate * 0.85)
|
||||
<< " The datarate for the file is lower than target by too much!";
|
||||
ASSERT_LE(effective_datarate_[0], cfg_.rc_target_bitrate * 1.15)
|
||||
<< " The datarate for the file is greater than target by too much!";
|
||||
}
|
||||
#endif // CONFIG_VP9_TEMPORAL_DENOISING
|
||||
|
||||
VP9_INSTANTIATE_TEST_CASE(DatarateTestVP9Large,
|
||||
::testing::Values(::libvpx_test::kOnePassGood,
|
||||
::libvpx_test::kRealTime),
|
||||
::testing::Range(2, 9), ::testing::Range(0, 4));
|
||||
|
||||
VP9_INSTANTIATE_TEST_CASE(DatarateTestVP9LargeOneBR,
|
||||
::testing::Values(::libvpx_test::kOnePassGood,
|
||||
::libvpx_test::kRealTime),
|
||||
::testing::Range(2, 9));
|
||||
|
||||
VP9_INSTANTIATE_TEST_CASE(DatarateTestVP9RealTime, ::testing::Range(5, 9));
|
||||
|
||||
#if CONFIG_VP9_TEMPORAL_DENOISING
|
||||
VP9_INSTANTIATE_TEST_CASE(DatarateTestVP9LargeDenoiser, ::testing::Range(5, 9));
|
||||
#endif
|
||||
} // namespace
|
@ -29,22 +29,11 @@ using libvpx_test::ACMRandom;
|
||||
namespace {
|
||||
|
||||
const int kNumPixels = 64 * 64;
|
||||
|
||||
typedef int (*Vp9DenoiserFilterFunc)(const uint8_t *sig, int sig_stride,
|
||||
const uint8_t *mc_avg, int mc_avg_stride,
|
||||
uint8_t *avg, int avg_stride,
|
||||
int increase_denoising, BLOCK_SIZE bs,
|
||||
int motion_magnitude);
|
||||
typedef ::testing::tuple<Vp9DenoiserFilterFunc, BLOCK_SIZE>
|
||||
VP9DenoiserTestParam;
|
||||
|
||||
class VP9DenoiserTest
|
||||
: public ::testing::Test,
|
||||
public ::testing::WithParamInterface<VP9DenoiserTestParam> {
|
||||
class VP9DenoiserTest : public ::testing::TestWithParam<BLOCK_SIZE> {
|
||||
public:
|
||||
virtual ~VP9DenoiserTest() {}
|
||||
|
||||
virtual void SetUp() { bs_ = GET_PARAM(1); }
|
||||
virtual void SetUp() { bs_ = GetParam(); }
|
||||
|
||||
virtual void TearDown() { libvpx_test::ClearSystemState(); }
|
||||
|
||||
@ -87,9 +76,9 @@ TEST_P(VP9DenoiserTest, BitexactCheck) {
|
||||
64, avg_block_c, 64, 0, bs_,
|
||||
motion_magnitude_random));
|
||||
|
||||
ASM_REGISTER_STATE_CHECK(GET_PARAM(0)(sig_block, 64, mc_avg_block, 64,
|
||||
avg_block_sse2, 64, 0, bs_,
|
||||
motion_magnitude_random));
|
||||
ASM_REGISTER_STATE_CHECK(vp9_denoiser_filter_sse2(
|
||||
sig_block, 64, mc_avg_block, 64, avg_block_sse2, 64, 0, bs_,
|
||||
motion_magnitude_random));
|
||||
|
||||
// Test bitexactness.
|
||||
for (int h = 0; h < (4 << b_height_log2_lookup[bs_]); ++h) {
|
||||
@ -100,36 +89,10 @@ TEST_P(VP9DenoiserTest, BitexactCheck) {
|
||||
}
|
||||
}
|
||||
|
||||
using ::testing::make_tuple;
|
||||
|
||||
// Test for all block size.
|
||||
#if HAVE_SSE2
|
||||
INSTANTIATE_TEST_CASE_P(
|
||||
SSE2, VP9DenoiserTest,
|
||||
::testing::Values(make_tuple(&vp9_denoiser_filter_sse2, BLOCK_8X8),
|
||||
make_tuple(&vp9_denoiser_filter_sse2, BLOCK_8X16),
|
||||
make_tuple(&vp9_denoiser_filter_sse2, BLOCK_16X8),
|
||||
make_tuple(&vp9_denoiser_filter_sse2, BLOCK_16X16),
|
||||
make_tuple(&vp9_denoiser_filter_sse2, BLOCK_16X32),
|
||||
make_tuple(&vp9_denoiser_filter_sse2, BLOCK_32X16),
|
||||
make_tuple(&vp9_denoiser_filter_sse2, BLOCK_32X32),
|
||||
make_tuple(&vp9_denoiser_filter_sse2, BLOCK_32X64),
|
||||
make_tuple(&vp9_denoiser_filter_sse2, BLOCK_64X32),
|
||||
make_tuple(&vp9_denoiser_filter_sse2, BLOCK_64X64)));
|
||||
#endif // HAVE_SSE2
|
||||
|
||||
#if HAVE_NEON
|
||||
INSTANTIATE_TEST_CASE_P(
|
||||
NEON, VP9DenoiserTest,
|
||||
::testing::Values(make_tuple(&vp9_denoiser_filter_neon, BLOCK_8X8),
|
||||
make_tuple(&vp9_denoiser_filter_neon, BLOCK_8X16),
|
||||
make_tuple(&vp9_denoiser_filter_neon, BLOCK_16X8),
|
||||
make_tuple(&vp9_denoiser_filter_neon, BLOCK_16X16),
|
||||
make_tuple(&vp9_denoiser_filter_neon, BLOCK_16X32),
|
||||
make_tuple(&vp9_denoiser_filter_neon, BLOCK_32X16),
|
||||
make_tuple(&vp9_denoiser_filter_neon, BLOCK_32X32),
|
||||
make_tuple(&vp9_denoiser_filter_neon, BLOCK_32X64),
|
||||
make_tuple(&vp9_denoiser_filter_neon, BLOCK_64X32),
|
||||
make_tuple(&vp9_denoiser_filter_neon, BLOCK_64X64)));
|
||||
#endif
|
||||
INSTANTIATE_TEST_CASE_P(SSE2, VP9DenoiserTest,
|
||||
::testing::Values(BLOCK_8X8, BLOCK_8X16, BLOCK_16X8,
|
||||
BLOCK_16X16, BLOCK_16X32, BLOCK_32X16,
|
||||
BLOCK_32X32, BLOCK_32X64, BLOCK_64X32,
|
||||
BLOCK_64X64));
|
||||
} // namespace
|
@ -99,7 +99,9 @@ class VpxEncoderParmsGetToDecoder
|
||||
vpx_codec_ctx_t *const vp9_decoder = decoder->GetDecoder();
|
||||
vpx_codec_alg_priv_t *const priv =
|
||||
reinterpret_cast<vpx_codec_alg_priv_t *>(vp9_decoder->priv);
|
||||
VP9_COMMON *const common = &priv->pbi->common;
|
||||
FrameWorkerData *const worker_data =
|
||||
reinterpret_cast<FrameWorkerData *>(priv->frame_workers[0].data1);
|
||||
VP9_COMMON *const common = &worker_data->pbi->common;
|
||||
|
||||
if (encode_parms.lossless) {
|
||||
EXPECT_EQ(0, common->base_qindex);
|
||||
|
@ -59,7 +59,7 @@ const TestVideoParam kTestVectors[] = {
|
||||
// Encoding modes tested
|
||||
const libvpx_test::TestMode kEncodingModeVectors[] = {
|
||||
::libvpx_test::kTwoPassGood, ::libvpx_test::kOnePassGood,
|
||||
::libvpx_test::kRealTime
|
||||
::libvpx_test::kRealTime,
|
||||
};
|
||||
|
||||
// Speed settings tested
|
||||
|
@ -23,36 +23,36 @@
|
||||
#include "vp9/common/vp9_entropy.h"
|
||||
#include "vpx/vpx_codec.h"
|
||||
#include "vpx/vpx_integer.h"
|
||||
#include "vpx_dsp/vpx_dsp_common.h"
|
||||
|
||||
using libvpx_test::ACMRandom;
|
||||
|
||||
namespace {
|
||||
#if CONFIG_VP9_HIGHBITDEPTH
|
||||
const int kNumIterations = 1000;
|
||||
|
||||
typedef int64_t (*HBDBlockErrorFunc)(const tran_low_t *coeff,
|
||||
const tran_low_t *dqcoeff,
|
||||
intptr_t block_size, int64_t *ssz,
|
||||
int bps);
|
||||
|
||||
typedef ::testing::tuple<HBDBlockErrorFunc, HBDBlockErrorFunc, vpx_bit_depth_t>
|
||||
BlockErrorParam;
|
||||
|
||||
typedef int64_t (*BlockErrorFunc)(const tran_low_t *coeff,
|
||||
typedef int64_t (*ErrorBlockFunc)(const tran_low_t *coeff,
|
||||
const tran_low_t *dqcoeff,
|
||||
intptr_t block_size, int64_t *ssz);
|
||||
intptr_t block_size, int64_t *ssz, int bps);
|
||||
|
||||
template <BlockErrorFunc fn>
|
||||
int64_t BlockError8BitWrapper(const tran_low_t *coeff,
|
||||
const tran_low_t *dqcoeff, intptr_t block_size,
|
||||
int64_t *ssz, int bps) {
|
||||
EXPECT_EQ(bps, 8);
|
||||
typedef std::tr1::tuple<ErrorBlockFunc, ErrorBlockFunc, vpx_bit_depth_t>
|
||||
ErrorBlockParam;
|
||||
|
||||
// wrapper for 8-bit block error functions without a 'bps' param.
|
||||
typedef int64_t (*HighBdBlockError8bit)(const tran_low_t *coeff,
|
||||
const tran_low_t *dqcoeff,
|
||||
intptr_t block_size, int64_t *ssz);
|
||||
template <HighBdBlockError8bit fn>
|
||||
int64_t HighBdBlockError8bitWrapper(const tran_low_t *coeff,
|
||||
const tran_low_t *dqcoeff,
|
||||
intptr_t block_size, int64_t *ssz,
|
||||
int bps) {
|
||||
EXPECT_EQ(8, bps);
|
||||
return fn(coeff, dqcoeff, block_size, ssz);
|
||||
}
|
||||
|
||||
class BlockErrorTest : public ::testing::TestWithParam<BlockErrorParam> {
|
||||
class ErrorBlockTest : public ::testing::TestWithParam<ErrorBlockParam> {
|
||||
public:
|
||||
virtual ~BlockErrorTest() {}
|
||||
virtual ~ErrorBlockTest() {}
|
||||
virtual void SetUp() {
|
||||
error_block_op_ = GET_PARAM(0);
|
||||
ref_error_block_op_ = GET_PARAM(1);
|
||||
@ -63,11 +63,11 @@ class BlockErrorTest : public ::testing::TestWithParam<BlockErrorParam> {
|
||||
|
||||
protected:
|
||||
vpx_bit_depth_t bit_depth_;
|
||||
HBDBlockErrorFunc error_block_op_;
|
||||
HBDBlockErrorFunc ref_error_block_op_;
|
||||
ErrorBlockFunc error_block_op_;
|
||||
ErrorBlockFunc ref_error_block_op_;
|
||||
};
|
||||
|
||||
TEST_P(BlockErrorTest, OperationCheck) {
|
||||
TEST_P(ErrorBlockTest, OperationCheck) {
|
||||
ACMRandom rnd(ACMRandom::DeterministicSeed());
|
||||
DECLARE_ALIGNED(16, tran_low_t, coeff[4096]);
|
||||
DECLARE_ALIGNED(16, tran_low_t, dqcoeff[4096]);
|
||||
@ -110,7 +110,7 @@ TEST_P(BlockErrorTest, OperationCheck) {
|
||||
<< "First failed at test case " << first_failure;
|
||||
}
|
||||
|
||||
TEST_P(BlockErrorTest, ExtremeValues) {
|
||||
TEST_P(ErrorBlockTest, ExtremeValues) {
|
||||
ACMRandom rnd(ACMRandom::DeterministicSeed());
|
||||
DECLARE_ALIGNED(16, tran_low_t, coeff[4096]);
|
||||
DECLARE_ALIGNED(16, tran_low_t, dqcoeff[4096]);
|
||||
@ -168,31 +168,32 @@ TEST_P(BlockErrorTest, ExtremeValues) {
|
||||
<< "First failed at test case " << first_failure;
|
||||
}
|
||||
|
||||
using ::testing::make_tuple;
|
||||
using std::tr1::make_tuple;
|
||||
|
||||
#if HAVE_SSE2
|
||||
const BlockErrorParam sse2_block_error_tests[] = {
|
||||
#if CONFIG_VP9_HIGHBITDEPTH
|
||||
make_tuple(&vp9_highbd_block_error_sse2, &vp9_highbd_block_error_c,
|
||||
VPX_BITS_10),
|
||||
make_tuple(&vp9_highbd_block_error_sse2, &vp9_highbd_block_error_c,
|
||||
VPX_BITS_12),
|
||||
make_tuple(&vp9_highbd_block_error_sse2, &vp9_highbd_block_error_c,
|
||||
VPX_BITS_8),
|
||||
#endif // CONFIG_VP9_HIGHBITDEPTH
|
||||
make_tuple(&BlockError8BitWrapper<vp9_block_error_sse2>,
|
||||
&BlockError8BitWrapper<vp9_block_error_c>, VPX_BITS_8)
|
||||
};
|
||||
|
||||
INSTANTIATE_TEST_CASE_P(SSE2, BlockErrorTest,
|
||||
::testing::ValuesIn(sse2_block_error_tests));
|
||||
INSTANTIATE_TEST_CASE_P(
|
||||
SSE2, ErrorBlockTest,
|
||||
::testing::Values(
|
||||
make_tuple(&vp9_highbd_block_error_sse2, &vp9_highbd_block_error_c,
|
||||
VPX_BITS_10),
|
||||
make_tuple(&vp9_highbd_block_error_sse2, &vp9_highbd_block_error_c,
|
||||
VPX_BITS_12),
|
||||
make_tuple(&vp9_highbd_block_error_sse2, &vp9_highbd_block_error_c,
|
||||
VPX_BITS_8),
|
||||
make_tuple(
|
||||
&HighBdBlockError8bitWrapper<vp9_highbd_block_error_8bit_sse2>,
|
||||
&HighBdBlockError8bitWrapper<vp9_highbd_block_error_8bit_c>,
|
||||
VPX_BITS_8)));
|
||||
#endif // HAVE_SSE2
|
||||
|
||||
#if HAVE_AVX2
|
||||
#if HAVE_AVX
|
||||
INSTANTIATE_TEST_CASE_P(
|
||||
AVX2, BlockErrorTest,
|
||||
::testing::Values(make_tuple(&BlockError8BitWrapper<vp9_block_error_avx2>,
|
||||
&BlockError8BitWrapper<vp9_block_error_c>,
|
||||
VPX_BITS_8)));
|
||||
#endif // HAVE_AVX2
|
||||
AVX, ErrorBlockTest,
|
||||
::testing::Values(make_tuple(
|
||||
&HighBdBlockError8bitWrapper<vp9_highbd_block_error_8bit_avx>,
|
||||
&HighBdBlockError8bitWrapper<vp9_highbd_block_error_8bit_c>,
|
||||
VPX_BITS_8)));
|
||||
#endif // HAVE_AVX
|
||||
|
||||
#endif // CONFIG_VP9_HIGHBITDEPTH
|
||||
} // namespace
|
@ -16,207 +16,8 @@
|
||||
#include "test/md5_helper.h"
|
||||
#include "test/util.h"
|
||||
#include "test/y4m_video_source.h"
|
||||
#include "vp9/encoder/vp9_firstpass.h"
|
||||
|
||||
namespace {
|
||||
// FIRSTPASS_STATS struct:
|
||||
// {
|
||||
// 25 double members;
|
||||
// 1 int64_t member;
|
||||
// }
|
||||
// Whenever FIRSTPASS_STATS struct is modified, the following constants need to
|
||||
// be revisited.
|
||||
const int kDbl = 25;
|
||||
const int kInt = 1;
|
||||
const size_t kFirstPassStatsSz = kDbl * sizeof(double) + kInt * sizeof(int64_t);
|
||||
|
||||
class VPxFirstPassEncoderThreadTest
|
||||
: public ::libvpx_test::EncoderTest,
|
||||
public ::libvpx_test::CodecTestWith2Params<libvpx_test::TestMode, int> {
|
||||
protected:
|
||||
VPxFirstPassEncoderThreadTest()
|
||||
: EncoderTest(GET_PARAM(0)), encoder_initialized_(false), tiles_(0),
|
||||
encoding_mode_(GET_PARAM(1)), set_cpu_used_(GET_PARAM(2)) {
|
||||
init_flags_ = VPX_CODEC_USE_PSNR;
|
||||
|
||||
row_mt_mode_ = 1;
|
||||
first_pass_only_ = true;
|
||||
firstpass_stats_.buf = NULL;
|
||||
firstpass_stats_.sz = 0;
|
||||
}
|
||||
virtual ~VPxFirstPassEncoderThreadTest() { free(firstpass_stats_.buf); }
|
||||
|
||||
virtual void SetUp() {
|
||||
InitializeConfig();
|
||||
SetMode(encoding_mode_);
|
||||
|
||||
cfg_.rc_end_usage = VPX_VBR;
|
||||
cfg_.rc_2pass_vbr_minsection_pct = 5;
|
||||
cfg_.rc_2pass_vbr_maxsection_pct = 2000;
|
||||
cfg_.rc_max_quantizer = 56;
|
||||
cfg_.rc_min_quantizer = 0;
|
||||
}
|
||||
|
||||
virtual void BeginPassHook(unsigned int /*pass*/) {
|
||||
encoder_initialized_ = false;
|
||||
abort_ = false;
|
||||
}
|
||||
|
||||
virtual void EndPassHook() {
|
||||
// For first pass stats test, only run first pass encoder.
|
||||
if (first_pass_only_ && cfg_.g_pass == VPX_RC_FIRST_PASS)
|
||||
abort_ |= first_pass_only_;
|
||||
}
|
||||
|
||||
virtual void PreEncodeFrameHook(::libvpx_test::VideoSource * /*video*/,
|
||||
::libvpx_test::Encoder *encoder) {
|
||||
if (!encoder_initialized_) {
|
||||
// Encode in 2-pass mode.
|
||||
encoder->Control(VP9E_SET_TILE_COLUMNS, tiles_);
|
||||
encoder->Control(VP8E_SET_CPUUSED, set_cpu_used_);
|
||||
encoder->Control(VP8E_SET_ENABLEAUTOALTREF, 1);
|
||||
encoder->Control(VP8E_SET_ARNR_MAXFRAMES, 7);
|
||||
encoder->Control(VP8E_SET_ARNR_STRENGTH, 5);
|
||||
encoder->Control(VP8E_SET_ARNR_TYPE, 3);
|
||||
encoder->Control(VP9E_SET_FRAME_PARALLEL_DECODING, 0);
|
||||
|
||||
if (encoding_mode_ == ::libvpx_test::kTwoPassGood)
|
||||
encoder->Control(VP9E_SET_ROW_MT, row_mt_mode_);
|
||||
|
||||
encoder_initialized_ = true;
|
||||
}
|
||||
}
|
||||
|
||||
virtual void StatsPktHook(const vpx_codec_cx_pkt_t *pkt) {
|
||||
const uint8_t *const pkt_buf =
|
||||
reinterpret_cast<uint8_t *>(pkt->data.twopass_stats.buf);
|
||||
const size_t pkt_size = pkt->data.twopass_stats.sz;
|
||||
|
||||
// First pass stats size equals sizeof(FIRSTPASS_STATS)
|
||||
EXPECT_EQ(pkt_size, kFirstPassStatsSz)
|
||||
<< "Error: First pass stats size doesn't equal kFirstPassStatsSz";
|
||||
|
||||
firstpass_stats_.buf =
|
||||
realloc(firstpass_stats_.buf, firstpass_stats_.sz + pkt_size);
|
||||
memcpy((uint8_t *)firstpass_stats_.buf + firstpass_stats_.sz, pkt_buf,
|
||||
pkt_size);
|
||||
firstpass_stats_.sz += pkt_size;
|
||||
}
|
||||
|
||||
bool encoder_initialized_;
|
||||
int tiles_;
|
||||
::libvpx_test::TestMode encoding_mode_;
|
||||
int set_cpu_used_;
|
||||
int row_mt_mode_;
|
||||
bool first_pass_only_;
|
||||
vpx_fixed_buf_t firstpass_stats_;
|
||||
};
|
||||
|
||||
static void compare_fp_stats(vpx_fixed_buf_t *fp_stats, double factor) {
|
||||
// fp_stats consists of 2 set of first pass encoding stats. These 2 set of
|
||||
// stats are compared to check if the stats match or at least are very close.
|
||||
FIRSTPASS_STATS *stats1 = reinterpret_cast<FIRSTPASS_STATS *>(fp_stats->buf);
|
||||
int nframes_ = (int)(fp_stats->sz / sizeof(FIRSTPASS_STATS));
|
||||
FIRSTPASS_STATS *stats2 = stats1 + nframes_ / 2;
|
||||
int i, j;
|
||||
|
||||
// The total stats are also output and included in the first pass stats. Here
|
||||
// ignore that in the comparison.
|
||||
for (i = 0; i < (nframes_ / 2 - 1); ++i) {
|
||||
const double *frame_stats1 = reinterpret_cast<double *>(stats1);
|
||||
const double *frame_stats2 = reinterpret_cast<double *>(stats2);
|
||||
|
||||
for (j = 0; j < kDbl; ++j) {
|
||||
ASSERT_LE(fabs(*frame_stats1 - *frame_stats2),
|
||||
fabs(*frame_stats1) / factor)
|
||||
<< "First failure @ frame #" << i << " stat #" << j << " ("
|
||||
<< *frame_stats1 << " vs. " << *frame_stats2 << ")";
|
||||
frame_stats1++;
|
||||
frame_stats2++;
|
||||
}
|
||||
|
||||
stats1++;
|
||||
stats2++;
|
||||
}
|
||||
|
||||
// Reset firstpass_stats_ to 0.
|
||||
memset((uint8_t *)fp_stats->buf, 0, fp_stats->sz);
|
||||
fp_stats->sz = 0;
|
||||
}
|
||||
|
||||
static void compare_fp_stats_md5(vpx_fixed_buf_t *fp_stats) {
|
||||
// fp_stats consists of 2 set of first pass encoding stats. These 2 set of
|
||||
// stats are compared to check if the stats match.
|
||||
uint8_t *stats1 = reinterpret_cast<uint8_t *>(fp_stats->buf);
|
||||
uint8_t *stats2 = stats1 + fp_stats->sz / 2;
|
||||
::libvpx_test::MD5 md5_row_mt_0, md5_row_mt_1;
|
||||
|
||||
md5_row_mt_0.Add(stats1, fp_stats->sz / 2);
|
||||
const char *md5_row_mt_0_str = md5_row_mt_0.Get();
|
||||
|
||||
md5_row_mt_1.Add(stats2, fp_stats->sz / 2);
|
||||
const char *md5_row_mt_1_str = md5_row_mt_1.Get();
|
||||
|
||||
// Check md5 match.
|
||||
ASSERT_STREQ(md5_row_mt_0_str, md5_row_mt_1_str)
|
||||
<< "MD5 checksums don't match";
|
||||
|
||||
// Reset firstpass_stats_ to 0.
|
||||
memset((uint8_t *)fp_stats->buf, 0, fp_stats->sz);
|
||||
fp_stats->sz = 0;
|
||||
}
|
||||
|
||||
TEST_P(VPxFirstPassEncoderThreadTest, FirstPassStatsTest) {
|
||||
::libvpx_test::Y4mVideoSource video("niklas_1280_720_30.y4m", 0, 60);
|
||||
|
||||
first_pass_only_ = true;
|
||||
cfg_.rc_target_bitrate = 1000;
|
||||
|
||||
// Test row_mt_mode: 0 vs 1 at single thread case(threads = 1, tiles_ = 0)
|
||||
tiles_ = 0;
|
||||
cfg_.g_threads = 1;
|
||||
|
||||
row_mt_mode_ = 0;
|
||||
init_flags_ = VPX_CODEC_USE_PSNR;
|
||||
ASSERT_NO_FATAL_FAILURE(RunLoop(&video));
|
||||
|
||||
row_mt_mode_ = 1;
|
||||
ASSERT_NO_FATAL_FAILURE(RunLoop(&video));
|
||||
|
||||
// Compare to check if using or not using row-mt generates close stats.
|
||||
ASSERT_NO_FATAL_FAILURE(compare_fp_stats(&firstpass_stats_, 1000.0));
|
||||
|
||||
// Test single thread vs multiple threads
|
||||
row_mt_mode_ = 1;
|
||||
tiles_ = 0;
|
||||
|
||||
cfg_.g_threads = 1;
|
||||
init_flags_ = VPX_CODEC_USE_PSNR;
|
||||
ASSERT_NO_FATAL_FAILURE(RunLoop(&video));
|
||||
|
||||
cfg_.g_threads = 4;
|
||||
ASSERT_NO_FATAL_FAILURE(RunLoop(&video));
|
||||
|
||||
// Compare to check if single-thread and multi-thread stats are close enough.
|
||||
ASSERT_NO_FATAL_FAILURE(compare_fp_stats(&firstpass_stats_, 1000.0));
|
||||
|
||||
// Bit exact test in row_mt mode.
|
||||
// When row_mt_mode_=1 and using >1 threads, the encoder generates bit exact
|
||||
// result.
|
||||
row_mt_mode_ = 1;
|
||||
tiles_ = 2;
|
||||
|
||||
cfg_.g_threads = 2;
|
||||
init_flags_ = VPX_CODEC_USE_PSNR;
|
||||
ASSERT_NO_FATAL_FAILURE(RunLoop(&video));
|
||||
|
||||
cfg_.g_threads = 8;
|
||||
ASSERT_NO_FATAL_FAILURE(RunLoop(&video));
|
||||
|
||||
// Compare to check if stats match with row-mt=0/1.
|
||||
compare_fp_stats_md5(&firstpass_stats_);
|
||||
}
|
||||
|
||||
class VPxEncoderThreadTest
|
||||
: public ::libvpx_test::EncoderTest,
|
||||
public ::libvpx_test::CodecTestWith4Params<libvpx_test::TestMode, int,
|
||||
@ -228,9 +29,6 @@ class VPxEncoderThreadTest
|
||||
encoding_mode_(GET_PARAM(1)), set_cpu_used_(GET_PARAM(2)) {
|
||||
init_flags_ = VPX_CODEC_USE_PSNR;
|
||||
md5_.clear();
|
||||
row_mt_mode_ = 1;
|
||||
psnr_ = 0.0;
|
||||
nframes_ = 0;
|
||||
}
|
||||
virtual ~VPxEncoderThreadTest() {}
|
||||
|
||||
@ -239,6 +37,7 @@ class VPxEncoderThreadTest
|
||||
SetMode(encoding_mode_);
|
||||
|
||||
if (encoding_mode_ != ::libvpx_test::kRealTime) {
|
||||
cfg_.g_lag_in_frames = 3;
|
||||
cfg_.rc_end_usage = VPX_VBR;
|
||||
cfg_.rc_2pass_vbr_minsection_pct = 5;
|
||||
cfg_.rc_2pass_vbr_maxsection_pct = 2000;
|
||||
@ -253,8 +52,6 @@ class VPxEncoderThreadTest
|
||||
|
||||
virtual void BeginPassHook(unsigned int /*pass*/) {
|
||||
encoder_initialized_ = false;
|
||||
psnr_ = 0.0;
|
||||
nframes_ = 0;
|
||||
}
|
||||
|
||||
virtual void PreEncodeFrameHook(::libvpx_test::VideoSource * /*video*/,
|
||||
@ -273,17 +70,10 @@ class VPxEncoderThreadTest
|
||||
encoder->Control(VP8E_SET_ENABLEAUTOALTREF, 0);
|
||||
encoder->Control(VP9E_SET_AQ_MODE, 3);
|
||||
}
|
||||
encoder->Control(VP9E_SET_ROW_MT, row_mt_mode_);
|
||||
|
||||
encoder_initialized_ = true;
|
||||
}
|
||||
}
|
||||
|
||||
virtual void PSNRPktHook(const vpx_codec_cx_pkt_t *pkt) {
|
||||
psnr_ += pkt->data.psnr.psnr[0];
|
||||
nframes_++;
|
||||
}
|
||||
|
||||
virtual void DecompressedFrameHook(const vpx_image_t &img,
|
||||
vpx_codec_pts_t /*pts*/) {
|
||||
::libvpx_test::MD5 md5_res;
|
||||
@ -302,127 +92,43 @@ class VPxEncoderThreadTest
|
||||
return true;
|
||||
}
|
||||
|
||||
double GetAveragePsnr() const { return nframes_ ? (psnr_ / nframes_) : 0.0; }
|
||||
|
||||
bool encoder_initialized_;
|
||||
int tiles_;
|
||||
int threads_;
|
||||
::libvpx_test::TestMode encoding_mode_;
|
||||
int set_cpu_used_;
|
||||
int row_mt_mode_;
|
||||
double psnr_;
|
||||
unsigned int nframes_;
|
||||
std::vector<std::string> md5_;
|
||||
};
|
||||
|
||||
TEST_P(VPxEncoderThreadTest, EncoderResultTest) {
|
||||
::libvpx_test::Y4mVideoSource video("niklas_1280_720_30.y4m", 15, 20);
|
||||
cfg_.rc_target_bitrate = 1000;
|
||||
std::vector<std::string> single_thr_md5, multi_thr_md5;
|
||||
|
||||
// Part 1: Bit exact test for row_mt_mode_ = 0.
|
||||
// This part keeps original unit tests done before row-mt code is checked in.
|
||||
row_mt_mode_ = 0;
|
||||
::libvpx_test::Y4mVideoSource video("niklas_1280_720_30.y4m", 15, 20);
|
||||
|
||||
cfg_.rc_target_bitrate = 1000;
|
||||
|
||||
// Encode using single thread.
|
||||
cfg_.g_threads = 1;
|
||||
init_flags_ = VPX_CODEC_USE_PSNR;
|
||||
ASSERT_NO_FATAL_FAILURE(RunLoop(&video));
|
||||
const std::vector<std::string> single_thr_md5 = md5_;
|
||||
single_thr_md5 = md5_;
|
||||
md5_.clear();
|
||||
|
||||
// Encode using multiple threads.
|
||||
cfg_.g_threads = threads_;
|
||||
ASSERT_NO_FATAL_FAILURE(RunLoop(&video));
|
||||
const std::vector<std::string> multi_thr_md5 = md5_;
|
||||
multi_thr_md5 = md5_;
|
||||
md5_.clear();
|
||||
|
||||
// Compare to check if two vectors are equal.
|
||||
ASSERT_EQ(single_thr_md5, multi_thr_md5);
|
||||
|
||||
// Part 2: row_mt_mode_ = 0 vs row_mt_mode_ = 1 single thread bit exact test.
|
||||
row_mt_mode_ = 1;
|
||||
|
||||
// Encode using single thread
|
||||
cfg_.g_threads = 1;
|
||||
init_flags_ = VPX_CODEC_USE_PSNR;
|
||||
ASSERT_NO_FATAL_FAILURE(RunLoop(&video));
|
||||
std::vector<std::string> row_mt_single_thr_md5 = md5_;
|
||||
md5_.clear();
|
||||
|
||||
ASSERT_EQ(single_thr_md5, row_mt_single_thr_md5);
|
||||
|
||||
// Part 3: Bit exact test with row-mt on
|
||||
// When row_mt_mode_=1 and using >1 threads, the encoder generates bit exact
|
||||
// result.
|
||||
row_mt_mode_ = 1;
|
||||
row_mt_single_thr_md5.clear();
|
||||
|
||||
// Encode using 2 threads.
|
||||
cfg_.g_threads = 2;
|
||||
init_flags_ = VPX_CODEC_USE_PSNR;
|
||||
ASSERT_NO_FATAL_FAILURE(RunLoop(&video));
|
||||
row_mt_single_thr_md5 = md5_;
|
||||
md5_.clear();
|
||||
|
||||
// Encode using multiple threads.
|
||||
cfg_.g_threads = threads_;
|
||||
ASSERT_NO_FATAL_FAILURE(RunLoop(&video));
|
||||
const std::vector<std::string> row_mt_multi_thr_md5 = md5_;
|
||||
md5_.clear();
|
||||
|
||||
// Compare to check if two vectors are equal.
|
||||
ASSERT_EQ(row_mt_single_thr_md5, row_mt_multi_thr_md5);
|
||||
|
||||
// Part 4: PSNR test with bit_match_mode_ = 0
|
||||
row_mt_mode_ = 1;
|
||||
|
||||
// Encode using single thread.
|
||||
cfg_.g_threads = 1;
|
||||
init_flags_ = VPX_CODEC_USE_PSNR;
|
||||
ASSERT_NO_FATAL_FAILURE(RunLoop(&video));
|
||||
const double single_thr_psnr = GetAveragePsnr();
|
||||
|
||||
// Encode using multiple threads.
|
||||
cfg_.g_threads = threads_;
|
||||
ASSERT_NO_FATAL_FAILURE(RunLoop(&video));
|
||||
const double multi_thr_psnr = GetAveragePsnr();
|
||||
|
||||
EXPECT_NEAR(single_thr_psnr, multi_thr_psnr, 0.1);
|
||||
}
|
||||
|
||||
INSTANTIATE_TEST_CASE_P(
|
||||
VP9, VPxFirstPassEncoderThreadTest,
|
||||
::testing::Combine(
|
||||
::testing::Values(
|
||||
static_cast<const libvpx_test::CodecFactory *>(&libvpx_test::kVP9)),
|
||||
::testing::Values(::libvpx_test::kTwoPassGood),
|
||||
::testing::Range(0, 4))); // cpu_used
|
||||
|
||||
// Split this into two instantiations so that we can distinguish
|
||||
// between very slow runs ( ie cpu_speed 0 ) vs ones that can be
|
||||
// run nightly by adding Large to the title.
|
||||
INSTANTIATE_TEST_CASE_P(
|
||||
VP9, VPxEncoderThreadTest,
|
||||
::testing::Combine(
|
||||
::testing::Values(
|
||||
static_cast<const libvpx_test::CodecFactory *>(&libvpx_test::kVP9)),
|
||||
::testing::Values(::libvpx_test::kTwoPassGood,
|
||||
::libvpx_test::kOnePassGood,
|
||||
::libvpx_test::kRealTime),
|
||||
::testing::Range(3, 9), // cpu_used
|
||||
::testing::Range(0, 3), // tile_columns
|
||||
::testing::Range(2, 5))); // threads
|
||||
|
||||
INSTANTIATE_TEST_CASE_P(
|
||||
VP9Large, VPxEncoderThreadTest,
|
||||
::testing::Combine(
|
||||
::testing::Values(
|
||||
static_cast<const libvpx_test::CodecFactory *>(&libvpx_test::kVP9)),
|
||||
::testing::Values(::libvpx_test::kTwoPassGood,
|
||||
::libvpx_test::kOnePassGood,
|
||||
::libvpx_test::kRealTime),
|
||||
::testing::Range(0, 3), // cpu_used
|
||||
::testing::Range(0, 3), // tile_columns
|
||||
::testing::Range(2, 5))); // threads
|
||||
|
||||
VP9_INSTANTIATE_TEST_CASE(VPxEncoderThreadTest,
|
||||
::testing::Values(::libvpx_test::kTwoPassGood,
|
||||
::libvpx_test::kOnePassGood,
|
||||
::libvpx_test::kRealTime),
|
||||
::testing::Range(0, 9), // cpu_used
|
||||
::testing::Range(0, 3), // tile_columns
|
||||
::testing::Range(2, 5)); // threads
|
||||
} // namespace
|
||||
|
217
test/vp9_frame_parallel_test.cc
Normal file
217
test/vp9_frame_parallel_test.cc
Normal file
@ -0,0 +1,217 @@
|
||||
/*
|
||||
* Copyright (c) 2014 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 <cstdio>
|
||||
#include <cstdlib>
|
||||
#include <string>
|
||||
#include "third_party/googletest/src/include/gtest/gtest.h"
|
||||
#include "./vpx_config.h"
|
||||
#include "test/codec_factory.h"
|
||||
#include "test/decode_test_driver.h"
|
||||
#include "test/ivf_video_source.h"
|
||||
#include "test/md5_helper.h"
|
||||
#include "test/util.h"
|
||||
#if CONFIG_WEBM_IO
|
||||
#include "test/webm_video_source.h"
|
||||
#endif
|
||||
#include "vpx_mem/vpx_mem.h"
|
||||
|
||||
namespace {
|
||||
|
||||
using std::string;
|
||||
|
||||
#if CONFIG_WEBM_IO
|
||||
|
||||
struct PauseFileList {
|
||||
const char *name;
|
||||
// md5 sum for decoded frames which does not include skipped frames.
|
||||
const char *expected_md5;
|
||||
const int pause_frame_num;
|
||||
};
|
||||
|
||||
// Decodes |filename| with |num_threads|. Pause at the specified frame_num,
|
||||
// seek to next key frame and then continue decoding until the end. Return
|
||||
// the md5 of the decoded frames which does not include skipped frames.
|
||||
string DecodeFileWithPause(const string &filename, int num_threads,
|
||||
int pause_num) {
|
||||
libvpx_test::WebMVideoSource video(filename);
|
||||
video.Init();
|
||||
int in_frames = 0;
|
||||
int out_frames = 0;
|
||||
|
||||
vpx_codec_dec_cfg_t cfg = vpx_codec_dec_cfg_t();
|
||||
cfg.threads = num_threads;
|
||||
vpx_codec_flags_t flags = 0;
|
||||
flags |= VPX_CODEC_USE_FRAME_THREADING;
|
||||
libvpx_test::VP9Decoder decoder(cfg, flags);
|
||||
|
||||
libvpx_test::MD5 md5;
|
||||
video.Begin();
|
||||
|
||||
do {
|
||||
++in_frames;
|
||||
const vpx_codec_err_t res =
|
||||
decoder.DecodeFrame(video.cxdata(), video.frame_size());
|
||||
if (res != VPX_CODEC_OK) {
|
||||
EXPECT_EQ(VPX_CODEC_OK, res) << decoder.DecodeError();
|
||||
break;
|
||||
}
|
||||
|
||||
// Pause at specified frame number.
|
||||
if (in_frames == pause_num) {
|
||||
// Flush the decoder and then seek to next key frame.
|
||||
decoder.DecodeFrame(NULL, 0);
|
||||
video.SeekToNextKeyFrame();
|
||||
} else {
|
||||
video.Next();
|
||||
}
|
||||
|
||||
// Flush the decoder at the end of the video.
|
||||
if (!video.cxdata()) decoder.DecodeFrame(NULL, 0);
|
||||
|
||||
libvpx_test::DxDataIterator dec_iter = decoder.GetDxData();
|
||||
const vpx_image_t *img;
|
||||
|
||||
// Get decompressed data
|
||||
while ((img = dec_iter.Next())) {
|
||||
++out_frames;
|
||||
md5.Add(img);
|
||||
}
|
||||
} while (video.cxdata() != NULL);
|
||||
|
||||
EXPECT_EQ(in_frames, out_frames)
|
||||
<< "Input frame count does not match output frame count";
|
||||
|
||||
return string(md5.Get());
|
||||
}
|
||||
|
||||
void DecodeFilesWithPause(const PauseFileList files[]) {
|
||||
for (const PauseFileList *iter = files; iter->name != NULL; ++iter) {
|
||||
SCOPED_TRACE(iter->name);
|
||||
for (int t = 2; t <= 8; ++t) {
|
||||
EXPECT_EQ(iter->expected_md5,
|
||||
DecodeFileWithPause(iter->name, t, iter->pause_frame_num))
|
||||
<< "threads = " << t;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
TEST(VP9MultiThreadedFrameParallel, PauseSeekResume) {
|
||||
// vp90-2-07-frame_parallel-1.webm is a 40 frame video file with
|
||||
// one key frame for every ten frames.
|
||||
static const PauseFileList files[] = {
|
||||
{ "vp90-2-07-frame_parallel-1.webm", "6ea7c3875d67252e7caf2bc6e75b36b1",
|
||||
6 },
|
||||
{ "vp90-2-07-frame_parallel-1.webm", "4bb634160c7356a8d7d4299b6dc83a45",
|
||||
12 },
|
||||
{ "vp90-2-07-frame_parallel-1.webm", "89772591e6ef461f9fa754f916c78ed8",
|
||||
26 },
|
||||
{ NULL, NULL, 0 },
|
||||
};
|
||||
DecodeFilesWithPause(files);
|
||||
}
|
||||
|
||||
struct FileList {
|
||||
const char *name;
|
||||
// md5 sum for decoded frames which does not include corrupted frames.
|
||||
const char *expected_md5;
|
||||
// Expected number of decoded frames which does not include corrupted frames.
|
||||
const int expected_frame_count;
|
||||
};
|
||||
|
||||
// Decodes |filename| with |num_threads|. Return the md5 of the decoded
|
||||
// frames which does not include corrupted frames.
|
||||
string DecodeFile(const string &filename, int num_threads,
|
||||
int expected_frame_count) {
|
||||
libvpx_test::WebMVideoSource video(filename);
|
||||
video.Init();
|
||||
|
||||
vpx_codec_dec_cfg_t cfg = vpx_codec_dec_cfg_t();
|
||||
cfg.threads = num_threads;
|
||||
const vpx_codec_flags_t flags = VPX_CODEC_USE_FRAME_THREADING;
|
||||
libvpx_test::VP9Decoder decoder(cfg, flags);
|
||||
|
||||
libvpx_test::MD5 md5;
|
||||
video.Begin();
|
||||
|
||||
int out_frames = 0;
|
||||
do {
|
||||
const vpx_codec_err_t res =
|
||||
decoder.DecodeFrame(video.cxdata(), video.frame_size());
|
||||
// TODO(hkuang): frame parallel mode should return an error on corruption.
|
||||
if (res != VPX_CODEC_OK) {
|
||||
EXPECT_EQ(VPX_CODEC_OK, res) << decoder.DecodeError();
|
||||
break;
|
||||
}
|
||||
|
||||
video.Next();
|
||||
|
||||
// Flush the decoder at the end of the video.
|
||||
if (!video.cxdata()) decoder.DecodeFrame(NULL, 0);
|
||||
|
||||
libvpx_test::DxDataIterator dec_iter = decoder.GetDxData();
|
||||
const vpx_image_t *img;
|
||||
|
||||
// Get decompressed data
|
||||
while ((img = dec_iter.Next())) {
|
||||
++out_frames;
|
||||
md5.Add(img);
|
||||
}
|
||||
} while (video.cxdata() != NULL);
|
||||
|
||||
EXPECT_EQ(expected_frame_count, out_frames)
|
||||
<< "Input frame count does not match expected output frame count";
|
||||
|
||||
return string(md5.Get());
|
||||
}
|
||||
|
||||
void DecodeFiles(const FileList files[]) {
|
||||
for (const FileList *iter = files; iter->name != NULL; ++iter) {
|
||||
SCOPED_TRACE(iter->name);
|
||||
for (int t = 2; t <= 8; ++t) {
|
||||
EXPECT_EQ(iter->expected_md5,
|
||||
DecodeFile(iter->name, t, iter->expected_frame_count))
|
||||
<< "threads = " << t;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
TEST(VP9MultiThreadedFrameParallel, InvalidFileTest) {
|
||||
static const FileList files[] = {
|
||||
// invalid-vp90-2-07-frame_parallel-1.webm is a 40 frame video file with
|
||||
// one key frame for every ten frames. The 11th frame has corrupted data.
|
||||
{ "invalid-vp90-2-07-frame_parallel-1.webm",
|
||||
"0549d0f45f60deaef8eb708e6c0eb6cb", 30 },
|
||||
// invalid-vp90-2-07-frame_parallel-2.webm is a 40 frame video file with
|
||||
// one key frame for every ten frames. The 1st and 31st frames have
|
||||
// corrupted data.
|
||||
{ "invalid-vp90-2-07-frame_parallel-2.webm",
|
||||
"6a1f3cf6f9e7a364212fadb9580d525e", 20 },
|
||||
// invalid-vp90-2-07-frame_parallel-3.webm is a 40 frame video file with
|
||||
// one key frame for every ten frames. The 5th and 13th frames have
|
||||
// corrupted data.
|
||||
{ "invalid-vp90-2-07-frame_parallel-3.webm",
|
||||
"8256544308de926b0681e04685b98677", 27 },
|
||||
{ NULL, NULL, 0 },
|
||||
};
|
||||
DecodeFiles(files);
|
||||
}
|
||||
|
||||
TEST(VP9MultiThreadedFrameParallel, ValidFileTest) {
|
||||
static const FileList files[] = {
|
||||
#if CONFIG_VP9_HIGHBITDEPTH
|
||||
{ "vp92-2-20-10bit-yuv420.webm", "a16b99df180c584e8db2ffeda987d293", 10 },
|
||||
#endif
|
||||
{ NULL, NULL, 0 },
|
||||
};
|
||||
DecodeFiles(files);
|
||||
}
|
||||
#endif // CONFIG_WEBM_IO
|
||||
} // namespace
|
@ -235,16 +235,8 @@ INSTANTIATE_TEST_CASE_P(
|
||||
8),
|
||||
IntraPredParam(&vpx_d45_predictor_16x16_neon,
|
||||
&vpx_d45_predictor_16x16_c, 16, 8),
|
||||
IntraPredParam(&vpx_d45_predictor_32x32_neon,
|
||||
&vpx_d45_predictor_32x32_c, 32, 8),
|
||||
IntraPredParam(&vpx_d135_predictor_4x4_neon, &vpx_d135_predictor_4x4_c,
|
||||
4, 8),
|
||||
IntraPredParam(&vpx_d135_predictor_8x8_neon, &vpx_d135_predictor_8x8_c,
|
||||
8, 8),
|
||||
IntraPredParam(&vpx_d135_predictor_16x16_neon,
|
||||
&vpx_d135_predictor_16x16_c, 16, 8),
|
||||
IntraPredParam(&vpx_d135_predictor_32x32_neon,
|
||||
&vpx_d135_predictor_32x32_c, 32, 8),
|
||||
IntraPredParam(&vpx_dc_128_predictor_4x4_neon,
|
||||
&vpx_dc_128_predictor_4x4_c, 4, 8),
|
||||
IntraPredParam(&vpx_dc_128_predictor_8x8_neon,
|
||||
@ -299,139 +291,6 @@ INSTANTIATE_TEST_CASE_P(
|
||||
32, 8)));
|
||||
#endif // HAVE_NEON
|
||||
|
||||
#if HAVE_DSPR2
|
||||
INSTANTIATE_TEST_CASE_P(
|
||||
DSPR2, VP9IntraPredTest,
|
||||
::testing::Values(IntraPredParam(&vpx_dc_predictor_4x4_dspr2,
|
||||
&vpx_dc_predictor_4x4_c, 4, 8),
|
||||
IntraPredParam(&vpx_dc_predictor_8x8_dspr2,
|
||||
&vpx_dc_predictor_8x8_c, 8, 8),
|
||||
IntraPredParam(&vpx_dc_predictor_16x16_dspr2,
|
||||
&vpx_dc_predictor_16x16_c, 16, 8),
|
||||
IntraPredParam(&vpx_h_predictor_4x4_dspr2,
|
||||
&vpx_h_predictor_4x4_c, 4, 8),
|
||||
IntraPredParam(&vpx_h_predictor_8x8_dspr2,
|
||||
&vpx_h_predictor_8x8_c, 8, 8),
|
||||
IntraPredParam(&vpx_h_predictor_16x16_dspr2,
|
||||
&vpx_h_predictor_16x16_c, 16, 8),
|
||||
IntraPredParam(&vpx_tm_predictor_4x4_dspr2,
|
||||
&vpx_tm_predictor_4x4_c, 4, 8),
|
||||
IntraPredParam(&vpx_tm_predictor_8x8_dspr2,
|
||||
&vpx_tm_predictor_8x8_c, 8, 8)));
|
||||
#endif // HAVE_DSPR2
|
||||
|
||||
#if HAVE_MSA
|
||||
INSTANTIATE_TEST_CASE_P(
|
||||
MSA, VP9IntraPredTest,
|
||||
::testing::Values(
|
||||
IntraPredParam(&vpx_dc_128_predictor_4x4_msa,
|
||||
&vpx_dc_128_predictor_4x4_c, 4, 8),
|
||||
IntraPredParam(&vpx_dc_128_predictor_8x8_msa,
|
||||
&vpx_dc_128_predictor_8x8_c, 8, 8),
|
||||
IntraPredParam(&vpx_dc_128_predictor_16x16_msa,
|
||||
&vpx_dc_128_predictor_16x16_c, 16, 8),
|
||||
IntraPredParam(&vpx_dc_128_predictor_32x32_msa,
|
||||
&vpx_dc_128_predictor_32x32_c, 32, 8),
|
||||
IntraPredParam(&vpx_dc_left_predictor_4x4_msa,
|
||||
&vpx_dc_left_predictor_4x4_c, 4, 8),
|
||||
IntraPredParam(&vpx_dc_left_predictor_8x8_msa,
|
||||
&vpx_dc_left_predictor_8x8_c, 8, 8),
|
||||
IntraPredParam(&vpx_dc_left_predictor_16x16_msa,
|
||||
&vpx_dc_left_predictor_16x16_c, 16, 8),
|
||||
IntraPredParam(&vpx_dc_left_predictor_32x32_msa,
|
||||
&vpx_dc_left_predictor_32x32_c, 32, 8),
|
||||
IntraPredParam(&vpx_dc_predictor_4x4_msa, &vpx_dc_predictor_4x4_c, 4,
|
||||
8),
|
||||
IntraPredParam(&vpx_dc_predictor_8x8_msa, &vpx_dc_predictor_8x8_c, 8,
|
||||
8),
|
||||
IntraPredParam(&vpx_dc_predictor_16x16_msa, &vpx_dc_predictor_16x16_c,
|
||||
16, 8),
|
||||
IntraPredParam(&vpx_dc_predictor_32x32_msa, &vpx_dc_predictor_32x32_c,
|
||||
32, 8),
|
||||
IntraPredParam(&vpx_dc_top_predictor_4x4_msa,
|
||||
&vpx_dc_top_predictor_4x4_c, 4, 8),
|
||||
IntraPredParam(&vpx_dc_top_predictor_8x8_msa,
|
||||
&vpx_dc_top_predictor_8x8_c, 8, 8),
|
||||
IntraPredParam(&vpx_dc_top_predictor_16x16_msa,
|
||||
&vpx_dc_top_predictor_16x16_c, 16, 8),
|
||||
IntraPredParam(&vpx_dc_top_predictor_32x32_msa,
|
||||
&vpx_dc_top_predictor_32x32_c, 32, 8),
|
||||
IntraPredParam(&vpx_h_predictor_4x4_msa, &vpx_h_predictor_4x4_c, 4, 8),
|
||||
IntraPredParam(&vpx_h_predictor_8x8_msa, &vpx_h_predictor_8x8_c, 8, 8),
|
||||
IntraPredParam(&vpx_h_predictor_16x16_msa, &vpx_h_predictor_16x16_c, 16,
|
||||
8),
|
||||
IntraPredParam(&vpx_h_predictor_32x32_msa, &vpx_h_predictor_32x32_c, 32,
|
||||
8),
|
||||
IntraPredParam(&vpx_tm_predictor_4x4_msa, &vpx_tm_predictor_4x4_c, 4,
|
||||
8),
|
||||
IntraPredParam(&vpx_tm_predictor_8x8_msa, &vpx_tm_predictor_8x8_c, 8,
|
||||
8),
|
||||
IntraPredParam(&vpx_tm_predictor_16x16_msa, &vpx_tm_predictor_16x16_c,
|
||||
16, 8),
|
||||
IntraPredParam(&vpx_tm_predictor_32x32_msa, &vpx_tm_predictor_32x32_c,
|
||||
32, 8),
|
||||
IntraPredParam(&vpx_v_predictor_4x4_msa, &vpx_v_predictor_4x4_c, 4, 8),
|
||||
IntraPredParam(&vpx_v_predictor_8x8_msa, &vpx_v_predictor_8x8_c, 8, 8),
|
||||
IntraPredParam(&vpx_v_predictor_16x16_msa, &vpx_v_predictor_16x16_c, 16,
|
||||
8),
|
||||
IntraPredParam(&vpx_v_predictor_32x32_msa, &vpx_v_predictor_32x32_c, 32,
|
||||
8)));
|
||||
#endif // HAVE_MSA
|
||||
|
||||
#if HAVE_VSX
|
||||
INSTANTIATE_TEST_CASE_P(
|
||||
VSX, VP9IntraPredTest,
|
||||
::testing::Values(
|
||||
IntraPredParam(&vpx_d45_predictor_8x8_vsx, &vpx_d45_predictor_8x8_c, 8,
|
||||
8),
|
||||
IntraPredParam(&vpx_d45_predictor_16x16_vsx, &vpx_d45_predictor_16x16_c,
|
||||
16, 8),
|
||||
IntraPredParam(&vpx_d45_predictor_32x32_vsx, &vpx_d45_predictor_32x32_c,
|
||||
32, 8),
|
||||
IntraPredParam(&vpx_d63_predictor_8x8_vsx, &vpx_d63_predictor_8x8_c, 8,
|
||||
8),
|
||||
IntraPredParam(&vpx_d63_predictor_16x16_vsx, &vpx_d63_predictor_16x16_c,
|
||||
16, 8),
|
||||
IntraPredParam(&vpx_d63_predictor_32x32_vsx, &vpx_d63_predictor_32x32_c,
|
||||
32, 8),
|
||||
IntraPredParam(&vpx_dc_128_predictor_16x16_vsx,
|
||||
&vpx_dc_128_predictor_16x16_c, 16, 8),
|
||||
IntraPredParam(&vpx_dc_128_predictor_32x32_vsx,
|
||||
&vpx_dc_128_predictor_32x32_c, 32, 8),
|
||||
IntraPredParam(&vpx_dc_left_predictor_16x16_vsx,
|
||||
&vpx_dc_left_predictor_16x16_c, 16, 8),
|
||||
IntraPredParam(&vpx_dc_left_predictor_32x32_vsx,
|
||||
&vpx_dc_left_predictor_32x32_c, 32, 8),
|
||||
IntraPredParam(&vpx_dc_predictor_8x8_vsx, &vpx_dc_predictor_8x8_c, 8,
|
||||
8),
|
||||
IntraPredParam(&vpx_dc_predictor_16x16_vsx, &vpx_dc_predictor_16x16_c,
|
||||
16, 8),
|
||||
IntraPredParam(&vpx_dc_predictor_32x32_vsx, &vpx_dc_predictor_32x32_c,
|
||||
32, 8),
|
||||
IntraPredParam(&vpx_dc_top_predictor_16x16_vsx,
|
||||
&vpx_dc_top_predictor_16x16_c, 16, 8),
|
||||
IntraPredParam(&vpx_dc_top_predictor_32x32_vsx,
|
||||
&vpx_dc_top_predictor_32x32_c, 32, 8),
|
||||
IntraPredParam(&vpx_h_predictor_4x4_vsx, &vpx_h_predictor_4x4_c, 4, 8),
|
||||
IntraPredParam(&vpx_h_predictor_8x8_vsx, &vpx_h_predictor_8x8_c, 8, 8),
|
||||
IntraPredParam(&vpx_h_predictor_16x16_vsx, &vpx_h_predictor_16x16_c, 16,
|
||||
8),
|
||||
IntraPredParam(&vpx_h_predictor_32x32_vsx, &vpx_h_predictor_32x32_c, 32,
|
||||
8),
|
||||
IntraPredParam(&vpx_tm_predictor_4x4_vsx, &vpx_tm_predictor_4x4_c, 4,
|
||||
8),
|
||||
IntraPredParam(&vpx_tm_predictor_8x8_vsx, &vpx_tm_predictor_8x8_c, 8,
|
||||
8),
|
||||
IntraPredParam(&vpx_tm_predictor_16x16_vsx, &vpx_tm_predictor_16x16_c,
|
||||
16, 8),
|
||||
IntraPredParam(&vpx_tm_predictor_32x32_vsx, &vpx_tm_predictor_32x32_c,
|
||||
32, 8),
|
||||
IntraPredParam(&vpx_v_predictor_16x16_vsx, &vpx_v_predictor_16x16_c, 16,
|
||||
8),
|
||||
IntraPredParam(&vpx_v_predictor_32x32_vsx, &vpx_v_predictor_32x32_c, 32,
|
||||
8)));
|
||||
#endif // HAVE_VSX
|
||||
|
||||
#if CONFIG_VP9_HIGHBITDEPTH
|
||||
typedef void (*HighbdIntraPred)(uint16_t *dst, ptrdiff_t stride,
|
||||
const uint16_t *above, const uint16_t *left,
|
||||
@ -467,164 +326,10 @@ TEST_P(VP9HighbdIntraPredTest, HighbdIntraPredTests) {
|
||||
RunTest(left_col, above_data, dst, ref_dst);
|
||||
}
|
||||
|
||||
#if HAVE_SSSE3
|
||||
INSTANTIATE_TEST_CASE_P(
|
||||
SSSE3_TO_C_8, VP9HighbdIntraPredTest,
|
||||
::testing::Values(
|
||||
HighbdIntraPredParam(&vpx_highbd_d45_predictor_4x4_ssse3,
|
||||
&vpx_highbd_d45_predictor_4x4_c, 4, 8),
|
||||
HighbdIntraPredParam(&vpx_highbd_d45_predictor_8x8_ssse3,
|
||||
&vpx_highbd_d45_predictor_8x8_c, 8, 8),
|
||||
HighbdIntraPredParam(&vpx_highbd_d45_predictor_16x16_ssse3,
|
||||
&vpx_highbd_d45_predictor_16x16_c, 16, 8),
|
||||
HighbdIntraPredParam(&vpx_highbd_d45_predictor_32x32_ssse3,
|
||||
&vpx_highbd_d45_predictor_32x32_c, 32, 8),
|
||||
HighbdIntraPredParam(&vpx_highbd_d63_predictor_8x8_ssse3,
|
||||
&vpx_highbd_d63_predictor_8x8_c, 8, 8),
|
||||
HighbdIntraPredParam(&vpx_highbd_d63_predictor_16x16_ssse3,
|
||||
&vpx_highbd_d63_predictor_16x16_c, 16, 8),
|
||||
HighbdIntraPredParam(&vpx_highbd_d63_predictor_32x32_c,
|
||||
&vpx_highbd_d63_predictor_32x32_ssse3, 32, 8),
|
||||
HighbdIntraPredParam(&vpx_highbd_d117_predictor_8x8_ssse3,
|
||||
&vpx_highbd_d117_predictor_8x8_c, 8, 8),
|
||||
HighbdIntraPredParam(&vpx_highbd_d117_predictor_16x16_ssse3,
|
||||
&vpx_highbd_d117_predictor_16x16_c, 16, 8),
|
||||
HighbdIntraPredParam(&vpx_highbd_d117_predictor_32x32_c,
|
||||
&vpx_highbd_d117_predictor_32x32_ssse3, 32, 8),
|
||||
HighbdIntraPredParam(&vpx_highbd_d135_predictor_8x8_ssse3,
|
||||
&vpx_highbd_d135_predictor_8x8_c, 8, 8),
|
||||
HighbdIntraPredParam(&vpx_highbd_d135_predictor_16x16_ssse3,
|
||||
&vpx_highbd_d135_predictor_16x16_c, 16, 8),
|
||||
HighbdIntraPredParam(&vpx_highbd_d135_predictor_32x32_ssse3,
|
||||
&vpx_highbd_d135_predictor_32x32_c, 32, 8),
|
||||
HighbdIntraPredParam(&vpx_highbd_d153_predictor_8x8_ssse3,
|
||||
&vpx_highbd_d153_predictor_8x8_c, 8, 8),
|
||||
HighbdIntraPredParam(&vpx_highbd_d153_predictor_16x16_ssse3,
|
||||
&vpx_highbd_d153_predictor_16x16_c, 16, 8),
|
||||
HighbdIntraPredParam(&vpx_highbd_d153_predictor_32x32_ssse3,
|
||||
&vpx_highbd_d153_predictor_32x32_c, 32, 8),
|
||||
HighbdIntraPredParam(&vpx_highbd_d207_predictor_8x8_ssse3,
|
||||
&vpx_highbd_d207_predictor_8x8_c, 8, 8),
|
||||
HighbdIntraPredParam(&vpx_highbd_d207_predictor_16x16_ssse3,
|
||||
&vpx_highbd_d207_predictor_16x16_c, 16, 8),
|
||||
HighbdIntraPredParam(&vpx_highbd_d207_predictor_32x32_ssse3,
|
||||
&vpx_highbd_d207_predictor_32x32_c, 32, 8)));
|
||||
|
||||
INSTANTIATE_TEST_CASE_P(
|
||||
SSSE3_TO_C_10, VP9HighbdIntraPredTest,
|
||||
::testing::Values(
|
||||
HighbdIntraPredParam(&vpx_highbd_d45_predictor_4x4_ssse3,
|
||||
&vpx_highbd_d45_predictor_4x4_c, 4, 10),
|
||||
HighbdIntraPredParam(&vpx_highbd_d45_predictor_8x8_ssse3,
|
||||
&vpx_highbd_d45_predictor_8x8_c, 8, 10),
|
||||
HighbdIntraPredParam(&vpx_highbd_d45_predictor_16x16_ssse3,
|
||||
&vpx_highbd_d45_predictor_16x16_c, 16, 10),
|
||||
HighbdIntraPredParam(&vpx_highbd_d45_predictor_32x32_ssse3,
|
||||
&vpx_highbd_d45_predictor_32x32_c, 32, 10),
|
||||
HighbdIntraPredParam(&vpx_highbd_d63_predictor_8x8_ssse3,
|
||||
&vpx_highbd_d63_predictor_8x8_c, 8, 10),
|
||||
HighbdIntraPredParam(&vpx_highbd_d63_predictor_16x16_ssse3,
|
||||
&vpx_highbd_d63_predictor_16x16_c, 16, 10),
|
||||
HighbdIntraPredParam(&vpx_highbd_d63_predictor_32x32_c,
|
||||
&vpx_highbd_d63_predictor_32x32_ssse3, 32, 10),
|
||||
HighbdIntraPredParam(&vpx_highbd_d117_predictor_8x8_ssse3,
|
||||
&vpx_highbd_d117_predictor_8x8_c, 8, 10),
|
||||
HighbdIntraPredParam(&vpx_highbd_d117_predictor_16x16_ssse3,
|
||||
&vpx_highbd_d117_predictor_16x16_c, 16, 10),
|
||||
HighbdIntraPredParam(&vpx_highbd_d117_predictor_32x32_c,
|
||||
&vpx_highbd_d117_predictor_32x32_ssse3, 32, 10),
|
||||
HighbdIntraPredParam(&vpx_highbd_d135_predictor_8x8_ssse3,
|
||||
&vpx_highbd_d135_predictor_8x8_c, 8, 10),
|
||||
HighbdIntraPredParam(&vpx_highbd_d135_predictor_16x16_ssse3,
|
||||
&vpx_highbd_d135_predictor_16x16_c, 16, 10),
|
||||
HighbdIntraPredParam(&vpx_highbd_d135_predictor_32x32_ssse3,
|
||||
&vpx_highbd_d135_predictor_32x32_c, 32, 10),
|
||||
HighbdIntraPredParam(&vpx_highbd_d153_predictor_8x8_ssse3,
|
||||
&vpx_highbd_d153_predictor_8x8_c, 8, 10),
|
||||
HighbdIntraPredParam(&vpx_highbd_d153_predictor_16x16_ssse3,
|
||||
&vpx_highbd_d153_predictor_16x16_c, 16, 10),
|
||||
HighbdIntraPredParam(&vpx_highbd_d153_predictor_32x32_ssse3,
|
||||
&vpx_highbd_d153_predictor_32x32_c, 32, 10),
|
||||
HighbdIntraPredParam(&vpx_highbd_d207_predictor_8x8_ssse3,
|
||||
&vpx_highbd_d207_predictor_8x8_c, 8, 10),
|
||||
HighbdIntraPredParam(&vpx_highbd_d207_predictor_16x16_ssse3,
|
||||
&vpx_highbd_d207_predictor_16x16_c, 16, 10),
|
||||
HighbdIntraPredParam(&vpx_highbd_d207_predictor_32x32_ssse3,
|
||||
&vpx_highbd_d207_predictor_32x32_c, 32, 10)));
|
||||
|
||||
INSTANTIATE_TEST_CASE_P(
|
||||
SSSE3_TO_C_12, VP9HighbdIntraPredTest,
|
||||
::testing::Values(
|
||||
HighbdIntraPredParam(&vpx_highbd_d45_predictor_4x4_ssse3,
|
||||
&vpx_highbd_d45_predictor_4x4_c, 4, 12),
|
||||
HighbdIntraPredParam(&vpx_highbd_d45_predictor_8x8_ssse3,
|
||||
&vpx_highbd_d45_predictor_8x8_c, 8, 12),
|
||||
HighbdIntraPredParam(&vpx_highbd_d45_predictor_16x16_ssse3,
|
||||
&vpx_highbd_d45_predictor_16x16_c, 16, 12),
|
||||
HighbdIntraPredParam(&vpx_highbd_d45_predictor_32x32_ssse3,
|
||||
&vpx_highbd_d45_predictor_32x32_c, 32, 12),
|
||||
HighbdIntraPredParam(&vpx_highbd_d63_predictor_8x8_ssse3,
|
||||
&vpx_highbd_d63_predictor_8x8_c, 8, 12),
|
||||
HighbdIntraPredParam(&vpx_highbd_d63_predictor_16x16_ssse3,
|
||||
&vpx_highbd_d63_predictor_16x16_c, 16, 12),
|
||||
HighbdIntraPredParam(&vpx_highbd_d63_predictor_32x32_c,
|
||||
&vpx_highbd_d63_predictor_32x32_ssse3, 32, 12),
|
||||
HighbdIntraPredParam(&vpx_highbd_d117_predictor_8x8_ssse3,
|
||||
&vpx_highbd_d117_predictor_8x8_c, 8, 12),
|
||||
HighbdIntraPredParam(&vpx_highbd_d117_predictor_16x16_ssse3,
|
||||
&vpx_highbd_d117_predictor_16x16_c, 16, 12),
|
||||
HighbdIntraPredParam(&vpx_highbd_d117_predictor_32x32_c,
|
||||
&vpx_highbd_d117_predictor_32x32_ssse3, 32, 12),
|
||||
HighbdIntraPredParam(&vpx_highbd_d135_predictor_8x8_ssse3,
|
||||
&vpx_highbd_d135_predictor_8x8_c, 8, 12),
|
||||
HighbdIntraPredParam(&vpx_highbd_d135_predictor_16x16_ssse3,
|
||||
&vpx_highbd_d135_predictor_16x16_c, 16, 12),
|
||||
HighbdIntraPredParam(&vpx_highbd_d135_predictor_32x32_ssse3,
|
||||
&vpx_highbd_d135_predictor_32x32_c, 32, 12),
|
||||
HighbdIntraPredParam(&vpx_highbd_d153_predictor_8x8_ssse3,
|
||||
&vpx_highbd_d153_predictor_8x8_c, 8, 12),
|
||||
HighbdIntraPredParam(&vpx_highbd_d153_predictor_16x16_ssse3,
|
||||
&vpx_highbd_d153_predictor_16x16_c, 16, 12),
|
||||
HighbdIntraPredParam(&vpx_highbd_d153_predictor_32x32_ssse3,
|
||||
&vpx_highbd_d153_predictor_32x32_c, 32, 12),
|
||||
HighbdIntraPredParam(&vpx_highbd_d207_predictor_8x8_ssse3,
|
||||
&vpx_highbd_d207_predictor_8x8_c, 8, 12),
|
||||
HighbdIntraPredParam(&vpx_highbd_d207_predictor_16x16_ssse3,
|
||||
&vpx_highbd_d207_predictor_16x16_c, 16, 12),
|
||||
HighbdIntraPredParam(&vpx_highbd_d207_predictor_32x32_ssse3,
|
||||
&vpx_highbd_d207_predictor_32x32_c, 32, 12)));
|
||||
#endif // HAVE_SSSE3
|
||||
|
||||
#if HAVE_SSE2
|
||||
INSTANTIATE_TEST_CASE_P(
|
||||
SSE2_TO_C_8, VP9HighbdIntraPredTest,
|
||||
::testing::Values(
|
||||
HighbdIntraPredParam(&vpx_highbd_dc_128_predictor_4x4_sse2,
|
||||
&vpx_highbd_dc_128_predictor_4x4_c, 4, 8),
|
||||
HighbdIntraPredParam(&vpx_highbd_dc_128_predictor_8x8_sse2,
|
||||
&vpx_highbd_dc_128_predictor_8x8_c, 8, 8),
|
||||
HighbdIntraPredParam(&vpx_highbd_dc_128_predictor_16x16_sse2,
|
||||
&vpx_highbd_dc_128_predictor_16x16_c, 16, 8),
|
||||
HighbdIntraPredParam(&vpx_highbd_dc_128_predictor_32x32_sse2,
|
||||
&vpx_highbd_dc_128_predictor_32x32_c, 32, 8),
|
||||
HighbdIntraPredParam(&vpx_highbd_d63_predictor_4x4_sse2,
|
||||
&vpx_highbd_d63_predictor_4x4_c, 4, 8),
|
||||
HighbdIntraPredParam(&vpx_highbd_d117_predictor_4x4_sse2,
|
||||
&vpx_highbd_d117_predictor_4x4_c, 4, 8),
|
||||
HighbdIntraPredParam(&vpx_highbd_d135_predictor_4x4_sse2,
|
||||
&vpx_highbd_d135_predictor_4x4_c, 4, 8),
|
||||
HighbdIntraPredParam(&vpx_highbd_d153_predictor_4x4_sse2,
|
||||
&vpx_highbd_d153_predictor_4x4_c, 4, 8),
|
||||
HighbdIntraPredParam(&vpx_highbd_d207_predictor_4x4_sse2,
|
||||
&vpx_highbd_d207_predictor_4x4_c, 4, 8),
|
||||
HighbdIntraPredParam(&vpx_highbd_dc_left_predictor_4x4_sse2,
|
||||
&vpx_highbd_dc_left_predictor_4x4_c, 4, 8),
|
||||
HighbdIntraPredParam(&vpx_highbd_dc_left_predictor_8x8_sse2,
|
||||
&vpx_highbd_dc_left_predictor_8x8_c, 8, 8),
|
||||
HighbdIntraPredParam(&vpx_highbd_dc_left_predictor_16x16_sse2,
|
||||
&vpx_highbd_dc_left_predictor_16x16_c, 16, 8),
|
||||
HighbdIntraPredParam(&vpx_highbd_dc_left_predictor_32x32_sse2,
|
||||
&vpx_highbd_dc_left_predictor_32x32_c, 32, 8),
|
||||
HighbdIntraPredParam(&vpx_highbd_dc_predictor_4x4_sse2,
|
||||
&vpx_highbd_dc_predictor_4x4_c, 4, 8),
|
||||
HighbdIntraPredParam(&vpx_highbd_dc_predictor_8x8_sse2,
|
||||
@ -633,14 +338,6 @@ INSTANTIATE_TEST_CASE_P(
|
||||
&vpx_highbd_dc_predictor_16x16_c, 16, 8),
|
||||
HighbdIntraPredParam(&vpx_highbd_dc_predictor_32x32_sse2,
|
||||
&vpx_highbd_dc_predictor_32x32_c, 32, 8),
|
||||
HighbdIntraPredParam(&vpx_highbd_dc_top_predictor_4x4_sse2,
|
||||
&vpx_highbd_dc_top_predictor_4x4_c, 4, 8),
|
||||
HighbdIntraPredParam(&vpx_highbd_dc_top_predictor_8x8_sse2,
|
||||
&vpx_highbd_dc_top_predictor_8x8_c, 8, 8),
|
||||
HighbdIntraPredParam(&vpx_highbd_dc_top_predictor_16x16_sse2,
|
||||
&vpx_highbd_dc_top_predictor_16x16_c, 16, 8),
|
||||
HighbdIntraPredParam(&vpx_highbd_dc_top_predictor_32x32_sse2,
|
||||
&vpx_highbd_dc_top_predictor_32x32_c, 32, 8),
|
||||
HighbdIntraPredParam(&vpx_highbd_tm_predictor_4x4_sse2,
|
||||
&vpx_highbd_tm_predictor_4x4_c, 4, 8),
|
||||
HighbdIntraPredParam(&vpx_highbd_tm_predictor_8x8_sse2,
|
||||
@ -649,14 +346,6 @@ INSTANTIATE_TEST_CASE_P(
|
||||
&vpx_highbd_tm_predictor_16x16_c, 16, 8),
|
||||
HighbdIntraPredParam(&vpx_highbd_tm_predictor_32x32_sse2,
|
||||
&vpx_highbd_tm_predictor_32x32_c, 32, 8),
|
||||
HighbdIntraPredParam(&vpx_highbd_h_predictor_4x4_sse2,
|
||||
&vpx_highbd_h_predictor_4x4_c, 4, 8),
|
||||
HighbdIntraPredParam(&vpx_highbd_h_predictor_8x8_sse2,
|
||||
&vpx_highbd_h_predictor_8x8_c, 8, 8),
|
||||
HighbdIntraPredParam(&vpx_highbd_h_predictor_16x16_sse2,
|
||||
&vpx_highbd_h_predictor_16x16_c, 16, 8),
|
||||
HighbdIntraPredParam(&vpx_highbd_h_predictor_32x32_sse2,
|
||||
&vpx_highbd_h_predictor_32x32_c, 32, 8),
|
||||
HighbdIntraPredParam(&vpx_highbd_v_predictor_4x4_sse2,
|
||||
&vpx_highbd_v_predictor_4x4_c, 4, 8),
|
||||
HighbdIntraPredParam(&vpx_highbd_v_predictor_8x8_sse2,
|
||||
@ -669,32 +358,6 @@ INSTANTIATE_TEST_CASE_P(
|
||||
INSTANTIATE_TEST_CASE_P(
|
||||
SSE2_TO_C_10, VP9HighbdIntraPredTest,
|
||||
::testing::Values(
|
||||
HighbdIntraPredParam(&vpx_highbd_dc_128_predictor_4x4_sse2,
|
||||
&vpx_highbd_dc_128_predictor_4x4_c, 4, 10),
|
||||
HighbdIntraPredParam(&vpx_highbd_dc_128_predictor_8x8_sse2,
|
||||
&vpx_highbd_dc_128_predictor_8x8_c, 8, 10),
|
||||
HighbdIntraPredParam(&vpx_highbd_dc_128_predictor_16x16_sse2,
|
||||
&vpx_highbd_dc_128_predictor_16x16_c, 16, 10),
|
||||
HighbdIntraPredParam(&vpx_highbd_dc_128_predictor_32x32_sse2,
|
||||
&vpx_highbd_dc_128_predictor_32x32_c, 32, 10),
|
||||
HighbdIntraPredParam(&vpx_highbd_d63_predictor_4x4_sse2,
|
||||
&vpx_highbd_d63_predictor_4x4_c, 4, 10),
|
||||
HighbdIntraPredParam(&vpx_highbd_d117_predictor_4x4_sse2,
|
||||
&vpx_highbd_d117_predictor_4x4_c, 4, 10),
|
||||
HighbdIntraPredParam(&vpx_highbd_d135_predictor_4x4_sse2,
|
||||
&vpx_highbd_d135_predictor_4x4_c, 4, 10),
|
||||
HighbdIntraPredParam(&vpx_highbd_d153_predictor_4x4_sse2,
|
||||
&vpx_highbd_d153_predictor_4x4_c, 4, 10),
|
||||
HighbdIntraPredParam(&vpx_highbd_d207_predictor_4x4_sse2,
|
||||
&vpx_highbd_d207_predictor_4x4_c, 4, 10),
|
||||
HighbdIntraPredParam(&vpx_highbd_dc_left_predictor_4x4_sse2,
|
||||
&vpx_highbd_dc_left_predictor_4x4_c, 4, 10),
|
||||
HighbdIntraPredParam(&vpx_highbd_dc_left_predictor_8x8_sse2,
|
||||
&vpx_highbd_dc_left_predictor_8x8_c, 8, 10),
|
||||
HighbdIntraPredParam(&vpx_highbd_dc_left_predictor_16x16_sse2,
|
||||
&vpx_highbd_dc_left_predictor_16x16_c, 16, 10),
|
||||
HighbdIntraPredParam(&vpx_highbd_dc_left_predictor_32x32_sse2,
|
||||
&vpx_highbd_dc_left_predictor_32x32_c, 32, 10),
|
||||
HighbdIntraPredParam(&vpx_highbd_dc_predictor_4x4_sse2,
|
||||
&vpx_highbd_dc_predictor_4x4_c, 4, 10),
|
||||
HighbdIntraPredParam(&vpx_highbd_dc_predictor_8x8_sse2,
|
||||
@ -703,14 +366,6 @@ INSTANTIATE_TEST_CASE_P(
|
||||
&vpx_highbd_dc_predictor_16x16_c, 16, 10),
|
||||
HighbdIntraPredParam(&vpx_highbd_dc_predictor_32x32_sse2,
|
||||
&vpx_highbd_dc_predictor_32x32_c, 32, 10),
|
||||
HighbdIntraPredParam(&vpx_highbd_dc_top_predictor_4x4_sse2,
|
||||
&vpx_highbd_dc_top_predictor_4x4_c, 4, 10),
|
||||
HighbdIntraPredParam(&vpx_highbd_dc_top_predictor_8x8_sse2,
|
||||
&vpx_highbd_dc_top_predictor_8x8_c, 8, 10),
|
||||
HighbdIntraPredParam(&vpx_highbd_dc_top_predictor_16x16_sse2,
|
||||
&vpx_highbd_dc_top_predictor_16x16_c, 16, 10),
|
||||
HighbdIntraPredParam(&vpx_highbd_dc_top_predictor_32x32_sse2,
|
||||
&vpx_highbd_dc_top_predictor_32x32_c, 32, 10),
|
||||
HighbdIntraPredParam(&vpx_highbd_tm_predictor_4x4_sse2,
|
||||
&vpx_highbd_tm_predictor_4x4_c, 4, 10),
|
||||
HighbdIntraPredParam(&vpx_highbd_tm_predictor_8x8_sse2,
|
||||
@ -719,14 +374,6 @@ INSTANTIATE_TEST_CASE_P(
|
||||
&vpx_highbd_tm_predictor_16x16_c, 16, 10),
|
||||
HighbdIntraPredParam(&vpx_highbd_tm_predictor_32x32_sse2,
|
||||
&vpx_highbd_tm_predictor_32x32_c, 32, 10),
|
||||
HighbdIntraPredParam(&vpx_highbd_h_predictor_4x4_sse2,
|
||||
&vpx_highbd_h_predictor_4x4_c, 4, 10),
|
||||
HighbdIntraPredParam(&vpx_highbd_h_predictor_8x8_sse2,
|
||||
&vpx_highbd_h_predictor_8x8_c, 8, 10),
|
||||
HighbdIntraPredParam(&vpx_highbd_h_predictor_16x16_sse2,
|
||||
&vpx_highbd_h_predictor_16x16_c, 16, 10),
|
||||
HighbdIntraPredParam(&vpx_highbd_h_predictor_32x32_sse2,
|
||||
&vpx_highbd_h_predictor_32x32_c, 32, 10),
|
||||
HighbdIntraPredParam(&vpx_highbd_v_predictor_4x4_sse2,
|
||||
&vpx_highbd_v_predictor_4x4_c, 4, 10),
|
||||
HighbdIntraPredParam(&vpx_highbd_v_predictor_8x8_sse2,
|
||||
@ -739,32 +386,6 @@ INSTANTIATE_TEST_CASE_P(
|
||||
INSTANTIATE_TEST_CASE_P(
|
||||
SSE2_TO_C_12, VP9HighbdIntraPredTest,
|
||||
::testing::Values(
|
||||
HighbdIntraPredParam(&vpx_highbd_dc_128_predictor_4x4_sse2,
|
||||
&vpx_highbd_dc_128_predictor_4x4_c, 4, 12),
|
||||
HighbdIntraPredParam(&vpx_highbd_dc_128_predictor_8x8_sse2,
|
||||
&vpx_highbd_dc_128_predictor_8x8_c, 8, 12),
|
||||
HighbdIntraPredParam(&vpx_highbd_dc_128_predictor_16x16_sse2,
|
||||
&vpx_highbd_dc_128_predictor_16x16_c, 16, 12),
|
||||
HighbdIntraPredParam(&vpx_highbd_dc_128_predictor_32x32_sse2,
|
||||
&vpx_highbd_dc_128_predictor_32x32_c, 32, 12),
|
||||
HighbdIntraPredParam(&vpx_highbd_d63_predictor_4x4_sse2,
|
||||
&vpx_highbd_d63_predictor_4x4_c, 4, 12),
|
||||
HighbdIntraPredParam(&vpx_highbd_d117_predictor_4x4_sse2,
|
||||
&vpx_highbd_d117_predictor_4x4_c, 4, 12),
|
||||
HighbdIntraPredParam(&vpx_highbd_d135_predictor_4x4_sse2,
|
||||
&vpx_highbd_d135_predictor_4x4_c, 4, 12),
|
||||
HighbdIntraPredParam(&vpx_highbd_d153_predictor_4x4_sse2,
|
||||
&vpx_highbd_d153_predictor_4x4_c, 4, 12),
|
||||
HighbdIntraPredParam(&vpx_highbd_d207_predictor_4x4_sse2,
|
||||
&vpx_highbd_d207_predictor_4x4_c, 4, 12),
|
||||
HighbdIntraPredParam(&vpx_highbd_dc_left_predictor_4x4_sse2,
|
||||
&vpx_highbd_dc_left_predictor_4x4_c, 4, 12),
|
||||
HighbdIntraPredParam(&vpx_highbd_dc_left_predictor_8x8_sse2,
|
||||
&vpx_highbd_dc_left_predictor_8x8_c, 8, 12),
|
||||
HighbdIntraPredParam(&vpx_highbd_dc_left_predictor_16x16_sse2,
|
||||
&vpx_highbd_dc_left_predictor_16x16_c, 16, 12),
|
||||
HighbdIntraPredParam(&vpx_highbd_dc_left_predictor_32x32_sse2,
|
||||
&vpx_highbd_dc_left_predictor_32x32_c, 32, 12),
|
||||
HighbdIntraPredParam(&vpx_highbd_dc_predictor_4x4_sse2,
|
||||
&vpx_highbd_dc_predictor_4x4_c, 4, 12),
|
||||
HighbdIntraPredParam(&vpx_highbd_dc_predictor_8x8_sse2,
|
||||
@ -773,14 +394,6 @@ INSTANTIATE_TEST_CASE_P(
|
||||
&vpx_highbd_dc_predictor_16x16_c, 16, 12),
|
||||
HighbdIntraPredParam(&vpx_highbd_dc_predictor_32x32_sse2,
|
||||
&vpx_highbd_dc_predictor_32x32_c, 32, 12),
|
||||
HighbdIntraPredParam(&vpx_highbd_dc_top_predictor_4x4_sse2,
|
||||
&vpx_highbd_dc_top_predictor_4x4_c, 4, 12),
|
||||
HighbdIntraPredParam(&vpx_highbd_dc_top_predictor_8x8_sse2,
|
||||
&vpx_highbd_dc_top_predictor_8x8_c, 8, 12),
|
||||
HighbdIntraPredParam(&vpx_highbd_dc_top_predictor_16x16_sse2,
|
||||
&vpx_highbd_dc_top_predictor_16x16_c, 16, 12),
|
||||
HighbdIntraPredParam(&vpx_highbd_dc_top_predictor_32x32_sse2,
|
||||
&vpx_highbd_dc_top_predictor_32x32_c, 32, 12),
|
||||
HighbdIntraPredParam(&vpx_highbd_tm_predictor_4x4_sse2,
|
||||
&vpx_highbd_tm_predictor_4x4_c, 4, 12),
|
||||
HighbdIntraPredParam(&vpx_highbd_tm_predictor_8x8_sse2,
|
||||
@ -789,14 +402,6 @@ INSTANTIATE_TEST_CASE_P(
|
||||
&vpx_highbd_tm_predictor_16x16_c, 16, 12),
|
||||
HighbdIntraPredParam(&vpx_highbd_tm_predictor_32x32_sse2,
|
||||
&vpx_highbd_tm_predictor_32x32_c, 32, 12),
|
||||
HighbdIntraPredParam(&vpx_highbd_h_predictor_4x4_sse2,
|
||||
&vpx_highbd_h_predictor_4x4_c, 4, 12),
|
||||
HighbdIntraPredParam(&vpx_highbd_h_predictor_8x8_sse2,
|
||||
&vpx_highbd_h_predictor_8x8_c, 8, 12),
|
||||
HighbdIntraPredParam(&vpx_highbd_h_predictor_16x16_sse2,
|
||||
&vpx_highbd_h_predictor_16x16_c, 16, 12),
|
||||
HighbdIntraPredParam(&vpx_highbd_h_predictor_32x32_sse2,
|
||||
&vpx_highbd_h_predictor_32x32_c, 32, 12),
|
||||
HighbdIntraPredParam(&vpx_highbd_v_predictor_4x4_sse2,
|
||||
&vpx_highbd_v_predictor_4x4_c, 4, 12),
|
||||
HighbdIntraPredParam(&vpx_highbd_v_predictor_8x8_sse2,
|
||||
@ -807,235 +412,5 @@ INSTANTIATE_TEST_CASE_P(
|
||||
&vpx_highbd_v_predictor_32x32_c, 32, 12)));
|
||||
#endif // HAVE_SSE2
|
||||
|
||||
#if HAVE_NEON
|
||||
INSTANTIATE_TEST_CASE_P(
|
||||
NEON_TO_C_8, VP9HighbdIntraPredTest,
|
||||
::testing::Values(
|
||||
HighbdIntraPredParam(&vpx_highbd_d45_predictor_4x4_neon,
|
||||
&vpx_highbd_d45_predictor_4x4_c, 4, 8),
|
||||
HighbdIntraPredParam(&vpx_highbd_d45_predictor_8x8_neon,
|
||||
&vpx_highbd_d45_predictor_8x8_c, 8, 8),
|
||||
HighbdIntraPredParam(&vpx_highbd_d45_predictor_16x16_neon,
|
||||
&vpx_highbd_d45_predictor_16x16_c, 16, 8),
|
||||
HighbdIntraPredParam(&vpx_highbd_d45_predictor_32x32_neon,
|
||||
&vpx_highbd_d45_predictor_32x32_c, 32, 8),
|
||||
HighbdIntraPredParam(&vpx_highbd_d135_predictor_4x4_neon,
|
||||
&vpx_highbd_d135_predictor_4x4_c, 4, 8),
|
||||
HighbdIntraPredParam(&vpx_highbd_d135_predictor_8x8_neon,
|
||||
&vpx_highbd_d135_predictor_8x8_c, 8, 8),
|
||||
HighbdIntraPredParam(&vpx_highbd_d135_predictor_16x16_neon,
|
||||
&vpx_highbd_d135_predictor_16x16_c, 16, 8),
|
||||
HighbdIntraPredParam(&vpx_highbd_d135_predictor_32x32_neon,
|
||||
&vpx_highbd_d135_predictor_32x32_c, 32, 8),
|
||||
HighbdIntraPredParam(&vpx_highbd_dc_128_predictor_4x4_neon,
|
||||
&vpx_highbd_dc_128_predictor_4x4_c, 4, 8),
|
||||
HighbdIntraPredParam(&vpx_highbd_dc_128_predictor_8x8_neon,
|
||||
&vpx_highbd_dc_128_predictor_8x8_c, 8, 8),
|
||||
HighbdIntraPredParam(&vpx_highbd_dc_128_predictor_16x16_neon,
|
||||
&vpx_highbd_dc_128_predictor_16x16_c, 16, 8),
|
||||
HighbdIntraPredParam(&vpx_highbd_dc_128_predictor_32x32_neon,
|
||||
&vpx_highbd_dc_128_predictor_32x32_c, 32, 8),
|
||||
HighbdIntraPredParam(&vpx_highbd_dc_left_predictor_4x4_neon,
|
||||
&vpx_highbd_dc_left_predictor_4x4_c, 4, 8),
|
||||
HighbdIntraPredParam(&vpx_highbd_dc_left_predictor_8x8_neon,
|
||||
&vpx_highbd_dc_left_predictor_8x8_c, 8, 8),
|
||||
HighbdIntraPredParam(&vpx_highbd_dc_left_predictor_16x16_neon,
|
||||
&vpx_highbd_dc_left_predictor_16x16_c, 16, 8),
|
||||
HighbdIntraPredParam(&vpx_highbd_dc_left_predictor_32x32_neon,
|
||||
&vpx_highbd_dc_left_predictor_32x32_c, 32, 8),
|
||||
HighbdIntraPredParam(&vpx_highbd_dc_predictor_4x4_neon,
|
||||
&vpx_highbd_dc_predictor_4x4_c, 4, 8),
|
||||
HighbdIntraPredParam(&vpx_highbd_dc_predictor_8x8_neon,
|
||||
&vpx_highbd_dc_predictor_8x8_c, 8, 8),
|
||||
HighbdIntraPredParam(&vpx_highbd_dc_predictor_16x16_neon,
|
||||
&vpx_highbd_dc_predictor_16x16_c, 16, 8),
|
||||
HighbdIntraPredParam(&vpx_highbd_dc_predictor_32x32_neon,
|
||||
&vpx_highbd_dc_predictor_32x32_c, 32, 8),
|
||||
HighbdIntraPredParam(&vpx_highbd_dc_top_predictor_4x4_neon,
|
||||
&vpx_highbd_dc_top_predictor_4x4_c, 4, 8),
|
||||
HighbdIntraPredParam(&vpx_highbd_dc_top_predictor_8x8_neon,
|
||||
&vpx_highbd_dc_top_predictor_8x8_c, 8, 8),
|
||||
HighbdIntraPredParam(&vpx_highbd_dc_top_predictor_16x16_neon,
|
||||
&vpx_highbd_dc_top_predictor_16x16_c, 16, 8),
|
||||
HighbdIntraPredParam(&vpx_highbd_dc_top_predictor_32x32_neon,
|
||||
&vpx_highbd_dc_top_predictor_32x32_c, 32, 8),
|
||||
HighbdIntraPredParam(&vpx_highbd_h_predictor_4x4_neon,
|
||||
&vpx_highbd_h_predictor_4x4_c, 4, 8),
|
||||
HighbdIntraPredParam(&vpx_highbd_h_predictor_8x8_neon,
|
||||
&vpx_highbd_h_predictor_8x8_c, 8, 8),
|
||||
HighbdIntraPredParam(&vpx_highbd_h_predictor_16x16_neon,
|
||||
&vpx_highbd_h_predictor_16x16_c, 16, 8),
|
||||
HighbdIntraPredParam(&vpx_highbd_h_predictor_32x32_neon,
|
||||
&vpx_highbd_h_predictor_32x32_c, 32, 8),
|
||||
HighbdIntraPredParam(&vpx_highbd_tm_predictor_4x4_neon,
|
||||
&vpx_highbd_tm_predictor_4x4_c, 4, 8),
|
||||
HighbdIntraPredParam(&vpx_highbd_tm_predictor_8x8_neon,
|
||||
&vpx_highbd_tm_predictor_8x8_c, 8, 8),
|
||||
HighbdIntraPredParam(&vpx_highbd_tm_predictor_16x16_neon,
|
||||
&vpx_highbd_tm_predictor_16x16_c, 16, 8),
|
||||
HighbdIntraPredParam(&vpx_highbd_tm_predictor_32x32_neon,
|
||||
&vpx_highbd_tm_predictor_32x32_c, 32, 8),
|
||||
HighbdIntraPredParam(&vpx_highbd_v_predictor_4x4_neon,
|
||||
&vpx_highbd_v_predictor_4x4_c, 4, 8),
|
||||
HighbdIntraPredParam(&vpx_highbd_v_predictor_8x8_neon,
|
||||
&vpx_highbd_v_predictor_8x8_c, 8, 8),
|
||||
HighbdIntraPredParam(&vpx_highbd_v_predictor_16x16_neon,
|
||||
&vpx_highbd_v_predictor_16x16_c, 16, 8),
|
||||
HighbdIntraPredParam(&vpx_highbd_v_predictor_32x32_neon,
|
||||
&vpx_highbd_v_predictor_32x32_c, 32, 8)));
|
||||
|
||||
INSTANTIATE_TEST_CASE_P(
|
||||
NEON_TO_C_10, VP9HighbdIntraPredTest,
|
||||
::testing::Values(
|
||||
HighbdIntraPredParam(&vpx_highbd_d45_predictor_4x4_neon,
|
||||
&vpx_highbd_d45_predictor_4x4_c, 4, 10),
|
||||
HighbdIntraPredParam(&vpx_highbd_d45_predictor_8x8_neon,
|
||||
&vpx_highbd_d45_predictor_8x8_c, 8, 10),
|
||||
HighbdIntraPredParam(&vpx_highbd_d45_predictor_16x16_neon,
|
||||
&vpx_highbd_d45_predictor_16x16_c, 16, 10),
|
||||
HighbdIntraPredParam(&vpx_highbd_d45_predictor_32x32_neon,
|
||||
&vpx_highbd_d45_predictor_32x32_c, 32, 10),
|
||||
HighbdIntraPredParam(&vpx_highbd_d135_predictor_4x4_neon,
|
||||
&vpx_highbd_d135_predictor_4x4_c, 4, 10),
|
||||
HighbdIntraPredParam(&vpx_highbd_d135_predictor_8x8_neon,
|
||||
&vpx_highbd_d135_predictor_8x8_c, 8, 10),
|
||||
HighbdIntraPredParam(&vpx_highbd_d135_predictor_16x16_neon,
|
||||
&vpx_highbd_d135_predictor_16x16_c, 16, 10),
|
||||
HighbdIntraPredParam(&vpx_highbd_d135_predictor_32x32_neon,
|
||||
&vpx_highbd_d135_predictor_32x32_c, 32, 10),
|
||||
HighbdIntraPredParam(&vpx_highbd_dc_128_predictor_4x4_neon,
|
||||
&vpx_highbd_dc_128_predictor_4x4_c, 4, 10),
|
||||
HighbdIntraPredParam(&vpx_highbd_dc_128_predictor_8x8_neon,
|
||||
&vpx_highbd_dc_128_predictor_8x8_c, 8, 10),
|
||||
HighbdIntraPredParam(&vpx_highbd_dc_128_predictor_16x16_neon,
|
||||
&vpx_highbd_dc_128_predictor_16x16_c, 16, 10),
|
||||
HighbdIntraPredParam(&vpx_highbd_dc_128_predictor_32x32_neon,
|
||||
&vpx_highbd_dc_128_predictor_32x32_c, 32, 10),
|
||||
HighbdIntraPredParam(&vpx_highbd_dc_left_predictor_4x4_neon,
|
||||
&vpx_highbd_dc_left_predictor_4x4_c, 4, 10),
|
||||
HighbdIntraPredParam(&vpx_highbd_dc_left_predictor_8x8_neon,
|
||||
&vpx_highbd_dc_left_predictor_8x8_c, 8, 10),
|
||||
HighbdIntraPredParam(&vpx_highbd_dc_left_predictor_16x16_neon,
|
||||
&vpx_highbd_dc_left_predictor_16x16_c, 16, 10),
|
||||
HighbdIntraPredParam(&vpx_highbd_dc_left_predictor_32x32_neon,
|
||||
&vpx_highbd_dc_left_predictor_32x32_c, 32, 10),
|
||||
HighbdIntraPredParam(&vpx_highbd_dc_predictor_4x4_neon,
|
||||
&vpx_highbd_dc_predictor_4x4_c, 4, 10),
|
||||
HighbdIntraPredParam(&vpx_highbd_dc_predictor_8x8_neon,
|
||||
&vpx_highbd_dc_predictor_8x8_c, 8, 10),
|
||||
HighbdIntraPredParam(&vpx_highbd_dc_predictor_16x16_neon,
|
||||
&vpx_highbd_dc_predictor_16x16_c, 16, 10),
|
||||
HighbdIntraPredParam(&vpx_highbd_dc_predictor_32x32_neon,
|
||||
&vpx_highbd_dc_predictor_32x32_c, 32, 10),
|
||||
HighbdIntraPredParam(&vpx_highbd_dc_top_predictor_4x4_neon,
|
||||
&vpx_highbd_dc_top_predictor_4x4_c, 4, 10),
|
||||
HighbdIntraPredParam(&vpx_highbd_dc_top_predictor_8x8_neon,
|
||||
&vpx_highbd_dc_top_predictor_8x8_c, 8, 10),
|
||||
HighbdIntraPredParam(&vpx_highbd_dc_top_predictor_16x16_neon,
|
||||
&vpx_highbd_dc_top_predictor_16x16_c, 16, 10),
|
||||
HighbdIntraPredParam(&vpx_highbd_dc_top_predictor_32x32_neon,
|
||||
&vpx_highbd_dc_top_predictor_32x32_c, 32, 10),
|
||||
HighbdIntraPredParam(&vpx_highbd_h_predictor_4x4_neon,
|
||||
&vpx_highbd_h_predictor_4x4_c, 4, 10),
|
||||
HighbdIntraPredParam(&vpx_highbd_h_predictor_8x8_neon,
|
||||
&vpx_highbd_h_predictor_8x8_c, 8, 10),
|
||||
HighbdIntraPredParam(&vpx_highbd_h_predictor_16x16_neon,
|
||||
&vpx_highbd_h_predictor_16x16_c, 16, 10),
|
||||
HighbdIntraPredParam(&vpx_highbd_h_predictor_32x32_neon,
|
||||
&vpx_highbd_h_predictor_32x32_c, 32, 10),
|
||||
HighbdIntraPredParam(&vpx_highbd_tm_predictor_4x4_neon,
|
||||
&vpx_highbd_tm_predictor_4x4_c, 4, 10),
|
||||
HighbdIntraPredParam(&vpx_highbd_tm_predictor_8x8_neon,
|
||||
&vpx_highbd_tm_predictor_8x8_c, 8, 10),
|
||||
HighbdIntraPredParam(&vpx_highbd_tm_predictor_16x16_neon,
|
||||
&vpx_highbd_tm_predictor_16x16_c, 16, 10),
|
||||
HighbdIntraPredParam(&vpx_highbd_tm_predictor_32x32_neon,
|
||||
&vpx_highbd_tm_predictor_32x32_c, 32, 10),
|
||||
HighbdIntraPredParam(&vpx_highbd_v_predictor_4x4_neon,
|
||||
&vpx_highbd_v_predictor_4x4_c, 4, 10),
|
||||
HighbdIntraPredParam(&vpx_highbd_v_predictor_8x8_neon,
|
||||
&vpx_highbd_v_predictor_8x8_c, 8, 10),
|
||||
HighbdIntraPredParam(&vpx_highbd_v_predictor_16x16_neon,
|
||||
&vpx_highbd_v_predictor_16x16_c, 16, 10),
|
||||
HighbdIntraPredParam(&vpx_highbd_v_predictor_32x32_neon,
|
||||
&vpx_highbd_v_predictor_32x32_c, 32, 10)));
|
||||
|
||||
INSTANTIATE_TEST_CASE_P(
|
||||
NEON_TO_C_12, VP9HighbdIntraPredTest,
|
||||
::testing::Values(
|
||||
HighbdIntraPredParam(&vpx_highbd_d45_predictor_4x4_neon,
|
||||
&vpx_highbd_d45_predictor_4x4_c, 4, 12),
|
||||
HighbdIntraPredParam(&vpx_highbd_d45_predictor_8x8_neon,
|
||||
&vpx_highbd_d45_predictor_8x8_c, 8, 12),
|
||||
HighbdIntraPredParam(&vpx_highbd_d45_predictor_16x16_neon,
|
||||
&vpx_highbd_d45_predictor_16x16_c, 16, 12),
|
||||
HighbdIntraPredParam(&vpx_highbd_d45_predictor_32x32_neon,
|
||||
&vpx_highbd_d45_predictor_32x32_c, 32, 12),
|
||||
HighbdIntraPredParam(&vpx_highbd_d135_predictor_4x4_neon,
|
||||
&vpx_highbd_d135_predictor_4x4_c, 4, 12),
|
||||
HighbdIntraPredParam(&vpx_highbd_d135_predictor_8x8_neon,
|
||||
&vpx_highbd_d135_predictor_8x8_c, 8, 12),
|
||||
HighbdIntraPredParam(&vpx_highbd_d135_predictor_16x16_neon,
|
||||
&vpx_highbd_d135_predictor_16x16_c, 16, 12),
|
||||
HighbdIntraPredParam(&vpx_highbd_d135_predictor_32x32_neon,
|
||||
&vpx_highbd_d135_predictor_32x32_c, 32, 12),
|
||||
HighbdIntraPredParam(&vpx_highbd_dc_128_predictor_4x4_neon,
|
||||
&vpx_highbd_dc_128_predictor_4x4_c, 4, 12),
|
||||
HighbdIntraPredParam(&vpx_highbd_dc_128_predictor_8x8_neon,
|
||||
&vpx_highbd_dc_128_predictor_8x8_c, 8, 12),
|
||||
HighbdIntraPredParam(&vpx_highbd_dc_128_predictor_16x16_neon,
|
||||
&vpx_highbd_dc_128_predictor_16x16_c, 16, 12),
|
||||
HighbdIntraPredParam(&vpx_highbd_dc_128_predictor_32x32_neon,
|
||||
&vpx_highbd_dc_128_predictor_32x32_c, 32, 12),
|
||||
HighbdIntraPredParam(&vpx_highbd_dc_left_predictor_4x4_neon,
|
||||
&vpx_highbd_dc_left_predictor_4x4_c, 4, 12),
|
||||
HighbdIntraPredParam(&vpx_highbd_dc_left_predictor_8x8_neon,
|
||||
&vpx_highbd_dc_left_predictor_8x8_c, 8, 12),
|
||||
HighbdIntraPredParam(&vpx_highbd_dc_left_predictor_16x16_neon,
|
||||
&vpx_highbd_dc_left_predictor_16x16_c, 16, 12),
|
||||
HighbdIntraPredParam(&vpx_highbd_dc_left_predictor_32x32_neon,
|
||||
&vpx_highbd_dc_left_predictor_32x32_c, 32, 12),
|
||||
HighbdIntraPredParam(&vpx_highbd_dc_predictor_4x4_neon,
|
||||
&vpx_highbd_dc_predictor_4x4_c, 4, 12),
|
||||
HighbdIntraPredParam(&vpx_highbd_dc_predictor_8x8_neon,
|
||||
&vpx_highbd_dc_predictor_8x8_c, 8, 12),
|
||||
HighbdIntraPredParam(&vpx_highbd_dc_predictor_16x16_neon,
|
||||
&vpx_highbd_dc_predictor_16x16_c, 16, 12),
|
||||
HighbdIntraPredParam(&vpx_highbd_dc_predictor_32x32_neon,
|
||||
&vpx_highbd_dc_predictor_32x32_c, 32, 12),
|
||||
HighbdIntraPredParam(&vpx_highbd_dc_top_predictor_4x4_neon,
|
||||
&vpx_highbd_dc_top_predictor_4x4_c, 4, 12),
|
||||
HighbdIntraPredParam(&vpx_highbd_dc_top_predictor_8x8_neon,
|
||||
&vpx_highbd_dc_top_predictor_8x8_c, 8, 12),
|
||||
HighbdIntraPredParam(&vpx_highbd_dc_top_predictor_16x16_neon,
|
||||
&vpx_highbd_dc_top_predictor_16x16_c, 16, 12),
|
||||
HighbdIntraPredParam(&vpx_highbd_dc_top_predictor_32x32_neon,
|
||||
&vpx_highbd_dc_top_predictor_32x32_c, 32, 12),
|
||||
HighbdIntraPredParam(&vpx_highbd_h_predictor_4x4_neon,
|
||||
&vpx_highbd_h_predictor_4x4_c, 4, 12),
|
||||
HighbdIntraPredParam(&vpx_highbd_h_predictor_8x8_neon,
|
||||
&vpx_highbd_h_predictor_8x8_c, 8, 12),
|
||||
HighbdIntraPredParam(&vpx_highbd_h_predictor_16x16_neon,
|
||||
&vpx_highbd_h_predictor_16x16_c, 16, 12),
|
||||
HighbdIntraPredParam(&vpx_highbd_h_predictor_32x32_neon,
|
||||
&vpx_highbd_h_predictor_32x32_c, 32, 12),
|
||||
HighbdIntraPredParam(&vpx_highbd_tm_predictor_4x4_neon,
|
||||
&vpx_highbd_tm_predictor_4x4_c, 4, 12),
|
||||
HighbdIntraPredParam(&vpx_highbd_tm_predictor_8x8_neon,
|
||||
&vpx_highbd_tm_predictor_8x8_c, 8, 12),
|
||||
HighbdIntraPredParam(&vpx_highbd_tm_predictor_16x16_neon,
|
||||
&vpx_highbd_tm_predictor_16x16_c, 16, 12),
|
||||
HighbdIntraPredParam(&vpx_highbd_tm_predictor_32x32_neon,
|
||||
&vpx_highbd_tm_predictor_32x32_c, 32, 12),
|
||||
HighbdIntraPredParam(&vpx_highbd_v_predictor_4x4_neon,
|
||||
&vpx_highbd_v_predictor_4x4_c, 4, 12),
|
||||
HighbdIntraPredParam(&vpx_highbd_v_predictor_8x8_neon,
|
||||
&vpx_highbd_v_predictor_8x8_c, 8, 12),
|
||||
HighbdIntraPredParam(&vpx_highbd_v_predictor_16x16_neon,
|
||||
&vpx_highbd_v_predictor_16x16_c, 16, 12),
|
||||
HighbdIntraPredParam(&vpx_highbd_v_predictor_32x32_neon,
|
||||
&vpx_highbd_v_predictor_32x32_c, 32, 12)));
|
||||
#endif // HAVE_NEON
|
||||
|
||||
#endif // CONFIG_VP9_HIGHBITDEPTH
|
||||
} // namespace
|
||||
|
@ -1,97 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2017 The WebM project authors. All Rights Reserved.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license
|
||||
* that can be found in the LICENSE file in the root of the source
|
||||
* tree. An additional intellectual property rights grant can be found
|
||||
* in the file PATENTS. All contributing project authors may
|
||||
* be found in the AUTHORS file in the root of the source tree.
|
||||
*/
|
||||
|
||||
#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/yuv_video_source.h"
|
||||
|
||||
namespace {
|
||||
#define MAX_EXTREME_MV 1
|
||||
#define MIN_EXTREME_MV 2
|
||||
|
||||
// Encoding modes
|
||||
const libvpx_test::TestMode kEncodingModeVectors[] = {
|
||||
::libvpx_test::kTwoPassGood, ::libvpx_test::kOnePassGood,
|
||||
::libvpx_test::kRealTime
|
||||
};
|
||||
|
||||
// Encoding speeds
|
||||
const int kCpuUsedVectors[] = { 0, 1, 2, 3, 4, 5, 6 };
|
||||
|
||||
// MV test modes: 1 - always use maximum MV; 2 - always use minimum MV.
|
||||
const int kMVTestModes[] = { MAX_EXTREME_MV, MIN_EXTREME_MV };
|
||||
|
||||
class MotionVectorTestLarge
|
||||
: public ::libvpx_test::EncoderTest,
|
||||
public ::libvpx_test::CodecTestWith3Params<libvpx_test::TestMode, int,
|
||||
int> {
|
||||
protected:
|
||||
MotionVectorTestLarge()
|
||||
: EncoderTest(GET_PARAM(0)), encoding_mode_(GET_PARAM(1)),
|
||||
cpu_used_(GET_PARAM(2)), mv_test_mode_(GET_PARAM(3)) {}
|
||||
|
||||
virtual ~MotionVectorTestLarge() {}
|
||||
|
||||
virtual void SetUp() {
|
||||
InitializeConfig();
|
||||
SetMode(encoding_mode_);
|
||||
if (encoding_mode_ != ::libvpx_test::kRealTime) {
|
||||
cfg_.g_lag_in_frames = 3;
|
||||
cfg_.rc_end_usage = VPX_VBR;
|
||||
} else {
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
virtual void PreEncodeFrameHook(::libvpx_test::VideoSource *video,
|
||||
::libvpx_test::Encoder *encoder) {
|
||||
if (video->frame() == 1) {
|
||||
encoder->Control(VP8E_SET_CPUUSED, cpu_used_);
|
||||
encoder->Control(VP9E_ENABLE_MOTION_VECTOR_UNIT_TEST, mv_test_mode_);
|
||||
if (encoding_mode_ != ::libvpx_test::kRealTime) {
|
||||
encoder->Control(VP8E_SET_ENABLEAUTOALTREF, 1);
|
||||
encoder->Control(VP8E_SET_ARNR_MAXFRAMES, 7);
|
||||
encoder->Control(VP8E_SET_ARNR_STRENGTH, 5);
|
||||
encoder->Control(VP8E_SET_ARNR_TYPE, 3);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
libvpx_test::TestMode encoding_mode_;
|
||||
int cpu_used_;
|
||||
int mv_test_mode_;
|
||||
};
|
||||
|
||||
TEST_P(MotionVectorTestLarge, OverallTest) {
|
||||
cfg_.rc_target_bitrate = 24000;
|
||||
cfg_.g_profile = 0;
|
||||
init_flags_ = VPX_CODEC_USE_PSNR;
|
||||
|
||||
testing::internal::scoped_ptr<libvpx_test::VideoSource> video;
|
||||
video.reset(new libvpx_test::YUVVideoSource(
|
||||
"niklas_640_480_30.yuv", VPX_IMG_FMT_I420, 3840, 2160, // 2048, 1080,
|
||||
30, 1, 0, 5));
|
||||
|
||||
ASSERT_TRUE(video.get() != NULL);
|
||||
ASSERT_NO_FATAL_FAILURE(RunLoop(video.get()));
|
||||
}
|
||||
|
||||
VP9_INSTANTIATE_TEST_CASE(MotionVectorTestLarge,
|
||||
::testing::ValuesIn(kEncodingModeVectors),
|
||||
::testing::ValuesIn(kCpuUsedVectors),
|
||||
::testing::ValuesIn(kMVTestModes));
|
||||
} // namespace
|
@ -14,11 +14,9 @@
|
||||
|
||||
#include "third_party/googletest/src/include/gtest/gtest.h"
|
||||
|
||||
#include "./vp9_rtcd.h"
|
||||
#include "./vpx_config.h"
|
||||
#include "./vpx_dsp_rtcd.h"
|
||||
#include "test/acm_random.h"
|
||||
#include "test/buffer.h"
|
||||
#include "test/clear_system_state.h"
|
||||
#include "test/register_state_check.h"
|
||||
#include "test/util.h"
|
||||
@ -26,12 +24,11 @@
|
||||
#include "vp9/common/vp9_scan.h"
|
||||
#include "vpx/vpx_codec.h"
|
||||
#include "vpx/vpx_integer.h"
|
||||
#include "vpx_ports/vpx_timer.h"
|
||||
|
||||
using libvpx_test::ACMRandom;
|
||||
using libvpx_test::Buffer;
|
||||
|
||||
namespace {
|
||||
#if CONFIG_VP9_HIGHBITDEPTH
|
||||
const int number_of_iterations = 100;
|
||||
|
||||
typedef void (*QuantizeFunc)(const tran_low_t *coeff, intptr_t count,
|
||||
@ -41,537 +38,307 @@ typedef void (*QuantizeFunc)(const tran_low_t *coeff, intptr_t count,
|
||||
tran_low_t *dqcoeff, const int16_t *dequant,
|
||||
uint16_t *eob, const int16_t *scan,
|
||||
const int16_t *iscan);
|
||||
typedef ::testing::tuple<QuantizeFunc, QuantizeFunc, vpx_bit_depth_t,
|
||||
int /*max_size*/, bool /*is_fp*/>
|
||||
typedef std::tr1::tuple<QuantizeFunc, QuantizeFunc, vpx_bit_depth_t>
|
||||
QuantizeParam;
|
||||
|
||||
// Wrapper for FP version which does not use zbin or quant_shift.
|
||||
typedef void (*QuantizeFPFunc)(const tran_low_t *coeff, intptr_t count,
|
||||
int skip_block, const int16_t *round,
|
||||
const int16_t *quant, tran_low_t *qcoeff,
|
||||
tran_low_t *dqcoeff, const int16_t *dequant,
|
||||
uint16_t *eob, const int16_t *scan,
|
||||
const int16_t *iscan);
|
||||
|
||||
template <QuantizeFPFunc fn>
|
||||
void QuantFPWrapper(const tran_low_t *coeff, intptr_t count, int skip_block,
|
||||
const int16_t *zbin, const int16_t *round,
|
||||
const int16_t *quant, const int16_t *quant_shift,
|
||||
tran_low_t *qcoeff, tran_low_t *dqcoeff,
|
||||
const int16_t *dequant, uint16_t *eob, const int16_t *scan,
|
||||
const int16_t *iscan) {
|
||||
(void)zbin;
|
||||
(void)quant_shift;
|
||||
|
||||
fn(coeff, count, skip_block, round, quant, qcoeff, dqcoeff, dequant, eob,
|
||||
scan, iscan);
|
||||
}
|
||||
|
||||
class VP9QuantizeBase {
|
||||
class VP9QuantizeTest : public ::testing::TestWithParam<QuantizeParam> {
|
||||
public:
|
||||
VP9QuantizeBase(vpx_bit_depth_t bit_depth, int max_size, bool is_fp)
|
||||
: bit_depth_(bit_depth), max_size_(max_size), is_fp_(is_fp) {
|
||||
max_value_ = (1 << bit_depth_) - 1;
|
||||
zbin_ptr_ =
|
||||
reinterpret_cast<int16_t *>(vpx_memalign(16, 8 * sizeof(*zbin_ptr_)));
|
||||
round_fp_ptr_ = reinterpret_cast<int16_t *>(
|
||||
vpx_memalign(16, 8 * sizeof(*round_fp_ptr_)));
|
||||
quant_fp_ptr_ = reinterpret_cast<int16_t *>(
|
||||
vpx_memalign(16, 8 * sizeof(*quant_fp_ptr_)));
|
||||
round_ptr_ =
|
||||
reinterpret_cast<int16_t *>(vpx_memalign(16, 8 * sizeof(*round_ptr_)));
|
||||
quant_ptr_ =
|
||||
reinterpret_cast<int16_t *>(vpx_memalign(16, 8 * sizeof(*quant_ptr_)));
|
||||
quant_shift_ptr_ = reinterpret_cast<int16_t *>(
|
||||
vpx_memalign(16, 8 * sizeof(*quant_shift_ptr_)));
|
||||
dequant_ptr_ = reinterpret_cast<int16_t *>(
|
||||
vpx_memalign(16, 8 * sizeof(*dequant_ptr_)));
|
||||
virtual ~VP9QuantizeTest() {}
|
||||
virtual void SetUp() {
|
||||
quantize_op_ = GET_PARAM(0);
|
||||
ref_quantize_op_ = GET_PARAM(1);
|
||||
bit_depth_ = GET_PARAM(2);
|
||||
mask_ = (1 << bit_depth_) - 1;
|
||||
}
|
||||
|
||||
~VP9QuantizeBase() {
|
||||
vpx_free(zbin_ptr_);
|
||||
vpx_free(round_fp_ptr_);
|
||||
vpx_free(quant_fp_ptr_);
|
||||
vpx_free(round_ptr_);
|
||||
vpx_free(quant_ptr_);
|
||||
vpx_free(quant_shift_ptr_);
|
||||
vpx_free(dequant_ptr_);
|
||||
zbin_ptr_ = NULL;
|
||||
round_fp_ptr_ = NULL;
|
||||
quant_fp_ptr_ = NULL;
|
||||
round_ptr_ = NULL;
|
||||
quant_ptr_ = NULL;
|
||||
quant_shift_ptr_ = NULL;
|
||||
dequant_ptr_ = NULL;
|
||||
libvpx_test::ClearSystemState();
|
||||
}
|
||||
virtual void TearDown() { libvpx_test::ClearSystemState(); }
|
||||
|
||||
protected:
|
||||
int16_t *zbin_ptr_;
|
||||
int16_t *round_fp_ptr_;
|
||||
int16_t *quant_fp_ptr_;
|
||||
int16_t *round_ptr_;
|
||||
int16_t *quant_ptr_;
|
||||
int16_t *quant_shift_ptr_;
|
||||
int16_t *dequant_ptr_;
|
||||
const vpx_bit_depth_t bit_depth_;
|
||||
int max_value_;
|
||||
const int max_size_;
|
||||
const bool is_fp_;
|
||||
vpx_bit_depth_t bit_depth_;
|
||||
int mask_;
|
||||
QuantizeFunc quantize_op_;
|
||||
QuantizeFunc ref_quantize_op_;
|
||||
};
|
||||
|
||||
class VP9QuantizeTest : public VP9QuantizeBase,
|
||||
public ::testing::TestWithParam<QuantizeParam> {
|
||||
class VP9Quantize32Test : public ::testing::TestWithParam<QuantizeParam> {
|
||||
public:
|
||||
VP9QuantizeTest()
|
||||
: VP9QuantizeBase(GET_PARAM(2), GET_PARAM(3), GET_PARAM(4)),
|
||||
quantize_op_(GET_PARAM(0)), ref_quantize_op_(GET_PARAM(1)) {}
|
||||
virtual ~VP9Quantize32Test() {}
|
||||
virtual void SetUp() {
|
||||
quantize_op_ = GET_PARAM(0);
|
||||
ref_quantize_op_ = GET_PARAM(1);
|
||||
bit_depth_ = GET_PARAM(2);
|
||||
mask_ = (1 << bit_depth_) - 1;
|
||||
}
|
||||
|
||||
virtual void TearDown() { libvpx_test::ClearSystemState(); }
|
||||
|
||||
protected:
|
||||
const QuantizeFunc quantize_op_;
|
||||
const QuantizeFunc ref_quantize_op_;
|
||||
vpx_bit_depth_t bit_depth_;
|
||||
int mask_;
|
||||
QuantizeFunc quantize_op_;
|
||||
QuantizeFunc ref_quantize_op_;
|
||||
};
|
||||
|
||||
// This quantizer compares the AC coefficients to the quantization step size to
|
||||
// determine if further multiplication operations are needed.
|
||||
// Based on vp9_quantize_fp_sse2().
|
||||
inline void quant_fp_nz(const tran_low_t *coeff_ptr, intptr_t n_coeffs,
|
||||
int skip_block, const int16_t *round_ptr,
|
||||
const int16_t *quant_ptr, tran_low_t *qcoeff_ptr,
|
||||
tran_low_t *dqcoeff_ptr, const int16_t *dequant_ptr,
|
||||
uint16_t *eob_ptr, const int16_t *scan,
|
||||
const int16_t *iscan, int is_32x32) {
|
||||
int i, eob = -1;
|
||||
const int thr = dequant_ptr[1] >> (1 + is_32x32);
|
||||
(void)iscan;
|
||||
(void)skip_block;
|
||||
assert(!skip_block);
|
||||
|
||||
// Quantization pass: All coefficients with index >= zero_flag are
|
||||
// skippable. Note: zero_flag can be zero.
|
||||
for (i = 0; i < n_coeffs; i += 16) {
|
||||
int y;
|
||||
int nzflag_cnt = 0;
|
||||
int abs_coeff[16];
|
||||
int coeff_sign[16];
|
||||
|
||||
// count nzflag for each row (16 tran_low_t)
|
||||
for (y = 0; y < 16; ++y) {
|
||||
const int rc = i + y;
|
||||
const int coeff = coeff_ptr[rc];
|
||||
coeff_sign[y] = (coeff >> 31);
|
||||
abs_coeff[y] = (coeff ^ coeff_sign[y]) - coeff_sign[y];
|
||||
// The first 16 are skipped in the sse2 code. Do the same here to match.
|
||||
if (i >= 16 && (abs_coeff[y] <= thr)) {
|
||||
nzflag_cnt++;
|
||||
}
|
||||
}
|
||||
|
||||
for (y = 0; y < 16; ++y) {
|
||||
const int rc = i + y;
|
||||
// If all of the AC coeffs in a row has magnitude less than the
|
||||
// quantization step_size/2, quantize to zero.
|
||||
if (nzflag_cnt < 16) {
|
||||
int tmp;
|
||||
int _round;
|
||||
|
||||
if (is_32x32) {
|
||||
_round = ROUND_POWER_OF_TWO(round_ptr[rc != 0], 1);
|
||||
} else {
|
||||
_round = round_ptr[rc != 0];
|
||||
}
|
||||
tmp = clamp(abs_coeff[y] + _round, INT16_MIN, INT16_MAX);
|
||||
tmp = (tmp * quant_ptr[rc != 0]) >> (16 - is_32x32);
|
||||
qcoeff_ptr[rc] = (tmp ^ coeff_sign[y]) - coeff_sign[y];
|
||||
dqcoeff_ptr[rc] = qcoeff_ptr[rc] * dequant_ptr[rc != 0];
|
||||
|
||||
if (is_32x32) {
|
||||
dqcoeff_ptr[rc] = qcoeff_ptr[rc] * dequant_ptr[rc != 0] / 2;
|
||||
} else {
|
||||
dqcoeff_ptr[rc] = qcoeff_ptr[rc] * dequant_ptr[rc != 0];
|
||||
}
|
||||
} else {
|
||||
qcoeff_ptr[rc] = 0;
|
||||
dqcoeff_ptr[rc] = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Scan for eob.
|
||||
for (i = 0; i < n_coeffs; i++) {
|
||||
// Use the scan order to find the correct eob.
|
||||
const int rc = scan[i];
|
||||
if (qcoeff_ptr[rc]) {
|
||||
eob = i;
|
||||
}
|
||||
}
|
||||
*eob_ptr = eob + 1;
|
||||
}
|
||||
|
||||
void quantize_fp_nz_c(const tran_low_t *coeff_ptr, intptr_t n_coeffs,
|
||||
int skip_block, const int16_t *round_ptr,
|
||||
const int16_t *quant_ptr, tran_low_t *qcoeff_ptr,
|
||||
tran_low_t *dqcoeff_ptr, const int16_t *dequant_ptr,
|
||||
uint16_t *eob_ptr, const int16_t *scan,
|
||||
const int16_t *iscan) {
|
||||
quant_fp_nz(coeff_ptr, n_coeffs, skip_block, round_ptr, quant_ptr, qcoeff_ptr,
|
||||
dqcoeff_ptr, dequant_ptr, eob_ptr, scan, iscan, 0);
|
||||
}
|
||||
|
||||
void quantize_fp_32x32_nz_c(const tran_low_t *coeff_ptr, intptr_t n_coeffs,
|
||||
int skip_block, const int16_t *round_ptr,
|
||||
const int16_t *quant_ptr, tran_low_t *qcoeff_ptr,
|
||||
tran_low_t *dqcoeff_ptr, const int16_t *dequant_ptr,
|
||||
uint16_t *eob_ptr, const int16_t *scan,
|
||||
const int16_t *iscan) {
|
||||
quant_fp_nz(coeff_ptr, n_coeffs, skip_block, round_ptr, quant_ptr, qcoeff_ptr,
|
||||
dqcoeff_ptr, dequant_ptr, eob_ptr, scan, iscan, 1);
|
||||
}
|
||||
|
||||
void GenerateHelperArrays(ACMRandom *rnd, int16_t *zbin, int16_t *round,
|
||||
int16_t *quant, int16_t *quant_shift,
|
||||
int16_t *dequant, int16_t *round_fp,
|
||||
int16_t *quant_fp) {
|
||||
// Max when q == 0. Otherwise, it is 48 for Y and 42 for U/V.
|
||||
const int max_qrounding_factor_fp = 64;
|
||||
|
||||
for (int j = 0; j < 2; j++) {
|
||||
// The range is 4 to 1828 in the VP9 tables.
|
||||
const int qlookup = rnd->RandRange(1825) + 4;
|
||||
round_fp[j] = (max_qrounding_factor_fp * qlookup) >> 7;
|
||||
quant_fp[j] = (1 << 16) / qlookup;
|
||||
|
||||
// Values determined by deconstructing vp9_init_quantizer().
|
||||
// zbin may be up to 1143 for 8 and 10 bit Y values, or 1200 for 12 bit Y
|
||||
// values or U/V values of any bit depth. This is because y_delta is not
|
||||
// factored into the vp9_ac_quant() call.
|
||||
zbin[j] = rnd->RandRange(1200);
|
||||
|
||||
// round may be up to 685 for Y values or 914 for U/V.
|
||||
round[j] = rnd->RandRange(914);
|
||||
// quant ranges from 1 to -32703
|
||||
quant[j] = static_cast<int>(rnd->RandRange(32704)) - 32703;
|
||||
// quant_shift goes up to 1 << 16.
|
||||
quant_shift[j] = rnd->RandRange(16384);
|
||||
// dequant maxes out at 1828 for all cases.
|
||||
dequant[j] = rnd->RandRange(1828);
|
||||
}
|
||||
for (int j = 2; j < 8; j++) {
|
||||
zbin[j] = zbin[1];
|
||||
round_fp[j] = round_fp[1];
|
||||
quant_fp[j] = quant_fp[1];
|
||||
round[j] = round[1];
|
||||
quant[j] = quant[1];
|
||||
quant_shift[j] = quant_shift[1];
|
||||
dequant[j] = dequant[1];
|
||||
}
|
||||
}
|
||||
|
||||
TEST_P(VP9QuantizeTest, OperationCheck) {
|
||||
ACMRandom rnd(ACMRandom::DeterministicSeed());
|
||||
Buffer<tran_low_t> coeff = Buffer<tran_low_t>(max_size_, max_size_, 0, 16);
|
||||
ASSERT_TRUE(coeff.Init());
|
||||
Buffer<tran_low_t> qcoeff = Buffer<tran_low_t>(max_size_, max_size_, 0, 32);
|
||||
ASSERT_TRUE(qcoeff.Init());
|
||||
Buffer<tran_low_t> dqcoeff = Buffer<tran_low_t>(max_size_, max_size_, 0, 32);
|
||||
ASSERT_TRUE(dqcoeff.Init());
|
||||
Buffer<tran_low_t> ref_qcoeff =
|
||||
Buffer<tran_low_t>(max_size_, max_size_, 0, 32);
|
||||
ASSERT_TRUE(ref_qcoeff.Init());
|
||||
Buffer<tran_low_t> ref_dqcoeff =
|
||||
Buffer<tran_low_t>(max_size_, max_size_, 0, 32);
|
||||
ASSERT_TRUE(ref_dqcoeff.Init());
|
||||
uint16_t eob, ref_eob;
|
||||
|
||||
DECLARE_ALIGNED(16, tran_low_t, coeff_ptr[256]);
|
||||
DECLARE_ALIGNED(16, int16_t, zbin_ptr[2]);
|
||||
DECLARE_ALIGNED(16, int16_t, round_ptr[2]);
|
||||
DECLARE_ALIGNED(16, int16_t, quant_ptr[2]);
|
||||
DECLARE_ALIGNED(16, int16_t, quant_shift_ptr[2]);
|
||||
DECLARE_ALIGNED(16, tran_low_t, qcoeff_ptr[256]);
|
||||
DECLARE_ALIGNED(16, tran_low_t, dqcoeff_ptr[256]);
|
||||
DECLARE_ALIGNED(16, tran_low_t, ref_qcoeff_ptr[256]);
|
||||
DECLARE_ALIGNED(16, tran_low_t, ref_dqcoeff_ptr[256]);
|
||||
DECLARE_ALIGNED(16, int16_t, dequant_ptr[2]);
|
||||
DECLARE_ALIGNED(16, uint16_t, eob_ptr[1]);
|
||||
DECLARE_ALIGNED(16, uint16_t, ref_eob_ptr[1]);
|
||||
int err_count_total = 0;
|
||||
int first_failure = -1;
|
||||
for (int i = 0; i < number_of_iterations; ++i) {
|
||||
// Test skip block for the first three iterations to catch all the different
|
||||
// sizes.
|
||||
const int skip_block = 0;
|
||||
TX_SIZE sz;
|
||||
if (max_size_ == 16) {
|
||||
sz = static_cast<TX_SIZE>(i % 3); // TX_4X4, TX_8X8 TX_16X16
|
||||
} else {
|
||||
sz = TX_32X32;
|
||||
}
|
||||
const TX_TYPE tx_type = static_cast<TX_TYPE>((i >> 2) % 3);
|
||||
const int skip_block = i == 0;
|
||||
const TX_SIZE sz = (TX_SIZE)(i % 3); // TX_4X4, TX_8X8 TX_16X16
|
||||
const TX_TYPE tx_type = (TX_TYPE)((i >> 2) % 3);
|
||||
const scan_order *scan_order = &vp9_scan_orders[sz][tx_type];
|
||||
const int count = (4 << sz) * (4 << sz);
|
||||
coeff.Set(&rnd, -max_value_, max_value_);
|
||||
GenerateHelperArrays(&rnd, zbin_ptr_, round_ptr_, quant_ptr_,
|
||||
quant_shift_ptr_, dequant_ptr_, round_fp_ptr_,
|
||||
quant_fp_ptr_);
|
||||
int16_t *r_ptr = (is_fp_) ? round_fp_ptr_ : round_ptr_;
|
||||
int16_t *q_ptr = (is_fp_) ? quant_fp_ptr_ : quant_ptr_;
|
||||
ref_quantize_op_(coeff.TopLeftPixel(), count, skip_block, zbin_ptr_, r_ptr,
|
||||
q_ptr, quant_shift_ptr_, ref_qcoeff.TopLeftPixel(),
|
||||
ref_dqcoeff.TopLeftPixel(), dequant_ptr_, &ref_eob,
|
||||
scan_order->scan, scan_order->iscan);
|
||||
|
||||
ASM_REGISTER_STATE_CHECK(quantize_op_(
|
||||
coeff.TopLeftPixel(), count, skip_block, zbin_ptr_, r_ptr, q_ptr,
|
||||
quant_shift_ptr_, qcoeff.TopLeftPixel(), dqcoeff.TopLeftPixel(),
|
||||
dequant_ptr_, &eob, scan_order->scan, scan_order->iscan));
|
||||
|
||||
EXPECT_TRUE(qcoeff.CheckValues(ref_qcoeff));
|
||||
EXPECT_TRUE(dqcoeff.CheckValues(ref_dqcoeff));
|
||||
|
||||
EXPECT_EQ(eob, ref_eob);
|
||||
|
||||
if (HasFailure()) {
|
||||
printf("Failure on iteration %d.\n", i);
|
||||
qcoeff.PrintDifference(ref_qcoeff);
|
||||
dqcoeff.PrintDifference(ref_dqcoeff);
|
||||
return;
|
||||
const int count = (4 << sz) * (4 << sz); // 16, 64, 256
|
||||
int err_count = 0;
|
||||
*eob_ptr = rnd.Rand16();
|
||||
*ref_eob_ptr = *eob_ptr;
|
||||
for (int j = 0; j < count; j++) {
|
||||
coeff_ptr[j] = rnd.Rand16() & mask_;
|
||||
}
|
||||
for (int j = 0; j < 2; j++) {
|
||||
zbin_ptr[j] = rnd.Rand16() & mask_;
|
||||
round_ptr[j] = rnd.Rand16();
|
||||
quant_ptr[j] = rnd.Rand16();
|
||||
quant_shift_ptr[j] = rnd.Rand16();
|
||||
dequant_ptr[j] = rnd.Rand16();
|
||||
}
|
||||
ref_quantize_op_(coeff_ptr, count, skip_block, zbin_ptr, round_ptr,
|
||||
quant_ptr, quant_shift_ptr, ref_qcoeff_ptr,
|
||||
ref_dqcoeff_ptr, dequant_ptr, ref_eob_ptr,
|
||||
scan_order->scan, scan_order->iscan);
|
||||
ASM_REGISTER_STATE_CHECK(quantize_op_(
|
||||
coeff_ptr, count, skip_block, zbin_ptr, round_ptr, quant_ptr,
|
||||
quant_shift_ptr, qcoeff_ptr, dqcoeff_ptr, dequant_ptr, eob_ptr,
|
||||
scan_order->scan, scan_order->iscan));
|
||||
for (int j = 0; j < sz; ++j) {
|
||||
err_count += (ref_qcoeff_ptr[j] != qcoeff_ptr[j]) |
|
||||
(ref_dqcoeff_ptr[j] != dqcoeff_ptr[j]);
|
||||
}
|
||||
err_count += (*ref_eob_ptr != *eob_ptr);
|
||||
if (err_count && !err_count_total) {
|
||||
first_failure = i;
|
||||
}
|
||||
err_count_total += err_count;
|
||||
}
|
||||
EXPECT_EQ(0, err_count_total)
|
||||
<< "Error: Quantization Test, C output doesn't match SSE2 output. "
|
||||
<< "First failed at test case " << first_failure;
|
||||
}
|
||||
|
||||
TEST_P(VP9Quantize32Test, OperationCheck) {
|
||||
ACMRandom rnd(ACMRandom::DeterministicSeed());
|
||||
DECLARE_ALIGNED(16, tran_low_t, coeff_ptr[1024]);
|
||||
DECLARE_ALIGNED(16, int16_t, zbin_ptr[2]);
|
||||
DECLARE_ALIGNED(16, int16_t, round_ptr[2]);
|
||||
DECLARE_ALIGNED(16, int16_t, quant_ptr[2]);
|
||||
DECLARE_ALIGNED(16, int16_t, quant_shift_ptr[2]);
|
||||
DECLARE_ALIGNED(16, tran_low_t, qcoeff_ptr[1024]);
|
||||
DECLARE_ALIGNED(16, tran_low_t, dqcoeff_ptr[1024]);
|
||||
DECLARE_ALIGNED(16, tran_low_t, ref_qcoeff_ptr[1024]);
|
||||
DECLARE_ALIGNED(16, tran_low_t, ref_dqcoeff_ptr[1024]);
|
||||
DECLARE_ALIGNED(16, int16_t, dequant_ptr[2]);
|
||||
DECLARE_ALIGNED(16, uint16_t, eob_ptr[1]);
|
||||
DECLARE_ALIGNED(16, uint16_t, ref_eob_ptr[1]);
|
||||
int err_count_total = 0;
|
||||
int first_failure = -1;
|
||||
for (int i = 0; i < number_of_iterations; ++i) {
|
||||
const int skip_block = i == 0;
|
||||
const TX_SIZE sz = TX_32X32;
|
||||
const TX_TYPE tx_type = (TX_TYPE)(i % 4);
|
||||
const scan_order *scan_order = &vp9_scan_orders[sz][tx_type];
|
||||
const int count = (4 << sz) * (4 << sz); // 1024
|
||||
int err_count = 0;
|
||||
*eob_ptr = rnd.Rand16();
|
||||
*ref_eob_ptr = *eob_ptr;
|
||||
for (int j = 0; j < count; j++) {
|
||||
coeff_ptr[j] = rnd.Rand16() & mask_;
|
||||
}
|
||||
for (int j = 0; j < 2; j++) {
|
||||
zbin_ptr[j] = rnd.Rand16() & mask_;
|
||||
round_ptr[j] = rnd.Rand16();
|
||||
quant_ptr[j] = rnd.Rand16();
|
||||
quant_shift_ptr[j] = rnd.Rand16();
|
||||
dequant_ptr[j] = rnd.Rand16();
|
||||
}
|
||||
ref_quantize_op_(coeff_ptr, count, skip_block, zbin_ptr, round_ptr,
|
||||
quant_ptr, quant_shift_ptr, ref_qcoeff_ptr,
|
||||
ref_dqcoeff_ptr, dequant_ptr, ref_eob_ptr,
|
||||
scan_order->scan, scan_order->iscan);
|
||||
ASM_REGISTER_STATE_CHECK(quantize_op_(
|
||||
coeff_ptr, count, skip_block, zbin_ptr, round_ptr, quant_ptr,
|
||||
quant_shift_ptr, qcoeff_ptr, dqcoeff_ptr, dequant_ptr, eob_ptr,
|
||||
scan_order->scan, scan_order->iscan));
|
||||
for (int j = 0; j < sz; ++j) {
|
||||
err_count += (ref_qcoeff_ptr[j] != qcoeff_ptr[j]) |
|
||||
(ref_dqcoeff_ptr[j] != dqcoeff_ptr[j]);
|
||||
}
|
||||
err_count += (*ref_eob_ptr != *eob_ptr);
|
||||
if (err_count && !err_count_total) {
|
||||
first_failure = i;
|
||||
}
|
||||
err_count_total += err_count;
|
||||
}
|
||||
EXPECT_EQ(0, err_count_total)
|
||||
<< "Error: Quantization Test, C output doesn't match SSE2 output. "
|
||||
<< "First failed at test case " << first_failure;
|
||||
}
|
||||
|
||||
TEST_P(VP9QuantizeTest, EOBCheck) {
|
||||
ACMRandom rnd(ACMRandom::DeterministicSeed());
|
||||
Buffer<tran_low_t> coeff = Buffer<tran_low_t>(max_size_, max_size_, 0, 16);
|
||||
ASSERT_TRUE(coeff.Init());
|
||||
Buffer<tran_low_t> qcoeff = Buffer<tran_low_t>(max_size_, max_size_, 0, 32);
|
||||
ASSERT_TRUE(qcoeff.Init());
|
||||
Buffer<tran_low_t> dqcoeff = Buffer<tran_low_t>(max_size_, max_size_, 0, 32);
|
||||
ASSERT_TRUE(dqcoeff.Init());
|
||||
Buffer<tran_low_t> ref_qcoeff =
|
||||
Buffer<tran_low_t>(max_size_, max_size_, 0, 32);
|
||||
ASSERT_TRUE(ref_qcoeff.Init());
|
||||
Buffer<tran_low_t> ref_dqcoeff =
|
||||
Buffer<tran_low_t>(max_size_, max_size_, 0, 32);
|
||||
ASSERT_TRUE(ref_dqcoeff.Init());
|
||||
uint16_t eob, ref_eob;
|
||||
|
||||
DECLARE_ALIGNED(16, tran_low_t, coeff_ptr[256]);
|
||||
DECLARE_ALIGNED(16, int16_t, zbin_ptr[2]);
|
||||
DECLARE_ALIGNED(16, int16_t, round_ptr[2]);
|
||||
DECLARE_ALIGNED(16, int16_t, quant_ptr[2]);
|
||||
DECLARE_ALIGNED(16, int16_t, quant_shift_ptr[2]);
|
||||
DECLARE_ALIGNED(16, tran_low_t, qcoeff_ptr[256]);
|
||||
DECLARE_ALIGNED(16, tran_low_t, dqcoeff_ptr[256]);
|
||||
DECLARE_ALIGNED(16, tran_low_t, ref_qcoeff_ptr[256]);
|
||||
DECLARE_ALIGNED(16, tran_low_t, ref_dqcoeff_ptr[256]);
|
||||
DECLARE_ALIGNED(16, int16_t, dequant_ptr[2]);
|
||||
DECLARE_ALIGNED(16, uint16_t, eob_ptr[1]);
|
||||
DECLARE_ALIGNED(16, uint16_t, ref_eob_ptr[1]);
|
||||
int err_count_total = 0;
|
||||
int first_failure = -1;
|
||||
for (int i = 0; i < number_of_iterations; ++i) {
|
||||
const int skip_block = 0;
|
||||
TX_SIZE sz;
|
||||
if (max_size_ == 16) {
|
||||
sz = static_cast<TX_SIZE>(i % 3); // TX_4X4, TX_8X8 TX_16X16
|
||||
} else {
|
||||
sz = TX_32X32;
|
||||
}
|
||||
const TX_TYPE tx_type = static_cast<TX_TYPE>((i >> 2) % 3);
|
||||
int skip_block = i == 0;
|
||||
TX_SIZE sz = (TX_SIZE)(i % 3); // TX_4X4, TX_8X8 TX_16X16
|
||||
TX_TYPE tx_type = (TX_TYPE)((i >> 2) % 3);
|
||||
const scan_order *scan_order = &vp9_scan_orders[sz][tx_type];
|
||||
int count = (4 << sz) * (4 << sz);
|
||||
int count = (4 << sz) * (4 << sz); // 16, 64, 256
|
||||
int err_count = 0;
|
||||
*eob_ptr = rnd.Rand16();
|
||||
*ref_eob_ptr = *eob_ptr;
|
||||
// Two random entries
|
||||
coeff.Set(0);
|
||||
coeff.TopLeftPixel()[rnd(count)] =
|
||||
static_cast<int>(rnd.RandRange(max_value_ * 2)) - max_value_;
|
||||
coeff.TopLeftPixel()[rnd(count)] =
|
||||
static_cast<int>(rnd.RandRange(max_value_ * 2)) - max_value_;
|
||||
GenerateHelperArrays(&rnd, zbin_ptr_, round_ptr_, quant_ptr_,
|
||||
quant_shift_ptr_, dequant_ptr_, round_fp_ptr_,
|
||||
quant_fp_ptr_);
|
||||
int16_t *r_ptr = (is_fp_) ? round_fp_ptr_ : round_ptr_;
|
||||
int16_t *q_ptr = (is_fp_) ? quant_fp_ptr_ : quant_ptr_;
|
||||
ref_quantize_op_(coeff.TopLeftPixel(), count, skip_block, zbin_ptr_, r_ptr,
|
||||
q_ptr, quant_shift_ptr_, ref_qcoeff.TopLeftPixel(),
|
||||
ref_dqcoeff.TopLeftPixel(), dequant_ptr_, &ref_eob,
|
||||
scan_order->scan, scan_order->iscan);
|
||||
for (int j = 0; j < count; j++) {
|
||||
coeff_ptr[j] = 0;
|
||||
}
|
||||
coeff_ptr[rnd(count)] = rnd.Rand16() & mask_;
|
||||
coeff_ptr[rnd(count)] = rnd.Rand16() & mask_;
|
||||
for (int j = 0; j < 2; j++) {
|
||||
zbin_ptr[j] = rnd.Rand16() & mask_;
|
||||
round_ptr[j] = rnd.Rand16();
|
||||
quant_ptr[j] = rnd.Rand16();
|
||||
quant_shift_ptr[j] = rnd.Rand16();
|
||||
dequant_ptr[j] = rnd.Rand16();
|
||||
}
|
||||
|
||||
ref_quantize_op_(coeff_ptr, count, skip_block, zbin_ptr, round_ptr,
|
||||
quant_ptr, quant_shift_ptr, ref_qcoeff_ptr,
|
||||
ref_dqcoeff_ptr, dequant_ptr, ref_eob_ptr,
|
||||
scan_order->scan, scan_order->iscan);
|
||||
ASM_REGISTER_STATE_CHECK(quantize_op_(
|
||||
coeff.TopLeftPixel(), count, skip_block, zbin_ptr_, r_ptr, q_ptr,
|
||||
quant_shift_ptr_, qcoeff.TopLeftPixel(), dqcoeff.TopLeftPixel(),
|
||||
dequant_ptr_, &eob, scan_order->scan, scan_order->iscan));
|
||||
coeff_ptr, count, skip_block, zbin_ptr, round_ptr, quant_ptr,
|
||||
quant_shift_ptr, qcoeff_ptr, dqcoeff_ptr, dequant_ptr, eob_ptr,
|
||||
scan_order->scan, scan_order->iscan));
|
||||
|
||||
EXPECT_TRUE(qcoeff.CheckValues(ref_qcoeff));
|
||||
EXPECT_TRUE(dqcoeff.CheckValues(ref_dqcoeff));
|
||||
|
||||
EXPECT_EQ(eob, ref_eob);
|
||||
|
||||
if (HasFailure()) {
|
||||
printf("Failure on iteration %d.\n", i);
|
||||
qcoeff.PrintDifference(ref_qcoeff);
|
||||
dqcoeff.PrintDifference(ref_dqcoeff);
|
||||
return;
|
||||
for (int j = 0; j < sz; ++j) {
|
||||
err_count += (ref_qcoeff_ptr[j] != qcoeff_ptr[j]) |
|
||||
(ref_dqcoeff_ptr[j] != dqcoeff_ptr[j]);
|
||||
}
|
||||
err_count += (*ref_eob_ptr != *eob_ptr);
|
||||
if (err_count && !err_count_total) {
|
||||
first_failure = i;
|
||||
}
|
||||
err_count_total += err_count;
|
||||
}
|
||||
EXPECT_EQ(0, err_count_total)
|
||||
<< "Error: Quantization Test, C output doesn't match SSE2 output. "
|
||||
<< "First failed at test case " << first_failure;
|
||||
}
|
||||
|
||||
TEST_P(VP9QuantizeTest, DISABLED_Speed) {
|
||||
TEST_P(VP9Quantize32Test, EOBCheck) {
|
||||
ACMRandom rnd(ACMRandom::DeterministicSeed());
|
||||
Buffer<tran_low_t> coeff = Buffer<tran_low_t>(max_size_, max_size_, 0, 16);
|
||||
ASSERT_TRUE(coeff.Init());
|
||||
Buffer<tran_low_t> qcoeff = Buffer<tran_low_t>(max_size_, max_size_, 0, 32);
|
||||
ASSERT_TRUE(qcoeff.Init());
|
||||
Buffer<tran_low_t> dqcoeff = Buffer<tran_low_t>(max_size_, max_size_, 0, 32);
|
||||
ASSERT_TRUE(dqcoeff.Init());
|
||||
uint16_t eob;
|
||||
TX_SIZE starting_sz, ending_sz;
|
||||
|
||||
if (max_size_ == 16) {
|
||||
starting_sz = TX_4X4;
|
||||
ending_sz = TX_16X16;
|
||||
} else {
|
||||
starting_sz = TX_32X32;
|
||||
ending_sz = TX_32X32;
|
||||
}
|
||||
|
||||
for (TX_SIZE sz = starting_sz; sz <= ending_sz; ++sz) {
|
||||
// zbin > coeff, zbin < coeff.
|
||||
for (int i = 0; i < 2; ++i) {
|
||||
const int skip_block = 0;
|
||||
// TX_TYPE defines the scan order. That is not relevant to the speed test.
|
||||
// Pick the first one.
|
||||
const TX_TYPE tx_type = DCT_DCT;
|
||||
const scan_order *scan_order = &vp9_scan_orders[sz][tx_type];
|
||||
const int count = (4 << sz) * (4 << sz);
|
||||
|
||||
GenerateHelperArrays(&rnd, zbin_ptr_, round_ptr_, quant_ptr_,
|
||||
quant_shift_ptr_, dequant_ptr_, round_fp_ptr_,
|
||||
quant_fp_ptr_);
|
||||
int16_t *r_ptr = (is_fp_) ? round_fp_ptr_ : round_ptr_;
|
||||
int16_t *q_ptr = (is_fp_) ? quant_fp_ptr_ : quant_ptr_;
|
||||
|
||||
if (i == 0) {
|
||||
// When |coeff values| are less than zbin the results are 0.
|
||||
int threshold = 100;
|
||||
if (max_size_ == 32) {
|
||||
// For 32x32, the threshold is halved. Double it to keep the values
|
||||
// from clearing it.
|
||||
threshold = 200;
|
||||
}
|
||||
for (int j = 0; j < 8; ++j) zbin_ptr_[j] = threshold;
|
||||
coeff.Set(&rnd, -99, 99);
|
||||
} else if (i == 1) {
|
||||
for (int j = 0; j < 8; ++j) zbin_ptr_[j] = 50;
|
||||
coeff.Set(&rnd, -500, 500);
|
||||
}
|
||||
|
||||
vpx_usec_timer timer;
|
||||
vpx_usec_timer_start(&timer);
|
||||
for (int j = 0; j < 100000000 / count; ++j) {
|
||||
quantize_op_(coeff.TopLeftPixel(), count, skip_block, zbin_ptr_, r_ptr,
|
||||
q_ptr, quant_shift_ptr_, qcoeff.TopLeftPixel(),
|
||||
dqcoeff.TopLeftPixel(), dequant_ptr_, &eob,
|
||||
scan_order->scan, scan_order->iscan);
|
||||
}
|
||||
vpx_usec_timer_mark(&timer);
|
||||
const int elapsed_time = static_cast<int>(vpx_usec_timer_elapsed(&timer));
|
||||
if (i == 0) printf("Bypass calculations.\n");
|
||||
if (i == 1) printf("Full calculations.\n");
|
||||
printf("Quantize %dx%d time: %5d ms\n", 4 << sz, 4 << sz,
|
||||
elapsed_time / 1000);
|
||||
DECLARE_ALIGNED(16, tran_low_t, coeff_ptr[1024]);
|
||||
DECLARE_ALIGNED(16, int16_t, zbin_ptr[2]);
|
||||
DECLARE_ALIGNED(16, int16_t, round_ptr[2]);
|
||||
DECLARE_ALIGNED(16, int16_t, quant_ptr[2]);
|
||||
DECLARE_ALIGNED(16, int16_t, quant_shift_ptr[2]);
|
||||
DECLARE_ALIGNED(16, tran_low_t, qcoeff_ptr[1024]);
|
||||
DECLARE_ALIGNED(16, tran_low_t, dqcoeff_ptr[1024]);
|
||||
DECLARE_ALIGNED(16, tran_low_t, ref_qcoeff_ptr[1024]);
|
||||
DECLARE_ALIGNED(16, tran_low_t, ref_dqcoeff_ptr[1024]);
|
||||
DECLARE_ALIGNED(16, int16_t, dequant_ptr[2]);
|
||||
DECLARE_ALIGNED(16, uint16_t, eob_ptr[1]);
|
||||
DECLARE_ALIGNED(16, uint16_t, ref_eob_ptr[1]);
|
||||
int err_count_total = 0;
|
||||
int first_failure = -1;
|
||||
for (int i = 0; i < number_of_iterations; ++i) {
|
||||
int skip_block = i == 0;
|
||||
TX_SIZE sz = TX_32X32;
|
||||
TX_TYPE tx_type = (TX_TYPE)(i % 4);
|
||||
const scan_order *scan_order = &vp9_scan_orders[sz][tx_type];
|
||||
int count = (4 << sz) * (4 << sz); // 1024
|
||||
int err_count = 0;
|
||||
*eob_ptr = rnd.Rand16();
|
||||
*ref_eob_ptr = *eob_ptr;
|
||||
for (int j = 0; j < count; j++) {
|
||||
coeff_ptr[j] = 0;
|
||||
}
|
||||
// Two random entries
|
||||
coeff_ptr[rnd(count)] = rnd.Rand16() & mask_;
|
||||
coeff_ptr[rnd(count)] = rnd.Rand16() & mask_;
|
||||
for (int j = 0; j < 2; j++) {
|
||||
zbin_ptr[j] = rnd.Rand16() & mask_;
|
||||
round_ptr[j] = rnd.Rand16();
|
||||
quant_ptr[j] = rnd.Rand16();
|
||||
quant_shift_ptr[j] = rnd.Rand16();
|
||||
dequant_ptr[j] = rnd.Rand16();
|
||||
}
|
||||
printf("\n");
|
||||
}
|
||||
}
|
||||
|
||||
using ::testing::make_tuple;
|
||||
ref_quantize_op_(coeff_ptr, count, skip_block, zbin_ptr, round_ptr,
|
||||
quant_ptr, quant_shift_ptr, ref_qcoeff_ptr,
|
||||
ref_dqcoeff_ptr, dequant_ptr, ref_eob_ptr,
|
||||
scan_order->scan, scan_order->iscan);
|
||||
ASM_REGISTER_STATE_CHECK(quantize_op_(
|
||||
coeff_ptr, count, skip_block, zbin_ptr, round_ptr, quant_ptr,
|
||||
quant_shift_ptr, qcoeff_ptr, dqcoeff_ptr, dequant_ptr, eob_ptr,
|
||||
scan_order->scan, scan_order->iscan));
|
||||
|
||||
for (int j = 0; j < sz; ++j) {
|
||||
err_count += (ref_qcoeff_ptr[j] != qcoeff_ptr[j]) |
|
||||
(ref_dqcoeff_ptr[j] != dqcoeff_ptr[j]);
|
||||
}
|
||||
err_count += (*ref_eob_ptr != *eob_ptr);
|
||||
if (err_count && !err_count_total) {
|
||||
first_failure = i;
|
||||
}
|
||||
err_count_total += err_count;
|
||||
}
|
||||
EXPECT_EQ(0, err_count_total)
|
||||
<< "Error: Quantization Test, C output doesn't match SSE2 output. "
|
||||
<< "First failed at test case " << first_failure;
|
||||
}
|
||||
using std::tr1::make_tuple;
|
||||
|
||||
#if HAVE_SSE2
|
||||
#if CONFIG_VP9_HIGHBITDEPTH
|
||||
// TODO(johannkoenig): Fix vpx_quantize_b_sse2 in highbitdepth builds.
|
||||
// make_tuple(&vpx_quantize_b_sse2, &vpx_highbd_quantize_b_c, VPX_BITS_8),
|
||||
INSTANTIATE_TEST_CASE_P(
|
||||
SSE2, VP9QuantizeTest,
|
||||
::testing::Values(
|
||||
make_tuple(&vpx_highbd_quantize_b_sse2, &vpx_highbd_quantize_b_c,
|
||||
VPX_BITS_8, 16, false),
|
||||
make_tuple(&vpx_highbd_quantize_b_sse2, &vpx_highbd_quantize_b_c,
|
||||
VPX_BITS_10, 16, false),
|
||||
make_tuple(&vpx_highbd_quantize_b_sse2, &vpx_highbd_quantize_b_c,
|
||||
VPX_BITS_12, 16, false),
|
||||
make_tuple(&vpx_highbd_quantize_b_32x32_sse2,
|
||||
&vpx_highbd_quantize_b_32x32_c, VPX_BITS_8, 32, false),
|
||||
make_tuple(&vpx_highbd_quantize_b_32x32_sse2,
|
||||
&vpx_highbd_quantize_b_32x32_c, VPX_BITS_10, 32, false),
|
||||
make_tuple(&vpx_highbd_quantize_b_32x32_sse2,
|
||||
&vpx_highbd_quantize_b_32x32_c, VPX_BITS_12, 32, false)));
|
||||
|
||||
#else
|
||||
::testing::Values(make_tuple(&vpx_highbd_quantize_b_sse2,
|
||||
&vpx_highbd_quantize_b_c, VPX_BITS_8),
|
||||
make_tuple(&vpx_highbd_quantize_b_sse2,
|
||||
&vpx_highbd_quantize_b_c, VPX_BITS_10),
|
||||
make_tuple(&vpx_highbd_quantize_b_sse2,
|
||||
&vpx_highbd_quantize_b_c, VPX_BITS_12)));
|
||||
INSTANTIATE_TEST_CASE_P(
|
||||
SSE2, VP9QuantizeTest,
|
||||
::testing::Values(make_tuple(&vpx_quantize_b_sse2, &vpx_quantize_b_c,
|
||||
VPX_BITS_8, 16, false),
|
||||
make_tuple(&QuantFPWrapper<vp9_quantize_fp_sse2>,
|
||||
&QuantFPWrapper<quantize_fp_nz_c>, VPX_BITS_8,
|
||||
16, true)));
|
||||
#endif // CONFIG_VP9_HIGHBITDEPTH
|
||||
SSE2, VP9Quantize32Test,
|
||||
::testing::Values(make_tuple(&vpx_highbd_quantize_b_32x32_sse2,
|
||||
&vpx_highbd_quantize_b_32x32_c, VPX_BITS_8),
|
||||
make_tuple(&vpx_highbd_quantize_b_32x32_sse2,
|
||||
&vpx_highbd_quantize_b_32x32_c, VPX_BITS_10),
|
||||
make_tuple(&vpx_highbd_quantize_b_32x32_sse2,
|
||||
&vpx_highbd_quantize_b_32x32_c, VPX_BITS_12)));
|
||||
#endif // HAVE_SSE2
|
||||
|
||||
#if HAVE_SSSE3 && !CONFIG_VP9_HIGHBITDEPTH
|
||||
#if ARCH_X86_64
|
||||
INSTANTIATE_TEST_CASE_P(
|
||||
SSSE3, VP9QuantizeTest,
|
||||
::testing::Values(make_tuple(&vpx_quantize_b_ssse3, &vpx_quantize_b_c,
|
||||
VPX_BITS_8, 16, false),
|
||||
make_tuple(&QuantFPWrapper<vp9_quantize_fp_ssse3>,
|
||||
&QuantFPWrapper<quantize_fp_nz_c>, VPX_BITS_8,
|
||||
16, true),
|
||||
make_tuple(&QuantFPWrapper<vp9_quantize_fp_32x32_ssse3>,
|
||||
&QuantFPWrapper<quantize_fp_32x32_nz_c>,
|
||||
VPX_BITS_8, 32, true)));
|
||||
#else
|
||||
INSTANTIATE_TEST_CASE_P(SSSE3, VP9QuantizeTest,
|
||||
::testing::Values(make_tuple(&vpx_quantize_b_ssse3,
|
||||
&vpx_quantize_b_c,
|
||||
VPX_BITS_8, 16, false)));
|
||||
#endif
|
||||
|
||||
#if ARCH_X86_64
|
||||
// TODO(johannkoenig): SSSE3 optimizations do not yet pass this test.
|
||||
INSTANTIATE_TEST_CASE_P(DISABLED_SSSE3, VP9QuantizeTest,
|
||||
::testing::Values(make_tuple(
|
||||
&vpx_quantize_b_32x32_ssse3,
|
||||
&vpx_quantize_b_32x32_c, VPX_BITS_8, 32, false)));
|
||||
#endif // ARCH_X86_64
|
||||
#endif // HAVE_SSSE3 && !CONFIG_VP9_HIGHBITDEPTH
|
||||
|
||||
// TODO(johannkoenig): AVX optimizations do not yet pass the 32x32 test or
|
||||
// highbitdepth configurations.
|
||||
#if HAVE_AVX && !CONFIG_VP9_HIGHBITDEPTH
|
||||
INSTANTIATE_TEST_CASE_P(
|
||||
AVX, VP9QuantizeTest,
|
||||
::testing::Values(make_tuple(&vpx_quantize_b_avx, &vpx_quantize_b_c,
|
||||
VPX_BITS_8, 16, false),
|
||||
// Even though SSSE3 and AVX do not match the reference
|
||||
// code, we can keep them in sync with each other.
|
||||
make_tuple(&vpx_quantize_b_32x32_avx,
|
||||
&vpx_quantize_b_32x32_ssse3, VPX_BITS_8, 32,
|
||||
false)));
|
||||
#endif // HAVE_AVX && !CONFIG_VP9_HIGHBITDEPTH
|
||||
|
||||
#if ARCH_X86_64 && HAVE_AVX2
|
||||
INSTANTIATE_TEST_CASE_P(
|
||||
AVX2, VP9QuantizeTest,
|
||||
::testing::Values(make_tuple(&QuantFPWrapper<vp9_quantize_fp_avx2>,
|
||||
&QuantFPWrapper<quantize_fp_nz_c>, VPX_BITS_8,
|
||||
16, true)));
|
||||
#endif // HAVE_AVX2 && !CONFIG_VP9_HIGHBITDEPTH
|
||||
|
||||
// TODO(webm:1448): dqcoeff is not handled correctly in HBD builds.
|
||||
#if HAVE_NEON && !CONFIG_VP9_HIGHBITDEPTH
|
||||
INSTANTIATE_TEST_CASE_P(
|
||||
NEON, VP9QuantizeTest,
|
||||
::testing::Values(make_tuple(&vpx_quantize_b_neon, &vpx_quantize_b_c,
|
||||
VPX_BITS_8, 16, false),
|
||||
make_tuple(&vpx_quantize_b_32x32_neon,
|
||||
&vpx_quantize_b_32x32_c, VPX_BITS_8, 32,
|
||||
false),
|
||||
make_tuple(&QuantFPWrapper<vp9_quantize_fp_neon>,
|
||||
&QuantFPWrapper<vp9_quantize_fp_c>, VPX_BITS_8,
|
||||
16, true),
|
||||
make_tuple(&QuantFPWrapper<vp9_quantize_fp_32x32_neon>,
|
||||
&QuantFPWrapper<vp9_quantize_fp_32x32_c>,
|
||||
VPX_BITS_8, 32, true)));
|
||||
#endif // HAVE_NEON && !CONFIG_VP9_HIGHBITDEPTH
|
||||
|
||||
// Only useful to compare "Speed" test results.
|
||||
INSTANTIATE_TEST_CASE_P(
|
||||
DISABLED_C, VP9QuantizeTest,
|
||||
::testing::Values(
|
||||
make_tuple(&vpx_quantize_b_c, &vpx_quantize_b_c, VPX_BITS_8, 16, false),
|
||||
make_tuple(&vpx_quantize_b_32x32_c, &vpx_quantize_b_32x32_c, VPX_BITS_8,
|
||||
32, false),
|
||||
make_tuple(&QuantFPWrapper<vp9_quantize_fp_c>,
|
||||
&QuantFPWrapper<vp9_quantize_fp_c>, VPX_BITS_8, 16, true),
|
||||
make_tuple(&QuantFPWrapper<quantize_fp_nz_c>,
|
||||
&QuantFPWrapper<quantize_fp_nz_c>, VPX_BITS_8, 16, true),
|
||||
make_tuple(&QuantFPWrapper<quantize_fp_32x32_nz_c>,
|
||||
&QuantFPWrapper<quantize_fp_32x32_nz_c>, VPX_BITS_8, 32,
|
||||
true),
|
||||
make_tuple(&QuantFPWrapper<vp9_quantize_fp_32x32_c>,
|
||||
&QuantFPWrapper<vp9_quantize_fp_32x32_c>, VPX_BITS_8, 32,
|
||||
true)));
|
||||
#endif // CONFIG_VP9_HIGHBITDEPTH
|
||||
} // namespace
|
||||
|
@ -1,215 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2017 The WebM project authors. All Rights Reserved.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license
|
||||
* that can be found in the LICENSE file in the root of the source
|
||||
* tree. An additional intellectual property rights grant can be found
|
||||
* in the file PATENTS. All contributing project authors may
|
||||
* be found in the AUTHORS file in the root of the source tree.
|
||||
*/
|
||||
|
||||
#include <assert.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "third_party/googletest/src/include/gtest/gtest.h"
|
||||
|
||||
#include "./vp9_rtcd.h"
|
||||
#include "./vpx_config.h"
|
||||
#include "./vpx_scale_rtcd.h"
|
||||
#include "test/clear_system_state.h"
|
||||
#include "test/register_state_check.h"
|
||||
#include "test/vpx_scale_test.h"
|
||||
#include "vpx_mem/vpx_mem.h"
|
||||
#include "vpx_ports/vpx_timer.h"
|
||||
#include "vpx_scale/yv12config.h"
|
||||
|
||||
namespace libvpx_test {
|
||||
|
||||
typedef void (*ScaleFrameFunc)(const YV12_BUFFER_CONFIG *src,
|
||||
YV12_BUFFER_CONFIG *dst,
|
||||
INTERP_FILTER filter_type, int phase_scaler);
|
||||
|
||||
class ScaleTest : public VpxScaleBase,
|
||||
public ::testing::TestWithParam<ScaleFrameFunc> {
|
||||
public:
|
||||
virtual ~ScaleTest() {}
|
||||
|
||||
protected:
|
||||
virtual void SetUp() { scale_fn_ = GetParam(); }
|
||||
|
||||
void ReferenceScaleFrame(INTERP_FILTER filter_type, int phase_scaler) {
|
||||
vp9_scale_and_extend_frame_c(&img_, &ref_img_, filter_type, phase_scaler);
|
||||
}
|
||||
|
||||
void ScaleFrame(INTERP_FILTER filter_type, int phase_scaler) {
|
||||
ASM_REGISTER_STATE_CHECK(
|
||||
scale_fn_(&img_, &dst_img_, filter_type, phase_scaler));
|
||||
}
|
||||
|
||||
void RunTest(INTERP_FILTER filter_type) {
|
||||
static const int kNumSizesToTest = 20;
|
||||
static const int kNumScaleFactorsToTest = 4;
|
||||
static const int kSizesToTest[] = {
|
||||
2, 4, 6, 8, 10, 12, 14, 16, 18, 20,
|
||||
22, 24, 26, 28, 30, 32, 34, 68, 128, 134
|
||||
};
|
||||
static const int kScaleFactors[] = { 1, 2, 3, 4 };
|
||||
for (int phase_scaler = 0; phase_scaler < 16; ++phase_scaler) {
|
||||
for (int h = 0; h < kNumSizesToTest; ++h) {
|
||||
const int src_height = kSizesToTest[h];
|
||||
for (int w = 0; w < kNumSizesToTest; ++w) {
|
||||
const int src_width = kSizesToTest[w];
|
||||
for (int sf_up_idx = 0; sf_up_idx < kNumScaleFactorsToTest;
|
||||
++sf_up_idx) {
|
||||
const int sf_up = kScaleFactors[sf_up_idx];
|
||||
for (int sf_down_idx = 0; sf_down_idx < kNumScaleFactorsToTest;
|
||||
++sf_down_idx) {
|
||||
const int sf_down = kScaleFactors[sf_down_idx];
|
||||
const int dst_width = src_width * sf_up / sf_down;
|
||||
const int dst_height = src_height * sf_up / sf_down;
|
||||
if (sf_up == sf_down && sf_up != 1) {
|
||||
continue;
|
||||
}
|
||||
// I420 frame width and height must be even.
|
||||
if (!dst_width || !dst_height || dst_width & 1 ||
|
||||
dst_height & 1) {
|
||||
continue;
|
||||
}
|
||||
// vpx_convolve8_c() has restriction on the step which cannot
|
||||
// exceed 64 (ratio 1 to 4).
|
||||
if (src_width > 4 * dst_width || src_height > 4 * dst_height) {
|
||||
continue;
|
||||
}
|
||||
ASSERT_NO_FATAL_FAILURE(ResetScaleImages(src_width, src_height,
|
||||
dst_width, dst_height));
|
||||
ReferenceScaleFrame(filter_type, phase_scaler);
|
||||
ScaleFrame(filter_type, phase_scaler);
|
||||
if (memcmp(dst_img_.buffer_alloc, ref_img_.buffer_alloc,
|
||||
ref_img_.frame_size)) {
|
||||
printf(
|
||||
"filter_type = %d, phase_scaler = %d, src_width = %4d, "
|
||||
"src_height = %4d, dst_width = %4d, dst_height = %4d, "
|
||||
"scale factor = %d:%d\n",
|
||||
filter_type, phase_scaler, src_width, src_height, dst_width,
|
||||
dst_height, sf_down, sf_up);
|
||||
PrintDiff();
|
||||
}
|
||||
CompareImages(dst_img_);
|
||||
DeallocScaleImages();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void PrintDiffComponent(const uint8_t *const ref, const uint8_t *const opt,
|
||||
const int stride, const int width, const int height,
|
||||
const int plane_idx) const {
|
||||
for (int y = 0; y < height; y++) {
|
||||
for (int x = 0; x < width; x++) {
|
||||
if (ref[y * stride + x] != opt[y * stride + x]) {
|
||||
printf("Plane %d pixel[%d][%d] diff:%6d (ref),%6d (opt)\n", plane_idx,
|
||||
y, x, ref[y * stride + x], opt[y * stride + x]);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void PrintDiff() const {
|
||||
assert(ref_img_.y_stride == dst_img_.y_stride);
|
||||
assert(ref_img_.y_width == dst_img_.y_width);
|
||||
assert(ref_img_.y_height == dst_img_.y_height);
|
||||
assert(ref_img_.uv_stride == dst_img_.uv_stride);
|
||||
assert(ref_img_.uv_width == dst_img_.uv_width);
|
||||
assert(ref_img_.uv_height == dst_img_.uv_height);
|
||||
|
||||
if (memcmp(dst_img_.buffer_alloc, ref_img_.buffer_alloc,
|
||||
ref_img_.frame_size)) {
|
||||
PrintDiffComponent(ref_img_.y_buffer, dst_img_.y_buffer,
|
||||
ref_img_.y_stride, ref_img_.y_width, ref_img_.y_height,
|
||||
0);
|
||||
PrintDiffComponent(ref_img_.u_buffer, dst_img_.u_buffer,
|
||||
ref_img_.uv_stride, ref_img_.uv_width,
|
||||
ref_img_.uv_height, 1);
|
||||
PrintDiffComponent(ref_img_.v_buffer, dst_img_.v_buffer,
|
||||
ref_img_.uv_stride, ref_img_.uv_width,
|
||||
ref_img_.uv_height, 2);
|
||||
}
|
||||
}
|
||||
|
||||
ScaleFrameFunc scale_fn_;
|
||||
};
|
||||
|
||||
TEST_P(ScaleTest, ScaleFrame_EightTap) { RunTest(EIGHTTAP); }
|
||||
TEST_P(ScaleTest, ScaleFrame_EightTapSmooth) { RunTest(EIGHTTAP_SMOOTH); }
|
||||
TEST_P(ScaleTest, ScaleFrame_EightTapSharp) { RunTest(EIGHTTAP_SHARP); }
|
||||
TEST_P(ScaleTest, ScaleFrame_Bilinear) { RunTest(BILINEAR); }
|
||||
|
||||
TEST_P(ScaleTest, DISABLED_Speed) {
|
||||
static const int kCountSpeedTestBlock = 100;
|
||||
static const int kNumScaleFactorsToTest = 4;
|
||||
static const int kScaleFactors[] = { 1, 2, 3, 4 };
|
||||
const int src_width = 1280;
|
||||
const int src_height = 720;
|
||||
for (INTERP_FILTER filter_type = 2; filter_type < 4; ++filter_type) {
|
||||
for (int phase_scaler = 0; phase_scaler < 2; ++phase_scaler) {
|
||||
for (int sf_up_idx = 0; sf_up_idx < kNumScaleFactorsToTest; ++sf_up_idx) {
|
||||
const int sf_up = kScaleFactors[sf_up_idx];
|
||||
for (int sf_down_idx = 0; sf_down_idx < kNumScaleFactorsToTest;
|
||||
++sf_down_idx) {
|
||||
const int sf_down = kScaleFactors[sf_down_idx];
|
||||
const int dst_width = src_width * sf_up / sf_down;
|
||||
const int dst_height = src_height * sf_up / sf_down;
|
||||
if (sf_up == sf_down && sf_up != 1) {
|
||||
continue;
|
||||
}
|
||||
// I420 frame width and height must be even.
|
||||
if (dst_width & 1 || dst_height & 1) {
|
||||
continue;
|
||||
}
|
||||
ASSERT_NO_FATAL_FAILURE(
|
||||
ResetScaleImages(src_width, src_height, dst_width, dst_height));
|
||||
ASM_REGISTER_STATE_CHECK(
|
||||
ReferenceScaleFrame(filter_type, phase_scaler));
|
||||
|
||||
vpx_usec_timer timer;
|
||||
vpx_usec_timer_start(&timer);
|
||||
for (int i = 0; i < kCountSpeedTestBlock; ++i) {
|
||||
ScaleFrame(filter_type, phase_scaler);
|
||||
}
|
||||
libvpx_test::ClearSystemState();
|
||||
vpx_usec_timer_mark(&timer);
|
||||
const int elapsed_time =
|
||||
static_cast<int>(vpx_usec_timer_elapsed(&timer) / 1000);
|
||||
CompareImages(dst_img_);
|
||||
DeallocScaleImages();
|
||||
|
||||
printf(
|
||||
"filter_type = %d, phase_scaler = %d, src_width = %4d, "
|
||||
"src_height = %4d, dst_width = %4d, dst_height = %4d, "
|
||||
"scale factor = %d:%d, scale time: %5d ms\n",
|
||||
filter_type, phase_scaler, src_width, src_height, dst_width,
|
||||
dst_height, sf_down, sf_up, elapsed_time);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
INSTANTIATE_TEST_CASE_P(C, ScaleTest,
|
||||
::testing::Values(vp9_scale_and_extend_frame_c));
|
||||
|
||||
#if HAVE_SSSE3
|
||||
INSTANTIATE_TEST_CASE_P(SSSE3, ScaleTest,
|
||||
::testing::Values(vp9_scale_and_extend_frame_ssse3));
|
||||
#endif // HAVE_SSSE3
|
||||
|
||||
#if HAVE_NEON
|
||||
INSTANTIATE_TEST_CASE_P(NEON, ScaleTest,
|
||||
::testing::Values(vp9_scale_and_extend_frame_neon));
|
||||
#endif // HAVE_NEON
|
||||
|
||||
} // namespace libvpx_test
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user