update libvpx to hash 133f83e2c tag v1.7.0 from https://chromium.googlesource.com/webm/libvpx
This commit is contained in:
parent
9bfd5255b2
commit
731ee28fe7
|
@ -3,11 +3,13 @@
|
||||||
|
|
||||||
Aaron Watry <awatry@gmail.com>
|
Aaron Watry <awatry@gmail.com>
|
||||||
Abo Talib Mahfoodh <ab.mahfoodh@gmail.com>
|
Abo Talib Mahfoodh <ab.mahfoodh@gmail.com>
|
||||||
Adam Xu <adam@xuyaowu.com>
|
|
||||||
Adrian Grange <agrange@google.com>
|
Adrian Grange <agrange@google.com>
|
||||||
Aℓex Converse <aconverse@google.com>
|
Aℓex Converse <aconverse@google.com>
|
||||||
Ahmad Sharif <asharif@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>
|
Alexander Voronov <avoronov@graphics.cs.msu.ru>
|
||||||
|
Alexandra Hájková <alexandra.khirnova@gmail.com>
|
||||||
Alexis Ballier <aballier@gentoo.org>
|
Alexis Ballier <aballier@gentoo.org>
|
||||||
Alok Ahuja <waveletcoeff@gmail.com>
|
Alok Ahuja <waveletcoeff@gmail.com>
|
||||||
Alpha Lam <hclam@google.com>
|
Alpha Lam <hclam@google.com>
|
||||||
|
@ -15,6 +17,7 @@ A.Mahfoodh <ab.mahfoodh@gmail.com>
|
||||||
Ami Fischman <fischman@chromium.org>
|
Ami Fischman <fischman@chromium.org>
|
||||||
Andoni Morales Alastruey <ylatuya@gmail.com>
|
Andoni Morales Alastruey <ylatuya@gmail.com>
|
||||||
Andres Mejia <mcitadel@gmail.com>
|
Andres Mejia <mcitadel@gmail.com>
|
||||||
|
Andrew Lewis <andrewlewis@google.com>
|
||||||
Andrew Russell <anrussell@google.com>
|
Andrew Russell <anrussell@google.com>
|
||||||
Angie Chiang <angiebird@google.com>
|
Angie Chiang <angiebird@google.com>
|
||||||
Aron Rosenberg <arosenberg@logitech.com>
|
Aron Rosenberg <arosenberg@logitech.com>
|
||||||
|
@ -22,11 +25,14 @@ Attila Nagy <attilanagy@google.com>
|
||||||
Brion Vibber <bvibber@wikimedia.org>
|
Brion Vibber <bvibber@wikimedia.org>
|
||||||
changjun.yang <changjun.yang@intel.com>
|
changjun.yang <changjun.yang@intel.com>
|
||||||
Charles 'Buck' Krasic <ckrasic@google.com>
|
Charles 'Buck' Krasic <ckrasic@google.com>
|
||||||
|
Cheng Chen <chengchen@google.com>
|
||||||
chm <chm@rock-chips.com>
|
chm <chm@rock-chips.com>
|
||||||
|
Chris Cunningham <chcunningham@chromium.org>
|
||||||
Christian Duvivier <cduvivier@google.com>
|
Christian Duvivier <cduvivier@google.com>
|
||||||
Daniele Castagna <dcastagna@chromium.org>
|
Daniele Castagna <dcastagna@chromium.org>
|
||||||
Daniel Kang <ddkang@google.com>
|
Daniel Kang <ddkang@google.com>
|
||||||
Deb Mukherjee <debargha@google.com>
|
Deb Mukherjee <debargha@google.com>
|
||||||
|
Deepa K G <deepa.kg@ittiam.com>
|
||||||
Dim Temp <dimtemp0@gmail.com>
|
Dim Temp <dimtemp0@gmail.com>
|
||||||
Dmitry Kovalev <dkovalev@google.com>
|
Dmitry Kovalev <dkovalev@google.com>
|
||||||
Dragan Mrdjan <dmrdjan@mips.com>
|
Dragan Mrdjan <dmrdjan@mips.com>
|
||||||
|
@ -37,17 +43,21 @@ Fabio Pedretti <fabio.ped@libero.it>
|
||||||
Frank Galligan <fgalligan@google.com>
|
Frank Galligan <fgalligan@google.com>
|
||||||
Fredrik Söderquist <fs@opera.com>
|
Fredrik Söderquist <fs@opera.com>
|
||||||
Fritz Koenig <frkoenig@google.com>
|
Fritz Koenig <frkoenig@google.com>
|
||||||
|
Gabriel Marin <gmx@chromium.org>
|
||||||
Gaute Strokkenes <gaute.strokkenes@broadcom.com>
|
Gaute Strokkenes <gaute.strokkenes@broadcom.com>
|
||||||
Geza Lore <gezalore@gmail.com>
|
Geza Lore <gezalore@gmail.com>
|
||||||
Ghislain MARY <ghislainmary2@gmail.com>
|
Ghislain MARY <ghislainmary2@gmail.com>
|
||||||
Giuseppe Scrivano <gscrivano@gnu.org>
|
Giuseppe Scrivano <gscrivano@gnu.org>
|
||||||
Gordana Cmiljanovic <gordana.cmiljanovic@imgtec.com>
|
Gordana Cmiljanovic <gordana.cmiljanovic@imgtec.com>
|
||||||
|
Gregor Jasny <gjasny@gmail.com>
|
||||||
Guillaume Martres <gmartres@google.com>
|
Guillaume Martres <gmartres@google.com>
|
||||||
Guillermo Ballester Valor <gbvalor@gmail.com>
|
Guillermo Ballester Valor <gbvalor@gmail.com>
|
||||||
Hangyu Kuang <hkuang@google.com>
|
Hangyu Kuang <hkuang@google.com>
|
||||||
Hanno Böck <hanno@hboeck.de>
|
Hanno Böck <hanno@hboeck.de>
|
||||||
|
Han Shen <shenhan@google.com>
|
||||||
Henrik Lundin <hlundin@google.com>
|
Henrik Lundin <hlundin@google.com>
|
||||||
Hui Su <huisu@google.com>
|
Hui Su <huisu@google.com>
|
||||||
|
Ivan Krasin <krasin@chromium.org>
|
||||||
Ivan Maltz <ivanmaltz@google.com>
|
Ivan Maltz <ivanmaltz@google.com>
|
||||||
Jacek Caban <cjacek@gmail.com>
|
Jacek Caban <cjacek@gmail.com>
|
||||||
Jacky Chen <jackychen@google.com>
|
Jacky Chen <jackychen@google.com>
|
||||||
|
@ -61,6 +71,7 @@ Jean-Yves Avenard <jyavenard@mozilla.com>
|
||||||
Jeff Faust <jfaust@google.com>
|
Jeff Faust <jfaust@google.com>
|
||||||
Jeff Muizelaar <jmuizelaar@mozilla.com>
|
Jeff Muizelaar <jmuizelaar@mozilla.com>
|
||||||
Jeff Petkau <jpet@chromium.org>
|
Jeff Petkau <jpet@chromium.org>
|
||||||
|
Jerome Jiang <jianj@google.com>
|
||||||
Jia Jia <jia.jia@linaro.org>
|
Jia Jia <jia.jia@linaro.org>
|
||||||
Jian Zhou <zhoujian@google.com>
|
Jian Zhou <zhoujian@google.com>
|
||||||
Jim Bankoski <jimbankoski@google.com>
|
Jim Bankoski <jimbankoski@google.com>
|
||||||
|
@ -75,7 +86,9 @@ Joshua Litt <joshualitt@google.com>
|
||||||
Julia Robson <juliamrobson@gmail.com>
|
Julia Robson <juliamrobson@gmail.com>
|
||||||
Justin Clift <justin@salasaga.org>
|
Justin Clift <justin@salasaga.org>
|
||||||
Justin Lebar <justin.lebar@gmail.com>
|
Justin Lebar <justin.lebar@gmail.com>
|
||||||
|
Kaustubh Raste <kaustubh.raste@imgtec.com>
|
||||||
KO Myung-Hun <komh@chollian.net>
|
KO Myung-Hun <komh@chollian.net>
|
||||||
|
Kyle Siefring <kylesiefring@gmail.com>
|
||||||
Lawrence Velázquez <larryv@macports.org>
|
Lawrence Velázquez <larryv@macports.org>
|
||||||
Linfeng Zhang <linfengz@google.com>
|
Linfeng Zhang <linfengz@google.com>
|
||||||
Lou Quillio <louquillio@google.com>
|
Lou Quillio <louquillio@google.com>
|
||||||
|
@ -91,8 +104,12 @@ Michael Kohler <michaelkohler@live.com>
|
||||||
Mike Frysinger <vapier@chromium.org>
|
Mike Frysinger <vapier@chromium.org>
|
||||||
Mike Hommey <mhommey@mozilla.com>
|
Mike Hommey <mhommey@mozilla.com>
|
||||||
Mikhal Shemer <mikhal@google.com>
|
Mikhal Shemer <mikhal@google.com>
|
||||||
|
Min Chen <chenm003@gmail.com>
|
||||||
Minghai Shang <minghai@google.com>
|
Minghai Shang <minghai@google.com>
|
||||||
|
Min Ye <yeemmi@google.com>
|
||||||
|
Moriyoshi Koizumi <mozo@mozo.jp>
|
||||||
Morton Jonuschat <yabawock@gmail.com>
|
Morton Jonuschat <yabawock@gmail.com>
|
||||||
|
Nathan E. Egge <negge@mozilla.com>
|
||||||
Nico Weber <thakis@chromium.org>
|
Nico Weber <thakis@chromium.org>
|
||||||
Parag Salasakar <img.mips1@gmail.com>
|
Parag Salasakar <img.mips1@gmail.com>
|
||||||
Pascal Massimino <pascal.massimino@gmail.com>
|
Pascal Massimino <pascal.massimino@gmail.com>
|
||||||
|
@ -101,16 +118,22 @@ Paul Wilkins <paulwilkins@google.com>
|
||||||
Pavol Rusnak <stick@gk2.sk>
|
Pavol Rusnak <stick@gk2.sk>
|
||||||
Paweł Hajdan <phajdan@google.com>
|
Paweł Hajdan <phajdan@google.com>
|
||||||
Pengchong Jin <pengchong@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>
|
Peter de Rivaz <peter.derivaz@gmail.com>
|
||||||
Philip Jägenstedt <philipj@opera.com>
|
Philip Jägenstedt <philipj@opera.com>
|
||||||
Priit Laes <plaes@plaes.org>
|
Priit Laes <plaes@plaes.org>
|
||||||
Rafael Ávila de Espíndola <rafael.espindola@gmail.com>
|
Rafael Ávila de Espíndola <rafael.espindola@gmail.com>
|
||||||
Rafaël Carré <funman@videolan.org>
|
Rafaël Carré <funman@videolan.org>
|
||||||
|
Rafael de Lucena Valle <rafaeldelucena@gmail.com>
|
||||||
|
Rahul Chaudhry <rahulchaudhry@google.com>
|
||||||
Ralph Giles <giles@xiph.org>
|
Ralph Giles <giles@xiph.org>
|
||||||
|
Ranjit Kumar Tulabandu <ranjit.tulabandu@ittiam.com>
|
||||||
Rob Bradford <rob@linux.intel.com>
|
Rob Bradford <rob@linux.intel.com>
|
||||||
Ronald S. Bultje <rsbultje@gmail.com>
|
Ronald S. Bultje <rsbultje@gmail.com>
|
||||||
Rui Ueyama <ruiu@google.com>
|
Rui Ueyama <ruiu@google.com>
|
||||||
Sami Pietilä <samipietila@google.com>
|
Sami Pietilä <samipietila@google.com>
|
||||||
|
Sarah Parker <sarahparker@google.com>
|
||||||
Sasi Inguva <isasi@google.com>
|
Sasi Inguva <isasi@google.com>
|
||||||
Scott Graham <scottmg@chromium.org>
|
Scott Graham <scottmg@chromium.org>
|
||||||
Scott LaVarnway <slavarnway@google.com>
|
Scott LaVarnway <slavarnway@google.com>
|
||||||
|
@ -118,9 +141,11 @@ Sean McGovern <gseanmcg@gmail.com>
|
||||||
Sergey Kolomenkin <kolomenkin@gmail.com>
|
Sergey Kolomenkin <kolomenkin@gmail.com>
|
||||||
Sergey Ulanov <sergeyu@chromium.org>
|
Sergey Ulanov <sergeyu@chromium.org>
|
||||||
Shimon Doodkin <helpmepro1@gmail.com>
|
Shimon Doodkin <helpmepro1@gmail.com>
|
||||||
|
Shiyou Yin <yinshiyou-hf@loongson.cn>
|
||||||
Shunyao Li <shunyaoli@google.com>
|
Shunyao Li <shunyaoli@google.com>
|
||||||
Stefan Holmer <holmer@google.com>
|
Stefan Holmer <holmer@google.com>
|
||||||
Suman Sunkara <sunkaras@google.com>
|
Suman Sunkara <sunkaras@google.com>
|
||||||
|
Sylvestre Ledru <sylvestre@mozilla.com>
|
||||||
Taekhyun Kim <takim@nvidia.com>
|
Taekhyun Kim <takim@nvidia.com>
|
||||||
Takanori MATSUURA <t.matsuu@gmail.com>
|
Takanori MATSUURA <t.matsuu@gmail.com>
|
||||||
Tamar Levy <tamar.levy@intel.com>
|
Tamar Levy <tamar.levy@intel.com>
|
||||||
|
@ -130,7 +155,10 @@ Thijs Vermeir <thijsvermeir@gmail.com>
|
||||||
Tim Kopp <tkopp@google.com>
|
Tim Kopp <tkopp@google.com>
|
||||||
Timothy B. Terriberry <tterribe@xiph.org>
|
Timothy B. Terriberry <tterribe@xiph.org>
|
||||||
Tom Finegan <tomfinegan@google.com>
|
Tom Finegan <tomfinegan@google.com>
|
||||||
|
Tristan Matthews <le.businessman@gmail.com>
|
||||||
|
Urvang Joshi <urvang@google.com>
|
||||||
Vignesh Venkatasubramanian <vigneshv@google.com>
|
Vignesh Venkatasubramanian <vigneshv@google.com>
|
||||||
|
Vlad Tsyrklevich <vtsyrklevich@chromium.org>
|
||||||
Yaowu Xu <yaowu@google.com>
|
Yaowu Xu <yaowu@google.com>
|
||||||
Yi Luo <luoyi@google.com>
|
Yi Luo <luoyi@google.com>
|
||||||
Yongzhe Wang <yongzhe@google.com>
|
Yongzhe Wang <yongzhe@google.com>
|
||||||
|
|
|
@ -1,3 +1,44 @@
|
||||||
|
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"
|
2016-07-20 v1.6.0 "Khaki Campbell Duck"
|
||||||
This release improves upon the VP9 encoder and speeds up the encoding and
|
This release improves upon the VP9 encoder and speeds up the encoding and
|
||||||
decoding processes.
|
decoding processes.
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
README - 20 July 2016
|
README - 24 January 2018
|
||||||
|
|
||||||
Welcome to the WebM VP8/VP9 Codec SDK!
|
Welcome to the WebM VP8/VP9 Codec SDK!
|
||||||
|
|
||||||
|
@ -47,6 +47,7 @@ COMPILING THE APPLICATIONS/LIBRARIES:
|
||||||
--help output of the configure script. As of this writing, the list of
|
--help output of the configure script. As of this writing, the list of
|
||||||
available targets is:
|
available targets is:
|
||||||
|
|
||||||
|
arm64-android-gcc
|
||||||
arm64-darwin-gcc
|
arm64-darwin-gcc
|
||||||
arm64-linux-gcc
|
arm64-linux-gcc
|
||||||
armv7-android-gcc
|
armv7-android-gcc
|
||||||
|
@ -57,10 +58,13 @@ COMPILING THE APPLICATIONS/LIBRARIES:
|
||||||
armv7-win32-vs11
|
armv7-win32-vs11
|
||||||
armv7-win32-vs12
|
armv7-win32-vs12
|
||||||
armv7-win32-vs14
|
armv7-win32-vs14
|
||||||
|
armv7-win32-vs15
|
||||||
armv7s-darwin-gcc
|
armv7s-darwin-gcc
|
||||||
armv8-linux-gcc
|
armv8-linux-gcc
|
||||||
mips32-linux-gcc
|
mips32-linux-gcc
|
||||||
mips64-linux-gcc
|
mips64-linux-gcc
|
||||||
|
ppc64-linux-gcc
|
||||||
|
ppc64le-linux-gcc
|
||||||
sparc-solaris-gcc
|
sparc-solaris-gcc
|
||||||
x86-android-gcc
|
x86-android-gcc
|
||||||
x86-darwin8-gcc
|
x86-darwin8-gcc
|
||||||
|
@ -73,6 +77,7 @@ COMPILING THE APPLICATIONS/LIBRARIES:
|
||||||
x86-darwin13-gcc
|
x86-darwin13-gcc
|
||||||
x86-darwin14-gcc
|
x86-darwin14-gcc
|
||||||
x86-darwin15-gcc
|
x86-darwin15-gcc
|
||||||
|
x86-darwin16-gcc
|
||||||
x86-iphonesimulator-gcc
|
x86-iphonesimulator-gcc
|
||||||
x86-linux-gcc
|
x86-linux-gcc
|
||||||
x86-linux-icc
|
x86-linux-icc
|
||||||
|
@ -83,6 +88,7 @@ COMPILING THE APPLICATIONS/LIBRARIES:
|
||||||
x86-win32-vs11
|
x86-win32-vs11
|
||||||
x86-win32-vs12
|
x86-win32-vs12
|
||||||
x86-win32-vs14
|
x86-win32-vs14
|
||||||
|
x86-win32-vs15
|
||||||
x86_64-android-gcc
|
x86_64-android-gcc
|
||||||
x86_64-darwin9-gcc
|
x86_64-darwin9-gcc
|
||||||
x86_64-darwin10-gcc
|
x86_64-darwin10-gcc
|
||||||
|
@ -91,6 +97,7 @@ COMPILING THE APPLICATIONS/LIBRARIES:
|
||||||
x86_64-darwin13-gcc
|
x86_64-darwin13-gcc
|
||||||
x86_64-darwin14-gcc
|
x86_64-darwin14-gcc
|
||||||
x86_64-darwin15-gcc
|
x86_64-darwin15-gcc
|
||||||
|
x86_64-darwin16-gcc
|
||||||
x86_64-iphonesimulator-gcc
|
x86_64-iphonesimulator-gcc
|
||||||
x86_64-linux-gcc
|
x86_64-linux-gcc
|
||||||
x86_64-linux-icc
|
x86_64-linux-icc
|
||||||
|
@ -100,6 +107,7 @@ COMPILING THE APPLICATIONS/LIBRARIES:
|
||||||
x86_64-win64-vs11
|
x86_64-win64-vs11
|
||||||
x86_64-win64-vs12
|
x86_64-win64-vs12
|
||||||
x86_64-win64-vs14
|
x86_64-win64-vs14
|
||||||
|
x86_64-win64-vs15
|
||||||
generic-gnu
|
generic-gnu
|
||||||
|
|
||||||
The generic-gnu target, in conjunction with the CROSS environment variable,
|
The generic-gnu target, in conjunction with the CROSS environment variable,
|
||||||
|
|
|
@ -13,6 +13,7 @@
|
||||||
#include <limits.h>
|
#include <limits.h>
|
||||||
#include "args.h"
|
#include "args.h"
|
||||||
|
|
||||||
|
#include "vpx/vpx_integer.h"
|
||||||
#include "vpx_ports/msvc.h"
|
#include "vpx_ports/msvc.h"
|
||||||
|
|
||||||
#if defined(__GNUC__) && __GNUC__
|
#if defined(__GNUC__) && __GNUC__
|
||||||
|
@ -118,13 +119,13 @@ void arg_show_usage(FILE *fp, const struct arg_def *const *defs) {
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned int arg_parse_uint(const struct arg *arg) {
|
unsigned int arg_parse_uint(const struct arg *arg) {
|
||||||
long int rawval;
|
uint32_t rawval;
|
||||||
char *endptr;
|
char *endptr;
|
||||||
|
|
||||||
rawval = strtol(arg->val, &endptr, 10);
|
rawval = (uint32_t)strtoul(arg->val, &endptr, 10);
|
||||||
|
|
||||||
if (arg->val[0] != '\0' && endptr[0] == '\0') {
|
if (arg->val[0] != '\0' && endptr[0] == '\0') {
|
||||||
if (rawval >= 0 && rawval <= UINT_MAX) return (unsigned int)rawval;
|
if (rawval <= UINT_MAX) return rawval;
|
||||||
|
|
||||||
die("Option %s: Value %ld out of range for unsigned int\n", arg->name,
|
die("Option %s: Value %ld out of range for unsigned int\n", arg->name,
|
||||||
rawval);
|
rawval);
|
||||||
|
@ -135,10 +136,10 @@ unsigned int arg_parse_uint(const struct arg *arg) {
|
||||||
}
|
}
|
||||||
|
|
||||||
int arg_parse_int(const struct arg *arg) {
|
int arg_parse_int(const struct arg *arg) {
|
||||||
long int rawval;
|
int32_t rawval;
|
||||||
char *endptr;
|
char *endptr;
|
||||||
|
|
||||||
rawval = strtol(arg->val, &endptr, 10);
|
rawval = (int32_t)strtol(arg->val, &endptr, 10);
|
||||||
|
|
||||||
if (arg->val[0] != '\0' && endptr[0] == '\0') {
|
if (arg->val[0] != '\0' && endptr[0] == '\0') {
|
||||||
if (rawval >= INT_MIN && rawval <= INT_MAX) return (int)rawval;
|
if (rawval >= INT_MIN && rawval <= INT_MAX) return (int)rawval;
|
||||||
|
|
|
@ -64,6 +64,9 @@ CONFIG_DIR := $(LOCAL_PATH)/
|
||||||
LIBVPX_PATH := $(LOCAL_PATH)/libvpx
|
LIBVPX_PATH := $(LOCAL_PATH)/libvpx
|
||||||
ASM_CNV_PATH_LOCAL := $(TARGET_ARCH_ABI)/ads2gas
|
ASM_CNV_PATH_LOCAL := $(TARGET_ARCH_ABI)/ads2gas
|
||||||
ASM_CNV_PATH := $(LOCAL_PATH)/$(ASM_CNV_PATH_LOCAL)
|
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
|
# Use the makefiles generated by upstream configure to determine which files to
|
||||||
# build. Also set any architecture-specific flags.
|
# build. Also set any architecture-specific flags.
|
||||||
|
@ -71,7 +74,7 @@ ifeq ($(TARGET_ARCH_ABI),armeabi-v7a)
|
||||||
include $(CONFIG_DIR)libs-armv7-android-gcc.mk
|
include $(CONFIG_DIR)libs-armv7-android-gcc.mk
|
||||||
LOCAL_ARM_MODE := arm
|
LOCAL_ARM_MODE := arm
|
||||||
else ifeq ($(TARGET_ARCH_ABI),arm64-v8a)
|
else ifeq ($(TARGET_ARCH_ABI),arm64-v8a)
|
||||||
include $(CONFIG_DIR)libs-armv8-android-gcc.mk
|
include $(CONFIG_DIR)libs-arm64-android-gcc.mk
|
||||||
LOCAL_ARM_MODE := arm
|
LOCAL_ARM_MODE := arm
|
||||||
else ifeq ($(TARGET_ARCH_ABI),x86)
|
else ifeq ($(TARGET_ARCH_ABI),x86)
|
||||||
include $(CONFIG_DIR)libs-x86-android-gcc.mk
|
include $(CONFIG_DIR)libs-x86-android-gcc.mk
|
||||||
|
@ -101,10 +104,10 @@ LOCAL_CFLAGS := -O3
|
||||||
# like x86inc.asm and x86_abi_support.asm
|
# like x86inc.asm and x86_abi_support.asm
|
||||||
LOCAL_ASMFLAGS := -I$(LIBVPX_PATH)
|
LOCAL_ASMFLAGS := -I$(LIBVPX_PATH)
|
||||||
|
|
||||||
.PRECIOUS: %.asm.s
|
.PRECIOUS: %.asm.S
|
||||||
$(ASM_CNV_PATH)/libvpx/%.asm.s: $(LIBVPX_PATH)/%.asm
|
$(ASM_CNV_PATH)/libvpx/%.asm.S: $(LIBVPX_PATH)/%.asm
|
||||||
@mkdir -p $(dir $@)
|
$(qexec)mkdir -p $(dir $@)
|
||||||
@$(CONFIG_DIR)$(ASM_CONVERSION) <$< > $@
|
$(qexec)$(CONFIG_DIR)$(ASM_CONVERSION) <$< > $@
|
||||||
|
|
||||||
# For building *_rtcd.h, which have rules in libs.mk
|
# For building *_rtcd.h, which have rules in libs.mk
|
||||||
TGT_ISA:=$(word 1, $(subst -, ,$(TOOLCHAIN)))
|
TGT_ISA:=$(word 1, $(subst -, ,$(TOOLCHAIN)))
|
||||||
|
@ -132,7 +135,7 @@ endif
|
||||||
|
|
||||||
# Pull out assembly files, splitting NEON from the rest. This is
|
# Pull out assembly files, splitting NEON from the rest. This is
|
||||||
# done to specify that the NEON assembly files use NEON assembler flags.
|
# done to specify that the NEON assembly files use NEON assembler flags.
|
||||||
# x86 assembly matches %.asm, arm matches %.asm.s
|
# x86 assembly matches %.asm, arm matches %.asm.S
|
||||||
|
|
||||||
# x86:
|
# x86:
|
||||||
|
|
||||||
|
@ -140,31 +143,44 @@ CODEC_SRCS_ASM_X86 = $(filter %.asm, $(CODEC_SRCS_UNIQUE))
|
||||||
LOCAL_SRC_FILES += $(foreach file, $(CODEC_SRCS_ASM_X86), libvpx/$(file))
|
LOCAL_SRC_FILES += $(foreach file, $(CODEC_SRCS_ASM_X86), libvpx/$(file))
|
||||||
|
|
||||||
# arm:
|
# arm:
|
||||||
CODEC_SRCS_ASM_ARM_ALL = $(filter %.asm.s, $(CODEC_SRCS_UNIQUE))
|
CODEC_SRCS_ASM_ARM_ALL = $(filter %.asm.S, $(CODEC_SRCS_UNIQUE))
|
||||||
CODEC_SRCS_ASM_ARM = $(foreach v, \
|
CODEC_SRCS_ASM_ARM = $(foreach v, \
|
||||||
$(CODEC_SRCS_ASM_ARM_ALL), \
|
$(CODEC_SRCS_ASM_ARM_ALL), \
|
||||||
$(if $(findstring neon,$(v)),,$(v)))
|
$(if $(findstring neon,$(v)),,$(v)))
|
||||||
CODEC_SRCS_ASM_ADS2GAS = $(patsubst %.s, \
|
CODEC_SRCS_ASM_ADS2GAS = $(patsubst %.S, \
|
||||||
$(ASM_CNV_PATH_LOCAL)/libvpx/%.s, \
|
$(ASM_CNV_PATH_LOCAL)/libvpx/%.S, \
|
||||||
$(CODEC_SRCS_ASM_ARM))
|
$(CODEC_SRCS_ASM_ARM))
|
||||||
LOCAL_SRC_FILES += $(CODEC_SRCS_ASM_ADS2GAS)
|
LOCAL_SRC_FILES += $(CODEC_SRCS_ASM_ADS2GAS)
|
||||||
|
|
||||||
ifeq ($(TARGET_ARCH_ABI),armeabi-v7a)
|
ifeq ($(TARGET_ARCH_ABI),armeabi-v7a)
|
||||||
|
ASM_INCLUDES := vpx_dsp/arm/idct_neon.asm.S
|
||||||
CODEC_SRCS_ASM_NEON = $(foreach v, \
|
CODEC_SRCS_ASM_NEON = $(foreach v, \
|
||||||
$(CODEC_SRCS_ASM_ARM_ALL),\
|
$(CODEC_SRCS_ASM_ARM_ALL),\
|
||||||
$(if $(findstring neon,$(v)),$(v),))
|
$(if $(findstring neon,$(v)),$(v),))
|
||||||
CODEC_SRCS_ASM_NEON_ADS2GAS = $(patsubst %.s, \
|
CODEC_SRCS_ASM_NEON := $(filter-out $(addprefix %, $(ASM_INCLUDES)), \
|
||||||
$(ASM_CNV_PATH_LOCAL)/libvpx/%.s, \
|
$(CODEC_SRCS_ASM_NEON))
|
||||||
|
CODEC_SRCS_ASM_NEON_ADS2GAS = $(patsubst %.S, \
|
||||||
|
$(ASM_CNV_PATH_LOCAL)/libvpx/%.S, \
|
||||||
$(CODEC_SRCS_ASM_NEON))
|
$(CODEC_SRCS_ASM_NEON))
|
||||||
LOCAL_SRC_FILES += $(patsubst %.s, \
|
LOCAL_SRC_FILES += $(patsubst %.S, \
|
||||||
%.s.neon, \
|
%.S.neon, \
|
||||||
$(CODEC_SRCS_ASM_NEON_ADS2GAS))
|
$(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
|
endif
|
||||||
|
|
||||||
LOCAL_CFLAGS += \
|
LOCAL_CFLAGS += \
|
||||||
-DHAVE_CONFIG_H=vpx_config.h \
|
-DHAVE_CONFIG_H=vpx_config.h \
|
||||||
-I$(LIBVPX_PATH) \
|
-I$(LIBVPX_PATH) \
|
||||||
-I$(ASM_CNV_PATH)
|
-I$(ASM_CNV_PATH) \
|
||||||
|
-I$(ASM_CNV_PATH)/libvpx
|
||||||
|
|
||||||
LOCAL_MODULE := libvpx
|
LOCAL_MODULE := libvpx
|
||||||
|
|
||||||
|
@ -185,7 +201,8 @@ endif
|
||||||
$$(rtcd_dep_template_SRCS): vpx_scale_rtcd.h
|
$$(rtcd_dep_template_SRCS): vpx_scale_rtcd.h
|
||||||
$$(rtcd_dep_template_SRCS): vpx_dsp_rtcd.h
|
$$(rtcd_dep_template_SRCS): vpx_dsp_rtcd.h
|
||||||
|
|
||||||
ifneq ($(findstring $(TARGET_ARCH_ABI),x86 x86_64),)
|
rtcd_dep_template_CONFIG_ASM_ABIS := x86 x86_64 armeabi-v7a
|
||||||
|
ifneq ($$(findstring $(TARGET_ARCH_ABI),$$(rtcd_dep_template_CONFIG_ASM_ABIS)),)
|
||||||
$$(rtcd_dep_template_SRCS): vpx_config.asm
|
$$(rtcd_dep_template_SRCS): vpx_config.asm
|
||||||
endif
|
endif
|
||||||
endef
|
endef
|
||||||
|
@ -195,16 +212,17 @@ $(eval $(call rtcd_dep_template))
|
||||||
.PHONY: clean
|
.PHONY: clean
|
||||||
clean:
|
clean:
|
||||||
@echo "Clean: ads2gas files [$(TARGET_ARCH_ABI)]"
|
@echo "Clean: ads2gas files [$(TARGET_ARCH_ABI)]"
|
||||||
@$(RM) $(CODEC_SRCS_ASM_ADS2GAS) $(CODEC_SRCS_ASM_NEON_ADS2GAS)
|
$(qexec)$(RM) $(CODEC_SRCS_ASM_ADS2GAS) $(CODEC_SRCS_ASM_NEON_ADS2GAS)
|
||||||
@$(RM) -r $(ASM_CNV_PATH)
|
$(qexec)$(RM) -r $(ASM_CNV_PATH)
|
||||||
@$(RM) $(CLEAN-OBJS)
|
$(qexec)$(RM) $(CLEAN-OBJS)
|
||||||
|
|
||||||
ifeq ($(ENABLE_SHARED),1)
|
ifeq ($(ENABLE_SHARED),1)
|
||||||
|
LOCAL_CFLAGS += -fPIC
|
||||||
include $(BUILD_SHARED_LIBRARY)
|
include $(BUILD_SHARED_LIBRARY)
|
||||||
else
|
else
|
||||||
include $(BUILD_STATIC_LIBRARY)
|
include $(BUILD_STATIC_LIBRARY)
|
||||||
endif
|
endif
|
||||||
|
|
||||||
ifeq ($(CONFIG_RUNTIME_CPU_DETECT),yes)
|
ifeq ($(CONFIG_RUNTIME_CPU_DETECT),yes)
|
||||||
$(call import-module,cpufeatures)
|
$(call import-module,android/cpufeatures)
|
||||||
endif
|
endif
|
||||||
|
|
|
@ -90,7 +90,7 @@ all:
|
||||||
|
|
||||||
.PHONY: clean
|
.PHONY: clean
|
||||||
clean::
|
clean::
|
||||||
rm -f $(OBJS-yes) $(OBJS-yes:.o=.d) $(OBJS-yes:.asm.s.o=.asm.s)
|
rm -f $(OBJS-yes) $(OBJS-yes:.o=.d) $(OBJS-yes:.asm.S.o=.asm.S)
|
||||||
rm -f $(CLEAN-OBJS)
|
rm -f $(CLEAN-OBJS)
|
||||||
|
|
||||||
.PHONY: clean
|
.PHONY: clean
|
||||||
|
@ -124,6 +124,7 @@ ifeq ($(TOOLCHAIN), x86-os2-gcc)
|
||||||
CFLAGS += -mstackrealign
|
CFLAGS += -mstackrealign
|
||||||
endif
|
endif
|
||||||
|
|
||||||
|
# x86[_64]
|
||||||
$(BUILD_PFX)%_mmx.c.d: CFLAGS += -mmmx
|
$(BUILD_PFX)%_mmx.c.d: CFLAGS += -mmmx
|
||||||
$(BUILD_PFX)%_mmx.c.o: CFLAGS += -mmmx
|
$(BUILD_PFX)%_mmx.c.o: CFLAGS += -mmmx
|
||||||
$(BUILD_PFX)%_sse2.c.d: CFLAGS += -msse2
|
$(BUILD_PFX)%_sse2.c.d: CFLAGS += -msse2
|
||||||
|
@ -138,6 +139,12 @@ $(BUILD_PFX)%_avx.c.d: CFLAGS += -mavx
|
||||||
$(BUILD_PFX)%_avx.c.o: CFLAGS += -mavx
|
$(BUILD_PFX)%_avx.c.o: CFLAGS += -mavx
|
||||||
$(BUILD_PFX)%_avx2.c.d: CFLAGS += -mavx2
|
$(BUILD_PFX)%_avx2.c.d: CFLAGS += -mavx2
|
||||||
$(BUILD_PFX)%_avx2.c.o: 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
|
$(BUILD_PFX)%.c.d: %.c
|
||||||
$(if $(quiet),@echo " [DEP] $@")
|
$(if $(quiet),@echo " [DEP] $@")
|
||||||
|
@ -180,13 +187,13 @@ $(BUILD_PFX)%.asm.o: %.asm
|
||||||
$(qexec)$(if $(CONFIG_DEPENDENCY_TRACKING),,mkdir -p $(dir $@))
|
$(qexec)$(if $(CONFIG_DEPENDENCY_TRACKING),,mkdir -p $(dir $@))
|
||||||
$(qexec)$(AS) $(ASFLAGS) -o $@ $<
|
$(qexec)$(AS) $(ASFLAGS) -o $@ $<
|
||||||
|
|
||||||
$(BUILD_PFX)%.s.d: %.s
|
$(BUILD_PFX)%.S.d: %.S
|
||||||
$(if $(quiet),@echo " [DEP] $@")
|
$(if $(quiet),@echo " [DEP] $@")
|
||||||
$(qexec)mkdir -p $(dir $@)
|
$(qexec)mkdir -p $(dir $@)
|
||||||
$(qexec)$(SRC_PATH_BARE)/build/make/gen_asm_deps.sh \
|
$(qexec)$(SRC_PATH_BARE)/build/make/gen_asm_deps.sh \
|
||||||
--build-pfx=$(BUILD_PFX) --depfile=$@ $(ASFLAGS) $< > $@
|
--build-pfx=$(BUILD_PFX) --depfile=$@ $(ASFLAGS) $< > $@
|
||||||
|
|
||||||
$(BUILD_PFX)%.s.o: %.s
|
$(BUILD_PFX)%.S.o: %.S
|
||||||
$(if $(quiet),@echo " [AS] $@")
|
$(if $(quiet),@echo " [AS] $@")
|
||||||
$(qexec)$(if $(CONFIG_DEPENDENCY_TRACKING),,mkdir -p $(dir $@))
|
$(qexec)$(if $(CONFIG_DEPENDENCY_TRACKING),,mkdir -p $(dir $@))
|
||||||
$(qexec)$(AS) $(ASFLAGS) -o $@ $<
|
$(qexec)$(AS) $(ASFLAGS) -o $@ $<
|
||||||
|
@ -198,8 +205,8 @@ $(BUILD_PFX)%.c.S: %.c
|
||||||
$(qexec)$(if $(CONFIG_DEPENDENCY_TRACKING),,mkdir -p $(dir $@))
|
$(qexec)$(if $(CONFIG_DEPENDENCY_TRACKING),,mkdir -p $(dir $@))
|
||||||
$(qexec)$(CC) -S $(CFLAGS) -o $@ $<
|
$(qexec)$(CC) -S $(CFLAGS) -o $@ $<
|
||||||
|
|
||||||
.PRECIOUS: %.asm.s
|
.PRECIOUS: %.asm.S
|
||||||
$(BUILD_PFX)%.asm.s: %.asm
|
$(BUILD_PFX)%.asm.S: %.asm
|
||||||
$(if $(quiet),@echo " [ASM CONVERSION] $@")
|
$(if $(quiet),@echo " [ASM CONVERSION] $@")
|
||||||
$(qexec)mkdir -p $(dir $@)
|
$(qexec)mkdir -p $(dir $@)
|
||||||
$(qexec)$(ASM_CONVERSION) <$< >$@
|
$(qexec)$(ASM_CONVERSION) <$< >$@
|
||||||
|
|
|
@ -138,14 +138,6 @@ while (<STDIN>)
|
||||||
s/DCD(.*)/.long $1/;
|
s/DCD(.*)/.long $1/;
|
||||||
s/DCB(.*)/.byte $1/;
|
s/DCB(.*)/.byte $1/;
|
||||||
|
|
||||||
# RN to .req
|
|
||||||
if (s/RN\s+([Rr]\d+|lr)/.req $1/)
|
|
||||||
{
|
|
||||||
print;
|
|
||||||
print "$comment_sub$comment\n" if defined $comment;
|
|
||||||
next;
|
|
||||||
}
|
|
||||||
|
|
||||||
# Make function visible to linker, and make additional symbol with
|
# Make function visible to linker, and make additional symbol with
|
||||||
# prepended underscore
|
# prepended underscore
|
||||||
s/EXPORT\s+\|([\$\w]*)\|/.global $1 \n\t.type $1, function/;
|
s/EXPORT\s+\|([\$\w]*)\|/.global $1 \n\t.type $1, function/;
|
||||||
|
|
|
@ -120,18 +120,6 @@ while (<STDIN>)
|
||||||
s/DCD(.*)/.long $1/;
|
s/DCD(.*)/.long $1/;
|
||||||
s/DCB(.*)/.byte $1/;
|
s/DCB(.*)/.byte $1/;
|
||||||
|
|
||||||
# Build a hash of all the register - alias pairs.
|
|
||||||
if (s/(.*)RN(.*)/$1 .req $2/g)
|
|
||||||
{
|
|
||||||
$register_aliases{trim($1)} = trim($2);
|
|
||||||
next;
|
|
||||||
}
|
|
||||||
|
|
||||||
while (($key, $value) = each(%register_aliases))
|
|
||||||
{
|
|
||||||
s/\b$key\b/$value/g;
|
|
||||||
}
|
|
||||||
|
|
||||||
# Make function visible to linker, and make additional symbol with
|
# Make function visible to linker, and make additional symbol with
|
||||||
# prepended underscore
|
# prepended underscore
|
||||||
s/EXPORT\s+\|([\$\w]*)\|/.globl _$1\n\t.globl $1/;
|
s/EXPORT\s+\|([\$\w]*)\|/.globl _$1\n\t.globl $1/;
|
||||||
|
|
|
@ -332,20 +332,10 @@ EOF
|
||||||
}
|
}
|
||||||
|
|
||||||
check_cflags() {
|
check_cflags() {
|
||||||
log check_cflags "$@"
|
log check_cflags "$@"
|
||||||
|
check_cc -Werror "$@" <<EOF
|
||||||
case "$CC" in
|
|
||||||
*gcc*|*clang)
|
|
||||||
check_cc -Werror "$@" <<EOF
|
|
||||||
int x;
|
int x;
|
||||||
EOF
|
EOF
|
||||||
;;
|
|
||||||
*)
|
|
||||||
check_cc "$@" <<EOF
|
|
||||||
int x;
|
|
||||||
EOF
|
|
||||||
;;
|
|
||||||
esac
|
|
||||||
}
|
}
|
||||||
|
|
||||||
check_cxxflags() {
|
check_cxxflags() {
|
||||||
|
@ -413,6 +403,23 @@ check_gcc_machine_option() {
|
||||||
fi
|
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() {
|
write_common_config_banner() {
|
||||||
print_webm_license config.mk "##" ""
|
print_webm_license config.mk "##" ""
|
||||||
echo '# This file automatically generated by configure. Do not edit!' >> config.mk
|
echo '# This file automatically generated by configure. Do not edit!' >> config.mk
|
||||||
|
@ -645,7 +652,7 @@ setup_gnu_toolchain() {
|
||||||
AS=${AS:-${CROSS}as}
|
AS=${AS:-${CROSS}as}
|
||||||
STRIP=${STRIP:-${CROSS}strip}
|
STRIP=${STRIP:-${CROSS}strip}
|
||||||
NM=${NM:-${CROSS}nm}
|
NM=${NM:-${CROSS}nm}
|
||||||
AS_SFX=.s
|
AS_SFX=.S
|
||||||
EXE_SFX=
|
EXE_SFX=
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -684,7 +691,6 @@ check_xcode_minimum_version() {
|
||||||
process_common_toolchain() {
|
process_common_toolchain() {
|
||||||
if [ -z "$toolchain" ]; then
|
if [ -z "$toolchain" ]; then
|
||||||
gcctarget="${CHOST:-$(gcc -dumpmachine 2> /dev/null)}"
|
gcctarget="${CHOST:-$(gcc -dumpmachine 2> /dev/null)}"
|
||||||
|
|
||||||
# detect tgt_isa
|
# detect tgt_isa
|
||||||
case "$gcctarget" in
|
case "$gcctarget" in
|
||||||
aarch64*)
|
aarch64*)
|
||||||
|
@ -707,6 +713,18 @@ process_common_toolchain() {
|
||||||
*sparc*)
|
*sparc*)
|
||||||
tgt_isa=sparc
|
tgt_isa=sparc
|
||||||
;;
|
;;
|
||||||
|
power*64*-*)
|
||||||
|
tgt_isa=ppc64
|
||||||
|
;;
|
||||||
|
power*)
|
||||||
|
tgt_isa=ppc
|
||||||
|
;;
|
||||||
|
*mips64el*)
|
||||||
|
tgt_isa=mips64
|
||||||
|
;;
|
||||||
|
*mips32el*)
|
||||||
|
tgt_isa=mips32
|
||||||
|
;;
|
||||||
esac
|
esac
|
||||||
|
|
||||||
# detect tgt_os
|
# detect tgt_os
|
||||||
|
@ -735,9 +753,16 @@ process_common_toolchain() {
|
||||||
tgt_isa=x86_64
|
tgt_isa=x86_64
|
||||||
tgt_os=darwin15
|
tgt_os=darwin15
|
||||||
;;
|
;;
|
||||||
|
*darwin16*)
|
||||||
|
tgt_isa=x86_64
|
||||||
|
tgt_os=darwin16
|
||||||
|
;;
|
||||||
x86_64*mingw32*)
|
x86_64*mingw32*)
|
||||||
tgt_os=win64
|
tgt_os=win64
|
||||||
;;
|
;;
|
||||||
|
x86_64*cygwin*)
|
||||||
|
tgt_os=win64
|
||||||
|
;;
|
||||||
*mingw32*|*cygwin*)
|
*mingw32*|*cygwin*)
|
||||||
[ -z "$tgt_isa" ] && tgt_isa=x86
|
[ -z "$tgt_isa" ] && tgt_isa=x86
|
||||||
tgt_os=win32
|
tgt_os=win32
|
||||||
|
@ -785,6 +810,9 @@ process_common_toolchain() {
|
||||||
mips*)
|
mips*)
|
||||||
enable_feature mips
|
enable_feature mips
|
||||||
;;
|
;;
|
||||||
|
ppc*)
|
||||||
|
enable_feature ppc
|
||||||
|
;;
|
||||||
esac
|
esac
|
||||||
|
|
||||||
# PIC is probably what we want when building shared libs
|
# PIC is probably what we want when building shared libs
|
||||||
|
@ -853,6 +881,10 @@ process_common_toolchain() {
|
||||||
add_cflags "-mmacosx-version-min=10.11"
|
add_cflags "-mmacosx-version-min=10.11"
|
||||||
add_ldflags "-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"
|
||||||
|
;;
|
||||||
*-iphonesimulator-*)
|
*-iphonesimulator-*)
|
||||||
add_cflags "-miphoneos-version-min=${IOS_VERSION_MIN}"
|
add_cflags "-miphoneos-version-min=${IOS_VERSION_MIN}"
|
||||||
add_ldflags "-miphoneos-version-min=${IOS_VERSION_MIN}"
|
add_ldflags "-miphoneos-version-min=${IOS_VERSION_MIN}"
|
||||||
|
@ -936,7 +968,7 @@ EOF
|
||||||
;;
|
;;
|
||||||
vs*)
|
vs*)
|
||||||
asm_conversion_cmd="${source_path}/build/make/ads2armasm_ms.pl"
|
asm_conversion_cmd="${source_path}/build/make/ads2armasm_ms.pl"
|
||||||
AS_SFX=.s
|
AS_SFX=.S
|
||||||
msvs_arch_dir=arm-msvs
|
msvs_arch_dir=arm-msvs
|
||||||
disable_feature multithread
|
disable_feature multithread
|
||||||
disable_feature unit_tests
|
disable_feature unit_tests
|
||||||
|
@ -946,6 +978,7 @@ EOF
|
||||||
# only "AppContainerApplication" which requires an AppxManifest.
|
# only "AppContainerApplication" which requires an AppxManifest.
|
||||||
# Therefore disable the examples, just build the library.
|
# Therefore disable the examples, just build the library.
|
||||||
disable_feature examples
|
disable_feature examples
|
||||||
|
disable_feature tools
|
||||||
fi
|
fi
|
||||||
;;
|
;;
|
||||||
rvct)
|
rvct)
|
||||||
|
@ -1044,7 +1077,7 @@ EOF
|
||||||
STRIP="$(${XCRUN_FIND} strip)"
|
STRIP="$(${XCRUN_FIND} strip)"
|
||||||
NM="$(${XCRUN_FIND} nm)"
|
NM="$(${XCRUN_FIND} nm)"
|
||||||
RANLIB="$(${XCRUN_FIND} ranlib)"
|
RANLIB="$(${XCRUN_FIND} ranlib)"
|
||||||
AS_SFX=.s
|
AS_SFX=.S
|
||||||
LD="${CXX:-$(${XCRUN_FIND} ld)}"
|
LD="${CXX:-$(${XCRUN_FIND} ld)}"
|
||||||
|
|
||||||
# ASFLAGS is written here instead of using check_add_asflags
|
# ASFLAGS is written here instead of using check_add_asflags
|
||||||
|
@ -1153,10 +1186,20 @@ EOF
|
||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
if enabled mmi; then
|
||||||
|
tgt_isa=loongson3a
|
||||||
|
check_add_ldflags -march=loongson3a
|
||||||
|
fi
|
||||||
|
|
||||||
check_add_cflags -march=${tgt_isa}
|
check_add_cflags -march=${tgt_isa}
|
||||||
check_add_asflags -march=${tgt_isa}
|
check_add_asflags -march=${tgt_isa}
|
||||||
check_add_asflags -KPIC
|
check_add_asflags -KPIC
|
||||||
;;
|
;;
|
||||||
|
ppc*)
|
||||||
|
link_with_cc=gcc
|
||||||
|
setup_gnu_toolchain
|
||||||
|
check_gcc_machine_option "vsx"
|
||||||
|
;;
|
||||||
x86*)
|
x86*)
|
||||||
case ${tgt_os} in
|
case ${tgt_os} in
|
||||||
win*)
|
win*)
|
||||||
|
@ -1211,6 +1254,13 @@ EOF
|
||||||
AS=msvs
|
AS=msvs
|
||||||
msvs_arch_dir=x86-msvs
|
msvs_arch_dir=x86-msvs
|
||||||
vc_version=${tgt_cc##vs}
|
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
|
case $vc_version in
|
||||||
7|8|9|10)
|
7|8|9|10)
|
||||||
echo "${tgt_cc} does not support avx/avx2, disabling....."
|
echo "${tgt_cc} does not support avx/avx2, disabling....."
|
||||||
|
@ -1255,9 +1305,18 @@ EOF
|
||||||
elif disabled $ext; then
|
elif disabled $ext; then
|
||||||
disable_exts="yes"
|
disable_exts="yes"
|
||||||
else
|
else
|
||||||
# use the shortened version for the flag: sse4_1 -> sse4
|
if [ "$ext" = "avx512" ]; then
|
||||||
check_gcc_machine_option ${ext%_*} $ext
|
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
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
# https://bugs.chromium.org/p/webm/issues/detail?id=1464
|
||||||
|
# The assembly optimizations for vpx_sub_pixel_variance do not link with
|
||||||
|
# gcc 6.
|
||||||
|
enabled sse2 && soft_enable pic
|
||||||
done
|
done
|
||||||
|
|
||||||
if enabled external_build; then
|
if enabled external_build; then
|
||||||
|
@ -1282,7 +1341,6 @@ EOF
|
||||||
esac
|
esac
|
||||||
log_echo " using $AS"
|
log_echo " using $AS"
|
||||||
fi
|
fi
|
||||||
[ "${AS##*/}" = nasm ] && add_asflags -Ox
|
|
||||||
AS_SFX=.asm
|
AS_SFX=.asm
|
||||||
case ${tgt_os} in
|
case ${tgt_os} in
|
||||||
win32)
|
win32)
|
||||||
|
@ -1291,7 +1349,7 @@ EOF
|
||||||
EXE_SFX=.exe
|
EXE_SFX=.exe
|
||||||
;;
|
;;
|
||||||
win64)
|
win64)
|
||||||
add_asflags -f x64
|
add_asflags -f win64
|
||||||
enabled debug && add_asflags -g cv8
|
enabled debug && add_asflags -g cv8
|
||||||
EXE_SFX=.exe
|
EXE_SFX=.exe
|
||||||
;;
|
;;
|
||||||
|
@ -1425,6 +1483,10 @@ EOF
|
||||||
echo "msa optimizations are available only for little endian platforms"
|
echo "msa optimizations are available only for little endian platforms"
|
||||||
disable_feature msa
|
disable_feature msa
|
||||||
fi
|
fi
|
||||||
|
if enabled mmi; then
|
||||||
|
echo "mmi optimizations are available only for little endian platforms"
|
||||||
|
disable_feature mmi
|
||||||
|
fi
|
||||||
fi
|
fi
|
||||||
;;
|
;;
|
||||||
esac
|
esac
|
||||||
|
|
|
@ -25,7 +25,7 @@ files.
|
||||||
Options:
|
Options:
|
||||||
--help Print this message
|
--help Print this message
|
||||||
--out=outfile Redirect output to a file
|
--out=outfile Redirect output to a file
|
||||||
--ver=version Version (7,8,9,10,11,12,14) of visual studio to generate for
|
--ver=version Version (7,8,9,10,11,12,14,15) of visual studio to generate for
|
||||||
--target=isa-os-cc Target specifier
|
--target=isa-os-cc Target specifier
|
||||||
EOF
|
EOF
|
||||||
exit 1
|
exit 1
|
||||||
|
@ -215,7 +215,7 @@ for opt in "$@"; do
|
||||||
;;
|
;;
|
||||||
--ver=*) vs_ver="$optval"
|
--ver=*) vs_ver="$optval"
|
||||||
case $optval in
|
case $optval in
|
||||||
10|11|12|14)
|
10|11|12|14|15)
|
||||||
;;
|
;;
|
||||||
*) die Unrecognized Visual Studio Version in $opt
|
*) die Unrecognized Visual Studio Version in $opt
|
||||||
;;
|
;;
|
||||||
|
@ -240,9 +240,12 @@ case "${vs_ver:-10}" in
|
||||||
12) sln_vers="12.00"
|
12) sln_vers="12.00"
|
||||||
sln_vers_str="Visual Studio 2013"
|
sln_vers_str="Visual Studio 2013"
|
||||||
;;
|
;;
|
||||||
14) sln_vers="14.00"
|
14) sln_vers="12.00"
|
||||||
sln_vers_str="Visual Studio 2015"
|
sln_vers_str="Visual Studio 2015"
|
||||||
;;
|
;;
|
||||||
|
15) sln_vers="12.00"
|
||||||
|
sln_vers_str="Visual Studio 2017"
|
||||||
|
;;
|
||||||
esac
|
esac
|
||||||
sfx=vcxproj
|
sfx=vcxproj
|
||||||
|
|
||||||
|
|
|
@ -34,7 +34,7 @@ Options:
|
||||||
--name=project_name Name of the project (required)
|
--name=project_name Name of the project (required)
|
||||||
--proj-guid=GUID GUID to use for the project
|
--proj-guid=GUID GUID to use for the project
|
||||||
--module-def=filename File containing export definitions (for DLLs)
|
--module-def=filename File containing export definitions (for DLLs)
|
||||||
--ver=version Version (10,11,12,14) of visual studio to generate for
|
--ver=version Version (10,11,12,14,15) of visual studio to generate for
|
||||||
--src-path-bare=dir Path to root of source tree
|
--src-path-bare=dir Path to root of source tree
|
||||||
-Ipath/to/include Additional include directories
|
-Ipath/to/include Additional include directories
|
||||||
-DFLAG[=value] Preprocessor macros to define
|
-DFLAG[=value] Preprocessor macros to define
|
||||||
|
@ -82,7 +82,7 @@ generate_filter() {
|
||||||
| sed -e "s,$src_path_bare,," \
|
| sed -e "s,$src_path_bare,," \
|
||||||
-e 's/^[\./]\+//g' -e 's,[:/ ],_,g')
|
-e 's/^[\./]\+//g' -e 's,[:/ ],_,g')
|
||||||
|
|
||||||
if ([ "$pat" == "asm" ] || [ "$pat" == "s" ]) && $asm_use_custom_step; then
|
if ([ "$pat" == "asm" ] || [ "$pat" == "s" ] || [ "$pat" == "S" ]) && $asm_use_custom_step; then
|
||||||
# Avoid object file name collisions, i.e. vpx_config.c and
|
# Avoid object file name collisions, i.e. vpx_config.c and
|
||||||
# vpx_config.asm produce the same object file without
|
# vpx_config.asm produce the same object file without
|
||||||
# this additional suffix.
|
# this additional suffix.
|
||||||
|
@ -168,7 +168,7 @@ for opt in "$@"; do
|
||||||
--ver=*)
|
--ver=*)
|
||||||
vs_ver="$optval"
|
vs_ver="$optval"
|
||||||
case "$optval" in
|
case "$optval" in
|
||||||
10|11|12|14)
|
10|11|12|14|15)
|
||||||
;;
|
;;
|
||||||
*) die Unrecognized Visual Studio Version in $opt
|
*) die Unrecognized Visual Studio Version in $opt
|
||||||
;;
|
;;
|
||||||
|
@ -203,7 +203,7 @@ for opt in "$@"; do
|
||||||
# The paths in file_list are fixed outside of the loop.
|
# The paths in file_list are fixed outside of the loop.
|
||||||
file_list[${#file_list[@]}]="$opt"
|
file_list[${#file_list[@]}]="$opt"
|
||||||
case "$opt" in
|
case "$opt" in
|
||||||
*.asm|*.s) uses_asm=true
|
*.asm|*.[Ss]) uses_asm=true
|
||||||
;;
|
;;
|
||||||
esac
|
esac
|
||||||
;;
|
;;
|
||||||
|
@ -218,7 +218,7 @@ guid=${guid:-`generate_uuid`}
|
||||||
asm_use_custom_step=false
|
asm_use_custom_step=false
|
||||||
uses_asm=${uses_asm:-false}
|
uses_asm=${uses_asm:-false}
|
||||||
case "${vs_ver:-11}" in
|
case "${vs_ver:-11}" in
|
||||||
10|11|12|14)
|
10|11|12|14|15)
|
||||||
asm_use_custom_step=$uses_asm
|
asm_use_custom_step=$uses_asm
|
||||||
;;
|
;;
|
||||||
esac
|
esac
|
||||||
|
@ -347,6 +347,9 @@ generate_vcxproj() {
|
||||||
if [ "$vs_ver" = "14" ]; then
|
if [ "$vs_ver" = "14" ]; then
|
||||||
tag_content PlatformToolset v140
|
tag_content PlatformToolset v140
|
||||||
fi
|
fi
|
||||||
|
if [ "$vs_ver" = "15" ]; then
|
||||||
|
tag_content PlatformToolset v141
|
||||||
|
fi
|
||||||
tag_content CharacterSet Unicode
|
tag_content CharacterSet Unicode
|
||||||
if [ "$config" = "Release" ]; then
|
if [ "$config" = "Release" ]; then
|
||||||
tag_content WholeProgramOptimization true
|
tag_content WholeProgramOptimization true
|
||||||
|
@ -452,7 +455,7 @@ generate_vcxproj() {
|
||||||
done
|
done
|
||||||
|
|
||||||
open_tag ItemGroup
|
open_tag ItemGroup
|
||||||
generate_filter "Source Files" "c;cc;cpp;def;odl;idl;hpj;bat;asm;asmx;s"
|
generate_filter "Source Files" "c;cc;cpp;def;odl;idl;hpj;bat;asm;asmx;s;S"
|
||||||
close_tag ItemGroup
|
close_tag ItemGroup
|
||||||
open_tag ItemGroup
|
open_tag ItemGroup
|
||||||
generate_filter "Header Files" "h;hm;inl;inc;xsd"
|
generate_filter "Header Files" "h;hm;inl;inc;xsd"
|
||||||
|
|
|
@ -35,8 +35,8 @@ ARM_TARGETS="arm64-darwin-gcc
|
||||||
armv7s-darwin-gcc"
|
armv7s-darwin-gcc"
|
||||||
SIM_TARGETS="x86-iphonesimulator-gcc
|
SIM_TARGETS="x86-iphonesimulator-gcc
|
||||||
x86_64-iphonesimulator-gcc"
|
x86_64-iphonesimulator-gcc"
|
||||||
OSX_TARGETS="x86-darwin15-gcc
|
OSX_TARGETS="x86-darwin16-gcc
|
||||||
x86_64-darwin15-gcc"
|
x86_64-darwin16-gcc"
|
||||||
TARGETS="${ARM_TARGETS} ${SIM_TARGETS}"
|
TARGETS="${ARM_TARGETS} ${SIM_TARGETS}"
|
||||||
|
|
||||||
# Configures for the target specified by $1, and invokes make with the dist
|
# 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.
|
--help: Display this message and exit.
|
||||||
--enable-shared: Build a dynamic framework for use on iOS 8 or later.
|
--enable-shared: Build a dynamic framework for use on iOS 8 or later.
|
||||||
--extra-configure-args <args>: Extra args to pass when configuring libvpx.
|
--extra-configure-args <args>: Extra args to pass when configuring libvpx.
|
||||||
--macosx: Uses darwin15 targets instead of iphonesimulator targets for x86
|
--macosx: Uses darwin16 targets instead of iphonesimulator targets for x86
|
||||||
and x86_64. Allows linking to framework when builds target MacOSX
|
and x86_64. Allows linking to framework when builds target MacOSX
|
||||||
instead of iOS.
|
instead of iOS.
|
||||||
--preserve-build-output: Do not delete the build directory.
|
--preserve-build-output: Do not delete the build directory.
|
||||||
|
|
|
@ -1,4 +1,13 @@
|
||||||
#!/usr/bin/env perl
|
#!/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';
|
no strict 'refs';
|
||||||
use warnings;
|
use warnings;
|
||||||
|
@ -200,6 +209,7 @@ sub filter {
|
||||||
sub common_top() {
|
sub common_top() {
|
||||||
my $include_guard = uc($opts{sym})."_H_";
|
my $include_guard = uc($opts{sym})."_H_";
|
||||||
print <<EOF;
|
print <<EOF;
|
||||||
|
// This file is generated. Do not edit.
|
||||||
#ifndef ${include_guard}
|
#ifndef ${include_guard}
|
||||||
#define ${include_guard}
|
#define ${include_guard}
|
||||||
|
|
||||||
|
@ -335,6 +345,36 @@ EOF
|
||||||
common_bottom;
|
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() {
|
sub unoptimized() {
|
||||||
determine_indirection "c";
|
determine_indirection "c";
|
||||||
common_top;
|
common_top;
|
||||||
|
@ -361,10 +401,10 @@ EOF
|
||||||
|
|
||||||
&require("c");
|
&require("c");
|
||||||
if ($opts{arch} eq 'x86') {
|
if ($opts{arch} eq 'x86') {
|
||||||
@ALL_ARCHS = filter(qw/mmx sse sse2 sse3 ssse3 sse4_1 avx avx2/);
|
@ALL_ARCHS = filter(qw/mmx sse sse2 sse3 ssse3 sse4_1 avx avx2 avx512/);
|
||||||
x86;
|
x86;
|
||||||
} elsif ($opts{arch} eq 'x86_64') {
|
} elsif ($opts{arch} eq 'x86_64') {
|
||||||
@ALL_ARCHS = filter(qw/mmx sse sse2 sse3 ssse3 sse4_1 avx avx2/);
|
@ALL_ARCHS = filter(qw/mmx sse sse2 sse3 ssse3 sse4_1 avx avx2 avx512/);
|
||||||
@REQUIRES = filter(keys %required ? keys %required : qw/mmx sse sse2/);
|
@REQUIRES = filter(keys %required ? keys %required : qw/mmx sse sse2/);
|
||||||
&require(@REQUIRES);
|
&require(@REQUIRES);
|
||||||
x86;
|
x86;
|
||||||
|
@ -381,6 +421,10 @@ if ($opts{arch} eq 'x86') {
|
||||||
@ALL_ARCHS = filter("$opts{arch}", qw/msa/);
|
@ALL_ARCHS = filter("$opts{arch}", qw/msa/);
|
||||||
last;
|
last;
|
||||||
}
|
}
|
||||||
|
if (/HAVE_MMI=yes/) {
|
||||||
|
@ALL_ARCHS = filter("$opts{arch}", qw/mmi/);
|
||||||
|
last;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
close CONFIG_FILE;
|
close CONFIG_FILE;
|
||||||
mips;
|
mips;
|
||||||
|
@ -390,6 +434,9 @@ if ($opts{arch} eq 'x86') {
|
||||||
} elsif ($opts{arch} eq 'armv8' || $opts{arch} eq 'arm64' ) {
|
} elsif ($opts{arch} eq 'armv8' || $opts{arch} eq 'arm64' ) {
|
||||||
@ALL_ARCHS = filter(qw/neon/);
|
@ALL_ARCHS = filter(qw/neon/);
|
||||||
arm;
|
arm;
|
||||||
|
} elsif ($opts{arch} =~ /^ppc/ ) {
|
||||||
|
@ALL_ARCHS = filter(qw/vsx/);
|
||||||
|
ppc;
|
||||||
} else {
|
} else {
|
||||||
unoptimized;
|
unoptimized;
|
||||||
}
|
}
|
||||||
|
|
|
@ -60,6 +60,7 @@ if [ ${bare} ]; then
|
||||||
echo "${changelog_version}${git_version_id}" > $$.tmp
|
echo "${changelog_version}${git_version_id}" > $$.tmp
|
||||||
else
|
else
|
||||||
cat<<EOF>$$.tmp
|
cat<<EOF>$$.tmp
|
||||||
|
// This file is generated. Do not edit.
|
||||||
#define VERSION_MAJOR $major_version
|
#define VERSION_MAJOR $major_version
|
||||||
#define VERSION_MINOR $minor_version
|
#define VERSION_MINOR $minor_version
|
||||||
#define VERSION_PATCH $patch_version
|
#define VERSION_PATCH $patch_version
|
||||||
|
|
|
@ -22,6 +22,7 @@ show_help(){
|
||||||
Advanced options:
|
Advanced options:
|
||||||
${toggle_libs} libraries
|
${toggle_libs} libraries
|
||||||
${toggle_examples} examples
|
${toggle_examples} examples
|
||||||
|
${toggle_tools} tools
|
||||||
${toggle_docs} documentation
|
${toggle_docs} documentation
|
||||||
${toggle_unit_tests} unit tests
|
${toggle_unit_tests} unit tests
|
||||||
${toggle_decode_perf_tests} build decoder perf tests with unit tests
|
${toggle_decode_perf_tests} build decoder perf tests with unit tests
|
||||||
|
@ -108,10 +109,13 @@ all_platforms="${all_platforms} armv7-none-rvct" #neon Cortex-A8
|
||||||
all_platforms="${all_platforms} armv7-win32-vs11"
|
all_platforms="${all_platforms} armv7-win32-vs11"
|
||||||
all_platforms="${all_platforms} armv7-win32-vs12"
|
all_platforms="${all_platforms} armv7-win32-vs12"
|
||||||
all_platforms="${all_platforms} armv7-win32-vs14"
|
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} armv7s-darwin-gcc"
|
||||||
all_platforms="${all_platforms} armv8-linux-gcc"
|
all_platforms="${all_platforms} armv8-linux-gcc"
|
||||||
all_platforms="${all_platforms} mips32-linux-gcc"
|
all_platforms="${all_platforms} mips32-linux-gcc"
|
||||||
all_platforms="${all_platforms} mips64-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} sparc-solaris-gcc"
|
||||||
all_platforms="${all_platforms} x86-android-gcc"
|
all_platforms="${all_platforms} x86-android-gcc"
|
||||||
all_platforms="${all_platforms} x86-darwin8-gcc"
|
all_platforms="${all_platforms} x86-darwin8-gcc"
|
||||||
|
@ -124,6 +128,7 @@ all_platforms="${all_platforms} x86-darwin12-gcc"
|
||||||
all_platforms="${all_platforms} x86-darwin13-gcc"
|
all_platforms="${all_platforms} x86-darwin13-gcc"
|
||||||
all_platforms="${all_platforms} x86-darwin14-gcc"
|
all_platforms="${all_platforms} x86-darwin14-gcc"
|
||||||
all_platforms="${all_platforms} x86-darwin15-gcc"
|
all_platforms="${all_platforms} x86-darwin15-gcc"
|
||||||
|
all_platforms="${all_platforms} x86-darwin16-gcc"
|
||||||
all_platforms="${all_platforms} x86-iphonesimulator-gcc"
|
all_platforms="${all_platforms} x86-iphonesimulator-gcc"
|
||||||
all_platforms="${all_platforms} x86-linux-gcc"
|
all_platforms="${all_platforms} x86-linux-gcc"
|
||||||
all_platforms="${all_platforms} x86-linux-icc"
|
all_platforms="${all_platforms} x86-linux-icc"
|
||||||
|
@ -134,6 +139,7 @@ all_platforms="${all_platforms} x86-win32-vs10"
|
||||||
all_platforms="${all_platforms} x86-win32-vs11"
|
all_platforms="${all_platforms} x86-win32-vs11"
|
||||||
all_platforms="${all_platforms} x86-win32-vs12"
|
all_platforms="${all_platforms} x86-win32-vs12"
|
||||||
all_platforms="${all_platforms} x86-win32-vs14"
|
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-android-gcc"
|
||||||
all_platforms="${all_platforms} x86_64-darwin9-gcc"
|
all_platforms="${all_platforms} x86_64-darwin9-gcc"
|
||||||
all_platforms="${all_platforms} x86_64-darwin10-gcc"
|
all_platforms="${all_platforms} x86_64-darwin10-gcc"
|
||||||
|
@ -142,6 +148,7 @@ all_platforms="${all_platforms} x86_64-darwin12-gcc"
|
||||||
all_platforms="${all_platforms} x86_64-darwin13-gcc"
|
all_platforms="${all_platforms} x86_64-darwin13-gcc"
|
||||||
all_platforms="${all_platforms} x86_64-darwin14-gcc"
|
all_platforms="${all_platforms} x86_64-darwin14-gcc"
|
||||||
all_platforms="${all_platforms} x86_64-darwin15-gcc"
|
all_platforms="${all_platforms} x86_64-darwin15-gcc"
|
||||||
|
all_platforms="${all_platforms} x86_64-darwin16-gcc"
|
||||||
all_platforms="${all_platforms} x86_64-iphonesimulator-gcc"
|
all_platforms="${all_platforms} x86_64-iphonesimulator-gcc"
|
||||||
all_platforms="${all_platforms} x86_64-linux-gcc"
|
all_platforms="${all_platforms} x86_64-linux-gcc"
|
||||||
all_platforms="${all_platforms} x86_64-linux-icc"
|
all_platforms="${all_platforms} x86_64-linux-icc"
|
||||||
|
@ -151,22 +158,26 @@ all_platforms="${all_platforms} x86_64-win64-vs10"
|
||||||
all_platforms="${all_platforms} x86_64-win64-vs11"
|
all_platforms="${all_platforms} x86_64-win64-vs11"
|
||||||
all_platforms="${all_platforms} x86_64-win64-vs12"
|
all_platforms="${all_platforms} x86_64-win64-vs12"
|
||||||
all_platforms="${all_platforms} x86_64-win64-vs14"
|
all_platforms="${all_platforms} x86_64-win64-vs14"
|
||||||
|
all_platforms="${all_platforms} x86_64-win64-vs15"
|
||||||
all_platforms="${all_platforms} generic-gnu"
|
all_platforms="${all_platforms} generic-gnu"
|
||||||
|
|
||||||
# all_targets is a list of all targets that can be configured
|
# all_targets is a list of all targets that can be configured
|
||||||
# note that these should be in dependency order for now.
|
# note that these should be in dependency order for now.
|
||||||
all_targets="libs examples docs"
|
all_targets="libs examples tools docs"
|
||||||
|
|
||||||
# all targets available are enabled, by default.
|
# all targets available are enabled, by default.
|
||||||
for t in ${all_targets}; do
|
for t in ${all_targets}; do
|
||||||
[ -f "${source_path}/${t}.mk" ] && enable_feature ${t}
|
[ -f "${source_path}/${t}.mk" ] && enable_feature ${t}
|
||||||
done
|
done
|
||||||
|
|
||||||
|
if ! diff --version >/dev/null; then
|
||||||
|
die "diff missing: Try installing diffutils via your package manager."
|
||||||
|
fi
|
||||||
|
|
||||||
if ! perl --version >/dev/null; then
|
if ! perl --version >/dev/null; then
|
||||||
die "Perl is required to build"
|
die "Perl is required to build"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
|
||||||
if [ "`cd \"${source_path}\" && pwd`" != "`pwd`" ]; then
|
if [ "`cd \"${source_path}\" && pwd`" != "`pwd`" ]; then
|
||||||
# test to see if source_path already configured
|
# test to see if source_path already configured
|
||||||
if [ -f "${source_path}/vpx_config.h" ]; then
|
if [ -f "${source_path}/vpx_config.h" ]; then
|
||||||
|
@ -222,6 +233,7 @@ ARCH_LIST="
|
||||||
mips
|
mips
|
||||||
x86
|
x86
|
||||||
x86_64
|
x86_64
|
||||||
|
ppc
|
||||||
"
|
"
|
||||||
ARCH_EXT_LIST_X86="
|
ARCH_EXT_LIST_X86="
|
||||||
mmx
|
mmx
|
||||||
|
@ -232,7 +244,13 @@ ARCH_EXT_LIST_X86="
|
||||||
sse4_1
|
sse4_1
|
||||||
avx
|
avx
|
||||||
avx2
|
avx2
|
||||||
|
avx512
|
||||||
"
|
"
|
||||||
|
|
||||||
|
ARCH_EXT_LIST_LOONGSON="
|
||||||
|
mmi
|
||||||
|
"
|
||||||
|
|
||||||
ARCH_EXT_LIST="
|
ARCH_EXT_LIST="
|
||||||
neon
|
neon
|
||||||
neon_asm
|
neon_asm
|
||||||
|
@ -243,6 +261,10 @@ ARCH_EXT_LIST="
|
||||||
mips64
|
mips64
|
||||||
|
|
||||||
${ARCH_EXT_LIST_X86}
|
${ARCH_EXT_LIST_X86}
|
||||||
|
|
||||||
|
vsx
|
||||||
|
|
||||||
|
${ARCH_EXT_LIST_LOONGSON}
|
||||||
"
|
"
|
||||||
HAVE_LIST="
|
HAVE_LIST="
|
||||||
${ARCH_EXT_LIST}
|
${ARCH_EXT_LIST}
|
||||||
|
@ -254,7 +276,6 @@ EXPERIMENT_LIST="
|
||||||
spatial_svc
|
spatial_svc
|
||||||
fp_mb_stats
|
fp_mb_stats
|
||||||
emulate_hardware
|
emulate_hardware
|
||||||
misc_fixes
|
|
||||||
"
|
"
|
||||||
CONFIG_LIST="
|
CONFIG_LIST="
|
||||||
dependency_tracking
|
dependency_tracking
|
||||||
|
@ -309,6 +330,7 @@ CONFIG_LIST="
|
||||||
better_hw_compatibility
|
better_hw_compatibility
|
||||||
experimental
|
experimental
|
||||||
size_limit
|
size_limit
|
||||||
|
always_adjust_bpm
|
||||||
${EXPERIMENT_LIST}
|
${EXPERIMENT_LIST}
|
||||||
"
|
"
|
||||||
CMDLINE_SELECT="
|
CMDLINE_SELECT="
|
||||||
|
@ -331,6 +353,7 @@ CMDLINE_SELECT="
|
||||||
|
|
||||||
libs
|
libs
|
||||||
examples
|
examples
|
||||||
|
tools
|
||||||
docs
|
docs
|
||||||
libc
|
libc
|
||||||
as
|
as
|
||||||
|
@ -367,6 +390,7 @@ CMDLINE_SELECT="
|
||||||
better_hw_compatibility
|
better_hw_compatibility
|
||||||
vp9_highbitdepth
|
vp9_highbitdepth
|
||||||
experimental
|
experimental
|
||||||
|
always_adjust_bpm
|
||||||
"
|
"
|
||||||
|
|
||||||
process_cmdline() {
|
process_cmdline() {
|
||||||
|
@ -476,7 +500,7 @@ EOF
|
||||||
#
|
#
|
||||||
# Write makefiles for all enabled targets
|
# Write makefiles for all enabled targets
|
||||||
#
|
#
|
||||||
for tgt in libs examples docs solution; do
|
for tgt in libs examples tools docs solution; do
|
||||||
tgt_fn="$tgt-$toolchain.mk"
|
tgt_fn="$tgt-$toolchain.mk"
|
||||||
|
|
||||||
if enabled $tgt; then
|
if enabled $tgt; then
|
||||||
|
@ -568,6 +592,7 @@ process_toolchain() {
|
||||||
check_add_cflags -Wdeclaration-after-statement
|
check_add_cflags -Wdeclaration-after-statement
|
||||||
check_add_cflags -Wdisabled-optimization
|
check_add_cflags -Wdisabled-optimization
|
||||||
check_add_cflags -Wfloat-conversion
|
check_add_cflags -Wfloat-conversion
|
||||||
|
check_add_cflags -Wparentheses-equality
|
||||||
check_add_cflags -Wpointer-arith
|
check_add_cflags -Wpointer-arith
|
||||||
check_add_cflags -Wtype-limits
|
check_add_cflags -Wtype-limits
|
||||||
check_add_cflags -Wcast-qual
|
check_add_cflags -Wcast-qual
|
||||||
|
@ -575,12 +600,20 @@ process_toolchain() {
|
||||||
check_add_cflags -Wimplicit-function-declaration
|
check_add_cflags -Wimplicit-function-declaration
|
||||||
check_add_cflags -Wuninitialized
|
check_add_cflags -Wuninitialized
|
||||||
check_add_cflags -Wunused
|
check_add_cflags -Wunused
|
||||||
|
# -Wextra has some tricky cases. Rather than fix them all now, get the
|
||||||
|
# flag for as many files as possible and fix the remaining issues
|
||||||
|
# piecemeal.
|
||||||
|
# https://bugs.chromium.org/p/webm/issues/detail?id=1069
|
||||||
|
check_add_cflags -Wextra
|
||||||
# check_add_cflags also adds to cxxflags. gtest does not do well with
|
# check_add_cflags also adds to cxxflags. gtest does not do well with
|
||||||
# -Wundef so add it explicitly to CFLAGS only.
|
# -Wundef so add it explicitly to CFLAGS only.
|
||||||
check_cflags -Wundef && add_cflags_only -Wundef
|
check_cflags -Wundef && add_cflags_only -Wundef
|
||||||
if enabled mips || [ -z "${INLINE}" ]; then
|
if enabled mips || [ -z "${INLINE}" ]; then
|
||||||
enabled extra_warnings || check_add_cflags -Wno-unused-function
|
enabled extra_warnings || check_add_cflags -Wno-unused-function
|
||||||
fi
|
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
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if enabled icc; then
|
if enabled icc; then
|
||||||
|
@ -632,7 +665,7 @@ process_toolchain() {
|
||||||
gen_vcproj_cmd=${source_path}/build/make/gen_msvs_vcxproj.sh
|
gen_vcproj_cmd=${source_path}/build/make/gen_msvs_vcxproj.sh
|
||||||
enabled werror && gen_vcproj_cmd="${gen_vcproj_cmd} --enable-werror"
|
enabled werror && gen_vcproj_cmd="${gen_vcproj_cmd} --enable-werror"
|
||||||
all_targets="${all_targets} solution"
|
all_targets="${all_targets} solution"
|
||||||
INLINE="__forceinline"
|
INLINE="__inline"
|
||||||
;;
|
;;
|
||||||
esac
|
esac
|
||||||
|
|
||||||
|
|
|
@ -76,6 +76,7 @@ vpxdec.SRCS += tools_common.c tools_common.h
|
||||||
vpxdec.SRCS += y4menc.c y4menc.h
|
vpxdec.SRCS += y4menc.c y4menc.h
|
||||||
ifeq ($(CONFIG_LIBYUV),yes)
|
ifeq ($(CONFIG_LIBYUV),yes)
|
||||||
vpxdec.SRCS += $(LIBYUV_SRCS)
|
vpxdec.SRCS += $(LIBYUV_SRCS)
|
||||||
|
$(BUILD_PFX)third_party/libyuv/%.cc.o: CXXFLAGS += -Wno-unused-parameter
|
||||||
endif
|
endif
|
||||||
ifeq ($(CONFIG_WEBM_IO),yes)
|
ifeq ($(CONFIG_WEBM_IO),yes)
|
||||||
vpxdec.SRCS += $(LIBWEBM_COMMON_SRCS)
|
vpxdec.SRCS += $(LIBWEBM_COMMON_SRCS)
|
||||||
|
|
|
@ -151,7 +151,7 @@ static void write_ivf_frame_header(FILE *outfile,
|
||||||
if (pkt->kind != VPX_CODEC_CX_FRAME_PKT) return;
|
if (pkt->kind != VPX_CODEC_CX_FRAME_PKT) return;
|
||||||
|
|
||||||
pts = pkt->data.frame.pts;
|
pts = pkt->data.frame.pts;
|
||||||
mem_put_le32(header, pkt->data.frame.sz);
|
mem_put_le32(header, (int)pkt->data.frame.sz);
|
||||||
mem_put_le32(header + 4, pts & 0xFFFFFFFF);
|
mem_put_le32(header + 4, pts & 0xFFFFFFFF);
|
||||||
mem_put_le32(header + 8, pts >> 32);
|
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[0] = 0;
|
||||||
cfg->ts_layer_id[1] = 1;
|
cfg->ts_layer_id[1] = 1;
|
||||||
// Use 60/40 bit allocation as example.
|
// Use 60/40 bit allocation as example.
|
||||||
cfg->ts_target_bitrate[0] = 0.6f * bitrate;
|
cfg->ts_target_bitrate[0] = (int)(0.6f * bitrate);
|
||||||
cfg->ts_target_bitrate[1] = bitrate;
|
cfg->ts_target_bitrate[1] = bitrate;
|
||||||
|
|
||||||
/* 0=L, 1=GF */
|
/* 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[1] = 2;
|
||||||
cfg->ts_layer_id[2] = 1;
|
cfg->ts_layer_id[2] = 1;
|
||||||
cfg->ts_layer_id[3] = 2;
|
cfg->ts_layer_id[3] = 2;
|
||||||
// Use 40/20/40 bit allocation as example.
|
// Use 45/20/35 bit allocation as example.
|
||||||
cfg->ts_target_bitrate[0] = 0.4f * bitrate;
|
cfg->ts_target_bitrate[0] = (int)(0.45f * bitrate);
|
||||||
cfg->ts_target_bitrate[1] = 0.6f * bitrate;
|
cfg->ts_target_bitrate[1] = (int)(0.65f * bitrate);
|
||||||
cfg->ts_target_bitrate[2] = bitrate;
|
cfg->ts_target_bitrate[2] = bitrate;
|
||||||
|
|
||||||
/* 0=L, 1=GF, 2=ARF */
|
/* 0=L, 1=GF, 2=ARF */
|
||||||
|
@ -294,8 +294,8 @@ int main(int argc, char **argv) {
|
||||||
vpx_codec_err_t res[NUM_ENCODERS];
|
vpx_codec_err_t res[NUM_ENCODERS];
|
||||||
|
|
||||||
int i;
|
int i;
|
||||||
long width;
|
int width;
|
||||||
long height;
|
int height;
|
||||||
int length_frame;
|
int length_frame;
|
||||||
int frame_avail;
|
int frame_avail;
|
||||||
int got_data;
|
int got_data;
|
||||||
|
@ -347,9 +347,9 @@ int main(int argc, char **argv) {
|
||||||
|
|
||||||
printf("Using %s\n", vpx_codec_iface_name(interface));
|
printf("Using %s\n", vpx_codec_iface_name(interface));
|
||||||
|
|
||||||
width = strtol(argv[1], NULL, 0);
|
width = (int)strtol(argv[1], NULL, 0);
|
||||||
height = strtol(argv[2], NULL, 0);
|
height = (int)strtol(argv[2], NULL, 0);
|
||||||
framerate = strtol(argv[3], NULL, 0);
|
framerate = (int)strtol(argv[3], NULL, 0);
|
||||||
|
|
||||||
if (width < 16 || width % 2 || height < 16 || height % 2)
|
if (width < 16 || width % 2 || height < 16 || height % 2)
|
||||||
die("Invalid resolution: %ldx%ld", width, height);
|
die("Invalid resolution: %ldx%ld", width, height);
|
||||||
|
@ -371,12 +371,13 @@ int main(int argc, char **argv) {
|
||||||
|
|
||||||
// Bitrates per spatial layer: overwrite default rates above.
|
// Bitrates per spatial layer: overwrite default rates above.
|
||||||
for (i = 0; i < NUM_ENCODERS; i++) {
|
for (i = 0; i < NUM_ENCODERS; i++) {
|
||||||
target_bitrate[i] = strtol(argv[NUM_ENCODERS + 5 + i], NULL, 0);
|
target_bitrate[i] = (int)strtol(argv[NUM_ENCODERS + 5 + i], NULL, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Temporal layers per spatial layers: overwrite default settings above.
|
// Temporal layers per spatial layers: overwrite default settings above.
|
||||||
for (i = 0; i < NUM_ENCODERS; i++) {
|
for (i = 0; i < NUM_ENCODERS; i++) {
|
||||||
num_temporal_layers[i] = strtol(argv[2 * NUM_ENCODERS + 5 + i], NULL, 0);
|
num_temporal_layers[i] =
|
||||||
|
(int)strtol(argv[2 * NUM_ENCODERS + 5 + i], NULL, 0);
|
||||||
if (num_temporal_layers[i] < 1 || num_temporal_layers[i] > 3)
|
if (num_temporal_layers[i] < 1 || num_temporal_layers[i] > 3)
|
||||||
die("Invalid temporal layers: %d, Must be 1, 2, or 3. \n",
|
die("Invalid temporal layers: %d, Must be 1, 2, or 3. \n",
|
||||||
num_temporal_layers);
|
num_temporal_layers);
|
||||||
|
@ -391,9 +392,9 @@ int main(int argc, char **argv) {
|
||||||
downsampled_input[i] = fopen(filename, "wb");
|
downsampled_input[i] = fopen(filename, "wb");
|
||||||
}
|
}
|
||||||
|
|
||||||
key_frame_insert = strtol(argv[3 * NUM_ENCODERS + 5], NULL, 0);
|
key_frame_insert = (int)strtol(argv[3 * NUM_ENCODERS + 5], NULL, 0);
|
||||||
|
|
||||||
show_psnr = strtol(argv[3 * NUM_ENCODERS + 6], NULL, 0);
|
show_psnr = (int)strtol(argv[3 * NUM_ENCODERS + 6], NULL, 0);
|
||||||
|
|
||||||
/* Populate default encoder configuration */
|
/* Populate default encoder configuration */
|
||||||
for (i = 0; i < NUM_ENCODERS; i++) {
|
for (i = 0; i < NUM_ENCODERS; i++) {
|
||||||
|
@ -460,7 +461,7 @@ int main(int argc, char **argv) {
|
||||||
|
|
||||||
// Set the number of threads per encode/spatial layer.
|
// Set the number of threads per encode/spatial layer.
|
||||||
// (1, 1, 1) means no encoder threading.
|
// (1, 1, 1) means no encoder threading.
|
||||||
cfg[0].g_threads = 2;
|
cfg[0].g_threads = 1;
|
||||||
cfg[1].g_threads = 1;
|
cfg[1].g_threads = 1;
|
||||||
cfg[2].g_threads = 1;
|
cfg[2].g_threads = 1;
|
||||||
|
|
||||||
|
@ -469,7 +470,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))
|
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);
|
die("Failed to allocate image", cfg[i].g_w, cfg[i].g_h);
|
||||||
|
|
||||||
if (raw[0].stride[VPX_PLANE_Y] == raw[0].d_w)
|
if (raw[0].stride[VPX_PLANE_Y] == (int)raw[0].d_w)
|
||||||
read_frame_p = read_frame;
|
read_frame_p = read_frame;
|
||||||
else
|
else
|
||||||
read_frame_p = read_frame_by_row;
|
read_frame_p = read_frame_by_row;
|
||||||
|
@ -507,9 +508,11 @@ int main(int argc, char **argv) {
|
||||||
|
|
||||||
/* Set NOISE_SENSITIVITY to do TEMPORAL_DENOISING */
|
/* Set NOISE_SENSITIVITY to do TEMPORAL_DENOISING */
|
||||||
/* Enable denoising for the highest-resolution encoder. */
|
/* Enable denoising for the highest-resolution encoder. */
|
||||||
if (vpx_codec_control(&codec[0], VP8E_SET_NOISE_SENSITIVITY, 4))
|
if (vpx_codec_control(&codec[0], VP8E_SET_NOISE_SENSITIVITY, 1))
|
||||||
die_codec(&codec[0], "Failed to set noise_sensitivity");
|
die_codec(&codec[0], "Failed to set noise_sensitivity");
|
||||||
for (i = 1; i < NUM_ENCODERS; i++) {
|
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++) {
|
||||||
if (vpx_codec_control(&codec[i], VP8E_SET_NOISE_SENSITIVITY, 0))
|
if (vpx_codec_control(&codec[i], VP8E_SET_NOISE_SENSITIVITY, 0))
|
||||||
die_codec(&codec[i], "Failed to set noise_sensitivity");
|
die_codec(&codec[i], "Failed to set noise_sensitivity");
|
||||||
}
|
}
|
||||||
|
@ -556,7 +559,8 @@ int main(int argc, char **argv) {
|
||||||
/* Write out down-sampled input. */
|
/* Write out down-sampled input. */
|
||||||
length_frame = cfg[i].g_w * cfg[i].g_h * 3 / 2;
|
length_frame = cfg[i].g_w * cfg[i].g_h * 3 / 2;
|
||||||
if (fwrite(raw[i].planes[0], 1, length_frame,
|
if (fwrite(raw[i].planes[0], 1, length_frame,
|
||||||
downsampled_input[NUM_ENCODERS - i - 1]) != length_frame) {
|
downsampled_input[NUM_ENCODERS - i - 1]) !=
|
||||||
|
(unsigned int)length_frame) {
|
||||||
return EXIT_FAILURE;
|
return EXIT_FAILURE;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -617,10 +621,6 @@ int main(int argc, char **argv) {
|
||||||
break;
|
break;
|
||||||
default: break;
|
default: break;
|
||||||
}
|
}
|
||||||
printf(pkt[i]->kind == VPX_CODEC_CX_FRAME_PKT &&
|
|
||||||
(pkt[i]->data.frame.flags & VPX_FRAME_IS_KEY)
|
|
||||||
? "K"
|
|
||||||
: "");
|
|
||||||
fflush(stdout);
|
fflush(stdout);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -661,7 +661,6 @@ int main(int argc, char **argv) {
|
||||||
write_ivf_file_header(outfile[i], &cfg[i], frame_cnt - 1);
|
write_ivf_file_header(outfile[i], &cfg[i], frame_cnt - 1);
|
||||||
fclose(outfile[i]);
|
fclose(outfile[i]);
|
||||||
}
|
}
|
||||||
printf("\n");
|
|
||||||
|
|
||||||
return EXIT_SUCCESS;
|
return EXIT_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
|
@ -84,6 +84,8 @@ static const arg_def_t speed_arg =
|
||||||
ARG_DEF("sp", "speed", 1, "speed configuration");
|
ARG_DEF("sp", "speed", 1, "speed configuration");
|
||||||
static const arg_def_t aqmode_arg =
|
static const arg_def_t aqmode_arg =
|
||||||
ARG_DEF("aq", "aqmode", 1, "aq-mode off/on");
|
ARG_DEF("aq", "aqmode", 1, "aq-mode off/on");
|
||||||
|
static const arg_def_t bitrates_arg =
|
||||||
|
ARG_DEF("bl", "bitrates", 1, "bitrates[sl * num_tl + tl]");
|
||||||
|
|
||||||
#if CONFIG_VP9_HIGHBITDEPTH
|
#if CONFIG_VP9_HIGHBITDEPTH
|
||||||
static const struct arg_enum_list bitdepth_enum[] = {
|
static const struct arg_enum_list bitdepth_enum[] = {
|
||||||
|
@ -124,6 +126,7 @@ static const arg_def_t *svc_args[] = { &frames_arg,
|
||||||
#endif
|
#endif
|
||||||
&speed_arg,
|
&speed_arg,
|
||||||
&rc_end_usage_arg,
|
&rc_end_usage_arg,
|
||||||
|
&bitrates_arg,
|
||||||
NULL };
|
NULL };
|
||||||
|
|
||||||
static const uint32_t default_frames_to_skip = 0;
|
static const uint32_t default_frames_to_skip = 0;
|
||||||
|
@ -165,7 +168,7 @@ void usage_exit(void) {
|
||||||
static void parse_command_line(int argc, const char **argv_,
|
static void parse_command_line(int argc, const char **argv_,
|
||||||
AppInput *app_input, SvcContext *svc_ctx,
|
AppInput *app_input, SvcContext *svc_ctx,
|
||||||
vpx_codec_enc_cfg_t *enc_cfg) {
|
vpx_codec_enc_cfg_t *enc_cfg) {
|
||||||
struct arg arg = { 0 };
|
struct arg arg;
|
||||||
char **argv = NULL;
|
char **argv = NULL;
|
||||||
char **argi = NULL;
|
char **argi = NULL;
|
||||||
char **argj = NULL;
|
char **argj = NULL;
|
||||||
|
@ -250,6 +253,9 @@ static void parse_command_line(int argc, const char **argv_,
|
||||||
} else if (arg_match(&arg, &scale_factors_arg, argi)) {
|
} else if (arg_match(&arg, &scale_factors_arg, argi)) {
|
||||||
snprintf(string_options, sizeof(string_options), "%s scale-factors=%s",
|
snprintf(string_options, sizeof(string_options), "%s scale-factors=%s",
|
||||||
string_options, arg.val);
|
string_options, arg.val);
|
||||||
|
} else if (arg_match(&arg, &bitrates_arg, argi)) {
|
||||||
|
snprintf(string_options, sizeof(string_options), "%s bitrates=%s",
|
||||||
|
string_options, arg.val);
|
||||||
} else if (arg_match(&arg, &passes_arg, argi)) {
|
} else if (arg_match(&arg, &passes_arg, argi)) {
|
||||||
passes = arg_parse_uint(&arg);
|
passes = arg_parse_uint(&arg);
|
||||||
if (passes < 1 || passes > 2) {
|
if (passes < 1 || passes > 2) {
|
||||||
|
@ -417,7 +423,6 @@ static void set_rate_control_stats(struct RateControlStats *rc,
|
||||||
for (sl = 0; sl < cfg->ss_number_layers; ++sl) {
|
for (sl = 0; sl < cfg->ss_number_layers; ++sl) {
|
||||||
for (tl = 0; tl < cfg->ts_number_layers; ++tl) {
|
for (tl = 0; tl < cfg->ts_number_layers; ++tl) {
|
||||||
const int layer = sl * cfg->ts_number_layers + tl;
|
const int layer = sl * cfg->ts_number_layers + tl;
|
||||||
const int tlayer0 = sl * cfg->ts_number_layers;
|
|
||||||
if (cfg->ts_number_layers == 1)
|
if (cfg->ts_number_layers == 1)
|
||||||
rc->layer_framerate[layer] = framerate;
|
rc->layer_framerate[layer] = framerate;
|
||||||
else
|
else
|
||||||
|
@ -428,8 +433,8 @@ static void set_rate_control_stats(struct RateControlStats *rc,
|
||||||
cfg->layer_target_bitrate[layer - 1]) /
|
cfg->layer_target_bitrate[layer - 1]) /
|
||||||
(rc->layer_framerate[layer] - rc->layer_framerate[layer - 1]);
|
(rc->layer_framerate[layer] - rc->layer_framerate[layer - 1]);
|
||||||
} else {
|
} else {
|
||||||
rc->layer_pfb[tlayer0] = 1000.0 * cfg->layer_target_bitrate[tlayer0] /
|
rc->layer_pfb[layer] = 1000.0 * cfg->layer_target_bitrate[layer] /
|
||||||
rc->layer_framerate[tlayer0];
|
rc->layer_framerate[layer];
|
||||||
}
|
}
|
||||||
rc->layer_input_frames[layer] = 0;
|
rc->layer_input_frames[layer] = 0;
|
||||||
rc->layer_enc_frames[layer] = 0;
|
rc->layer_enc_frames[layer] = 0;
|
||||||
|
@ -449,12 +454,13 @@ static void printout_rate_control_summary(struct RateControlStats *rc,
|
||||||
vpx_codec_enc_cfg_t *cfg,
|
vpx_codec_enc_cfg_t *cfg,
|
||||||
int frame_cnt) {
|
int frame_cnt) {
|
||||||
unsigned int sl, tl;
|
unsigned int sl, tl;
|
||||||
int tot_num_frames = 0;
|
|
||||||
double perc_fluctuation = 0.0;
|
double perc_fluctuation = 0.0;
|
||||||
|
int tot_num_frames = 0;
|
||||||
printf("Total number of processed frames: %d\n\n", frame_cnt - 1);
|
printf("Total number of processed frames: %d\n\n", frame_cnt - 1);
|
||||||
printf("Rate control layer stats for sl%d tl%d layer(s):\n\n",
|
printf("Rate control layer stats for sl%d tl%d layer(s):\n\n",
|
||||||
cfg->ss_number_layers, cfg->ts_number_layers);
|
cfg->ss_number_layers, cfg->ts_number_layers);
|
||||||
for (sl = 0; sl < cfg->ss_number_layers; ++sl) {
|
for (sl = 0; sl < cfg->ss_number_layers; ++sl) {
|
||||||
|
tot_num_frames = 0;
|
||||||
for (tl = 0; tl < cfg->ts_number_layers; ++tl) {
|
for (tl = 0; tl < cfg->ts_number_layers; ++tl) {
|
||||||
const int layer = sl * cfg->ts_number_layers + tl;
|
const int layer = sl * cfg->ts_number_layers + tl;
|
||||||
const int num_dropped =
|
const int num_dropped =
|
||||||
|
@ -462,7 +468,7 @@ static void printout_rate_control_summary(struct RateControlStats *rc,
|
||||||
? (rc->layer_input_frames[layer] - rc->layer_enc_frames[layer])
|
? (rc->layer_input_frames[layer] - rc->layer_enc_frames[layer])
|
||||||
: (rc->layer_input_frames[layer] - rc->layer_enc_frames[layer] -
|
: (rc->layer_input_frames[layer] - rc->layer_enc_frames[layer] -
|
||||||
1);
|
1);
|
||||||
if (!sl) tot_num_frames += rc->layer_input_frames[layer];
|
tot_num_frames += rc->layer_input_frames[layer];
|
||||||
rc->layer_encoding_bitrate[layer] = 0.001 * rc->layer_framerate[layer] *
|
rc->layer_encoding_bitrate[layer] = 0.001 * rc->layer_framerate[layer] *
|
||||||
rc->layer_encoding_bitrate[layer] /
|
rc->layer_encoding_bitrate[layer] /
|
||||||
tot_num_frames;
|
tot_num_frames;
|
||||||
|
@ -503,7 +509,7 @@ static void printout_rate_control_summary(struct RateControlStats *rc,
|
||||||
}
|
}
|
||||||
|
|
||||||
vpx_codec_err_t parse_superframe_index(const uint8_t *data, size_t data_sz,
|
vpx_codec_err_t parse_superframe_index(const uint8_t *data, size_t data_sz,
|
||||||
uint32_t sizes[8], int *count) {
|
uint64_t sizes[8], int *count) {
|
||||||
// A chunk ending with a byte matching 0xc0 is an invalid chunk unless
|
// 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
|
// 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
|
// data is 0xc0 the encoder must add a 0 byte. If we have the marker but
|
||||||
|
@ -600,9 +606,9 @@ void set_frame_flags_bypass_mode(int sl, int tl, int num_spatial_layers,
|
||||||
}
|
}
|
||||||
|
|
||||||
int main(int argc, const char **argv) {
|
int main(int argc, const char **argv) {
|
||||||
AppInput app_input = { 0 };
|
AppInput app_input;
|
||||||
VpxVideoWriter *writer = NULL;
|
VpxVideoWriter *writer = NULL;
|
||||||
VpxVideoInfo info = { 0 };
|
VpxVideoInfo info;
|
||||||
vpx_codec_ctx_t codec;
|
vpx_codec_ctx_t codec;
|
||||||
vpx_codec_enc_cfg_t enc_cfg;
|
vpx_codec_enc_cfg_t enc_cfg;
|
||||||
SvcContext svc_ctx;
|
SvcContext svc_ctx;
|
||||||
|
@ -620,7 +626,7 @@ int main(int argc, const char **argv) {
|
||||||
struct RateControlStats rc;
|
struct RateControlStats rc;
|
||||||
vpx_svc_layer_id_t layer_id;
|
vpx_svc_layer_id_t layer_id;
|
||||||
vpx_svc_ref_frame_config_t ref_frame_config;
|
vpx_svc_ref_frame_config_t ref_frame_config;
|
||||||
int sl, tl;
|
unsigned int sl, tl;
|
||||||
double sum_bitrate = 0.0;
|
double sum_bitrate = 0.0;
|
||||||
double sum_bitrate2 = 0.0;
|
double sum_bitrate2 = 0.0;
|
||||||
double framerate = 30.0;
|
double framerate = 30.0;
|
||||||
|
@ -634,8 +640,9 @@ int main(int argc, const char **argv) {
|
||||||
|
|
||||||
// Allocate image buffer
|
// Allocate image buffer
|
||||||
#if CONFIG_VP9_HIGHBITDEPTH
|
#if CONFIG_VP9_HIGHBITDEPTH
|
||||||
if (!vpx_img_alloc(&raw, enc_cfg.g_input_bit_depth == 8 ? VPX_IMG_FMT_I420
|
if (!vpx_img_alloc(&raw,
|
||||||
: VPX_IMG_FMT_I42016,
|
enc_cfg.g_input_bit_depth == 8 ? VPX_IMG_FMT_I420
|
||||||
|
: VPX_IMG_FMT_I42016,
|
||||||
enc_cfg.g_w, enc_cfg.g_h, 32)) {
|
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);
|
die("Failed to allocate image %dx%d\n", enc_cfg.g_w, enc_cfg.g_h);
|
||||||
}
|
}
|
||||||
|
@ -673,7 +680,7 @@ int main(int argc, const char **argv) {
|
||||||
}
|
}
|
||||||
#if OUTPUT_RC_STATS
|
#if OUTPUT_RC_STATS
|
||||||
// For now, just write temporal layer streams.
|
// For now, just write temporal layer streams.
|
||||||
// TODO(wonkap): do spatial by re-writing superframe.
|
// TODO(marpan): do spatial by re-writing superframe.
|
||||||
if (svc_ctx.output_rc_stat) {
|
if (svc_ctx.output_rc_stat) {
|
||||||
for (tl = 0; tl < enc_cfg.ts_number_layers; ++tl) {
|
for (tl = 0; tl < enc_cfg.ts_number_layers; ++tl) {
|
||||||
char file_name[PATH_MAX];
|
char file_name[PATH_MAX];
|
||||||
|
@ -691,10 +698,18 @@ int main(int argc, const char **argv) {
|
||||||
|
|
||||||
if (svc_ctx.speed != -1)
|
if (svc_ctx.speed != -1)
|
||||||
vpx_codec_control(&codec, VP8E_SET_CPUUSED, svc_ctx.speed);
|
vpx_codec_control(&codec, VP8E_SET_CPUUSED, svc_ctx.speed);
|
||||||
if (svc_ctx.threads)
|
if (svc_ctx.threads) {
|
||||||
vpx_codec_control(&codec, VP9E_SET_TILE_COLUMNS, (svc_ctx.threads >> 1));
|
vpx_codec_control(&codec, VP9E_SET_TILE_COLUMNS, (svc_ctx.threads >> 1));
|
||||||
|
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.speed >= 5 && svc_ctx.aqmode == 1)
|
if (svc_ctx.speed >= 5 && svc_ctx.aqmode == 1)
|
||||||
vpx_codec_control(&codec, VP9E_SET_AQ_MODE, 3);
|
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);
|
||||||
|
|
||||||
// Encode frames
|
// Encode frames
|
||||||
while (!end_of_stream) {
|
while (!end_of_stream) {
|
||||||
|
@ -730,7 +745,7 @@ int main(int argc, const char **argv) {
|
||||||
&ref_frame_config);
|
&ref_frame_config);
|
||||||
// Keep track of input frames, to account for frame drops in rate control
|
// Keep track of input frames, to account for frame drops in rate control
|
||||||
// stats/metrics.
|
// stats/metrics.
|
||||||
for (sl = 0; sl < enc_cfg.ss_number_layers; ++sl) {
|
for (sl = 0; sl < (unsigned int)enc_cfg.ss_number_layers; ++sl) {
|
||||||
++rc.layer_input_frames[sl * enc_cfg.ts_number_layers +
|
++rc.layer_input_frames[sl * enc_cfg.ts_number_layers +
|
||||||
layer_id.temporal_layer_id];
|
layer_id.temporal_layer_id];
|
||||||
}
|
}
|
||||||
|
@ -755,18 +770,20 @@ int main(int argc, const char **argv) {
|
||||||
SvcInternal_t *const si = (SvcInternal_t *)svc_ctx.internal;
|
SvcInternal_t *const si = (SvcInternal_t *)svc_ctx.internal;
|
||||||
if (cx_pkt->data.frame.sz > 0) {
|
if (cx_pkt->data.frame.sz > 0) {
|
||||||
#if OUTPUT_RC_STATS
|
#if OUTPUT_RC_STATS
|
||||||
uint32_t sizes[8];
|
uint64_t sizes[8];
|
||||||
int count = 0;
|
int count = 0;
|
||||||
#endif
|
#endif
|
||||||
vpx_video_writer_write_frame(writer, cx_pkt->data.frame.buf,
|
vpx_video_writer_write_frame(writer, cx_pkt->data.frame.buf,
|
||||||
cx_pkt->data.frame.sz,
|
cx_pkt->data.frame.sz,
|
||||||
cx_pkt->data.frame.pts);
|
cx_pkt->data.frame.pts);
|
||||||
#if OUTPUT_RC_STATS
|
#if OUTPUT_RC_STATS
|
||||||
// TODO(marpan/wonkap): Put this (to line728) in separate function.
|
// TODO(marpan): Put this (to line728) in separate function.
|
||||||
if (svc_ctx.output_rc_stat) {
|
if (svc_ctx.output_rc_stat) {
|
||||||
vpx_codec_control(&codec, VP9E_GET_SVC_LAYER_ID, &layer_id);
|
vpx_codec_control(&codec, VP9E_GET_SVC_LAYER_ID, &layer_id);
|
||||||
parse_superframe_index(cx_pkt->data.frame.buf,
|
parse_superframe_index(cx_pkt->data.frame.buf,
|
||||||
cx_pkt->data.frame.sz, sizes, &count);
|
cx_pkt->data.frame.sz, sizes, &count);
|
||||||
|
if (enc_cfg.ss_number_layers == 1)
|
||||||
|
sizes[0] = cx_pkt->data.frame.sz;
|
||||||
// Note computing input_layer_frames here won't account for frame
|
// Note computing input_layer_frames here won't account for frame
|
||||||
// drops in rate control stats.
|
// drops in rate control stats.
|
||||||
// TODO(marpan): Fix this for non-bypass mode so we can get stats
|
// TODO(marpan): Fix this for non-bypass mode so we can get stats
|
||||||
|
@ -793,7 +810,7 @@ int main(int argc, const char **argv) {
|
||||||
rc.layer_encoding_bitrate[layer] += 8.0 * sizes[sl];
|
rc.layer_encoding_bitrate[layer] += 8.0 * sizes[sl];
|
||||||
// Keep count of rate control stats per layer, for non-key
|
// Keep count of rate control stats per layer, for non-key
|
||||||
// frames.
|
// frames.
|
||||||
if (tl == layer_id.temporal_layer_id &&
|
if (tl == (unsigned int)layer_id.temporal_layer_id &&
|
||||||
!(cx_pkt->data.frame.flags & VPX_FRAME_IS_KEY)) {
|
!(cx_pkt->data.frame.flags & VPX_FRAME_IS_KEY)) {
|
||||||
rc.layer_avg_frame_size[layer] += 8.0 * sizes[sl];
|
rc.layer_avg_frame_size[layer] += 8.0 * sizes[sl];
|
||||||
rc.layer_avg_rate_mismatch[layer] +=
|
rc.layer_avg_rate_mismatch[layer] +=
|
||||||
|
@ -807,7 +824,7 @@ int main(int argc, const char **argv) {
|
||||||
// Update for short-time encoding bitrate states, for moving
|
// Update for short-time encoding bitrate states, for moving
|
||||||
// window of size rc->window, shifted by rc->window / 2.
|
// window of size rc->window, shifted by rc->window / 2.
|
||||||
// Ignore first window segment, due to key frame.
|
// Ignore first window segment, due to key frame.
|
||||||
if (frame_cnt > rc.window_size) {
|
if (frame_cnt > (unsigned int)rc.window_size) {
|
||||||
tl = layer_id.temporal_layer_id;
|
tl = layer_id.temporal_layer_id;
|
||||||
for (sl = 0; sl < enc_cfg.ss_number_layers; ++sl) {
|
for (sl = 0; sl < enc_cfg.ss_number_layers; ++sl) {
|
||||||
sum_bitrate += 0.001 * 8.0 * sizes[sl] * framerate;
|
sum_bitrate += 0.001 * 8.0 * sizes[sl] * framerate;
|
||||||
|
@ -823,13 +840,14 @@ int main(int argc, const char **argv) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Second shifted window.
|
// Second shifted window.
|
||||||
if (frame_cnt > rc.window_size + rc.window_size / 2) {
|
if (frame_cnt >
|
||||||
|
(unsigned int)(rc.window_size + rc.window_size / 2)) {
|
||||||
tl = layer_id.temporal_layer_id;
|
tl = layer_id.temporal_layer_id;
|
||||||
for (sl = 0; sl < enc_cfg.ss_number_layers; ++sl) {
|
for (sl = 0; sl < enc_cfg.ss_number_layers; ++sl) {
|
||||||
sum_bitrate2 += 0.001 * 8.0 * sizes[sl] * framerate;
|
sum_bitrate2 += 0.001 * 8.0 * sizes[sl] * framerate;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (frame_cnt > 2 * rc.window_size &&
|
if (frame_cnt > (unsigned int)(2 * rc.window_size) &&
|
||||||
frame_cnt % rc.window_size == 0) {
|
frame_cnt % rc.window_size == 0) {
|
||||||
rc.window_count += 1;
|
rc.window_count += 1;
|
||||||
rc.avg_st_encoding_bitrate += sum_bitrate2 / rc.window_size;
|
rc.avg_st_encoding_bitrate += sum_bitrate2 / rc.window_size;
|
||||||
|
@ -842,10 +860,11 @@ int main(int argc, const char **argv) {
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
/*
|
||||||
printf("SVC frame: %d, kf: %d, size: %d, pts: %d\n", frames_received,
|
printf("SVC frame: %d, kf: %d, size: %d, pts: %d\n", frames_received,
|
||||||
!!(cx_pkt->data.frame.flags & VPX_FRAME_IS_KEY),
|
!!(cx_pkt->data.frame.flags & VPX_FRAME_IS_KEY),
|
||||||
(int)cx_pkt->data.frame.sz, (int)cx_pkt->data.frame.pts);
|
(int)cx_pkt->data.frame.sz, (int)cx_pkt->data.frame.pts);
|
||||||
|
*/
|
||||||
if (enc_cfg.ss_number_layers == 1 && enc_cfg.ts_number_layers == 1)
|
if (enc_cfg.ss_number_layers == 1 && enc_cfg.ts_number_layers == 1)
|
||||||
si->bytes_sum[0] += (int)cx_pkt->data.frame.sz;
|
si->bytes_sum[0] += (int)cx_pkt->data.frame.sz;
|
||||||
++frames_received;
|
++frames_received;
|
||||||
|
|
|
@ -304,6 +304,7 @@ int main(int argc, char **argv) {
|
||||||
const char *height_arg = NULL;
|
const char *height_arg = NULL;
|
||||||
const char *infile_arg = NULL;
|
const char *infile_arg = NULL;
|
||||||
const char *outfile_arg = NULL;
|
const char *outfile_arg = NULL;
|
||||||
|
const char *update_frame_num_arg = NULL;
|
||||||
unsigned int limit = 0;
|
unsigned int limit = 0;
|
||||||
|
|
||||||
vp9_zero(ecodec);
|
vp9_zero(ecodec);
|
||||||
|
@ -318,18 +319,21 @@ int main(int argc, char **argv) {
|
||||||
height_arg = argv[2];
|
height_arg = argv[2];
|
||||||
infile_arg = argv[3];
|
infile_arg = argv[3];
|
||||||
outfile_arg = argv[4];
|
outfile_arg = argv[4];
|
||||||
|
update_frame_num_arg = argv[5];
|
||||||
|
|
||||||
encoder = get_vpx_encoder_by_name("vp9");
|
encoder = get_vpx_encoder_by_name("vp9");
|
||||||
if (!encoder) die("Unsupported codec.");
|
if (!encoder) die("Unsupported codec.");
|
||||||
|
|
||||||
update_frame_num = atoi(argv[5]);
|
update_frame_num = (unsigned int)strtoul(update_frame_num_arg, NULL, 0);
|
||||||
// In VP9, the reference buffers (cm->buffer_pool->frame_bufs[i].buf) are
|
// In VP9, the reference buffers (cm->buffer_pool->frame_bufs[i].buf) are
|
||||||
// allocated while calling vpx_codec_encode(), thus, setting reference for
|
// allocated while calling vpx_codec_encode(), thus, setting reference for
|
||||||
// 1st frame isn't supported.
|
// 1st frame isn't supported.
|
||||||
if (update_frame_num <= 1) die("Couldn't parse frame number '%s'\n", argv[5]);
|
if (update_frame_num <= 1) {
|
||||||
|
die("Couldn't parse frame number '%s'\n", update_frame_num_arg);
|
||||||
|
}
|
||||||
|
|
||||||
if (argc > 6) {
|
if (argc > 6) {
|
||||||
limit = atoi(argv[6]);
|
limit = (unsigned int)strtoul(argv[6], NULL, 0);
|
||||||
if (update_frame_num > limit)
|
if (update_frame_num > limit)
|
||||||
die("Update frame number couldn't larger than limit\n");
|
die("Update frame number couldn't larger than limit\n");
|
||||||
}
|
}
|
||||||
|
|
|
@ -26,17 +26,27 @@
|
||||||
#include "../tools_common.h"
|
#include "../tools_common.h"
|
||||||
#include "../video_writer.h"
|
#include "../video_writer.h"
|
||||||
|
|
||||||
|
#define VP8_ROI_MAP 0
|
||||||
|
|
||||||
static const char *exec_name;
|
static const char *exec_name;
|
||||||
|
|
||||||
void usage_exit(void) { exit(EXIT_FAILURE); }
|
void usage_exit(void) { exit(EXIT_FAILURE); }
|
||||||
|
|
||||||
// Denoiser states, for temporal denoising.
|
// Denoiser states for vp8, for temporal denoising.
|
||||||
enum denoiserState {
|
enum denoiserStateVp8 {
|
||||||
kDenoiserOff,
|
kVp8DenoiserOff,
|
||||||
kDenoiserOnYOnly,
|
kVp8DenoiserOnYOnly,
|
||||||
kDenoiserOnYUV,
|
kVp8DenoiserOnYUV,
|
||||||
kDenoiserOnYUVAggressive,
|
kVp8DenoiserOnYUVAggressive,
|
||||||
kDenoiserOnAdaptive
|
kVp8DenoiserOnAdaptive
|
||||||
|
};
|
||||||
|
|
||||||
|
// Denoiser states for vp9, for temporal denoising.
|
||||||
|
enum denoiserStateVp9 {
|
||||||
|
kVp9DenoiserOff,
|
||||||
|
kVp9DenoiserOnYOnly,
|
||||||
|
// For SVC: denoise the top two spatial layers.
|
||||||
|
kVp9DenoiserOnYTwoSpatialLayers
|
||||||
};
|
};
|
||||||
|
|
||||||
static int mode_to_num_layers[13] = { 1, 2, 2, 3, 3, 3, 3, 5, 2, 3, 3, 3, 3 };
|
static int mode_to_num_layers[13] = { 1, 2, 2, 3, 3, 3, 3, 5, 2, 3, 3, 3, 3 };
|
||||||
|
@ -154,6 +164,53 @@ static void printout_rate_control_summary(struct RateControlMetrics *rc,
|
||||||
die("Error: Number of input frames not equal to output! \n");
|
die("Error: Number of input frames not equal to output! \n");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if VP8_ROI_MAP
|
||||||
|
static void vp8_set_roi_map(vpx_codec_enc_cfg_t *cfg, vpx_roi_map_t *roi) {
|
||||||
|
unsigned int i, j;
|
||||||
|
memset(roi, 0, sizeof(*roi));
|
||||||
|
|
||||||
|
// ROI is based on the segments (4 for vp8, 8 for vp9), smallest unit for
|
||||||
|
// segment is 16x16 for vp8, 8x8 for vp9.
|
||||||
|
roi->rows = (cfg->g_h + 15) / 16;
|
||||||
|
roi->cols = (cfg->g_w + 15) / 16;
|
||||||
|
|
||||||
|
// Applies delta QP on the segment blocks, varies from -63 to 63.
|
||||||
|
// Setting to negative means lower QP (better quality).
|
||||||
|
// Below we set delta_q to the extreme (-63) to show strong effect.
|
||||||
|
roi->delta_q[0] = 0;
|
||||||
|
roi->delta_q[1] = -63;
|
||||||
|
roi->delta_q[2] = 0;
|
||||||
|
roi->delta_q[3] = 0;
|
||||||
|
|
||||||
|
// Applies delta loopfilter strength on the segment blocks, varies from -63 to
|
||||||
|
// 63. Setting to positive means stronger loopfilter.
|
||||||
|
roi->delta_lf[0] = 0;
|
||||||
|
roi->delta_lf[1] = 0;
|
||||||
|
roi->delta_lf[2] = 0;
|
||||||
|
roi->delta_lf[3] = 0;
|
||||||
|
|
||||||
|
// Applies skip encoding threshold on the segment blocks, varies from 0 to
|
||||||
|
// UINT_MAX. Larger value means more skipping of encoding is possible.
|
||||||
|
// This skip threshold only applies on delta frames.
|
||||||
|
roi->static_threshold[0] = 0;
|
||||||
|
roi->static_threshold[1] = 0;
|
||||||
|
roi->static_threshold[2] = 0;
|
||||||
|
roi->static_threshold[3] = 0;
|
||||||
|
|
||||||
|
// 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:
|
// Temporal scaling parameters:
|
||||||
// NOTE: The 3 prediction frames cannot be used interchangeably due to
|
// NOTE: The 3 prediction frames cannot be used interchangeably due to
|
||||||
// differences in the way they are handled throughout the code. The
|
// differences in the way they are handled throughout the code. The
|
||||||
|
@ -495,6 +552,7 @@ int main(int argc, char **argv) {
|
||||||
vpx_codec_err_t res;
|
vpx_codec_err_t res;
|
||||||
unsigned int width;
|
unsigned int width;
|
||||||
unsigned int height;
|
unsigned int height;
|
||||||
|
uint32_t error_resilient = 0;
|
||||||
int speed;
|
int speed;
|
||||||
int frame_avail;
|
int frame_avail;
|
||||||
int got_data;
|
int got_data;
|
||||||
|
@ -505,16 +563,15 @@ int main(int argc, char **argv) {
|
||||||
int layering_mode = 0;
|
int layering_mode = 0;
|
||||||
int layer_flags[VPX_TS_MAX_PERIODICITY] = { 0 };
|
int layer_flags[VPX_TS_MAX_PERIODICITY] = { 0 };
|
||||||
int flag_periodicity = 1;
|
int flag_periodicity = 1;
|
||||||
#if VPX_ENCODER_ABI_VERSION > (4 + VPX_CODEC_ABI_VERSION)
|
#if VP8_ROI_MAP
|
||||||
vpx_svc_layer_id_t layer_id = { 0, 0 };
|
vpx_roi_map_t roi;
|
||||||
#else
|
|
||||||
vpx_svc_layer_id_t layer_id = { 0 };
|
|
||||||
#endif
|
#endif
|
||||||
|
vpx_svc_layer_id_t layer_id = { 0, 0 };
|
||||||
const VpxInterface *encoder = NULL;
|
const VpxInterface *encoder = NULL;
|
||||||
FILE *infile = NULL;
|
FILE *infile = NULL;
|
||||||
struct RateControlMetrics rc;
|
struct RateControlMetrics rc;
|
||||||
int64_t cx_time = 0;
|
int64_t cx_time = 0;
|
||||||
const int min_args_base = 11;
|
const int min_args_base = 13;
|
||||||
#if CONFIG_VP9_HIGHBITDEPTH
|
#if CONFIG_VP9_HIGHBITDEPTH
|
||||||
vpx_bit_depth_t bit_depth = VPX_BITS_8;
|
vpx_bit_depth_t bit_depth = VPX_BITS_8;
|
||||||
int input_bit_depth = 8;
|
int input_bit_depth = 8;
|
||||||
|
@ -531,12 +588,14 @@ int main(int argc, char **argv) {
|
||||||
if (argc < min_args) {
|
if (argc < min_args) {
|
||||||
#if CONFIG_VP9_HIGHBITDEPTH
|
#if CONFIG_VP9_HIGHBITDEPTH
|
||||||
die("Usage: %s <infile> <outfile> <codec_type(vp8/vp9)> <width> <height> "
|
die("Usage: %s <infile> <outfile> <codec_type(vp8/vp9)> <width> <height> "
|
||||||
"<rate_num> <rate_den> <speed> <frame_drop_threshold> <mode> "
|
"<rate_num> <rate_den> <speed> <frame_drop_threshold> "
|
||||||
|
"<error_resilient> <threads> <mode> "
|
||||||
"<Rate_0> ... <Rate_nlayers-1> <bit-depth> \n",
|
"<Rate_0> ... <Rate_nlayers-1> <bit-depth> \n",
|
||||||
argv[0]);
|
argv[0]);
|
||||||
#else
|
#else
|
||||||
die("Usage: %s <infile> <outfile> <codec_type(vp8/vp9)> <width> <height> "
|
die("Usage: %s <infile> <outfile> <codec_type(vp8/vp9)> <width> <height> "
|
||||||
"<rate_num> <rate_den> <speed> <frame_drop_threshold> <mode> "
|
"<rate_num> <rate_den> <speed> <frame_drop_threshold> "
|
||||||
|
"<error_resilient> <threads> <mode> "
|
||||||
"<Rate_0> ... <Rate_nlayers-1> \n",
|
"<Rate_0> ... <Rate_nlayers-1> \n",
|
||||||
argv[0]);
|
argv[0]);
|
||||||
#endif // CONFIG_VP9_HIGHBITDEPTH
|
#endif // CONFIG_VP9_HIGHBITDEPTH
|
||||||
|
@ -553,9 +612,9 @@ int main(int argc, char **argv) {
|
||||||
die("Invalid resolution: %d x %d", width, height);
|
die("Invalid resolution: %d x %d", width, height);
|
||||||
}
|
}
|
||||||
|
|
||||||
layering_mode = (int)strtol(argv[10], NULL, 0);
|
layering_mode = (int)strtol(argv[12], NULL, 0);
|
||||||
if (layering_mode < 0 || layering_mode > 13) {
|
if (layering_mode < 0 || layering_mode > 13) {
|
||||||
die("Invalid layering mode (0..12) %s", argv[10]);
|
die("Invalid layering mode (0..12) %s", argv[12]);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (argc != min_args + mode_to_num_layers[layering_mode]) {
|
if (argc != min_args + mode_to_num_layers[layering_mode]) {
|
||||||
|
@ -619,11 +678,11 @@ int main(int argc, char **argv) {
|
||||||
|
|
||||||
for (i = min_args_base;
|
for (i = min_args_base;
|
||||||
(int)i < min_args_base + mode_to_num_layers[layering_mode]; ++i) {
|
(int)i < min_args_base + mode_to_num_layers[layering_mode]; ++i) {
|
||||||
rc.layer_target_bitrate[i - 11] = (int)strtol(argv[i], NULL, 0);
|
rc.layer_target_bitrate[i - 13] = (int)strtol(argv[i], NULL, 0);
|
||||||
if (strncmp(encoder->name, "vp8", 3) == 0)
|
if (strncmp(encoder->name, "vp8", 3) == 0)
|
||||||
cfg.ts_target_bitrate[i - 11] = rc.layer_target_bitrate[i - 11];
|
cfg.ts_target_bitrate[i - 13] = rc.layer_target_bitrate[i - 13];
|
||||||
else if (strncmp(encoder->name, "vp9", 3) == 0)
|
else if (strncmp(encoder->name, "vp9", 3) == 0)
|
||||||
cfg.layer_target_bitrate[i - 11] = rc.layer_target_bitrate[i - 11];
|
cfg.layer_target_bitrate[i - 13] = rc.layer_target_bitrate[i - 13];
|
||||||
}
|
}
|
||||||
|
|
||||||
// Real time parameters.
|
// Real time parameters.
|
||||||
|
@ -634,7 +693,7 @@ int main(int argc, char **argv) {
|
||||||
if (strncmp(encoder->name, "vp9", 3) == 0) cfg.rc_max_quantizer = 52;
|
if (strncmp(encoder->name, "vp9", 3) == 0) cfg.rc_max_quantizer = 52;
|
||||||
cfg.rc_undershoot_pct = 50;
|
cfg.rc_undershoot_pct = 50;
|
||||||
cfg.rc_overshoot_pct = 50;
|
cfg.rc_overshoot_pct = 50;
|
||||||
cfg.rc_buf_initial_sz = 500;
|
cfg.rc_buf_initial_sz = 600;
|
||||||
cfg.rc_buf_optimal_sz = 600;
|
cfg.rc_buf_optimal_sz = 600;
|
||||||
cfg.rc_buf_sz = 1000;
|
cfg.rc_buf_sz = 1000;
|
||||||
|
|
||||||
|
@ -642,10 +701,14 @@ int main(int argc, char **argv) {
|
||||||
cfg.rc_resize_allowed = 0;
|
cfg.rc_resize_allowed = 0;
|
||||||
|
|
||||||
// Use 1 thread as default.
|
// Use 1 thread as default.
|
||||||
cfg.g_threads = 1;
|
cfg.g_threads = (unsigned int)strtoul(argv[11], 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.
|
// Enable error resilient mode.
|
||||||
cfg.g_error_resilient = 1;
|
cfg.g_error_resilient = error_resilient;
|
||||||
cfg.g_lag_in_frames = 0;
|
cfg.g_lag_in_frames = 0;
|
||||||
cfg.kf_mode = VPX_KF_AUTO;
|
cfg.kf_mode = VPX_KF_AUTO;
|
||||||
|
|
||||||
|
@ -700,18 +763,33 @@ int main(int argc, char **argv) {
|
||||||
|
|
||||||
if (strncmp(encoder->name, "vp8", 3) == 0) {
|
if (strncmp(encoder->name, "vp8", 3) == 0) {
|
||||||
vpx_codec_control(&codec, VP8E_SET_CPUUSED, -speed);
|
vpx_codec_control(&codec, VP8E_SET_CPUUSED, -speed);
|
||||||
vpx_codec_control(&codec, VP8E_SET_NOISE_SENSITIVITY, kDenoiserOff);
|
vpx_codec_control(&codec, VP8E_SET_NOISE_SENSITIVITY, kVp8DenoiserOff);
|
||||||
vpx_codec_control(&codec, VP8E_SET_STATIC_THRESHOLD, 1);
|
vpx_codec_control(&codec, VP8E_SET_STATIC_THRESHOLD, 1);
|
||||||
|
vpx_codec_control(&codec, VP8E_SET_GF_CBR_BOOST_PCT, 0);
|
||||||
|
#if VP8_ROI_MAP
|
||||||
|
vp8_set_roi_map(&cfg, &roi);
|
||||||
|
if (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) {
|
} else if (strncmp(encoder->name, "vp9", 3) == 0) {
|
||||||
vpx_svc_extra_cfg_t svc_params;
|
vpx_svc_extra_cfg_t svc_params;
|
||||||
memset(&svc_params, 0, sizeof(svc_params));
|
memset(&svc_params, 0, sizeof(svc_params));
|
||||||
vpx_codec_control(&codec, VP8E_SET_CPUUSED, speed);
|
vpx_codec_control(&codec, VP8E_SET_CPUUSED, speed);
|
||||||
vpx_codec_control(&codec, VP9E_SET_AQ_MODE, 3);
|
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_FRAME_PERIODIC_BOOST, 0);
|
||||||
vpx_codec_control(&codec, VP9E_SET_NOISE_SENSITIVITY, kDenoiserOff);
|
vpx_codec_control(&codec, VP9E_SET_NOISE_SENSITIVITY, kVp9DenoiserOff);
|
||||||
vpx_codec_control(&codec, VP8E_SET_STATIC_THRESHOLD, 1);
|
vpx_codec_control(&codec, VP8E_SET_STATIC_THRESHOLD, 1);
|
||||||
vpx_codec_control(&codec, VP9E_SET_TUNE_CONTENT, 0);
|
vpx_codec_control(&codec, VP9E_SET_TUNE_CONTENT, 0);
|
||||||
vpx_codec_control(&codec, VP9E_SET_TILE_COLUMNS, (cfg.g_threads >> 1));
|
vpx_codec_control(&codec, VP9E_SET_TILE_COLUMNS, (cfg.g_threads >> 1));
|
||||||
|
// 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);
|
||||||
if (vpx_codec_control(&codec, VP9E_SET_SVC, layering_mode > 0 ? 1 : 0))
|
if (vpx_codec_control(&codec, VP9E_SET_SVC, layering_mode > 0 ? 1 : 0))
|
||||||
die_codec(&codec, "Failed to set SVC");
|
die_codec(&codec, "Failed to set SVC");
|
||||||
for (i = 0; i < cfg.ts_number_layers; ++i) {
|
for (i = 0; i < cfg.ts_number_layers; ++i) {
|
||||||
|
@ -730,7 +808,7 @@ int main(int argc, char **argv) {
|
||||||
// For generating smaller key frames, use a smaller max_intra_size_pct
|
// For generating smaller key frames, use a smaller max_intra_size_pct
|
||||||
// value, like 100 or 200.
|
// value, like 100 or 200.
|
||||||
{
|
{
|
||||||
const int max_intra_size_pct = 900;
|
const int max_intra_size_pct = 1000;
|
||||||
vpx_codec_control(&codec, VP8E_SET_MAX_INTRA_BITRATE_PCT,
|
vpx_codec_control(&codec, VP8E_SET_MAX_INTRA_BITRATE_PCT,
|
||||||
max_intra_size_pct);
|
max_intra_size_pct);
|
||||||
}
|
}
|
||||||
|
@ -740,10 +818,8 @@ int main(int argc, char **argv) {
|
||||||
struct vpx_usec_timer timer;
|
struct vpx_usec_timer timer;
|
||||||
vpx_codec_iter_t iter = NULL;
|
vpx_codec_iter_t iter = NULL;
|
||||||
const vpx_codec_cx_pkt_t *pkt;
|
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.
|
// Update the temporal layer_id. No spatial layers in this test.
|
||||||
layer_id.spatial_layer_id = 0;
|
layer_id.spatial_layer_id = 0;
|
||||||
#endif
|
|
||||||
layer_id.temporal_layer_id =
|
layer_id.temporal_layer_id =
|
||||||
cfg.ts_layer_id[frame_cnt % cfg.ts_periodicity];
|
cfg.ts_layer_id[frame_cnt % cfg.ts_periodicity];
|
||||||
if (strncmp(encoder->name, "vp9", 3) == 0) {
|
if (strncmp(encoder->name, "vp9", 3) == 0) {
|
||||||
|
|
|
@ -12,7 +12,7 @@
|
||||||
# ARM assembly files are written in RVCT-style. We use some make magic to
|
# ARM assembly files are written in RVCT-style. We use some make magic to
|
||||||
# filter those files to allow GCC compilation
|
# filter those files to allow GCC compilation
|
||||||
ifeq ($(ARCH_ARM),yes)
|
ifeq ($(ARCH_ARM),yes)
|
||||||
ASM:=$(if $(filter yes,$(CONFIG_GCC)$(CONFIG_MSVS)),.asm.s,.asm)
|
ASM:=$(if $(filter yes,$(CONFIG_GCC)$(CONFIG_MSVS)),.asm.S,.asm)
|
||||||
else
|
else
|
||||||
ASM:=.asm
|
ASM:=.asm
|
||||||
endif
|
endif
|
||||||
|
@ -106,9 +106,6 @@ ifeq ($(CONFIG_VP9_DECODER),yes)
|
||||||
CODEC_DOC_SECTIONS += vp9 vp9_decoder
|
CODEC_DOC_SECTIONS += vp9 vp9_decoder
|
||||||
endif
|
endif
|
||||||
|
|
||||||
VP9_PREFIX=vp9/
|
|
||||||
$(BUILD_PFX)$(VP9_PREFIX)%.c.o:
|
|
||||||
|
|
||||||
ifeq ($(CONFIG_ENCODERS),yes)
|
ifeq ($(CONFIG_ENCODERS),yes)
|
||||||
CODEC_DOC_SECTIONS += encoder
|
CODEC_DOC_SECTIONS += encoder
|
||||||
endif
|
endif
|
||||||
|
@ -116,6 +113,12 @@ ifeq ($(CONFIG_DECODERS),yes)
|
||||||
CODEC_DOC_SECTIONS += decoder
|
CODEC_DOC_SECTIONS += decoder
|
||||||
endif
|
endif
|
||||||
|
|
||||||
|
# Suppress -Wextra warnings in third party code.
|
||||||
|
$(BUILD_PFX)third_party/googletest/%.cc.o: CXXFLAGS += -Wno-missing-field-initializers
|
||||||
|
# Suppress -Wextra warnings in first party code pending investigation.
|
||||||
|
# https://bugs.chromium.org/p/webm/issues/detail?id=1069
|
||||||
|
$(BUILD_PFX)vp8/encoder/onyx_if.c.o: CFLAGS += -Wno-unknown-warning-option -Wno-clobbered
|
||||||
|
$(BUILD_PFX)vp8/decoder/onyxd_if.c.o: CFLAGS += -Wno-unknown-warning-option -Wno-clobbered
|
||||||
|
|
||||||
ifeq ($(CONFIG_MSVS),yes)
|
ifeq ($(CONFIG_MSVS),yes)
|
||||||
CODEC_LIB=$(if $(CONFIG_STATIC_MSVCRT),vpxmt,vpxmd)
|
CODEC_LIB=$(if $(CONFIG_STATIC_MSVCRT),vpxmt,vpxmd)
|
||||||
|
@ -146,6 +149,7 @@ CODEC_SRCS-yes += $(BUILD_PFX)vpx_config.c
|
||||||
INSTALL-SRCS-no += $(BUILD_PFX)vpx_config.c
|
INSTALL-SRCS-no += $(BUILD_PFX)vpx_config.c
|
||||||
ifeq ($(ARCH_X86)$(ARCH_X86_64),yes)
|
ifeq ($(ARCH_X86)$(ARCH_X86_64),yes)
|
||||||
INSTALL-SRCS-$(CONFIG_CODEC_SRCS) += third_party/x86inc/x86inc.asm
|
INSTALL-SRCS-$(CONFIG_CODEC_SRCS) += third_party/x86inc/x86inc.asm
|
||||||
|
INSTALL-SRCS-$(CONFIG_CODEC_SRCS) += vpx_dsp/x86/bitdepth_conversion_sse2.asm
|
||||||
endif
|
endif
|
||||||
CODEC_EXPORTS-yes += vpx/exports_com
|
CODEC_EXPORTS-yes += vpx/exports_com
|
||||||
CODEC_EXPORTS-$(CONFIG_ENCODERS) += vpx/exports_enc
|
CODEC_EXPORTS-$(CONFIG_ENCODERS) += vpx/exports_enc
|
||||||
|
@ -184,6 +188,13 @@ libvpx_srcs.txt:
|
||||||
@echo $(CODEC_SRCS) | xargs -n1 echo | LC_ALL=C sort -u > $@
|
@echo $(CODEC_SRCS) | xargs -n1 echo | LC_ALL=C sort -u > $@
|
||||||
CLEAN-OBJS += libvpx_srcs.txt
|
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_EXTERNAL_BUILD),yes)
|
||||||
ifeq ($(CONFIG_MSVS),yes)
|
ifeq ($(CONFIG_MSVS),yes)
|
||||||
|
@ -195,13 +206,6 @@ vpx.def: $(call enabled,CODEC_EXPORTS)
|
||||||
--out=$@ $^
|
--out=$@ $^
|
||||||
CLEAN-OBJS += vpx.def
|
CLEAN-OBJS += vpx.def
|
||||||
|
|
||||||
# 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
|
vpx.$(VCPROJ_SFX): $(CODEC_SRCS) vpx.def
|
||||||
@echo " [CREATE] $@"
|
@echo " [CREATE] $@"
|
||||||
$(qexec)$(GEN_VCPROJ) \
|
$(qexec)$(GEN_VCPROJ) \
|
||||||
|
@ -224,12 +228,12 @@ vpx.$(VCPROJ_SFX): $(RTCD)
|
||||||
|
|
||||||
endif
|
endif
|
||||||
else
|
else
|
||||||
LIBVPX_OBJS=$(call objs,$(CODEC_SRCS))
|
LIBVPX_OBJS=$(call objs, $(filter-out $(ASM_INCLUDES), $(CODEC_SRCS)))
|
||||||
OBJS-yes += $(LIBVPX_OBJS)
|
OBJS-yes += $(LIBVPX_OBJS)
|
||||||
LIBS-$(if yes,$(CONFIG_STATIC)) += $(BUILD_PFX)libvpx.a $(BUILD_PFX)libvpx_g.a
|
LIBS-$(if yes,$(CONFIG_STATIC)) += $(BUILD_PFX)libvpx.a $(BUILD_PFX)libvpx_g.a
|
||||||
$(BUILD_PFX)libvpx_g.a: $(LIBVPX_OBJS)
|
$(BUILD_PFX)libvpx_g.a: $(LIBVPX_OBJS)
|
||||||
|
|
||||||
SO_VERSION_MAJOR := 4
|
SO_VERSION_MAJOR := 5
|
||||||
SO_VERSION_MINOR := 0
|
SO_VERSION_MINOR := 0
|
||||||
SO_VERSION_PATCH := 0
|
SO_VERSION_PATCH := 0
|
||||||
ifeq ($(filter darwin%,$(TGT_OS)),$(TGT_OS))
|
ifeq ($(filter darwin%,$(TGT_OS)),$(TGT_OS))
|
||||||
|
@ -363,7 +367,7 @@ endif
|
||||||
#
|
#
|
||||||
# Add assembler dependencies for configuration.
|
# Add assembler dependencies for configuration.
|
||||||
#
|
#
|
||||||
$(filter %.s.o,$(OBJS-yes)): $(BUILD_PFX)vpx_config.asm
|
$(filter %.S.o,$(OBJS-yes)): $(BUILD_PFX)vpx_config.asm
|
||||||
$(filter %$(ASM).o,$(OBJS-yes)): $(BUILD_PFX)vpx_config.asm
|
$(filter %$(ASM).o,$(OBJS-yes)): $(BUILD_PFX)vpx_config.asm
|
||||||
|
|
||||||
|
|
||||||
|
@ -388,7 +392,7 @@ LIBVPX_TEST_SRCS=$(addprefix test/,$(call enabled,LIBVPX_TEST_SRCS))
|
||||||
LIBVPX_TEST_BIN=./test_libvpx$(EXE_SFX)
|
LIBVPX_TEST_BIN=./test_libvpx$(EXE_SFX)
|
||||||
LIBVPX_TEST_DATA=$(addprefix $(LIBVPX_TEST_DATA_PATH)/,\
|
LIBVPX_TEST_DATA=$(addprefix $(LIBVPX_TEST_DATA_PATH)/,\
|
||||||
$(call enabled,LIBVPX_TEST_DATA))
|
$(call enabled,LIBVPX_TEST_DATA))
|
||||||
libvpx_test_data_url=http://downloads.webmproject.org/test_data/libvpx/$(1)
|
libvpx_test_data_url=https://storage.googleapis.com/downloads.webmproject.org/test_data/libvpx/$(1)
|
||||||
|
|
||||||
TEST_INTRA_PRED_SPEED_BIN=./test_intra_pred_speed$(EXE_SFX)
|
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))
|
TEST_INTRA_PRED_SPEED_SRCS=$(addprefix test/,$(call enabled,TEST_INTRA_PRED_SPEED_SRCS))
|
||||||
|
@ -401,8 +405,16 @@ CLEAN-OBJS += libvpx_test_srcs.txt
|
||||||
|
|
||||||
$(LIBVPX_TEST_DATA): $(SRC_PATH_BARE)/test/test-data.sha1
|
$(LIBVPX_TEST_DATA): $(SRC_PATH_BARE)/test/test-data.sha1
|
||||||
@echo " [DOWNLOAD] $@"
|
@echo " [DOWNLOAD] $@"
|
||||||
$(qexec)trap 'rm -f $@' INT TERM &&\
|
# Attempt to download the file using curl, retrying once if it fails for a
|
||||||
curl -L -o $@ $(call libvpx_test_data_url,$(@F))
|
# 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 \
|
||||||
|
)
|
||||||
|
|
||||||
testdata:: $(LIBVPX_TEST_DATA)
|
testdata:: $(LIBVPX_TEST_DATA)
|
||||||
$(qexec)[ -x "$$(which sha1sum)" ] && sha1sum=sha1sum;\
|
$(qexec)[ -x "$$(which sha1sum)" ] && sha1sum=sha1sum;\
|
||||||
|
|
|
@ -37,7 +37,13 @@ struct rate_hist {
|
||||||
struct rate_hist *init_rate_histogram(const vpx_codec_enc_cfg_t *cfg,
|
struct rate_hist *init_rate_histogram(const vpx_codec_enc_cfg_t *cfg,
|
||||||
const vpx_rational_t *fps) {
|
const vpx_rational_t *fps) {
|
||||||
int i;
|
int i;
|
||||||
struct rate_hist *hist = malloc(sizeof(*hist));
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
// Determine the number of samples in the buffer. Use the file's framerate
|
// 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
|
// to determine the number of frames in rc_buf_sz milliseconds, with an
|
||||||
|
@ -80,7 +86,11 @@ void update_rate_histogram(struct rate_hist *hist,
|
||||||
(uint64_t)cfg->g_timebase.num /
|
(uint64_t)cfg->g_timebase.num /
|
||||||
(uint64_t)cfg->g_timebase.den;
|
(uint64_t)cfg->g_timebase.den;
|
||||||
|
|
||||||
int idx = hist->frames++ % hist->samples;
|
int idx;
|
||||||
|
|
||||||
|
if (hist == NULL || cfg == NULL || pkt == NULL) return;
|
||||||
|
|
||||||
|
idx = hist->frames++ % hist->samples;
|
||||||
hist->pts[idx] = now;
|
hist->pts[idx] = now;
|
||||||
hist->sz[idx] = (int)pkt->data.frame.sz;
|
hist->sz[idx] = (int)pkt->data.frame.sz;
|
||||||
|
|
||||||
|
@ -116,9 +126,14 @@ void update_rate_histogram(struct rate_hist *hist,
|
||||||
static int merge_hist_buckets(struct hist_bucket *bucket, int max_buckets,
|
static int merge_hist_buckets(struct hist_bucket *bucket, int max_buckets,
|
||||||
int *num_buckets) {
|
int *num_buckets) {
|
||||||
int small_bucket = 0, merge_bucket = INT_MAX, big_bucket = 0;
|
int small_bucket = 0, merge_bucket = INT_MAX, big_bucket = 0;
|
||||||
int buckets = *num_buckets;
|
int buckets;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
|
assert(bucket != NULL);
|
||||||
|
assert(num_buckets != NULL);
|
||||||
|
|
||||||
|
buckets = *num_buckets;
|
||||||
|
|
||||||
/* Find the extrema for this list of buckets */
|
/* Find the extrema for this list of buckets */
|
||||||
big_bucket = small_bucket = 0;
|
big_bucket = small_bucket = 0;
|
||||||
for (i = 0; i < buckets; i++) {
|
for (i = 0; i < buckets; i++) {
|
||||||
|
@ -181,6 +196,8 @@ static void show_histogram(const struct hist_bucket *bucket, int buckets,
|
||||||
const char *pat1, *pat2;
|
const char *pat1, *pat2;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
|
assert(bucket != NULL);
|
||||||
|
|
||||||
switch ((int)(log(bucket[buckets - 1].high) / log(10)) + 1) {
|
switch ((int)(log(bucket[buckets - 1].high) / log(10)) + 1) {
|
||||||
case 1:
|
case 1:
|
||||||
case 2:
|
case 2:
|
||||||
|
@ -259,6 +276,8 @@ void show_rate_histogram(struct rate_hist *hist, const vpx_codec_enc_cfg_t *cfg,
|
||||||
int i, scale;
|
int i, scale;
|
||||||
int buckets = 0;
|
int buckets = 0;
|
||||||
|
|
||||||
|
if (hist == NULL || cfg == NULL) return;
|
||||||
|
|
||||||
for (i = 0; i < RATE_BINS; i++) {
|
for (i = 0; i < RATE_BINS; i++) {
|
||||||
if (hist->bucket[i].low == INT_MAX) continue;
|
if (hist->bucket[i].low == INT_MAX) continue;
|
||||||
hist->bucket[buckets++] = hist->bucket[i];
|
hist->bucket[buckets++] = hist->bucket[i];
|
||||||
|
|
|
@ -11,6 +11,10 @@
|
||||||
#ifndef TEST_ACM_RANDOM_H_
|
#ifndef TEST_ACM_RANDOM_H_
|
||||||
#define TEST_ACM_RANDOM_H_
|
#define TEST_ACM_RANDOM_H_
|
||||||
|
|
||||||
|
#include <assert.h>
|
||||||
|
|
||||||
|
#include <limits>
|
||||||
|
|
||||||
#include "third_party/googletest/src/include/gtest/gtest.h"
|
#include "third_party/googletest/src/include/gtest/gtest.h"
|
||||||
|
|
||||||
#include "vpx/vpx_integer.h"
|
#include "vpx/vpx_integer.h"
|
||||||
|
@ -50,6 +54,13 @@ class ACMRandom {
|
||||||
return r < 128 ? r << 4 : r >> 4;
|
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 PseudoUniform(int range) { return random_.Generate(range); }
|
||||||
|
|
||||||
int operator()(int n) { return PseudoUniform(n); }
|
int operator()(int n) { return PseudoUniform(n); }
|
||||||
|
|
|
@ -32,6 +32,7 @@ LOCAL_CPP_EXTENSION := .cc
|
||||||
LOCAL_MODULE := gtest
|
LOCAL_MODULE := gtest
|
||||||
LOCAL_C_INCLUDES := $(LOCAL_PATH)/third_party/googletest/src/
|
LOCAL_C_INCLUDES := $(LOCAL_PATH)/third_party/googletest/src/
|
||||||
LOCAL_C_INCLUDES += $(LOCAL_PATH)/third_party/googletest/src/include/
|
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
|
LOCAL_SRC_FILES := ./third_party/googletest/src/src/gtest-all.cc
|
||||||
include $(BUILD_STATIC_LIBRARY)
|
include $(BUILD_STATIC_LIBRARY)
|
||||||
|
|
||||||
|
|
|
@ -14,6 +14,7 @@
|
||||||
|
|
||||||
#include "third_party/googletest/src/include/gtest/gtest.h"
|
#include "third_party/googletest/src/include/gtest/gtest.h"
|
||||||
|
|
||||||
|
#include "./vp9_rtcd.h"
|
||||||
#include "./vpx_config.h"
|
#include "./vpx_config.h"
|
||||||
#include "./vpx_dsp_rtcd.h"
|
#include "./vpx_dsp_rtcd.h"
|
||||||
|
|
||||||
|
@ -22,6 +23,7 @@
|
||||||
#include "test/register_state_check.h"
|
#include "test/register_state_check.h"
|
||||||
#include "test/util.h"
|
#include "test/util.h"
|
||||||
#include "vpx_mem/vpx_mem.h"
|
#include "vpx_mem/vpx_mem.h"
|
||||||
|
#include "vpx_ports/vpx_timer.h"
|
||||||
|
|
||||||
using libvpx_test::ACMRandom;
|
using libvpx_test::ACMRandom;
|
||||||
|
|
||||||
|
@ -53,7 +55,7 @@ class AverageTestBase : public ::testing::Test {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Sum Pixels
|
// Sum Pixels
|
||||||
unsigned int ReferenceAverage8x8(const uint8_t *source, int pitch) {
|
static unsigned int ReferenceAverage8x8(const uint8_t *source, int pitch) {
|
||||||
unsigned int average = 0;
|
unsigned int average = 0;
|
||||||
for (int h = 0; h < 8; ++h) {
|
for (int h = 0; h < 8; ++h) {
|
||||||
for (int w = 0; w < 8; ++w) average += source[h * pitch + w];
|
for (int w = 0; w < 8; ++w) average += source[h * pitch + w];
|
||||||
|
@ -61,7 +63,7 @@ class AverageTestBase : public ::testing::Test {
|
||||||
return ((average + 32) >> 6);
|
return ((average + 32) >> 6);
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned int ReferenceAverage4x4(const uint8_t *source, int pitch) {
|
static unsigned int ReferenceAverage4x4(const uint8_t *source, int pitch) {
|
||||||
unsigned int average = 0;
|
unsigned int average = 0;
|
||||||
for (int h = 0; h < 4; ++h) {
|
for (int h = 0; h < 4; ++h) {
|
||||||
for (int w = 0; w < 4; ++w) average += source[h * pitch + w];
|
for (int w = 0; w < 4; ++w) average += source[h * pitch + w];
|
||||||
|
@ -98,11 +100,12 @@ class AverageTest : public AverageTestBase,
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
void CheckAverages() {
|
void CheckAverages() {
|
||||||
|
const int block_size = GET_PARAM(3);
|
||||||
unsigned int expected = 0;
|
unsigned int expected = 0;
|
||||||
if (GET_PARAM(3) == 8) {
|
if (block_size == 8) {
|
||||||
expected =
|
expected =
|
||||||
ReferenceAverage8x8(source_data_ + GET_PARAM(2), source_stride_);
|
ReferenceAverage8x8(source_data_ + GET_PARAM(2), source_stride_);
|
||||||
} else if (GET_PARAM(3) == 4) {
|
} else if (block_size == 4) {
|
||||||
expected =
|
expected =
|
||||||
ReferenceAverage4x4(source_data_ + GET_PARAM(2), source_stride_);
|
ReferenceAverage4x4(source_data_ + GET_PARAM(2), source_stride_);
|
||||||
}
|
}
|
||||||
|
@ -185,7 +188,7 @@ class IntProColTest : public AverageTestBase,
|
||||||
int16_t sum_c_;
|
int16_t sum_c_;
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef int (*SatdFunc)(const int16_t *coeffs, int length);
|
typedef int (*SatdFunc)(const tran_low_t *coeffs, int length);
|
||||||
typedef std::tr1::tuple<int, SatdFunc> SatdTestParam;
|
typedef std::tr1::tuple<int, SatdFunc> SatdTestParam;
|
||||||
|
|
||||||
class SatdTest : public ::testing::Test,
|
class SatdTest : public ::testing::Test,
|
||||||
|
@ -195,7 +198,7 @@ class SatdTest : public ::testing::Test,
|
||||||
satd_size_ = GET_PARAM(0);
|
satd_size_ = GET_PARAM(0);
|
||||||
satd_func_ = GET_PARAM(1);
|
satd_func_ = GET_PARAM(1);
|
||||||
rnd_.Reset(ACMRandom::DeterministicSeed());
|
rnd_.Reset(ACMRandom::DeterministicSeed());
|
||||||
src_ = reinterpret_cast<int16_t *>(
|
src_ = reinterpret_cast<tran_low_t *>(
|
||||||
vpx_memalign(16, sizeof(*src_) * satd_size_));
|
vpx_memalign(16, sizeof(*src_) * satd_size_));
|
||||||
ASSERT_TRUE(src_ != NULL);
|
ASSERT_TRUE(src_ != NULL);
|
||||||
}
|
}
|
||||||
|
@ -205,12 +208,15 @@ class SatdTest : public ::testing::Test,
|
||||||
vpx_free(src_);
|
vpx_free(src_);
|
||||||
}
|
}
|
||||||
|
|
||||||
void FillConstant(const int16_t val) {
|
void FillConstant(const tran_low_t val) {
|
||||||
for (int i = 0; i < satd_size_; ++i) src_[i] = val;
|
for (int i = 0; i < satd_size_; ++i) src_[i] = val;
|
||||||
}
|
}
|
||||||
|
|
||||||
void FillRandom() {
|
void FillRandom() {
|
||||||
for (int i = 0; i < satd_size_; ++i) src_[i] = rnd_.Rand16();
|
for (int i = 0; i < satd_size_; ++i) {
|
||||||
|
const int16_t tmp = rnd_.Rand16();
|
||||||
|
src_[i] = (tran_low_t)tmp;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Check(const int expected) {
|
void Check(const int expected) {
|
||||||
|
@ -222,11 +228,66 @@ class SatdTest : public ::testing::Test,
|
||||||
int satd_size_;
|
int satd_size_;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
int16_t *src_;
|
tran_low_t *src_;
|
||||||
SatdFunc satd_func_;
|
SatdFunc satd_func_;
|
||||||
ACMRandom rnd_;
|
ACMRandom rnd_;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
typedef int64_t (*BlockErrorFunc)(const tran_low_t *coeff,
|
||||||
|
const tran_low_t *dqcoeff, int block_size);
|
||||||
|
typedef std::tr1::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;
|
uint8_t *AverageTestBase::source_data_ = NULL;
|
||||||
|
|
||||||
TEST_P(AverageTest, MinValue) {
|
TEST_P(AverageTest, MinValue) {
|
||||||
|
@ -307,6 +368,66 @@ TEST_P(SatdTest, Random) {
|
||||||
Check(expected);
|
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 std::tr1::make_tuple;
|
using std::tr1::make_tuple;
|
||||||
|
|
||||||
INSTANTIATE_TEST_CASE_P(
|
INSTANTIATE_TEST_CASE_P(
|
||||||
|
@ -320,6 +441,13 @@ INSTANTIATE_TEST_CASE_P(C, SatdTest,
|
||||||
make_tuple(256, &vpx_satd_c),
|
make_tuple(256, &vpx_satd_c),
|
||||||
make_tuple(1024, &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
|
#if HAVE_SSE2
|
||||||
INSTANTIATE_TEST_CASE_P(
|
INSTANTIATE_TEST_CASE_P(
|
||||||
SSE2, AverageTest,
|
SSE2, AverageTest,
|
||||||
|
@ -349,6 +477,28 @@ INSTANTIATE_TEST_CASE_P(SSE2, SatdTest,
|
||||||
make_tuple(64, &vpx_satd_sse2),
|
make_tuple(64, &vpx_satd_sse2),
|
||||||
make_tuple(256, &vpx_satd_sse2),
|
make_tuple(256, &vpx_satd_sse2),
|
||||||
make_tuple(1024, &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
|
#endif
|
||||||
|
|
||||||
#if HAVE_NEON
|
#if HAVE_NEON
|
||||||
|
@ -380,7 +530,18 @@ INSTANTIATE_TEST_CASE_P(NEON, SatdTest,
|
||||||
make_tuple(64, &vpx_satd_neon),
|
make_tuple(64, &vpx_satd_neon),
|
||||||
make_tuple(256, &vpx_satd_neon),
|
make_tuple(256, &vpx_satd_neon),
|
||||||
make_tuple(1024, &vpx_satd_neon)));
|
make_tuple(1024, &vpx_satd_neon)));
|
||||||
#endif
|
|
||||||
|
// 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
|
||||||
|
|
||||||
#if HAVE_MSA
|
#if HAVE_MSA
|
||||||
INSTANTIATE_TEST_CASE_P(
|
INSTANTIATE_TEST_CASE_P(
|
||||||
|
@ -391,6 +552,30 @@ INSTANTIATE_TEST_CASE_P(
|
||||||
make_tuple(16, 16, 0, 4, &vpx_avg_4x4_msa),
|
make_tuple(16, 16, 0, 4, &vpx_avg_4x4_msa),
|
||||||
make_tuple(16, 16, 5, 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)));
|
make_tuple(32, 32, 15, 4, &vpx_avg_4x4_msa)));
|
||||||
#endif
|
|
||||||
|
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
|
||||||
|
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
|
@ -0,0 +1,382 @@
|
||||||
|
/*
|
||||||
|
* 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.
|
// TODO(fgalligan): Move the MD5 testing code into another class.
|
||||||
void OpenMd5File(const std::string &md5_file_name_) {
|
void OpenMd5File(const std::string &md5_file_name_) {
|
||||||
md5_file_ = libvpx_test::OpenTestDataFile(md5_file_name_);
|
md5_file_ = libvpx_test::OpenTestDataFile(md5_file_name_);
|
||||||
ASSERT_TRUE(md5_file_ != NULL) << "MD5 file open failed. Filename: "
|
ASSERT_TRUE(md5_file_ != NULL)
|
||||||
<< md5_file_name_;
|
<< "MD5 file open failed. Filename: " << md5_file_name_;
|
||||||
}
|
}
|
||||||
|
|
||||||
void CheckMd5(const vpx_image_t &img) {
|
void CheckMd5(const vpx_image_t &img) {
|
||||||
|
|
|
@ -65,6 +65,12 @@ class CodecTestWith3Params
|
||||||
: public ::testing::TestWithParam<
|
: public ::testing::TestWithParam<
|
||||||
std::tr1::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<
|
||||||
|
std::tr1::tuple<const libvpx_test::CodecFactory *, T1, T2, T3, T4> > {
|
||||||
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* VP8 Codec Definitions
|
* VP8 Codec Definitions
|
||||||
*/
|
*/
|
||||||
|
@ -115,6 +121,8 @@ class VP8CodecFactory : public CodecFactory {
|
||||||
#if CONFIG_VP8_DECODER
|
#if CONFIG_VP8_DECODER
|
||||||
return new VP8Decoder(cfg, flags);
|
return new VP8Decoder(cfg, flags);
|
||||||
#else
|
#else
|
||||||
|
(void)cfg;
|
||||||
|
(void)flags;
|
||||||
return NULL;
|
return NULL;
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
@ -126,6 +134,10 @@ class VP8CodecFactory : public CodecFactory {
|
||||||
#if CONFIG_VP8_ENCODER
|
#if CONFIG_VP8_ENCODER
|
||||||
return new VP8Encoder(cfg, deadline, init_flags, stats);
|
return new VP8Encoder(cfg, deadline, init_flags, stats);
|
||||||
#else
|
#else
|
||||||
|
(void)cfg;
|
||||||
|
(void)deadline;
|
||||||
|
(void)init_flags;
|
||||||
|
(void)stats;
|
||||||
return NULL;
|
return NULL;
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
@ -135,6 +147,8 @@ class VP8CodecFactory : public CodecFactory {
|
||||||
#if CONFIG_VP8_ENCODER
|
#if CONFIG_VP8_ENCODER
|
||||||
return vpx_codec_enc_config_default(&vpx_codec_vp8_cx_algo, cfg, usage);
|
return vpx_codec_enc_config_default(&vpx_codec_vp8_cx_algo, cfg, usage);
|
||||||
#else
|
#else
|
||||||
|
(void)cfg;
|
||||||
|
(void)usage;
|
||||||
return VPX_CODEC_INCAPABLE;
|
return VPX_CODEC_INCAPABLE;
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
@ -203,6 +217,8 @@ class VP9CodecFactory : public CodecFactory {
|
||||||
#if CONFIG_VP9_DECODER
|
#if CONFIG_VP9_DECODER
|
||||||
return new VP9Decoder(cfg, flags);
|
return new VP9Decoder(cfg, flags);
|
||||||
#else
|
#else
|
||||||
|
(void)cfg;
|
||||||
|
(void)flags;
|
||||||
return NULL;
|
return NULL;
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
@ -214,6 +230,10 @@ class VP9CodecFactory : public CodecFactory {
|
||||||
#if CONFIG_VP9_ENCODER
|
#if CONFIG_VP9_ENCODER
|
||||||
return new VP9Encoder(cfg, deadline, init_flags, stats);
|
return new VP9Encoder(cfg, deadline, init_flags, stats);
|
||||||
#else
|
#else
|
||||||
|
(void)cfg;
|
||||||
|
(void)deadline;
|
||||||
|
(void)init_flags;
|
||||||
|
(void)stats;
|
||||||
return NULL;
|
return NULL;
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
@ -223,6 +243,8 @@ class VP9CodecFactory : public CodecFactory {
|
||||||
#if CONFIG_VP9_ENCODER
|
#if CONFIG_VP9_ENCODER
|
||||||
return vpx_codec_enc_config_default(&vpx_codec_vp9_cx_algo, cfg, usage);
|
return vpx_codec_enc_config_default(&vpx_codec_vp9_cx_algo, cfg, usage);
|
||||||
#else
|
#else
|
||||||
|
(void)cfg;
|
||||||
|
(void)usage;
|
||||||
return VPX_CODEC_INCAPABLE;
|
return VPX_CODEC_INCAPABLE;
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,182 @@
|
||||||
|
/*
|
||||||
|
* 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
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
|
@ -255,11 +255,11 @@ void iht16x16_ref(const tran_low_t *in, uint8_t *dest, int stride,
|
||||||
|
|
||||||
#if CONFIG_VP9_HIGHBITDEPTH
|
#if CONFIG_VP9_HIGHBITDEPTH
|
||||||
void idct16x16_10(const tran_low_t *in, uint8_t *out, int stride) {
|
void idct16x16_10(const tran_low_t *in, uint8_t *out, int stride) {
|
||||||
vpx_highbd_idct16x16_256_add_c(in, out, stride, 10);
|
vpx_highbd_idct16x16_256_add_c(in, CAST_TO_SHORTPTR(out), stride, 10);
|
||||||
}
|
}
|
||||||
|
|
||||||
void idct16x16_12(const tran_low_t *in, uint8_t *out, int stride) {
|
void idct16x16_12(const tran_low_t *in, uint8_t *out, int stride) {
|
||||||
vpx_highbd_idct16x16_256_add_c(in, out, stride, 12);
|
vpx_highbd_idct16x16_256_add_c(in, CAST_TO_SHORTPTR(out), stride, 12);
|
||||||
}
|
}
|
||||||
|
|
||||||
void idct16x16_10_ref(const tran_low_t *in, uint8_t *out, int stride,
|
void idct16x16_10_ref(const tran_low_t *in, uint8_t *out, int stride,
|
||||||
|
@ -273,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) {
|
void iht16x16_10(const tran_low_t *in, uint8_t *out, int stride, int tx_type) {
|
||||||
vp9_highbd_iht16x16_256_add_c(in, out, stride, tx_type, 10);
|
vp9_highbd_iht16x16_256_add_c(in, CAST_TO_SHORTPTR(out), stride, tx_type, 10);
|
||||||
}
|
}
|
||||||
|
|
||||||
void iht16x16_12(const tran_low_t *in, uint8_t *out, int stride, int tx_type) {
|
void iht16x16_12(const tran_low_t *in, uint8_t *out, int stride, int tx_type) {
|
||||||
vp9_highbd_iht16x16_256_add_c(in, out, stride, tx_type, 12);
|
vp9_highbd_iht16x16_256_add_c(in, CAST_TO_SHORTPTR(out), stride, tx_type, 12);
|
||||||
}
|
}
|
||||||
|
|
||||||
#if HAVE_SSE2
|
#if HAVE_SSE2
|
||||||
void idct16x16_10_add_10_c(const tran_low_t *in, uint8_t *out, int stride) {
|
void idct16x16_10_add_10_c(const tran_low_t *in, uint8_t *out, int stride) {
|
||||||
vpx_highbd_idct16x16_10_add_c(in, out, stride, 10);
|
vpx_highbd_idct16x16_10_add_c(in, CAST_TO_SHORTPTR(out), stride, 10);
|
||||||
}
|
}
|
||||||
|
|
||||||
void idct16x16_10_add_12_c(const tran_low_t *in, uint8_t *out, int stride) {
|
void idct16x16_10_add_12_c(const tran_low_t *in, uint8_t *out, int stride) {
|
||||||
vpx_highbd_idct16x16_10_add_c(in, out, stride, 12);
|
vpx_highbd_idct16x16_10_add_c(in, CAST_TO_SHORTPTR(out), stride, 12);
|
||||||
}
|
}
|
||||||
|
|
||||||
void idct16x16_256_add_10_sse2(const tran_low_t *in, uint8_t *out, int stride) {
|
void idct16x16_256_add_10_sse2(const tran_low_t *in, uint8_t *out, int stride) {
|
||||||
vpx_highbd_idct16x16_256_add_sse2(in, out, stride, 10);
|
vpx_highbd_idct16x16_256_add_sse2(in, CAST_TO_SHORTPTR(out), stride, 10);
|
||||||
}
|
}
|
||||||
|
|
||||||
void idct16x16_256_add_12_sse2(const tran_low_t *in, uint8_t *out, int stride) {
|
void idct16x16_256_add_12_sse2(const tran_low_t *in, uint8_t *out, int stride) {
|
||||||
vpx_highbd_idct16x16_256_add_sse2(in, out, stride, 12);
|
vpx_highbd_idct16x16_256_add_sse2(in, CAST_TO_SHORTPTR(out), stride, 12);
|
||||||
}
|
}
|
||||||
|
|
||||||
void idct16x16_10_add_10_sse2(const tran_low_t *in, uint8_t *out, int stride) {
|
void idct16x16_10_add_10_sse2(const tran_low_t *in, uint8_t *out, int stride) {
|
||||||
vpx_highbd_idct16x16_10_add_sse2(in, out, stride, 10);
|
vpx_highbd_idct16x16_10_add_sse2(in, CAST_TO_SHORTPTR(out), stride, 10);
|
||||||
}
|
}
|
||||||
|
|
||||||
void idct16x16_10_add_12_sse2(const tran_low_t *in, uint8_t *out, int stride) {
|
void idct16x16_10_add_12_sse2(const tran_low_t *in, uint8_t *out, int stride) {
|
||||||
vpx_highbd_idct16x16_10_add_sse2(in, out, stride, 12);
|
vpx_highbd_idct16x16_10_add_sse2(in, CAST_TO_SHORTPTR(out), stride, 12);
|
||||||
}
|
}
|
||||||
#endif // HAVE_SSE2
|
#endif // HAVE_SSE2
|
||||||
#endif // CONFIG_VP9_HIGHBITDEPTH
|
#endif // CONFIG_VP9_HIGHBITDEPTH
|
||||||
|
@ -353,7 +353,7 @@ class Trans16x16TestBase {
|
||||||
#if CONFIG_VP9_HIGHBITDEPTH
|
#if CONFIG_VP9_HIGHBITDEPTH
|
||||||
} else {
|
} else {
|
||||||
ASM_REGISTER_STATE_CHECK(
|
ASM_REGISTER_STATE_CHECK(
|
||||||
RunInvTxfm(test_temp_block, CONVERT_TO_BYTEPTR(dst16), pitch_));
|
RunInvTxfm(test_temp_block, CAST_TO_BYTEPTR(dst16), pitch_));
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -475,10 +475,10 @@ class Trans16x16TestBase {
|
||||||
ASM_REGISTER_STATE_CHECK(RunInvTxfm(output_ref_block, dst, pitch_));
|
ASM_REGISTER_STATE_CHECK(RunInvTxfm(output_ref_block, dst, pitch_));
|
||||||
#if CONFIG_VP9_HIGHBITDEPTH
|
#if CONFIG_VP9_HIGHBITDEPTH
|
||||||
} else {
|
} else {
|
||||||
inv_txfm_ref(output_ref_block, CONVERT_TO_BYTEPTR(ref16), pitch_,
|
inv_txfm_ref(output_ref_block, CAST_TO_BYTEPTR(ref16), pitch_,
|
||||||
tx_type_);
|
tx_type_);
|
||||||
ASM_REGISTER_STATE_CHECK(
|
ASM_REGISTER_STATE_CHECK(
|
||||||
RunInvTxfm(output_ref_block, CONVERT_TO_BYTEPTR(dst16), pitch_));
|
RunInvTxfm(output_ref_block, CAST_TO_BYTEPTR(dst16), pitch_));
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
if (bit_depth_ == VPX_BITS_8) {
|
if (bit_depth_ == VPX_BITS_8) {
|
||||||
|
@ -530,8 +530,7 @@ class Trans16x16TestBase {
|
||||||
ASM_REGISTER_STATE_CHECK(RunInvTxfm(coeff, dst, 16));
|
ASM_REGISTER_STATE_CHECK(RunInvTxfm(coeff, dst, 16));
|
||||||
#if CONFIG_VP9_HIGHBITDEPTH
|
#if CONFIG_VP9_HIGHBITDEPTH
|
||||||
} else {
|
} else {
|
||||||
ASM_REGISTER_STATE_CHECK(
|
ASM_REGISTER_STATE_CHECK(RunInvTxfm(coeff, CAST_TO_BYTEPTR(dst16), 16));
|
||||||
RunInvTxfm(coeff, CONVERT_TO_BYTEPTR(dst16), 16));
|
|
||||||
#endif // CONFIG_VP9_HIGHBITDEPTH
|
#endif // CONFIG_VP9_HIGHBITDEPTH
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -543,8 +542,8 @@ class Trans16x16TestBase {
|
||||||
const uint32_t diff = dst[j] - src[j];
|
const uint32_t diff = dst[j] - src[j];
|
||||||
#endif // CONFIG_VP9_HIGHBITDEPTH
|
#endif // CONFIG_VP9_HIGHBITDEPTH
|
||||||
const uint32_t error = diff * diff;
|
const uint32_t error = diff * diff;
|
||||||
EXPECT_GE(1u, error) << "Error: 16x16 IDCT has error " << error
|
EXPECT_GE(1u, error)
|
||||||
<< " at index " << j;
|
<< "Error: 16x16 IDCT has error " << error << " at index " << j;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -585,9 +584,9 @@ class Trans16x16TestBase {
|
||||||
ASM_REGISTER_STATE_CHECK(RunInvTxfm(coeff, dst, pitch_));
|
ASM_REGISTER_STATE_CHECK(RunInvTxfm(coeff, dst, pitch_));
|
||||||
} else {
|
} else {
|
||||||
#if CONFIG_VP9_HIGHBITDEPTH
|
#if CONFIG_VP9_HIGHBITDEPTH
|
||||||
ref_txfm(coeff, CONVERT_TO_BYTEPTR(ref16), pitch_);
|
ref_txfm(coeff, CAST_TO_BYTEPTR(ref16), pitch_);
|
||||||
ASM_REGISTER_STATE_CHECK(
|
ASM_REGISTER_STATE_CHECK(
|
||||||
RunInvTxfm(coeff, CONVERT_TO_BYTEPTR(dst16), pitch_));
|
RunInvTxfm(coeff, CAST_TO_BYTEPTR(dst16), pitch_));
|
||||||
#endif // CONFIG_VP9_HIGHBITDEPTH
|
#endif // CONFIG_VP9_HIGHBITDEPTH
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -745,66 +744,6 @@ TEST_P(InvTrans16x16DCT, CompareReference) {
|
||||||
CompareInvReference(ref_txfm_, thresh_);
|
CompareInvReference(ref_txfm_, thresh_);
|
||||||
}
|
}
|
||||||
|
|
||||||
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;
|
using std::tr1::make_tuple;
|
||||||
|
|
||||||
#if CONFIG_VP9_HIGHBITDEPTH
|
#if CONFIG_VP9_HIGHBITDEPTH
|
||||||
|
@ -837,11 +776,6 @@ 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, 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, 2, VPX_BITS_8),
|
||||||
make_tuple(&vp9_fht16x16_c, &vp9_iht16x16_256_add_c, 3, 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
|
#else
|
||||||
INSTANTIATE_TEST_CASE_P(
|
INSTANTIATE_TEST_CASE_P(
|
||||||
C, Trans16x16HT,
|
C, Trans16x16HT,
|
||||||
|
@ -850,17 +784,14 @@ 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, 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, 2, VPX_BITS_8),
|
||||||
make_tuple(&vp9_fht16x16_c, &vp9_iht16x16_256_add_c, 3, 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
|
#endif // CONFIG_VP9_HIGHBITDEPTH
|
||||||
|
|
||||||
#if HAVE_NEON && !CONFIG_VP9_HIGHBITDEPTH && !CONFIG_EMULATE_HARDWARE
|
#if HAVE_NEON && !CONFIG_EMULATE_HARDWARE
|
||||||
INSTANTIATE_TEST_CASE_P(
|
INSTANTIATE_TEST_CASE_P(
|
||||||
NEON, Trans16x16DCT,
|
NEON, Trans16x16DCT,
|
||||||
::testing::Values(make_tuple(&vpx_fdct16x16_c, &vpx_idct16x16_256_add_neon,
|
::testing::Values(make_tuple(&vpx_fdct16x16_neon,
|
||||||
0, VPX_BITS_8)));
|
&vpx_idct16x16_256_add_neon, 0, VPX_BITS_8)));
|
||||||
#endif
|
#endif // HAVE_NEON && !CONFIG_EMULATE_HARDWARE
|
||||||
|
|
||||||
#if HAVE_SSE2 && !CONFIG_VP9_HIGHBITDEPTH && !CONFIG_EMULATE_HARDWARE
|
#if HAVE_SSE2 && !CONFIG_VP9_HIGHBITDEPTH && !CONFIG_EMULATE_HARDWARE
|
||||||
INSTANTIATE_TEST_CASE_P(
|
INSTANTIATE_TEST_CASE_P(
|
||||||
|
@ -877,9 +808,6 @@ INSTANTIATE_TEST_CASE_P(
|
||||||
2, VPX_BITS_8),
|
2, VPX_BITS_8),
|
||||||
make_tuple(&vp9_fht16x16_sse2, &vp9_iht16x16_256_add_sse2,
|
make_tuple(&vp9_fht16x16_sse2, &vp9_iht16x16_256_add_sse2,
|
||||||
3, VPX_BITS_8)));
|
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
|
#endif // HAVE_SSE2 && !CONFIG_VP9_HIGHBITDEPTH && !CONFIG_EMULATE_HARDWARE
|
||||||
|
|
||||||
#if HAVE_SSE2 && CONFIG_VP9_HIGHBITDEPTH && !CONFIG_EMULATE_HARDWARE
|
#if HAVE_SSE2 && CONFIG_VP9_HIGHBITDEPTH && !CONFIG_EMULATE_HARDWARE
|
||||||
|
@ -914,9 +842,6 @@ INSTANTIATE_TEST_CASE_P(
|
||||||
&idct16x16_10_add_12_sse2, 3167, VPX_BITS_12),
|
&idct16x16_10_add_12_sse2, 3167, VPX_BITS_12),
|
||||||
make_tuple(&idct16x16_12, &idct16x16_256_add_12_sse2,
|
make_tuple(&idct16x16_12, &idct16x16_256_add_12_sse2,
|
||||||
3167, VPX_BITS_12)));
|
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
|
#endif // HAVE_SSE2 && CONFIG_VP9_HIGHBITDEPTH && !CONFIG_EMULATE_HARDWARE
|
||||||
|
|
||||||
#if HAVE_MSA && !CONFIG_VP9_HIGHBITDEPTH && !CONFIG_EMULATE_HARDWARE
|
#if HAVE_MSA && !CONFIG_VP9_HIGHBITDEPTH && !CONFIG_EMULATE_HARDWARE
|
||||||
|
@ -932,8 +857,12 @@ 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, 2, VPX_BITS_8),
|
||||||
make_tuple(&vp9_fht16x16_msa, &vp9_iht16x16_256_add_msa, 3,
|
make_tuple(&vp9_fht16x16_msa, &vp9_iht16x16_256_add_msa, 3,
|
||||||
VPX_BITS_8)));
|
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
|
#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
|
} // namespace
|
||||||
|
|
|
@ -71,11 +71,11 @@ typedef std::tr1::tuple<FwdTxfmFunc, InvTxfmFunc, int, vpx_bit_depth_t>
|
||||||
|
|
||||||
#if CONFIG_VP9_HIGHBITDEPTH
|
#if CONFIG_VP9_HIGHBITDEPTH
|
||||||
void idct32x32_10(const tran_low_t *in, uint8_t *out, int stride) {
|
void idct32x32_10(const tran_low_t *in, uint8_t *out, int stride) {
|
||||||
vpx_highbd_idct32x32_1024_add_c(in, out, stride, 10);
|
vpx_highbd_idct32x32_1024_add_c(in, CAST_TO_SHORTPTR(out), stride, 10);
|
||||||
}
|
}
|
||||||
|
|
||||||
void idct32x32_12(const tran_low_t *in, uint8_t *out, int stride) {
|
void idct32x32_12(const tran_low_t *in, uint8_t *out, int stride) {
|
||||||
vpx_highbd_idct32x32_1024_add_c(in, out, stride, 12);
|
vpx_highbd_idct32x32_1024_add_c(in, CAST_TO_SHORTPTR(out), stride, 12);
|
||||||
}
|
}
|
||||||
#endif // CONFIG_VP9_HIGHBITDEPTH
|
#endif // CONFIG_VP9_HIGHBITDEPTH
|
||||||
|
|
||||||
|
@ -137,7 +137,7 @@ TEST_P(Trans32x32Test, AccuracyCheck) {
|
||||||
#if CONFIG_VP9_HIGHBITDEPTH
|
#if CONFIG_VP9_HIGHBITDEPTH
|
||||||
} else {
|
} else {
|
||||||
ASM_REGISTER_STATE_CHECK(
|
ASM_REGISTER_STATE_CHECK(
|
||||||
inv_txfm_(test_temp_block, CONVERT_TO_BYTEPTR(dst16), 32));
|
inv_txfm_(test_temp_block, CAST_TO_BYTEPTR(dst16), 32));
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -275,7 +275,7 @@ TEST_P(Trans32x32Test, InverseAccuracy) {
|
||||||
ASM_REGISTER_STATE_CHECK(inv_txfm_(coeff, dst, 32));
|
ASM_REGISTER_STATE_CHECK(inv_txfm_(coeff, dst, 32));
|
||||||
#if CONFIG_VP9_HIGHBITDEPTH
|
#if CONFIG_VP9_HIGHBITDEPTH
|
||||||
} else {
|
} else {
|
||||||
ASM_REGISTER_STATE_CHECK(inv_txfm_(coeff, CONVERT_TO_BYTEPTR(dst16), 32));
|
ASM_REGISTER_STATE_CHECK(inv_txfm_(coeff, CAST_TO_BYTEPTR(dst16), 32));
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
for (int j = 0; j < kNumCoeffs; ++j) {
|
for (int j = 0; j < kNumCoeffs; ++j) {
|
||||||
|
@ -292,67 +292,6 @@ TEST_P(Trans32x32Test, InverseAccuracy) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
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;
|
using std::tr1::make_tuple;
|
||||||
|
|
||||||
#if CONFIG_VP9_HIGHBITDEPTH
|
#if CONFIG_VP9_HIGHBITDEPTH
|
||||||
|
@ -366,11 +305,6 @@ INSTANTIATE_TEST_CASE_P(
|
||||||
make_tuple(&vpx_fdct32x32_c, &vpx_idct32x32_1024_add_c, 0, VPX_BITS_8),
|
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,
|
make_tuple(&vpx_fdct32x32_rd_c, &vpx_idct32x32_1024_add_c, 1,
|
||||||
VPX_BITS_8)));
|
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
|
#else
|
||||||
INSTANTIATE_TEST_CASE_P(
|
INSTANTIATE_TEST_CASE_P(
|
||||||
C, Trans32x32Test,
|
C, Trans32x32Test,
|
||||||
|
@ -378,19 +312,16 @@ INSTANTIATE_TEST_CASE_P(
|
||||||
VPX_BITS_8),
|
VPX_BITS_8),
|
||||||
make_tuple(&vpx_fdct32x32_rd_c, &vpx_idct32x32_1024_add_c,
|
make_tuple(&vpx_fdct32x32_rd_c, &vpx_idct32x32_1024_add_c,
|
||||||
1, VPX_BITS_8)));
|
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
|
#endif // CONFIG_VP9_HIGHBITDEPTH
|
||||||
|
|
||||||
#if HAVE_NEON && !CONFIG_VP9_HIGHBITDEPTH && !CONFIG_EMULATE_HARDWARE
|
#if HAVE_NEON && !CONFIG_EMULATE_HARDWARE
|
||||||
INSTANTIATE_TEST_CASE_P(
|
INSTANTIATE_TEST_CASE_P(
|
||||||
NEON, Trans32x32Test,
|
NEON, Trans32x32Test,
|
||||||
::testing::Values(make_tuple(&vpx_fdct32x32_c, &vpx_idct32x32_1024_add_neon,
|
::testing::Values(make_tuple(&vpx_fdct32x32_neon,
|
||||||
0, VPX_BITS_8),
|
&vpx_idct32x32_1024_add_neon, 0, VPX_BITS_8),
|
||||||
make_tuple(&vpx_fdct32x32_rd_c,
|
make_tuple(&vpx_fdct32x32_rd_neon,
|
||||||
&vpx_idct32x32_1024_add_neon, 1, VPX_BITS_8)));
|
&vpx_idct32x32_1024_add_neon, 1, VPX_BITS_8)));
|
||||||
#endif // HAVE_NEON && !CONFIG_VP9_HIGHBITDEPTH && !CONFIG_EMULATE_HARDWARE
|
#endif // HAVE_NEON && !CONFIG_EMULATE_HARDWARE
|
||||||
|
|
||||||
#if HAVE_SSE2 && !CONFIG_VP9_HIGHBITDEPTH && !CONFIG_EMULATE_HARDWARE
|
#if HAVE_SSE2 && !CONFIG_VP9_HIGHBITDEPTH && !CONFIG_EMULATE_HARDWARE
|
||||||
INSTANTIATE_TEST_CASE_P(
|
INSTANTIATE_TEST_CASE_P(
|
||||||
|
@ -399,9 +330,6 @@ INSTANTIATE_TEST_CASE_P(
|
||||||
&vpx_idct32x32_1024_add_sse2, 0, VPX_BITS_8),
|
&vpx_idct32x32_1024_add_sse2, 0, VPX_BITS_8),
|
||||||
make_tuple(&vpx_fdct32x32_rd_sse2,
|
make_tuple(&vpx_fdct32x32_rd_sse2,
|
||||||
&vpx_idct32x32_1024_add_sse2, 1, VPX_BITS_8)));
|
&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
|
#endif // HAVE_SSE2 && !CONFIG_VP9_HIGHBITDEPTH && !CONFIG_EMULATE_HARDWARE
|
||||||
|
|
||||||
#if HAVE_SSE2 && CONFIG_VP9_HIGHBITDEPTH && !CONFIG_EMULATE_HARDWARE
|
#if HAVE_SSE2 && CONFIG_VP9_HIGHBITDEPTH && !CONFIG_EMULATE_HARDWARE
|
||||||
|
@ -418,9 +346,6 @@ INSTANTIATE_TEST_CASE_P(
|
||||||
VPX_BITS_8),
|
VPX_BITS_8),
|
||||||
make_tuple(&vpx_fdct32x32_rd_sse2, &vpx_idct32x32_1024_add_c, 1,
|
make_tuple(&vpx_fdct32x32_rd_sse2, &vpx_idct32x32_1024_add_c, 1,
|
||||||
VPX_BITS_8)));
|
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
|
#endif // HAVE_SSE2 && CONFIG_VP9_HIGHBITDEPTH && !CONFIG_EMULATE_HARDWARE
|
||||||
|
|
||||||
#if HAVE_AVX2 && !CONFIG_VP9_HIGHBITDEPTH && !CONFIG_EMULATE_HARDWARE
|
#if HAVE_AVX2 && !CONFIG_VP9_HIGHBITDEPTH && !CONFIG_EMULATE_HARDWARE
|
||||||
|
@ -439,8 +364,14 @@ INSTANTIATE_TEST_CASE_P(
|
||||||
&vpx_idct32x32_1024_add_msa, 0, VPX_BITS_8),
|
&vpx_idct32x32_1024_add_msa, 0, VPX_BITS_8),
|
||||||
make_tuple(&vpx_fdct32x32_rd_msa,
|
make_tuple(&vpx_fdct32x32_rd_msa,
|
||||||
&vpx_idct32x32_1024_add_msa, 1, VPX_BITS_8)));
|
&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
|
#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
|
} // namespace
|
||||||
|
|
|
@ -0,0 +1,169 @@
|
||||||
|
/*
|
||||||
|
* 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 libvpx_test::ACMRandom;
|
||||||
|
using libvpx_test::Buffer;
|
||||||
|
using std::tr1::tuple;
|
||||||
|
using std::tr1::make_tuple;
|
||||||
|
|
||||||
|
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
|
|
@ -0,0 +1,737 @@
|
||||||
|
/*
|
||||||
|
* 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 libvpx_test::ACMRandom;
|
||||||
|
using libvpx_test::Buffer;
|
||||||
|
using std::tr1::tuple;
|
||||||
|
using std::tr1::make_tuple;
|
||||||
|
|
||||||
|
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);
|
||||||
|
|
||||||
|
/* forward transform, inverse transform, size, transform type, bit depth */
|
||||||
|
typedef tuple<FdctFunc, IdctFunc, int, int, vpx_bit_depth_t> DctParam;
|
||||||
|
typedef tuple<FhtFunc, IhtFunc, int, int, vpx_bit_depth_t> HtParam;
|
||||||
|
|
||||||
|
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());
|
||||||
|
}
|
||||||
|
|
||||||
|
#if CONFIG_VP9_HIGHBITDEPTH
|
||||||
|
#define idctNxN(n, coeffs, bitdepth) \
|
||||||
|
void idct##n##x##n##_##bitdepth(const tran_low_t *in, uint8_t *out, \
|
||||||
|
int stride) { \
|
||||||
|
vpx_highbd_idct##n##x##n##_##coeffs##_add_c(in, CAST_TO_SHORTPTR(out), \
|
||||||
|
stride, bitdepth); \
|
||||||
|
}
|
||||||
|
|
||||||
|
idctNxN(4, 16, 10);
|
||||||
|
idctNxN(4, 16, 12);
|
||||||
|
idctNxN(8, 64, 10);
|
||||||
|
idctNxN(8, 64, 12);
|
||||||
|
idctNxN(16, 256, 10);
|
||||||
|
idctNxN(16, 256, 12);
|
||||||
|
idctNxN(32, 1024, 10);
|
||||||
|
idctNxN(32, 1024, 12);
|
||||||
|
|
||||||
|
#define ihtNxN(n, coeffs, bitdepth) \
|
||||||
|
void iht##n##x##n##_##bitdepth(const tran_low_t *in, uint8_t *out, \
|
||||||
|
int stride, int tx_type) { \
|
||||||
|
vp9_highbd_iht##n##x##n##_##coeffs##_add_c(in, CAST_TO_SHORTPTR(out), \
|
||||||
|
stride, tx_type, bitdepth); \
|
||||||
|
}
|
||||||
|
|
||||||
|
ihtNxN(4, 16, 10);
|
||||||
|
ihtNxN(4, 16, 12);
|
||||||
|
ihtNxN(8, 64, 10);
|
||||||
|
ihtNxN(8, 64, 12);
|
||||||
|
ihtNxN(16, 256, 10);
|
||||||
|
// ihtNxN(16, 256, 12);
|
||||||
|
|
||||||
|
void iwht4x4_10(const tran_low_t *in, uint8_t *out, int stride) {
|
||||||
|
vpx_highbd_iwht4x4_16_add_c(in, CAST_TO_SHORTPTR(out), stride, 10);
|
||||||
|
}
|
||||||
|
|
||||||
|
void iwht4x4_12(const tran_low_t *in, uint8_t *out, int stride) {
|
||||||
|
vpx_highbd_iwht4x4_16_add_c(in, CAST_TO_SHORTPTR(out), stride, 12);
|
||||||
|
}
|
||||||
|
#endif // CONFIG_VP9_HIGHBITDEPTH
|
||||||
|
|
||||||
|
class TransTestBase {
|
||||||
|
public:
|
||||||
|
virtual void TearDown() { libvpx_test::ClearSystemState(); }
|
||||||
|
|
||||||
|
protected:
|
||||||
|
virtual void RunFwdTxfm(const Buffer<int16_t> &in,
|
||||||
|
Buffer<tran_low_t> *out) = 0;
|
||||||
|
|
||||||
|
virtual void RunInvTxfm(const Buffer<tran_low_t> &in, uint8_t *out) = 0;
|
||||||
|
|
||||||
|
void RunAccuracyCheck(int limit) {
|
||||||
|
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());
|
||||||
|
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, 16);
|
||||||
|
ASSERT_TRUE(src.Init());
|
||||||
|
#if CONFIG_VP9_HIGHBITDEPTH
|
||||||
|
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, 16);
|
||||||
|
ASSERT_TRUE(src16.Init());
|
||||||
|
#endif // CONFIG_VP9_HIGHBITDEPTH
|
||||||
|
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) {
|
||||||
|
if (bit_depth_ == 8) {
|
||||||
|
src.Set(&rnd, &ACMRandom::Rand8);
|
||||||
|
dst.Set(&rnd, &ACMRandom::Rand8);
|
||||||
|
// Initialize a test block with input range [-255, 255].
|
||||||
|
for (int h = 0; h < size_; ++h) {
|
||||||
|
for (int w = 0; w < size_; ++w) {
|
||||||
|
test_input_block.TopLeftPixel()[h * test_input_block.stride() + w] =
|
||||||
|
src.TopLeftPixel()[h * src.stride() + w] -
|
||||||
|
dst.TopLeftPixel()[h * dst.stride() + w];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#if CONFIG_VP9_HIGHBITDEPTH
|
||||||
|
} else {
|
||||||
|
src16.Set(&rnd, 0, max_pixel_value_);
|
||||||
|
dst16.Set(&rnd, 0, max_pixel_value_);
|
||||||
|
for (int h = 0; h < size_; ++h) {
|
||||||
|
for (int w = 0; w < size_; ++w) {
|
||||||
|
test_input_block.TopLeftPixel()[h * test_input_block.stride() + w] =
|
||||||
|
src16.TopLeftPixel()[h * src16.stride() + w] -
|
||||||
|
dst16.TopLeftPixel()[h * dst16.stride() + w];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif // CONFIG_VP9_HIGHBITDEPTH
|
||||||
|
}
|
||||||
|
|
||||||
|
ASM_REGISTER_STATE_CHECK(RunFwdTxfm(test_input_block, &test_temp_block));
|
||||||
|
if (bit_depth_ == VPX_BITS_8) {
|
||||||
|
ASM_REGISTER_STATE_CHECK(
|
||||||
|
RunInvTxfm(test_temp_block, dst.TopLeftPixel()));
|
||||||
|
#if CONFIG_VP9_HIGHBITDEPTH
|
||||||
|
} else {
|
||||||
|
ASM_REGISTER_STATE_CHECK(
|
||||||
|
RunInvTxfm(test_temp_block, CAST_TO_BYTEPTR(dst16.TopLeftPixel())));
|
||||||
|
#endif // CONFIG_VP9_HIGHBITDEPTH
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int h = 0; h < size_; ++h) {
|
||||||
|
for (int w = 0; w < size_; ++w) {
|
||||||
|
int diff;
|
||||||
|
#if CONFIG_VP9_HIGHBITDEPTH
|
||||||
|
if (bit_depth_ != 8) {
|
||||||
|
diff = dst16.TopLeftPixel()[h * dst16.stride() + w] -
|
||||||
|
src16.TopLeftPixel()[h * src16.stride() + w];
|
||||||
|
} else {
|
||||||
|
#endif // CONFIG_VP9_HIGHBITDEPTH
|
||||||
|
diff = dst.TopLeftPixel()[h * dst.stride() + w] -
|
||||||
|
src.TopLeftPixel()[h * src.stride() + w];
|
||||||
|
#if CONFIG_VP9_HIGHBITDEPTH
|
||||||
|
}
|
||||||
|
#endif // CONFIG_VP9_HIGHBITDEPTH
|
||||||
|
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;
|
||||||
|
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() {
|
||||||
|
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: 4x4 FDCT 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) {
|
||||||
|
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) {
|
||||||
|
// Initialize a test block with input range [-max_pixel_value_,
|
||||||
|
// max_pixel_value_].
|
||||||
|
if (bit_depth_ == VPX_BITS_8) {
|
||||||
|
src.Set(&rnd, &ACMRandom::Rand8);
|
||||||
|
dst.Set(&rnd, &ACMRandom::Rand8);
|
||||||
|
for (int h = 0; h < size_; ++h) {
|
||||||
|
for (int w = 0; w < size_; ++w) {
|
||||||
|
in.TopLeftPixel()[h * in.stride() + w] =
|
||||||
|
src.TopLeftPixel()[h * src.stride() + w] -
|
||||||
|
dst.TopLeftPixel()[h * dst.stride() + w];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#if CONFIG_VP9_HIGHBITDEPTH
|
||||||
|
} else {
|
||||||
|
src16.Set(&rnd, 0, max_pixel_value_);
|
||||||
|
dst16.Set(&rnd, 0, max_pixel_value_);
|
||||||
|
for (int h = 0; h < size_; ++h) {
|
||||||
|
for (int w = 0; w < size_; ++w) {
|
||||||
|
in.TopLeftPixel()[h * in.stride() + w] =
|
||||||
|
src16.TopLeftPixel()[h * src16.stride() + w] -
|
||||||
|
dst16.TopLeftPixel()[h * dst16.stride() + w];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif // CONFIG_VP9_HIGHBITDEPTH
|
||||||
|
}
|
||||||
|
|
||||||
|
fwd_txfm_ref(in, &coeff, size_, tx_type_);
|
||||||
|
|
||||||
|
if (bit_depth_ == VPX_BITS_8) {
|
||||||
|
ASM_REGISTER_STATE_CHECK(RunInvTxfm(coeff, dst.TopLeftPixel()));
|
||||||
|
#if CONFIG_VP9_HIGHBITDEPTH
|
||||||
|
} else {
|
||||||
|
ASM_REGISTER_STATE_CHECK(
|
||||||
|
RunInvTxfm(coeff, CAST_TO_BYTEPTR(dst16.TopLeftPixel())));
|
||||||
|
#endif // CONFIG_VP9_HIGHBITDEPTH
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int h = 0; h < size_; ++h) {
|
||||||
|
for (int w = 0; w < size_; ++w) {
|
||||||
|
int diff;
|
||||||
|
#if CONFIG_VP9_HIGHBITDEPTH
|
||||||
|
if (bit_depth_ != 8) {
|
||||||
|
diff = dst16.TopLeftPixel()[h * dst16.stride() + w] -
|
||||||
|
src16.TopLeftPixel()[h * src16.stride() + w];
|
||||||
|
} else {
|
||||||
|
#endif // CONFIG_VP9_HIGHBITDEPTH
|
||||||
|
diff = dst.TopLeftPixel()[h * dst.stride() + w] -
|
||||||
|
src.TopLeftPixel()[h * src.stride() + w];
|
||||||
|
#if CONFIG_VP9_HIGHBITDEPTH
|
||||||
|
}
|
||||||
|
#endif // CONFIG_VP9_HIGHBITDEPTH
|
||||||
|
const uint32_t error = diff * diff;
|
||||||
|
EXPECT_GE(static_cast<uint32_t>(limit), error)
|
||||||
|
<< "Error: " << size_ << "x" << size_ << " IDCT has error "
|
||||||
|
<< error << " at " << w << "," << h;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
FhtFuncRef fwd_txfm_ref;
|
||||||
|
vpx_bit_depth_t bit_depth_;
|
||||||
|
int tx_type_;
|
||||||
|
int max_pixel_value_;
|
||||||
|
int size_;
|
||||||
|
};
|
||||||
|
|
||||||
|
class TransDCT : public TransTestBase,
|
||||||
|
public ::testing::TestWithParam<DctParam> {
|
||||||
|
public:
|
||||||
|
TransDCT() {
|
||||||
|
fwd_txfm_ref = fdct_ref;
|
||||||
|
fwd_txfm_ = GET_PARAM(0);
|
||||||
|
inv_txfm_ = GET_PARAM(1);
|
||||||
|
size_ = GET_PARAM(2);
|
||||||
|
tx_type_ = GET_PARAM(3);
|
||||||
|
bit_depth_ = GET_PARAM(4);
|
||||||
|
max_pixel_value_ = (1 << bit_depth_) - 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected:
|
||||||
|
void RunFwdTxfm(const Buffer<int16_t> &in, Buffer<tran_low_t> *out) {
|
||||||
|
fwd_txfm_(in.TopLeftPixel(), out->TopLeftPixel(), in.stride());
|
||||||
|
}
|
||||||
|
|
||||||
|
void RunInvTxfm(const Buffer<tran_low_t> &in, uint8_t *out) {
|
||||||
|
inv_txfm_(in.TopLeftPixel(), out, in.stride());
|
||||||
|
}
|
||||||
|
|
||||||
|
FdctFunc fwd_txfm_;
|
||||||
|
IdctFunc inv_txfm_;
|
||||||
|
};
|
||||||
|
|
||||||
|
TEST_P(TransDCT, AccuracyCheck) { RunAccuracyCheck(1); }
|
||||||
|
|
||||||
|
TEST_P(TransDCT, CoeffCheck) { RunCoeffCheck(); }
|
||||||
|
|
||||||
|
TEST_P(TransDCT, MemCheck) { RunMemCheck(); }
|
||||||
|
|
||||||
|
TEST_P(TransDCT, InvAccuracyCheck) { RunInvAccuracyCheck(1); }
|
||||||
|
|
||||||
|
#if CONFIG_VP9_HIGHBITDEPTH
|
||||||
|
INSTANTIATE_TEST_CASE_P(
|
||||||
|
C, TransDCT,
|
||||||
|
::testing::Values(
|
||||||
|
make_tuple(&vpx_highbd_fdct32x32_c, &idct32x32_10, 32, 0, VPX_BITS_10),
|
||||||
|
make_tuple(&vpx_highbd_fdct32x32_c, &idct32x32_12, 32, 0, VPX_BITS_10),
|
||||||
|
make_tuple(&vpx_fdct32x32_c, &vpx_idct32x32_1024_add_c, 32, 0,
|
||||||
|
VPX_BITS_8),
|
||||||
|
make_tuple(&vpx_highbd_fdct16x16_c, &idct16x16_10, 16, 0, VPX_BITS_10),
|
||||||
|
make_tuple(&vpx_highbd_fdct16x16_c, &idct16x16_12, 16, 0, VPX_BITS_10),
|
||||||
|
make_tuple(&vpx_fdct16x16_c, &vpx_idct16x16_256_add_c, 16, 0,
|
||||||
|
VPX_BITS_8),
|
||||||
|
make_tuple(&vpx_highbd_fdct8x8_c, &idct8x8_10, 8, 0, VPX_BITS_10),
|
||||||
|
make_tuple(&vpx_highbd_fdct8x8_c, &idct8x8_12, 8, 0, VPX_BITS_10),
|
||||||
|
make_tuple(&vpx_fdct8x8_c, &vpx_idct8x8_64_add_c, 8, 0, VPX_BITS_8),
|
||||||
|
make_tuple(&vpx_highbd_fdct4x4_c, &idct4x4_10, 4, 0, VPX_BITS_10),
|
||||||
|
make_tuple(&vpx_highbd_fdct4x4_c, &idct4x4_12, 4, 0, VPX_BITS_12),
|
||||||
|
make_tuple(&vpx_fdct4x4_c, &vpx_idct4x4_16_add_c, 4, 0, VPX_BITS_8)));
|
||||||
|
#else
|
||||||
|
INSTANTIATE_TEST_CASE_P(
|
||||||
|
C, TransDCT,
|
||||||
|
::testing::Values(
|
||||||
|
make_tuple(&vpx_fdct32x32_c, &vpx_idct32x32_1024_add_c, 32, 0,
|
||||||
|
VPX_BITS_8),
|
||||||
|
make_tuple(&vpx_fdct16x16_c, &vpx_idct16x16_256_add_c, 16, 0,
|
||||||
|
VPX_BITS_8),
|
||||||
|
make_tuple(&vpx_fdct8x8_c, &vpx_idct8x8_64_add_c, 8, 0, VPX_BITS_8),
|
||||||
|
make_tuple(&vpx_fdct4x4_c, &vpx_idct4x4_16_add_c, 4, 0, VPX_BITS_8)));
|
||||||
|
#endif // CONFIG_VP9_HIGHBITDEPTH
|
||||||
|
|
||||||
|
#if HAVE_SSE2
|
||||||
|
#if !CONFIG_EMULATE_HARDWARE
|
||||||
|
#if CONFIG_VP9_HIGHBITDEPTH
|
||||||
|
/* TODO:(johannkoenig) Determine why these fail AccuracyCheck
|
||||||
|
make_tuple(&vpx_highbd_fdct32x32_sse2, &idct32x32_12, 32, 0, VPX_BITS_12),
|
||||||
|
make_tuple(&vpx_highbd_fdct16x16_sse2, &idct16x16_12, 16, 0, VPX_BITS_12),
|
||||||
|
*/
|
||||||
|
INSTANTIATE_TEST_CASE_P(
|
||||||
|
SSE2, TransDCT,
|
||||||
|
::testing::Values(
|
||||||
|
make_tuple(&vpx_highbd_fdct32x32_sse2, &idct32x32_10, 32, 0,
|
||||||
|
VPX_BITS_10),
|
||||||
|
make_tuple(&vpx_fdct32x32_sse2, &vpx_idct32x32_1024_add_sse2, 32, 0,
|
||||||
|
VPX_BITS_8),
|
||||||
|
make_tuple(&vpx_highbd_fdct16x16_sse2, &idct16x16_10, 16, 0,
|
||||||
|
VPX_BITS_10),
|
||||||
|
make_tuple(&vpx_fdct16x16_sse2, &vpx_idct16x16_256_add_sse2, 16, 0,
|
||||||
|
VPX_BITS_8),
|
||||||
|
make_tuple(&vpx_highbd_fdct8x8_sse2, &idct8x8_10, 8, 0, VPX_BITS_10),
|
||||||
|
make_tuple(&vpx_highbd_fdct8x8_sse2, &idct8x8_12, 8, 0, VPX_BITS_12),
|
||||||
|
make_tuple(&vpx_fdct8x8_sse2, &vpx_idct8x8_64_add_sse2, 8, 0,
|
||||||
|
VPX_BITS_8),
|
||||||
|
make_tuple(&vpx_highbd_fdct4x4_sse2, &idct4x4_10, 4, 0, VPX_BITS_10),
|
||||||
|
make_tuple(&vpx_highbd_fdct4x4_sse2, &idct4x4_12, 4, 0, VPX_BITS_12),
|
||||||
|
make_tuple(&vpx_fdct4x4_sse2, &vpx_idct4x4_16_add_sse2, 4, 0,
|
||||||
|
VPX_BITS_8)));
|
||||||
|
#else
|
||||||
|
INSTANTIATE_TEST_CASE_P(
|
||||||
|
SSE2, TransDCT,
|
||||||
|
::testing::Values(make_tuple(&vpx_fdct32x32_sse2,
|
||||||
|
&vpx_idct32x32_1024_add_sse2, 32, 0,
|
||||||
|
VPX_BITS_8),
|
||||||
|
make_tuple(&vpx_fdct16x16_sse2,
|
||||||
|
&vpx_idct16x16_256_add_sse2, 16, 0,
|
||||||
|
VPX_BITS_8),
|
||||||
|
make_tuple(&vpx_fdct8x8_sse2, &vpx_idct8x8_64_add_sse2, 8,
|
||||||
|
0, VPX_BITS_8),
|
||||||
|
make_tuple(&vpx_fdct4x4_sse2, &vpx_idct4x4_16_add_sse2, 4,
|
||||||
|
0, VPX_BITS_8)));
|
||||||
|
#endif // CONFIG_VP9_HIGHBITDEPTH
|
||||||
|
#endif // !CONFIG_EMULATE_HARDWARE
|
||||||
|
#endif // HAVE_SSE2
|
||||||
|
|
||||||
|
#if !CONFIG_VP9_HIGHBITDEPTH
|
||||||
|
#if HAVE_SSSE3 && !CONFIG_EMULATE_HARDWARE
|
||||||
|
#if !ARCH_X86_64
|
||||||
|
// TODO(johannkoenig): high bit depth fdct8x8.
|
||||||
|
INSTANTIATE_TEST_CASE_P(
|
||||||
|
SSSE3, TransDCT,
|
||||||
|
::testing::Values(make_tuple(&vpx_fdct32x32_c, &vpx_idct32x32_1024_add_sse2,
|
||||||
|
32, 0, VPX_BITS_8),
|
||||||
|
make_tuple(&vpx_fdct8x8_c, &vpx_idct8x8_64_add_sse2, 8, 0,
|
||||||
|
VPX_BITS_8)));
|
||||||
|
#else
|
||||||
|
// vpx_fdct8x8_ssse3 is only available in 64 bit builds.
|
||||||
|
INSTANTIATE_TEST_CASE_P(
|
||||||
|
SSSE3, TransDCT,
|
||||||
|
::testing::Values(make_tuple(&vpx_fdct32x32_c, &vpx_idct32x32_1024_add_sse2,
|
||||||
|
32, 0, VPX_BITS_8),
|
||||||
|
make_tuple(&vpx_fdct8x8_ssse3, &vpx_idct8x8_64_add_sse2,
|
||||||
|
8, 0, VPX_BITS_8)));
|
||||||
|
#endif // !ARCH_X86_64
|
||||||
|
#endif // HAVE_SSSE3 && !CONFIG_EMULATE_HARDWARE
|
||||||
|
#endif // !CONFIG_VP9_HIGHBITDEPTH
|
||||||
|
|
||||||
|
#if !CONFIG_VP9_HIGHBITDEPTH && HAVE_AVX2 && !CONFIG_EMULATE_HARDWARE
|
||||||
|
// TODO(johannkoenig): high bit depth fdct32x32.
|
||||||
|
INSTANTIATE_TEST_CASE_P(
|
||||||
|
AVX2, TransDCT, ::testing::Values(make_tuple(&vpx_fdct32x32_avx2,
|
||||||
|
&vpx_idct32x32_1024_add_sse2,
|
||||||
|
32, 0, VPX_BITS_8)));
|
||||||
|
|
||||||
|
#endif // !CONFIG_VP9_HIGHBITDEPTH && HAVE_AVX2 && !CONFIG_EMULATE_HARDWARE
|
||||||
|
|
||||||
|
#if HAVE_NEON
|
||||||
|
#if !CONFIG_EMULATE_HARDWARE
|
||||||
|
INSTANTIATE_TEST_CASE_P(
|
||||||
|
NEON, TransDCT,
|
||||||
|
::testing::Values(make_tuple(&vpx_fdct32x32_neon,
|
||||||
|
&vpx_idct32x32_1024_add_neon, 32, 0,
|
||||||
|
VPX_BITS_8),
|
||||||
|
make_tuple(&vpx_fdct16x16_neon,
|
||||||
|
&vpx_idct16x16_256_add_neon, 16, 0,
|
||||||
|
VPX_BITS_8),
|
||||||
|
make_tuple(&vpx_fdct8x8_neon, &vpx_idct8x8_64_add_neon, 8,
|
||||||
|
0, VPX_BITS_8),
|
||||||
|
make_tuple(&vpx_fdct4x4_neon, &vpx_idct4x4_16_add_neon, 4,
|
||||||
|
0, VPX_BITS_8)));
|
||||||
|
#endif // !CONFIG_EMULATE_HARDWARE
|
||||||
|
#endif // HAVE_NEON
|
||||||
|
|
||||||
|
#if HAVE_MSA
|
||||||
|
#if !CONFIG_VP9_HIGHBITDEPTH
|
||||||
|
#if !CONFIG_EMULATE_HARDWARE
|
||||||
|
INSTANTIATE_TEST_CASE_P(
|
||||||
|
MSA, TransDCT,
|
||||||
|
::testing::Values(
|
||||||
|
make_tuple(&vpx_fdct32x32_msa, &vpx_idct32x32_1024_add_msa, 32, 0,
|
||||||
|
VPX_BITS_8),
|
||||||
|
make_tuple(&vpx_fdct16x16_msa, &vpx_idct16x16_256_add_msa, 16, 0,
|
||||||
|
VPX_BITS_8),
|
||||||
|
make_tuple(&vpx_fdct8x8_msa, &vpx_idct8x8_64_add_msa, 8, 0, VPX_BITS_8),
|
||||||
|
make_tuple(&vpx_fdct4x4_msa, &vpx_idct4x4_16_add_msa, 4, 0,
|
||||||
|
VPX_BITS_8)));
|
||||||
|
#endif // !CONFIG_EMULATE_HARDWARE
|
||||||
|
#endif // !CONFIG_VP9_HIGHBITDEPTH
|
||||||
|
#endif // HAVE_MSA
|
||||||
|
|
||||||
|
#if HAVE_VSX && !CONFIG_VP9_HIGHBITDEPTH && !CONFIG_EMULATE_HARDWARE
|
||||||
|
INSTANTIATE_TEST_CASE_P(VSX, TransDCT,
|
||||||
|
::testing::Values(make_tuple(&vpx_fdct4x4_c,
|
||||||
|
&vpx_idct4x4_16_add_vsx, 4,
|
||||||
|
0, VPX_BITS_8)));
|
||||||
|
#endif // HAVE_VSX && !CONFIG_VP9_HIGHBITDEPTH && !CONFIG_EMULATE_HARDWARE
|
||||||
|
|
||||||
|
class TransHT : public TransTestBase, public ::testing::TestWithParam<HtParam> {
|
||||||
|
public:
|
||||||
|
TransHT() {
|
||||||
|
fwd_txfm_ref = fht_ref;
|
||||||
|
fwd_txfm_ = GET_PARAM(0);
|
||||||
|
inv_txfm_ = GET_PARAM(1);
|
||||||
|
size_ = GET_PARAM(2);
|
||||||
|
tx_type_ = GET_PARAM(3);
|
||||||
|
bit_depth_ = GET_PARAM(4);
|
||||||
|
max_pixel_value_ = (1 << bit_depth_) - 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected:
|
||||||
|
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, in.stride(), tx_type_);
|
||||||
|
}
|
||||||
|
|
||||||
|
FhtFunc fwd_txfm_;
|
||||||
|
IhtFunc inv_txfm_;
|
||||||
|
};
|
||||||
|
|
||||||
|
TEST_P(TransHT, AccuracyCheck) { RunAccuracyCheck(1); }
|
||||||
|
|
||||||
|
TEST_P(TransHT, CoeffCheck) { RunCoeffCheck(); }
|
||||||
|
|
||||||
|
TEST_P(TransHT, MemCheck) { RunMemCheck(); }
|
||||||
|
|
||||||
|
TEST_P(TransHT, InvAccuracyCheck) { RunInvAccuracyCheck(1); }
|
||||||
|
|
||||||
|
/* TODO:(johannkoenig) Determine why these fail AccuracyCheck
|
||||||
|
make_tuple(&vp9_highbd_fht16x16_c, &iht16x16_12, 16, 0, VPX_BITS_12),
|
||||||
|
make_tuple(&vp9_highbd_fht16x16_c, &iht16x16_12, 16, 1, VPX_BITS_12),
|
||||||
|
make_tuple(&vp9_highbd_fht16x16_c, &iht16x16_12, 16, 2, VPX_BITS_12),
|
||||||
|
make_tuple(&vp9_highbd_fht16x16_c, &iht16x16_12, 16, 3, VPX_BITS_12),
|
||||||
|
*/
|
||||||
|
#if CONFIG_VP9_HIGHBITDEPTH
|
||||||
|
INSTANTIATE_TEST_CASE_P(
|
||||||
|
C, TransHT,
|
||||||
|
::testing::Values(
|
||||||
|
make_tuple(&vp9_highbd_fht16x16_c, &iht16x16_10, 16, 0, VPX_BITS_10),
|
||||||
|
make_tuple(&vp9_highbd_fht16x16_c, &iht16x16_10, 16, 1, VPX_BITS_10),
|
||||||
|
make_tuple(&vp9_highbd_fht16x16_c, &iht16x16_10, 16, 2, VPX_BITS_10),
|
||||||
|
make_tuple(&vp9_highbd_fht16x16_c, &iht16x16_10, 16, 3, VPX_BITS_10),
|
||||||
|
make_tuple(&vp9_fht16x16_c, &vp9_iht16x16_256_add_c, 16, 0, VPX_BITS_8),
|
||||||
|
make_tuple(&vp9_fht16x16_c, &vp9_iht16x16_256_add_c, 16, 1, VPX_BITS_8),
|
||||||
|
make_tuple(&vp9_fht16x16_c, &vp9_iht16x16_256_add_c, 16, 2, VPX_BITS_8),
|
||||||
|
make_tuple(&vp9_fht16x16_c, &vp9_iht16x16_256_add_c, 16, 3, VPX_BITS_8),
|
||||||
|
make_tuple(&vp9_highbd_fht8x8_c, &iht8x8_10, 8, 0, VPX_BITS_10),
|
||||||
|
make_tuple(&vp9_highbd_fht8x8_c, &iht8x8_10, 8, 1, VPX_BITS_10),
|
||||||
|
make_tuple(&vp9_highbd_fht8x8_c, &iht8x8_10, 8, 2, VPX_BITS_10),
|
||||||
|
make_tuple(&vp9_highbd_fht8x8_c, &iht8x8_10, 8, 3, VPX_BITS_10),
|
||||||
|
make_tuple(&vp9_highbd_fht8x8_c, &iht8x8_12, 8, 0, VPX_BITS_12),
|
||||||
|
make_tuple(&vp9_highbd_fht8x8_c, &iht8x8_12, 8, 1, VPX_BITS_12),
|
||||||
|
make_tuple(&vp9_highbd_fht8x8_c, &iht8x8_12, 8, 2, VPX_BITS_12),
|
||||||
|
make_tuple(&vp9_highbd_fht8x8_c, &iht8x8_12, 8, 3, VPX_BITS_12),
|
||||||
|
make_tuple(&vp9_fht8x8_c, &vp9_iht8x8_64_add_c, 8, 0, VPX_BITS_8),
|
||||||
|
make_tuple(&vp9_fht8x8_c, &vp9_iht8x8_64_add_c, 8, 1, VPX_BITS_8),
|
||||||
|
make_tuple(&vp9_fht8x8_c, &vp9_iht8x8_64_add_c, 8, 2, VPX_BITS_8),
|
||||||
|
make_tuple(&vp9_fht8x8_c, &vp9_iht8x8_64_add_c, 8, 3, VPX_BITS_8),
|
||||||
|
make_tuple(&vp9_highbd_fht4x4_c, &iht4x4_10, 4, 0, VPX_BITS_10),
|
||||||
|
make_tuple(&vp9_highbd_fht4x4_c, &iht4x4_10, 4, 1, VPX_BITS_10),
|
||||||
|
make_tuple(&vp9_highbd_fht4x4_c, &iht4x4_10, 4, 2, VPX_BITS_10),
|
||||||
|
make_tuple(&vp9_highbd_fht4x4_c, &iht4x4_10, 4, 3, VPX_BITS_10),
|
||||||
|
make_tuple(&vp9_highbd_fht4x4_c, &iht4x4_12, 4, 0, VPX_BITS_12),
|
||||||
|
make_tuple(&vp9_highbd_fht4x4_c, &iht4x4_12, 4, 1, VPX_BITS_12),
|
||||||
|
make_tuple(&vp9_highbd_fht4x4_c, &iht4x4_12, 4, 2, VPX_BITS_12),
|
||||||
|
make_tuple(&vp9_highbd_fht4x4_c, &iht4x4_12, 4, 3, VPX_BITS_12),
|
||||||
|
make_tuple(&vp9_fht4x4_c, &vp9_iht4x4_16_add_c, 4, 0, VPX_BITS_8),
|
||||||
|
make_tuple(&vp9_fht4x4_c, &vp9_iht4x4_16_add_c, 4, 1, VPX_BITS_8),
|
||||||
|
make_tuple(&vp9_fht4x4_c, &vp9_iht4x4_16_add_c, 4, 2, VPX_BITS_8),
|
||||||
|
make_tuple(&vp9_fht4x4_c, &vp9_iht4x4_16_add_c, 4, 3, VPX_BITS_8)));
|
||||||
|
#else
|
||||||
|
INSTANTIATE_TEST_CASE_P(
|
||||||
|
C, TransHT,
|
||||||
|
::testing::Values(
|
||||||
|
make_tuple(&vp9_fht16x16_c, &vp9_iht16x16_256_add_c, 16, 0, VPX_BITS_8),
|
||||||
|
make_tuple(&vp9_fht16x16_c, &vp9_iht16x16_256_add_c, 16, 1, VPX_BITS_8),
|
||||||
|
make_tuple(&vp9_fht16x16_c, &vp9_iht16x16_256_add_c, 16, 2, VPX_BITS_8),
|
||||||
|
make_tuple(&vp9_fht16x16_c, &vp9_iht16x16_256_add_c, 16, 3, VPX_BITS_8),
|
||||||
|
|
||||||
|
make_tuple(&vp9_fht8x8_c, &vp9_iht8x8_64_add_c, 8, 0, VPX_BITS_8),
|
||||||
|
make_tuple(&vp9_fht8x8_c, &vp9_iht8x8_64_add_c, 8, 1, VPX_BITS_8),
|
||||||
|
make_tuple(&vp9_fht8x8_c, &vp9_iht8x8_64_add_c, 8, 2, VPX_BITS_8),
|
||||||
|
make_tuple(&vp9_fht8x8_c, &vp9_iht8x8_64_add_c, 8, 3, VPX_BITS_8),
|
||||||
|
|
||||||
|
make_tuple(&vp9_fht4x4_c, &vp9_iht4x4_16_add_c, 4, 0, VPX_BITS_8),
|
||||||
|
make_tuple(&vp9_fht4x4_c, &vp9_iht4x4_16_add_c, 4, 1, VPX_BITS_8),
|
||||||
|
make_tuple(&vp9_fht4x4_c, &vp9_iht4x4_16_add_c, 4, 2, VPX_BITS_8),
|
||||||
|
make_tuple(&vp9_fht4x4_c, &vp9_iht4x4_16_add_c, 4, 3, VPX_BITS_8)));
|
||||||
|
#endif // CONFIG_VP9_HIGHBITDEPTH
|
||||||
|
|
||||||
|
#if HAVE_SSE2
|
||||||
|
INSTANTIATE_TEST_CASE_P(
|
||||||
|
SSE2, TransHT,
|
||||||
|
::testing::Values(
|
||||||
|
make_tuple(&vp9_fht16x16_sse2, &vp9_iht16x16_256_add_sse2, 16, 0,
|
||||||
|
VPX_BITS_8),
|
||||||
|
make_tuple(&vp9_fht16x16_sse2, &vp9_iht16x16_256_add_sse2, 16, 1,
|
||||||
|
VPX_BITS_8),
|
||||||
|
make_tuple(&vp9_fht16x16_sse2, &vp9_iht16x16_256_add_sse2, 16, 2,
|
||||||
|
VPX_BITS_8),
|
||||||
|
make_tuple(&vp9_fht16x16_sse2, &vp9_iht16x16_256_add_sse2, 16, 3,
|
||||||
|
VPX_BITS_8),
|
||||||
|
|
||||||
|
make_tuple(&vp9_fht8x8_sse2, &vp9_iht8x8_64_add_sse2, 8, 0, VPX_BITS_8),
|
||||||
|
make_tuple(&vp9_fht8x8_sse2, &vp9_iht8x8_64_add_sse2, 8, 1, VPX_BITS_8),
|
||||||
|
make_tuple(&vp9_fht8x8_sse2, &vp9_iht8x8_64_add_sse2, 8, 2, VPX_BITS_8),
|
||||||
|
make_tuple(&vp9_fht8x8_sse2, &vp9_iht8x8_64_add_sse2, 8, 3, VPX_BITS_8),
|
||||||
|
|
||||||
|
make_tuple(&vp9_fht4x4_sse2, &vp9_iht4x4_16_add_sse2, 4, 0, VPX_BITS_8),
|
||||||
|
make_tuple(&vp9_fht4x4_sse2, &vp9_iht4x4_16_add_sse2, 4, 1, VPX_BITS_8),
|
||||||
|
make_tuple(&vp9_fht4x4_sse2, &vp9_iht4x4_16_add_sse2, 4, 2, VPX_BITS_8),
|
||||||
|
make_tuple(&vp9_fht4x4_sse2, &vp9_iht4x4_16_add_sse2, 4, 3,
|
||||||
|
VPX_BITS_8)));
|
||||||
|
#endif // HAVE_SSE2
|
||||||
|
|
||||||
|
class TransWHT : public TransTestBase,
|
||||||
|
public ::testing::TestWithParam<DctParam> {
|
||||||
|
public:
|
||||||
|
TransWHT() {
|
||||||
|
fwd_txfm_ref = fwht_ref;
|
||||||
|
fwd_txfm_ = GET_PARAM(0);
|
||||||
|
inv_txfm_ = GET_PARAM(1);
|
||||||
|
size_ = GET_PARAM(2);
|
||||||
|
tx_type_ = GET_PARAM(3);
|
||||||
|
bit_depth_ = GET_PARAM(4);
|
||||||
|
max_pixel_value_ = (1 << bit_depth_) - 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected:
|
||||||
|
void RunFwdTxfm(const Buffer<int16_t> &in, Buffer<tran_low_t> *out) {
|
||||||
|
fwd_txfm_(in.TopLeftPixel(), out->TopLeftPixel(), in.stride());
|
||||||
|
}
|
||||||
|
|
||||||
|
void RunInvTxfm(const Buffer<tran_low_t> &in, uint8_t *out) {
|
||||||
|
inv_txfm_(in.TopLeftPixel(), out, in.stride());
|
||||||
|
}
|
||||||
|
|
||||||
|
FdctFunc fwd_txfm_;
|
||||||
|
IdctFunc inv_txfm_;
|
||||||
|
};
|
||||||
|
|
||||||
|
TEST_P(TransWHT, AccuracyCheck) { RunAccuracyCheck(0); }
|
||||||
|
|
||||||
|
TEST_P(TransWHT, CoeffCheck) { RunCoeffCheck(); }
|
||||||
|
|
||||||
|
TEST_P(TransWHT, MemCheck) { RunMemCheck(); }
|
||||||
|
|
||||||
|
TEST_P(TransWHT, InvAccuracyCheck) { RunInvAccuracyCheck(0); }
|
||||||
|
|
||||||
|
#if CONFIG_VP9_HIGHBITDEPTH
|
||||||
|
INSTANTIATE_TEST_CASE_P(
|
||||||
|
C, TransWHT,
|
||||||
|
::testing::Values(
|
||||||
|
make_tuple(&vp9_highbd_fwht4x4_c, &iwht4x4_10, 4, 0, VPX_BITS_10),
|
||||||
|
make_tuple(&vp9_highbd_fwht4x4_c, &iwht4x4_12, 4, 0, VPX_BITS_12),
|
||||||
|
make_tuple(&vp9_fwht4x4_c, &vpx_iwht4x4_16_add_c, 4, 0, VPX_BITS_8)));
|
||||||
|
#else
|
||||||
|
INSTANTIATE_TEST_CASE_P(C, TransWHT,
|
||||||
|
::testing::Values(make_tuple(&vp9_fwht4x4_c,
|
||||||
|
&vpx_iwht4x4_16_add_c, 4,
|
||||||
|
0, VPX_BITS_8)));
|
||||||
|
#endif // CONFIG_VP9_HIGHBITDEPTH
|
||||||
|
|
||||||
|
#if HAVE_SSE2
|
||||||
|
INSTANTIATE_TEST_CASE_P(SSE2, TransWHT,
|
||||||
|
::testing::Values(make_tuple(&vp9_fwht4x4_sse2,
|
||||||
|
&vpx_iwht4x4_16_add_sse2,
|
||||||
|
4, 0, VPX_BITS_8)));
|
||||||
|
#endif // HAVE_SSE2
|
||||||
|
} // namespace
|
|
@ -172,4 +172,21 @@ TEST(DecodeAPI, Vp9PeekSI) {
|
||||||
}
|
}
|
||||||
#endif // CONFIG_VP9_DECODER
|
#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
|
} // namespace
|
||||||
|
|
|
@ -0,0 +1,124 @@
|
||||||
|
/*
|
||||||
|
* 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 <string>
|
||||||
|
|
||||||
|
#include "test/codec_factory.h"
|
||||||
|
#include "test/decode_test_driver.h"
|
||||||
|
#include "test/ivf_video_source.h"
|
||||||
|
#include "test/test_vectors.h"
|
||||||
|
#include "test/util.h"
|
||||||
|
|
||||||
|
namespace {
|
||||||
|
|
||||||
|
const unsigned int kNumFrames = 19;
|
||||||
|
|
||||||
|
class DecodeSvcTest : public ::libvpx_test::DecoderTest,
|
||||||
|
public ::libvpx_test::CodecTestWithParam<const char *> {
|
||||||
|
protected:
|
||||||
|
DecodeSvcTest() : DecoderTest(GET_PARAM(::libvpx_test::kCodecFactoryParam)) {}
|
||||||
|
virtual ~DecodeSvcTest() {}
|
||||||
|
|
||||||
|
virtual void PreDecodeFrameHook(
|
||||||
|
const libvpx_test::CompressedVideoSource &video,
|
||||||
|
libvpx_test::Decoder *decoder) {
|
||||||
|
if (video.frame_number() == 0)
|
||||||
|
decoder->Control(VP9_DECODE_SVC_SPATIAL_LAYER, spatial_layer_);
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual void DecompressedFrameHook(const vpx_image_t &img,
|
||||||
|
const unsigned int frame_number) {
|
||||||
|
ASSERT_EQ(img.d_w, width_);
|
||||||
|
ASSERT_EQ(img.d_h, height_);
|
||||||
|
total_frames_ = frame_number;
|
||||||
|
}
|
||||||
|
|
||||||
|
int spatial_layer_;
|
||||||
|
unsigned int width_;
|
||||||
|
unsigned int height_;
|
||||||
|
unsigned int total_frames_;
|
||||||
|
};
|
||||||
|
|
||||||
|
// SVC test vector is 1280x720, with 3 spatial layers, and 20 frames.
|
||||||
|
|
||||||
|
// Decode the SVC test vector, which has 3 spatial layers, and decode up to
|
||||||
|
// spatial layer 0. Verify the resolution of each decoded frame and the total
|
||||||
|
// number of frames decoded. This results in 1/4x1/4 resolution (320x180).
|
||||||
|
TEST_P(DecodeSvcTest, DecodeSvcTestUpToSpatialLayer0) {
|
||||||
|
const std::string filename = GET_PARAM(1);
|
||||||
|
testing::internal::scoped_ptr<libvpx_test::CompressedVideoSource> video;
|
||||||
|
video.reset(new libvpx_test::IVFVideoSource(filename));
|
||||||
|
ASSERT_TRUE(video.get() != NULL);
|
||||||
|
video->Init();
|
||||||
|
total_frames_ = 0;
|
||||||
|
spatial_layer_ = 0;
|
||||||
|
width_ = 320;
|
||||||
|
height_ = 180;
|
||||||
|
ASSERT_NO_FATAL_FAILURE(RunLoop(video.get()));
|
||||||
|
ASSERT_EQ(total_frames_, kNumFrames);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Decode the SVC test vector, which has 3 spatial layers, and decode up to
|
||||||
|
// spatial layer 1. Verify the resolution of each decoded frame and the total
|
||||||
|
// number of frames decoded. This results in 1/2x1/2 resolution (640x360).
|
||||||
|
TEST_P(DecodeSvcTest, DecodeSvcTestUpToSpatialLayer1) {
|
||||||
|
const std::string filename = GET_PARAM(1);
|
||||||
|
testing::internal::scoped_ptr<libvpx_test::CompressedVideoSource> video;
|
||||||
|
video.reset(new libvpx_test::IVFVideoSource(filename));
|
||||||
|
ASSERT_TRUE(video.get() != NULL);
|
||||||
|
video->Init();
|
||||||
|
total_frames_ = 0;
|
||||||
|
spatial_layer_ = 1;
|
||||||
|
width_ = 640;
|
||||||
|
height_ = 360;
|
||||||
|
ASSERT_NO_FATAL_FAILURE(RunLoop(video.get()));
|
||||||
|
ASSERT_EQ(total_frames_, kNumFrames);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Decode the SVC test vector, which has 3 spatial layers, and decode up to
|
||||||
|
// spatial layer 2. Verify the resolution of each decoded frame and the total
|
||||||
|
// number of frames decoded. This results in the full resolution (1280x720).
|
||||||
|
TEST_P(DecodeSvcTest, DecodeSvcTestUpToSpatialLayer2) {
|
||||||
|
const std::string filename = GET_PARAM(1);
|
||||||
|
testing::internal::scoped_ptr<libvpx_test::CompressedVideoSource> video;
|
||||||
|
video.reset(new libvpx_test::IVFVideoSource(filename));
|
||||||
|
ASSERT_TRUE(video.get() != NULL);
|
||||||
|
video->Init();
|
||||||
|
total_frames_ = 0;
|
||||||
|
spatial_layer_ = 2;
|
||||||
|
width_ = 1280;
|
||||||
|
height_ = 720;
|
||||||
|
ASSERT_NO_FATAL_FAILURE(RunLoop(video.get()));
|
||||||
|
ASSERT_EQ(total_frames_, kNumFrames);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Decode the SVC test vector, which has 3 spatial layers, and decode up to
|
||||||
|
// spatial layer 10. Verify the resolution of each decoded frame and the total
|
||||||
|
// number of frames decoded. This is beyond the number of spatial layers, so
|
||||||
|
// the decoding should result in the full resolution (1280x720).
|
||||||
|
TEST_P(DecodeSvcTest, DecodeSvcTestUpToSpatialLayer10) {
|
||||||
|
const std::string filename = GET_PARAM(1);
|
||||||
|
testing::internal::scoped_ptr<libvpx_test::CompressedVideoSource> video;
|
||||||
|
video.reset(new libvpx_test::IVFVideoSource(filename));
|
||||||
|
ASSERT_TRUE(video.get() != NULL);
|
||||||
|
video->Init();
|
||||||
|
total_frames_ = 0;
|
||||||
|
spatial_layer_ = 10;
|
||||||
|
width_ = 1280;
|
||||||
|
height_ = 720;
|
||||||
|
ASSERT_NO_FATAL_FAILURE(RunLoop(video.get()));
|
||||||
|
ASSERT_EQ(total_frames_, kNumFrames);
|
||||||
|
}
|
||||||
|
|
||||||
|
VP9_INSTANTIATE_TEST_CASE(
|
||||||
|
DecodeSvcTest, ::testing::ValuesIn(libvpx_test::kVP9TestVectorsSvc,
|
||||||
|
libvpx_test::kVP9TestVectorsSvc +
|
||||||
|
libvpx_test::kNumVP9TestVectorsSvc));
|
||||||
|
} // namespace
|
|
@ -53,13 +53,13 @@ void DecoderTest::HandlePeekResult(Decoder *const decoder,
|
||||||
* pass it is not a keyframe, so we only expect VPX_CODEC_OK on the first
|
* pass it is not a keyframe, so we only expect VPX_CODEC_OK on the first
|
||||||
* frame, which must be a keyframe. */
|
* frame, which must be a keyframe. */
|
||||||
if (video->frame_number() == 0)
|
if (video->frame_number() == 0)
|
||||||
ASSERT_EQ(VPX_CODEC_OK, res_peek) << "Peek return failed: "
|
ASSERT_EQ(VPX_CODEC_OK, res_peek)
|
||||||
<< vpx_codec_err_to_string(res_peek);
|
<< "Peek return failed: " << vpx_codec_err_to_string(res_peek);
|
||||||
} else {
|
} else {
|
||||||
/* The Vp9 implementation of PeekStream returns an error only if the
|
/* The Vp9 implementation of PeekStream returns an error only if the
|
||||||
* data passed to it isn't a valid Vp9 chunk. */
|
* data passed to it isn't a valid Vp9 chunk. */
|
||||||
ASSERT_EQ(VPX_CODEC_OK, res_peek) << "Peek return failed: "
|
ASSERT_EQ(VPX_CODEC_OK, res_peek)
|
||||||
<< vpx_codec_err_to_string(res_peek);
|
<< "Peek return failed: " << vpx_codec_err_to_string(res_peek);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -62,4 +62,134 @@ 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
|
} // namespace
|
||||||
|
|
|
@ -201,6 +201,8 @@ void EncoderTest::RunLoop(VideoSource *video) {
|
||||||
PreEncodeFrameHook(video, encoder.get());
|
PreEncodeFrameHook(video, encoder.get());
|
||||||
encoder->EncodeFrame(video, frame_flags_);
|
encoder->EncodeFrame(video, frame_flags_);
|
||||||
|
|
||||||
|
PostEncodeFrameHook(encoder.get());
|
||||||
|
|
||||||
CxDataIterator iter = encoder->GetCxData();
|
CxDataIterator iter = encoder->GetCxData();
|
||||||
|
|
||||||
bool has_cxdata = false;
|
bool has_cxdata = false;
|
||||||
|
@ -226,6 +228,8 @@ void EncoderTest::RunLoop(VideoSource *video) {
|
||||||
|
|
||||||
case VPX_CODEC_PSNR_PKT: PSNRPktHook(pkt); break;
|
case VPX_CODEC_PSNR_PKT: PSNRPktHook(pkt); break;
|
||||||
|
|
||||||
|
case VPX_CODEC_STATS_PKT: StatsPktHook(pkt); break;
|
||||||
|
|
||||||
default: break;
|
default: break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -139,6 +139,13 @@ class Encoder {
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if CONFIG_VP8_ENCODER
|
||||||
|
void Control(int ctrl_id, vpx_roi_map_t *arg) {
|
||||||
|
const vpx_codec_err_t res = vpx_codec_control_(&encoder_, ctrl_id, arg);
|
||||||
|
ASSERT_EQ(VPX_CODEC_OK, res) << EncoderError();
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
void Config(const vpx_codec_enc_cfg_t *cfg) {
|
void Config(const vpx_codec_enc_cfg_t *cfg) {
|
||||||
const vpx_codec_err_t res = vpx_codec_enc_config_set(&encoder_, cfg);
|
const vpx_codec_err_t res = vpx_codec_enc_config_set(&encoder_, cfg);
|
||||||
ASSERT_EQ(VPX_CODEC_OK, res) << EncoderError();
|
ASSERT_EQ(VPX_CODEC_OK, res) << EncoderError();
|
||||||
|
@ -212,12 +219,17 @@ class EncoderTest {
|
||||||
virtual void PreEncodeFrameHook(VideoSource * /*video*/,
|
virtual void PreEncodeFrameHook(VideoSource * /*video*/,
|
||||||
Encoder * /*encoder*/) {}
|
Encoder * /*encoder*/) {}
|
||||||
|
|
||||||
|
virtual void PostEncodeFrameHook(Encoder * /*encoder*/) {}
|
||||||
|
|
||||||
// Hook to be called on every compressed data packet.
|
// Hook to be called on every compressed data packet.
|
||||||
virtual void FramePktHook(const vpx_codec_cx_pkt_t * /*pkt*/) {}
|
virtual void FramePktHook(const vpx_codec_cx_pkt_t * /*pkt*/) {}
|
||||||
|
|
||||||
// Hook to be called on every PSNR packet.
|
// Hook to be called on every PSNR packet.
|
||||||
virtual void PSNRPktHook(const vpx_codec_cx_pkt_t * /*pkt*/) {}
|
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.
|
// Hook to determine whether the encode loop should continue.
|
||||||
virtual bool Continue() const {
|
virtual bool Continue() const {
|
||||||
return !(::testing::Test::HasFatalFailure() || abort_);
|
return !(::testing::Test::HasFatalFailure() || abort_);
|
||||||
|
|
|
@ -90,8 +90,7 @@ class ErrorResilienceTestLarge
|
||||||
return frame_flags;
|
return frame_flags;
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual void PreEncodeFrameHook(libvpx_test::VideoSource *video,
|
virtual void PreEncodeFrameHook(libvpx_test::VideoSource *video) {
|
||||||
::libvpx_test::Encoder * /*encoder*/) {
|
|
||||||
frame_flags_ &=
|
frame_flags_ &=
|
||||||
~(VP8_EFLAG_NO_UPD_LAST | VP8_EFLAG_NO_UPD_GF | VP8_EFLAG_NO_UPD_ARF);
|
~(VP8_EFLAG_NO_UPD_LAST | VP8_EFLAG_NO_UPD_GF | VP8_EFLAG_NO_UPD_ARF);
|
||||||
// For temporal layer case.
|
// For temporal layer case.
|
||||||
|
|
|
@ -15,7 +15,7 @@
|
||||||
example_tests=$(ls $(dirname $0)/*.sh)
|
example_tests=$(ls $(dirname $0)/*.sh)
|
||||||
|
|
||||||
# List of script names to exclude.
|
# List of script names to exclude.
|
||||||
exclude_list="examples tools_common"
|
exclude_list="examples stress tools_common"
|
||||||
|
|
||||||
# Filter out the scripts in $exclude_list.
|
# Filter out the scripts in $exclude_list.
|
||||||
for word in ${exclude_list}; do
|
for word in ${exclude_list}; do
|
||||||
|
|
|
@ -34,7 +34,8 @@ struct ExternalFrameBuffer {
|
||||||
// Class to manipulate a list of external frame buffers.
|
// Class to manipulate a list of external frame buffers.
|
||||||
class ExternalFrameBufferList {
|
class ExternalFrameBufferList {
|
||||||
public:
|
public:
|
||||||
ExternalFrameBufferList() : num_buffers_(0), ext_fb_list_(NULL) {}
|
ExternalFrameBufferList()
|
||||||
|
: num_buffers_(0), num_used_buffers_(0), ext_fb_list_(NULL) {}
|
||||||
|
|
||||||
virtual ~ExternalFrameBufferList() {
|
virtual ~ExternalFrameBufferList() {
|
||||||
for (int i = 0; i < num_buffers_; ++i) {
|
for (int i = 0; i < num_buffers_; ++i) {
|
||||||
|
@ -71,6 +72,8 @@ class ExternalFrameBufferList {
|
||||||
}
|
}
|
||||||
|
|
||||||
SetFrameBuffer(idx, fb);
|
SetFrameBuffer(idx, fb);
|
||||||
|
|
||||||
|
num_used_buffers_++;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -106,6 +109,7 @@ class ExternalFrameBufferList {
|
||||||
}
|
}
|
||||||
EXPECT_EQ(1, ext_fb->in_use);
|
EXPECT_EQ(1, ext_fb->in_use);
|
||||||
ext_fb->in_use = 0;
|
ext_fb->in_use = 0;
|
||||||
|
num_used_buffers_--;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -121,6 +125,8 @@ class ExternalFrameBufferList {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int num_used_buffers() const { return num_used_buffers_; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
// Returns the index of the first free frame buffer. Returns |num_buffers_|
|
// Returns the index of the first free frame buffer. Returns |num_buffers_|
|
||||||
// if there are no free frame buffers.
|
// if there are no free frame buffers.
|
||||||
|
@ -145,6 +151,7 @@ class ExternalFrameBufferList {
|
||||||
}
|
}
|
||||||
|
|
||||||
int num_buffers_;
|
int num_buffers_;
|
||||||
|
int num_used_buffers_;
|
||||||
ExternalFrameBuffer *ext_fb_list_;
|
ExternalFrameBuffer *ext_fb_list_;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -220,8 +227,8 @@ class ExternalFrameBufferMD5Test
|
||||||
|
|
||||||
void OpenMD5File(const std::string &md5_file_name_) {
|
void OpenMD5File(const std::string &md5_file_name_) {
|
||||||
md5_file_ = libvpx_test::OpenTestDataFile(md5_file_name_);
|
md5_file_ = libvpx_test::OpenTestDataFile(md5_file_name_);
|
||||||
ASSERT_TRUE(md5_file_ != NULL) << "Md5 file open failed. Filename: "
|
ASSERT_TRUE(md5_file_ != NULL)
|
||||||
<< md5_file_name_;
|
<< "Md5 file open failed. Filename: " << md5_file_name_;
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual void DecompressedFrameHook(const vpx_image_t &img,
|
virtual void DecompressedFrameHook(const vpx_image_t &img,
|
||||||
|
@ -273,6 +280,7 @@ class ExternalFrameBufferMD5Test
|
||||||
|
|
||||||
#if CONFIG_WEBM_IO
|
#if CONFIG_WEBM_IO
|
||||||
const char kVP9TestFile[] = "vp90-2-02-size-lf-1920x1080.webm";
|
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 for testing passing in external frame buffers to libvpx.
|
||||||
class ExternalFrameBufferTest : public ::testing::Test {
|
class ExternalFrameBufferTest : public ::testing::Test {
|
||||||
|
@ -292,7 +300,9 @@ class ExternalFrameBufferTest : public ::testing::Test {
|
||||||
|
|
||||||
virtual void TearDown() {
|
virtual void TearDown() {
|
||||||
delete decoder_;
|
delete decoder_;
|
||||||
|
decoder_ = NULL;
|
||||||
delete video_;
|
delete video_;
|
||||||
|
video_ = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Passes the external frame buffer information to libvpx.
|
// Passes the external frame buffer information to libvpx.
|
||||||
|
@ -325,7 +335,7 @@ class ExternalFrameBufferTest : public ::testing::Test {
|
||||||
return VPX_CODEC_OK;
|
return VPX_CODEC_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
protected:
|
||||||
void CheckDecodedFrames() {
|
void CheckDecodedFrames() {
|
||||||
libvpx_test::DxDataIterator dec_iter = decoder_->GetDxData();
|
libvpx_test::DxDataIterator dec_iter = decoder_->GetDxData();
|
||||||
const vpx_image_t *img = NULL;
|
const vpx_image_t *img = NULL;
|
||||||
|
@ -341,6 +351,25 @@ class ExternalFrameBufferTest : public ::testing::Test {
|
||||||
int num_buffers_;
|
int num_buffers_;
|
||||||
ExternalFrameBufferList fb_list_;
|
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
|
#endif // CONFIG_WEBM_IO
|
||||||
|
|
||||||
// This test runs through the set of test vectors, and decodes them.
|
// This test runs through the set of test vectors, and decodes them.
|
||||||
|
@ -419,6 +448,8 @@ TEST_F(ExternalFrameBufferTest, NotEnoughBuffers) {
|
||||||
SetFrameBufferFunctions(num_buffers, get_vp9_frame_buffer,
|
SetFrameBufferFunctions(num_buffers, get_vp9_frame_buffer,
|
||||||
release_vp9_frame_buffer));
|
release_vp9_frame_buffer));
|
||||||
ASSERT_EQ(VPX_CODEC_OK, DecodeOneFrame());
|
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());
|
ASSERT_EQ(VPX_CODEC_MEM_ERROR, DecodeRemainingFrames());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -467,6 +498,15 @@ TEST_F(ExternalFrameBufferTest, SetAfterDecode) {
|
||||||
SetFrameBufferFunctions(num_buffers, get_vp9_frame_buffer,
|
SetFrameBufferFunctions(num_buffers, get_vp9_frame_buffer,
|
||||||
release_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
|
#endif // CONFIG_WEBM_IO
|
||||||
|
|
||||||
VP9_INSTANTIATE_TEST_CASE(
|
VP9_INSTANTIATE_TEST_CASE(
|
||||||
|
|
|
@ -1,512 +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 <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
|
|
|
@ -88,45 +88,45 @@ void fht8x8_ref(const int16_t *in, tran_low_t *out, int stride, int tx_type) {
|
||||||
|
|
||||||
#if CONFIG_VP9_HIGHBITDEPTH
|
#if CONFIG_VP9_HIGHBITDEPTH
|
||||||
void idct8x8_10(const tran_low_t *in, uint8_t *out, int stride) {
|
void idct8x8_10(const tran_low_t *in, uint8_t *out, int stride) {
|
||||||
vpx_highbd_idct8x8_64_add_c(in, out, stride, 10);
|
vpx_highbd_idct8x8_64_add_c(in, CAST_TO_SHORTPTR(out), stride, 10);
|
||||||
}
|
}
|
||||||
|
|
||||||
void idct8x8_12(const tran_low_t *in, uint8_t *out, int stride) {
|
void idct8x8_12(const tran_low_t *in, uint8_t *out, int stride) {
|
||||||
vpx_highbd_idct8x8_64_add_c(in, out, stride, 12);
|
vpx_highbd_idct8x8_64_add_c(in, CAST_TO_SHORTPTR(out), stride, 12);
|
||||||
}
|
}
|
||||||
|
|
||||||
void iht8x8_10(const tran_low_t *in, uint8_t *out, int stride, int tx_type) {
|
void iht8x8_10(const tran_low_t *in, uint8_t *out, int stride, int tx_type) {
|
||||||
vp9_highbd_iht8x8_64_add_c(in, out, stride, tx_type, 10);
|
vp9_highbd_iht8x8_64_add_c(in, CAST_TO_SHORTPTR(out), stride, tx_type, 10);
|
||||||
}
|
}
|
||||||
|
|
||||||
void iht8x8_12(const tran_low_t *in, uint8_t *out, int stride, int tx_type) {
|
void iht8x8_12(const tran_low_t *in, uint8_t *out, int stride, int tx_type) {
|
||||||
vp9_highbd_iht8x8_64_add_c(in, out, stride, tx_type, 12);
|
vp9_highbd_iht8x8_64_add_c(in, CAST_TO_SHORTPTR(out), stride, tx_type, 12);
|
||||||
}
|
}
|
||||||
|
|
||||||
#if HAVE_SSE2
|
#if HAVE_SSE2
|
||||||
|
|
||||||
void idct8x8_10_add_10_c(const tran_low_t *in, uint8_t *out, int stride) {
|
void idct8x8_12_add_10_c(const tran_low_t *in, uint8_t *out, int stride) {
|
||||||
vpx_highbd_idct8x8_10_add_c(in, out, stride, 10);
|
vpx_highbd_idct8x8_12_add_c(in, CAST_TO_SHORTPTR(out), stride, 10);
|
||||||
}
|
}
|
||||||
|
|
||||||
void idct8x8_10_add_12_c(const tran_low_t *in, uint8_t *out, int stride) {
|
void idct8x8_12_add_12_c(const tran_low_t *in, uint8_t *out, int stride) {
|
||||||
vpx_highbd_idct8x8_10_add_c(in, out, stride, 12);
|
vpx_highbd_idct8x8_12_add_c(in, CAST_TO_SHORTPTR(out), stride, 12);
|
||||||
}
|
}
|
||||||
|
|
||||||
void idct8x8_10_add_10_sse2(const tran_low_t *in, uint8_t *out, int stride) {
|
void idct8x8_12_add_10_sse2(const tran_low_t *in, uint8_t *out, int stride) {
|
||||||
vpx_highbd_idct8x8_10_add_sse2(in, out, stride, 10);
|
vpx_highbd_idct8x8_12_add_sse2(in, CAST_TO_SHORTPTR(out), stride, 10);
|
||||||
}
|
}
|
||||||
|
|
||||||
void idct8x8_10_add_12_sse2(const tran_low_t *in, uint8_t *out, int stride) {
|
void idct8x8_12_add_12_sse2(const tran_low_t *in, uint8_t *out, int stride) {
|
||||||
vpx_highbd_idct8x8_10_add_sse2(in, out, stride, 12);
|
vpx_highbd_idct8x8_12_add_sse2(in, CAST_TO_SHORTPTR(out), stride, 12);
|
||||||
}
|
}
|
||||||
|
|
||||||
void idct8x8_64_add_10_sse2(const tran_low_t *in, uint8_t *out, int stride) {
|
void idct8x8_64_add_10_sse2(const tran_low_t *in, uint8_t *out, int stride) {
|
||||||
vpx_highbd_idct8x8_64_add_sse2(in, out, stride, 10);
|
vpx_highbd_idct8x8_64_add_sse2(in, CAST_TO_SHORTPTR(out), stride, 10);
|
||||||
}
|
}
|
||||||
|
|
||||||
void idct8x8_64_add_12_sse2(const tran_low_t *in, uint8_t *out, int stride) {
|
void idct8x8_64_add_12_sse2(const tran_low_t *in, uint8_t *out, int stride) {
|
||||||
vpx_highbd_idct8x8_64_add_sse2(in, out, stride, 12);
|
vpx_highbd_idct8x8_64_add_sse2(in, CAST_TO_SHORTPTR(out), stride, 12);
|
||||||
}
|
}
|
||||||
#endif // HAVE_SSE2
|
#endif // HAVE_SSE2
|
||||||
#endif // CONFIG_VP9_HIGHBITDEPTH
|
#endif // CONFIG_VP9_HIGHBITDEPTH
|
||||||
|
@ -257,7 +257,7 @@ class FwdTrans8x8TestBase {
|
||||||
#if CONFIG_VP9_HIGHBITDEPTH
|
#if CONFIG_VP9_HIGHBITDEPTH
|
||||||
} else {
|
} else {
|
||||||
ASM_REGISTER_STATE_CHECK(
|
ASM_REGISTER_STATE_CHECK(
|
||||||
RunInvTxfm(test_temp_block, CONVERT_TO_BYTEPTR(dst16), pitch_));
|
RunInvTxfm(test_temp_block, CAST_TO_BYTEPTR(dst16), pitch_));
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -340,7 +340,7 @@ class FwdTrans8x8TestBase {
|
||||||
#if CONFIG_VP9_HIGHBITDEPTH
|
#if CONFIG_VP9_HIGHBITDEPTH
|
||||||
} else {
|
} else {
|
||||||
ASM_REGISTER_STATE_CHECK(
|
ASM_REGISTER_STATE_CHECK(
|
||||||
RunInvTxfm(test_temp_block, CONVERT_TO_BYTEPTR(dst16), pitch_));
|
RunInvTxfm(test_temp_block, CAST_TO_BYTEPTR(dst16), pitch_));
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -413,7 +413,7 @@ class FwdTrans8x8TestBase {
|
||||||
#if CONFIG_VP9_HIGHBITDEPTH
|
#if CONFIG_VP9_HIGHBITDEPTH
|
||||||
} else {
|
} else {
|
||||||
ASM_REGISTER_STATE_CHECK(
|
ASM_REGISTER_STATE_CHECK(
|
||||||
RunInvTxfm(coeff, CONVERT_TO_BYTEPTR(dst16), pitch_));
|
RunInvTxfm(coeff, CAST_TO_BYTEPTR(dst16), pitch_));
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -497,9 +497,9 @@ class FwdTrans8x8TestBase {
|
||||||
ASM_REGISTER_STATE_CHECK(RunInvTxfm(coeff, dst, pitch_));
|
ASM_REGISTER_STATE_CHECK(RunInvTxfm(coeff, dst, pitch_));
|
||||||
#if CONFIG_VP9_HIGHBITDEPTH
|
#if CONFIG_VP9_HIGHBITDEPTH
|
||||||
} else {
|
} else {
|
||||||
ref_txfm(coeff, CONVERT_TO_BYTEPTR(ref16), pitch_);
|
ref_txfm(coeff, CAST_TO_BYTEPTR(ref16), pitch_);
|
||||||
ASM_REGISTER_STATE_CHECK(
|
ASM_REGISTER_STATE_CHECK(
|
||||||
RunInvTxfm(coeff, CONVERT_TO_BYTEPTR(dst16), pitch_));
|
RunInvTxfm(coeff, CAST_TO_BYTEPTR(dst16), pitch_));
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -511,8 +511,8 @@ class FwdTrans8x8TestBase {
|
||||||
const int diff = dst[j] - ref[j];
|
const int diff = dst[j] - ref[j];
|
||||||
#endif
|
#endif
|
||||||
const uint32_t error = diff * diff;
|
const uint32_t error = diff * diff;
|
||||||
EXPECT_EQ(0u, error) << "Error: 8x8 IDCT has error " << error
|
EXPECT_EQ(0u, error)
|
||||||
<< " at index " << j;
|
<< "Error: 8x8 IDCT has error " << error << " at index " << j;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -670,14 +670,12 @@ INSTANTIATE_TEST_CASE_P(
|
||||||
make_tuple(&vp9_fht8x8_c, &vp9_iht8x8_64_add_c, 3, VPX_BITS_8)));
|
make_tuple(&vp9_fht8x8_c, &vp9_iht8x8_64_add_c, 3, VPX_BITS_8)));
|
||||||
#endif // CONFIG_VP9_HIGHBITDEPTH
|
#endif // CONFIG_VP9_HIGHBITDEPTH
|
||||||
|
|
||||||
#if HAVE_NEON_ASM && !CONFIG_VP9_HIGHBITDEPTH && !CONFIG_EMULATE_HARDWARE
|
#if HAVE_NEON && !CONFIG_EMULATE_HARDWARE
|
||||||
INSTANTIATE_TEST_CASE_P(NEON, FwdTrans8x8DCT,
|
INSTANTIATE_TEST_CASE_P(NEON, FwdTrans8x8DCT,
|
||||||
::testing::Values(make_tuple(&vpx_fdct8x8_neon,
|
::testing::Values(make_tuple(&vpx_fdct8x8_neon,
|
||||||
&vpx_idct8x8_64_add_neon,
|
&vpx_idct8x8_64_add_neon,
|
||||||
0, VPX_BITS_8)));
|
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(
|
INSTANTIATE_TEST_CASE_P(
|
||||||
NEON, FwdTrans8x8HT,
|
NEON, FwdTrans8x8HT,
|
||||||
::testing::Values(
|
::testing::Values(
|
||||||
|
@ -685,7 +683,8 @@ 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, 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, 2, VPX_BITS_8),
|
||||||
make_tuple(&vp9_fht8x8_c, &vp9_iht8x8_64_add_neon, 3, VPX_BITS_8)));
|
make_tuple(&vp9_fht8x8_c, &vp9_iht8x8_64_add_neon, 3, VPX_BITS_8)));
|
||||||
#endif // HAVE_NEON && !CONFIG_VP9_HIGHBITDEPTH && !CONFIG_EMULATE_HARDWARE
|
#endif // !CONFIG_VP9_HIGHBITDEPTH
|
||||||
|
#endif // HAVE_NEON && !CONFIG_EMULATE_HARDWARE
|
||||||
|
|
||||||
#if HAVE_SSE2 && !CONFIG_VP9_HIGHBITDEPTH && !CONFIG_EMULATE_HARDWARE
|
#if HAVE_SSE2 && !CONFIG_VP9_HIGHBITDEPTH && !CONFIG_EMULATE_HARDWARE
|
||||||
INSTANTIATE_TEST_CASE_P(SSE2, FwdTrans8x8DCT,
|
INSTANTIATE_TEST_CASE_P(SSE2, FwdTrans8x8DCT,
|
||||||
|
@ -728,10 +727,10 @@ INSTANTIATE_TEST_CASE_P(
|
||||||
INSTANTIATE_TEST_CASE_P(
|
INSTANTIATE_TEST_CASE_P(
|
||||||
SSE2, InvTrans8x8DCT,
|
SSE2, InvTrans8x8DCT,
|
||||||
::testing::Values(
|
::testing::Values(
|
||||||
make_tuple(&idct8x8_10_add_10_c, &idct8x8_10_add_10_sse2, 6225,
|
make_tuple(&idct8x8_12_add_10_c, &idct8x8_12_add_10_sse2, 6225,
|
||||||
VPX_BITS_10),
|
VPX_BITS_10),
|
||||||
make_tuple(&idct8x8_10, &idct8x8_64_add_10_sse2, 6225, VPX_BITS_10),
|
make_tuple(&idct8x8_10, &idct8x8_64_add_10_sse2, 6225, VPX_BITS_10),
|
||||||
make_tuple(&idct8x8_10_add_12_c, &idct8x8_10_add_12_sse2, 6225,
|
make_tuple(&idct8x8_12_add_12_c, &idct8x8_12_add_12_sse2, 6225,
|
||||||
VPX_BITS_12),
|
VPX_BITS_12),
|
||||||
make_tuple(&idct8x8_12, &idct8x8_64_add_12_sse2, 6225, VPX_BITS_12)));
|
make_tuple(&idct8x8_12, &idct8x8_64_add_12_sse2, 6225, VPX_BITS_12)));
|
||||||
#endif // HAVE_SSE2 && CONFIG_VP9_HIGHBITDEPTH && !CONFIG_EMULATE_HARDWARE
|
#endif // HAVE_SSE2 && CONFIG_VP9_HIGHBITDEPTH && !CONFIG_EMULATE_HARDWARE
|
||||||
|
@ -740,7 +739,7 @@ INSTANTIATE_TEST_CASE_P(
|
||||||
!CONFIG_EMULATE_HARDWARE
|
!CONFIG_EMULATE_HARDWARE
|
||||||
INSTANTIATE_TEST_CASE_P(SSSE3, FwdTrans8x8DCT,
|
INSTANTIATE_TEST_CASE_P(SSSE3, FwdTrans8x8DCT,
|
||||||
::testing::Values(make_tuple(&vpx_fdct8x8_ssse3,
|
::testing::Values(make_tuple(&vpx_fdct8x8_ssse3,
|
||||||
&vpx_idct8x8_64_add_ssse3,
|
&vpx_idct8x8_64_add_sse2,
|
||||||
0, VPX_BITS_8)));
|
0, VPX_BITS_8)));
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -757,4 +756,11 @@ 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, 2, VPX_BITS_8),
|
||||||
make_tuple(&vp9_fht8x8_msa, &vp9_iht8x8_64_add_msa, 3, 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
|
#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
|
} // namespace
|
||||||
|
|
|
@ -13,6 +13,7 @@
|
||||||
#include "third_party/googletest/src/include/gtest/gtest.h"
|
#include "third_party/googletest/src/include/gtest/gtest.h"
|
||||||
|
|
||||||
#include "./vpx_dsp_rtcd.h"
|
#include "./vpx_dsp_rtcd.h"
|
||||||
|
#include "vpx_ports/vpx_timer.h"
|
||||||
|
|
||||||
#include "test/acm_random.h"
|
#include "test/acm_random.h"
|
||||||
#include "test/register_state_check.h"
|
#include "test/register_state_check.h"
|
||||||
|
@ -21,7 +22,8 @@ namespace {
|
||||||
|
|
||||||
using ::libvpx_test::ACMRandom;
|
using ::libvpx_test::ACMRandom;
|
||||||
|
|
||||||
typedef void (*HadamardFunc)(const int16_t *a, int a_stride, int16_t *b);
|
typedef void (*HadamardFunc)(const int16_t *a, ptrdiff_t a_stride,
|
||||||
|
tran_low_t *b);
|
||||||
|
|
||||||
void hadamard_loop(const int16_t *a, int a_stride, int16_t *out) {
|
void hadamard_loop(const int16_t *a, int a_stride, int16_t *out) {
|
||||||
int16_t b[8];
|
int16_t b[8];
|
||||||
|
@ -46,18 +48,16 @@ void hadamard_loop(const int16_t *a, int a_stride, int16_t *out) {
|
||||||
out[5] = c[3] - c[7];
|
out[5] = c[3] - c[7];
|
||||||
}
|
}
|
||||||
|
|
||||||
void reference_hadamard8x8(const int16_t *a, int a_stride, int16_t *b) {
|
void reference_hadamard8x8(const int16_t *a, int a_stride, tran_low_t *b) {
|
||||||
int16_t buf[64];
|
int16_t buf[64];
|
||||||
for (int i = 0; i < 8; ++i) {
|
int16_t buf2[64];
|
||||||
hadamard_loop(a + i, a_stride, buf + i * 8);
|
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) {
|
for (int i = 0; i < 64; ++i) b[i] = (tran_low_t)buf2[i];
|
||||||
hadamard_loop(buf + i, 8, b + i * 8);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void reference_hadamard16x16(const int16_t *a, int a_stride, int16_t *b) {
|
void reference_hadamard16x16(const int16_t *a, int a_stride, tran_low_t *b) {
|
||||||
/* The source is a 16x16 block. The destination is rearranged to 8x32.
|
/* The source is a 16x16 block. The destination is rearranged to 8x32.
|
||||||
* Input is 9 bit. */
|
* Input is 9 bit. */
|
||||||
reference_hadamard8x8(a + 0 + 0 * a_stride, a_stride, b + 0);
|
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, int16_t *b) {
|
||||||
/* Overlay the 8x8 blocks and combine. */
|
/* Overlay the 8x8 blocks and combine. */
|
||||||
for (int i = 0; i < 64; ++i) {
|
for (int i = 0; i < 64; ++i) {
|
||||||
/* 8x8 steps the range up to 15 bits. */
|
/* 8x8 steps the range up to 15 bits. */
|
||||||
const int16_t a0 = b[0];
|
const tran_low_t a0 = b[0];
|
||||||
const int16_t a1 = b[64];
|
const tran_low_t a1 = b[64];
|
||||||
const int16_t a2 = b[128];
|
const tran_low_t a2 = b[128];
|
||||||
const int16_t a3 = b[192];
|
const tran_low_t a3 = b[192];
|
||||||
|
|
||||||
/* Prevent the result from escaping int16_t. */
|
/* Prevent the result from escaping int16_t. */
|
||||||
const int16_t b0 = (a0 + a1) >> 1;
|
const tran_low_t b0 = (a0 + a1) >> 1;
|
||||||
const int16_t b1 = (a0 - a1) >> 1;
|
const tran_low_t b1 = (a0 - a1) >> 1;
|
||||||
const int16_t b2 = (a2 + a3) >> 1;
|
const tran_low_t b2 = (a2 + a3) >> 1;
|
||||||
const int16_t b3 = (a2 - a3) >> 1;
|
const tran_low_t b3 = (a2 - a3) >> 1;
|
||||||
|
|
||||||
/* Store a 16 bit value. */
|
/* Store a 16 bit value. */
|
||||||
b[0] = b0 + b2;
|
b[0] = b0 + b2;
|
||||||
|
@ -101,12 +101,35 @@ class HadamardTestBase : public ::testing::TestWithParam<HadamardFunc> {
|
||||||
ACMRandom rnd_;
|
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 {};
|
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) {
|
TEST_P(Hadamard8x8Test, CompareReferenceRandom) {
|
||||||
DECLARE_ALIGNED(16, int16_t, a[64]);
|
DECLARE_ALIGNED(16, int16_t, a[64]);
|
||||||
DECLARE_ALIGNED(16, int16_t, b[64]);
|
DECLARE_ALIGNED(16, tran_low_t, b[64]);
|
||||||
int16_t b_ref[64];
|
tran_low_t b_ref[64];
|
||||||
for (int i = 0; i < 64; ++i) {
|
for (int i = 0; i < 64; ++i) {
|
||||||
a[i] = rnd_.Rand9Signed();
|
a[i] = rnd_.Rand9Signed();
|
||||||
}
|
}
|
||||||
|
@ -124,8 +147,8 @@ TEST_P(Hadamard8x8Test, CompareReferenceRandom) {
|
||||||
|
|
||||||
TEST_P(Hadamard8x8Test, VaryStride) {
|
TEST_P(Hadamard8x8Test, VaryStride) {
|
||||||
DECLARE_ALIGNED(16, int16_t, a[64 * 8]);
|
DECLARE_ALIGNED(16, int16_t, a[64 * 8]);
|
||||||
DECLARE_ALIGNED(16, int16_t, b[64]);
|
DECLARE_ALIGNED(16, tran_low_t, b[64]);
|
||||||
int16_t b_ref[64];
|
tran_low_t b_ref[64];
|
||||||
for (int i = 0; i < 64 * 8; ++i) {
|
for (int i = 0; i < 64 * 8; ++i) {
|
||||||
a[i] = rnd_.Rand9Signed();
|
a[i] = rnd_.Rand9Signed();
|
||||||
}
|
}
|
||||||
|
@ -144,6 +167,12 @@ 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,
|
INSTANTIATE_TEST_CASE_P(C, Hadamard8x8Test,
|
||||||
::testing::Values(&vpx_hadamard_8x8_c));
|
::testing::Values(&vpx_hadamard_8x8_c));
|
||||||
|
|
||||||
|
@ -162,12 +191,33 @@ INSTANTIATE_TEST_CASE_P(NEON, Hadamard8x8Test,
|
||||||
::testing::Values(&vpx_hadamard_8x8_neon));
|
::testing::Values(&vpx_hadamard_8x8_neon));
|
||||||
#endif // HAVE_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 {};
|
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) {
|
TEST_P(Hadamard16x16Test, CompareReferenceRandom) {
|
||||||
DECLARE_ALIGNED(16, int16_t, a[16 * 16]);
|
DECLARE_ALIGNED(16, int16_t, a[16 * 16]);
|
||||||
DECLARE_ALIGNED(16, int16_t, b[16 * 16]);
|
DECLARE_ALIGNED(16, tran_low_t, b[16 * 16]);
|
||||||
int16_t b_ref[16 * 16];
|
tran_low_t b_ref[16 * 16];
|
||||||
for (int i = 0; i < 16 * 16; ++i) {
|
for (int i = 0; i < 16 * 16; ++i) {
|
||||||
a[i] = rnd_.Rand9Signed();
|
a[i] = rnd_.Rand9Signed();
|
||||||
}
|
}
|
||||||
|
@ -185,8 +235,8 @@ TEST_P(Hadamard16x16Test, CompareReferenceRandom) {
|
||||||
|
|
||||||
TEST_P(Hadamard16x16Test, VaryStride) {
|
TEST_P(Hadamard16x16Test, VaryStride) {
|
||||||
DECLARE_ALIGNED(16, int16_t, a[16 * 16 * 8]);
|
DECLARE_ALIGNED(16, int16_t, a[16 * 16 * 8]);
|
||||||
DECLARE_ALIGNED(16, int16_t, b[16 * 16]);
|
DECLARE_ALIGNED(16, tran_low_t, b[16 * 16]);
|
||||||
int16_t b_ref[16 * 16];
|
tran_low_t b_ref[16 * 16];
|
||||||
for (int i = 0; i < 16 * 16 * 8; ++i) {
|
for (int i = 0; i < 16 * 16 * 8; ++i) {
|
||||||
a[i] = rnd_.Rand9Signed();
|
a[i] = rnd_.Rand9Signed();
|
||||||
}
|
}
|
||||||
|
@ -205,6 +255,12 @@ 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,
|
INSTANTIATE_TEST_CASE_P(C, Hadamard16x16Test,
|
||||||
::testing::Values(&vpx_hadamard_16x16_c));
|
::testing::Values(&vpx_hadamard_16x16_c));
|
||||||
|
|
||||||
|
@ -213,8 +269,25 @@ INSTANTIATE_TEST_CASE_P(SSE2, Hadamard16x16Test,
|
||||||
::testing::Values(&vpx_hadamard_16x16_sse2));
|
::testing::Values(&vpx_hadamard_16x16_sse2));
|
||||||
#endif // HAVE_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
|
#if HAVE_NEON
|
||||||
INSTANTIATE_TEST_CASE_P(NEON, Hadamard16x16Test,
|
INSTANTIATE_TEST_CASE_P(NEON, Hadamard16x16Test,
|
||||||
::testing::Values(&vpx_hadamard_16x16_neon));
|
::testing::Values(&vpx_hadamard_16x16_neon));
|
||||||
#endif // HAVE_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
|
} // namespace
|
||||||
|
|
|
@ -13,6 +13,7 @@
|
||||||
|
|
||||||
#include "third_party/googletest/src/include/gtest/gtest.h"
|
#include "third_party/googletest/src/include/gtest/gtest.h"
|
||||||
|
|
||||||
|
#include "test/buffer.h"
|
||||||
#include "test/clear_system_state.h"
|
#include "test/clear_system_state.h"
|
||||||
#include "test/register_state_check.h"
|
#include "test/register_state_check.h"
|
||||||
#include "vpx/vpx_integer.h"
|
#include "vpx/vpx_integer.h"
|
||||||
|
@ -21,106 +22,156 @@ typedef void (*IdctFunc)(int16_t *input, unsigned char *pred_ptr,
|
||||||
int pred_stride, unsigned char *dst_ptr,
|
int pred_stride, unsigned char *dst_ptr,
|
||||||
int dst_stride);
|
int dst_stride);
|
||||||
namespace {
|
namespace {
|
||||||
|
|
||||||
|
using libvpx_test::Buffer;
|
||||||
|
|
||||||
class IDCTTest : public ::testing::TestWithParam<IdctFunc> {
|
class IDCTTest : public ::testing::TestWithParam<IdctFunc> {
|
||||||
protected:
|
protected:
|
||||||
virtual void SetUp() {
|
virtual void SetUp() {
|
||||||
int i;
|
|
||||||
|
|
||||||
UUT = GetParam();
|
UUT = GetParam();
|
||||||
memset(input, 0, sizeof(input));
|
|
||||||
/* Set up guard blocks */
|
input = new Buffer<int16_t>(4, 4, 0);
|
||||||
for (i = 0; i < 256; i++) output[i] = ((i & 0xF) < 4 && (i < 64)) ? 0 : -1;
|
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());
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual void TearDown() { libvpx_test::ClearSystemState(); }
|
virtual void TearDown() {
|
||||||
|
delete input;
|
||||||
|
delete predict;
|
||||||
|
delete output;
|
||||||
|
libvpx_test::ClearSystemState();
|
||||||
|
}
|
||||||
|
|
||||||
IdctFunc UUT;
|
IdctFunc UUT;
|
||||||
int16_t input[16];
|
Buffer<int16_t> *input;
|
||||||
unsigned char output[256];
|
Buffer<uint8_t> *predict;
|
||||||
unsigned char predict[256];
|
Buffer<uint8_t> *output;
|
||||||
};
|
};
|
||||||
|
|
||||||
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) {
|
TEST_P(IDCTTest, TestAllZeros) {
|
||||||
int i;
|
// When the input is '0' the output will be '0'.
|
||||||
|
input->Set(0);
|
||||||
|
predict->Set(0);
|
||||||
|
output->Set(0);
|
||||||
|
|
||||||
ASM_REGISTER_STATE_CHECK(UUT(input, output, 16, output, 16));
|
ASM_REGISTER_STATE_CHECK(UUT(input->TopLeftPixel(), predict->TopLeftPixel(),
|
||||||
|
predict->stride(), output->TopLeftPixel(),
|
||||||
|
output->stride()));
|
||||||
|
|
||||||
for (i = 0; i < 256; i++) {
|
ASSERT_TRUE(input->CheckValues(0));
|
||||||
if ((i & 0xF) < 4 && i < 64)
|
ASSERT_TRUE(input->CheckPadding());
|
||||||
EXPECT_EQ(0, output[i]) << "i==" << i;
|
ASSERT_TRUE(output->CheckValues(0));
|
||||||
else
|
ASSERT_TRUE(output->CheckPadding());
|
||||||
EXPECT_EQ(255, output[i]) << "i==" << i;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_P(IDCTTest, TestAllOnes) {
|
TEST_P(IDCTTest, TestAllOnes) {
|
||||||
int i;
|
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);
|
||||||
|
|
||||||
input[0] = 4;
|
ASM_REGISTER_STATE_CHECK(UUT(input->TopLeftPixel(), predict->TopLeftPixel(),
|
||||||
ASM_REGISTER_STATE_CHECK(UUT(input, output, 16, output, 16));
|
predict->stride(), output->TopLeftPixel(),
|
||||||
|
output->stride()));
|
||||||
|
|
||||||
for (i = 0; i < 256; i++) {
|
ASSERT_TRUE(output->CheckValues(1));
|
||||||
if ((i & 0xF) < 4 && i < 64)
|
ASSERT_TRUE(output->CheckPadding());
|
||||||
EXPECT_EQ(1, output[i]) << "i==" << i;
|
|
||||||
else
|
|
||||||
EXPECT_EQ(255, output[i]) << "i==" << i;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_P(IDCTTest, TestAddOne) {
|
TEST_P(IDCTTest, TestAddOne) {
|
||||||
int i;
|
// 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);
|
||||||
|
|
||||||
for (i = 0; i < 256; i++) predict[i] = i;
|
uint8_t *pred = predict->TopLeftPixel();
|
||||||
input[0] = 4;
|
for (int y = 0; y < 4; ++y) {
|
||||||
ASM_REGISTER_STATE_CHECK(UUT(input, predict, 16, output, 16));
|
for (int x = 0; x < 4; ++x) {
|
||||||
|
pred[y * predict->stride() + x] = y * 4 + x;
|
||||||
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_P(IDCTTest, TestWithData) {
|
||||||
int i;
|
// Test a single known input.
|
||||||
|
predict->Set(0);
|
||||||
|
|
||||||
for (i = 0; i < 16; i++) input[i] = i;
|
int16_t *in = input->TopLeftPixel();
|
||||||
|
for (int y = 0; y < 4; ++y) {
|
||||||
ASM_REGISTER_STATE_CHECK(UUT(input, output, 16, output, 16));
|
for (int x = 0; x < 4; ++x) {
|
||||||
|
in[y * input->stride() + x] = y * 4 + x;
|
||||||
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));
|
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
|
||||||
|
|
||||||
#if HAVE_MMX
|
#if HAVE_MMX
|
||||||
INSTANTIATE_TEST_CASE_P(MMX, IDCTTest,
|
INSTANTIATE_TEST_CASE_P(MMX, IDCTTest,
|
||||||
::testing::Values(vp8_short_idct4x4llm_mmx));
|
::testing::Values(vp8_short_idct4x4llm_mmx));
|
||||||
#endif
|
#endif // HAVE_MMX
|
||||||
|
|
||||||
#if HAVE_MSA
|
#if HAVE_MSA
|
||||||
INSTANTIATE_TEST_CASE_P(MSA, IDCTTest,
|
INSTANTIATE_TEST_CASE_P(MSA, IDCTTest,
|
||||||
::testing::Values(vp8_short_idct4x4llm_msa));
|
::testing::Values(vp8_short_idct4x4llm_msa));
|
||||||
#endif
|
#endif // HAVE_MSA
|
||||||
|
|
||||||
|
#if HAVE_MMI
|
||||||
|
INSTANTIATE_TEST_CASE_P(MMI, IDCTTest,
|
||||||
|
::testing::Values(vp8_short_idct4x4llm_mmi));
|
||||||
|
#endif // HAVE_MMI
|
||||||
}
|
}
|
||||||
|
|
|
@ -45,8 +45,8 @@ class InvalidFileTest : public ::libvpx_test::DecoderTest,
|
||||||
|
|
||||||
void OpenResFile(const std::string &res_file_name_) {
|
void OpenResFile(const std::string &res_file_name_) {
|
||||||
res_file_ = libvpx_test::OpenTestDataFile(res_file_name_);
|
res_file_ = libvpx_test::OpenTestDataFile(res_file_name_);
|
||||||
ASSERT_TRUE(res_file_ != NULL) << "Result file open failed. Filename: "
|
ASSERT_TRUE(res_file_ != NULL)
|
||||||
<< res_file_name_;
|
<< "Result file open failed. Filename: " << res_file_name_;
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual bool HandleDecodeResult(
|
virtual bool HandleDecodeResult(
|
||||||
|
@ -120,10 +120,23 @@ class InvalidFileTest : public ::libvpx_test::DecoderTest,
|
||||||
|
|
||||||
TEST_P(InvalidFileTest, ReturnCode) { RunTest(); }
|
TEST_P(InvalidFileTest, ReturnCode) { RunTest(); }
|
||||||
|
|
||||||
|
#if CONFIG_VP8_DECODER
|
||||||
|
const DecodeParam kVP8InvalidFileTests[] = {
|
||||||
|
{ 1, "invalid-bug-1443.ivf" },
|
||||||
|
};
|
||||||
|
|
||||||
|
VP8_INSTANTIATE_TEST_CASE(InvalidFileTest,
|
||||||
|
::testing::ValuesIn(kVP8InvalidFileTests));
|
||||||
|
#endif // CONFIG_VP8_DECODER
|
||||||
|
|
||||||
|
#if CONFIG_VP9_DECODER
|
||||||
const DecodeParam kVP9InvalidFileTests[] = {
|
const DecodeParam kVP9InvalidFileTests[] = {
|
||||||
{ 1, "invalid-vp90-02-v2.webm" },
|
{ 1, "invalid-vp90-02-v2.webm" },
|
||||||
#if CONFIG_VP9_HIGHBITDEPTH
|
#if CONFIG_VP9_HIGHBITDEPTH
|
||||||
{ 1, "invalid-vp90-2-00-quantizer-00.webm.ivf.s5861_r01-05_b6-.v2.ivf" },
|
{ 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
|
#endif
|
||||||
{ 1, "invalid-vp90-03-v3.webm" },
|
{ 1, "invalid-vp90-03-v3.webm" },
|
||||||
{ 1, "invalid-vp90-2-00-quantizer-11.webm.ivf.s52984_r01-05_b6-.ivf" },
|
{ 1, "invalid-vp90-2-00-quantizer-11.webm.ivf.s52984_r01-05_b6-.ivf" },
|
||||||
|
@ -141,10 +154,14 @@ const DecodeParam kVP9InvalidFileTests[] = {
|
||||||
{ 1, "invalid-vp90-2-12-droppable_1.ivf.s73804_r01-05_b6-.ivf" },
|
{ 1, "invalid-vp90-2-12-droppable_1.ivf.s73804_r01-05_b6-.ivf" },
|
||||||
{ 1, "invalid-vp90-2-03-size-224x196.webm.ivf.s44156_r01-05_b6-.ivf" },
|
{ 1, "invalid-vp90-2-03-size-224x196.webm.ivf.s44156_r01-05_b6-.ivf" },
|
||||||
{ 1, "invalid-vp90-2-03-size-202x210.webm.ivf.s113306_r01-05_b6-.ivf" },
|
{ 1, "invalid-vp90-2-03-size-202x210.webm.ivf.s113306_r01-05_b6-.ivf" },
|
||||||
|
{ 1,
|
||||||
|
"invalid-vp90-2-10-show-existing-frame.webm.ivf.s180315_r01-05_b6-.ivf" },
|
||||||
|
{ 1, "invalid-crbug-667044.webm" },
|
||||||
};
|
};
|
||||||
|
|
||||||
VP9_INSTANTIATE_TEST_CASE(InvalidFileTest,
|
VP9_INSTANTIATE_TEST_CASE(InvalidFileTest,
|
||||||
::testing::ValuesIn(kVP9InvalidFileTests));
|
::testing::ValuesIn(kVP9InvalidFileTests));
|
||||||
|
#endif // CONFIG_VP9_DECODER
|
||||||
|
|
||||||
// This class will include test vectors that are expected to fail
|
// This class will include test vectors that are expected to fail
|
||||||
// peek. However they are still expected to have no fatal failures.
|
// peek. However they are still expected to have no fatal failures.
|
||||||
|
@ -159,12 +176,12 @@ class InvalidFileInvalidPeekTest : public InvalidFileTest {
|
||||||
TEST_P(InvalidFileInvalidPeekTest, ReturnCode) { RunTest(); }
|
TEST_P(InvalidFileInvalidPeekTest, ReturnCode) { RunTest(); }
|
||||||
|
|
||||||
#if CONFIG_VP8_DECODER
|
#if CONFIG_VP8_DECODER
|
||||||
const DecodeParam kVP8InvalidFileTests[] = {
|
const DecodeParam kVP8InvalidPeekTests[] = {
|
||||||
{ 1, "invalid-vp80-00-comprehensive-018.ivf.2kf_0x6.ivf" },
|
{ 1, "invalid-vp80-00-comprehensive-018.ivf.2kf_0x6.ivf" },
|
||||||
};
|
};
|
||||||
|
|
||||||
VP8_INSTANTIATE_TEST_CASE(InvalidFileInvalidPeekTest,
|
VP8_INSTANTIATE_TEST_CASE(InvalidFileInvalidPeekTest,
|
||||||
::testing::ValuesIn(kVP8InvalidFileTests));
|
::testing::ValuesIn(kVP8InvalidPeekTests));
|
||||||
#endif // CONFIG_VP8_DECODER
|
#endif // CONFIG_VP8_DECODER
|
||||||
|
|
||||||
#if CONFIG_VP9_DECODER
|
#if CONFIG_VP9_DECODER
|
||||||
|
@ -184,6 +201,7 @@ const DecodeParam kMultiThreadedVP9InvalidFileTests[] = {
|
||||||
"invalid-vp90-2-08-tile_1x8_frame_parallel.webm.ivf.s288_r01-05_b6-.ivf" },
|
"invalid-vp90-2-08-tile_1x8_frame_parallel.webm.ivf.s288_r01-05_b6-.ivf" },
|
||||||
{ 2, "invalid-vp90-2-09-aq2.webm.ivf.s3984_r01-05_b6-.v2.ivf" },
|
{ 2, "invalid-vp90-2-09-aq2.webm.ivf.s3984_r01-05_b6-.v2.ivf" },
|
||||||
{ 4, "invalid-vp90-2-09-subpixel-00.ivf.s19552_r01-05_b6-.v2.ivf" },
|
{ 4, "invalid-vp90-2-09-subpixel-00.ivf.s19552_r01-05_b6-.v2.ivf" },
|
||||||
|
{ 2, "invalid-crbug-629481.webm" },
|
||||||
};
|
};
|
||||||
|
|
||||||
INSTANTIATE_TEST_CASE_P(
|
INSTANTIATE_TEST_CASE_P(
|
||||||
|
|
|
@ -47,8 +47,8 @@ class IVFVideoSource : public CompressedVideoSource {
|
||||||
|
|
||||||
virtual void Begin() {
|
virtual void Begin() {
|
||||||
input_file_ = OpenTestDataFile(file_name_);
|
input_file_ = OpenTestDataFile(file_name_);
|
||||||
ASSERT_TRUE(input_file_ != NULL) << "Input file open failed. Filename: "
|
ASSERT_TRUE(input_file_ != NULL)
|
||||||
<< file_name_;
|
<< "Input file open failed. Filename: " << file_name_;
|
||||||
|
|
||||||
// Read file header
|
// Read file header
|
||||||
uint8_t file_hdr[kIvfFileHdrSize];
|
uint8_t file_hdr[kIvfFileHdrSize];
|
||||||
|
|
|
@ -135,8 +135,8 @@ TEST_P(KeyframeTest, TestAutoKeyframe) {
|
||||||
for (std::vector<vpx_codec_pts_t>::const_iterator iter = kf_pts_list_.begin();
|
for (std::vector<vpx_codec_pts_t>::const_iterator iter = kf_pts_list_.begin();
|
||||||
iter != kf_pts_list_.end(); ++iter) {
|
iter != kf_pts_list_.end(); ++iter) {
|
||||||
if (deadline_ == VPX_DL_REALTIME && *iter > 0)
|
if (deadline_ == VPX_DL_REALTIME && *iter > 0)
|
||||||
EXPECT_EQ(0, (*iter - 1) % 30) << "Unexpected keyframe at frame "
|
EXPECT_EQ(0, (*iter - 1) % 30)
|
||||||
<< *iter;
|
<< "Unexpected keyframe at frame " << *iter;
|
||||||
else
|
else
|
||||||
EXPECT_EQ(0, *iter % 30) << "Unexpected keyframe at frame " << *iter;
|
EXPECT_EQ(0, *iter % 30) << "Unexpected keyframe at frame " << *iter;
|
||||||
}
|
}
|
||||||
|
|
|
@ -66,6 +66,36 @@ class LevelTest
|
||||||
int level_;
|
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 for keeping level stats only
|
||||||
TEST_P(LevelTest, TestTargetLevel0) {
|
TEST_P(LevelTest, TestTargetLevel0) {
|
||||||
::libvpx_test::I420VideoSource video("hantro_odd.yuv", 208, 144, 30, 1, 0,
|
::libvpx_test::I420VideoSource video("hantro_odd.yuv", 208, 144, 30, 1, 0,
|
||||||
|
@ -73,11 +103,11 @@ TEST_P(LevelTest, TestTargetLevel0) {
|
||||||
target_level_ = 0;
|
target_level_ = 0;
|
||||||
min_gf_internal_ = 4;
|
min_gf_internal_ = 4;
|
||||||
ASSERT_NO_FATAL_FAILURE(RunLoop(&video));
|
ASSERT_NO_FATAL_FAILURE(RunLoop(&video));
|
||||||
ASSERT_EQ(11, level_);
|
ASSERT_GE(11, level_);
|
||||||
|
|
||||||
cfg_.rc_target_bitrate = 1600;
|
cfg_.rc_target_bitrate = 1600;
|
||||||
ASSERT_NO_FATAL_FAILURE(RunLoop(&video));
|
ASSERT_NO_FATAL_FAILURE(RunLoop(&video));
|
||||||
ASSERT_EQ(20, level_);
|
ASSERT_GE(20, level_);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Test for level control being turned off
|
// Test for level control being turned off
|
||||||
|
@ -94,12 +124,13 @@ TEST_P(LevelTest, TestTargetLevelApi) {
|
||||||
vpx_codec_ctx_t enc;
|
vpx_codec_ctx_t enc;
|
||||||
vpx_codec_enc_cfg_t cfg;
|
vpx_codec_enc_cfg_t cfg;
|
||||||
EXPECT_EQ(VPX_CODEC_OK, vpx_codec_enc_config_default(codec, &cfg, 0));
|
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));
|
EXPECT_EQ(VPX_CODEC_OK, vpx_codec_enc_init(&enc, codec, &cfg, 0));
|
||||||
for (int level = 0; level <= 256; ++level) {
|
for (int level = 0; level <= 256; ++level) {
|
||||||
if (level == 10 || level == 11 || level == 20 || level == 21 ||
|
if (level == 10 || level == 11 || level == 20 || level == 21 ||
|
||||||
level == 30 || level == 31 || level == 40 || level == 41 ||
|
level == 30 || level == 31 || level == 40 || level == 41 ||
|
||||||
level == 50 || level == 51 || level == 52 || level == 60 ||
|
level == 50 || level == 51 || level == 52 || level == 60 ||
|
||||||
level == 61 || level == 62 || level == 0 || level == 255)
|
level == 61 || level == 62 || level == 0 || level == 1 || level == 255)
|
||||||
EXPECT_EQ(VPX_CODEC_OK,
|
EXPECT_EQ(VPX_CODEC_OK,
|
||||||
vpx_codec_control(&enc, VP9E_SET_TARGET_LEVEL, level));
|
vpx_codec_control(&enc, VP9E_SET_TARGET_LEVEL, level));
|
||||||
else
|
else
|
||||||
|
|
|
@ -114,6 +114,18 @@ 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> {
|
class Loop8Test6Param : public ::testing::TestWithParam<loop8_param_t> {
|
||||||
public:
|
public:
|
||||||
virtual ~Loop8Test6Param() {}
|
virtual ~Loop8Test6Param() {}
|
||||||
|
@ -162,15 +174,15 @@ TEST_P(Loop8Test6Param, OperationCheck) {
|
||||||
int first_failure = -1;
|
int first_failure = -1;
|
||||||
for (int i = 0; i < count_test_block; ++i) {
|
for (int i = 0; i < count_test_block; ++i) {
|
||||||
int err_count = 0;
|
int err_count = 0;
|
||||||
uint8_t tmp = static_cast<uint8_t>(rnd(3 * MAX_LOOP_FILTER + 4));
|
uint8_t tmp = GetOuterThresh(&rnd);
|
||||||
DECLARE_ALIGNED(16, const uint8_t,
|
DECLARE_ALIGNED(16, const uint8_t,
|
||||||
blimit[16]) = { tmp, tmp, tmp, tmp, tmp, tmp, tmp, tmp,
|
blimit[16]) = { tmp, tmp, tmp, tmp, tmp, tmp, tmp, tmp,
|
||||||
tmp, tmp, tmp, tmp, tmp, tmp, tmp, tmp };
|
tmp, tmp, tmp, tmp, tmp, tmp, tmp, tmp };
|
||||||
tmp = static_cast<uint8_t>(rnd(MAX_LOOP_FILTER));
|
tmp = GetInnerThresh(&rnd);
|
||||||
DECLARE_ALIGNED(16, const uint8_t,
|
DECLARE_ALIGNED(16, const uint8_t,
|
||||||
limit[16]) = { tmp, tmp, tmp, tmp, tmp, tmp, tmp, tmp,
|
limit[16]) = { tmp, tmp, tmp, tmp, tmp, tmp, tmp, tmp,
|
||||||
tmp, tmp, tmp, tmp, tmp, tmp, tmp, tmp };
|
tmp, tmp, tmp, tmp, tmp, tmp, tmp, tmp };
|
||||||
tmp = rnd.Rand8();
|
tmp = GetHevThresh(&rnd);
|
||||||
DECLARE_ALIGNED(16, const uint8_t,
|
DECLARE_ALIGNED(16, const uint8_t,
|
||||||
thresh[16]) = { tmp, tmp, tmp, tmp, tmp, tmp, tmp, tmp,
|
thresh[16]) = { tmp, tmp, tmp, tmp, tmp, tmp, tmp, tmp,
|
||||||
tmp, tmp, tmp, tmp, tmp, tmp, tmp, tmp };
|
tmp, tmp, tmp, tmp, tmp, tmp, tmp, tmp };
|
||||||
|
@ -221,15 +233,15 @@ TEST_P(Loop8Test6Param, ValueCheck) {
|
||||||
|
|
||||||
for (int i = 0; i < count_test_block; ++i) {
|
for (int i = 0; i < count_test_block; ++i) {
|
||||||
int err_count = 0;
|
int err_count = 0;
|
||||||
uint8_t tmp = static_cast<uint8_t>(rnd(3 * MAX_LOOP_FILTER + 4));
|
uint8_t tmp = GetOuterThresh(&rnd);
|
||||||
DECLARE_ALIGNED(16, const uint8_t,
|
DECLARE_ALIGNED(16, const uint8_t,
|
||||||
blimit[16]) = { tmp, tmp, tmp, tmp, tmp, tmp, tmp, tmp,
|
blimit[16]) = { tmp, tmp, tmp, tmp, tmp, tmp, tmp, tmp,
|
||||||
tmp, tmp, tmp, tmp, tmp, tmp, tmp, tmp };
|
tmp, tmp, tmp, tmp, tmp, tmp, tmp, tmp };
|
||||||
tmp = static_cast<uint8_t>(rnd(MAX_LOOP_FILTER));
|
tmp = GetInnerThresh(&rnd);
|
||||||
DECLARE_ALIGNED(16, const uint8_t,
|
DECLARE_ALIGNED(16, const uint8_t,
|
||||||
limit[16]) = { tmp, tmp, tmp, tmp, tmp, tmp, tmp, tmp,
|
limit[16]) = { tmp, tmp, tmp, tmp, tmp, tmp, tmp, tmp,
|
||||||
tmp, tmp, tmp, tmp, tmp, tmp, tmp, tmp };
|
tmp, tmp, tmp, tmp, tmp, tmp, tmp, tmp };
|
||||||
tmp = rnd.Rand8();
|
tmp = GetHevThresh(&rnd);
|
||||||
DECLARE_ALIGNED(16, const uint8_t,
|
DECLARE_ALIGNED(16, const uint8_t,
|
||||||
thresh[16]) = { tmp, tmp, tmp, tmp, tmp, tmp, tmp, tmp,
|
thresh[16]) = { tmp, tmp, tmp, tmp, tmp, tmp, tmp, tmp,
|
||||||
tmp, tmp, tmp, tmp, tmp, tmp, tmp, tmp };
|
tmp, tmp, tmp, tmp, tmp, tmp, tmp, tmp };
|
||||||
|
@ -271,27 +283,27 @@ TEST_P(Loop8Test9Param, OperationCheck) {
|
||||||
int first_failure = -1;
|
int first_failure = -1;
|
||||||
for (int i = 0; i < count_test_block; ++i) {
|
for (int i = 0; i < count_test_block; ++i) {
|
||||||
int err_count = 0;
|
int err_count = 0;
|
||||||
uint8_t tmp = static_cast<uint8_t>(rnd(3 * MAX_LOOP_FILTER + 4));
|
uint8_t tmp = GetOuterThresh(&rnd);
|
||||||
DECLARE_ALIGNED(16, const uint8_t,
|
DECLARE_ALIGNED(16, const uint8_t,
|
||||||
blimit0[16]) = { tmp, tmp, tmp, tmp, tmp, tmp, tmp, tmp,
|
blimit0[16]) = { tmp, tmp, tmp, tmp, tmp, tmp, tmp, tmp,
|
||||||
tmp, tmp, tmp, tmp, tmp, tmp, tmp, tmp };
|
tmp, tmp, tmp, tmp, tmp, tmp, tmp, tmp };
|
||||||
tmp = static_cast<uint8_t>(rnd(MAX_LOOP_FILTER));
|
tmp = GetInnerThresh(&rnd);
|
||||||
DECLARE_ALIGNED(16, const uint8_t,
|
DECLARE_ALIGNED(16, const uint8_t,
|
||||||
limit0[16]) = { tmp, tmp, tmp, tmp, tmp, tmp, tmp, tmp,
|
limit0[16]) = { tmp, tmp, tmp, tmp, tmp, tmp, tmp, tmp,
|
||||||
tmp, tmp, tmp, tmp, tmp, tmp, tmp, tmp };
|
tmp, tmp, tmp, tmp, tmp, tmp, tmp, tmp };
|
||||||
tmp = rnd.Rand8();
|
tmp = GetHevThresh(&rnd);
|
||||||
DECLARE_ALIGNED(16, const uint8_t,
|
DECLARE_ALIGNED(16, const uint8_t,
|
||||||
thresh0[16]) = { tmp, tmp, tmp, tmp, tmp, tmp, tmp, tmp,
|
thresh0[16]) = { tmp, tmp, tmp, tmp, tmp, tmp, tmp, tmp,
|
||||||
tmp, tmp, tmp, tmp, tmp, tmp, tmp, tmp };
|
tmp, tmp, tmp, tmp, tmp, tmp, tmp, tmp };
|
||||||
tmp = static_cast<uint8_t>(rnd(3 * MAX_LOOP_FILTER + 4));
|
tmp = GetOuterThresh(&rnd);
|
||||||
DECLARE_ALIGNED(16, const uint8_t,
|
DECLARE_ALIGNED(16, const uint8_t,
|
||||||
blimit1[16]) = { tmp, tmp, tmp, tmp, tmp, tmp, tmp, tmp,
|
blimit1[16]) = { tmp, tmp, tmp, tmp, tmp, tmp, tmp, tmp,
|
||||||
tmp, tmp, tmp, tmp, tmp, tmp, tmp, tmp };
|
tmp, tmp, tmp, tmp, tmp, tmp, tmp, tmp };
|
||||||
tmp = static_cast<uint8_t>(rnd(MAX_LOOP_FILTER));
|
tmp = GetInnerThresh(&rnd);
|
||||||
DECLARE_ALIGNED(16, const uint8_t,
|
DECLARE_ALIGNED(16, const uint8_t,
|
||||||
limit1[16]) = { tmp, tmp, tmp, tmp, tmp, tmp, tmp, tmp,
|
limit1[16]) = { tmp, tmp, tmp, tmp, tmp, tmp, tmp, tmp,
|
||||||
tmp, tmp, tmp, tmp, tmp, tmp, tmp, tmp };
|
tmp, tmp, tmp, tmp, tmp, tmp, tmp, tmp };
|
||||||
tmp = rnd.Rand8();
|
tmp = GetHevThresh(&rnd);
|
||||||
DECLARE_ALIGNED(16, const uint8_t,
|
DECLARE_ALIGNED(16, const uint8_t,
|
||||||
thresh1[16]) = { tmp, tmp, tmp, tmp, tmp, tmp, tmp, tmp,
|
thresh1[16]) = { tmp, tmp, tmp, tmp, tmp, tmp, tmp, tmp,
|
||||||
tmp, tmp, tmp, tmp, tmp, tmp, tmp, tmp };
|
tmp, tmp, tmp, tmp, tmp, tmp, tmp, tmp };
|
||||||
|
@ -334,27 +346,27 @@ TEST_P(Loop8Test9Param, ValueCheck) {
|
||||||
int first_failure = -1;
|
int first_failure = -1;
|
||||||
for (int i = 0; i < count_test_block; ++i) {
|
for (int i = 0; i < count_test_block; ++i) {
|
||||||
int err_count = 0;
|
int err_count = 0;
|
||||||
uint8_t tmp = static_cast<uint8_t>(rnd(3 * MAX_LOOP_FILTER + 4));
|
uint8_t tmp = GetOuterThresh(&rnd);
|
||||||
DECLARE_ALIGNED(16, const uint8_t,
|
DECLARE_ALIGNED(16, const uint8_t,
|
||||||
blimit0[16]) = { tmp, tmp, tmp, tmp, tmp, tmp, tmp, tmp,
|
blimit0[16]) = { tmp, tmp, tmp, tmp, tmp, tmp, tmp, tmp,
|
||||||
tmp, tmp, tmp, tmp, tmp, tmp, tmp, tmp };
|
tmp, tmp, tmp, tmp, tmp, tmp, tmp, tmp };
|
||||||
tmp = static_cast<uint8_t>(rnd(MAX_LOOP_FILTER));
|
tmp = GetInnerThresh(&rnd);
|
||||||
DECLARE_ALIGNED(16, const uint8_t,
|
DECLARE_ALIGNED(16, const uint8_t,
|
||||||
limit0[16]) = { tmp, tmp, tmp, tmp, tmp, tmp, tmp, tmp,
|
limit0[16]) = { tmp, tmp, tmp, tmp, tmp, tmp, tmp, tmp,
|
||||||
tmp, tmp, tmp, tmp, tmp, tmp, tmp, tmp };
|
tmp, tmp, tmp, tmp, tmp, tmp, tmp, tmp };
|
||||||
tmp = rnd.Rand8();
|
tmp = GetHevThresh(&rnd);
|
||||||
DECLARE_ALIGNED(16, const uint8_t,
|
DECLARE_ALIGNED(16, const uint8_t,
|
||||||
thresh0[16]) = { tmp, tmp, tmp, tmp, tmp, tmp, tmp, tmp,
|
thresh0[16]) = { tmp, tmp, tmp, tmp, tmp, tmp, tmp, tmp,
|
||||||
tmp, tmp, tmp, tmp, tmp, tmp, tmp, tmp };
|
tmp, tmp, tmp, tmp, tmp, tmp, tmp, tmp };
|
||||||
tmp = static_cast<uint8_t>(rnd(3 * MAX_LOOP_FILTER + 4));
|
tmp = GetOuterThresh(&rnd);
|
||||||
DECLARE_ALIGNED(16, const uint8_t,
|
DECLARE_ALIGNED(16, const uint8_t,
|
||||||
blimit1[16]) = { tmp, tmp, tmp, tmp, tmp, tmp, tmp, tmp,
|
blimit1[16]) = { tmp, tmp, tmp, tmp, tmp, tmp, tmp, tmp,
|
||||||
tmp, tmp, tmp, tmp, tmp, tmp, tmp, tmp };
|
tmp, tmp, tmp, tmp, tmp, tmp, tmp, tmp };
|
||||||
tmp = static_cast<uint8_t>(rnd(MAX_LOOP_FILTER));
|
tmp = GetInnerThresh(&rnd);
|
||||||
DECLARE_ALIGNED(16, const uint8_t,
|
DECLARE_ALIGNED(16, const uint8_t,
|
||||||
limit1[16]) = { tmp, tmp, tmp, tmp, tmp, tmp, tmp, tmp,
|
limit1[16]) = { tmp, tmp, tmp, tmp, tmp, tmp, tmp, tmp,
|
||||||
tmp, tmp, tmp, tmp, tmp, tmp, tmp, tmp };
|
tmp, tmp, tmp, tmp, tmp, tmp, tmp, tmp };
|
||||||
tmp = rnd.Rand8();
|
tmp = GetHevThresh(&rnd);
|
||||||
DECLARE_ALIGNED(16, const uint8_t,
|
DECLARE_ALIGNED(16, const uint8_t,
|
||||||
thresh1[16]) = { tmp, tmp, tmp, tmp, tmp, tmp, tmp, tmp,
|
thresh1[16]) = { tmp, tmp, tmp, tmp, tmp, tmp, tmp, tmp,
|
||||||
tmp, tmp, tmp, tmp, tmp, tmp, tmp, tmp };
|
tmp, tmp, tmp, tmp, tmp, tmp, tmp, tmp };
|
||||||
|
@ -402,10 +414,10 @@ INSTANTIATE_TEST_CASE_P(
|
||||||
&vpx_highbd_lpf_vertical_4_c, 8),
|
&vpx_highbd_lpf_vertical_4_c, 8),
|
||||||
make_tuple(&vpx_highbd_lpf_horizontal_8_sse2,
|
make_tuple(&vpx_highbd_lpf_horizontal_8_sse2,
|
||||||
&vpx_highbd_lpf_horizontal_8_c, 8),
|
&vpx_highbd_lpf_horizontal_8_c, 8),
|
||||||
make_tuple(&vpx_highbd_lpf_horizontal_edge_8_sse2,
|
make_tuple(&vpx_highbd_lpf_horizontal_16_sse2,
|
||||||
&vpx_highbd_lpf_horizontal_edge_8_c, 8),
|
&vpx_highbd_lpf_horizontal_16_c, 8),
|
||||||
make_tuple(&vpx_highbd_lpf_horizontal_edge_16_sse2,
|
make_tuple(&vpx_highbd_lpf_horizontal_16_dual_sse2,
|
||||||
&vpx_highbd_lpf_horizontal_edge_16_c, 8),
|
&vpx_highbd_lpf_horizontal_16_dual_c, 8),
|
||||||
make_tuple(&vpx_highbd_lpf_vertical_8_sse2,
|
make_tuple(&vpx_highbd_lpf_vertical_8_sse2,
|
||||||
&vpx_highbd_lpf_vertical_8_c, 8),
|
&vpx_highbd_lpf_vertical_8_c, 8),
|
||||||
make_tuple(&vpx_highbd_lpf_vertical_16_sse2,
|
make_tuple(&vpx_highbd_lpf_vertical_16_sse2,
|
||||||
|
@ -416,10 +428,10 @@ INSTANTIATE_TEST_CASE_P(
|
||||||
&vpx_highbd_lpf_vertical_4_c, 10),
|
&vpx_highbd_lpf_vertical_4_c, 10),
|
||||||
make_tuple(&vpx_highbd_lpf_horizontal_8_sse2,
|
make_tuple(&vpx_highbd_lpf_horizontal_8_sse2,
|
||||||
&vpx_highbd_lpf_horizontal_8_c, 10),
|
&vpx_highbd_lpf_horizontal_8_c, 10),
|
||||||
make_tuple(&vpx_highbd_lpf_horizontal_edge_8_sse2,
|
make_tuple(&vpx_highbd_lpf_horizontal_16_sse2,
|
||||||
&vpx_highbd_lpf_horizontal_edge_8_c, 10),
|
&vpx_highbd_lpf_horizontal_16_c, 10),
|
||||||
make_tuple(&vpx_highbd_lpf_horizontal_edge_16_sse2,
|
make_tuple(&vpx_highbd_lpf_horizontal_16_dual_sse2,
|
||||||
&vpx_highbd_lpf_horizontal_edge_16_c, 10),
|
&vpx_highbd_lpf_horizontal_16_dual_c, 10),
|
||||||
make_tuple(&vpx_highbd_lpf_vertical_8_sse2,
|
make_tuple(&vpx_highbd_lpf_vertical_8_sse2,
|
||||||
&vpx_highbd_lpf_vertical_8_c, 10),
|
&vpx_highbd_lpf_vertical_8_c, 10),
|
||||||
make_tuple(&vpx_highbd_lpf_vertical_16_sse2,
|
make_tuple(&vpx_highbd_lpf_vertical_16_sse2,
|
||||||
|
@ -430,10 +442,10 @@ INSTANTIATE_TEST_CASE_P(
|
||||||
&vpx_highbd_lpf_vertical_4_c, 12),
|
&vpx_highbd_lpf_vertical_4_c, 12),
|
||||||
make_tuple(&vpx_highbd_lpf_horizontal_8_sse2,
|
make_tuple(&vpx_highbd_lpf_horizontal_8_sse2,
|
||||||
&vpx_highbd_lpf_horizontal_8_c, 12),
|
&vpx_highbd_lpf_horizontal_8_c, 12),
|
||||||
make_tuple(&vpx_highbd_lpf_horizontal_edge_8_sse2,
|
make_tuple(&vpx_highbd_lpf_horizontal_16_sse2,
|
||||||
&vpx_highbd_lpf_horizontal_edge_8_c, 12),
|
&vpx_highbd_lpf_horizontal_16_c, 12),
|
||||||
make_tuple(&vpx_highbd_lpf_horizontal_edge_16_sse2,
|
make_tuple(&vpx_highbd_lpf_horizontal_16_dual_sse2,
|
||||||
&vpx_highbd_lpf_horizontal_edge_16_c, 12),
|
&vpx_highbd_lpf_horizontal_16_dual_c, 12),
|
||||||
make_tuple(&vpx_highbd_lpf_vertical_8_sse2,
|
make_tuple(&vpx_highbd_lpf_vertical_8_sse2,
|
||||||
&vpx_highbd_lpf_vertical_8_c, 12),
|
&vpx_highbd_lpf_vertical_8_c, 12),
|
||||||
make_tuple(&vpx_highbd_lpf_vertical_16_sse2,
|
make_tuple(&vpx_highbd_lpf_vertical_16_sse2,
|
||||||
|
@ -450,10 +462,9 @@ INSTANTIATE_TEST_CASE_P(
|
||||||
::testing::Values(
|
::testing::Values(
|
||||||
make_tuple(&vpx_lpf_horizontal_4_sse2, &vpx_lpf_horizontal_4_c, 8),
|
make_tuple(&vpx_lpf_horizontal_4_sse2, &vpx_lpf_horizontal_4_c, 8),
|
||||||
make_tuple(&vpx_lpf_horizontal_8_sse2, &vpx_lpf_horizontal_8_c, 8),
|
make_tuple(&vpx_lpf_horizontal_8_sse2, &vpx_lpf_horizontal_8_c, 8),
|
||||||
make_tuple(&vpx_lpf_horizontal_edge_8_sse2,
|
make_tuple(&vpx_lpf_horizontal_16_sse2, &vpx_lpf_horizontal_16_c, 8),
|
||||||
&vpx_lpf_horizontal_edge_8_c, 8),
|
make_tuple(&vpx_lpf_horizontal_16_dual_sse2,
|
||||||
make_tuple(&vpx_lpf_horizontal_edge_16_sse2,
|
&vpx_lpf_horizontal_16_dual_c, 8),
|
||||||
&vpx_lpf_horizontal_edge_16_c, 8),
|
|
||||||
make_tuple(&vpx_lpf_vertical_4_sse2, &vpx_lpf_vertical_4_c, 8),
|
make_tuple(&vpx_lpf_vertical_4_sse2, &vpx_lpf_vertical_4_c, 8),
|
||||||
make_tuple(&vpx_lpf_vertical_8_sse2, &vpx_lpf_vertical_8_c, 8),
|
make_tuple(&vpx_lpf_vertical_8_sse2, &vpx_lpf_vertical_8_c, 8),
|
||||||
make_tuple(&vpx_lpf_vertical_16_sse2, &vpx_lpf_vertical_16_c, 8),
|
make_tuple(&vpx_lpf_vertical_16_sse2, &vpx_lpf_vertical_16_c, 8),
|
||||||
|
@ -465,10 +476,10 @@ INSTANTIATE_TEST_CASE_P(
|
||||||
#if HAVE_AVX2 && (!CONFIG_VP9_HIGHBITDEPTH)
|
#if HAVE_AVX2 && (!CONFIG_VP9_HIGHBITDEPTH)
|
||||||
INSTANTIATE_TEST_CASE_P(
|
INSTANTIATE_TEST_CASE_P(
|
||||||
AVX2, Loop8Test6Param,
|
AVX2, Loop8Test6Param,
|
||||||
::testing::Values(make_tuple(&vpx_lpf_horizontal_edge_8_avx2,
|
::testing::Values(make_tuple(&vpx_lpf_horizontal_16_avx2,
|
||||||
&vpx_lpf_horizontal_edge_8_c, 8),
|
&vpx_lpf_horizontal_16_c, 8),
|
||||||
make_tuple(&vpx_lpf_horizontal_edge_16_avx2,
|
make_tuple(&vpx_lpf_horizontal_16_dual_avx2,
|
||||||
&vpx_lpf_horizontal_edge_16_c, 8)));
|
&vpx_lpf_horizontal_16_dual_c, 8)));
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if HAVE_SSE2
|
#if HAVE_SSE2
|
||||||
|
@ -515,15 +526,89 @@ INSTANTIATE_TEST_CASE_P(
|
||||||
|
|
||||||
#if HAVE_NEON
|
#if HAVE_NEON
|
||||||
#if CONFIG_VP9_HIGHBITDEPTH
|
#if CONFIG_VP9_HIGHBITDEPTH
|
||||||
// No neon high bitdepth functions.
|
INSTANTIATE_TEST_CASE_P(
|
||||||
|
NEON, Loop8Test6Param,
|
||||||
|
::testing::Values(make_tuple(&vpx_highbd_lpf_horizontal_4_neon,
|
||||||
|
&vpx_highbd_lpf_horizontal_4_c, 8),
|
||||||
|
make_tuple(&vpx_highbd_lpf_horizontal_4_neon,
|
||||||
|
&vpx_highbd_lpf_horizontal_4_c, 10),
|
||||||
|
make_tuple(&vpx_highbd_lpf_horizontal_4_neon,
|
||||||
|
&vpx_highbd_lpf_horizontal_4_c, 12),
|
||||||
|
make_tuple(&vpx_highbd_lpf_horizontal_8_neon,
|
||||||
|
&vpx_highbd_lpf_horizontal_8_c, 8),
|
||||||
|
make_tuple(&vpx_highbd_lpf_horizontal_8_neon,
|
||||||
|
&vpx_highbd_lpf_horizontal_8_c, 10),
|
||||||
|
make_tuple(&vpx_highbd_lpf_horizontal_8_neon,
|
||||||
|
&vpx_highbd_lpf_horizontal_8_c, 12),
|
||||||
|
make_tuple(&vpx_highbd_lpf_horizontal_16_neon,
|
||||||
|
&vpx_highbd_lpf_horizontal_16_c, 8),
|
||||||
|
make_tuple(&vpx_highbd_lpf_horizontal_16_neon,
|
||||||
|
&vpx_highbd_lpf_horizontal_16_c, 10),
|
||||||
|
make_tuple(&vpx_highbd_lpf_horizontal_16_neon,
|
||||||
|
&vpx_highbd_lpf_horizontal_16_c, 12),
|
||||||
|
make_tuple(&vpx_highbd_lpf_horizontal_16_dual_neon,
|
||||||
|
&vpx_highbd_lpf_horizontal_16_dual_c, 8),
|
||||||
|
make_tuple(&vpx_highbd_lpf_horizontal_16_dual_neon,
|
||||||
|
&vpx_highbd_lpf_horizontal_16_dual_c, 10),
|
||||||
|
make_tuple(&vpx_highbd_lpf_horizontal_16_dual_neon,
|
||||||
|
&vpx_highbd_lpf_horizontal_16_dual_c, 12),
|
||||||
|
make_tuple(&vpx_highbd_lpf_vertical_4_neon,
|
||||||
|
&vpx_highbd_lpf_vertical_4_c, 8),
|
||||||
|
make_tuple(&vpx_highbd_lpf_vertical_4_neon,
|
||||||
|
&vpx_highbd_lpf_vertical_4_c, 10),
|
||||||
|
make_tuple(&vpx_highbd_lpf_vertical_4_neon,
|
||||||
|
&vpx_highbd_lpf_vertical_4_c, 12),
|
||||||
|
make_tuple(&vpx_highbd_lpf_vertical_8_neon,
|
||||||
|
&vpx_highbd_lpf_vertical_8_c, 8),
|
||||||
|
make_tuple(&vpx_highbd_lpf_vertical_8_neon,
|
||||||
|
&vpx_highbd_lpf_vertical_8_c, 10),
|
||||||
|
make_tuple(&vpx_highbd_lpf_vertical_8_neon,
|
||||||
|
&vpx_highbd_lpf_vertical_8_c, 12),
|
||||||
|
make_tuple(&vpx_highbd_lpf_vertical_16_neon,
|
||||||
|
&vpx_highbd_lpf_vertical_16_c, 8),
|
||||||
|
make_tuple(&vpx_highbd_lpf_vertical_16_neon,
|
||||||
|
&vpx_highbd_lpf_vertical_16_c, 10),
|
||||||
|
make_tuple(&vpx_highbd_lpf_vertical_16_neon,
|
||||||
|
&vpx_highbd_lpf_vertical_16_c, 12),
|
||||||
|
make_tuple(&vpx_highbd_lpf_vertical_16_dual_neon,
|
||||||
|
&vpx_highbd_lpf_vertical_16_dual_c, 8),
|
||||||
|
make_tuple(&vpx_highbd_lpf_vertical_16_dual_neon,
|
||||||
|
&vpx_highbd_lpf_vertical_16_dual_c, 10),
|
||||||
|
make_tuple(&vpx_highbd_lpf_vertical_16_dual_neon,
|
||||||
|
&vpx_highbd_lpf_vertical_16_dual_c, 12)));
|
||||||
|
INSTANTIATE_TEST_CASE_P(
|
||||||
|
NEON, Loop8Test9Param,
|
||||||
|
::testing::Values(make_tuple(&vpx_highbd_lpf_horizontal_4_dual_neon,
|
||||||
|
&vpx_highbd_lpf_horizontal_4_dual_c, 8),
|
||||||
|
make_tuple(&vpx_highbd_lpf_horizontal_4_dual_neon,
|
||||||
|
&vpx_highbd_lpf_horizontal_4_dual_c, 10),
|
||||||
|
make_tuple(&vpx_highbd_lpf_horizontal_4_dual_neon,
|
||||||
|
&vpx_highbd_lpf_horizontal_4_dual_c, 12),
|
||||||
|
make_tuple(&vpx_highbd_lpf_horizontal_8_dual_neon,
|
||||||
|
&vpx_highbd_lpf_horizontal_8_dual_c, 8),
|
||||||
|
make_tuple(&vpx_highbd_lpf_horizontal_8_dual_neon,
|
||||||
|
&vpx_highbd_lpf_horizontal_8_dual_c, 10),
|
||||||
|
make_tuple(&vpx_highbd_lpf_horizontal_8_dual_neon,
|
||||||
|
&vpx_highbd_lpf_horizontal_8_dual_c, 12),
|
||||||
|
make_tuple(&vpx_highbd_lpf_vertical_4_dual_neon,
|
||||||
|
&vpx_highbd_lpf_vertical_4_dual_c, 8),
|
||||||
|
make_tuple(&vpx_highbd_lpf_vertical_4_dual_neon,
|
||||||
|
&vpx_highbd_lpf_vertical_4_dual_c, 10),
|
||||||
|
make_tuple(&vpx_highbd_lpf_vertical_4_dual_neon,
|
||||||
|
&vpx_highbd_lpf_vertical_4_dual_c, 12),
|
||||||
|
make_tuple(&vpx_highbd_lpf_vertical_8_dual_neon,
|
||||||
|
&vpx_highbd_lpf_vertical_8_dual_c, 8),
|
||||||
|
make_tuple(&vpx_highbd_lpf_vertical_8_dual_neon,
|
||||||
|
&vpx_highbd_lpf_vertical_8_dual_c, 10),
|
||||||
|
make_tuple(&vpx_highbd_lpf_vertical_8_dual_neon,
|
||||||
|
&vpx_highbd_lpf_vertical_8_dual_c, 12)));
|
||||||
#else
|
#else
|
||||||
INSTANTIATE_TEST_CASE_P(
|
INSTANTIATE_TEST_CASE_P(
|
||||||
NEON, Loop8Test6Param,
|
NEON, Loop8Test6Param,
|
||||||
::testing::Values(
|
::testing::Values(
|
||||||
make_tuple(&vpx_lpf_horizontal_edge_8_neon,
|
make_tuple(&vpx_lpf_horizontal_16_neon, &vpx_lpf_horizontal_16_c, 8),
|
||||||
&vpx_lpf_horizontal_edge_8_c, 8),
|
make_tuple(&vpx_lpf_horizontal_16_dual_neon,
|
||||||
make_tuple(&vpx_lpf_horizontal_edge_16_neon,
|
&vpx_lpf_horizontal_16_dual_c, 8),
|
||||||
&vpx_lpf_horizontal_edge_16_c, 8),
|
|
||||||
make_tuple(&vpx_lpf_vertical_16_neon, &vpx_lpf_vertical_16_c, 8),
|
make_tuple(&vpx_lpf_vertical_16_neon, &vpx_lpf_vertical_16_c, 8),
|
||||||
make_tuple(&vpx_lpf_vertical_16_dual_neon, &vpx_lpf_vertical_16_dual_c,
|
make_tuple(&vpx_lpf_vertical_16_dual_neon, &vpx_lpf_vertical_16_dual_c,
|
||||||
8),
|
8),
|
||||||
|
@ -550,8 +635,9 @@ INSTANTIATE_TEST_CASE_P(
|
||||||
::testing::Values(
|
::testing::Values(
|
||||||
make_tuple(&vpx_lpf_horizontal_4_dspr2, &vpx_lpf_horizontal_4_c, 8),
|
make_tuple(&vpx_lpf_horizontal_4_dspr2, &vpx_lpf_horizontal_4_c, 8),
|
||||||
make_tuple(&vpx_lpf_horizontal_8_dspr2, &vpx_lpf_horizontal_8_c, 8),
|
make_tuple(&vpx_lpf_horizontal_8_dspr2, &vpx_lpf_horizontal_8_c, 8),
|
||||||
make_tuple(&vpx_lpf_horizontal_edge_8, &vpx_lpf_horizontal_edge_8, 8),
|
make_tuple(&vpx_lpf_horizontal_16_dspr2, &vpx_lpf_horizontal_16_c, 8),
|
||||||
make_tuple(&vpx_lpf_horizontal_edge_16, &vpx_lpf_horizontal_edge_16, 8),
|
make_tuple(&vpx_lpf_horizontal_16_dual_dspr2,
|
||||||
|
&vpx_lpf_horizontal_16_dual_c, 8),
|
||||||
make_tuple(&vpx_lpf_vertical_4_dspr2, &vpx_lpf_vertical_4_c, 8),
|
make_tuple(&vpx_lpf_vertical_4_dspr2, &vpx_lpf_vertical_4_c, 8),
|
||||||
make_tuple(&vpx_lpf_vertical_8_dspr2, &vpx_lpf_vertical_8_c, 8),
|
make_tuple(&vpx_lpf_vertical_8_dspr2, &vpx_lpf_vertical_8_c, 8),
|
||||||
make_tuple(&vpx_lpf_vertical_16_dspr2, &vpx_lpf_vertical_16_c, 8),
|
make_tuple(&vpx_lpf_vertical_16_dspr2, &vpx_lpf_vertical_16_c, 8),
|
||||||
|
@ -576,10 +662,9 @@ INSTANTIATE_TEST_CASE_P(
|
||||||
::testing::Values(
|
::testing::Values(
|
||||||
make_tuple(&vpx_lpf_horizontal_4_msa, &vpx_lpf_horizontal_4_c, 8),
|
make_tuple(&vpx_lpf_horizontal_4_msa, &vpx_lpf_horizontal_4_c, 8),
|
||||||
make_tuple(&vpx_lpf_horizontal_8_msa, &vpx_lpf_horizontal_8_c, 8),
|
make_tuple(&vpx_lpf_horizontal_8_msa, &vpx_lpf_horizontal_8_c, 8),
|
||||||
make_tuple(&vpx_lpf_horizontal_edge_8_msa, &vpx_lpf_horizontal_edge_8_c,
|
make_tuple(&vpx_lpf_horizontal_16_msa, &vpx_lpf_horizontal_16_c, 8),
|
||||||
8),
|
make_tuple(&vpx_lpf_horizontal_16_dual_msa,
|
||||||
make_tuple(&vpx_lpf_horizontal_edge_16_msa,
|
&vpx_lpf_horizontal_16_dual_c, 8),
|
||||||
&vpx_lpf_horizontal_edge_16_c, 8),
|
|
||||||
make_tuple(&vpx_lpf_vertical_4_msa, &vpx_lpf_vertical_4_c, 8),
|
make_tuple(&vpx_lpf_vertical_4_msa, &vpx_lpf_vertical_4_c, 8),
|
||||||
make_tuple(&vpx_lpf_vertical_8_msa, &vpx_lpf_vertical_8_c, 8),
|
make_tuple(&vpx_lpf_vertical_8_msa, &vpx_lpf_vertical_8_c, 8),
|
||||||
make_tuple(&vpx_lpf_vertical_16_msa, &vpx_lpf_vertical_16_c, 8)));
|
make_tuple(&vpx_lpf_vertical_16_msa, &vpx_lpf_vertical_16_c, 8)));
|
||||||
|
|
|
@ -107,10 +107,10 @@ TEST_P(MinMaxTest, CompareReferenceAndVaryStride) {
|
||||||
int min_ref, max_ref, min, max;
|
int min_ref, max_ref, min, max;
|
||||||
reference_minmax(a, a_stride, b, b_stride, &min_ref, &max_ref);
|
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));
|
ASM_REGISTER_STATE_CHECK(mm_func_(a, a_stride, b, b_stride, &min, &max));
|
||||||
EXPECT_EQ(max_ref, max) << "when a_stride = " << a_stride
|
EXPECT_EQ(max_ref, max)
|
||||||
<< " and b_stride = " << b_stride;
|
<< "when a_stride = " << a_stride << " and b_stride = " << b_stride;
|
||||||
EXPECT_EQ(min_ref, min) << "when a_stride = " << a_stride
|
EXPECT_EQ(min_ref, min)
|
||||||
<< " and b_stride = " << b_stride;
|
<< "when a_stride = " << a_stride << " and b_stride = " << b_stride;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -127,4 +127,9 @@ INSTANTIATE_TEST_CASE_P(NEON, MinMaxTest,
|
||||||
::testing::Values(&vpx_minmax_8x8_neon));
|
::testing::Values(&vpx_minmax_8x8_neon));
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if HAVE_MSA
|
||||||
|
INSTANTIATE_TEST_CASE_P(MSA, MinMaxTest,
|
||||||
|
::testing::Values(&vpx_minmax_8x8_msa));
|
||||||
|
#endif
|
||||||
|
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -7,22 +7,42 @@
|
||||||
* in the file PATENTS. All contributing project authors may
|
* in the file PATENTS. All contributing project authors may
|
||||||
* be found in the AUTHORS file in the root of the source tree.
|
* 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/clear_system_state.h"
|
||||||
#include "test/register_state_check.h"
|
#include "test/register_state_check.h"
|
||||||
#include "third_party/googletest/src/include/gtest/gtest.h"
|
#include "third_party/googletest/src/include/gtest/gtest.h"
|
||||||
#include "./vpx_config.h"
|
|
||||||
#include "./vpx_dsp_rtcd.h"
|
|
||||||
#include "vpx/vpx_integer.h"
|
#include "vpx/vpx_integer.h"
|
||||||
#include "vpx_mem/vpx_mem.h"
|
#include "vpx_mem/vpx_mem.h"
|
||||||
|
|
||||||
typedef void (*PostProcFunc)(unsigned char *src_ptr, unsigned char *dst_ptr,
|
using libvpx_test::ACMRandom;
|
||||||
int src_pixels_per_line, int dst_pixels_per_line,
|
using libvpx_test::Buffer;
|
||||||
int cols, unsigned char *flimit, int size);
|
|
||||||
|
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 {
|
namespace {
|
||||||
|
|
||||||
class VPxPostProcessingFilterTest
|
// Compute the filter level used in post proc from the loop filter strength
|
||||||
: public ::testing::TestWithParam<PostProcFunc> {
|
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:
|
public:
|
||||||
virtual void TearDown() { libvpx_test::ClearSystemState(); }
|
virtual void TearDown() { libvpx_test::ClearSystemState(); }
|
||||||
};
|
};
|
||||||
|
@ -30,31 +50,22 @@ class VPxPostProcessingFilterTest
|
||||||
// Test routine for the VPx post-processing function
|
// Test routine for the VPx post-processing function
|
||||||
// vpx_post_proc_down_and_across_mb_row_c.
|
// vpx_post_proc_down_and_across_mb_row_c.
|
||||||
|
|
||||||
TEST_P(VPxPostProcessingFilterTest, FilterOutputCheck) {
|
TEST_P(VpxPostProcDownAndAcrossMbRowTest, CheckFilterOutput) {
|
||||||
// Size of the underlying data block that will be filtered.
|
// Size of the underlying data block that will be filtered.
|
||||||
const int block_width = 16;
|
const int block_width = 16;
|
||||||
const int block_height = 16;
|
const int block_height = 16;
|
||||||
|
|
||||||
// 5-tap filter needs 2 padding rows above and below the block in the input.
|
// 5-tap filter needs 2 padding rows above and below the block in the input.
|
||||||
const int input_width = block_width;
|
Buffer<uint8_t> src_image = Buffer<uint8_t>(block_width, block_height, 2);
|
||||||
const int input_height = block_height + 4;
|
ASSERT_TRUE(src_image.Init());
|
||||||
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.
|
// Filter extends output block by 8 samples at left and right edges.
|
||||||
const int output_width = block_width + 16;
|
// Though the left padding is only 8 bytes, the assembly code tries to
|
||||||
const int output_height = block_height;
|
// read 16 bytes before the pointer.
|
||||||
const int output_stride = output_width;
|
Buffer<uint8_t> dst_image =
|
||||||
const int output_size = output_width * output_height;
|
Buffer<uint8_t>(block_width, block_height, 8, 16, 8, 8);
|
||||||
|
ASSERT_TRUE(dst_image.Init());
|
||||||
|
|
||||||
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 =
|
uint8_t *const flimits =
|
||||||
reinterpret_cast<uint8_t *>(vpx_memalign(16, block_width));
|
reinterpret_cast<uint8_t *>(vpx_memalign(16, block_width));
|
||||||
(void)memset(flimits, 255, block_width);
|
(void)memset(flimits, 255, block_width);
|
||||||
|
@ -62,53 +73,412 @@ TEST_P(VPxPostProcessingFilterTest, FilterOutputCheck) {
|
||||||
// Initialize pixels in the input:
|
// Initialize pixels in the input:
|
||||||
// block pixels to value 1,
|
// block pixels to value 1,
|
||||||
// border pixels to value 10.
|
// border pixels to value 10.
|
||||||
(void)memset(src_image, 10, input_size);
|
src_image.SetPadding(10);
|
||||||
uint8_t *pixel_ptr = src_image_ptr;
|
src_image.Set(1);
|
||||||
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.
|
// Initialize pixels in the output to 99.
|
||||||
(void)memset(dst_image, 99, output_size);
|
dst_image.Set(99);
|
||||||
|
|
||||||
ASM_REGISTER_STATE_CHECK(GetParam()(src_image_ptr, dst_image_ptr,
|
ASM_REGISTER_STATE_CHECK(GetParam()(
|
||||||
input_stride, output_stride, block_width,
|
src_image.TopLeftPixel(), dst_image.TopLeftPixel(), src_image.stride(),
|
||||||
flimits, 16));
|
dst_image.stride(), block_width, flimits, 16));
|
||||||
|
|
||||||
static const uint8_t expected_data[block_height] = { 4, 3, 1, 1, 1, 1, 1, 1,
|
static const uint8_t kExpectedOutput[block_height] = {
|
||||||
1, 1, 1, 1, 1, 1, 3, 4 };
|
4, 3, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 3, 4
|
||||||
|
};
|
||||||
|
|
||||||
pixel_ptr = dst_image_ptr;
|
uint8_t *pixel_ptr = dst_image.TopLeftPixel();
|
||||||
for (int i = 0; i < block_height; ++i) {
|
for (int i = 0; i < block_height; ++i) {
|
||||||
for (int j = 0; j < block_width; ++j) {
|
for (int j = 0; j < block_width; ++j) {
|
||||||
EXPECT_EQ(expected_data[i], pixel_ptr[j])
|
ASSERT_EQ(kExpectedOutput[i], pixel_ptr[j])
|
||||||
<< "VPxPostProcessingFilterTest failed with invalid filter output";
|
<< "at (" << i << ", " << j << ")";
|
||||||
}
|
}
|
||||||
pixel_ptr += output_stride;
|
pixel_ptr += dst_image.stride();
|
||||||
}
|
}
|
||||||
|
|
||||||
vpx_free(src_image);
|
|
||||||
vpx_free(dst_image);
|
|
||||||
vpx_free(flimits);
|
vpx_free(flimits);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
TEST_P(VpxPostProcDownAndAcrossMbRowTest, CheckCvsAssembly) {
|
||||||
|
// Size of the underlying data block that will be filtered.
|
||||||
|
// Y blocks are always a multiple of 16 wide and exactly 16 high. U and V
|
||||||
|
// blocks are always a multiple of 8 wide and exactly 8 high.
|
||||||
|
const int block_width = 136;
|
||||||
|
const int block_height = 16;
|
||||||
|
|
||||||
|
// 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(
|
INSTANTIATE_TEST_CASE_P(
|
||||||
C, VPxPostProcessingFilterTest,
|
C, VpxPostProcDownAndAcrossMbRowTest,
|
||||||
::testing::Values(vpx_post_proc_down_and_across_mb_row_c));
|
::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
|
#if HAVE_SSE2
|
||||||
INSTANTIATE_TEST_CASE_P(
|
INSTANTIATE_TEST_CASE_P(
|
||||||
SSE2, VPxPostProcessingFilterTest,
|
SSE2, VpxPostProcDownAndAcrossMbRowTest,
|
||||||
::testing::Values(vpx_post_proc_down_and_across_mb_row_sse2));
|
::testing::Values(vpx_post_proc_down_and_across_mb_row_sse2));
|
||||||
#endif
|
|
||||||
|
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
|
||||||
|
|
||||||
#if HAVE_MSA
|
#if HAVE_MSA
|
||||||
INSTANTIATE_TEST_CASE_P(
|
INSTANTIATE_TEST_CASE_P(
|
||||||
MSA, VPxPostProcessingFilterTest,
|
MSA, VpxPostProcDownAndAcrossMbRowTest,
|
||||||
::testing::Values(vpx_post_proc_down_and_across_mb_row_msa));
|
::testing::Values(vpx_post_proc_down_and_across_mb_row_msa));
|
||||||
#endif
|
|
||||||
|
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
|
||||||
|
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
|
@ -292,15 +292,13 @@ INSTANTIATE_TEST_CASE_P(
|
||||||
NEON, SixtapPredictTest,
|
NEON, SixtapPredictTest,
|
||||||
::testing::Values(make_tuple(16, 16, &vp8_sixtap_predict16x16_neon),
|
::testing::Values(make_tuple(16, 16, &vp8_sixtap_predict16x16_neon),
|
||||||
make_tuple(8, 8, &vp8_sixtap_predict8x8_neon),
|
make_tuple(8, 8, &vp8_sixtap_predict8x8_neon),
|
||||||
make_tuple(8, 4, &vp8_sixtap_predict8x4_neon)));
|
make_tuple(8, 4, &vp8_sixtap_predict8x4_neon),
|
||||||
|
make_tuple(4, 4, &vp8_sixtap_predict4x4_neon)));
|
||||||
#endif
|
#endif
|
||||||
#if HAVE_MMX
|
#if HAVE_MMX
|
||||||
INSTANTIATE_TEST_CASE_P(
|
INSTANTIATE_TEST_CASE_P(
|
||||||
MMX, SixtapPredictTest,
|
MMX, SixtapPredictTest,
|
||||||
::testing::Values(make_tuple(16, 16, &vp8_sixtap_predict16x16_mmx),
|
::testing::Values(make_tuple(4, 4, &vp8_sixtap_predict4x4_mmx)));
|
||||||
make_tuple(8, 8, &vp8_sixtap_predict8x8_mmx),
|
|
||||||
make_tuple(8, 4, &vp8_sixtap_predict8x4_mmx),
|
|
||||||
make_tuple(4, 4, &vp8_sixtap_predict4x4_mmx)));
|
|
||||||
#endif
|
#endif
|
||||||
#if HAVE_SSE2
|
#if HAVE_SSE2
|
||||||
INSTANTIATE_TEST_CASE_P(
|
INSTANTIATE_TEST_CASE_P(
|
||||||
|
@ -326,6 +324,15 @@ INSTANTIATE_TEST_CASE_P(
|
||||||
make_tuple(4, 4, &vp8_sixtap_predict4x4_msa)));
|
make_tuple(4, 4, &vp8_sixtap_predict4x4_msa)));
|
||||||
#endif
|
#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 {};
|
class BilinearPredictTest : public PredictTestBase {};
|
||||||
|
|
||||||
TEST_P(BilinearPredictTest, TestWithRandomData) {
|
TEST_P(BilinearPredictTest, TestWithRandomData) {
|
||||||
|
@ -352,9 +359,7 @@ INSTANTIATE_TEST_CASE_P(
|
||||||
#if HAVE_MMX
|
#if HAVE_MMX
|
||||||
INSTANTIATE_TEST_CASE_P(
|
INSTANTIATE_TEST_CASE_P(
|
||||||
MMX, BilinearPredictTest,
|
MMX, BilinearPredictTest,
|
||||||
::testing::Values(make_tuple(16, 16, &vp8_bilinear_predict16x16_mmx),
|
::testing::Values(make_tuple(8, 4, &vp8_bilinear_predict8x4_mmx),
|
||||||
make_tuple(8, 8, &vp8_bilinear_predict8x8_mmx),
|
|
||||||
make_tuple(8, 4, &vp8_bilinear_predict8x4_mmx),
|
|
||||||
make_tuple(4, 4, &vp8_bilinear_predict4x4_mmx)));
|
make_tuple(4, 4, &vp8_bilinear_predict4x4_mmx)));
|
||||||
#endif
|
#endif
|
||||||
#if HAVE_SSE2
|
#if HAVE_SSE2
|
||||||
|
|
|
@ -200,4 +200,12 @@ INSTANTIATE_TEST_CASE_P(
|
||||||
make_tuple(&vp8_fast_quantize_b_msa, &vp8_fast_quantize_b_c),
|
make_tuple(&vp8_fast_quantize_b_msa, &vp8_fast_quantize_b_c),
|
||||||
make_tuple(&vp8_regular_quantize_b_msa, &vp8_regular_quantize_b_c)));
|
make_tuple(&vp8_regular_quantize_b_msa, &vp8_regular_quantize_b_c)));
|
||||||
#endif // HAVE_MSA
|
#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
|
} // namespace
|
||||||
|
|
|
@ -32,7 +32,9 @@
|
||||||
|
|
||||||
#undef NOMINMAX
|
#undef NOMINMAX
|
||||||
#define NOMINMAX
|
#define NOMINMAX
|
||||||
|
#ifndef WIN32_LEAN_AND_MEAN
|
||||||
#define WIN32_LEAN_AND_MEAN
|
#define WIN32_LEAN_AND_MEAN
|
||||||
|
#endif
|
||||||
#include <windows.h>
|
#include <windows.h>
|
||||||
#include <winnt.h>
|
#include <winnt.h>
|
||||||
|
|
||||||
|
@ -111,8 +113,8 @@ class RegisterStateCheck {
|
||||||
int64_t post_store[8];
|
int64_t post_store[8];
|
||||||
vpx_push_neon(post_store);
|
vpx_push_neon(post_store);
|
||||||
for (int i = 0; i < 8; ++i) {
|
for (int i = 0; i < 8; ++i) {
|
||||||
EXPECT_EQ(pre_store_[i], post_store[i]) << "d" << i + 8
|
EXPECT_EQ(pre_store_[i], post_store[i])
|
||||||
<< " has been modified";
|
<< "d" << i + 8 << " has been modified";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -298,10 +298,10 @@ TEST_P(ResizeTest, TestExternalResizeWorks) {
|
||||||
unsigned int expected_h;
|
unsigned int expected_h;
|
||||||
ScaleForFrameNumber(frame, kInitialWidth, kInitialHeight, &expected_w,
|
ScaleForFrameNumber(frame, kInitialWidth, kInitialHeight, &expected_w,
|
||||||
&expected_h, 0);
|
&expected_h, 0);
|
||||||
EXPECT_EQ(expected_w, info->w) << "Frame " << frame
|
EXPECT_EQ(expected_w, info->w)
|
||||||
<< " had unexpected width";
|
<< "Frame " << frame << " had unexpected width";
|
||||||
EXPECT_EQ(expected_h, info->h) << "Frame " << frame
|
EXPECT_EQ(expected_h, info->h)
|
||||||
<< " had unexpected height";
|
<< "Frame " << frame << " had unexpected height";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -513,10 +513,10 @@ TEST_P(ResizeRealtimeTest, TestExternalResizeWorks) {
|
||||||
unsigned int expected_h;
|
unsigned int expected_h;
|
||||||
ScaleForFrameNumber(frame, kInitialWidth, kInitialHeight, &expected_w,
|
ScaleForFrameNumber(frame, kInitialWidth, kInitialHeight, &expected_w,
|
||||||
&expected_h, 1);
|
&expected_h, 1);
|
||||||
EXPECT_EQ(expected_w, info->w) << "Frame " << frame
|
EXPECT_EQ(expected_w, info->w)
|
||||||
<< " had unexpected width";
|
<< "Frame " << frame << " had unexpected width";
|
||||||
EXPECT_EQ(expected_h, info->h) << "Frame " << frame
|
EXPECT_EQ(expected_h, info->h)
|
||||||
<< " had unexpected height";
|
<< "Frame " << frame << " had unexpected height";
|
||||||
EXPECT_EQ(static_cast<unsigned int>(0), GetMismatchFrames());
|
EXPECT_EQ(static_cast<unsigned int>(0), GetMismatchFrames());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -644,19 +644,50 @@ INSTANTIATE_TEST_CASE_P(C, SADx4Test, ::testing::ValuesIn(x4d_c_tests));
|
||||||
#if HAVE_NEON
|
#if HAVE_NEON
|
||||||
const SadMxNParam neon_tests[] = {
|
const SadMxNParam neon_tests[] = {
|
||||||
SadMxNParam(64, 64, &vpx_sad64x64_neon),
|
SadMxNParam(64, 64, &vpx_sad64x64_neon),
|
||||||
|
SadMxNParam(64, 32, &vpx_sad64x32_neon),
|
||||||
SadMxNParam(32, 32, &vpx_sad32x32_neon),
|
SadMxNParam(32, 32, &vpx_sad32x32_neon),
|
||||||
|
SadMxNParam(16, 32, &vpx_sad16x32_neon),
|
||||||
SadMxNParam(16, 16, &vpx_sad16x16_neon),
|
SadMxNParam(16, 16, &vpx_sad16x16_neon),
|
||||||
SadMxNParam(16, 8, &vpx_sad16x8_neon),
|
SadMxNParam(16, 8, &vpx_sad16x8_neon),
|
||||||
SadMxNParam(8, 16, &vpx_sad8x16_neon),
|
SadMxNParam(8, 16, &vpx_sad8x16_neon),
|
||||||
SadMxNParam(8, 8, &vpx_sad8x8_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),
|
SadMxNParam(4, 4, &vpx_sad4x4_neon),
|
||||||
};
|
};
|
||||||
INSTANTIATE_TEST_CASE_P(NEON, SADTest, ::testing::ValuesIn(neon_tests));
|
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[] = {
|
const SadMxNx4Param x4d_neon_tests[] = {
|
||||||
SadMxNx4Param(64, 64, &vpx_sad64x64x4d_neon),
|
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, 32, &vpx_sad32x32x4d_neon),
|
||||||
|
SadMxNx4Param(32, 16, &vpx_sad32x16x4d_neon),
|
||||||
|
SadMxNx4Param(16, 32, &vpx_sad16x32x4d_neon),
|
||||||
SadMxNx4Param(16, 16, &vpx_sad16x16x4d_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));
|
INSTANTIATE_TEST_CASE_P(NEON, SADx4Test, ::testing::ValuesIn(x4d_neon_tests));
|
||||||
#endif // HAVE_NEON
|
#endif // HAVE_NEON
|
||||||
|
@ -865,6 +896,14 @@ const SadMxNx4Param x4d_avx2_tests[] = {
|
||||||
INSTANTIATE_TEST_CASE_P(AVX2, SADx4Test, ::testing::ValuesIn(x4d_avx2_tests));
|
INSTANTIATE_TEST_CASE_P(AVX2, SADx4Test, ::testing::ValuesIn(x4d_avx2_tests));
|
||||||
#endif // HAVE_AVX2
|
#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
|
// MIPS functions
|
||||||
#if HAVE_MSA
|
#if HAVE_MSA
|
||||||
|
@ -920,4 +959,98 @@ const SadMxNx4Param x4d_msa_tests[] = {
|
||||||
INSTANTIATE_TEST_CASE_P(MSA, SADx4Test, ::testing::ValuesIn(x4d_msa_tests));
|
INSTANTIATE_TEST_CASE_P(MSA, SADx4Test, ::testing::ValuesIn(x4d_msa_tests));
|
||||||
#endif // HAVE_MSA
|
#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
|
} // namespace
|
||||||
|
|
|
@ -146,14 +146,6 @@ TEST(VP8RoiMapTest, ParameterCheck) {
|
||||||
if (deltas_valid != roi_retval) break;
|
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.
|
// Test invalid number of rows or colums.
|
||||||
roi_retval =
|
roi_retval =
|
||||||
vp8_set_roimap(&cpi, roi_map, cpi.common.mb_rows + 1,
|
vp8_set_roimap(&cpi, roi_map, cpi.common.mb_rows + 1,
|
||||||
|
|
|
@ -0,0 +1,169 @@
|
||||||
|
#!/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"
|
|
@ -110,4 +110,10 @@ INSTANTIATE_TEST_CASE_P(
|
||||||
::testing::Values(make_tuple(&vpx_sum_squares_2d_i16_c,
|
::testing::Values(make_tuple(&vpx_sum_squares_2d_i16_c,
|
||||||
&vpx_sum_squares_2d_i16_sse2)));
|
&vpx_sum_squares_2d_i16_sse2)));
|
||||||
#endif // HAVE_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
|
} // namespace
|
||||||
|
|
|
@ -438,7 +438,7 @@ TEST_F(SvcTest, SetAutoAltRefOption) {
|
||||||
// Test that decoder can handle an SVC frame as the first frame in a sequence.
|
// Test that decoder can handle an SVC frame as the first frame in a sequence.
|
||||||
TEST_F(SvcTest, OnePassEncodeOneFrame) {
|
TEST_F(SvcTest, OnePassEncodeOneFrame) {
|
||||||
codec_enc_.g_pass = VPX_RC_ONE_PASS;
|
codec_enc_.g_pass = VPX_RC_ONE_PASS;
|
||||||
vpx_fixed_buf output = { 0 };
|
vpx_fixed_buf output = vpx_fixed_buf();
|
||||||
Pass2EncodeNFrames(NULL, 1, 2, &output);
|
Pass2EncodeNFrames(NULL, 1, 2, &output);
|
||||||
DecodeNFrames(&output, 1);
|
DecodeNFrames(&output, 1);
|
||||||
FreeBitstreamBuffers(&output, 1);
|
FreeBitstreamBuffers(&output, 1);
|
||||||
|
|
|
@ -0,0 +1,277 @@
|
||||||
|
/*
|
||||||
|
* 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,8 +20,10 @@ 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) += desktop_credits.y4m
|
||||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_ENCODER) += niklas_1280_720_30.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) += rush_hour_444.y4m
|
||||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_ENCODER) += screendata.y4m
|
LIBVPX_TEST_DATA-$(CONFIG_VP9_ENCODER) += screendata.y4m
|
||||||
|
LIBVPX_TEST_DATA-$(CONFIG_VP9_ENCODER) += niklas_640_480_30.yuv
|
||||||
|
|
||||||
# Test vectors
|
# Test vectors
|
||||||
LIBVPX_TEST_DATA-$(CONFIG_VP8_DECODER) += vp80-00-comprehensive-001.ivf
|
LIBVPX_TEST_DATA-$(CONFIG_VP8_DECODER) += vp80-00-comprehensive-001.ivf
|
||||||
|
@ -730,6 +732,8 @@ LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp93-2-20-12bit-yuv444.webm.md5
|
||||||
endif # CONFIG_VP9_HIGHBITDEPTH
|
endif # CONFIG_VP9_HIGHBITDEPTH
|
||||||
|
|
||||||
# Invalid files for testing libvpx error checking.
|
# 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-vp80-00-comprehensive-018.ivf.2kf_0x6.ivf
|
LIBVPX_TEST_DATA-$(CONFIG_VP8_DECODER) += invalid-vp80-00-comprehensive-018.ivf.2kf_0x6.ivf
|
||||||
LIBVPX_TEST_DATA-$(CONFIG_VP8_DECODER) += invalid-vp80-00-comprehensive-018.ivf.2kf_0x6.ivf.res
|
LIBVPX_TEST_DATA-$(CONFIG_VP8_DECODER) += invalid-vp80-00-comprehensive-018.ivf.2kf_0x6.ivf.res
|
||||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += invalid-vp90-01-v3.webm
|
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += invalid-vp90-01-v3.webm
|
||||||
|
@ -764,15 +768,23 @@ LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += invalid-vp90-2-09-subpixel-00.ivf.s195
|
||||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += invalid-vp90-2-09-subpixel-00.ivf.s19552_r01-05_b6-.v2.ivf.res
|
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += invalid-vp90-2-09-subpixel-00.ivf.s19552_r01-05_b6-.v2.ivf.res
|
||||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += invalid-vp90-2-09-subpixel-00.ivf.s20492_r01-05_b6-.v2.ivf
|
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += invalid-vp90-2-09-subpixel-00.ivf.s20492_r01-05_b6-.v2.ivf
|
||||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += invalid-vp90-2-09-subpixel-00.ivf.s20492_r01-05_b6-.v2.ivf.res
|
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += invalid-vp90-2-09-subpixel-00.ivf.s20492_r01-05_b6-.v2.ivf.res
|
||||||
|
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += invalid-vp90-2-10-show-existing-frame.webm.ivf.s180315_r01-05_b6-.ivf
|
||||||
|
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += invalid-vp90-2-10-show-existing-frame.webm.ivf.s180315_r01-05_b6-.ivf.res
|
||||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += invalid-vp90-2-12-droppable_1.ivf.s3676_r01-05_b6-.ivf
|
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += invalid-vp90-2-12-droppable_1.ivf.s3676_r01-05_b6-.ivf
|
||||||
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.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
|
||||||
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-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
|
||||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += invalid-vp91-2-mixedrefcsp-444to420.ivf.res
|
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
|
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += invalid-vp90-2-07-frame_parallel-1.webm
|
||||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += invalid-vp90-2-07-frame_parallel-2.webm
|
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += invalid-vp90-2-07-frame_parallel-2.webm
|
||||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += invalid-vp90-2-07-frame_parallel-3.webm
|
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += invalid-vp90-2-07-frame_parallel-3.webm
|
||||||
|
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += invalid-crbug-629481.webm
|
||||||
|
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += invalid-crbug-629481.webm.res
|
||||||
|
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += invalid-crbug-667044.webm
|
||||||
|
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += invalid-crbug-667044.webm.res
|
||||||
|
|
||||||
ifeq ($(CONFIG_DECODE_PERF_TESTS),yes)
|
ifeq ($(CONFIG_DECODE_PERF_TESTS),yes)
|
||||||
# Encode / Decode test
|
# Encode / Decode test
|
||||||
|
@ -807,7 +819,6 @@ 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) += macmarcomoving_640_480_30.yuv
|
||||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_ENCODER) += macmarcostationary_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_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) += tacomanarrows_640_480_30.yuv
|
||||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_ENCODER) += tacomasmallcameramovement_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
|
LIBVPX_TEST_DATA-$(CONFIG_VP9_ENCODER) += thaloundeskmtg_640_480_30.yuv
|
||||||
|
@ -865,3 +876,7 @@ LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-21-resize_inter_1920x1080_7_1-2
|
||||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-21-resize_inter_1920x1080_7_1-2.webm.md5
|
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-21-resize_inter_1920x1080_7_1-2.webm.md5
|
||||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-21-resize_inter_1920x1080_7_3-4.webm
|
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-21-resize_inter_1920x1080_7_3-4.webm
|
||||||
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-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,6 +6,8 @@ b87815bf86020c592ccc7a846ba2e28ec8043902 *hantro_odd.yuv
|
||||||
456d1493e52d32a5c30edf44a27debc1fa6b253a *invalid-vp90-2-00-quantizer-11.webm.ivf.s52984_r01-05_b6-.ivf.res
|
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
|
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
|
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
|
fe346136b9b8c1e6f6084cc106485706915795e4 *invalid-vp90-01-v3.webm
|
||||||
5d9474c0309b7ca09a182d888f73b37a8fe1362c *invalid-vp90-01-v3.webm.res
|
5d9474c0309b7ca09a182d888f73b37a8fe1362c *invalid-vp90-01-v3.webm.res
|
||||||
d78e2fceba5ac942246503ec8366f879c4775ca5 *invalid-vp90-02-v2.webm
|
d78e2fceba5ac942246503ec8366f879c4775ca5 *invalid-vp90-02-v2.webm
|
||||||
|
@ -14,6 +16,7 @@ df1a1453feb3c00d7d89746c7003b4163523bff3 *invalid-vp90-03-v3.webm
|
||||||
4935c62becc68c13642a03db1e6d3e2331c1c612 *invalid-vp90-03-v3.webm.res
|
4935c62becc68c13642a03db1e6d3e2331c1c612 *invalid-vp90-03-v3.webm.res
|
||||||
d637297561dd904eb2c97a9015deeb31c4a1e8d2 *invalid-vp90-2-08-tile_1x4_frame_parallel_all_key.webm
|
d637297561dd904eb2c97a9015deeb31c4a1e8d2 *invalid-vp90-2-08-tile_1x4_frame_parallel_all_key.webm
|
||||||
3a204bdbeaa3c6458b77bcebb8366d107267f55d *invalid-vp90-2-08-tile_1x4_frame_parallel_all_key.webm.res
|
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
|
a432f96ff0a787268e2f94a8092ab161a18d1b06 *park_joy_90p_10_420.y4m
|
||||||
0b194cc312c3a2e84d156a221b0a5eb615dfddc5 *park_joy_90p_10_422.y4m
|
0b194cc312c3a2e84d156a221b0a5eb615dfddc5 *park_joy_90p_10_422.y4m
|
||||||
ff0e0a21dc2adc95b8c1b37902713700655ced17 *park_joy_90p_10_444.y4m
|
ff0e0a21dc2adc95b8c1b37902713700655ced17 *park_joy_90p_10_444.y4m
|
||||||
|
@ -838,3 +841,16 @@ a000d568431d07379dd5a8ec066061c07e560b47 *invalid-vp90-2-00-quantizer-63.ivf.kf_
|
||||||
1e75aad3433c5c21c194a7b53fc393970f0a8d7f *invalid-vp90-2-00-quantizer-63.ivf.kf_65527x61446.ivf.res
|
1e75aad3433c5c21c194a7b53fc393970f0a8d7f *invalid-vp90-2-00-quantizer-63.ivf.kf_65527x61446.ivf.res
|
||||||
235182f9a1c5c8841552510dd4288487447bfc40 *invalid-vp80-00-comprehensive-018.ivf.2kf_0x6.ivf
|
235182f9a1c5c8841552510dd4288487447bfc40 *invalid-vp80-00-comprehensive-018.ivf.2kf_0x6.ivf
|
||||||
787f04f0483320d536894282f3358a4f8cac1cf9 *invalid-vp80-00-comprehensive-018.ivf.2kf_0x6.ivf.res
|
787f04f0483320d536894282f3358a4f8cac1cf9 *invalid-vp80-00-comprehensive-018.ivf.2kf_0x6.ivf.res
|
||||||
|
91d3cefd0deb98f3b0caf3a2d900ec7a7605e53a *invalid-vp90-2-10-show-existing-frame.webm.ivf.s180315_r01-05_b6-.ivf
|
||||||
|
1e472baaf5f6113459f0399a38a5a5e68d17799d *invalid-vp90-2-10-show-existing-frame.webm.ivf.s180315_r01-05_b6-.ivf.res
|
||||||
|
70057835bf29d14e66699ce5f022df2551fb6b37 *invalid-crbug-629481.webm
|
||||||
|
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
|
||||||
|
17696cd21e875f1d6e5d418cbf89feab02c8850a *vp90-2-22-svc_1280x720_1.webm
|
||||||
|
e2f9e1e47a791b4e939a9bdc50bf7a25b3761f77 *vp90-2-22-svc_1280x720_1.webm.md5
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
LIBVPX_TEST_SRCS-yes += acm_random.h
|
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 += clear_system_state.h
|
||||||
LIBVPX_TEST_SRCS-yes += codec_factory.h
|
LIBVPX_TEST_SRCS-yes += codec_factory.h
|
||||||
LIBVPX_TEST_SRCS-yes += md5_helper.h
|
LIBVPX_TEST_SRCS-yes += md5_helper.h
|
||||||
|
@ -35,9 +36,9 @@ LIBVPX_TEST_SRCS-$(CONFIG_VP8_ENCODER) += cq_test.cc
|
||||||
LIBVPX_TEST_SRCS-$(CONFIG_VP8_ENCODER) += keyframe_test.cc
|
LIBVPX_TEST_SRCS-$(CONFIG_VP8_ENCODER) += keyframe_test.cc
|
||||||
|
|
||||||
LIBVPX_TEST_SRCS-$(CONFIG_VP9_DECODER) += byte_alignment_test.cc
|
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) += external_frame_buffer_test.cc
|
||||||
LIBVPX_TEST_SRCS-$(CONFIG_VP9_DECODER) += user_priv_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_refresh_test.cc
|
||||||
LIBVPX_TEST_SRCS-$(CONFIG_VP9_ENCODER) += active_map_test.cc
|
LIBVPX_TEST_SRCS-$(CONFIG_VP9_ENCODER) += active_map_test.cc
|
||||||
LIBVPX_TEST_SRCS-$(CONFIG_VP9_ENCODER) += borders_test.cc
|
LIBVPX_TEST_SRCS-$(CONFIG_VP9_ENCODER) += borders_test.cc
|
||||||
|
@ -46,6 +47,7 @@ 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_lossless_test.cc
|
||||||
LIBVPX_TEST_SRCS-$(CONFIG_VP9_ENCODER) += vp9_end_to_end_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_ethread_test.cc
|
||||||
|
LIBVPX_TEST_SRCS-$(CONFIG_VP9_ENCODER) += vp9_motion_vector_test.cc
|
||||||
LIBVPX_TEST_SRCS-$(CONFIG_VP9_ENCODER) += level_test.cc
|
LIBVPX_TEST_SRCS-$(CONFIG_VP9_ENCODER) += level_test.cc
|
||||||
|
|
||||||
LIBVPX_TEST_SRCS-yes += decode_test_driver.cc
|
LIBVPX_TEST_SRCS-yes += decode_test_driver.cc
|
||||||
|
@ -121,6 +123,7 @@ LIBVPX_TEST_SRCS-$(CONFIG_VP8_ENCODER) += vp8_fdct4x4_test.cc
|
||||||
LIBVPX_TEST_SRCS-yes += idct_test.cc
|
LIBVPX_TEST_SRCS-yes += idct_test.cc
|
||||||
LIBVPX_TEST_SRCS-yes += predict_test.cc
|
LIBVPX_TEST_SRCS-yes += predict_test.cc
|
||||||
LIBVPX_TEST_SRCS-yes += vpx_scale_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)
|
ifeq ($(CONFIG_VP8_ENCODER)$(CONFIG_TEMPORAL_DENOISING),yesyes)
|
||||||
LIBVPX_TEST_SRCS-$(HAVE_SSE2) += vp8_denoiser_sse2_test.cc
|
LIBVPX_TEST_SRCS-$(HAVE_SSE2) += vp8_denoiser_sse2_test.cc
|
||||||
|
@ -148,14 +151,20 @@ 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_decrypt_test.cc
|
||||||
LIBVPX_TEST_SRCS-$(CONFIG_VP9_DECODER) += vp9_thread_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) += 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) += dct16x16_test.cc
|
||||||
LIBVPX_TEST_SRCS-$(CONFIG_VP9_ENCODER) += dct32x32_test.cc
|
LIBVPX_TEST_SRCS-$(CONFIG_VP9_ENCODER) += dct32x32_test.cc
|
||||||
LIBVPX_TEST_SRCS-$(CONFIG_VP9_ENCODER) += fdct4x4_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) += fdct8x8_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) += hadamard_test.cc
|
||||||
LIBVPX_TEST_SRCS-$(CONFIG_VP9_ENCODER) += minmax_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) += variance_test.cc
|
||||||
LIBVPX_TEST_SRCS-$(CONFIG_VP9_ENCODER) += vp9_error_block_test.cc
|
LIBVPX_TEST_SRCS-$(CONFIG_VP9_ENCODER) += vp9_block_error_test.cc
|
||||||
LIBVPX_TEST_SRCS-$(CONFIG_VP9_ENCODER) += vp9_quantize_test.cc
|
LIBVPX_TEST_SRCS-$(CONFIG_VP9_ENCODER) += vp9_quantize_test.cc
|
||||||
LIBVPX_TEST_SRCS-$(CONFIG_VP9_ENCODER) += vp9_subtract_test.cc
|
LIBVPX_TEST_SRCS-$(CONFIG_VP9_ENCODER) += vp9_subtract_test.cc
|
||||||
|
|
||||||
|
@ -166,7 +175,7 @@ LIBVPX_TEST_SRCS-$(CONFIG_INTERNAL_STATS) += consistency_test.cc
|
||||||
endif
|
endif
|
||||||
|
|
||||||
ifeq ($(CONFIG_VP9_ENCODER)$(CONFIG_VP9_TEMPORAL_DENOISING),yesyes)
|
ifeq ($(CONFIG_VP9_ENCODER)$(CONFIG_VP9_TEMPORAL_DENOISING),yesyes)
|
||||||
LIBVPX_TEST_SRCS-$(HAVE_SSE2) += vp9_denoiser_sse2_test.cc
|
LIBVPX_TEST_SRCS-yes += vp9_denoiser_test.cc
|
||||||
endif
|
endif
|
||||||
LIBVPX_TEST_SRCS-$(CONFIG_VP9_ENCODER) += vp9_arf_freq_test.cc
|
LIBVPX_TEST_SRCS-$(CONFIG_VP9_ENCODER) += vp9_arf_freq_test.cc
|
||||||
|
|
||||||
|
|
|
@ -29,6 +29,8 @@ namespace {
|
||||||
typedef void (*VpxPredFunc)(uint8_t *dst, ptrdiff_t y_stride,
|
typedef void (*VpxPredFunc)(uint8_t *dst, ptrdiff_t y_stride,
|
||||||
const uint8_t *above, const uint8_t *left);
|
const uint8_t *above, const uint8_t *left);
|
||||||
|
|
||||||
|
const int kBPS = 32;
|
||||||
|
const int kTotalPixels = 32 * kBPS;
|
||||||
const int kNumVp9IntraPredFuncs = 13;
|
const int kNumVp9IntraPredFuncs = 13;
|
||||||
const char *kVp9IntraPredNames[kNumVp9IntraPredFuncs] = {
|
const char *kVp9IntraPredNames[kNumVp9IntraPredFuncs] = {
|
||||||
"DC_PRED", "DC_LEFT_PRED", "DC_TOP_PRED", "DC_128_PRED", "V_PRED",
|
"DC_PRED", "DC_LEFT_PRED", "DC_TOP_PRED", "DC_128_PRED", "V_PRED",
|
||||||
|
@ -36,107 +38,121 @@ const char *kVp9IntraPredNames[kNumVp9IntraPredFuncs] = {
|
||||||
"D207_PRED", "D63_PRED", "TM_PRED"
|
"D207_PRED", "D63_PRED", "TM_PRED"
|
||||||
};
|
};
|
||||||
|
|
||||||
|
template <typename Pixel>
|
||||||
|
struct IntraPredTestMem {
|
||||||
|
void Init(int block_size, int bd) {
|
||||||
|
libvpx_test::ACMRandom rnd(libvpx_test::ACMRandom::DeterministicSeed());
|
||||||
|
Pixel *const above = above_mem + 16;
|
||||||
|
const int mask = (1 << bd) - 1;
|
||||||
|
for (int i = 0; i < kTotalPixels; ++i) ref_src[i] = rnd.Rand16() & mask;
|
||||||
|
for (int i = 0; i < kBPS; ++i) left[i] = rnd.Rand16() & mask;
|
||||||
|
for (int i = -1; i < kBPS; ++i) above[i] = rnd.Rand16() & mask;
|
||||||
|
|
||||||
|
// some code assumes the top row has been extended:
|
||||||
|
// d45/d63 C-code, for instance, but not the assembly.
|
||||||
|
// TODO(jzern): this style of extension isn't strictly necessary.
|
||||||
|
ASSERT_LE(block_size, kBPS);
|
||||||
|
for (int i = block_size; i < 2 * kBPS; ++i) {
|
||||||
|
above[i] = above[block_size - 1];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
DECLARE_ALIGNED(16, Pixel, src[kTotalPixels]);
|
||||||
|
DECLARE_ALIGNED(16, Pixel, ref_src[kTotalPixels]);
|
||||||
|
DECLARE_ALIGNED(16, Pixel, left[kBPS]);
|
||||||
|
DECLARE_ALIGNED(16, Pixel, above_mem[2 * kBPS + 16]);
|
||||||
|
};
|
||||||
|
|
||||||
|
typedef IntraPredTestMem<uint8_t> Vp9IntraPredTestMem;
|
||||||
|
|
||||||
|
void CheckMd5Signature(const char name[], const char *const signatures[],
|
||||||
|
const void *data, size_t data_size, int elapsed_time,
|
||||||
|
int idx) {
|
||||||
|
libvpx_test::MD5 md5;
|
||||||
|
md5.Add(reinterpret_cast<const uint8_t *>(data), data_size);
|
||||||
|
printf("Mode %s[%12s]: %5d ms MD5: %s\n", name, kVp9IntraPredNames[idx],
|
||||||
|
elapsed_time, md5.Get());
|
||||||
|
EXPECT_STREQ(signatures[idx], md5.Get());
|
||||||
|
}
|
||||||
|
|
||||||
void TestIntraPred(const char name[], VpxPredFunc const *pred_funcs,
|
void TestIntraPred(const char name[], VpxPredFunc const *pred_funcs,
|
||||||
const char *const pred_func_names[], int num_funcs,
|
const char *const signatures[], int block_size) {
|
||||||
const char *const signatures[], int block_size,
|
const int kNumTests = static_cast<int>(
|
||||||
int num_pixels_per_test) {
|
2.e10 / (block_size * block_size * kNumVp9IntraPredFuncs));
|
||||||
libvpx_test::ACMRandom rnd(libvpx_test::ACMRandom::DeterministicSeed());
|
Vp9IntraPredTestMem intra_pred_test_mem;
|
||||||
const int kBPS = 32;
|
const uint8_t *const above = intra_pred_test_mem.above_mem + 16;
|
||||||
const int kTotalPixels = 32 * kBPS;
|
|
||||||
DECLARE_ALIGNED(16, uint8_t, src[kTotalPixels]);
|
|
||||||
DECLARE_ALIGNED(16, uint8_t, ref_src[kTotalPixels]);
|
|
||||||
DECLARE_ALIGNED(16, uint8_t, left[kBPS]);
|
|
||||||
DECLARE_ALIGNED(16, uint8_t, above_mem[2 * kBPS + 16]);
|
|
||||||
uint8_t *const above = above_mem + 16;
|
|
||||||
for (int i = 0; i < kTotalPixels; ++i) ref_src[i] = rnd.Rand8();
|
|
||||||
for (int i = 0; i < kBPS; ++i) left[i] = rnd.Rand8();
|
|
||||||
for (int i = -1; i < kBPS; ++i) above[i] = rnd.Rand8();
|
|
||||||
const int kNumTests = static_cast<int>(2.e10 / num_pixels_per_test);
|
|
||||||
|
|
||||||
// some code assumes the top row has been extended:
|
intra_pred_test_mem.Init(block_size, 8);
|
||||||
// d45/d63 C-code, for instance, but not the assembly.
|
|
||||||
// TODO(jzern): this style of extension isn't strictly necessary.
|
|
||||||
ASSERT_LE(block_size, kBPS);
|
|
||||||
memset(above + block_size, above[block_size - 1], 2 * kBPS - block_size);
|
|
||||||
|
|
||||||
for (int k = 0; k < num_funcs; ++k) {
|
for (int k = 0; k < kNumVp9IntraPredFuncs; ++k) {
|
||||||
if (pred_funcs[k] == NULL) continue;
|
if (pred_funcs[k] == NULL) continue;
|
||||||
memcpy(src, ref_src, sizeof(src));
|
memcpy(intra_pred_test_mem.src, intra_pred_test_mem.ref_src,
|
||||||
|
sizeof(intra_pred_test_mem.src));
|
||||||
vpx_usec_timer timer;
|
vpx_usec_timer timer;
|
||||||
vpx_usec_timer_start(&timer);
|
vpx_usec_timer_start(&timer);
|
||||||
for (int num_tests = 0; num_tests < kNumTests; ++num_tests) {
|
for (int num_tests = 0; num_tests < kNumTests; ++num_tests) {
|
||||||
pred_funcs[k](src, kBPS, above, left);
|
pred_funcs[k](intra_pred_test_mem.src, kBPS, above,
|
||||||
|
intra_pred_test_mem.left);
|
||||||
}
|
}
|
||||||
libvpx_test::ClearSystemState();
|
libvpx_test::ClearSystemState();
|
||||||
vpx_usec_timer_mark(&timer);
|
vpx_usec_timer_mark(&timer);
|
||||||
const int elapsed_time =
|
const int elapsed_time =
|
||||||
static_cast<int>(vpx_usec_timer_elapsed(&timer) / 1000);
|
static_cast<int>(vpx_usec_timer_elapsed(&timer) / 1000);
|
||||||
libvpx_test::MD5 md5;
|
CheckMd5Signature(name, signatures, intra_pred_test_mem.src,
|
||||||
md5.Add(src, sizeof(src));
|
sizeof(intra_pred_test_mem.src), elapsed_time, k);
|
||||||
printf("Mode %s[%12s]: %5d ms MD5: %s\n", name, pred_func_names[k],
|
|
||||||
elapsed_time, md5.Get());
|
|
||||||
EXPECT_STREQ(signatures[k], md5.Get());
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void TestIntraPred4(VpxPredFunc const *pred_funcs) {
|
void TestIntraPred4(VpxPredFunc const *pred_funcs) {
|
||||||
static const int kNumVp9IntraFuncs = 13;
|
static const char *const kSignatures[kNumVp9IntraPredFuncs] = {
|
||||||
static const char *const kSignatures[kNumVp9IntraFuncs] = {
|
"e7ed7353c3383fff942e500e9bfe82fe", "2a4a26fcc6ce005eadc08354d196c8a9",
|
||||||
"4334156168b34ab599d9b5b30f522fe9", "bc4649d5ba47c7ff178d92e475960fb0",
|
"269d92eff86f315d9c38fe7640d85b15", "ae2960eea9f71ee3dabe08b282ec1773",
|
||||||
"8d316e5933326dcac24e1064794b5d12", "a27270fed024eafd762c95de85f4da51",
|
"6c1abcc44e90148998b51acd11144e9c", "f7bb3186e1ef8a2b326037ff898cad8e",
|
||||||
"c33dff000d4256c2b8f3bf9e9bab14d2", "44d8cddc2ad8f79b8ed3306051722b4f",
|
"364c1f3fb2f445f935aec2a70a67eaa4", "141624072a4a56773f68fadbdd07c4a7",
|
||||||
"eb54839b2bad6699d8946f01ec041cd0", "ecb0d56ae5f677ea45127ce9d5c058e4",
|
"7be49b08687a5f24df3a2c612fca3876", "459bb5d9fd5b238348179c9a22108cd6",
|
||||||
"0b7936841f6813da818275944895b574", "9117972ef64f91a58ff73e1731c81db2",
|
"73edb8831bf1bdfce21ae8eaa43b1234", "2e2457f2009c701a355a8b25eb74fcda",
|
||||||
"c56d5e8c729e46825f46dd5d3b5d508a", "c0889e2039bcf7bcb5d2f33cdca69adc",
|
"52ae4e8bdbe41494c1f43051d4dd7f0b"
|
||||||
"309a618577b27c648f9c5ee45252bc8f",
|
|
||||||
};
|
};
|
||||||
TestIntraPred("Intra4", pred_funcs, kVp9IntraPredNames, kNumVp9IntraFuncs,
|
TestIntraPred("Intra4", pred_funcs, kSignatures, 4);
|
||||||
kSignatures, 4, 4 * 4 * kNumVp9IntraFuncs);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void TestIntraPred8(VpxPredFunc const *pred_funcs) {
|
void TestIntraPred8(VpxPredFunc const *pred_funcs) {
|
||||||
static const int kNumVp9IntraFuncs = 13;
|
static const char *const kSignatures[kNumVp9IntraPredFuncs] = {
|
||||||
static const char *const kSignatures[kNumVp9IntraFuncs] = {
|
"d8bbae5d6547cfc17e4f5f44c8730e88", "373bab6d931868d41a601d9d88ce9ac3",
|
||||||
"7694ddeeefed887faf9d339d18850928", "7d726b1213591b99f736be6dec65065b",
|
"6fdd5ff4ff79656c14747598ca9e3706", "d9661c2811d6a73674f40ffb2b841847",
|
||||||
"19c5711281357a485591aaf9c96c0a67", "ba6b66877a089e71cd938e3b8c40caac",
|
"7c722d10b19ccff0b8c171868e747385", "f81dd986eb2b50f750d3a7da716b7e27",
|
||||||
"802440c93317e0f8ba93fab02ef74265", "9e09a47a15deb0b9d8372824f9805080",
|
"d500f2c8fc78f46a4c74e4dcf51f14fb", "0e3523f9cab2142dd37fd07ec0760bce",
|
||||||
"b7c2d8c662268c0c427da412d7b0311d", "78339c1c60bb1d67d248ab8c4da08b7f",
|
"79ac4efe907f0a0f1885d43066cfedee", "19ecf2432ac305057de3b6578474eec6",
|
||||||
"5c97d70f7d47de1882a6cd86c165c8a9", "8182bf60688b42205acd95e59e967157",
|
"4f985b61acc6dd5d2d2585fa89ea2e2d", "f1bb25a9060dd262f405f15a38f5f674",
|
||||||
"08323400005a297f16d7e57e7fe1eaac", "95f7bfc262329a5849eda66d8f7c68ce",
|
"209ea00801584829e9a0f7be7d4a74ba"
|
||||||
"815b75c8e0d91cc1ae766dc5d3e445a3",
|
|
||||||
};
|
};
|
||||||
TestIntraPred("Intra8", pred_funcs, kVp9IntraPredNames, kNumVp9IntraFuncs,
|
TestIntraPred("Intra8", pred_funcs, kSignatures, 8);
|
||||||
kSignatures, 8, 8 * 8 * kNumVp9IntraFuncs);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void TestIntraPred16(VpxPredFunc const *pred_funcs) {
|
void TestIntraPred16(VpxPredFunc const *pred_funcs) {
|
||||||
static const int kNumVp9IntraFuncs = 13;
|
static const char *const kSignatures[kNumVp9IntraPredFuncs] = {
|
||||||
static const char *const kSignatures[kNumVp9IntraFuncs] = {
|
"50971c07ce26977d30298538fffec619", "527a6b9e0dc5b21b98cf276305432bef",
|
||||||
"b40dbb555d5d16a043dc361e6694fe53", "fb08118cee3b6405d64c1fd68be878c6",
|
"7eff2868f80ebc2c43a4f367281d80f7", "67cd60512b54964ef6aff1bd4816d922",
|
||||||
"6c190f341475c837cc38c2e566b64875", "db5c34ccbe2c7f595d9b08b0dc2c698c",
|
"48371c87dc95c08a33b2048f89cf6468", "b0acf2872ee411d7530af6d2625a7084",
|
||||||
"a62cbfd153a1f0b9fed13e62b8408a7a", "143df5b4c89335e281103f610f5052e4",
|
"f32aafed4d8d3776ed58bcb6188756d5", "dae208f3dca583529cff49b73f7c4183",
|
||||||
"d87feb124107cdf2cfb147655aa0bb3c", "7841fae7d4d47b519322e6a03eeed9dc",
|
"7af66a2f4c8e0b4908e40f047e60c47c", "125e3ab6ab9bc961f183ec366a7afa88",
|
||||||
"f6ebed3f71cbcf8d6d0516ce87e11093", "3cc480297dbfeed01a1c2d78dd03d0c5",
|
"6b90f25b23983c35386b9fd704427622", "f8d6b11d710edc136a7c62c917435f93",
|
||||||
"b9f69fa6532b372c545397dcb78ef311", "a8fe1c70432f09d0c20c67bdb6432c4d",
|
"ed308f18614a362917f411c218aee532"
|
||||||
"b8a41aa968ec108af447af4217cba91b",
|
|
||||||
};
|
};
|
||||||
TestIntraPred("Intra16", pred_funcs, kVp9IntraPredNames, kNumVp9IntraFuncs,
|
TestIntraPred("Intra16", pred_funcs, kSignatures, 16);
|
||||||
kSignatures, 16, 16 * 16 * kNumVp9IntraFuncs);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void TestIntraPred32(VpxPredFunc const *pred_funcs) {
|
void TestIntraPred32(VpxPredFunc const *pred_funcs) {
|
||||||
static const int kNumVp9IntraFuncs = 13;
|
static const char *const kSignatures[kNumVp9IntraPredFuncs] = {
|
||||||
static const char *const kSignatures[kNumVp9IntraFuncs] = {
|
"a0a618c900e65ae521ccc8af789729f2", "985aaa7c72b4a6c2fb431d32100cf13a",
|
||||||
"558541656d84f9ae7896db655826febe", "b3587a1f9a01495fa38c8cd3c8e2a1bf",
|
"10662d09febc3ca13ee4e700120daeb5", "b3b01379ba08916ef6b1b35f7d9ad51c",
|
||||||
"4c6501e64f25aacc55a2a16c7e8f0255", "b3b01379ba08916ef6b1b35f7d9ad51c",
|
"9f4261755795af97e34679c333ec7004", "bc2c9da91ad97ef0d1610fb0a9041657",
|
||||||
"0f1eb38b6cbddb3d496199ef9f329071", "911c06efb9ed1c3b4c104b232b55812f",
|
"75c79b1362ad18abfcdb1aa0aacfc21d", "4039bb7da0f6860090d3c57b5c85468f",
|
||||||
"9225beb0ddfa7a1d24eaa1be430a6654", "0a6d584a44f8db9aa7ade2e2fdb9fc9e",
|
"b29fff7b61804e68383e3a609b33da58", "e1aa5e49067fd8dba66c2eb8d07b7a89",
|
||||||
"b01c9076525216925f3456f034fb6eee", "d267e20ad9e5cd2915d1a47254d3d149",
|
"4e042822909c1c06d3b10a88281df1eb", "72eb9d9e0e67c93f4c66b70348e9fef7",
|
||||||
"ed012a4a5da71f36c2393023184a0e59", "f162b51ed618d28b936974cff4391da5",
|
"a22d102bcb51ca798aac12ca4ae8f2e8"
|
||||||
"9e1370c6d42e08d357d9612c93a71cfc",
|
|
||||||
};
|
};
|
||||||
TestIntraPred("Intra32", pred_funcs, kVp9IntraPredNames, kNumVp9IntraFuncs,
|
TestIntraPred("Intra32", pred_funcs, kSignatures, 32);
|
||||||
kSignatures, 32, 32 * 32 * kNumVp9IntraFuncs);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace
|
} // namespace
|
||||||
|
@ -153,7 +169,6 @@ void TestIntraPred32(VpxPredFunc const *pred_funcs) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// -----------------------------------------------------------------------------
|
// -----------------------------------------------------------------------------
|
||||||
// 4x4
|
|
||||||
|
|
||||||
INTRA_PRED_TEST(C, TestIntraPred4, vpx_dc_predictor_4x4_c,
|
INTRA_PRED_TEST(C, TestIntraPred4, vpx_dc_predictor_4x4_c,
|
||||||
vpx_dc_left_predictor_4x4_c, vpx_dc_top_predictor_4x4_c,
|
vpx_dc_left_predictor_4x4_c, vpx_dc_top_predictor_4x4_c,
|
||||||
|
@ -163,47 +178,6 @@ INTRA_PRED_TEST(C, TestIntraPred4, vpx_dc_predictor_4x4_c,
|
||||||
vpx_d153_predictor_4x4_c, vpx_d207_predictor_4x4_c,
|
vpx_d153_predictor_4x4_c, vpx_d207_predictor_4x4_c,
|
||||||
vpx_d63_predictor_4x4_c, vpx_tm_predictor_4x4_c)
|
vpx_d63_predictor_4x4_c, vpx_tm_predictor_4x4_c)
|
||||||
|
|
||||||
#if HAVE_SSE2
|
|
||||||
INTRA_PRED_TEST(SSE2, TestIntraPred4, vpx_dc_predictor_4x4_sse2,
|
|
||||||
vpx_dc_left_predictor_4x4_sse2, vpx_dc_top_predictor_4x4_sse2,
|
|
||||||
vpx_dc_128_predictor_4x4_sse2, vpx_v_predictor_4x4_sse2,
|
|
||||||
vpx_h_predictor_4x4_sse2, vpx_d45_predictor_4x4_sse2, NULL,
|
|
||||||
NULL, NULL, vpx_d207_predictor_4x4_sse2, NULL,
|
|
||||||
vpx_tm_predictor_4x4_sse2)
|
|
||||||
#endif // HAVE_SSE2
|
|
||||||
|
|
||||||
#if HAVE_SSSE3
|
|
||||||
INTRA_PRED_TEST(SSSE3, TestIntraPred4, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
|
||||||
NULL, NULL, vpx_d153_predictor_4x4_ssse3, NULL,
|
|
||||||
vpx_d63_predictor_4x4_ssse3, NULL)
|
|
||||||
#endif // HAVE_SSSE3
|
|
||||||
|
|
||||||
#if HAVE_DSPR2
|
|
||||||
INTRA_PRED_TEST(DSPR2, TestIntraPred4, vpx_dc_predictor_4x4_dspr2, NULL, NULL,
|
|
||||||
NULL, NULL, vpx_h_predictor_4x4_dspr2, NULL, NULL, NULL, NULL,
|
|
||||||
NULL, NULL, vpx_tm_predictor_4x4_dspr2)
|
|
||||||
#endif // HAVE_DSPR2
|
|
||||||
|
|
||||||
#if HAVE_NEON
|
|
||||||
INTRA_PRED_TEST(NEON, TestIntraPred4, vpx_dc_predictor_4x4_neon,
|
|
||||||
vpx_dc_left_predictor_4x4_neon, vpx_dc_top_predictor_4x4_neon,
|
|
||||||
vpx_dc_128_predictor_4x4_neon, vpx_v_predictor_4x4_neon,
|
|
||||||
vpx_h_predictor_4x4_neon, vpx_d45_predictor_4x4_neon,
|
|
||||||
vpx_d135_predictor_4x4_neon, NULL, NULL, NULL, NULL,
|
|
||||||
vpx_tm_predictor_4x4_neon)
|
|
||||||
#endif // HAVE_NEON
|
|
||||||
|
|
||||||
#if HAVE_MSA
|
|
||||||
INTRA_PRED_TEST(MSA, TestIntraPred4, vpx_dc_predictor_4x4_msa,
|
|
||||||
vpx_dc_left_predictor_4x4_msa, vpx_dc_top_predictor_4x4_msa,
|
|
||||||
vpx_dc_128_predictor_4x4_msa, vpx_v_predictor_4x4_msa,
|
|
||||||
vpx_h_predictor_4x4_msa, NULL, NULL, NULL, NULL, NULL, NULL,
|
|
||||||
vpx_tm_predictor_4x4_msa)
|
|
||||||
#endif // HAVE_MSA
|
|
||||||
|
|
||||||
// -----------------------------------------------------------------------------
|
|
||||||
// 8x8
|
|
||||||
|
|
||||||
INTRA_PRED_TEST(C, TestIntraPred8, vpx_dc_predictor_8x8_c,
|
INTRA_PRED_TEST(C, TestIntraPred8, vpx_dc_predictor_8x8_c,
|
||||||
vpx_dc_left_predictor_8x8_c, vpx_dc_top_predictor_8x8_c,
|
vpx_dc_left_predictor_8x8_c, vpx_dc_top_predictor_8x8_c,
|
||||||
vpx_dc_128_predictor_8x8_c, vpx_v_predictor_8x8_c,
|
vpx_dc_128_predictor_8x8_c, vpx_v_predictor_8x8_c,
|
||||||
|
@ -212,46 +186,6 @@ INTRA_PRED_TEST(C, TestIntraPred8, vpx_dc_predictor_8x8_c,
|
||||||
vpx_d153_predictor_8x8_c, vpx_d207_predictor_8x8_c,
|
vpx_d153_predictor_8x8_c, vpx_d207_predictor_8x8_c,
|
||||||
vpx_d63_predictor_8x8_c, vpx_tm_predictor_8x8_c)
|
vpx_d63_predictor_8x8_c, vpx_tm_predictor_8x8_c)
|
||||||
|
|
||||||
#if HAVE_SSE2
|
|
||||||
INTRA_PRED_TEST(SSE2, TestIntraPred8, vpx_dc_predictor_8x8_sse2,
|
|
||||||
vpx_dc_left_predictor_8x8_sse2, vpx_dc_top_predictor_8x8_sse2,
|
|
||||||
vpx_dc_128_predictor_8x8_sse2, vpx_v_predictor_8x8_sse2,
|
|
||||||
vpx_h_predictor_8x8_sse2, vpx_d45_predictor_8x8_sse2, NULL,
|
|
||||||
NULL, NULL, NULL, NULL, vpx_tm_predictor_8x8_sse2)
|
|
||||||
#endif // HAVE_SSE2
|
|
||||||
|
|
||||||
#if HAVE_SSSE3
|
|
||||||
INTRA_PRED_TEST(SSSE3, TestIntraPred8, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
|
||||||
NULL, NULL, vpx_d153_predictor_8x8_ssse3,
|
|
||||||
vpx_d207_predictor_8x8_ssse3, vpx_d63_predictor_8x8_ssse3, NULL)
|
|
||||||
#endif // HAVE_SSSE3
|
|
||||||
|
|
||||||
#if HAVE_DSPR2
|
|
||||||
INTRA_PRED_TEST(DSPR2, TestIntraPred8, vpx_dc_predictor_8x8_dspr2, NULL, NULL,
|
|
||||||
NULL, NULL, vpx_h_predictor_8x8_dspr2, NULL, NULL, NULL, NULL,
|
|
||||||
NULL, NULL, vpx_tm_predictor_8x8_c)
|
|
||||||
#endif // HAVE_DSPR2
|
|
||||||
|
|
||||||
#if HAVE_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, NULL,
|
|
||||||
NULL, NULL, NULL, NULL, vpx_tm_predictor_8x8_neon)
|
|
||||||
|
|
||||||
#endif // HAVE_NEON
|
|
||||||
|
|
||||||
#if HAVE_MSA
|
|
||||||
INTRA_PRED_TEST(MSA, TestIntraPred8, vpx_dc_predictor_8x8_msa,
|
|
||||||
vpx_dc_left_predictor_8x8_msa, vpx_dc_top_predictor_8x8_msa,
|
|
||||||
vpx_dc_128_predictor_8x8_msa, vpx_v_predictor_8x8_msa,
|
|
||||||
vpx_h_predictor_8x8_msa, NULL, NULL, NULL, NULL, NULL, NULL,
|
|
||||||
vpx_tm_predictor_8x8_msa)
|
|
||||||
#endif // HAVE_MSA
|
|
||||||
|
|
||||||
// -----------------------------------------------------------------------------
|
|
||||||
// 16x16
|
|
||||||
|
|
||||||
INTRA_PRED_TEST(C, TestIntraPred16, vpx_dc_predictor_16x16_c,
|
INTRA_PRED_TEST(C, TestIntraPred16, vpx_dc_predictor_16x16_c,
|
||||||
vpx_dc_left_predictor_16x16_c, vpx_dc_top_predictor_16x16_c,
|
vpx_dc_left_predictor_16x16_c, vpx_dc_top_predictor_16x16_c,
|
||||||
vpx_dc_128_predictor_16x16_c, vpx_v_predictor_16x16_c,
|
vpx_dc_128_predictor_16x16_c, vpx_v_predictor_16x16_c,
|
||||||
|
@ -260,48 +194,6 @@ INTRA_PRED_TEST(C, TestIntraPred16, vpx_dc_predictor_16x16_c,
|
||||||
vpx_d153_predictor_16x16_c, vpx_d207_predictor_16x16_c,
|
vpx_d153_predictor_16x16_c, vpx_d207_predictor_16x16_c,
|
||||||
vpx_d63_predictor_16x16_c, vpx_tm_predictor_16x16_c)
|
vpx_d63_predictor_16x16_c, vpx_tm_predictor_16x16_c)
|
||||||
|
|
||||||
#if HAVE_SSE2
|
|
||||||
INTRA_PRED_TEST(SSE2, TestIntraPred16, vpx_dc_predictor_16x16_sse2,
|
|
||||||
vpx_dc_left_predictor_16x16_sse2,
|
|
||||||
vpx_dc_top_predictor_16x16_sse2,
|
|
||||||
vpx_dc_128_predictor_16x16_sse2, vpx_v_predictor_16x16_sse2,
|
|
||||||
vpx_h_predictor_16x16_sse2, NULL, NULL, NULL, NULL, NULL, NULL,
|
|
||||||
vpx_tm_predictor_16x16_sse2)
|
|
||||||
#endif // HAVE_SSE2
|
|
||||||
|
|
||||||
#if HAVE_SSSE3
|
|
||||||
INTRA_PRED_TEST(SSSE3, TestIntraPred16, NULL, NULL, NULL, NULL, NULL, NULL,
|
|
||||||
vpx_d45_predictor_16x16_ssse3, NULL, NULL,
|
|
||||||
vpx_d153_predictor_16x16_ssse3, vpx_d207_predictor_16x16_ssse3,
|
|
||||||
vpx_d63_predictor_16x16_ssse3, NULL)
|
|
||||||
#endif // HAVE_SSSE3
|
|
||||||
|
|
||||||
#if HAVE_DSPR2
|
|
||||||
INTRA_PRED_TEST(DSPR2, TestIntraPred16, vpx_dc_predictor_16x16_dspr2, NULL,
|
|
||||||
NULL, NULL, NULL, vpx_h_predictor_16x16_dspr2, NULL, NULL, NULL,
|
|
||||||
NULL, NULL, NULL, NULL)
|
|
||||||
#endif // HAVE_DSPR2
|
|
||||||
|
|
||||||
#if HAVE_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, NULL,
|
|
||||||
NULL, NULL, NULL, NULL, vpx_tm_predictor_16x16_neon)
|
|
||||||
#endif // HAVE_NEON
|
|
||||||
|
|
||||||
#if HAVE_MSA
|
|
||||||
INTRA_PRED_TEST(MSA, TestIntraPred16, vpx_dc_predictor_16x16_msa,
|
|
||||||
vpx_dc_left_predictor_16x16_msa, vpx_dc_top_predictor_16x16_msa,
|
|
||||||
vpx_dc_128_predictor_16x16_msa, vpx_v_predictor_16x16_msa,
|
|
||||||
vpx_h_predictor_16x16_msa, NULL, NULL, NULL, NULL, NULL, NULL,
|
|
||||||
vpx_tm_predictor_16x16_msa)
|
|
||||||
#endif // HAVE_MSA
|
|
||||||
|
|
||||||
// -----------------------------------------------------------------------------
|
|
||||||
// 32x32
|
|
||||||
|
|
||||||
INTRA_PRED_TEST(C, TestIntraPred32, vpx_dc_predictor_32x32_c,
|
INTRA_PRED_TEST(C, TestIntraPred32, vpx_dc_predictor_32x32_c,
|
||||||
vpx_dc_left_predictor_32x32_c, vpx_dc_top_predictor_32x32_c,
|
vpx_dc_left_predictor_32x32_c, vpx_dc_top_predictor_32x32_c,
|
||||||
vpx_dc_128_predictor_32x32_c, vpx_v_predictor_32x32_c,
|
vpx_dc_128_predictor_32x32_c, vpx_v_predictor_32x32_c,
|
||||||
|
@ -311,6 +203,26 @@ INTRA_PRED_TEST(C, TestIntraPred32, vpx_dc_predictor_32x32_c,
|
||||||
vpx_d63_predictor_32x32_c, vpx_tm_predictor_32x32_c)
|
vpx_d63_predictor_32x32_c, vpx_tm_predictor_32x32_c)
|
||||||
|
|
||||||
#if HAVE_SSE2
|
#if HAVE_SSE2
|
||||||
|
INTRA_PRED_TEST(SSE2, TestIntraPred4, vpx_dc_predictor_4x4_sse2,
|
||||||
|
vpx_dc_left_predictor_4x4_sse2, vpx_dc_top_predictor_4x4_sse2,
|
||||||
|
vpx_dc_128_predictor_4x4_sse2, vpx_v_predictor_4x4_sse2,
|
||||||
|
vpx_h_predictor_4x4_sse2, vpx_d45_predictor_4x4_sse2, NULL,
|
||||||
|
NULL, NULL, vpx_d207_predictor_4x4_sse2, NULL,
|
||||||
|
vpx_tm_predictor_4x4_sse2)
|
||||||
|
|
||||||
|
INTRA_PRED_TEST(SSE2, TestIntraPred8, vpx_dc_predictor_8x8_sse2,
|
||||||
|
vpx_dc_left_predictor_8x8_sse2, vpx_dc_top_predictor_8x8_sse2,
|
||||||
|
vpx_dc_128_predictor_8x8_sse2, vpx_v_predictor_8x8_sse2,
|
||||||
|
vpx_h_predictor_8x8_sse2, vpx_d45_predictor_8x8_sse2, NULL,
|
||||||
|
NULL, NULL, NULL, NULL, vpx_tm_predictor_8x8_sse2)
|
||||||
|
|
||||||
|
INTRA_PRED_TEST(SSE2, TestIntraPred16, vpx_dc_predictor_16x16_sse2,
|
||||||
|
vpx_dc_left_predictor_16x16_sse2,
|
||||||
|
vpx_dc_top_predictor_16x16_sse2,
|
||||||
|
vpx_dc_128_predictor_16x16_sse2, vpx_v_predictor_16x16_sse2,
|
||||||
|
vpx_h_predictor_16x16_sse2, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||||
|
vpx_tm_predictor_16x16_sse2)
|
||||||
|
|
||||||
INTRA_PRED_TEST(SSE2, TestIntraPred32, vpx_dc_predictor_32x32_sse2,
|
INTRA_PRED_TEST(SSE2, TestIntraPred32, vpx_dc_predictor_32x32_sse2,
|
||||||
vpx_dc_left_predictor_32x32_sse2,
|
vpx_dc_left_predictor_32x32_sse2,
|
||||||
vpx_dc_top_predictor_32x32_sse2,
|
vpx_dc_top_predictor_32x32_sse2,
|
||||||
|
@ -320,22 +232,79 @@ INTRA_PRED_TEST(SSE2, TestIntraPred32, vpx_dc_predictor_32x32_sse2,
|
||||||
#endif // HAVE_SSE2
|
#endif // HAVE_SSE2
|
||||||
|
|
||||||
#if HAVE_SSSE3
|
#if HAVE_SSSE3
|
||||||
|
INTRA_PRED_TEST(SSSE3, TestIntraPred4, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||||
|
NULL, NULL, vpx_d153_predictor_4x4_ssse3, NULL,
|
||||||
|
vpx_d63_predictor_4x4_ssse3, NULL)
|
||||||
|
INTRA_PRED_TEST(SSSE3, TestIntraPred8, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||||
|
NULL, NULL, vpx_d153_predictor_8x8_ssse3,
|
||||||
|
vpx_d207_predictor_8x8_ssse3, vpx_d63_predictor_8x8_ssse3, NULL)
|
||||||
|
INTRA_PRED_TEST(SSSE3, TestIntraPred16, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||||
|
vpx_d45_predictor_16x16_ssse3, NULL, NULL,
|
||||||
|
vpx_d153_predictor_16x16_ssse3, vpx_d207_predictor_16x16_ssse3,
|
||||||
|
vpx_d63_predictor_16x16_ssse3, NULL)
|
||||||
INTRA_PRED_TEST(SSSE3, TestIntraPred32, NULL, NULL, NULL, NULL, NULL, NULL,
|
INTRA_PRED_TEST(SSSE3, TestIntraPred32, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||||
vpx_d45_predictor_32x32_ssse3, NULL, NULL,
|
vpx_d45_predictor_32x32_ssse3, NULL, NULL,
|
||||||
vpx_d153_predictor_32x32_ssse3, vpx_d207_predictor_32x32_ssse3,
|
vpx_d153_predictor_32x32_ssse3, vpx_d207_predictor_32x32_ssse3,
|
||||||
vpx_d63_predictor_32x32_ssse3, NULL)
|
vpx_d63_predictor_32x32_ssse3, NULL)
|
||||||
#endif // HAVE_SSSE3
|
#endif // HAVE_SSSE3
|
||||||
|
|
||||||
|
#if HAVE_DSPR2
|
||||||
|
INTRA_PRED_TEST(DSPR2, TestIntraPred4, vpx_dc_predictor_4x4_dspr2, NULL, NULL,
|
||||||
|
NULL, NULL, vpx_h_predictor_4x4_dspr2, NULL, NULL, NULL, NULL,
|
||||||
|
NULL, NULL, vpx_tm_predictor_4x4_dspr2)
|
||||||
|
INTRA_PRED_TEST(DSPR2, TestIntraPred8, vpx_dc_predictor_8x8_dspr2, NULL, NULL,
|
||||||
|
NULL, NULL, vpx_h_predictor_8x8_dspr2, NULL, NULL, NULL, NULL,
|
||||||
|
NULL, NULL, vpx_tm_predictor_8x8_c)
|
||||||
|
INTRA_PRED_TEST(DSPR2, TestIntraPred16, vpx_dc_predictor_16x16_dspr2, NULL,
|
||||||
|
NULL, NULL, NULL, vpx_h_predictor_16x16_dspr2, NULL, NULL, NULL,
|
||||||
|
NULL, NULL, NULL, NULL)
|
||||||
|
#endif // HAVE_DSPR2
|
||||||
|
|
||||||
#if HAVE_NEON
|
#if HAVE_NEON
|
||||||
|
INTRA_PRED_TEST(NEON, TestIntraPred4, vpx_dc_predictor_4x4_neon,
|
||||||
|
vpx_dc_left_predictor_4x4_neon, vpx_dc_top_predictor_4x4_neon,
|
||||||
|
vpx_dc_128_predictor_4x4_neon, vpx_v_predictor_4x4_neon,
|
||||||
|
vpx_h_predictor_4x4_neon, vpx_d45_predictor_4x4_neon,
|
||||||
|
vpx_d135_predictor_4x4_neon, NULL, NULL, NULL, NULL,
|
||||||
|
vpx_tm_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)
|
||||||
|
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)
|
||||||
INTRA_PRED_TEST(NEON, TestIntraPred32, vpx_dc_predictor_32x32_neon,
|
INTRA_PRED_TEST(NEON, TestIntraPred32, vpx_dc_predictor_32x32_neon,
|
||||||
vpx_dc_left_predictor_32x32_neon,
|
vpx_dc_left_predictor_32x32_neon,
|
||||||
vpx_dc_top_predictor_32x32_neon,
|
vpx_dc_top_predictor_32x32_neon,
|
||||||
vpx_dc_128_predictor_32x32_neon, vpx_v_predictor_32x32_neon,
|
vpx_dc_128_predictor_32x32_neon, vpx_v_predictor_32x32_neon,
|
||||||
vpx_h_predictor_32x32_neon, NULL, NULL, NULL, NULL, NULL, NULL,
|
vpx_h_predictor_32x32_neon, vpx_d45_predictor_32x32_neon,
|
||||||
|
vpx_d135_predictor_32x32_neon, NULL, NULL, NULL, NULL,
|
||||||
vpx_tm_predictor_32x32_neon)
|
vpx_tm_predictor_32x32_neon)
|
||||||
#endif // HAVE_NEON
|
#endif // HAVE_NEON
|
||||||
|
|
||||||
#if HAVE_MSA
|
#if HAVE_MSA
|
||||||
|
INTRA_PRED_TEST(MSA, TestIntraPred4, vpx_dc_predictor_4x4_msa,
|
||||||
|
vpx_dc_left_predictor_4x4_msa, vpx_dc_top_predictor_4x4_msa,
|
||||||
|
vpx_dc_128_predictor_4x4_msa, vpx_v_predictor_4x4_msa,
|
||||||
|
vpx_h_predictor_4x4_msa, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||||
|
vpx_tm_predictor_4x4_msa)
|
||||||
|
INTRA_PRED_TEST(MSA, TestIntraPred8, vpx_dc_predictor_8x8_msa,
|
||||||
|
vpx_dc_left_predictor_8x8_msa, vpx_dc_top_predictor_8x8_msa,
|
||||||
|
vpx_dc_128_predictor_8x8_msa, vpx_v_predictor_8x8_msa,
|
||||||
|
vpx_h_predictor_8x8_msa, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||||
|
vpx_tm_predictor_8x8_msa)
|
||||||
|
INTRA_PRED_TEST(MSA, TestIntraPred16, vpx_dc_predictor_16x16_msa,
|
||||||
|
vpx_dc_left_predictor_16x16_msa, vpx_dc_top_predictor_16x16_msa,
|
||||||
|
vpx_dc_128_predictor_16x16_msa, vpx_v_predictor_16x16_msa,
|
||||||
|
vpx_h_predictor_16x16_msa, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||||
|
vpx_tm_predictor_16x16_msa)
|
||||||
INTRA_PRED_TEST(MSA, TestIntraPred32, vpx_dc_predictor_32x32_msa,
|
INTRA_PRED_TEST(MSA, TestIntraPred32, vpx_dc_predictor_32x32_msa,
|
||||||
vpx_dc_left_predictor_32x32_msa, vpx_dc_top_predictor_32x32_msa,
|
vpx_dc_left_predictor_32x32_msa, vpx_dc_top_predictor_32x32_msa,
|
||||||
vpx_dc_128_predictor_32x32_msa, vpx_v_predictor_32x32_msa,
|
vpx_dc_128_predictor_32x32_msa, vpx_v_predictor_32x32_msa,
|
||||||
|
@ -343,4 +312,275 @@ INTRA_PRED_TEST(MSA, TestIntraPred32, vpx_dc_predictor_32x32_msa,
|
||||||
vpx_tm_predictor_32x32_msa)
|
vpx_tm_predictor_32x32_msa)
|
||||||
#endif // HAVE_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
|
||||||
|
namespace {
|
||||||
|
|
||||||
|
typedef void (*VpxHighbdPredFunc)(uint16_t *dst, ptrdiff_t y_stride,
|
||||||
|
const uint16_t *above, const uint16_t *left,
|
||||||
|
int bd);
|
||||||
|
|
||||||
|
typedef IntraPredTestMem<uint16_t> Vp9HighbdIntraPredTestMem;
|
||||||
|
|
||||||
|
void TestHighbdIntraPred(const char name[], VpxHighbdPredFunc const *pred_funcs,
|
||||||
|
const char *const signatures[], int block_size) {
|
||||||
|
const int kNumTests = static_cast<int>(
|
||||||
|
2.e10 / (block_size * block_size * kNumVp9IntraPredFuncs));
|
||||||
|
Vp9HighbdIntraPredTestMem intra_pred_test_mem;
|
||||||
|
const uint16_t *const above = intra_pred_test_mem.above_mem + 16;
|
||||||
|
|
||||||
|
intra_pred_test_mem.Init(block_size, 12);
|
||||||
|
|
||||||
|
for (int k = 0; k < kNumVp9IntraPredFuncs; ++k) {
|
||||||
|
if (pred_funcs[k] == NULL) continue;
|
||||||
|
memcpy(intra_pred_test_mem.src, intra_pred_test_mem.ref_src,
|
||||||
|
sizeof(intra_pred_test_mem.src));
|
||||||
|
vpx_usec_timer timer;
|
||||||
|
vpx_usec_timer_start(&timer);
|
||||||
|
for (int num_tests = 0; num_tests < kNumTests; ++num_tests) {
|
||||||
|
pred_funcs[k](intra_pred_test_mem.src, kBPS, above,
|
||||||
|
intra_pred_test_mem.left, 12);
|
||||||
|
}
|
||||||
|
libvpx_test::ClearSystemState();
|
||||||
|
vpx_usec_timer_mark(&timer);
|
||||||
|
const int elapsed_time =
|
||||||
|
static_cast<int>(vpx_usec_timer_elapsed(&timer) / 1000);
|
||||||
|
CheckMd5Signature(name, signatures, intra_pred_test_mem.src,
|
||||||
|
sizeof(intra_pred_test_mem.src), elapsed_time, k);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void TestHighbdIntraPred4(VpxHighbdPredFunc const *pred_funcs) {
|
||||||
|
static const char *const kSignatures[kNumVp9IntraPredFuncs] = {
|
||||||
|
"11f74af6c5737df472f3275cbde062fa", "51bea056b6447c93f6eb8f6b7e8f6f71",
|
||||||
|
"27e97f946766331795886f4de04c5594", "53ab15974b049111fb596c5168ec7e3f",
|
||||||
|
"f0b640bb176fbe4584cf3d32a9b0320a", "729783ca909e03afd4b47111c80d967b",
|
||||||
|
"fbf1c30793d9f32812e4d9f905d53530", "293fc903254a33754133314c6cdba81f",
|
||||||
|
"f8074d704233e73dfd35b458c6092374", "aa6363d08544a1ec4da33d7a0be5640d",
|
||||||
|
"462abcfdfa3d087bb33c9a88f2aec491", "863eab65d22550dd44a2397277c1ec71",
|
||||||
|
"23d61df1574d0fa308f9731811047c4b"
|
||||||
|
};
|
||||||
|
TestHighbdIntraPred("Intra4", pred_funcs, kSignatures, 4);
|
||||||
|
}
|
||||||
|
|
||||||
|
void TestHighbdIntraPred8(VpxHighbdPredFunc const *pred_funcs) {
|
||||||
|
static const char *const kSignatures[kNumVp9IntraPredFuncs] = {
|
||||||
|
"03da8829fe94663047fd108c5fcaa71d", "ecdb37b8120a2d3a4c706b016bd1bfd7",
|
||||||
|
"1d4543ed8d2b9368cb96898095fe8a75", "f791c9a67b913cbd82d9da8ecede30e2",
|
||||||
|
"065c70646f4dbaff913282f55a45a441", "51f87123616662ef7c35691497dfd0ba",
|
||||||
|
"2a5b0131ef4716f098ee65e6df01e3dd", "9ffe186a6bc7db95275f1bbddd6f7aba",
|
||||||
|
"a3258a2eae2e2bd55cb8f71351b22998", "8d909f0a2066e39b3216092c6289ece4",
|
||||||
|
"d183abb30b9f24c886a0517e991b22c7", "702a42fe4c7d665dc561b2aeeb60f311",
|
||||||
|
"7b5dbbbe7ae3a4ac2948731600bde5d6"
|
||||||
|
};
|
||||||
|
TestHighbdIntraPred("Intra8", pred_funcs, kSignatures, 8);
|
||||||
|
}
|
||||||
|
|
||||||
|
void TestHighbdIntraPred16(VpxHighbdPredFunc const *pred_funcs) {
|
||||||
|
static const char *const kSignatures[kNumVp9IntraPredFuncs] = {
|
||||||
|
"e33cb3f56a878e2fddb1b2fc51cdd275", "c7bff6f04b6052c8ab335d726dbbd52d",
|
||||||
|
"d0b0b47b654a9bcc5c6008110a44589b", "78f5da7b10b2b9ab39f114a33b6254e9",
|
||||||
|
"c78e31d23831abb40d6271a318fdd6f3", "90d1347f4ec9198a0320daecb6ff90b8",
|
||||||
|
"d2c623746cbb64a0c9e29c10f2c57041", "cf28bd387b81ad3e5f1a1c779a4b70a0",
|
||||||
|
"24c304330431ddeaf630f6ce94af2eac", "91a329798036bf64e8e00a87b131b8b1",
|
||||||
|
"d39111f22885307f920796a42084c872", "e2e702f7250ece98dd8f3f2854c31eeb",
|
||||||
|
"e2fb05b01eb8b88549e85641d8ce5b59"
|
||||||
|
};
|
||||||
|
TestHighbdIntraPred("Intra16", pred_funcs, kSignatures, 16);
|
||||||
|
}
|
||||||
|
|
||||||
|
void TestHighbdIntraPred32(VpxHighbdPredFunc const *pred_funcs) {
|
||||||
|
static const char *const kSignatures[kNumVp9IntraPredFuncs] = {
|
||||||
|
"a3e8056ba7e36628cce4917cd956fedd", "cc7d3024fe8748b512407edee045377e",
|
||||||
|
"2aab0a0f330a1d3e19b8ecb8f06387a3", "a547bc3fb7b06910bf3973122a426661",
|
||||||
|
"26f712514da95042f93d6e8dc8e431dc", "bb08c6e16177081daa3d936538dbc2e3",
|
||||||
|
"8f031af3e2650e89620d8d2c3a843d8b", "42867c8553285e94ee8e4df7abafbda8",
|
||||||
|
"6496bdee96100667833f546e1be3d640", "2ebfa25bf981377e682e580208504300",
|
||||||
|
"3e8ae52fd1f607f348aa4cb436c71ab7", "3d4efe797ca82193613696753ea624c4",
|
||||||
|
"cb8aab6d372278f3131e8d99efde02d9"
|
||||||
|
};
|
||||||
|
TestHighbdIntraPred("Intra32", pred_funcs, kSignatures, 32);
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace
|
||||||
|
|
||||||
|
// Defines a test case for |arch| (e.g., C, SSE2, ...) passing the predictors
|
||||||
|
// to |test_func|. The test name is 'arch.test_func', e.g., C.TestIntraPred4.
|
||||||
|
#define HIGHBD_INTRA_PRED_TEST(arch, test_func, dc, dc_left, dc_top, dc_128, \
|
||||||
|
v, h, d45, d135, d117, d153, d207, d63, tm) \
|
||||||
|
TEST(arch, test_func) { \
|
||||||
|
static const VpxHighbdPredFunc vpx_intra_pred[] = { \
|
||||||
|
dc, dc_left, dc_top, dc_128, v, h, d45, d135, d117, d153, d207, d63, tm \
|
||||||
|
}; \
|
||||||
|
test_func(vpx_intra_pred); \
|
||||||
|
}
|
||||||
|
|
||||||
|
// -----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
HIGHBD_INTRA_PRED_TEST(
|
||||||
|
C, TestHighbdIntraPred4, vpx_highbd_dc_predictor_4x4_c,
|
||||||
|
vpx_highbd_dc_left_predictor_4x4_c, vpx_highbd_dc_top_predictor_4x4_c,
|
||||||
|
vpx_highbd_dc_128_predictor_4x4_c, vpx_highbd_v_predictor_4x4_c,
|
||||||
|
vpx_highbd_h_predictor_4x4_c, vpx_highbd_d45_predictor_4x4_c,
|
||||||
|
vpx_highbd_d135_predictor_4x4_c, vpx_highbd_d117_predictor_4x4_c,
|
||||||
|
vpx_highbd_d153_predictor_4x4_c, vpx_highbd_d207_predictor_4x4_c,
|
||||||
|
vpx_highbd_d63_predictor_4x4_c, vpx_highbd_tm_predictor_4x4_c)
|
||||||
|
|
||||||
|
HIGHBD_INTRA_PRED_TEST(
|
||||||
|
C, TestHighbdIntraPred8, vpx_highbd_dc_predictor_8x8_c,
|
||||||
|
vpx_highbd_dc_left_predictor_8x8_c, vpx_highbd_dc_top_predictor_8x8_c,
|
||||||
|
vpx_highbd_dc_128_predictor_8x8_c, vpx_highbd_v_predictor_8x8_c,
|
||||||
|
vpx_highbd_h_predictor_8x8_c, vpx_highbd_d45_predictor_8x8_c,
|
||||||
|
vpx_highbd_d135_predictor_8x8_c, vpx_highbd_d117_predictor_8x8_c,
|
||||||
|
vpx_highbd_d153_predictor_8x8_c, vpx_highbd_d207_predictor_8x8_c,
|
||||||
|
vpx_highbd_d63_predictor_8x8_c, vpx_highbd_tm_predictor_8x8_c)
|
||||||
|
|
||||||
|
HIGHBD_INTRA_PRED_TEST(
|
||||||
|
C, TestHighbdIntraPred16, vpx_highbd_dc_predictor_16x16_c,
|
||||||
|
vpx_highbd_dc_left_predictor_16x16_c, vpx_highbd_dc_top_predictor_16x16_c,
|
||||||
|
vpx_highbd_dc_128_predictor_16x16_c, vpx_highbd_v_predictor_16x16_c,
|
||||||
|
vpx_highbd_h_predictor_16x16_c, vpx_highbd_d45_predictor_16x16_c,
|
||||||
|
vpx_highbd_d135_predictor_16x16_c, vpx_highbd_d117_predictor_16x16_c,
|
||||||
|
vpx_highbd_d153_predictor_16x16_c, vpx_highbd_d207_predictor_16x16_c,
|
||||||
|
vpx_highbd_d63_predictor_16x16_c, vpx_highbd_tm_predictor_16x16_c)
|
||||||
|
|
||||||
|
HIGHBD_INTRA_PRED_TEST(
|
||||||
|
C, TestHighbdIntraPred32, vpx_highbd_dc_predictor_32x32_c,
|
||||||
|
vpx_highbd_dc_left_predictor_32x32_c, vpx_highbd_dc_top_predictor_32x32_c,
|
||||||
|
vpx_highbd_dc_128_predictor_32x32_c, vpx_highbd_v_predictor_32x32_c,
|
||||||
|
vpx_highbd_h_predictor_32x32_c, vpx_highbd_d45_predictor_32x32_c,
|
||||||
|
vpx_highbd_d135_predictor_32x32_c, vpx_highbd_d117_predictor_32x32_c,
|
||||||
|
vpx_highbd_d153_predictor_32x32_c, vpx_highbd_d207_predictor_32x32_c,
|
||||||
|
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, 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)
|
||||||
|
|
||||||
|
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)
|
||||||
|
|
||||||
|
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)
|
||||||
|
#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"
|
#include "test/test_libvpx.cc"
|
||||||
|
|
|
@ -53,6 +53,9 @@ int main(int argc, char **argv) {
|
||||||
}
|
}
|
||||||
if (!(simd_caps & HAS_AVX)) append_negative_gtest_filter(":AVX.*:AVX/*");
|
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_AVX2)) append_negative_gtest_filter(":AVX2.*:AVX2/*");
|
||||||
|
if (!(simd_caps & HAS_AVX512)) {
|
||||||
|
append_negative_gtest_filter(":AVX512.*:AVX512/*");
|
||||||
|
}
|
||||||
#endif // ARCH_X86 || ARCH_X86_64
|
#endif // ARCH_X86 || ARCH_X86_64
|
||||||
|
|
||||||
#if !CONFIG_SHARED
|
#if !CONFIG_SHARED
|
||||||
|
|
|
@ -28,13 +28,10 @@
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
|
|
||||||
enum DecodeMode { kSerialMode, kFrameParallelMode };
|
const int kThreads = 0;
|
||||||
|
const int kFileName = 1;
|
||||||
|
|
||||||
const int kDecodeMode = 0;
|
typedef std::tr1::tuple<int, const char *> DecodeParam;
|
||||||
const int kThreads = 1;
|
|
||||||
const int kFileName = 2;
|
|
||||||
|
|
||||||
typedef std::tr1::tuple<int, int, const char *> DecodeParam;
|
|
||||||
|
|
||||||
class TestVectorTest : public ::libvpx_test::DecoderTest,
|
class TestVectorTest : public ::libvpx_test::DecoderTest,
|
||||||
public ::libvpx_test::CodecTestWithParam<DecodeParam> {
|
public ::libvpx_test::CodecTestWithParam<DecodeParam> {
|
||||||
|
@ -53,8 +50,8 @@ class TestVectorTest : public ::libvpx_test::DecoderTest,
|
||||||
|
|
||||||
void OpenMD5File(const std::string &md5_file_name_) {
|
void OpenMD5File(const std::string &md5_file_name_) {
|
||||||
md5_file_ = libvpx_test::OpenTestDataFile(md5_file_name_);
|
md5_file_ = libvpx_test::OpenTestDataFile(md5_file_name_);
|
||||||
ASSERT_TRUE(md5_file_ != NULL) << "Md5 file open failed. Filename: "
|
ASSERT_TRUE(md5_file_ != NULL)
|
||||||
<< md5_file_name_;
|
<< "Md5 file open failed. Filename: " << md5_file_name_;
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual void DecompressedFrameHook(const vpx_image_t &img,
|
virtual void DecompressedFrameHook(const vpx_image_t &img,
|
||||||
|
@ -92,29 +89,14 @@ class TestVectorTest : public ::libvpx_test::DecoderTest,
|
||||||
TEST_P(TestVectorTest, MD5Match) {
|
TEST_P(TestVectorTest, MD5Match) {
|
||||||
const DecodeParam input = GET_PARAM(1);
|
const DecodeParam input = GET_PARAM(1);
|
||||||
const std::string filename = std::tr1::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_flags_t flags = 0;
|
||||||
vpx_codec_dec_cfg_t cfg = vpx_codec_dec_cfg_t();
|
vpx_codec_dec_cfg_t cfg = vpx_codec_dec_cfg_t();
|
||||||
char str[256];
|
char str[256];
|
||||||
|
|
||||||
if (mode == kFrameParallelMode) {
|
cfg.threads = std::tr1::get<kThreads>(input);
|
||||||
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
|
|
||||||
}
|
|
||||||
|
|
||||||
cfg.threads = threads;
|
snprintf(str, sizeof(str) / sizeof(str[0]) - 1, "file: %s threads: %d",
|
||||||
|
filename.c_str(), cfg.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);
|
SCOPED_TRACE(str);
|
||||||
|
|
||||||
// Open compressed video file.
|
// Open compressed video file.
|
||||||
|
@ -145,38 +127,44 @@ TEST_P(TestVectorTest, MD5Match) {
|
||||||
ASSERT_NO_FATAL_FAILURE(RunLoop(video.get(), cfg));
|
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
|
#if CONFIG_VP8_DECODER
|
||||||
VP8_INSTANTIATE_TEST_CASE(
|
VP8_INSTANTIATE_TEST_CASE(
|
||||||
TestVectorTest,
|
TestVectorTest,
|
||||||
::testing::Combine(
|
::testing::Combine(
|
||||||
::testing::Values(0), // Serial Mode.
|
|
||||||
::testing::Values(1), // Single thread.
|
::testing::Values(1), // Single thread.
|
||||||
::testing::ValuesIn(libvpx_test::kVP8TestVectors,
|
::testing::ValuesIn(libvpx_test::kVP8TestVectors,
|
||||||
libvpx_test::kVP8TestVectors +
|
libvpx_test::kVP8TestVectors +
|
||||||
libvpx_test::kNumVP8TestVectors)));
|
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
|
#endif // CONFIG_VP8_DECODER
|
||||||
|
|
||||||
// Test VP9 decode in serial mode with single thread.
|
|
||||||
#if CONFIG_VP9_DECODER
|
#if CONFIG_VP9_DECODER
|
||||||
VP9_INSTANTIATE_TEST_CASE(
|
VP9_INSTANTIATE_TEST_CASE(
|
||||||
TestVectorTest,
|
TestVectorTest,
|
||||||
::testing::Combine(
|
::testing::Combine(
|
||||||
::testing::Values(0), // Serial Mode.
|
|
||||||
::testing::Values(1), // Single thread.
|
::testing::Values(1), // Single thread.
|
||||||
::testing::ValuesIn(libvpx_test::kVP9TestVectors,
|
::testing::ValuesIn(libvpx_test::kVP9TestVectors,
|
||||||
libvpx_test::kVP9TestVectors +
|
libvpx_test::kVP9TestVectors +
|
||||||
libvpx_test::kNumVP9TestVectors)));
|
libvpx_test::kNumVP9TestVectors)));
|
||||||
|
|
||||||
// Test VP9 decode in frame parallel mode with different number of threads.
|
|
||||||
INSTANTIATE_TEST_CASE_P(
|
INSTANTIATE_TEST_CASE_P(
|
||||||
VP9MultiThreadedFrameParallel, TestVectorTest,
|
VP9MultiThreaded, TestVectorTest,
|
||||||
::testing::Combine(
|
::testing::Combine(
|
||||||
::testing::Values(
|
::testing::Values(
|
||||||
static_cast<const libvpx_test::CodecFactory *>(&libvpx_test::kVP9)),
|
static_cast<const libvpx_test::CodecFactory *>(&libvpx_test::kVP9)),
|
||||||
::testing::Combine(
|
::testing::Combine(
|
||||||
::testing::Values(1), // Frame Parallel mode.
|
|
||||||
::testing::Range(2, 9), // With 2 ~ 8 threads.
|
::testing::Range(2, 9), // With 2 ~ 8 threads.
|
||||||
::testing::ValuesIn(libvpx_test::kVP9TestVectors,
|
::testing::ValuesIn(libvpx_test::kVP9TestVectors,
|
||||||
libvpx_test::kVP9TestVectors +
|
libvpx_test::kVP9TestVectors +
|
||||||
|
|
|
@ -371,9 +371,12 @@ const char *const kVP9TestVectors[] = {
|
||||||
#endif // CONFIG_VP9_HIGHBITDEPTH
|
#endif // CONFIG_VP9_HIGHBITDEPTH
|
||||||
"vp90-2-20-big_superframe-01.webm",
|
"vp90-2-20-big_superframe-01.webm",
|
||||||
"vp90-2-20-big_superframe-02.webm",
|
"vp90-2-20-big_superframe-02.webm",
|
||||||
|
"vp90-2-22-svc_1280x720_1.webm",
|
||||||
RESIZE_TEST_VECTORS
|
RESIZE_TEST_VECTORS
|
||||||
};
|
};
|
||||||
|
const char *const kVP9TestVectorsSvc[] = { "vp90-2-22-svc_1280x720_3.ivf" };
|
||||||
const int kNumVP9TestVectors = NELEMENTS(kVP9TestVectors);
|
const int kNumVP9TestVectors = NELEMENTS(kVP9TestVectors);
|
||||||
|
const int kNumVP9TestVectorsSvc = NELEMENTS(kVP9TestVectorsSvc);
|
||||||
const char *const kVP9TestVectorsResize[] = { RESIZE_TEST_VECTORS };
|
const char *const kVP9TestVectorsResize[] = { RESIZE_TEST_VECTORS };
|
||||||
const int kNumVP9TestVectorsResize = NELEMENTS(kVP9TestVectorsResize);
|
const int kNumVP9TestVectorsResize = NELEMENTS(kVP9TestVectorsResize);
|
||||||
#undef RESIZE_TEST_VECTORS
|
#undef RESIZE_TEST_VECTORS
|
||||||
|
|
|
@ -23,6 +23,8 @@ extern const char *const kVP8TestVectors[];
|
||||||
#if CONFIG_VP9_DECODER
|
#if CONFIG_VP9_DECODER
|
||||||
extern const int kNumVP9TestVectors;
|
extern const int kNumVP9TestVectors;
|
||||||
extern const char *const kVP9TestVectors[];
|
extern const char *const kVP9TestVectors[];
|
||||||
|
extern const int kNumVP9TestVectorsSvc;
|
||||||
|
extern const char *const kVP9TestVectorsSvc[];
|
||||||
extern const int kNumVP9TestVectorsResize;
|
extern const int kNumVP9TestVectorsResize;
|
||||||
extern const char *const kVP9TestVectorsResize[];
|
extern const char *const kVP9TestVectorsResize[];
|
||||||
#endif // CONFIG_VP9_DECODER
|
#endif // CONFIG_VP9_DECODER
|
||||||
|
|
|
@ -54,7 +54,10 @@ twopass_encoder_vp9() {
|
||||||
fi
|
fi
|
||||||
}
|
}
|
||||||
|
|
||||||
twopass_encoder_tests="twopass_encoder_vp8
|
|
||||||
twopass_encoder_vp9"
|
|
||||||
|
|
||||||
run_tests twopass_encoder_verify_environment "${twopass_encoder_tests}"
|
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
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -13,7 +13,9 @@
|
||||||
#if defined(_WIN32)
|
#if defined(_WIN32)
|
||||||
#undef NOMINMAX
|
#undef NOMINMAX
|
||||||
#define NOMINMAX
|
#define NOMINMAX
|
||||||
|
#ifndef WIN32_LEAN_AND_MEAN
|
||||||
#define WIN32_LEAN_AND_MEAN
|
#define WIN32_LEAN_AND_MEAN
|
||||||
|
#endif
|
||||||
#include <windows.h>
|
#include <windows.h>
|
||||||
#endif
|
#endif
|
||||||
#include <cstdio>
|
#include <cstdio>
|
||||||
|
|
|
@ -17,12 +17,16 @@
|
||||||
|
|
||||||
#include "third_party/googletest/src/include/gtest/gtest.h"
|
#include "third_party/googletest/src/include/gtest/gtest.h"
|
||||||
|
|
||||||
|
#include "./vpx_config.h"
|
||||||
#include "./vp8_rtcd.h"
|
#include "./vp8_rtcd.h"
|
||||||
#include "test/acm_random.h"
|
#include "test/acm_random.h"
|
||||||
#include "vpx/vpx_integer.h"
|
#include "vpx/vpx_integer.h"
|
||||||
|
#include "vpx_ports/mem.h"
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
|
|
||||||
|
typedef void (*FdctFunc)(int16_t *a, int16_t *b, int a_stride);
|
||||||
|
|
||||||
const int cospi8sqrt2minus1 = 20091;
|
const int cospi8sqrt2minus1 = 20091;
|
||||||
const int sinpi8sqrt2 = 35468;
|
const int sinpi8sqrt2 = 35468;
|
||||||
|
|
||||||
|
@ -68,10 +72,21 @@ void reference_idct4x4(const int16_t *input, int16_t *output) {
|
||||||
|
|
||||||
using libvpx_test::ACMRandom;
|
using libvpx_test::ACMRandom;
|
||||||
|
|
||||||
TEST(VP8FdctTest, SignBiasCheck) {
|
class FdctTest : public ::testing::TestWithParam<FdctFunc> {
|
||||||
ACMRandom rnd(ACMRandom::DeterministicSeed());
|
public:
|
||||||
|
virtual void SetUp() {
|
||||||
|
fdct_func_ = GetParam();
|
||||||
|
rnd_.Reset(ACMRandom::DeterministicSeed());
|
||||||
|
}
|
||||||
|
|
||||||
|
protected:
|
||||||
|
FdctFunc fdct_func_;
|
||||||
|
ACMRandom rnd_;
|
||||||
|
};
|
||||||
|
|
||||||
|
TEST_P(FdctTest, SignBiasCheck) {
|
||||||
int16_t test_input_block[16];
|
int16_t test_input_block[16];
|
||||||
int16_t test_output_block[16];
|
DECLARE_ALIGNED(16, int16_t, test_output_block[16]);
|
||||||
const int pitch = 8;
|
const int pitch = 8;
|
||||||
int count_sign_block[16][2];
|
int count_sign_block[16][2];
|
||||||
const int count_test_block = 1000000;
|
const int count_test_block = 1000000;
|
||||||
|
@ -81,10 +96,10 @@ TEST(VP8FdctTest, SignBiasCheck) {
|
||||||
for (int i = 0; i < count_test_block; ++i) {
|
for (int i = 0; i < count_test_block; ++i) {
|
||||||
// Initialize a test block with input range [-255, 255].
|
// Initialize a test block with input range [-255, 255].
|
||||||
for (int j = 0; j < 16; ++j) {
|
for (int j = 0; j < 16; ++j) {
|
||||||
test_input_block[j] = rnd.Rand8() - rnd.Rand8();
|
test_input_block[j] = rnd_.Rand8() - rnd_.Rand8();
|
||||||
}
|
}
|
||||||
|
|
||||||
vp8_short_fdct4x4_c(test_input_block, test_output_block, pitch);
|
fdct_func_(test_input_block, test_output_block, pitch);
|
||||||
|
|
||||||
for (int j = 0; j < 16; ++j) {
|
for (int j = 0; j < 16; ++j) {
|
||||||
if (test_output_block[j] < 0) {
|
if (test_output_block[j] < 0) {
|
||||||
|
@ -110,10 +125,10 @@ TEST(VP8FdctTest, SignBiasCheck) {
|
||||||
for (int i = 0; i < count_test_block; ++i) {
|
for (int i = 0; i < count_test_block; ++i) {
|
||||||
// Initialize a test block with input range [-15, 15].
|
// Initialize a test block with input range [-15, 15].
|
||||||
for (int j = 0; j < 16; ++j) {
|
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);
|
||||||
}
|
}
|
||||||
|
|
||||||
vp8_short_fdct4x4_c(test_input_block, test_output_block, pitch);
|
fdct_func_(test_input_block, test_output_block, pitch);
|
||||||
|
|
||||||
for (int j = 0; j < 16; ++j) {
|
for (int j = 0; j < 16; ++j) {
|
||||||
if (test_output_block[j] < 0) {
|
if (test_output_block[j] < 0) {
|
||||||
|
@ -135,23 +150,22 @@ TEST(VP8FdctTest, SignBiasCheck) {
|
||||||
<< "Error: 4x4 FDCT has a sign bias > 10% for input range [-15, 15]";
|
<< "Error: 4x4 FDCT has a sign bias > 10% for input range [-15, 15]";
|
||||||
};
|
};
|
||||||
|
|
||||||
TEST(VP8FdctTest, RoundTripErrorCheck) {
|
TEST_P(FdctTest, RoundTripErrorCheck) {
|
||||||
ACMRandom rnd(ACMRandom::DeterministicSeed());
|
|
||||||
int max_error = 0;
|
int max_error = 0;
|
||||||
double total_error = 0;
|
double total_error = 0;
|
||||||
const int count_test_block = 1000000;
|
const int count_test_block = 1000000;
|
||||||
for (int i = 0; i < count_test_block; ++i) {
|
for (int i = 0; i < count_test_block; ++i) {
|
||||||
int16_t test_input_block[16];
|
int16_t test_input_block[16];
|
||||||
int16_t test_temp_block[16];
|
|
||||||
int16_t test_output_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].
|
// Initialize a test block with input range [-255, 255].
|
||||||
for (int j = 0; j < 16; ++j) {
|
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;
|
const int pitch = 8;
|
||||||
vp8_short_fdct4x4_c(test_input_block, test_temp_block, pitch);
|
fdct_func_(test_input_block, test_temp_block, pitch);
|
||||||
reference_idct4x4(test_temp_block, test_output_block);
|
reference_idct4x4(test_temp_block, test_output_block);
|
||||||
|
|
||||||
for (int j = 0; j < 16; ++j) {
|
for (int j = 0; j < 16; ++j) {
|
||||||
|
@ -169,4 +183,24 @@ TEST(VP8FdctTest, RoundTripErrorCheck) {
|
||||||
<< "Error: FDCT/IDCT has average roundtrip error > 1 per block";
|
<< "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
|
} // namespace
|
||||||
|
|
|
@ -23,36 +23,36 @@
|
||||||
#include "vp9/common/vp9_entropy.h"
|
#include "vp9/common/vp9_entropy.h"
|
||||||
#include "vpx/vpx_codec.h"
|
#include "vpx/vpx_codec.h"
|
||||||
#include "vpx/vpx_integer.h"
|
#include "vpx/vpx_integer.h"
|
||||||
|
#include "vpx_dsp/vpx_dsp_common.h"
|
||||||
|
|
||||||
using libvpx_test::ACMRandom;
|
using libvpx_test::ACMRandom;
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
#if CONFIG_VP9_HIGHBITDEPTH
|
|
||||||
const int kNumIterations = 1000;
|
const int kNumIterations = 1000;
|
||||||
|
|
||||||
typedef int64_t (*ErrorBlockFunc)(const tran_low_t *coeff,
|
typedef int64_t (*HBDBlockErrorFunc)(const tran_low_t *coeff,
|
||||||
|
const tran_low_t *dqcoeff,
|
||||||
|
intptr_t block_size, int64_t *ssz,
|
||||||
|
int bps);
|
||||||
|
|
||||||
|
typedef std::tr1::tuple<HBDBlockErrorFunc, HBDBlockErrorFunc, vpx_bit_depth_t>
|
||||||
|
BlockErrorParam;
|
||||||
|
|
||||||
|
typedef int64_t (*BlockErrorFunc)(const tran_low_t *coeff,
|
||||||
const tran_low_t *dqcoeff,
|
const tran_low_t *dqcoeff,
|
||||||
intptr_t block_size, int64_t *ssz, int bps);
|
intptr_t block_size, int64_t *ssz);
|
||||||
|
|
||||||
typedef std::tr1::tuple<ErrorBlockFunc, ErrorBlockFunc, vpx_bit_depth_t>
|
template <BlockErrorFunc fn>
|
||||||
ErrorBlockParam;
|
int64_t BlockError8BitWrapper(const tran_low_t *coeff,
|
||||||
|
const tran_low_t *dqcoeff, intptr_t block_size,
|
||||||
// wrapper for 8-bit block error functions without a 'bps' param.
|
int64_t *ssz, int bps) {
|
||||||
typedef int64_t (*HighBdBlockError8bit)(const tran_low_t *coeff,
|
EXPECT_EQ(bps, 8);
|
||||||
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);
|
return fn(coeff, dqcoeff, block_size, ssz);
|
||||||
}
|
}
|
||||||
|
|
||||||
class ErrorBlockTest : public ::testing::TestWithParam<ErrorBlockParam> {
|
class BlockErrorTest : public ::testing::TestWithParam<BlockErrorParam> {
|
||||||
public:
|
public:
|
||||||
virtual ~ErrorBlockTest() {}
|
virtual ~BlockErrorTest() {}
|
||||||
virtual void SetUp() {
|
virtual void SetUp() {
|
||||||
error_block_op_ = GET_PARAM(0);
|
error_block_op_ = GET_PARAM(0);
|
||||||
ref_error_block_op_ = GET_PARAM(1);
|
ref_error_block_op_ = GET_PARAM(1);
|
||||||
|
@ -63,11 +63,11 @@ class ErrorBlockTest : public ::testing::TestWithParam<ErrorBlockParam> {
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
vpx_bit_depth_t bit_depth_;
|
vpx_bit_depth_t bit_depth_;
|
||||||
ErrorBlockFunc error_block_op_;
|
HBDBlockErrorFunc error_block_op_;
|
||||||
ErrorBlockFunc ref_error_block_op_;
|
HBDBlockErrorFunc ref_error_block_op_;
|
||||||
};
|
};
|
||||||
|
|
||||||
TEST_P(ErrorBlockTest, OperationCheck) {
|
TEST_P(BlockErrorTest, OperationCheck) {
|
||||||
ACMRandom rnd(ACMRandom::DeterministicSeed());
|
ACMRandom rnd(ACMRandom::DeterministicSeed());
|
||||||
DECLARE_ALIGNED(16, tran_low_t, coeff[4096]);
|
DECLARE_ALIGNED(16, tran_low_t, coeff[4096]);
|
||||||
DECLARE_ALIGNED(16, tran_low_t, dqcoeff[4096]);
|
DECLARE_ALIGNED(16, tran_low_t, dqcoeff[4096]);
|
||||||
|
@ -110,7 +110,7 @@ TEST_P(ErrorBlockTest, OperationCheck) {
|
||||||
<< "First failed at test case " << first_failure;
|
<< "First failed at test case " << first_failure;
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_P(ErrorBlockTest, ExtremeValues) {
|
TEST_P(BlockErrorTest, ExtremeValues) {
|
||||||
ACMRandom rnd(ACMRandom::DeterministicSeed());
|
ACMRandom rnd(ACMRandom::DeterministicSeed());
|
||||||
DECLARE_ALIGNED(16, tran_low_t, coeff[4096]);
|
DECLARE_ALIGNED(16, tran_low_t, coeff[4096]);
|
||||||
DECLARE_ALIGNED(16, tran_low_t, dqcoeff[4096]);
|
DECLARE_ALIGNED(16, tran_low_t, dqcoeff[4096]);
|
||||||
|
@ -171,29 +171,28 @@ TEST_P(ErrorBlockTest, ExtremeValues) {
|
||||||
using std::tr1::make_tuple;
|
using std::tr1::make_tuple;
|
||||||
|
|
||||||
#if HAVE_SSE2
|
#if HAVE_SSE2
|
||||||
INSTANTIATE_TEST_CASE_P(
|
const BlockErrorParam sse2_block_error_tests[] = {
|
||||||
SSE2, ErrorBlockTest,
|
#if CONFIG_VP9_HIGHBITDEPTH
|
||||||
::testing::Values(
|
make_tuple(&vp9_highbd_block_error_sse2, &vp9_highbd_block_error_c,
|
||||||
make_tuple(&vp9_highbd_block_error_sse2, &vp9_highbd_block_error_c,
|
VPX_BITS_10),
|
||||||
VPX_BITS_10),
|
make_tuple(&vp9_highbd_block_error_sse2, &vp9_highbd_block_error_c,
|
||||||
make_tuple(&vp9_highbd_block_error_sse2, &vp9_highbd_block_error_c,
|
VPX_BITS_12),
|
||||||
VPX_BITS_12),
|
make_tuple(&vp9_highbd_block_error_sse2, &vp9_highbd_block_error_c,
|
||||||
make_tuple(&vp9_highbd_block_error_sse2, &vp9_highbd_block_error_c,
|
VPX_BITS_8),
|
||||||
VPX_BITS_8),
|
#endif // CONFIG_VP9_HIGHBITDEPTH
|
||||||
make_tuple(
|
make_tuple(&BlockError8BitWrapper<vp9_block_error_sse2>,
|
||||||
&HighBdBlockError8bitWrapper<vp9_highbd_block_error_8bit_sse2>,
|
&BlockError8BitWrapper<vp9_block_error_c>, VPX_BITS_8)
|
||||||
&HighBdBlockError8bitWrapper<vp9_highbd_block_error_8bit_c>,
|
};
|
||||||
VPX_BITS_8)));
|
|
||||||
|
INSTANTIATE_TEST_CASE_P(SSE2, BlockErrorTest,
|
||||||
|
::testing::ValuesIn(sse2_block_error_tests));
|
||||||
#endif // HAVE_SSE2
|
#endif // HAVE_SSE2
|
||||||
|
|
||||||
#if HAVE_AVX
|
#if HAVE_AVX2
|
||||||
INSTANTIATE_TEST_CASE_P(
|
INSTANTIATE_TEST_CASE_P(
|
||||||
AVX, ErrorBlockTest,
|
AVX2, BlockErrorTest,
|
||||||
::testing::Values(make_tuple(
|
::testing::Values(make_tuple(&BlockError8BitWrapper<vp9_block_error_avx2>,
|
||||||
&HighBdBlockError8bitWrapper<vp9_highbd_block_error_8bit_avx>,
|
&BlockError8BitWrapper<vp9_block_error_c>,
|
||||||
&HighBdBlockError8bitWrapper<vp9_highbd_block_error_8bit_c>,
|
VPX_BITS_8)));
|
||||||
VPX_BITS_8)));
|
#endif // HAVE_AVX2
|
||||||
#endif // HAVE_AVX
|
|
||||||
|
|
||||||
#endif // CONFIG_VP9_HIGHBITDEPTH
|
|
||||||
} // namespace
|
} // namespace
|
|
@ -29,11 +29,21 @@ using libvpx_test::ACMRandom;
|
||||||
namespace {
|
namespace {
|
||||||
|
|
||||||
const int kNumPixels = 64 * 64;
|
const int kNumPixels = 64 * 64;
|
||||||
class VP9DenoiserTest : public ::testing::TestWithParam<BLOCK_SIZE> {
|
|
||||||
|
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 std::tr1::tuple<Vp9DenoiserFilterFunc, BLOCK_SIZE> VP9DenoiserTestParam;
|
||||||
|
|
||||||
|
class VP9DenoiserTest
|
||||||
|
: public ::testing::Test,
|
||||||
|
public ::testing::WithParamInterface<VP9DenoiserTestParam> {
|
||||||
public:
|
public:
|
||||||
virtual ~VP9DenoiserTest() {}
|
virtual ~VP9DenoiserTest() {}
|
||||||
|
|
||||||
virtual void SetUp() { bs_ = GetParam(); }
|
virtual void SetUp() { bs_ = GET_PARAM(1); }
|
||||||
|
|
||||||
virtual void TearDown() { libvpx_test::ClearSystemState(); }
|
virtual void TearDown() { libvpx_test::ClearSystemState(); }
|
||||||
|
|
||||||
|
@ -76,9 +86,9 @@ TEST_P(VP9DenoiserTest, BitexactCheck) {
|
||||||
64, avg_block_c, 64, 0, bs_,
|
64, avg_block_c, 64, 0, bs_,
|
||||||
motion_magnitude_random));
|
motion_magnitude_random));
|
||||||
|
|
||||||
ASM_REGISTER_STATE_CHECK(vp9_denoiser_filter_sse2(
|
ASM_REGISTER_STATE_CHECK(GET_PARAM(0)(sig_block, 64, mc_avg_block, 64,
|
||||||
sig_block, 64, mc_avg_block, 64, avg_block_sse2, 64, 0, bs_,
|
avg_block_sse2, 64, 0, bs_,
|
||||||
motion_magnitude_random));
|
motion_magnitude_random));
|
||||||
|
|
||||||
// Test bitexactness.
|
// Test bitexactness.
|
||||||
for (int h = 0; h < (4 << b_height_log2_lookup[bs_]); ++h) {
|
for (int h = 0; h < (4 << b_height_log2_lookup[bs_]); ++h) {
|
||||||
|
@ -89,10 +99,36 @@ TEST_P(VP9DenoiserTest, BitexactCheck) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
using std::tr1::make_tuple;
|
||||||
|
|
||||||
// Test for all block size.
|
// Test for all block size.
|
||||||
INSTANTIATE_TEST_CASE_P(SSE2, VP9DenoiserTest,
|
#if HAVE_SSE2
|
||||||
::testing::Values(BLOCK_8X8, BLOCK_8X16, BLOCK_16X8,
|
INSTANTIATE_TEST_CASE_P(
|
||||||
BLOCK_16X16, BLOCK_16X32, BLOCK_32X16,
|
SSE2, VP9DenoiserTest,
|
||||||
BLOCK_32X32, BLOCK_32X64, BLOCK_64X32,
|
::testing::Values(make_tuple(&vp9_denoiser_filter_sse2, BLOCK_8X8),
|
||||||
BLOCK_64X64));
|
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
|
||||||
} // namespace
|
} // namespace
|
|
@ -99,9 +99,7 @@ class VpxEncoderParmsGetToDecoder
|
||||||
vpx_codec_ctx_t *const vp9_decoder = decoder->GetDecoder();
|
vpx_codec_ctx_t *const vp9_decoder = decoder->GetDecoder();
|
||||||
vpx_codec_alg_priv_t *const priv =
|
vpx_codec_alg_priv_t *const priv =
|
||||||
reinterpret_cast<vpx_codec_alg_priv_t *>(vp9_decoder->priv);
|
reinterpret_cast<vpx_codec_alg_priv_t *>(vp9_decoder->priv);
|
||||||
FrameWorkerData *const worker_data =
|
VP9_COMMON *const common = &priv->pbi->common;
|
||||||
reinterpret_cast<FrameWorkerData *>(priv->frame_workers[0].data1);
|
|
||||||
VP9_COMMON *const common = &worker_data->pbi->common;
|
|
||||||
|
|
||||||
if (encode_parms.lossless) {
|
if (encode_parms.lossless) {
|
||||||
EXPECT_EQ(0, common->base_qindex);
|
EXPECT_EQ(0, common->base_qindex);
|
||||||
|
|
|
@ -16,17 +16,221 @@
|
||||||
#include "test/md5_helper.h"
|
#include "test/md5_helper.h"
|
||||||
#include "test/util.h"
|
#include "test/util.h"
|
||||||
#include "test/y4m_video_source.h"
|
#include "test/y4m_video_source.h"
|
||||||
|
#include "vp9/encoder/vp9_firstpass.h"
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
class VPxEncoderThreadTest
|
// 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::EncoderTest,
|
||||||
public ::libvpx_test::CodecTestWith2Params<libvpx_test::TestMode, int> {
|
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,
|
||||||
|
int, int> {
|
||||||
protected:
|
protected:
|
||||||
VPxEncoderThreadTest()
|
VPxEncoderThreadTest()
|
||||||
: EncoderTest(GET_PARAM(0)), encoder_initialized_(false), tiles_(2),
|
: EncoderTest(GET_PARAM(0)), encoder_initialized_(false),
|
||||||
|
tiles_(GET_PARAM(3)), threads_(GET_PARAM(4)),
|
||||||
encoding_mode_(GET_PARAM(1)), set_cpu_used_(GET_PARAM(2)) {
|
encoding_mode_(GET_PARAM(1)), set_cpu_used_(GET_PARAM(2)) {
|
||||||
init_flags_ = VPX_CODEC_USE_PSNR;
|
init_flags_ = VPX_CODEC_USE_PSNR;
|
||||||
md5_.clear();
|
md5_.clear();
|
||||||
|
row_mt_mode_ = 1;
|
||||||
|
psnr_ = 0.0;
|
||||||
|
nframes_ = 0;
|
||||||
}
|
}
|
||||||
virtual ~VPxEncoderThreadTest() {}
|
virtual ~VPxEncoderThreadTest() {}
|
||||||
|
|
||||||
|
@ -35,7 +239,6 @@ class VPxEncoderThreadTest
|
||||||
SetMode(encoding_mode_);
|
SetMode(encoding_mode_);
|
||||||
|
|
||||||
if (encoding_mode_ != ::libvpx_test::kRealTime) {
|
if (encoding_mode_ != ::libvpx_test::kRealTime) {
|
||||||
cfg_.g_lag_in_frames = 3;
|
|
||||||
cfg_.rc_end_usage = VPX_VBR;
|
cfg_.rc_end_usage = VPX_VBR;
|
||||||
cfg_.rc_2pass_vbr_minsection_pct = 5;
|
cfg_.rc_2pass_vbr_minsection_pct = 5;
|
||||||
cfg_.rc_2pass_vbr_maxsection_pct = 2000;
|
cfg_.rc_2pass_vbr_maxsection_pct = 2000;
|
||||||
|
@ -50,6 +253,8 @@ class VPxEncoderThreadTest
|
||||||
|
|
||||||
virtual void BeginPassHook(unsigned int /*pass*/) {
|
virtual void BeginPassHook(unsigned int /*pass*/) {
|
||||||
encoder_initialized_ = false;
|
encoder_initialized_ = false;
|
||||||
|
psnr_ = 0.0;
|
||||||
|
nframes_ = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual void PreEncodeFrameHook(::libvpx_test::VideoSource * /*video*/,
|
virtual void PreEncodeFrameHook(::libvpx_test::VideoSource * /*video*/,
|
||||||
|
@ -63,14 +268,22 @@ class VPxEncoderThreadTest
|
||||||
encoder->Control(VP8E_SET_ARNR_MAXFRAMES, 7);
|
encoder->Control(VP8E_SET_ARNR_MAXFRAMES, 7);
|
||||||
encoder->Control(VP8E_SET_ARNR_STRENGTH, 5);
|
encoder->Control(VP8E_SET_ARNR_STRENGTH, 5);
|
||||||
encoder->Control(VP8E_SET_ARNR_TYPE, 3);
|
encoder->Control(VP8E_SET_ARNR_TYPE, 3);
|
||||||
|
encoder->Control(VP9E_SET_FRAME_PARALLEL_DECODING, 0);
|
||||||
} else {
|
} else {
|
||||||
encoder->Control(VP8E_SET_ENABLEAUTOALTREF, 0);
|
encoder->Control(VP8E_SET_ENABLEAUTOALTREF, 0);
|
||||||
encoder->Control(VP9E_SET_AQ_MODE, 3);
|
encoder->Control(VP9E_SET_AQ_MODE, 3);
|
||||||
}
|
}
|
||||||
|
encoder->Control(VP9E_SET_ROW_MT, row_mt_mode_);
|
||||||
|
|
||||||
encoder_initialized_ = true;
|
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,
|
virtual void DecompressedFrameHook(const vpx_image_t &img,
|
||||||
vpx_codec_pts_t /*pts*/) {
|
vpx_codec_pts_t /*pts*/) {
|
||||||
::libvpx_test::MD5 md5_res;
|
::libvpx_test::MD5 md5_res;
|
||||||
|
@ -89,40 +302,127 @@ class VPxEncoderThreadTest
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
double GetAveragePsnr() const { return nframes_ ? (psnr_ / nframes_) : 0.0; }
|
||||||
|
|
||||||
bool encoder_initialized_;
|
bool encoder_initialized_;
|
||||||
int tiles_;
|
int tiles_;
|
||||||
|
int threads_;
|
||||||
::libvpx_test::TestMode encoding_mode_;
|
::libvpx_test::TestMode encoding_mode_;
|
||||||
int set_cpu_used_;
|
int set_cpu_used_;
|
||||||
|
int row_mt_mode_;
|
||||||
|
double psnr_;
|
||||||
|
unsigned int nframes_;
|
||||||
std::vector<std::string> md5_;
|
std::vector<std::string> md5_;
|
||||||
};
|
};
|
||||||
|
|
||||||
TEST_P(VPxEncoderThreadTest, EncoderResultTest) {
|
TEST_P(VPxEncoderThreadTest, EncoderResultTest) {
|
||||||
std::vector<std::string> single_thr_md5, multi_thr_md5;
|
|
||||||
|
|
||||||
::libvpx_test::Y4mVideoSource video("niklas_1280_720_30.y4m", 15, 20);
|
::libvpx_test::Y4mVideoSource video("niklas_1280_720_30.y4m", 15, 20);
|
||||||
|
|
||||||
cfg_.rc_target_bitrate = 1000;
|
cfg_.rc_target_bitrate = 1000;
|
||||||
|
|
||||||
|
// 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;
|
||||||
|
|
||||||
// Encode using single thread.
|
// Encode using single thread.
|
||||||
cfg_.g_threads = 1;
|
cfg_.g_threads = 1;
|
||||||
init_flags_ = VPX_CODEC_USE_PSNR;
|
init_flags_ = VPX_CODEC_USE_PSNR;
|
||||||
ASSERT_NO_FATAL_FAILURE(RunLoop(&video));
|
ASSERT_NO_FATAL_FAILURE(RunLoop(&video));
|
||||||
single_thr_md5 = md5_;
|
const std::vector<std::string> single_thr_md5 = md5_;
|
||||||
md5_.clear();
|
md5_.clear();
|
||||||
|
|
||||||
// Encode using multiple threads.
|
// Encode using multiple threads.
|
||||||
cfg_.g_threads = 4;
|
cfg_.g_threads = threads_;
|
||||||
ASSERT_NO_FATAL_FAILURE(RunLoop(&video));
|
ASSERT_NO_FATAL_FAILURE(RunLoop(&video));
|
||||||
multi_thr_md5 = md5_;
|
const std::vector<std::string> multi_thr_md5 = md5_;
|
||||||
md5_.clear();
|
md5_.clear();
|
||||||
|
|
||||||
// Compare to check if two vectors are equal.
|
// Compare to check if two vectors are equal.
|
||||||
ASSERT_EQ(single_thr_md5, multi_thr_md5);
|
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);
|
||||||
}
|
}
|
||||||
|
|
||||||
VP9_INSTANTIATE_TEST_CASE(VPxEncoderThreadTest,
|
INSTANTIATE_TEST_CASE_P(
|
||||||
::testing::Values(::libvpx_test::kTwoPassGood,
|
VP9, VPxFirstPassEncoderThreadTest,
|
||||||
::libvpx_test::kOnePassGood,
|
::testing::Combine(
|
||||||
::libvpx_test::kRealTime),
|
::testing::Values(
|
||||||
::testing::Range(1, 9));
|
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
|
||||||
|
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
|
@ -1,217 +0,0 @@
|
||||||
/*
|
|
||||||
* 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
|
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,97 @@
|
||||||
|
/*
|
||||||
|
* 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,9 +14,11 @@
|
||||||
|
|
||||||
#include "third_party/googletest/src/include/gtest/gtest.h"
|
#include "third_party/googletest/src/include/gtest/gtest.h"
|
||||||
|
|
||||||
|
#include "./vp9_rtcd.h"
|
||||||
#include "./vpx_config.h"
|
#include "./vpx_config.h"
|
||||||
#include "./vpx_dsp_rtcd.h"
|
#include "./vpx_dsp_rtcd.h"
|
||||||
#include "test/acm_random.h"
|
#include "test/acm_random.h"
|
||||||
|
#include "test/buffer.h"
|
||||||
#include "test/clear_system_state.h"
|
#include "test/clear_system_state.h"
|
||||||
#include "test/register_state_check.h"
|
#include "test/register_state_check.h"
|
||||||
#include "test/util.h"
|
#include "test/util.h"
|
||||||
|
@ -24,11 +26,12 @@
|
||||||
#include "vp9/common/vp9_scan.h"
|
#include "vp9/common/vp9_scan.h"
|
||||||
#include "vpx/vpx_codec.h"
|
#include "vpx/vpx_codec.h"
|
||||||
#include "vpx/vpx_integer.h"
|
#include "vpx/vpx_integer.h"
|
||||||
|
#include "vpx_ports/vpx_timer.h"
|
||||||
|
|
||||||
using libvpx_test::ACMRandom;
|
using libvpx_test::ACMRandom;
|
||||||
|
using libvpx_test::Buffer;
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
#if CONFIG_VP9_HIGHBITDEPTH
|
|
||||||
const int number_of_iterations = 100;
|
const int number_of_iterations = 100;
|
||||||
|
|
||||||
typedef void (*QuantizeFunc)(const tran_low_t *coeff, intptr_t count,
|
typedef void (*QuantizeFunc)(const tran_low_t *coeff, intptr_t count,
|
||||||
|
@ -38,307 +41,494 @@ typedef void (*QuantizeFunc)(const tran_low_t *coeff, intptr_t count,
|
||||||
tran_low_t *dqcoeff, const int16_t *dequant,
|
tran_low_t *dqcoeff, const int16_t *dequant,
|
||||||
uint16_t *eob, const int16_t *scan,
|
uint16_t *eob, const int16_t *scan,
|
||||||
const int16_t *iscan);
|
const int16_t *iscan);
|
||||||
typedef std::tr1::tuple<QuantizeFunc, QuantizeFunc, vpx_bit_depth_t>
|
typedef std::tr1::tuple<QuantizeFunc, QuantizeFunc, vpx_bit_depth_t,
|
||||||
|
int /*max_size*/, bool /*is_fp*/>
|
||||||
QuantizeParam;
|
QuantizeParam;
|
||||||
|
|
||||||
class VP9QuantizeTest : public ::testing::TestWithParam<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 {
|
||||||
public:
|
public:
|
||||||
virtual ~VP9QuantizeTest() {}
|
VP9QuantizeBase(vpx_bit_depth_t bit_depth, int max_size, bool is_fp)
|
||||||
virtual void SetUp() {
|
: bit_depth_(bit_depth), max_size_(max_size), is_fp_(is_fp) {
|
||||||
quantize_op_ = GET_PARAM(0);
|
max_value_ = (1 << bit_depth_) - 1;
|
||||||
ref_quantize_op_ = GET_PARAM(1);
|
zbin_ptr_ =
|
||||||
bit_depth_ = GET_PARAM(2);
|
reinterpret_cast<int16_t *>(vpx_memalign(16, 8 * sizeof(*zbin_ptr_)));
|
||||||
mask_ = (1 << bit_depth_) - 1;
|
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 void TearDown() { libvpx_test::ClearSystemState(); }
|
~VP9QuantizeBase() {
|
||||||
|
vpx_free(zbin_ptr_);
|
||||||
protected:
|
vpx_free(round_fp_ptr_);
|
||||||
vpx_bit_depth_t bit_depth_;
|
vpx_free(quant_fp_ptr_);
|
||||||
int mask_;
|
vpx_free(round_ptr_);
|
||||||
QuantizeFunc quantize_op_;
|
vpx_free(quant_ptr_);
|
||||||
QuantizeFunc ref_quantize_op_;
|
vpx_free(quant_shift_ptr_);
|
||||||
};
|
vpx_free(dequant_ptr_);
|
||||||
|
zbin_ptr_ = NULL;
|
||||||
class VP9Quantize32Test : public ::testing::TestWithParam<QuantizeParam> {
|
round_fp_ptr_ = NULL;
|
||||||
public:
|
quant_fp_ptr_ = NULL;
|
||||||
virtual ~VP9Quantize32Test() {}
|
round_ptr_ = NULL;
|
||||||
virtual void SetUp() {
|
quant_ptr_ = NULL;
|
||||||
quantize_op_ = GET_PARAM(0);
|
quant_shift_ptr_ = NULL;
|
||||||
ref_quantize_op_ = GET_PARAM(1);
|
dequant_ptr_ = NULL;
|
||||||
bit_depth_ = GET_PARAM(2);
|
libvpx_test::ClearSystemState();
|
||||||
mask_ = (1 << bit_depth_) - 1;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
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_;
|
||||||
|
};
|
||||||
|
|
||||||
|
class VP9QuantizeTest : public VP9QuantizeBase,
|
||||||
|
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)) {}
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
vpx_bit_depth_t bit_depth_;
|
const QuantizeFunc quantize_op_;
|
||||||
int mask_;
|
const QuantizeFunc ref_quantize_op_;
|
||||||
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().
|
||||||
|
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) {
|
||||||
|
int i, eob = -1;
|
||||||
|
const int thr = dequant_ptr[1] >> 1;
|
||||||
|
(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 =
|
||||||
|
clamp(abs_coeff[y] + round_ptr[rc != 0], INT16_MIN, INT16_MAX);
|
||||||
|
tmp = (tmp * quant_ptr[rc != 0]) >> 16;
|
||||||
|
qcoeff_ptr[rc] = (tmp ^ coeff_sign[y]) - coeff_sign[y];
|
||||||
|
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 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) {
|
TEST_P(VP9QuantizeTest, OperationCheck) {
|
||||||
ACMRandom rnd(ACMRandom::DeterministicSeed());
|
ACMRandom rnd(ACMRandom::DeterministicSeed());
|
||||||
DECLARE_ALIGNED(16, tran_low_t, coeff_ptr[256]);
|
Buffer<tran_low_t> coeff = Buffer<tran_low_t>(max_size_, max_size_, 0, 16);
|
||||||
DECLARE_ALIGNED(16, int16_t, zbin_ptr[2]);
|
ASSERT_TRUE(coeff.Init());
|
||||||
DECLARE_ALIGNED(16, int16_t, round_ptr[2]);
|
Buffer<tran_low_t> qcoeff = Buffer<tran_low_t>(max_size_, max_size_, 0, 32);
|
||||||
DECLARE_ALIGNED(16, int16_t, quant_ptr[2]);
|
ASSERT_TRUE(qcoeff.Init());
|
||||||
DECLARE_ALIGNED(16, int16_t, quant_shift_ptr[2]);
|
Buffer<tran_low_t> dqcoeff = Buffer<tran_low_t>(max_size_, max_size_, 0, 32);
|
||||||
DECLARE_ALIGNED(16, tran_low_t, qcoeff_ptr[256]);
|
ASSERT_TRUE(dqcoeff.Init());
|
||||||
DECLARE_ALIGNED(16, tran_low_t, dqcoeff_ptr[256]);
|
Buffer<tran_low_t> ref_qcoeff =
|
||||||
DECLARE_ALIGNED(16, tran_low_t, ref_qcoeff_ptr[256]);
|
Buffer<tran_low_t>(max_size_, max_size_, 0, 32);
|
||||||
DECLARE_ALIGNED(16, tran_low_t, ref_dqcoeff_ptr[256]);
|
ASSERT_TRUE(ref_qcoeff.Init());
|
||||||
DECLARE_ALIGNED(16, int16_t, dequant_ptr[2]);
|
Buffer<tran_low_t> ref_dqcoeff =
|
||||||
DECLARE_ALIGNED(16, uint16_t, eob_ptr[1]);
|
Buffer<tran_low_t>(max_size_, max_size_, 0, 32);
|
||||||
DECLARE_ALIGNED(16, uint16_t, ref_eob_ptr[1]);
|
ASSERT_TRUE(ref_dqcoeff.Init());
|
||||||
int err_count_total = 0;
|
uint16_t eob, ref_eob;
|
||||||
int first_failure = -1;
|
|
||||||
for (int i = 0; i < number_of_iterations; ++i) {
|
|
||||||
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); // 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) {
|
for (int i = 0; i < number_of_iterations; ++i) {
|
||||||
const int skip_block = i == 0;
|
// Test skip block for the first three iterations to catch all the different
|
||||||
const TX_SIZE sz = TX_32X32;
|
// sizes.
|
||||||
const TX_TYPE tx_type = (TX_TYPE)(i % 4);
|
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 scan_order *scan_order = &vp9_scan_orders[sz][tx_type];
|
const scan_order *scan_order = &vp9_scan_orders[sz][tx_type];
|
||||||
const int count = (4 << sz) * (4 << sz); // 1024
|
const int count = (4 << sz) * (4 << sz);
|
||||||
int err_count = 0;
|
coeff.Set(&rnd, -max_value_, max_value_);
|
||||||
*eob_ptr = rnd.Rand16();
|
GenerateHelperArrays(&rnd, zbin_ptr_, round_ptr_, quant_ptr_,
|
||||||
*ref_eob_ptr = *eob_ptr;
|
quant_shift_ptr_, dequant_ptr_, round_fp_ptr_,
|
||||||
for (int j = 0; j < count; j++) {
|
quant_fp_ptr_);
|
||||||
coeff_ptr[j] = rnd.Rand16() & mask_;
|
int16_t *r_ptr = (is_fp_) ? round_fp_ptr_ : round_ptr_;
|
||||||
}
|
int16_t *q_ptr = (is_fp_) ? quant_fp_ptr_ : quant_ptr_;
|
||||||
for (int j = 0; j < 2; j++) {
|
ref_quantize_op_(coeff.TopLeftPixel(), count, skip_block, zbin_ptr_, r_ptr,
|
||||||
zbin_ptr[j] = rnd.Rand16() & mask_;
|
q_ptr, quant_shift_ptr_, ref_qcoeff.TopLeftPixel(),
|
||||||
round_ptr[j] = rnd.Rand16();
|
ref_dqcoeff.TopLeftPixel(), dequant_ptr_, &ref_eob,
|
||||||
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);
|
scan_order->scan, scan_order->iscan);
|
||||||
|
|
||||||
ASM_REGISTER_STATE_CHECK(quantize_op_(
|
ASM_REGISTER_STATE_CHECK(quantize_op_(
|
||||||
coeff_ptr, count, skip_block, zbin_ptr, round_ptr, quant_ptr,
|
coeff.TopLeftPixel(), count, skip_block, zbin_ptr_, r_ptr, q_ptr,
|
||||||
quant_shift_ptr, qcoeff_ptr, dqcoeff_ptr, dequant_ptr, eob_ptr,
|
quant_shift_ptr_, qcoeff.TopLeftPixel(), dqcoeff.TopLeftPixel(),
|
||||||
scan_order->scan, scan_order->iscan));
|
dequant_ptr_, &eob, scan_order->scan, scan_order->iscan));
|
||||||
for (int j = 0; j < sz; ++j) {
|
|
||||||
err_count += (ref_qcoeff_ptr[j] != qcoeff_ptr[j]) |
|
EXPECT_TRUE(qcoeff.CheckValues(ref_qcoeff));
|
||||||
(ref_dqcoeff_ptr[j] != dqcoeff_ptr[j]);
|
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;
|
||||||
}
|
}
|
||||||
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) {
|
TEST_P(VP9QuantizeTest, EOBCheck) {
|
||||||
ACMRandom rnd(ACMRandom::DeterministicSeed());
|
ACMRandom rnd(ACMRandom::DeterministicSeed());
|
||||||
DECLARE_ALIGNED(16, tran_low_t, coeff_ptr[256]);
|
Buffer<tran_low_t> coeff = Buffer<tran_low_t>(max_size_, max_size_, 0, 16);
|
||||||
DECLARE_ALIGNED(16, int16_t, zbin_ptr[2]);
|
ASSERT_TRUE(coeff.Init());
|
||||||
DECLARE_ALIGNED(16, int16_t, round_ptr[2]);
|
Buffer<tran_low_t> qcoeff = Buffer<tran_low_t>(max_size_, max_size_, 0, 32);
|
||||||
DECLARE_ALIGNED(16, int16_t, quant_ptr[2]);
|
ASSERT_TRUE(qcoeff.Init());
|
||||||
DECLARE_ALIGNED(16, int16_t, quant_shift_ptr[2]);
|
Buffer<tran_low_t> dqcoeff = Buffer<tran_low_t>(max_size_, max_size_, 0, 32);
|
||||||
DECLARE_ALIGNED(16, tran_low_t, qcoeff_ptr[256]);
|
ASSERT_TRUE(dqcoeff.Init());
|
||||||
DECLARE_ALIGNED(16, tran_low_t, dqcoeff_ptr[256]);
|
Buffer<tran_low_t> ref_qcoeff =
|
||||||
DECLARE_ALIGNED(16, tran_low_t, ref_qcoeff_ptr[256]);
|
Buffer<tran_low_t>(max_size_, max_size_, 0, 32);
|
||||||
DECLARE_ALIGNED(16, tran_low_t, ref_dqcoeff_ptr[256]);
|
ASSERT_TRUE(ref_qcoeff.Init());
|
||||||
DECLARE_ALIGNED(16, int16_t, dequant_ptr[2]);
|
Buffer<tran_low_t> ref_dqcoeff =
|
||||||
DECLARE_ALIGNED(16, uint16_t, eob_ptr[1]);
|
Buffer<tran_low_t>(max_size_, max_size_, 0, 32);
|
||||||
DECLARE_ALIGNED(16, uint16_t, ref_eob_ptr[1]);
|
ASSERT_TRUE(ref_dqcoeff.Init());
|
||||||
int err_count_total = 0;
|
uint16_t eob, ref_eob;
|
||||||
int first_failure = -1;
|
|
||||||
for (int i = 0; i < number_of_iterations; ++i) {
|
for (int i = 0; i < number_of_iterations; ++i) {
|
||||||
int skip_block = i == 0;
|
const int skip_block = 0;
|
||||||
TX_SIZE sz = (TX_SIZE)(i % 3); // TX_4X4, TX_8X8 TX_16X16
|
TX_SIZE sz;
|
||||||
TX_TYPE tx_type = (TX_TYPE)((i >> 2) % 3);
|
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 scan_order *scan_order = &vp9_scan_orders[sz][tx_type];
|
const scan_order *scan_order = &vp9_scan_orders[sz][tx_type];
|
||||||
int count = (4 << sz) * (4 << sz); // 16, 64, 256
|
int count = (4 << sz) * (4 << sz);
|
||||||
int err_count = 0;
|
|
||||||
*eob_ptr = rnd.Rand16();
|
|
||||||
*ref_eob_ptr = *eob_ptr;
|
|
||||||
// Two random entries
|
// Two random entries
|
||||||
for (int j = 0; j < count; j++) {
|
coeff.Set(0);
|
||||||
coeff_ptr[j] = 0;
|
coeff.TopLeftPixel()[rnd(count)] =
|
||||||
}
|
static_cast<int>(rnd.RandRange(max_value_ * 2)) - max_value_;
|
||||||
coeff_ptr[rnd(count)] = rnd.Rand16() & mask_;
|
coeff.TopLeftPixel()[rnd(count)] =
|
||||||
coeff_ptr[rnd(count)] = rnd.Rand16() & mask_;
|
static_cast<int>(rnd.RandRange(max_value_ * 2)) - max_value_;
|
||||||
for (int j = 0; j < 2; j++) {
|
GenerateHelperArrays(&rnd, zbin_ptr_, round_ptr_, quant_ptr_,
|
||||||
zbin_ptr[j] = rnd.Rand16() & mask_;
|
quant_shift_ptr_, dequant_ptr_, round_fp_ptr_,
|
||||||
round_ptr[j] = rnd.Rand16();
|
quant_fp_ptr_);
|
||||||
quant_ptr[j] = rnd.Rand16();
|
int16_t *r_ptr = (is_fp_) ? round_fp_ptr_ : round_ptr_;
|
||||||
quant_shift_ptr[j] = rnd.Rand16();
|
int16_t *q_ptr = (is_fp_) ? quant_fp_ptr_ : quant_ptr_;
|
||||||
dequant_ptr[j] = rnd.Rand16();
|
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,
|
||||||
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);
|
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) {
|
ASM_REGISTER_STATE_CHECK(quantize_op_(
|
||||||
err_count += (ref_qcoeff_ptr[j] != qcoeff_ptr[j]) |
|
coeff.TopLeftPixel(), count, skip_block, zbin_ptr_, r_ptr, q_ptr,
|
||||||
(ref_dqcoeff_ptr[j] != dqcoeff_ptr[j]);
|
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;
|
||||||
}
|
}
|
||||||
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, EOBCheck) {
|
TEST_P(VP9QuantizeTest, DISABLED_Speed) {
|
||||||
ACMRandom rnd(ACMRandom::DeterministicSeed());
|
ACMRandom rnd(ACMRandom::DeterministicSeed());
|
||||||
DECLARE_ALIGNED(16, tran_low_t, coeff_ptr[1024]);
|
Buffer<tran_low_t> coeff = Buffer<tran_low_t>(max_size_, max_size_, 0, 16);
|
||||||
DECLARE_ALIGNED(16, int16_t, zbin_ptr[2]);
|
ASSERT_TRUE(coeff.Init());
|
||||||
DECLARE_ALIGNED(16, int16_t, round_ptr[2]);
|
Buffer<tran_low_t> qcoeff = Buffer<tran_low_t>(max_size_, max_size_, 0, 32);
|
||||||
DECLARE_ALIGNED(16, int16_t, quant_ptr[2]);
|
ASSERT_TRUE(qcoeff.Init());
|
||||||
DECLARE_ALIGNED(16, int16_t, quant_shift_ptr[2]);
|
Buffer<tran_low_t> dqcoeff = Buffer<tran_low_t>(max_size_, max_size_, 0, 32);
|
||||||
DECLARE_ALIGNED(16, tran_low_t, qcoeff_ptr[1024]);
|
ASSERT_TRUE(dqcoeff.Init());
|
||||||
DECLARE_ALIGNED(16, tran_low_t, dqcoeff_ptr[1024]);
|
uint16_t eob;
|
||||||
DECLARE_ALIGNED(16, tran_low_t, ref_qcoeff_ptr[1024]);
|
TX_SIZE starting_sz, ending_sz;
|
||||||
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();
|
|
||||||
}
|
|
||||||
|
|
||||||
ref_quantize_op_(coeff_ptr, count, skip_block, zbin_ptr, round_ptr,
|
if (max_size_ == 16) {
|
||||||
quant_ptr, quant_shift_ptr, ref_qcoeff_ptr,
|
starting_sz = TX_4X4;
|
||||||
ref_dqcoeff_ptr, dequant_ptr, ref_eob_ptr,
|
ending_sz = TX_16X16;
|
||||||
scan_order->scan, scan_order->iscan);
|
} else {
|
||||||
ASM_REGISTER_STATE_CHECK(quantize_op_(
|
starting_sz = TX_32X32;
|
||||||
coeff_ptr, count, skip_block, zbin_ptr, round_ptr, quant_ptr,
|
ending_sz = TX_32X32;
|
||||||
quant_shift_ptr, qcoeff_ptr, dqcoeff_ptr, dequant_ptr, eob_ptr,
|
}
|
||||||
scan_order->scan, scan_order->iscan));
|
|
||||||
|
for (TX_SIZE sz = starting_sz; sz <= ending_sz; ++sz) {
|
||||||
for (int j = 0; j < sz; ++j) {
|
// zbin > coeff, zbin < coeff.
|
||||||
err_count += (ref_qcoeff_ptr[j] != qcoeff_ptr[j]) |
|
for (int i = 0; i < 2; ++i) {
|
||||||
(ref_dqcoeff_ptr[j] != dqcoeff_ptr[j]);
|
const int skip_block = 0;
|
||||||
}
|
// TX_TYPE defines the scan order. That is not relevant to the speed test.
|
||||||
err_count += (*ref_eob_ptr != *eob_ptr);
|
// Pick the first one.
|
||||||
if (err_count && !err_count_total) {
|
const TX_TYPE tx_type = DCT_DCT;
|
||||||
first_failure = i;
|
const scan_order *scan_order = &vp9_scan_orders[sz][tx_type];
|
||||||
}
|
const int count = (4 << sz) * (4 << sz);
|
||||||
err_count_total += err_count;
|
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
printf("\n");
|
||||||
}
|
}
|
||||||
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;
|
using std::tr1::make_tuple;
|
||||||
|
|
||||||
#if HAVE_SSE2
|
#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(
|
INSTANTIATE_TEST_CASE_P(
|
||||||
SSE2, VP9QuantizeTest,
|
SSE2, VP9QuantizeTest,
|
||||||
::testing::Values(make_tuple(&vpx_highbd_quantize_b_sse2,
|
::testing::Values(
|
||||||
&vpx_highbd_quantize_b_c, VPX_BITS_8),
|
make_tuple(&vpx_highbd_quantize_b_sse2, &vpx_highbd_quantize_b_c,
|
||||||
make_tuple(&vpx_highbd_quantize_b_sse2,
|
VPX_BITS_8, 16, false),
|
||||||
&vpx_highbd_quantize_b_c, VPX_BITS_10),
|
make_tuple(&vpx_highbd_quantize_b_sse2, &vpx_highbd_quantize_b_c,
|
||||||
make_tuple(&vpx_highbd_quantize_b_sse2,
|
VPX_BITS_10, 16, false),
|
||||||
&vpx_highbd_quantize_b_c, VPX_BITS_12)));
|
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
|
||||||
INSTANTIATE_TEST_CASE_P(
|
INSTANTIATE_TEST_CASE_P(
|
||||||
SSE2, VP9Quantize32Test,
|
SSE2, VP9QuantizeTest,
|
||||||
::testing::Values(make_tuple(&vpx_highbd_quantize_b_32x32_sse2,
|
::testing::Values(make_tuple(&vpx_quantize_b_sse2, &vpx_quantize_b_c,
|
||||||
&vpx_highbd_quantize_b_32x32_c, VPX_BITS_8),
|
VPX_BITS_8, 16, false),
|
||||||
make_tuple(&vpx_highbd_quantize_b_32x32_sse2,
|
make_tuple(&QuantFPWrapper<vp9_quantize_fp_sse2>,
|
||||||
&vpx_highbd_quantize_b_32x32_c, VPX_BITS_10),
|
&QuantFPWrapper<quantize_fp_nz_c>, VPX_BITS_8,
|
||||||
make_tuple(&vpx_highbd_quantize_b_32x32_sse2,
|
16, true)));
|
||||||
&vpx_highbd_quantize_b_32x32_c, VPX_BITS_12)));
|
|
||||||
#endif // HAVE_SSE2
|
|
||||||
#endif // CONFIG_VP9_HIGHBITDEPTH
|
#endif // CONFIG_VP9_HIGHBITDEPTH
|
||||||
|
#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)));
|
||||||
|
#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),
|
||||||
|
make_tuple(&QuantFPWrapper<vp9_quantize_fp_32x32_ssse3>,
|
||||||
|
&QuantFPWrapper<vp9_quantize_fp_32x32_c>,
|
||||||
|
VPX_BITS_8, 32, true)));
|
||||||
|
#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
|
||||||
|
|
||||||
|
// 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<vp9_quantize_fp_32x32_c>,
|
||||||
|
&QuantFPWrapper<vp9_quantize_fp_32x32_c>, VPX_BITS_8, 32,
|
||||||
|
true)));
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
|
@ -0,0 +1,214 @@
|
||||||
|
/*
|
||||||
|
* 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() {
|
||||||
|
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 (INTERP_FILTER filter_type = 0; filter_type < 4; ++filter_type) {
|
||||||
|
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) { ASSERT_NO_FATAL_FAILURE(RunTest()); }
|
||||||
|
|
||||||
|
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
|
|
@ -85,8 +85,8 @@ class SkipLoopFilterTest {
|
||||||
// TODO(fgalligan): Move the MD5 testing code into another class.
|
// TODO(fgalligan): Move the MD5 testing code into another class.
|
||||||
void OpenMd5File(const std::string &md5_file_name) {
|
void OpenMd5File(const std::string &md5_file_name) {
|
||||||
md5_file_ = libvpx_test::OpenTestDataFile(md5_file_name);
|
md5_file_ = libvpx_test::OpenTestDataFile(md5_file_name);
|
||||||
ASSERT_TRUE(md5_file_ != NULL) << "MD5 file open failed. Filename: "
|
ASSERT_TRUE(md5_file_ != NULL)
|
||||||
<< md5_file_name;
|
<< "MD5 file open failed. Filename: " << md5_file_name;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Reads the next line of the MD5 file.
|
// Reads the next line of the MD5 file.
|
||||||
|
|
|
@ -101,4 +101,9 @@ INSTANTIATE_TEST_CASE_P(MSA, VP9SubtractBlockTest,
|
||||||
::testing::Values(vpx_subtract_block_msa));
|
::testing::Values(vpx_subtract_block_msa));
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if HAVE_MMI
|
||||||
|
INSTANTIATE_TEST_CASE_P(MMI, VP9SubtractBlockTest,
|
||||||
|
::testing::Values(vpx_subtract_block_mmi));
|
||||||
|
#endif
|
||||||
|
|
||||||
} // namespace vp9
|
} // namespace vp9
|
||||||
|
|
|
@ -187,8 +187,8 @@ void DecodeFiles(const FileList files[]) {
|
||||||
for (const FileList *iter = files; iter->name != NULL; ++iter) {
|
for (const FileList *iter = files; iter->name != NULL; ++iter) {
|
||||||
SCOPED_TRACE(iter->name);
|
SCOPED_TRACE(iter->name);
|
||||||
for (int t = 1; t <= 8; ++t) {
|
for (int t = 1; t <= 8; ++t) {
|
||||||
EXPECT_EQ(iter->expected_md5, DecodeFile(iter->name, t)) << "threads = "
|
EXPECT_EQ(iter->expected_md5, DecodeFile(iter->name, t))
|
||||||
<< t;
|
<< "threads = " << t;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -14,149 +14,17 @@
|
||||||
#include "./vpx_scale_rtcd.h"
|
#include "./vpx_scale_rtcd.h"
|
||||||
#include "test/clear_system_state.h"
|
#include "test/clear_system_state.h"
|
||||||
#include "test/register_state_check.h"
|
#include "test/register_state_check.h"
|
||||||
|
#include "test/vpx_scale_test.h"
|
||||||
#include "vpx_mem/vpx_mem.h"
|
#include "vpx_mem/vpx_mem.h"
|
||||||
|
#include "vpx_ports/vpx_timer.h"
|
||||||
#include "vpx_scale/yv12config.h"
|
#include "vpx_scale/yv12config.h"
|
||||||
|
|
||||||
namespace {
|
namespace libvpx_test {
|
||||||
|
|
||||||
typedef void (*ExtendFrameBorderFunc)(YV12_BUFFER_CONFIG *ybf);
|
typedef void (*ExtendFrameBorderFunc)(YV12_BUFFER_CONFIG *ybf);
|
||||||
typedef void (*CopyFrameFunc)(const YV12_BUFFER_CONFIG *src_ybf,
|
typedef void (*CopyFrameFunc)(const YV12_BUFFER_CONFIG *src_ybf,
|
||||||
YV12_BUFFER_CONFIG *dst_ybf);
|
YV12_BUFFER_CONFIG *dst_ybf);
|
||||||
|
|
||||||
class VpxScaleBase {
|
|
||||||
public:
|
|
||||||
virtual ~VpxScaleBase() { libvpx_test::ClearSystemState(); }
|
|
||||||
|
|
||||||
void ResetImage(int width, int height) {
|
|
||||||
width_ = width;
|
|
||||||
height_ = height;
|
|
||||||
memset(&img_, 0, sizeof(img_));
|
|
||||||
ASSERT_EQ(0, vp8_yv12_alloc_frame_buffer(&img_, width_, height_,
|
|
||||||
VP8BORDERINPIXELS));
|
|
||||||
memset(img_.buffer_alloc, kBufFiller, img_.frame_size);
|
|
||||||
FillPlane(img_.y_buffer, img_.y_crop_width, img_.y_crop_height,
|
|
||||||
img_.y_stride);
|
|
||||||
FillPlane(img_.u_buffer, img_.uv_crop_width, img_.uv_crop_height,
|
|
||||||
img_.uv_stride);
|
|
||||||
FillPlane(img_.v_buffer, img_.uv_crop_width, img_.uv_crop_height,
|
|
||||||
img_.uv_stride);
|
|
||||||
|
|
||||||
memset(&ref_img_, 0, sizeof(ref_img_));
|
|
||||||
ASSERT_EQ(0, vp8_yv12_alloc_frame_buffer(&ref_img_, width_, height_,
|
|
||||||
VP8BORDERINPIXELS));
|
|
||||||
memset(ref_img_.buffer_alloc, kBufFiller, ref_img_.frame_size);
|
|
||||||
|
|
||||||
memset(&cpy_img_, 0, sizeof(cpy_img_));
|
|
||||||
ASSERT_EQ(0, vp8_yv12_alloc_frame_buffer(&cpy_img_, width_, height_,
|
|
||||||
VP8BORDERINPIXELS));
|
|
||||||
memset(cpy_img_.buffer_alloc, kBufFiller, cpy_img_.frame_size);
|
|
||||||
ReferenceCopyFrame();
|
|
||||||
}
|
|
||||||
|
|
||||||
void DeallocImage() {
|
|
||||||
vp8_yv12_de_alloc_frame_buffer(&img_);
|
|
||||||
vp8_yv12_de_alloc_frame_buffer(&ref_img_);
|
|
||||||
vp8_yv12_de_alloc_frame_buffer(&cpy_img_);
|
|
||||||
}
|
|
||||||
|
|
||||||
protected:
|
|
||||||
static const int kBufFiller = 123;
|
|
||||||
static const int kBufMax = kBufFiller - 1;
|
|
||||||
|
|
||||||
static void FillPlane(uint8_t *buf, int width, int height, int stride) {
|
|
||||||
for (int y = 0; y < height; ++y) {
|
|
||||||
for (int x = 0; x < width; ++x) {
|
|
||||||
buf[x + (y * stride)] = (x + (width * y)) % kBufMax;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static void ExtendPlane(uint8_t *buf, int crop_width, int crop_height,
|
|
||||||
int width, int height, int stride, int padding) {
|
|
||||||
// Copy the outermost visible pixel to a distance of at least 'padding.'
|
|
||||||
// The buffers are allocated such that there may be excess space outside the
|
|
||||||
// padding. As long as the minimum amount of padding is achieved it is not
|
|
||||||
// necessary to fill this space as well.
|
|
||||||
uint8_t *left = buf - padding;
|
|
||||||
uint8_t *right = buf + crop_width;
|
|
||||||
const int right_extend = padding + (width - crop_width);
|
|
||||||
const int bottom_extend = padding + (height - crop_height);
|
|
||||||
|
|
||||||
// Fill the border pixels from the nearest image pixel.
|
|
||||||
for (int y = 0; y < crop_height; ++y) {
|
|
||||||
memset(left, left[padding], padding);
|
|
||||||
memset(right, right[-1], right_extend);
|
|
||||||
left += stride;
|
|
||||||
right += stride;
|
|
||||||
}
|
|
||||||
|
|
||||||
left = buf - padding;
|
|
||||||
uint8_t *top = left - (stride * padding);
|
|
||||||
// The buffer does not always extend as far as the stride.
|
|
||||||
// Equivalent to padding + width + padding.
|
|
||||||
const int extend_width = padding + crop_width + right_extend;
|
|
||||||
|
|
||||||
// The first row was already extended to the left and right. Copy it up.
|
|
||||||
for (int y = 0; y < padding; ++y) {
|
|
||||||
memcpy(top, left, extend_width);
|
|
||||||
top += stride;
|
|
||||||
}
|
|
||||||
|
|
||||||
uint8_t *bottom = left + (crop_height * stride);
|
|
||||||
for (int y = 0; y < bottom_extend; ++y) {
|
|
||||||
memcpy(bottom, left + (crop_height - 1) * stride, extend_width);
|
|
||||||
bottom += stride;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void ReferenceExtendBorder() {
|
|
||||||
ExtendPlane(ref_img_.y_buffer, ref_img_.y_crop_width,
|
|
||||||
ref_img_.y_crop_height, ref_img_.y_width, ref_img_.y_height,
|
|
||||||
ref_img_.y_stride, ref_img_.border);
|
|
||||||
ExtendPlane(ref_img_.u_buffer, ref_img_.uv_crop_width,
|
|
||||||
ref_img_.uv_crop_height, ref_img_.uv_width, ref_img_.uv_height,
|
|
||||||
ref_img_.uv_stride, ref_img_.border / 2);
|
|
||||||
ExtendPlane(ref_img_.v_buffer, ref_img_.uv_crop_width,
|
|
||||||
ref_img_.uv_crop_height, ref_img_.uv_width, ref_img_.uv_height,
|
|
||||||
ref_img_.uv_stride, ref_img_.border / 2);
|
|
||||||
}
|
|
||||||
|
|
||||||
void ReferenceCopyFrame() {
|
|
||||||
// Copy img_ to ref_img_ and extend frame borders. This will be used for
|
|
||||||
// verifying extend_fn_ as well as copy_frame_fn_.
|
|
||||||
EXPECT_EQ(ref_img_.frame_size, img_.frame_size);
|
|
||||||
for (int y = 0; y < img_.y_crop_height; ++y) {
|
|
||||||
for (int x = 0; x < img_.y_crop_width; ++x) {
|
|
||||||
ref_img_.y_buffer[x + y * ref_img_.y_stride] =
|
|
||||||
img_.y_buffer[x + y * img_.y_stride];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
for (int y = 0; y < img_.uv_crop_height; ++y) {
|
|
||||||
for (int x = 0; x < img_.uv_crop_width; ++x) {
|
|
||||||
ref_img_.u_buffer[x + y * ref_img_.uv_stride] =
|
|
||||||
img_.u_buffer[x + y * img_.uv_stride];
|
|
||||||
ref_img_.v_buffer[x + y * ref_img_.uv_stride] =
|
|
||||||
img_.v_buffer[x + y * img_.uv_stride];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
ReferenceExtendBorder();
|
|
||||||
}
|
|
||||||
|
|
||||||
void CompareImages(const YV12_BUFFER_CONFIG actual) {
|
|
||||||
EXPECT_EQ(ref_img_.frame_size, actual.frame_size);
|
|
||||||
EXPECT_EQ(0, memcmp(ref_img_.buffer_alloc, actual.buffer_alloc,
|
|
||||||
ref_img_.frame_size));
|
|
||||||
}
|
|
||||||
|
|
||||||
YV12_BUFFER_CONFIG img_;
|
|
||||||
YV12_BUFFER_CONFIG ref_img_;
|
|
||||||
YV12_BUFFER_CONFIG cpy_img_;
|
|
||||||
int width_;
|
|
||||||
int height_;
|
|
||||||
};
|
|
||||||
|
|
||||||
class ExtendBorderTest
|
class ExtendBorderTest
|
||||||
: public VpxScaleBase,
|
: public VpxScaleBase,
|
||||||
public ::testing::TestWithParam<ExtendFrameBorderFunc> {
|
public ::testing::TestWithParam<ExtendFrameBorderFunc> {
|
||||||
|
@ -178,11 +46,11 @@ class ExtendBorderTest
|
||||||
static const int kSizesToTest[] = { 1, 15, 33, 145, 512, 1025, 16383 };
|
static const int kSizesToTest[] = { 1, 15, 33, 145, 512, 1025, 16383 };
|
||||||
for (int h = 0; h < kNumSizesToTest; ++h) {
|
for (int h = 0; h < kNumSizesToTest; ++h) {
|
||||||
for (int w = 0; w < kNumSizesToTest; ++w) {
|
for (int w = 0; w < kNumSizesToTest; ++w) {
|
||||||
ResetImage(kSizesToTest[w], kSizesToTest[h]);
|
ASSERT_NO_FATAL_FAILURE(ResetImages(kSizesToTest[w], kSizesToTest[h]));
|
||||||
|
ReferenceCopyFrame();
|
||||||
ExtendBorder();
|
ExtendBorder();
|
||||||
ReferenceExtendBorder();
|
|
||||||
CompareImages(img_);
|
CompareImages(img_);
|
||||||
DeallocImage();
|
DeallocImages();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -204,7 +72,7 @@ class CopyFrameTest : public VpxScaleBase,
|
||||||
virtual void SetUp() { copy_frame_fn_ = GetParam(); }
|
virtual void SetUp() { copy_frame_fn_ = GetParam(); }
|
||||||
|
|
||||||
void CopyFrame() {
|
void CopyFrame() {
|
||||||
ASM_REGISTER_STATE_CHECK(copy_frame_fn_(&img_, &cpy_img_));
|
ASM_REGISTER_STATE_CHECK(copy_frame_fn_(&img_, &dst_img_));
|
||||||
}
|
}
|
||||||
|
|
||||||
void RunTest() {
|
void RunTest() {
|
||||||
|
@ -217,11 +85,11 @@ class CopyFrameTest : public VpxScaleBase,
|
||||||
static const int kSizesToTest[] = { 1, 15, 33, 145, 512, 1025, 16383 };
|
static const int kSizesToTest[] = { 1, 15, 33, 145, 512, 1025, 16383 };
|
||||||
for (int h = 0; h < kNumSizesToTest; ++h) {
|
for (int h = 0; h < kNumSizesToTest; ++h) {
|
||||||
for (int w = 0; w < kNumSizesToTest; ++w) {
|
for (int w = 0; w < kNumSizesToTest; ++w) {
|
||||||
ResetImage(kSizesToTest[w], kSizesToTest[h]);
|
ASSERT_NO_FATAL_FAILURE(ResetImages(kSizesToTest[w], kSizesToTest[h]));
|
||||||
ReferenceCopyFrame();
|
ReferenceCopyFrame();
|
||||||
CopyFrame();
|
CopyFrame();
|
||||||
CompareImages(cpy_img_);
|
CompareImages(dst_img_);
|
||||||
DeallocImage();
|
DeallocImages();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -233,4 +101,5 @@ TEST_P(CopyFrameTest, CopyFrame) { ASSERT_NO_FATAL_FAILURE(RunTest()); }
|
||||||
|
|
||||||
INSTANTIATE_TEST_CASE_P(C, CopyFrameTest,
|
INSTANTIATE_TEST_CASE_P(C, CopyFrameTest,
|
||||||
::testing::Values(vp8_yv12_copy_frame_c));
|
::testing::Values(vp8_yv12_copy_frame_c));
|
||||||
} // namespace
|
|
||||||
|
} // namespace libvpx_test
|
||||||
|
|
|
@ -0,0 +1,200 @@
|
||||||
|
/*
|
||||||
|
* 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef TEST_VPX_SCALE_TEST_H_
|
||||||
|
#define TEST_VPX_SCALE_TEST_H_
|
||||||
|
|
||||||
|
#include "third_party/googletest/src/include/gtest/gtest.h"
|
||||||
|
|
||||||
|
#include "./vpx_config.h"
|
||||||
|
#include "./vpx_scale_rtcd.h"
|
||||||
|
#include "test/acm_random.h"
|
||||||
|
#include "test/clear_system_state.h"
|
||||||
|
#include "test/register_state_check.h"
|
||||||
|
#include "vpx_mem/vpx_mem.h"
|
||||||
|
#include "vpx_scale/yv12config.h"
|
||||||
|
|
||||||
|
using libvpx_test::ACMRandom;
|
||||||
|
|
||||||
|
namespace libvpx_test {
|
||||||
|
|
||||||
|
class VpxScaleBase {
|
||||||
|
public:
|
||||||
|
virtual ~VpxScaleBase() { libvpx_test::ClearSystemState(); }
|
||||||
|
|
||||||
|
void ResetImage(YV12_BUFFER_CONFIG *const img, const int width,
|
||||||
|
const int height) {
|
||||||
|
memset(img, 0, sizeof(*img));
|
||||||
|
ASSERT_EQ(
|
||||||
|
0, vp8_yv12_alloc_frame_buffer(img, width, height, VP8BORDERINPIXELS));
|
||||||
|
memset(img->buffer_alloc, kBufFiller, img->frame_size);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ResetImages(const int width, const int height) {
|
||||||
|
ResetImage(&img_, width, height);
|
||||||
|
ResetImage(&ref_img_, width, height);
|
||||||
|
ResetImage(&dst_img_, width, height);
|
||||||
|
|
||||||
|
FillPlane(img_.y_buffer, img_.y_crop_width, img_.y_crop_height,
|
||||||
|
img_.y_stride);
|
||||||
|
FillPlane(img_.u_buffer, img_.uv_crop_width, img_.uv_crop_height,
|
||||||
|
img_.uv_stride);
|
||||||
|
FillPlane(img_.v_buffer, img_.uv_crop_width, img_.uv_crop_height,
|
||||||
|
img_.uv_stride);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ResetScaleImage(YV12_BUFFER_CONFIG *const img, const int width,
|
||||||
|
const int height) {
|
||||||
|
memset(img, 0, sizeof(*img));
|
||||||
|
#if CONFIG_VP9_HIGHBITDEPTH
|
||||||
|
ASSERT_EQ(0, vpx_alloc_frame_buffer(img, width, height, 1, 1, 0,
|
||||||
|
VP9_ENC_BORDER_IN_PIXELS, 0));
|
||||||
|
#else
|
||||||
|
ASSERT_EQ(0, vpx_alloc_frame_buffer(img, width, height, 1, 1,
|
||||||
|
VP9_ENC_BORDER_IN_PIXELS, 0));
|
||||||
|
#endif
|
||||||
|
memset(img->buffer_alloc, kBufFiller, img->frame_size);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ResetScaleImages(const int src_width, const int src_height,
|
||||||
|
const int dst_width, const int dst_height) {
|
||||||
|
ResetScaleImage(&img_, src_width, src_height);
|
||||||
|
ResetScaleImage(&ref_img_, dst_width, dst_height);
|
||||||
|
ResetScaleImage(&dst_img_, dst_width, dst_height);
|
||||||
|
FillPlaneExtreme(img_.y_buffer, img_.y_crop_width, img_.y_crop_height,
|
||||||
|
img_.y_stride);
|
||||||
|
FillPlaneExtreme(img_.u_buffer, img_.uv_crop_width, img_.uv_crop_height,
|
||||||
|
img_.uv_stride);
|
||||||
|
FillPlaneExtreme(img_.v_buffer, img_.uv_crop_width, img_.uv_crop_height,
|
||||||
|
img_.uv_stride);
|
||||||
|
}
|
||||||
|
|
||||||
|
void DeallocImages() {
|
||||||
|
vp8_yv12_de_alloc_frame_buffer(&img_);
|
||||||
|
vp8_yv12_de_alloc_frame_buffer(&ref_img_);
|
||||||
|
vp8_yv12_de_alloc_frame_buffer(&dst_img_);
|
||||||
|
}
|
||||||
|
|
||||||
|
void DeallocScaleImages() {
|
||||||
|
vpx_free_frame_buffer(&img_);
|
||||||
|
vpx_free_frame_buffer(&ref_img_);
|
||||||
|
vpx_free_frame_buffer(&dst_img_);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected:
|
||||||
|
static const int kBufFiller = 123;
|
||||||
|
static const int kBufMax = kBufFiller - 1;
|
||||||
|
|
||||||
|
static void FillPlane(uint8_t *const buf, const int width, const int height,
|
||||||
|
const int stride) {
|
||||||
|
for (int y = 0; y < height; ++y) {
|
||||||
|
for (int x = 0; x < width; ++x) {
|
||||||
|
buf[x + (y * stride)] = (x + (width * y)) % kBufMax;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void FillPlaneExtreme(uint8_t *const buf, const int width,
|
||||||
|
const int height, const int stride) {
|
||||||
|
ACMRandom rnd;
|
||||||
|
for (int y = 0; y < height; ++y) {
|
||||||
|
for (int x = 0; x < width; ++x) {
|
||||||
|
buf[x + (y * stride)] = rnd.Rand8() % 2 ? 255 : 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void ExtendPlane(uint8_t *buf, int crop_width, int crop_height,
|
||||||
|
int width, int height, int stride, int padding) {
|
||||||
|
// Copy the outermost visible pixel to a distance of at least 'padding.'
|
||||||
|
// The buffers are allocated such that there may be excess space outside the
|
||||||
|
// padding. As long as the minimum amount of padding is achieved it is not
|
||||||
|
// necessary to fill this space as well.
|
||||||
|
uint8_t *left = buf - padding;
|
||||||
|
uint8_t *right = buf + crop_width;
|
||||||
|
const int right_extend = padding + (width - crop_width);
|
||||||
|
const int bottom_extend = padding + (height - crop_height);
|
||||||
|
|
||||||
|
// Fill the border pixels from the nearest image pixel.
|
||||||
|
for (int y = 0; y < crop_height; ++y) {
|
||||||
|
memset(left, left[padding], padding);
|
||||||
|
memset(right, right[-1], right_extend);
|
||||||
|
left += stride;
|
||||||
|
right += stride;
|
||||||
|
}
|
||||||
|
|
||||||
|
left = buf - padding;
|
||||||
|
uint8_t *top = left - (stride * padding);
|
||||||
|
// The buffer does not always extend as far as the stride.
|
||||||
|
// Equivalent to padding + width + padding.
|
||||||
|
const int extend_width = padding + crop_width + right_extend;
|
||||||
|
|
||||||
|
// The first row was already extended to the left and right. Copy it up.
|
||||||
|
for (int y = 0; y < padding; ++y) {
|
||||||
|
memcpy(top, left, extend_width);
|
||||||
|
top += stride;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8_t *bottom = left + (crop_height * stride);
|
||||||
|
for (int y = 0; y < bottom_extend; ++y) {
|
||||||
|
memcpy(bottom, left + (crop_height - 1) * stride, extend_width);
|
||||||
|
bottom += stride;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void ReferenceExtendBorder() {
|
||||||
|
ExtendPlane(ref_img_.y_buffer, ref_img_.y_crop_width,
|
||||||
|
ref_img_.y_crop_height, ref_img_.y_width, ref_img_.y_height,
|
||||||
|
ref_img_.y_stride, ref_img_.border);
|
||||||
|
ExtendPlane(ref_img_.u_buffer, ref_img_.uv_crop_width,
|
||||||
|
ref_img_.uv_crop_height, ref_img_.uv_width, ref_img_.uv_height,
|
||||||
|
ref_img_.uv_stride, ref_img_.border / 2);
|
||||||
|
ExtendPlane(ref_img_.v_buffer, ref_img_.uv_crop_width,
|
||||||
|
ref_img_.uv_crop_height, ref_img_.uv_width, ref_img_.uv_height,
|
||||||
|
ref_img_.uv_stride, ref_img_.border / 2);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ReferenceCopyFrame() {
|
||||||
|
// Copy img_ to ref_img_ and extend frame borders. This will be used for
|
||||||
|
// verifying extend_fn_ as well as copy_frame_fn_.
|
||||||
|
EXPECT_EQ(ref_img_.frame_size, img_.frame_size);
|
||||||
|
for (int y = 0; y < img_.y_crop_height; ++y) {
|
||||||
|
for (int x = 0; x < img_.y_crop_width; ++x) {
|
||||||
|
ref_img_.y_buffer[x + y * ref_img_.y_stride] =
|
||||||
|
img_.y_buffer[x + y * img_.y_stride];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int y = 0; y < img_.uv_crop_height; ++y) {
|
||||||
|
for (int x = 0; x < img_.uv_crop_width; ++x) {
|
||||||
|
ref_img_.u_buffer[x + y * ref_img_.uv_stride] =
|
||||||
|
img_.u_buffer[x + y * img_.uv_stride];
|
||||||
|
ref_img_.v_buffer[x + y * ref_img_.uv_stride] =
|
||||||
|
img_.v_buffer[x + y * img_.uv_stride];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ReferenceExtendBorder();
|
||||||
|
}
|
||||||
|
|
||||||
|
void CompareImages(const YV12_BUFFER_CONFIG actual) {
|
||||||
|
EXPECT_EQ(ref_img_.frame_size, actual.frame_size);
|
||||||
|
EXPECT_EQ(0, memcmp(ref_img_.buffer_alloc, actual.buffer_alloc,
|
||||||
|
ref_img_.frame_size));
|
||||||
|
}
|
||||||
|
|
||||||
|
YV12_BUFFER_CONFIG img_;
|
||||||
|
YV12_BUFFER_CONFIG ref_img_;
|
||||||
|
YV12_BUFFER_CONFIG dst_img_;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace libvpx_test
|
||||||
|
|
||||||
|
#endif // TEST_VPX_SCALE_TEST_H_
|
|
@ -40,6 +40,8 @@ vpx_tsvc_encoder() {
|
||||||
local timebase_den="1000"
|
local timebase_den="1000"
|
||||||
local speed="6"
|
local speed="6"
|
||||||
local frame_drop_thresh="30"
|
local frame_drop_thresh="30"
|
||||||
|
local max_threads="4"
|
||||||
|
local error_resilient="1"
|
||||||
|
|
||||||
shift 2
|
shift 2
|
||||||
|
|
||||||
|
@ -48,11 +50,22 @@ vpx_tsvc_encoder() {
|
||||||
return 1
|
return 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
eval "${VPX_TEST_PREFIX}" "${encoder}" "${YUV_RAW_INPUT}" "${output_file}" \
|
# TODO(tomfinegan): Verify file output for all thread runs.
|
||||||
"${codec}" "${YUV_RAW_INPUT_WIDTH}" "${YUV_RAW_INPUT_HEIGHT}" \
|
for threads in $(seq $max_threads); do
|
||||||
"${timebase_num}" "${timebase_den}" "${speed}" "${frame_drop_thresh}" \
|
if [ "$(vpx_config_option_enabled CONFIG_VP9_HIGHBITDEPTH)" != "yes" ]; then
|
||||||
"$@" \
|
eval "${VPX_TEST_PREFIX}" "${encoder}" "${YUV_RAW_INPUT}" \
|
||||||
${devnull}
|
"${output_file}" "${codec}" "${YUV_RAW_INPUT_WIDTH}" \
|
||||||
|
"${YUV_RAW_INPUT_HEIGHT}" "${timebase_num}" "${timebase_den}" \
|
||||||
|
"${speed}" "${frame_drop_thresh}" "${error_resilient}" "${threads}" \
|
||||||
|
"$@" ${devnull}
|
||||||
|
else
|
||||||
|
eval "${VPX_TEST_PREFIX}" "${encoder}" "${YUV_RAW_INPUT}" \
|
||||||
|
"${output_file}" "${codec}" "${YUV_RAW_INPUT_WIDTH}" \
|
||||||
|
"${YUV_RAW_INPUT_HEIGHT}" "${timebase_num}" "${timebase_den}" \
|
||||||
|
"${speed}" "${frame_drop_thresh}" "${error_resilient}" "${threads}" \
|
||||||
|
"$@" "8" ${devnull}
|
||||||
|
fi
|
||||||
|
done
|
||||||
}
|
}
|
||||||
|
|
||||||
# Confirms that all expected output files exist given the output file name
|
# Confirms that all expected output files exist given the output file name
|
||||||
|
@ -72,193 +85,217 @@ files_exist() {
|
||||||
|
|
||||||
vpx_tsvc_encoder_vp8_mode_0() {
|
vpx_tsvc_encoder_vp8_mode_0() {
|
||||||
if [ "$(vp8_encode_available)" = "yes" ]; then
|
if [ "$(vp8_encode_available)" = "yes" ]; then
|
||||||
vpx_tsvc_encoder vp8 "${FUNCNAME}" 0 200 || return 1
|
local readonly output_basename="vpx_tsvc_encoder_vp8_mode_0"
|
||||||
|
vpx_tsvc_encoder vp8 "${output_basename}" 0 200 || return 1
|
||||||
# Mode 0 produces 1 stream
|
# Mode 0 produces 1 stream
|
||||||
files_exist "${FUNCNAME}" 1 || return 1
|
files_exist "${output_basename}" 1 || return 1
|
||||||
fi
|
fi
|
||||||
}
|
}
|
||||||
|
|
||||||
vpx_tsvc_encoder_vp8_mode_1() {
|
vpx_tsvc_encoder_vp8_mode_1() {
|
||||||
if [ "$(vp8_encode_available)" = "yes" ]; then
|
if [ "$(vp8_encode_available)" = "yes" ]; then
|
||||||
vpx_tsvc_encoder vp8 "${FUNCNAME}" 1 200 400 || return 1
|
local readonly output_basename="vpx_tsvc_encoder_vp8_mode_1"
|
||||||
|
vpx_tsvc_encoder vp8 "${output_basename}" 1 200 400 || return 1
|
||||||
# Mode 1 produces 2 streams
|
# Mode 1 produces 2 streams
|
||||||
files_exist "${FUNCNAME}" 2 || return 1
|
files_exist "${output_basename}" 2 || return 1
|
||||||
fi
|
fi
|
||||||
}
|
}
|
||||||
|
|
||||||
vpx_tsvc_encoder_vp8_mode_2() {
|
vpx_tsvc_encoder_vp8_mode_2() {
|
||||||
if [ "$(vp8_encode_available)" = "yes" ]; then
|
if [ "$(vp8_encode_available)" = "yes" ]; then
|
||||||
vpx_tsvc_encoder vp8 "${FUNCNAME}" 2 200 400 || return 1
|
local readonly output_basename="vpx_tsvc_encoder_vp8_mode_2"
|
||||||
|
vpx_tsvc_encoder vp8 "${output_basename}" 2 200 400 || return 1
|
||||||
# Mode 2 produces 2 streams
|
# Mode 2 produces 2 streams
|
||||||
files_exist "${FUNCNAME}" 2 || return 1
|
files_exist "${output_basename}" 2 || return 1
|
||||||
fi
|
fi
|
||||||
}
|
}
|
||||||
|
|
||||||
vpx_tsvc_encoder_vp8_mode_3() {
|
vpx_tsvc_encoder_vp8_mode_3() {
|
||||||
if [ "$(vp8_encode_available)" = "yes" ]; then
|
if [ "$(vp8_encode_available)" = "yes" ]; then
|
||||||
vpx_tsvc_encoder vp8 "${FUNCNAME}" 3 200 400 600 || return 1
|
local readonly output_basename="vpx_tsvc_encoder_vp8_mode_3"
|
||||||
|
vpx_tsvc_encoder vp8 "${output_basename}" 3 200 400 600 || return 1
|
||||||
# Mode 3 produces 3 streams
|
# Mode 3 produces 3 streams
|
||||||
files_exist "${FUNCNAME}" 3 || return 1
|
files_exist "${output_basename}" 3 || return 1
|
||||||
fi
|
fi
|
||||||
}
|
}
|
||||||
|
|
||||||
vpx_tsvc_encoder_vp8_mode_4() {
|
vpx_tsvc_encoder_vp8_mode_4() {
|
||||||
if [ "$(vp8_encode_available)" = "yes" ]; then
|
if [ "$(vp8_encode_available)" = "yes" ]; then
|
||||||
vpx_tsvc_encoder vp8 "${FUNCNAME}" 4 200 400 600 || return 1
|
local readonly output_basename="vpx_tsvc_encoder_vp8_mode_4"
|
||||||
|
vpx_tsvc_encoder vp8 "${output_basename}" 4 200 400 600 || return 1
|
||||||
# Mode 4 produces 3 streams
|
# Mode 4 produces 3 streams
|
||||||
files_exist "${FUNCNAME}" 3 || return 1
|
files_exist "${output_basename}" 3 || return 1
|
||||||
fi
|
fi
|
||||||
}
|
}
|
||||||
|
|
||||||
vpx_tsvc_encoder_vp8_mode_5() {
|
vpx_tsvc_encoder_vp8_mode_5() {
|
||||||
if [ "$(vp8_encode_available)" = "yes" ]; then
|
if [ "$(vp8_encode_available)" = "yes" ]; then
|
||||||
vpx_tsvc_encoder vp8 "${FUNCNAME}" 5 200 400 600 || return 1
|
local readonly output_basename="vpx_tsvc_encoder_vp8_mode_5"
|
||||||
|
vpx_tsvc_encoder vp8 "${output_basename}" 5 200 400 600 || return 1
|
||||||
# Mode 5 produces 3 streams
|
# Mode 5 produces 3 streams
|
||||||
files_exist "${FUNCNAME}" 3 || return 1
|
files_exist "${output_basename}" 3 || return 1
|
||||||
fi
|
fi
|
||||||
}
|
}
|
||||||
|
|
||||||
vpx_tsvc_encoder_vp8_mode_6() {
|
vpx_tsvc_encoder_vp8_mode_6() {
|
||||||
if [ "$(vp8_encode_available)" = "yes" ]; then
|
if [ "$(vp8_encode_available)" = "yes" ]; then
|
||||||
vpx_tsvc_encoder vp8 "${FUNCNAME}" 6 200 400 600 || return 1
|
local readonly output_basename="vpx_tsvc_encoder_vp8_mode_6"
|
||||||
|
vpx_tsvc_encoder vp8 "${output_basename}" 6 200 400 600 || return 1
|
||||||
# Mode 6 produces 3 streams
|
# Mode 6 produces 3 streams
|
||||||
files_exist "${FUNCNAME}" 3 || return 1
|
files_exist "${output_basename}" 3 || return 1
|
||||||
fi
|
fi
|
||||||
}
|
}
|
||||||
|
|
||||||
vpx_tsvc_encoder_vp8_mode_7() {
|
vpx_tsvc_encoder_vp8_mode_7() {
|
||||||
if [ "$(vp8_encode_available)" = "yes" ]; then
|
if [ "$(vp8_encode_available)" = "yes" ]; then
|
||||||
vpx_tsvc_encoder vp8 "${FUNCNAME}" 7 200 400 600 800 1000 || return 1
|
local readonly output_basename="vpx_tsvc_encoder_vp8_mode_7"
|
||||||
|
vpx_tsvc_encoder vp8 "${output_basename}" 7 200 400 600 800 1000 || return 1
|
||||||
# Mode 7 produces 5 streams
|
# Mode 7 produces 5 streams
|
||||||
files_exist "${FUNCNAME}" 5 || return 1
|
files_exist "${output_basename}" 5 || return 1
|
||||||
fi
|
fi
|
||||||
}
|
}
|
||||||
|
|
||||||
vpx_tsvc_encoder_vp8_mode_8() {
|
vpx_tsvc_encoder_vp8_mode_8() {
|
||||||
if [ "$(vp8_encode_available)" = "yes" ]; then
|
if [ "$(vp8_encode_available)" = "yes" ]; then
|
||||||
vpx_tsvc_encoder vp8 "${FUNCNAME}" 8 200 400 || return 1
|
local readonly output_basename="vpx_tsvc_encoder_vp8_mode_8"
|
||||||
|
vpx_tsvc_encoder vp8 "${output_basename}" 8 200 400 || return 1
|
||||||
# Mode 8 produces 2 streams
|
# Mode 8 produces 2 streams
|
||||||
files_exist "${FUNCNAME}" 2 || return 1
|
files_exist "${output_basename}" 2 || return 1
|
||||||
fi
|
fi
|
||||||
}
|
}
|
||||||
|
|
||||||
vpx_tsvc_encoder_vp8_mode_9() {
|
vpx_tsvc_encoder_vp8_mode_9() {
|
||||||
if [ "$(vp8_encode_available)" = "yes" ]; then
|
if [ "$(vp8_encode_available)" = "yes" ]; then
|
||||||
vpx_tsvc_encoder vp8 "${FUNCNAME}" 9 200 400 600 || return 1
|
local readonly output_basename="vpx_tsvc_encoder_vp8_mode_9"
|
||||||
|
vpx_tsvc_encoder vp8 "${output_basename}" 9 200 400 600 || return 1
|
||||||
# Mode 9 produces 3 streams
|
# Mode 9 produces 3 streams
|
||||||
files_exist "${FUNCNAME}" 3 || return 1
|
files_exist "${output_basename}" 3 || return 1
|
||||||
fi
|
fi
|
||||||
}
|
}
|
||||||
|
|
||||||
vpx_tsvc_encoder_vp8_mode_10() {
|
vpx_tsvc_encoder_vp8_mode_10() {
|
||||||
if [ "$(vp8_encode_available)" = "yes" ]; then
|
if [ "$(vp8_encode_available)" = "yes" ]; then
|
||||||
vpx_tsvc_encoder vp8 "${FUNCNAME}" 10 200 400 600 || return 1
|
local readonly output_basename="vpx_tsvc_encoder_vp8_mode_10"
|
||||||
|
vpx_tsvc_encoder vp8 "${output_basename}" 10 200 400 600 || return 1
|
||||||
# Mode 10 produces 3 streams
|
# Mode 10 produces 3 streams
|
||||||
files_exist "${FUNCNAME}" 3 || return 1
|
files_exist "${output_basename}" 3 || return 1
|
||||||
fi
|
fi
|
||||||
}
|
}
|
||||||
|
|
||||||
vpx_tsvc_encoder_vp8_mode_11() {
|
vpx_tsvc_encoder_vp8_mode_11() {
|
||||||
if [ "$(vp8_encode_available)" = "yes" ]; then
|
if [ "$(vp8_encode_available)" = "yes" ]; then
|
||||||
vpx_tsvc_encoder vp8 "${FUNCNAME}" 11 200 400 600 || return 1
|
local readonly output_basename="vpx_tsvc_encoder_vp8_mode_11"
|
||||||
|
vpx_tsvc_encoder vp8 "${output_basename}" 11 200 400 600 || return 1
|
||||||
# Mode 11 produces 3 streams
|
# Mode 11 produces 3 streams
|
||||||
files_exist "${FUNCNAME}" 3 || return 1
|
files_exist "${output_basename}" 3 || return 1
|
||||||
fi
|
fi
|
||||||
}
|
}
|
||||||
|
|
||||||
vpx_tsvc_encoder_vp9_mode_0() {
|
vpx_tsvc_encoder_vp9_mode_0() {
|
||||||
if [ "$(vp9_encode_available)" = "yes" ]; then
|
if [ "$(vp9_encode_available)" = "yes" ]; then
|
||||||
vpx_tsvc_encoder vp9 "${FUNCNAME}" 0 200 || return 1
|
local readonly output_basename="vpx_tsvc_encoder_vp9_mode_0"
|
||||||
|
vpx_tsvc_encoder vp9 "${output_basename}" 0 200 || return 1
|
||||||
# Mode 0 produces 1 stream
|
# Mode 0 produces 1 stream
|
||||||
files_exist "${FUNCNAME}" 1 || return 1
|
files_exist "${output_basename}" 1 || return 1
|
||||||
fi
|
fi
|
||||||
}
|
}
|
||||||
|
|
||||||
vpx_tsvc_encoder_vp9_mode_1() {
|
vpx_tsvc_encoder_vp9_mode_1() {
|
||||||
if [ "$(vp9_encode_available)" = "yes" ]; then
|
if [ "$(vp9_encode_available)" = "yes" ]; then
|
||||||
vpx_tsvc_encoder vp9 "${FUNCNAME}" 1 200 400 || return 1
|
local readonly output_basename="vpx_tsvc_encoder_vp9_mode_1"
|
||||||
|
vpx_tsvc_encoder vp9 "${output_basename}" 1 200 400 || return 1
|
||||||
# Mode 1 produces 2 streams
|
# Mode 1 produces 2 streams
|
||||||
files_exist "${FUNCNAME}" 2 || return 1
|
files_exist "${output_basename}" 2 || return 1
|
||||||
fi
|
fi
|
||||||
}
|
}
|
||||||
|
|
||||||
vpx_tsvc_encoder_vp9_mode_2() {
|
vpx_tsvc_encoder_vp9_mode_2() {
|
||||||
if [ "$(vp9_encode_available)" = "yes" ]; then
|
if [ "$(vp9_encode_available)" = "yes" ]; then
|
||||||
vpx_tsvc_encoder vp9 "${FUNCNAME}" 2 200 400 || return 1
|
local readonly output_basename="vpx_tsvc_encoder_vp9_mode_2"
|
||||||
|
vpx_tsvc_encoder vp9 "${output_basename}" 2 200 400 || return 1
|
||||||
# Mode 2 produces 2 streams
|
# Mode 2 produces 2 streams
|
||||||
files_exist "${FUNCNAME}" 2 || return 1
|
files_exist "${output_basename}" 2 || return 1
|
||||||
fi
|
fi
|
||||||
}
|
}
|
||||||
|
|
||||||
vpx_tsvc_encoder_vp9_mode_3() {
|
vpx_tsvc_encoder_vp9_mode_3() {
|
||||||
if [ "$(vp9_encode_available)" = "yes" ]; then
|
if [ "$(vp9_encode_available)" = "yes" ]; then
|
||||||
vpx_tsvc_encoder vp9 "${FUNCNAME}" 3 200 400 600 || return 1
|
local readonly output_basename="vpx_tsvc_encoder_vp9_mode_3"
|
||||||
|
vpx_tsvc_encoder vp9 "${output_basename}" 3 200 400 600 || return 1
|
||||||
# Mode 3 produces 3 streams
|
# Mode 3 produces 3 streams
|
||||||
files_exist "${FUNCNAME}" 3 || return 1
|
files_exist "${output_basename}" 3 || return 1
|
||||||
fi
|
fi
|
||||||
}
|
}
|
||||||
|
|
||||||
vpx_tsvc_encoder_vp9_mode_4() {
|
vpx_tsvc_encoder_vp9_mode_4() {
|
||||||
if [ "$(vp9_encode_available)" = "yes" ]; then
|
if [ "$(vp9_encode_available)" = "yes" ]; then
|
||||||
vpx_tsvc_encoder vp9 "${FUNCNAME}" 4 200 400 600 || return 1
|
local readonly output_basename="vpx_tsvc_encoder_vp9_mode_4"
|
||||||
|
vpx_tsvc_encoder vp9 "${output_basename}" 4 200 400 600 || return 1
|
||||||
# Mode 4 produces 3 streams
|
# Mode 4 produces 3 streams
|
||||||
files_exist "${FUNCNAME}" 3 || return 1
|
files_exist "${output_basename}" 3 || return 1
|
||||||
fi
|
fi
|
||||||
}
|
}
|
||||||
|
|
||||||
vpx_tsvc_encoder_vp9_mode_5() {
|
vpx_tsvc_encoder_vp9_mode_5() {
|
||||||
if [ "$(vp9_encode_available)" = "yes" ]; then
|
if [ "$(vp9_encode_available)" = "yes" ]; then
|
||||||
vpx_tsvc_encoder vp9 "${FUNCNAME}" 5 200 400 600 || return 1
|
local readonly output_basename="vpx_tsvc_encoder_vp9_mode_5"
|
||||||
|
vpx_tsvc_encoder vp9 "${output_basename}" 5 200 400 600 || return 1
|
||||||
# Mode 5 produces 3 streams
|
# Mode 5 produces 3 streams
|
||||||
files_exist "${FUNCNAME}" 3 || return 1
|
files_exist "${output_basename}" 3 || return 1
|
||||||
fi
|
fi
|
||||||
}
|
}
|
||||||
|
|
||||||
vpx_tsvc_encoder_vp9_mode_6() {
|
vpx_tsvc_encoder_vp9_mode_6() {
|
||||||
if [ "$(vp9_encode_available)" = "yes" ]; then
|
if [ "$(vp9_encode_available)" = "yes" ]; then
|
||||||
vpx_tsvc_encoder vp9 "${FUNCNAME}" 6 200 400 600 || return 1
|
local readonly output_basename="vpx_tsvc_encoder_vp9_mode_6"
|
||||||
|
vpx_tsvc_encoder vp9 "${output_basename}" 6 200 400 600 || return 1
|
||||||
# Mode 6 produces 3 streams
|
# Mode 6 produces 3 streams
|
||||||
files_exist "${FUNCNAME}" 3 || return 1
|
files_exist "${output_basename}" 3 || return 1
|
||||||
fi
|
fi
|
||||||
}
|
}
|
||||||
|
|
||||||
vpx_tsvc_encoder_vp9_mode_7() {
|
vpx_tsvc_encoder_vp9_mode_7() {
|
||||||
if [ "$(vp9_encode_available)" = "yes" ]; then
|
if [ "$(vp9_encode_available)" = "yes" ]; then
|
||||||
vpx_tsvc_encoder vp9 "${FUNCNAME}" 7 200 400 600 800 1000 || return 1
|
local readonly output_basename="vpx_tsvc_encoder_vp9_mode_7"
|
||||||
|
vpx_tsvc_encoder vp9 "${output_basename}" 7 200 400 600 800 1000 || return 1
|
||||||
# Mode 7 produces 5 streams
|
# Mode 7 produces 5 streams
|
||||||
files_exist "${FUNCNAME}" 5 || return 1
|
files_exist "${output_basename}" 5 || return 1
|
||||||
fi
|
fi
|
||||||
}
|
}
|
||||||
|
|
||||||
vpx_tsvc_encoder_vp9_mode_8() {
|
vpx_tsvc_encoder_vp9_mode_8() {
|
||||||
if [ "$(vp9_encode_available)" = "yes" ]; then
|
if [ "$(vp9_encode_available)" = "yes" ]; then
|
||||||
vpx_tsvc_encoder vp9 "${FUNCNAME}" 8 200 400 || return 1
|
local readonly output_basename="vpx_tsvc_encoder_vp9_mode_8"
|
||||||
|
vpx_tsvc_encoder vp9 "${output_basename}" 8 200 400 || return 1
|
||||||
# Mode 8 produces 2 streams
|
# Mode 8 produces 2 streams
|
||||||
files_exist "${FUNCNAME}" 2 || return 1
|
files_exist "${output_basename}" 2 || return 1
|
||||||
fi
|
fi
|
||||||
}
|
}
|
||||||
|
|
||||||
vpx_tsvc_encoder_vp9_mode_9() {
|
vpx_tsvc_encoder_vp9_mode_9() {
|
||||||
if [ "$(vp9_encode_available)" = "yes" ]; then
|
if [ "$(vp9_encode_available)" = "yes" ]; then
|
||||||
vpx_tsvc_encoder vp9 "${FUNCNAME}" 9 200 400 600 || return 1
|
local readonly output_basename="vpx_tsvc_encoder_vp9_mode_9"
|
||||||
|
vpx_tsvc_encoder vp9 "${output_basename}" 9 200 400 600 || return 1
|
||||||
# Mode 9 produces 3 streams
|
# Mode 9 produces 3 streams
|
||||||
files_exist "${FUNCNAME}" 3 || return 1
|
files_exist "${output_basename}" 3 || return 1
|
||||||
fi
|
fi
|
||||||
}
|
}
|
||||||
|
|
||||||
vpx_tsvc_encoder_vp9_mode_10() {
|
vpx_tsvc_encoder_vp9_mode_10() {
|
||||||
if [ "$(vp9_encode_available)" = "yes" ]; then
|
if [ "$(vp9_encode_available)" = "yes" ]; then
|
||||||
vpx_tsvc_encoder vp9 "${FUNCNAME}" 10 200 400 600 || return 1
|
local readonly output_basename="vpx_tsvc_encoder_vp9_mode_10"
|
||||||
|
vpx_tsvc_encoder vp9 "${output_basename}" 10 200 400 600 || return 1
|
||||||
# Mode 10 produces 3 streams
|
# Mode 10 produces 3 streams
|
||||||
files_exist "${FUNCNAME}" 3 || return 1
|
files_exist "${output_basename}" 3 || return 1
|
||||||
fi
|
fi
|
||||||
}
|
}
|
||||||
|
|
||||||
vpx_tsvc_encoder_vp9_mode_11() {
|
vpx_tsvc_encoder_vp9_mode_11() {
|
||||||
if [ "$(vp9_encode_available)" = "yes" ]; then
|
if [ "$(vp9_encode_available)" = "yes" ]; then
|
||||||
vpx_tsvc_encoder vp9 "${FUNCNAME}" 11 200 400 600 || return 1
|
local readonly output_basename="vpx_tsvc_encoder_vp9_mode_11"
|
||||||
|
vpx_tsvc_encoder vp9 "${output_basename}" 11 200 400 600 || return 1
|
||||||
# Mode 11 produces 3 streams
|
# Mode 11 produces 3 streams
|
||||||
files_exist "${FUNCNAME}" 3 || return 1
|
files_exist "${output_basename}" 3 || return 1
|
||||||
fi
|
fi
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -90,6 +90,15 @@ vpxenc_rt_params() {
|
||||||
--undershoot-pct=50"
|
--undershoot-pct=50"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
# Forces --passes to 1 with CONFIG_REALTIME_ONLY.
|
||||||
|
vpxenc_passes_param() {
|
||||||
|
if [ "$(vpx_config_option_enabled CONFIG_REALTIME_ONLY)" = "yes" ]; then
|
||||||
|
echo "--passes=1"
|
||||||
|
else
|
||||||
|
echo "--passes=2"
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
# Wrapper function for running vpxenc with pipe input. Requires that
|
# Wrapper function for running vpxenc with pipe input. Requires that
|
||||||
# LIBVPX_BIN_PATH points to the directory containing vpxenc. $1 is used as the
|
# LIBVPX_BIN_PATH points to the directory containing vpxenc. $1 is used as the
|
||||||
# input file path and shifted away. All remaining parameters are passed through
|
# input file path and shifted away. All remaining parameters are passed through
|
||||||
|
@ -218,9 +227,11 @@ vpxenc_vp8_ivf_piped_input() {
|
||||||
vpxenc_vp9_ivf() {
|
vpxenc_vp9_ivf() {
|
||||||
if [ "$(vpxenc_can_encode_vp9)" = "yes" ]; then
|
if [ "$(vpxenc_can_encode_vp9)" = "yes" ]; then
|
||||||
local readonly output="${VPX_TEST_OUTPUT_DIR}/vp9.ivf"
|
local readonly output="${VPX_TEST_OUTPUT_DIR}/vp9.ivf"
|
||||||
|
local readonly passes=$(vpxenc_passes_param)
|
||||||
vpxenc $(yuv_input_hantro_collage) \
|
vpxenc $(yuv_input_hantro_collage) \
|
||||||
--codec=vp9 \
|
--codec=vp9 \
|
||||||
--limit="${TEST_FRAMES}" \
|
--limit="${TEST_FRAMES}" \
|
||||||
|
"${passes}" \
|
||||||
--ivf \
|
--ivf \
|
||||||
--output="${output}"
|
--output="${output}"
|
||||||
|
|
||||||
|
@ -235,9 +246,11 @@ vpxenc_vp9_webm() {
|
||||||
if [ "$(vpxenc_can_encode_vp9)" = "yes" ] && \
|
if [ "$(vpxenc_can_encode_vp9)" = "yes" ] && \
|
||||||
[ "$(webm_io_available)" = "yes" ]; then
|
[ "$(webm_io_available)" = "yes" ]; then
|
||||||
local readonly output="${VPX_TEST_OUTPUT_DIR}/vp9.webm"
|
local readonly output="${VPX_TEST_OUTPUT_DIR}/vp9.webm"
|
||||||
|
local readonly passes=$(vpxenc_passes_param)
|
||||||
vpxenc $(yuv_input_hantro_collage) \
|
vpxenc $(yuv_input_hantro_collage) \
|
||||||
--codec=vp9 \
|
--codec=vp9 \
|
||||||
--limit="${TEST_FRAMES}" \
|
--limit="${TEST_FRAMES}" \
|
||||||
|
"${passes}" \
|
||||||
--output="${output}"
|
--output="${output}"
|
||||||
|
|
||||||
if [ ! -e "${output}" ]; then
|
if [ ! -e "${output}" ]; then
|
||||||
|
@ -339,11 +352,13 @@ vpxenc_vp9_webm_2pass() {
|
||||||
vpxenc_vp9_ivf_lossless() {
|
vpxenc_vp9_ivf_lossless() {
|
||||||
if [ "$(vpxenc_can_encode_vp9)" = "yes" ]; then
|
if [ "$(vpxenc_can_encode_vp9)" = "yes" ]; then
|
||||||
local readonly output="${VPX_TEST_OUTPUT_DIR}/vp9_lossless.ivf"
|
local readonly output="${VPX_TEST_OUTPUT_DIR}/vp9_lossless.ivf"
|
||||||
|
local readonly passes=$(vpxenc_passes_param)
|
||||||
vpxenc $(yuv_input_hantro_collage) \
|
vpxenc $(yuv_input_hantro_collage) \
|
||||||
--codec=vp9 \
|
--codec=vp9 \
|
||||||
--limit="${TEST_FRAMES}" \
|
--limit="${TEST_FRAMES}" \
|
||||||
--ivf \
|
--ivf \
|
||||||
--output="${output}" \
|
--output="${output}" \
|
||||||
|
"${passes}" \
|
||||||
--lossless=1
|
--lossless=1
|
||||||
|
|
||||||
if [ ! -e "${output}" ]; then
|
if [ ! -e "${output}" ]; then
|
||||||
|
@ -356,11 +371,13 @@ vpxenc_vp9_ivf_lossless() {
|
||||||
vpxenc_vp9_ivf_minq0_maxq0() {
|
vpxenc_vp9_ivf_minq0_maxq0() {
|
||||||
if [ "$(vpxenc_can_encode_vp9)" = "yes" ]; then
|
if [ "$(vpxenc_can_encode_vp9)" = "yes" ]; then
|
||||||
local readonly output="${VPX_TEST_OUTPUT_DIR}/vp9_lossless_minq0_maxq0.ivf"
|
local readonly output="${VPX_TEST_OUTPUT_DIR}/vp9_lossless_minq0_maxq0.ivf"
|
||||||
|
local readonly passes=$(vpxenc_passes_param)
|
||||||
vpxenc $(yuv_input_hantro_collage) \
|
vpxenc $(yuv_input_hantro_collage) \
|
||||||
--codec=vp9 \
|
--codec=vp9 \
|
||||||
--limit="${TEST_FRAMES}" \
|
--limit="${TEST_FRAMES}" \
|
||||||
--ivf \
|
--ivf \
|
||||||
--output="${output}" \
|
--output="${output}" \
|
||||||
|
"${passes}" \
|
||||||
--min-q=0 \
|
--min-q=0 \
|
||||||
--max-q=0
|
--max-q=0
|
||||||
|
|
||||||
|
@ -377,12 +394,13 @@ vpxenc_vp9_webm_lag10_frames20() {
|
||||||
local readonly lag_total_frames=20
|
local readonly lag_total_frames=20
|
||||||
local readonly lag_frames=10
|
local readonly lag_frames=10
|
||||||
local readonly output="${VPX_TEST_OUTPUT_DIR}/vp9_lag10_frames20.webm"
|
local readonly output="${VPX_TEST_OUTPUT_DIR}/vp9_lag10_frames20.webm"
|
||||||
|
local readonly passes=$(vpxenc_passes_param)
|
||||||
vpxenc $(yuv_input_hantro_collage) \
|
vpxenc $(yuv_input_hantro_collage) \
|
||||||
--codec=vp9 \
|
--codec=vp9 \
|
||||||
--limit="${lag_total_frames}" \
|
--limit="${lag_total_frames}" \
|
||||||
--lag-in-frames="${lag_frames}" \
|
--lag-in-frames="${lag_frames}" \
|
||||||
--output="${output}" \
|
--output="${output}" \
|
||||||
--passes=2 \
|
"${passes}" \
|
||||||
--auto-alt-ref=1
|
--auto-alt-ref=1
|
||||||
|
|
||||||
if [ ! -e "${output}" ]; then
|
if [ ! -e "${output}" ]; then
|
||||||
|
@ -397,9 +415,11 @@ vpxenc_vp9_webm_non_square_par() {
|
||||||
if [ "$(vpxenc_can_encode_vp9)" = "yes" ] && \
|
if [ "$(vpxenc_can_encode_vp9)" = "yes" ] && \
|
||||||
[ "$(webm_io_available)" = "yes" ]; then
|
[ "$(webm_io_available)" = "yes" ]; then
|
||||||
local readonly output="${VPX_TEST_OUTPUT_DIR}/vp9_non_square_par.webm"
|
local readonly output="${VPX_TEST_OUTPUT_DIR}/vp9_non_square_par.webm"
|
||||||
|
local readonly passes=$(vpxenc_passes_param)
|
||||||
vpxenc $(y4m_input_non_square_par) \
|
vpxenc $(y4m_input_non_square_par) \
|
||||||
--codec=vp9 \
|
--codec=vp9 \
|
||||||
--limit="${TEST_FRAMES}" \
|
--limit="${TEST_FRAMES}" \
|
||||||
|
"${passes}" \
|
||||||
--output="${output}"
|
--output="${output}"
|
||||||
|
|
||||||
if [ ! -e "${output}" ]; then
|
if [ ! -e "${output}" ]; then
|
||||||
|
@ -412,18 +432,21 @@ vpxenc_vp9_webm_non_square_par() {
|
||||||
vpxenc_tests="vpxenc_vp8_ivf
|
vpxenc_tests="vpxenc_vp8_ivf
|
||||||
vpxenc_vp8_webm
|
vpxenc_vp8_webm
|
||||||
vpxenc_vp8_webm_rt
|
vpxenc_vp8_webm_rt
|
||||||
vpxenc_vp8_webm_2pass
|
|
||||||
vpxenc_vp8_webm_lag10_frames20
|
|
||||||
vpxenc_vp8_ivf_piped_input
|
vpxenc_vp8_ivf_piped_input
|
||||||
vpxenc_vp9_ivf
|
vpxenc_vp9_ivf
|
||||||
vpxenc_vp9_webm
|
vpxenc_vp9_webm
|
||||||
vpxenc_vp9_webm_rt
|
vpxenc_vp9_webm_rt
|
||||||
vpxenc_vp9_webm_rt_multithread_tiled
|
vpxenc_vp9_webm_rt_multithread_tiled
|
||||||
vpxenc_vp9_webm_rt_multithread_tiled_frameparallel
|
vpxenc_vp9_webm_rt_multithread_tiled_frameparallel
|
||||||
vpxenc_vp9_webm_2pass
|
|
||||||
vpxenc_vp9_ivf_lossless
|
vpxenc_vp9_ivf_lossless
|
||||||
vpxenc_vp9_ivf_minq0_maxq0
|
vpxenc_vp9_ivf_minq0_maxq0
|
||||||
vpxenc_vp9_webm_lag10_frames20
|
vpxenc_vp9_webm_lag10_frames20
|
||||||
vpxenc_vp9_webm_non_square_par"
|
vpxenc_vp9_webm_non_square_par"
|
||||||
|
if [ "$(vpx_config_option_enabled CONFIG_REALTIME_ONLY)" != "yes" ]; then
|
||||||
|
vpxenc_tests="$vpxenc_tests
|
||||||
|
vpxenc_vp8_webm_2pass
|
||||||
|
vpxenc_vp8_webm_lag10_frames20
|
||||||
|
vpxenc_vp9_webm_2pass"
|
||||||
|
fi
|
||||||
|
|
||||||
run_tests vpxenc_verify_environment "${vpxenc_tests}"
|
run_tests vpxenc_verify_environment "${vpxenc_tests}"
|
||||||
|
|
|
@ -40,8 +40,8 @@ class WebMVideoSource : public CompressedVideoSource {
|
||||||
|
|
||||||
virtual void Begin() {
|
virtual void Begin() {
|
||||||
vpx_ctx_->file = OpenTestDataFile(file_name_);
|
vpx_ctx_->file = OpenTestDataFile(file_name_);
|
||||||
ASSERT_TRUE(vpx_ctx_->file != NULL) << "Input file open failed. Filename: "
|
ASSERT_TRUE(vpx_ctx_->file != NULL)
|
||||||
<< file_name_;
|
<< "Input file open failed. Filename: " << file_name_;
|
||||||
|
|
||||||
ASSERT_EQ(file_is_webm(webm_ctx_, vpx_ctx_), 1) << "file is not WebM";
|
ASSERT_EQ(file_is_webm(webm_ctx_, vpx_ctx_), 1) << "file is not WebM";
|
||||||
|
|
||||||
|
|
|
@ -34,8 +34,8 @@ class Y4mVideoSource : public VideoSource {
|
||||||
virtual void OpenSource() {
|
virtual void OpenSource() {
|
||||||
CloseSource();
|
CloseSource();
|
||||||
input_file_ = OpenTestDataFile(file_name_);
|
input_file_ = OpenTestDataFile(file_name_);
|
||||||
ASSERT_TRUE(input_file_ != NULL) << "Input file open failed. Filename: "
|
ASSERT_TRUE(input_file_ != NULL)
|
||||||
<< file_name_;
|
<< "Input file open failed. Filename: " << file_name_;
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual void ReadSourceToStart() {
|
virtual void ReadSourceToStart() {
|
||||||
|
|
|
@ -43,8 +43,8 @@ class YUVVideoSource : public VideoSource {
|
||||||
virtual void Begin() {
|
virtual void Begin() {
|
||||||
if (input_file_) fclose(input_file_);
|
if (input_file_) fclose(input_file_);
|
||||||
input_file_ = OpenTestDataFile(file_name_);
|
input_file_ = OpenTestDataFile(file_name_);
|
||||||
ASSERT_TRUE(input_file_ != NULL) << "Input file open failed. Filename: "
|
ASSERT_TRUE(input_file_ != NULL)
|
||||||
<< file_name_;
|
<< "Input file open failed. Filename: " << file_name_;
|
||||||
if (start_) {
|
if (start_) {
|
||||||
fseek(input_file_, static_cast<unsigned>(raw_size_) * start_, SEEK_SET);
|
fseek(input_file_, static_cast<unsigned>(raw_size_) * start_, SEEK_SET);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
URL: http://code.google.com/p/googletest/
|
URL: https://github.com/google/googletest
|
||||||
Version: 1.7.0
|
Version: 1.8.0
|
||||||
License: BSD
|
License: BSD
|
||||||
License File: COPYING
|
License File: LICENSE
|
||||||
|
|
||||||
Description:
|
Description:
|
||||||
Google's framework for writing C++ tests on a variety of platforms
|
Google's framework for writing C++ tests on a variety of platforms
|
||||||
|
@ -12,10 +12,13 @@ failures, various options for running the tests, and XML test report
|
||||||
generation.
|
generation.
|
||||||
|
|
||||||
Local Modifications:
|
Local Modifications:
|
||||||
- Removed unused declarations of kPathSeparatorString to have warning
|
- Remove everything but:
|
||||||
free build.
|
googletest-release-1.8.0/googletest/
|
||||||
- Added GTEST_ATTRIBUTE_UNUSED_ to test registering dummies in TEST_P
|
CHANGES
|
||||||
and INSTANTIATE_TEST_CASE_P to remove warnings about unused variables
|
CONTRIBUTORS
|
||||||
under GCC 5.
|
include
|
||||||
- Only define g_in_fast_death_test_child for non-Windows builds; quiets an
|
LICENSE
|
||||||
unused variable warning.
|
README.md
|
||||||
|
src
|
||||||
|
- Suppress unsigned overflow instrumentation in the LCG
|
||||||
|
https://github.com/google/googletest/pull/1066
|
||||||
|
|
|
@ -1,435 +0,0 @@
|
||||||
Google C++ Testing Framework
|
|
||||||
============================
|
|
||||||
|
|
||||||
http://code.google.com/p/googletest/
|
|
||||||
|
|
||||||
Overview
|
|
||||||
--------
|
|
||||||
|
|
||||||
Google's framework for writing C++ tests on a variety of platforms
|
|
||||||
(Linux, Mac OS X, Windows, Windows CE, Symbian, etc). Based on the
|
|
||||||
xUnit architecture. Supports automatic test discovery, a rich set of
|
|
||||||
assertions, user-defined assertions, death tests, fatal and non-fatal
|
|
||||||
failures, various options for running the tests, and XML test report
|
|
||||||
generation.
|
|
||||||
|
|
||||||
Please see the project page above for more information as well as the
|
|
||||||
mailing list for questions, discussions, and development. There is
|
|
||||||
also an IRC channel on OFTC (irc.oftc.net) #gtest available. Please
|
|
||||||
join us!
|
|
||||||
|
|
||||||
Requirements for End Users
|
|
||||||
--------------------------
|
|
||||||
|
|
||||||
Google Test is designed to have fairly minimal requirements to build
|
|
||||||
and use with your projects, but there are some. Currently, we support
|
|
||||||
Linux, Windows, Mac OS X, and Cygwin. We will also make our best
|
|
||||||
effort to support other platforms (e.g. Solaris, AIX, and z/OS).
|
|
||||||
However, since core members of the Google Test project have no access
|
|
||||||
to these platforms, Google Test may have outstanding issues there. If
|
|
||||||
you notice any problems on your platform, please notify
|
|
||||||
googletestframework@googlegroups.com. Patches for fixing them are
|
|
||||||
even more welcome!
|
|
||||||
|
|
||||||
### Linux Requirements ###
|
|
||||||
|
|
||||||
These are the base requirements to build and use Google Test from a source
|
|
||||||
package (as described below):
|
|
||||||
* GNU-compatible Make or gmake
|
|
||||||
* POSIX-standard shell
|
|
||||||
* POSIX(-2) Regular Expressions (regex.h)
|
|
||||||
* A C++98-standard-compliant compiler
|
|
||||||
|
|
||||||
### Windows Requirements ###
|
|
||||||
|
|
||||||
* Microsoft Visual C++ 7.1 or newer
|
|
||||||
|
|
||||||
### Cygwin Requirements ###
|
|
||||||
|
|
||||||
* Cygwin 1.5.25-14 or newer
|
|
||||||
|
|
||||||
### Mac OS X Requirements ###
|
|
||||||
|
|
||||||
* Mac OS X 10.4 Tiger or newer
|
|
||||||
* Developer Tools Installed
|
|
||||||
|
|
||||||
Also, you'll need CMake 2.6.4 or higher if you want to build the
|
|
||||||
samples using the provided CMake script, regardless of the platform.
|
|
||||||
|
|
||||||
Requirements for Contributors
|
|
||||||
-----------------------------
|
|
||||||
|
|
||||||
We welcome patches. If you plan to contribute a patch, you need to
|
|
||||||
build Google Test and its own tests from an SVN checkout (described
|
|
||||||
below), which has further requirements:
|
|
||||||
|
|
||||||
* Python version 2.3 or newer (for running some of the tests and
|
|
||||||
re-generating certain source files from templates)
|
|
||||||
* CMake 2.6.4 or newer
|
|
||||||
|
|
||||||
Getting the Source
|
|
||||||
------------------
|
|
||||||
|
|
||||||
There are two primary ways of getting Google Test's source code: you
|
|
||||||
can download a stable source release in your preferred archive format,
|
|
||||||
or directly check out the source from our Subversion (SVN) repositary.
|
|
||||||
The SVN checkout requires a few extra steps and some extra software
|
|
||||||
packages on your system, but lets you track the latest development and
|
|
||||||
make patches much more easily, so we highly encourage it.
|
|
||||||
|
|
||||||
### Source Package ###
|
|
||||||
|
|
||||||
Google Test is released in versioned source packages which can be
|
|
||||||
downloaded from the download page [1]. Several different archive
|
|
||||||
formats are provided, but the only difference is the tools used to
|
|
||||||
manipulate them, and the size of the resulting file. Download
|
|
||||||
whichever you are most comfortable with.
|
|
||||||
|
|
||||||
[1] http://code.google.com/p/googletest/downloads/list
|
|
||||||
|
|
||||||
Once the package is downloaded, expand it using whichever tools you
|
|
||||||
prefer for that type. This will result in a new directory with the
|
|
||||||
name "gtest-X.Y.Z" which contains all of the source code. Here are
|
|
||||||
some examples on Linux:
|
|
||||||
|
|
||||||
tar -xvzf gtest-X.Y.Z.tar.gz
|
|
||||||
tar -xvjf gtest-X.Y.Z.tar.bz2
|
|
||||||
unzip gtest-X.Y.Z.zip
|
|
||||||
|
|
||||||
### SVN Checkout ###
|
|
||||||
|
|
||||||
To check out the main branch (also known as the "trunk") of Google
|
|
||||||
Test, run the following Subversion command:
|
|
||||||
|
|
||||||
svn checkout http://googletest.googlecode.com/svn/trunk/ gtest-svn
|
|
||||||
|
|
||||||
Setting up the Build
|
|
||||||
--------------------
|
|
||||||
|
|
||||||
To build Google Test and your tests that use it, you need to tell your
|
|
||||||
build system where to find its headers and source files. The exact
|
|
||||||
way to do it depends on which build system you use, and is usually
|
|
||||||
straightforward.
|
|
||||||
|
|
||||||
### Generic Build Instructions ###
|
|
||||||
|
|
||||||
Suppose you put Google Test in directory ${GTEST_DIR}. To build it,
|
|
||||||
create a library build target (or a project as called by Visual Studio
|
|
||||||
and Xcode) to compile
|
|
||||||
|
|
||||||
${GTEST_DIR}/src/gtest-all.cc
|
|
||||||
|
|
||||||
with ${GTEST_DIR}/include in the system header search path and ${GTEST_DIR}
|
|
||||||
in the normal header search path. Assuming a Linux-like system and gcc,
|
|
||||||
something like the following will do:
|
|
||||||
|
|
||||||
g++ -isystem ${GTEST_DIR}/include -I${GTEST_DIR} \
|
|
||||||
-pthread -c ${GTEST_DIR}/src/gtest-all.cc
|
|
||||||
ar -rv libgtest.a gtest-all.o
|
|
||||||
|
|
||||||
(We need -pthread as Google Test uses threads.)
|
|
||||||
|
|
||||||
Next, you should compile your test source file with
|
|
||||||
${GTEST_DIR}/include in the system header search path, and link it
|
|
||||||
with gtest and any other necessary libraries:
|
|
||||||
|
|
||||||
g++ -isystem ${GTEST_DIR}/include -pthread path/to/your_test.cc libgtest.a \
|
|
||||||
-o your_test
|
|
||||||
|
|
||||||
As an example, the make/ directory contains a Makefile that you can
|
|
||||||
use to build Google Test on systems where GNU make is available
|
|
||||||
(e.g. Linux, Mac OS X, and Cygwin). It doesn't try to build Google
|
|
||||||
Test's own tests. Instead, it just builds the Google Test library and
|
|
||||||
a sample test. You can use it as a starting point for your own build
|
|
||||||
script.
|
|
||||||
|
|
||||||
If the default settings are correct for your environment, the
|
|
||||||
following commands should succeed:
|
|
||||||
|
|
||||||
cd ${GTEST_DIR}/make
|
|
||||||
make
|
|
||||||
./sample1_unittest
|
|
||||||
|
|
||||||
If you see errors, try to tweak the contents of make/Makefile to make
|
|
||||||
them go away. There are instructions in make/Makefile on how to do
|
|
||||||
it.
|
|
||||||
|
|
||||||
### Using CMake ###
|
|
||||||
|
|
||||||
Google Test comes with a CMake build script (CMakeLists.txt) that can
|
|
||||||
be used on a wide range of platforms ("C" stands for cross-platofrm.).
|
|
||||||
If you don't have CMake installed already, you can download it for
|
|
||||||
free from http://www.cmake.org/.
|
|
||||||
|
|
||||||
CMake works by generating native makefiles or build projects that can
|
|
||||||
be used in the compiler environment of your choice. The typical
|
|
||||||
workflow starts with:
|
|
||||||
|
|
||||||
mkdir mybuild # Create a directory to hold the build output.
|
|
||||||
cd mybuild
|
|
||||||
cmake ${GTEST_DIR} # Generate native build scripts.
|
|
||||||
|
|
||||||
If you want to build Google Test's samples, you should replace the
|
|
||||||
last command with
|
|
||||||
|
|
||||||
cmake -Dgtest_build_samples=ON ${GTEST_DIR}
|
|
||||||
|
|
||||||
If you are on a *nix system, you should now see a Makefile in the
|
|
||||||
current directory. Just type 'make' to build gtest.
|
|
||||||
|
|
||||||
If you use Windows and have Vistual Studio installed, a gtest.sln file
|
|
||||||
and several .vcproj files will be created. You can then build them
|
|
||||||
using Visual Studio.
|
|
||||||
|
|
||||||
On Mac OS X with Xcode installed, a .xcodeproj file will be generated.
|
|
||||||
|
|
||||||
### Legacy Build Scripts ###
|
|
||||||
|
|
||||||
Before settling on CMake, we have been providing hand-maintained build
|
|
||||||
projects/scripts for Visual Studio, Xcode, and Autotools. While we
|
|
||||||
continue to provide them for convenience, they are not actively
|
|
||||||
maintained any more. We highly recommend that you follow the
|
|
||||||
instructions in the previous two sections to integrate Google Test
|
|
||||||
with your existing build system.
|
|
||||||
|
|
||||||
If you still need to use the legacy build scripts, here's how:
|
|
||||||
|
|
||||||
The msvc\ folder contains two solutions with Visual C++ projects.
|
|
||||||
Open the gtest.sln or gtest-md.sln file using Visual Studio, and you
|
|
||||||
are ready to build Google Test the same way you build any Visual
|
|
||||||
Studio project. Files that have names ending with -md use DLL
|
|
||||||
versions of Microsoft runtime libraries (the /MD or the /MDd compiler
|
|
||||||
option). Files without that suffix use static versions of the runtime
|
|
||||||
libraries (the /MT or the /MTd option). Please note that one must use
|
|
||||||
the same option to compile both gtest and the test code. If you use
|
|
||||||
Visual Studio 2005 or above, we recommend the -md version as /MD is
|
|
||||||
the default for new projects in these versions of Visual Studio.
|
|
||||||
|
|
||||||
On Mac OS X, open the gtest.xcodeproj in the xcode/ folder using
|
|
||||||
Xcode. Build the "gtest" target. The universal binary framework will
|
|
||||||
end up in your selected build directory (selected in the Xcode
|
|
||||||
"Preferences..." -> "Building" pane and defaults to xcode/build).
|
|
||||||
Alternatively, at the command line, enter:
|
|
||||||
|
|
||||||
xcodebuild
|
|
||||||
|
|
||||||
This will build the "Release" configuration of gtest.framework in your
|
|
||||||
default build location. See the "xcodebuild" man page for more
|
|
||||||
information about building different configurations and building in
|
|
||||||
different locations.
|
|
||||||
|
|
||||||
If you wish to use the Google Test Xcode project with Xcode 4.x and
|
|
||||||
above, you need to either:
|
|
||||||
* update the SDK configuration options in xcode/Config/General.xconfig.
|
|
||||||
Comment options SDKROOT, MACOS_DEPLOYMENT_TARGET, and GCC_VERSION. If
|
|
||||||
you choose this route you lose the ability to target earlier versions
|
|
||||||
of MacOS X.
|
|
||||||
* Install an SDK for an earlier version. This doesn't appear to be
|
|
||||||
supported by Apple, but has been reported to work
|
|
||||||
(http://stackoverflow.com/questions/5378518).
|
|
||||||
|
|
||||||
Tweaking Google Test
|
|
||||||
--------------------
|
|
||||||
|
|
||||||
Google Test can be used in diverse environments. The default
|
|
||||||
configuration may not work (or may not work well) out of the box in
|
|
||||||
some environments. However, you can easily tweak Google Test by
|
|
||||||
defining control macros on the compiler command line. Generally,
|
|
||||||
these macros are named like GTEST_XYZ and you define them to either 1
|
|
||||||
or 0 to enable or disable a certain feature.
|
|
||||||
|
|
||||||
We list the most frequently used macros below. For a complete list,
|
|
||||||
see file include/gtest/internal/gtest-port.h.
|
|
||||||
|
|
||||||
### Choosing a TR1 Tuple Library ###
|
|
||||||
|
|
||||||
Some Google Test features require the C++ Technical Report 1 (TR1)
|
|
||||||
tuple library, which is not yet available with all compilers. The
|
|
||||||
good news is that Google Test implements a subset of TR1 tuple that's
|
|
||||||
enough for its own need, and will automatically use this when the
|
|
||||||
compiler doesn't provide TR1 tuple.
|
|
||||||
|
|
||||||
Usually you don't need to care about which tuple library Google Test
|
|
||||||
uses. However, if your project already uses TR1 tuple, you need to
|
|
||||||
tell Google Test to use the same TR1 tuple library the rest of your
|
|
||||||
project uses, or the two tuple implementations will clash. To do
|
|
||||||
that, add
|
|
||||||
|
|
||||||
-DGTEST_USE_OWN_TR1_TUPLE=0
|
|
||||||
|
|
||||||
to the compiler flags while compiling Google Test and your tests. If
|
|
||||||
you want to force Google Test to use its own tuple library, just add
|
|
||||||
|
|
||||||
-DGTEST_USE_OWN_TR1_TUPLE=1
|
|
||||||
|
|
||||||
to the compiler flags instead.
|
|
||||||
|
|
||||||
If you don't want Google Test to use tuple at all, add
|
|
||||||
|
|
||||||
-DGTEST_HAS_TR1_TUPLE=0
|
|
||||||
|
|
||||||
and all features using tuple will be disabled.
|
|
||||||
|
|
||||||
### Multi-threaded Tests ###
|
|
||||||
|
|
||||||
Google Test is thread-safe where the pthread library is available.
|
|
||||||
After #include "gtest/gtest.h", you can check the GTEST_IS_THREADSAFE
|
|
||||||
macro to see whether this is the case (yes if the macro is #defined to
|
|
||||||
1, no if it's undefined.).
|
|
||||||
|
|
||||||
If Google Test doesn't correctly detect whether pthread is available
|
|
||||||
in your environment, you can force it with
|
|
||||||
|
|
||||||
-DGTEST_HAS_PTHREAD=1
|
|
||||||
|
|
||||||
or
|
|
||||||
|
|
||||||
-DGTEST_HAS_PTHREAD=0
|
|
||||||
|
|
||||||
When Google Test uses pthread, you may need to add flags to your
|
|
||||||
compiler and/or linker to select the pthread library, or you'll get
|
|
||||||
link errors. If you use the CMake script or the deprecated Autotools
|
|
||||||
script, this is taken care of for you. If you use your own build
|
|
||||||
script, you'll need to read your compiler and linker's manual to
|
|
||||||
figure out what flags to add.
|
|
||||||
|
|
||||||
### As a Shared Library (DLL) ###
|
|
||||||
|
|
||||||
Google Test is compact, so most users can build and link it as a
|
|
||||||
static library for the simplicity. You can choose to use Google Test
|
|
||||||
as a shared library (known as a DLL on Windows) if you prefer.
|
|
||||||
|
|
||||||
To compile *gtest* as a shared library, add
|
|
||||||
|
|
||||||
-DGTEST_CREATE_SHARED_LIBRARY=1
|
|
||||||
|
|
||||||
to the compiler flags. You'll also need to tell the linker to produce
|
|
||||||
a shared library instead - consult your linker's manual for how to do
|
|
||||||
it.
|
|
||||||
|
|
||||||
To compile your *tests* that use the gtest shared library, add
|
|
||||||
|
|
||||||
-DGTEST_LINKED_AS_SHARED_LIBRARY=1
|
|
||||||
|
|
||||||
to the compiler flags.
|
|
||||||
|
|
||||||
Note: while the above steps aren't technically necessary today when
|
|
||||||
using some compilers (e.g. GCC), they may become necessary in the
|
|
||||||
future, if we decide to improve the speed of loading the library (see
|
|
||||||
http://gcc.gnu.org/wiki/Visibility for details). Therefore you are
|
|
||||||
recommended to always add the above flags when using Google Test as a
|
|
||||||
shared library. Otherwise a future release of Google Test may break
|
|
||||||
your build script.
|
|
||||||
|
|
||||||
### Avoiding Macro Name Clashes ###
|
|
||||||
|
|
||||||
In C++, macros don't obey namespaces. Therefore two libraries that
|
|
||||||
both define a macro of the same name will clash if you #include both
|
|
||||||
definitions. In case a Google Test macro clashes with another
|
|
||||||
library, you can force Google Test to rename its macro to avoid the
|
|
||||||
conflict.
|
|
||||||
|
|
||||||
Specifically, if both Google Test and some other code define macro
|
|
||||||
FOO, you can add
|
|
||||||
|
|
||||||
-DGTEST_DONT_DEFINE_FOO=1
|
|
||||||
|
|
||||||
to the compiler flags to tell Google Test to change the macro's name
|
|
||||||
from FOO to GTEST_FOO. Currently FOO can be FAIL, SUCCEED, or TEST.
|
|
||||||
For example, with -DGTEST_DONT_DEFINE_TEST=1, you'll need to write
|
|
||||||
|
|
||||||
GTEST_TEST(SomeTest, DoesThis) { ... }
|
|
||||||
|
|
||||||
instead of
|
|
||||||
|
|
||||||
TEST(SomeTest, DoesThis) { ... }
|
|
||||||
|
|
||||||
in order to define a test.
|
|
||||||
|
|
||||||
Upgrating from an Earlier Version
|
|
||||||
---------------------------------
|
|
||||||
|
|
||||||
We strive to keep Google Test releases backward compatible.
|
|
||||||
Sometimes, though, we have to make some breaking changes for the
|
|
||||||
users' long-term benefits. This section describes what you'll need to
|
|
||||||
do if you are upgrading from an earlier version of Google Test.
|
|
||||||
|
|
||||||
### Upgrading from 1.3.0 or Earlier ###
|
|
||||||
|
|
||||||
You may need to explicitly enable or disable Google Test's own TR1
|
|
||||||
tuple library. See the instructions in section "Choosing a TR1 Tuple
|
|
||||||
Library".
|
|
||||||
|
|
||||||
### Upgrading from 1.4.0 or Earlier ###
|
|
||||||
|
|
||||||
The Autotools build script (configure + make) is no longer officially
|
|
||||||
supportted. You are encouraged to migrate to your own build system or
|
|
||||||
use CMake. If you still need to use Autotools, you can find
|
|
||||||
instructions in the README file from Google Test 1.4.0.
|
|
||||||
|
|
||||||
On platforms where the pthread library is available, Google Test uses
|
|
||||||
it in order to be thread-safe. See the "Multi-threaded Tests" section
|
|
||||||
for what this means to your build script.
|
|
||||||
|
|
||||||
If you use Microsoft Visual C++ 7.1 with exceptions disabled, Google
|
|
||||||
Test will no longer compile. This should affect very few people, as a
|
|
||||||
large portion of STL (including <string>) doesn't compile in this mode
|
|
||||||
anyway. We decided to stop supporting it in order to greatly simplify
|
|
||||||
Google Test's implementation.
|
|
||||||
|
|
||||||
Developing Google Test
|
|
||||||
----------------------
|
|
||||||
|
|
||||||
This section discusses how to make your own changes to Google Test.
|
|
||||||
|
|
||||||
### Testing Google Test Itself ###
|
|
||||||
|
|
||||||
To make sure your changes work as intended and don't break existing
|
|
||||||
functionality, you'll want to compile and run Google Test's own tests.
|
|
||||||
For that you can use CMake:
|
|
||||||
|
|
||||||
mkdir mybuild
|
|
||||||
cd mybuild
|
|
||||||
cmake -Dgtest_build_tests=ON ${GTEST_DIR}
|
|
||||||
|
|
||||||
Make sure you have Python installed, as some of Google Test's tests
|
|
||||||
are written in Python. If the cmake command complains about not being
|
|
||||||
able to find Python ("Could NOT find PythonInterp (missing:
|
|
||||||
PYTHON_EXECUTABLE)"), try telling it explicitly where your Python
|
|
||||||
executable can be found:
|
|
||||||
|
|
||||||
cmake -DPYTHON_EXECUTABLE=path/to/python -Dgtest_build_tests=ON ${GTEST_DIR}
|
|
||||||
|
|
||||||
Next, you can build Google Test and all of its own tests. On *nix,
|
|
||||||
this is usually done by 'make'. To run the tests, do
|
|
||||||
|
|
||||||
make test
|
|
||||||
|
|
||||||
All tests should pass.
|
|
||||||
|
|
||||||
### Regenerating Source Files ###
|
|
||||||
|
|
||||||
Some of Google Test's source files are generated from templates (not
|
|
||||||
in the C++ sense) using a script. A template file is named FOO.pump,
|
|
||||||
where FOO is the name of the file it will generate. For example, the
|
|
||||||
file include/gtest/internal/gtest-type-util.h.pump is used to generate
|
|
||||||
gtest-type-util.h in the same directory.
|
|
||||||
|
|
||||||
Normally you don't need to worry about regenerating the source files,
|
|
||||||
unless you need to modify them. In that case, you should modify the
|
|
||||||
corresponding .pump files instead and run the pump.py Python script to
|
|
||||||
regenerate them. You can find pump.py in the scripts/ directory.
|
|
||||||
Read the Pump manual [2] for how to use it.
|
|
||||||
|
|
||||||
[2] http://code.google.com/p/googletest/wiki/PumpManual
|
|
||||||
|
|
||||||
### Contributing a Patch ###
|
|
||||||
|
|
||||||
We welcome patches. Please read the Google Test developer's guide [3]
|
|
||||||
for how you can contribute. In particular, make sure you have signed
|
|
||||||
the Contributor License Agreement, or we won't be able to accept the
|
|
||||||
patch.
|
|
||||||
|
|
||||||
[3] http://code.google.com/p/googletest/wiki/GoogleTestDevGuide
|
|
||||||
|
|
||||||
Happy testing!
|
|
|
@ -0,0 +1,280 @@
|
||||||
|
|
||||||
|
### Generic Build Instructions ###
|
||||||
|
|
||||||
|
#### Setup ####
|
||||||
|
|
||||||
|
To build Google Test and your tests that use it, you need to tell your
|
||||||
|
build system where to find its headers and source files. The exact
|
||||||
|
way to do it depends on which build system you use, and is usually
|
||||||
|
straightforward.
|
||||||
|
|
||||||
|
#### Build ####
|
||||||
|
|
||||||
|
Suppose you put Google Test in directory `${GTEST_DIR}`. To build it,
|
||||||
|
create a library build target (or a project as called by Visual Studio
|
||||||
|
and Xcode) to compile
|
||||||
|
|
||||||
|
${GTEST_DIR}/src/gtest-all.cc
|
||||||
|
|
||||||
|
with `${GTEST_DIR}/include` in the system header search path and `${GTEST_DIR}`
|
||||||
|
in the normal header search path. Assuming a Linux-like system and gcc,
|
||||||
|
something like the following will do:
|
||||||
|
|
||||||
|
g++ -isystem ${GTEST_DIR}/include -I${GTEST_DIR} \
|
||||||
|
-pthread -c ${GTEST_DIR}/src/gtest-all.cc
|
||||||
|
ar -rv libgtest.a gtest-all.o
|
||||||
|
|
||||||
|
(We need `-pthread` as Google Test uses threads.)
|
||||||
|
|
||||||
|
Next, you should compile your test source file with
|
||||||
|
`${GTEST_DIR}/include` in the system header search path, and link it
|
||||||
|
with gtest and any other necessary libraries:
|
||||||
|
|
||||||
|
g++ -isystem ${GTEST_DIR}/include -pthread path/to/your_test.cc libgtest.a \
|
||||||
|
-o your_test
|
||||||
|
|
||||||
|
As an example, the make/ directory contains a Makefile that you can
|
||||||
|
use to build Google Test on systems where GNU make is available
|
||||||
|
(e.g. Linux, Mac OS X, and Cygwin). It doesn't try to build Google
|
||||||
|
Test's own tests. Instead, it just builds the Google Test library and
|
||||||
|
a sample test. You can use it as a starting point for your own build
|
||||||
|
script.
|
||||||
|
|
||||||
|
If the default settings are correct for your environment, the
|
||||||
|
following commands should succeed:
|
||||||
|
|
||||||
|
cd ${GTEST_DIR}/make
|
||||||
|
make
|
||||||
|
./sample1_unittest
|
||||||
|
|
||||||
|
If you see errors, try to tweak the contents of `make/Makefile` to make
|
||||||
|
them go away. There are instructions in `make/Makefile` on how to do
|
||||||
|
it.
|
||||||
|
|
||||||
|
### Using CMake ###
|
||||||
|
|
||||||
|
Google Test comes with a CMake build script (
|
||||||
|
[CMakeLists.txt](CMakeLists.txt)) that can be used on a wide range of platforms ("C" stands for
|
||||||
|
cross-platform.). If you don't have CMake installed already, you can
|
||||||
|
download it for free from <http://www.cmake.org/>.
|
||||||
|
|
||||||
|
CMake works by generating native makefiles or build projects that can
|
||||||
|
be used in the compiler environment of your choice. The typical
|
||||||
|
workflow starts with:
|
||||||
|
|
||||||
|
mkdir mybuild # Create a directory to hold the build output.
|
||||||
|
cd mybuild
|
||||||
|
cmake ${GTEST_DIR} # Generate native build scripts.
|
||||||
|
|
||||||
|
If you want to build Google Test's samples, you should replace the
|
||||||
|
last command with
|
||||||
|
|
||||||
|
cmake -Dgtest_build_samples=ON ${GTEST_DIR}
|
||||||
|
|
||||||
|
If you are on a \*nix system, you should now see a Makefile in the
|
||||||
|
current directory. Just type 'make' to build gtest.
|
||||||
|
|
||||||
|
If you use Windows and have Visual Studio installed, a `gtest.sln` file
|
||||||
|
and several `.vcproj` files will be created. You can then build them
|
||||||
|
using Visual Studio.
|
||||||
|
|
||||||
|
On Mac OS X with Xcode installed, a `.xcodeproj` file will be generated.
|
||||||
|
|
||||||
|
### Legacy Build Scripts ###
|
||||||
|
|
||||||
|
Before settling on CMake, we have been providing hand-maintained build
|
||||||
|
projects/scripts for Visual Studio, Xcode, and Autotools. While we
|
||||||
|
continue to provide them for convenience, they are not actively
|
||||||
|
maintained any more. We highly recommend that you follow the
|
||||||
|
instructions in the previous two sections to integrate Google Test
|
||||||
|
with your existing build system.
|
||||||
|
|
||||||
|
If you still need to use the legacy build scripts, here's how:
|
||||||
|
|
||||||
|
The msvc\ folder contains two solutions with Visual C++ projects.
|
||||||
|
Open the `gtest.sln` or `gtest-md.sln` file using Visual Studio, and you
|
||||||
|
are ready to build Google Test the same way you build any Visual
|
||||||
|
Studio project. Files that have names ending with -md use DLL
|
||||||
|
versions of Microsoft runtime libraries (the /MD or the /MDd compiler
|
||||||
|
option). Files without that suffix use static versions of the runtime
|
||||||
|
libraries (the /MT or the /MTd option). Please note that one must use
|
||||||
|
the same option to compile both gtest and the test code. If you use
|
||||||
|
Visual Studio 2005 or above, we recommend the -md version as /MD is
|
||||||
|
the default for new projects in these versions of Visual Studio.
|
||||||
|
|
||||||
|
On Mac OS X, open the `gtest.xcodeproj` in the `xcode/` folder using
|
||||||
|
Xcode. Build the "gtest" target. The universal binary framework will
|
||||||
|
end up in your selected build directory (selected in the Xcode
|
||||||
|
"Preferences..." -> "Building" pane and defaults to xcode/build).
|
||||||
|
Alternatively, at the command line, enter:
|
||||||
|
|
||||||
|
xcodebuild
|
||||||
|
|
||||||
|
This will build the "Release" configuration of gtest.framework in your
|
||||||
|
default build location. See the "xcodebuild" man page for more
|
||||||
|
information about building different configurations and building in
|
||||||
|
different locations.
|
||||||
|
|
||||||
|
If you wish to use the Google Test Xcode project with Xcode 4.x and
|
||||||
|
above, you need to either:
|
||||||
|
|
||||||
|
* update the SDK configuration options in xcode/Config/General.xconfig.
|
||||||
|
Comment options `SDKROOT`, `MACOS_DEPLOYMENT_TARGET`, and `GCC_VERSION`. If
|
||||||
|
you choose this route you lose the ability to target earlier versions
|
||||||
|
of MacOS X.
|
||||||
|
* Install an SDK for an earlier version. This doesn't appear to be
|
||||||
|
supported by Apple, but has been reported to work
|
||||||
|
(http://stackoverflow.com/questions/5378518).
|
||||||
|
|
||||||
|
### Tweaking Google Test ###
|
||||||
|
|
||||||
|
Google Test can be used in diverse environments. The default
|
||||||
|
configuration may not work (or may not work well) out of the box in
|
||||||
|
some environments. However, you can easily tweak Google Test by
|
||||||
|
defining control macros on the compiler command line. Generally,
|
||||||
|
these macros are named like `GTEST_XYZ` and you define them to either 1
|
||||||
|
or 0 to enable or disable a certain feature.
|
||||||
|
|
||||||
|
We list the most frequently used macros below. For a complete list,
|
||||||
|
see file [include/gtest/internal/gtest-port.h](include/gtest/internal/gtest-port.h).
|
||||||
|
|
||||||
|
### Choosing a TR1 Tuple Library ###
|
||||||
|
|
||||||
|
Some Google Test features require the C++ Technical Report 1 (TR1)
|
||||||
|
tuple library, which is not yet available with all compilers. The
|
||||||
|
good news is that Google Test implements a subset of TR1 tuple that's
|
||||||
|
enough for its own need, and will automatically use this when the
|
||||||
|
compiler doesn't provide TR1 tuple.
|
||||||
|
|
||||||
|
Usually you don't need to care about which tuple library Google Test
|
||||||
|
uses. However, if your project already uses TR1 tuple, you need to
|
||||||
|
tell Google Test to use the same TR1 tuple library the rest of your
|
||||||
|
project uses, or the two tuple implementations will clash. To do
|
||||||
|
that, add
|
||||||
|
|
||||||
|
-DGTEST_USE_OWN_TR1_TUPLE=0
|
||||||
|
|
||||||
|
to the compiler flags while compiling Google Test and your tests. If
|
||||||
|
you want to force Google Test to use its own tuple library, just add
|
||||||
|
|
||||||
|
-DGTEST_USE_OWN_TR1_TUPLE=1
|
||||||
|
|
||||||
|
to the compiler flags instead.
|
||||||
|
|
||||||
|
If you don't want Google Test to use tuple at all, add
|
||||||
|
|
||||||
|
-DGTEST_HAS_TR1_TUPLE=0
|
||||||
|
|
||||||
|
and all features using tuple will be disabled.
|
||||||
|
|
||||||
|
### Multi-threaded Tests ###
|
||||||
|
|
||||||
|
Google Test is thread-safe where the pthread library is available.
|
||||||
|
After `#include "gtest/gtest.h"`, you can check the `GTEST_IS_THREADSAFE`
|
||||||
|
macro to see whether this is the case (yes if the macro is `#defined` to
|
||||||
|
1, no if it's undefined.).
|
||||||
|
|
||||||
|
If Google Test doesn't correctly detect whether pthread is available
|
||||||
|
in your environment, you can force it with
|
||||||
|
|
||||||
|
-DGTEST_HAS_PTHREAD=1
|
||||||
|
|
||||||
|
or
|
||||||
|
|
||||||
|
-DGTEST_HAS_PTHREAD=0
|
||||||
|
|
||||||
|
When Google Test uses pthread, you may need to add flags to your
|
||||||
|
compiler and/or linker to select the pthread library, or you'll get
|
||||||
|
link errors. If you use the CMake script or the deprecated Autotools
|
||||||
|
script, this is taken care of for you. If you use your own build
|
||||||
|
script, you'll need to read your compiler and linker's manual to
|
||||||
|
figure out what flags to add.
|
||||||
|
|
||||||
|
### As a Shared Library (DLL) ###
|
||||||
|
|
||||||
|
Google Test is compact, so most users can build and link it as a
|
||||||
|
static library for the simplicity. You can choose to use Google Test
|
||||||
|
as a shared library (known as a DLL on Windows) if you prefer.
|
||||||
|
|
||||||
|
To compile *gtest* as a shared library, add
|
||||||
|
|
||||||
|
-DGTEST_CREATE_SHARED_LIBRARY=1
|
||||||
|
|
||||||
|
to the compiler flags. You'll also need to tell the linker to produce
|
||||||
|
a shared library instead - consult your linker's manual for how to do
|
||||||
|
it.
|
||||||
|
|
||||||
|
To compile your *tests* that use the gtest shared library, add
|
||||||
|
|
||||||
|
-DGTEST_LINKED_AS_SHARED_LIBRARY=1
|
||||||
|
|
||||||
|
to the compiler flags.
|
||||||
|
|
||||||
|
Note: while the above steps aren't technically necessary today when
|
||||||
|
using some compilers (e.g. GCC), they may become necessary in the
|
||||||
|
future, if we decide to improve the speed of loading the library (see
|
||||||
|
<http://gcc.gnu.org/wiki/Visibility> for details). Therefore you are
|
||||||
|
recommended to always add the above flags when using Google Test as a
|
||||||
|
shared library. Otherwise a future release of Google Test may break
|
||||||
|
your build script.
|
||||||
|
|
||||||
|
### Avoiding Macro Name Clashes ###
|
||||||
|
|
||||||
|
In C++, macros don't obey namespaces. Therefore two libraries that
|
||||||
|
both define a macro of the same name will clash if you `#include` both
|
||||||
|
definitions. In case a Google Test macro clashes with another
|
||||||
|
library, you can force Google Test to rename its macro to avoid the
|
||||||
|
conflict.
|
||||||
|
|
||||||
|
Specifically, if both Google Test and some other code define macro
|
||||||
|
FOO, you can add
|
||||||
|
|
||||||
|
-DGTEST_DONT_DEFINE_FOO=1
|
||||||
|
|
||||||
|
to the compiler flags to tell Google Test to change the macro's name
|
||||||
|
from `FOO` to `GTEST_FOO`. Currently `FOO` can be `FAIL`, `SUCCEED`,
|
||||||
|
or `TEST`. For example, with `-DGTEST_DONT_DEFINE_TEST=1`, you'll
|
||||||
|
need to write
|
||||||
|
|
||||||
|
GTEST_TEST(SomeTest, DoesThis) { ... }
|
||||||
|
|
||||||
|
instead of
|
||||||
|
|
||||||
|
TEST(SomeTest, DoesThis) { ... }
|
||||||
|
|
||||||
|
in order to define a test.
|
||||||
|
|
||||||
|
## Developing Google Test ##
|
||||||
|
|
||||||
|
This section discusses how to make your own changes to Google Test.
|
||||||
|
|
||||||
|
### Testing Google Test Itself ###
|
||||||
|
|
||||||
|
To make sure your changes work as intended and don't break existing
|
||||||
|
functionality, you'll want to compile and run Google Test's own tests.
|
||||||
|
For that you can use CMake:
|
||||||
|
|
||||||
|
mkdir mybuild
|
||||||
|
cd mybuild
|
||||||
|
cmake -Dgtest_build_tests=ON ${GTEST_DIR}
|
||||||
|
|
||||||
|
Make sure you have Python installed, as some of Google Test's tests
|
||||||
|
are written in Python. If the cmake command complains about not being
|
||||||
|
able to find Python (`Could NOT find PythonInterp (missing:
|
||||||
|
PYTHON_EXECUTABLE)`), try telling it explicitly where your Python
|
||||||
|
executable can be found:
|
||||||
|
|
||||||
|
cmake -DPYTHON_EXECUTABLE=path/to/python -Dgtest_build_tests=ON ${GTEST_DIR}
|
||||||
|
|
||||||
|
Next, you can build Google Test and all of its own tests. On \*nix,
|
||||||
|
this is usually done by 'make'. To run the tests, do
|
||||||
|
|
||||||
|
make test
|
||||||
|
|
||||||
|
All tests should pass.
|
||||||
|
|
||||||
|
Normally you don't need to worry about regenerating the source files,
|
||||||
|
unless you need to modify them. In that case, you should modify the
|
||||||
|
corresponding .pump files instead and run the pump.py Python script to
|
||||||
|
regenerate them. You can find pump.py in the [scripts/](scripts/) directory.
|
||||||
|
Read the [Pump manual](docs/PumpManual.md) for how to use it.
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue