Compare commits

..

9 Commits

Author SHA1 Message Date
Alex Converse
2898c6728d PRecompute token tab
Change-Id: I85e172352dacf7a990d8d9296e071f9d603fcb7b
2015-10-14 18:03:36 -07:00
Alex Converse
c62859fe76 Write tokens with rans
Change-Id: I3009ec1cf54a36c96b59d8203bc01f4fe82145a0
2015-10-14 17:57:56 -07:00
Alex Converse
365e37193c bar
Change-Id: I5d5acdde6ea98b986d8e0c9247df20a41c56950b
2015-09-14 11:40:34 -07:00
Alex Converse
f2b5185d76 Avoid conflicting with the superframe marker
Change-Id: If77f415380528d388a4bc330ec843dd58fac2f01
2015-09-11 16:57:15 -07:00
Alex Converse
5720143261 fencepost
Change-Id: Ib0f988e11f80d3684d37119f457ca795f0ad16fa
2015-09-11 16:37:01 -07:00
Alex Converse
911f6b036e tmp
Change-Id: I6121c07f4af8065c1f4c4488e50990f3d71cc4c1
2015-09-11 14:17:59 -07:00
Alex Converse
4858f93633 tmp ans
Change-Id: Id5dadc88fccca610fc10495352590782eca4a62f
2015-09-11 13:02:45 -07:00
Alex Converse
e4e605623b WIP reverse tree writing still using the old boolcoder.
Change-Id: I41f056f4a7d360f1085c6435deeea5b3bcf32dbe
2015-09-09 20:36:18 -07:00
Alex Converse
9245a0661d WIP move tokens to end of tile
Change-Id: I220de204642734f68f7bf54ec3d406f8e39f0382
2015-09-09 18:13:51 -07:00
967 changed files with 186224 additions and 112726 deletions

View File

@@ -1,68 +0,0 @@
---
Language: Cpp
# BasedOnStyle: Google
# Generated with clang-format 3.7.1
AccessModifierOffset: -1
AlignAfterOpenBracket: true
AlignConsecutiveAssignments: false
AlignEscapedNewlinesLeft: true
AlignOperands: true
AlignTrailingComments: true
AllowAllParametersOfDeclarationOnNextLine: true
AllowShortBlocksOnASingleLine: false
AllowShortCaseLabelsOnASingleLine: true
AllowShortFunctionsOnASingleLine: All
AllowShortIfStatementsOnASingleLine: true
AllowShortLoopsOnASingleLine: true
AlwaysBreakAfterDefinitionReturnType: None
AlwaysBreakBeforeMultilineStrings: true
AlwaysBreakTemplateDeclarations: true
BinPackArguments: true
BinPackParameters: true
BreakBeforeBinaryOperators: None
BreakBeforeBraces: Attach
BreakBeforeTernaryOperators: true
BreakConstructorInitializersBeforeComma: false
ColumnLimit: 80
CommentPragmas: '^ IWYU pragma:'
ConstructorInitializerAllOnOneLineOrOnePerLine: false
ConstructorInitializerIndentWidth: 4
ContinuationIndentWidth: 4
Cpp11BracedListStyle: false
DerivePointerAlignment: false
DisableFormat: false
ExperimentalAutoDetectBinPacking: false
ForEachMacros: [ foreach, Q_FOREACH, BOOST_FOREACH ]
IndentCaseLabels: true
IndentWidth: 2
IndentWrappedFunctionNames: false
KeepEmptyLinesAtTheStartOfBlocks: false
MacroBlockBegin: ''
MacroBlockEnd: ''
MaxEmptyLinesToKeep: 1
NamespaceIndentation: None
ObjCBlockIndentWidth: 2
ObjCSpaceAfterProperty: false
ObjCSpaceBeforeProtocolList: false
PenaltyBreakBeforeFirstCallParameter: 1
PenaltyBreakComment: 300
PenaltyBreakFirstLessLess: 120
PenaltyBreakString: 1000
PenaltyExcessCharacter: 1000000
PenaltyReturnTypeOnItsOwnLine: 200
PointerAlignment: Right
SpaceAfterCStyleCast: false
SpaceBeforeAssignmentOperators: true
SpaceBeforeParens: ControlStatements
SpaceInEmptyParentheses: false
SpacesBeforeTrailingComments: 2
SpacesInAngles: false
SpacesInContainerLiterals: true
SpacesInCStyleCastParentheses: false
SpacesInParentheses: false
SpacesInSquareBrackets: false
Standard: Auto
TabWidth: 8
UseTab: Never
...

View File

@@ -1,37 +1,26 @@
Adrian Grange <agrange@google.com>
Aex Converse <aconverse@google.com>
Aex Converse <aconverse@google.com> <alex.converse@gmail.com>
Alex Converse <aconverse@google.com> <alex.converse@gmail.com>
Alexis Ballier <aballier@gentoo.org> <alexis.ballier@gmail.com>
Alpha Lam <hclam@google.com> <hclam@chromium.org>
Daniele Castagna <dcastagna@chromium.org> <dcastagna@google.com>
Deb Mukherjee <debargha@google.com>
Erik Niemeyer <erik.a.niemeyer@intel.com> <erik.a.niemeyer@gmail.com>
Guillaume Martres <gmartres@google.com> <smarter3@gmail.com>
Hangyu Kuang <hkuang@google.com>
Hui Su <huisu@google.com>
Jacky Chen <jackychen@google.com>
Jim Bankoski <jimbankoski@google.com>
Johann Koenig <johannkoenig@google.com>
Johann Koenig <johannkoenig@google.com> <johann.koenig@duck.com>
Johann Koenig <johannkoenig@google.com> <johann.koenig@gmail.com>
Johann Koenig <johannkoenig@google.com> <johannkoenig@chromium.org>
John Koleszar <jkoleszar@google.com>
Joshua Litt <joshualitt@google.com> <joshualitt@chromium.org>
Marco Paniconi <marpan@google.com>
Marco Paniconi <marpan@google.com> <marpan@chromium.org>
Pascal Massimino <pascal.massimino@gmail.com>
Paul Wilkins <paulwilkins@google.com>
Peter de Rivaz <peter.derivaz@gmail.com>
Peter de Rivaz <peter.derivaz@gmail.com> <peter.derivaz@argondesign.com>
Ralph Giles <giles@xiph.org> <giles@entropywave.com>
Ralph Giles <giles@xiph.org> <giles@mozilla.com>
Ronald S. Bultje <rsbultje@gmail.com> <rbultje@google.com>
Sami Pietilä <samipietila@google.com>
Tamar Levy <tamar.levy@intel.com>
Tamar Levy <tamar.levy@intel.com> <levytamar82@gmail.com>
Tero Rintaluoma <teror@google.com> <tero.rintaluoma@on2.com>
Timothy B. Terriberry <tterribe@xiph.org> <tterriberry@mozilla.com>
Timothy B. Terriberry <tterribe@xiph.org> Tim Terriberry <tterriberry@mozilla.com>
Tom Finegan <tomfinegan@google.com>
Tom Finegan <tomfinegan@google.com> <tomfinegan@chromium.org>
Yaowu Xu <yaowu@google.com> <yaowu@xuyaowu.com>
Yaowu Xu <yaowu@google.com> <Yaowu Xu>

21
AUTHORS
View File

@@ -5,9 +5,9 @@ Aaron Watry <awatry@gmail.com>
Abo Talib Mahfoodh <ab.mahfoodh@gmail.com>
Adam Xu <adam@xuyaowu.com>
Adrian Grange <agrange@google.com>
Aex Converse <aconverse@google.com>
Ahmad Sharif <asharif@google.com>
Alexander Voronov <avoronov@graphics.cs.msu.ru>
Alex Converse <aconverse@google.com>
Alexis Ballier <aballier@gentoo.org>
Alok Ahuja <waveletcoeff@gmail.com>
Alpha Lam <hclam@google.com>
@@ -16,21 +16,17 @@ Ami Fischman <fischman@chromium.org>
Andoni Morales Alastruey <ylatuya@gmail.com>
Andres Mejia <mcitadel@gmail.com>
Andrew Russell <anrussell@google.com>
Angie Chiang <angiebird@google.com>
Aron Rosenberg <arosenberg@logitech.com>
Attila Nagy <attilanagy@google.com>
Brion Vibber <bvibber@wikimedia.org>
changjun.yang <changjun.yang@intel.com>
Charles 'Buck' Krasic <ckrasic@google.com>
chm <chm@rock-chips.com>
Christian Duvivier <cduvivier@google.com>
Daniele Castagna <dcastagna@chromium.org>
Daniel Kang <ddkang@google.com>
Deb Mukherjee <debargha@google.com>
Dim Temp <dimtemp0@gmail.com>
Dmitry Kovalev <dkovalev@google.com>
Dragan Mrdjan <dmrdjan@mips.com>
Ed Baker <edward.baker@intel.com>
Ehsan Akhgari <ehsan.akhgari@gmail.com>
Erik Niemeyer <erik.a.niemeyer@intel.com>
Fabio Pedretti <fabio.ped@libero.it>
@@ -38,8 +34,6 @@ Frank Galligan <fgalligan@google.com>
Fredrik Söderquist <fs@opera.com>
Fritz Koenig <frkoenig@google.com>
Gaute Strokkenes <gaute.strokkenes@broadcom.com>
Geza Lore <gezalore@gmail.com>
Ghislain MARY <ghislainmary2@gmail.com>
Giuseppe Scrivano <gscrivano@gnu.org>
Gordana Cmiljanovic <gordana.cmiljanovic@imgtec.com>
Guillaume Martres <gmartres@google.com>
@@ -57,27 +51,22 @@ James Zern <jzern@google.com>
Jan Gerber <j@mailb.org>
Jan Kratochvil <jan.kratochvil@redhat.com>
Janne Salonen <jsalonen@google.com>
Jean-Yves Avenard <jyavenard@mozilla.com>
Jeff Faust <jfaust@google.com>
Jeff Muizelaar <jmuizelaar@mozilla.com>
Jeff Petkau <jpet@chromium.org>
Jia Jia <jia.jia@linaro.org>
Jian Zhou <zhoujian@google.com>
Jim Bankoski <jimbankoski@google.com>
Jingning Han <jingning@google.com>
Joey Parrish <joeyparrish@google.com>
Johann Koenig <johannkoenig@google.com>
John Koleszar <jkoleszar@google.com>
Johnny Klonaris <google@jawknee.com>
John Stark <jhnstrk@gmail.com>
Joshua Bleecher Snyder <josh@treelinelabs.com>
Joshua Litt <joshualitt@google.com>
Julia Robson <juliamrobson@gmail.com>
Justin Clift <justin@salasaga.org>
Justin Lebar <justin.lebar@gmail.com>
KO Myung-Hun <komh@chollian.net>
Lawrence Velázquez <larryv@macports.org>
Linfeng Zhang <linfengz@google.com>
Lou Quillio <louquillio@google.com>
Luca Barbato <lu_zero@gentoo.org>
Makoto Kato <makoto.kt@gmail.com>
@@ -93,7 +82,6 @@ Mike Hommey <mhommey@mozilla.com>
Mikhal Shemer <mikhal@google.com>
Minghai Shang <minghai@google.com>
Morton Jonuschat <yabawock@gmail.com>
Nico Weber <thakis@chromium.org>
Parag Salasakar <img.mips1@gmail.com>
Pascal Massimino <pascal.massimino@gmail.com>
Patrik Westin <patrik.westin@gmail.com>
@@ -108,17 +96,14 @@ Rafael Ávila de Espíndola <rafael.espindola@gmail.com>
Rafaël Carré <funman@videolan.org>
Ralph Giles <giles@xiph.org>
Rob Bradford <rob@linux.intel.com>
Ronald S. Bultje <rsbultje@gmail.com>
Ronald S. Bultje <rbultje@google.com>
Rui Ueyama <ruiu@google.com>
Sami Pietilä <samipietila@google.com>
Sasi Inguva <isasi@google.com>
Scott Graham <scottmg@chromium.org>
Scott LaVarnway <slavarnway@google.com>
Sean McGovern <gseanmcg@gmail.com>
Sergey Kolomenkin <kolomenkin@gmail.com>
Sergey Ulanov <sergeyu@chromium.org>
Shimon Doodkin <helpmepro1@gmail.com>
Shunyao Li <shunyaoli@google.com>
Stefan Holmer <holmer@google.com>
Suman Sunkara <sunkaras@google.com>
Taekhyun Kim <takim@nvidia.com>
@@ -132,10 +117,8 @@ Timothy B. Terriberry <tterribe@xiph.org>
Tom Finegan <tomfinegan@google.com>
Vignesh Venkatasubramanian <vigneshv@google.com>
Yaowu Xu <yaowu@google.com>
Yi Luo <luoyi@google.com>
Yongzhe Wang <yongzhe@google.com>
Yunqing Wang <yunqingwang@google.com>
Yury Gitman <yuryg@google.com>
Zoe Liu <zoeliu@google.com>
Google Inc.
The Mozilla Foundation

View File

@@ -1,49 +1,7 @@
2016-07-20 v1.6.0 "Khaki Campbell Duck"
This release improves upon the VP9 encoder and speeds up the encoding and
decoding processes.
- Upgrading:
This release is ABI incompatible with 1.5.0 due to a new 'color_range' enum
in vpx_image and some minor changes to the VP8_COMP structure.
The default key frame interval for VP9 has changed from 128 to 9999.
- Enhancement:
A core focus has been performance for low end Intel processors. SSSE3
instructions such as 'pshufb' have been avoided and instructions have been
reordered to better accommodate the more constrained pipelines.
As a result, devices based on Celeron processors have seen substantial
decoding improvements. From Indian Runner Duck to Javan Whistling Duck,
decoding speed improved between 10 and 30%. Between Javan Whistling Duck
and Khaki Campbell Duck, it improved another 10 to 15%.
While Celeron benefited most, Core-i5 also improved 5% and 10% between the
respective releases.
Realtime performance for WebRTC for both speed and quality has received a
lot of attention.
- Bug Fixes:
A number of fuzzing issues, found variously by Mozilla, Chromium and others,
have been fixed and we strongly recommend updating.
2015-11-09 v1.5.0 "Javan Whistling Duck"
This release improves upon the VP9 encoder and speeds up the encoding and
decoding processes.
- Upgrading:
This release is ABI incompatible with 1.4.0. It drops deprecated VP8
controls and adds a variety of VP9 controls for testing.
The vpxenc utility now prefers VP9 by default.
- Enhancements:
Faster VP9 encoding and decoding
Smaller library size by combining functions used by VP8 and VP9
- Bug Fixes:
A variety of fuzzing issues
xxxx-yy-zz v1.4.0 "Changes for next release"
vpxenc is changed to use VP9 by default.
Encoder controls added for 1 pass SVC.
Decoder control to toggle on/off loopfilter.
2015-04-03 v1.4.0 "Indian Runner Duck"
This release includes significant improvements to the VP9 codec.

32
README
View File

@@ -1,4 +1,4 @@
README - 20 July 2016
README - 23 March 2015
Welcome to the WebM VP8/VP9 Codec SDK!
@@ -47,8 +47,11 @@ COMPILING THE APPLICATIONS/LIBRARIES:
--help output of the configure script. As of this writing, the list of
available targets is:
armv6-darwin-gcc
armv6-linux-rvct
armv6-linux-gcc
armv6-none-rvct
arm64-darwin-gcc
arm64-linux-gcc
armv7-android-gcc
armv7-darwin-gcc
armv7-linux-rvct
@@ -58,7 +61,6 @@ COMPILING THE APPLICATIONS/LIBRARIES:
armv7-win32-vs12
armv7-win32-vs14
armv7s-darwin-gcc
armv8-linux-gcc
mips32-linux-gcc
mips64-linux-gcc
sparc-solaris-gcc
@@ -72,13 +74,15 @@ COMPILING THE APPLICATIONS/LIBRARIES:
x86-darwin12-gcc
x86-darwin13-gcc
x86-darwin14-gcc
x86-darwin15-gcc
x86-iphonesimulator-gcc
x86-linux-gcc
x86-linux-icc
x86-os2-gcc
x86-solaris-gcc
x86-win32-gcc
x86-win32-vs7
x86-win32-vs8
x86-win32-vs9
x86-win32-vs10
x86-win32-vs11
x86-win32-vs12
@@ -90,12 +94,13 @@ COMPILING THE APPLICATIONS/LIBRARIES:
x86_64-darwin12-gcc
x86_64-darwin13-gcc
x86_64-darwin14-gcc
x86_64-darwin15-gcc
x86_64-iphonesimulator-gcc
x86_64-linux-gcc
x86_64-linux-icc
x86_64-solaris-gcc
x86_64-win64-gcc
x86_64-win64-vs8
x86_64-win64-vs9
x86_64-win64-vs10
x86_64-win64-vs11
x86_64-win64-vs12
@@ -128,22 +133,7 @@ VP8/VP9 TEST VECTORS:
$ ./configure --enable-unit-tests
$ LIBVPX_TEST_DATA_PATH=../libvpx-test-data make testdata
CODE STYLE:
The coding style used by this project is enforced with clang-format using the
configuration contained in the .clang-format file in the root of the
repository.
Before pushing changes for review you can format your code with:
# Apply clang-format to modified .c, .h and .cc files
$ clang-format -i --style=file \
$(git diff --name-only --diff-filter=ACMR '*.[hc]' '*.cc')
Check the .clang-format file for the version used to generate it if there is
any difference between your local formatting and the review system.
See also: http://clang.llvm.org/docs/ClangFormat.html
SUPPORT
This library is an open source project supported by its community. Please
email webm-discuss@webmproject.org for help.
please email webm-discuss@webmproject.org for help.

92
args.c
View File

@@ -8,6 +8,7 @@
* be found in the AUTHORS file in the root of the source tree.
*/
#include <stdlib.h>
#include <string.h>
#include <limits.h>
@@ -21,6 +22,7 @@ extern void die(const char *fmt, ...) __attribute__((noreturn));
extern void die(const char *fmt, ...);
#endif
struct arg arg_init(char **argv) {
struct arg a;
@@ -35,22 +37,27 @@ struct arg arg_init(char **argv) {
int arg_match(struct arg *arg_, const struct arg_def *def, char **argv) {
struct arg arg;
if (!argv[0] || argv[0][0] != '-') return 0;
if (!argv[0] || argv[0][0] != '-')
return 0;
arg = arg_init(argv);
if (def->short_name && strlen(arg.argv[0]) == strlen(def->short_name) + 1 &&
!strcmp(arg.argv[0] + 1, def->short_name)) {
if (def->short_name
&& strlen(arg.argv[0]) == strlen(def->short_name) + 1
&& !strcmp(arg.argv[0] + 1, def->short_name)) {
arg.name = arg.argv[0] + 1;
arg.val = def->has_val ? arg.argv[1] : NULL;
arg.argv_step = def->has_val ? 2 : 1;
} else if (def->long_name) {
const size_t name_len = strlen(def->long_name);
if (strlen(arg.argv[0]) >= name_len + 2 && arg.argv[0][1] == '-' &&
!strncmp(arg.argv[0] + 2, def->long_name, name_len) &&
(arg.argv[0][name_len + 2] == '=' ||
arg.argv[0][name_len + 2] == '\0')) {
if (strlen(arg.argv[0]) >= name_len + 2
&& arg.argv[0][1] == '-'
&& !strncmp(arg.argv[0] + 2, def->long_name, name_len)
&& (arg.argv[0][name_len + 2] == '='
|| arg.argv[0][name_len + 2] == '\0')) {
arg.name = arg.argv[0] + 2;
arg.val = arg.name[name_len] == '=' ? arg.name + name_len + 1 : NULL;
arg.argv_step = 1;
@@ -63,7 +70,8 @@ int arg_match(struct arg *arg_, const struct arg_def *def, char **argv) {
if (arg.name && arg.val && !def->has_val)
die("Error: option %s requires no argument.\n", arg.name);
if (arg.name && (arg.val || !def->has_val)) {
if (arg.name
&& (arg.val || !def->has_val)) {
arg.def = def;
*arg_ = arg;
return 1;
@@ -72,12 +80,15 @@ int arg_match(struct arg *arg_, const struct arg_def *def, char **argv) {
return 0;
}
const char *arg_next(struct arg *arg) {
if (arg->argv[0]) arg->argv += arg->argv_step;
if (arg->argv[0])
arg->argv += arg->argv_step;
return *arg->argv;
}
char **argv_dup(int argc, const char **argv) {
char **new_argv = malloc((argc + 1) * sizeof(*argv));
@@ -86,6 +97,7 @@ char **argv_dup(int argc, const char **argv) {
return new_argv;
}
void arg_show_usage(FILE *fp, const struct arg_def *const *defs) {
char option_text[40] = {0};
@@ -97,12 +109,15 @@ void arg_show_usage(FILE *fp, const struct arg_def *const *defs) {
if (def->short_name && def->long_name) {
char *comma = def->has_val ? "," : ", ";
snprintf(option_text, 37, "-%s%s%s --%s%6s", def->short_name, short_val,
comma, def->long_name, long_val);
snprintf(option_text, 37, "-%s%s%s --%s%6s",
def->short_name, short_val, comma,
def->long_name, long_val);
} else if (def->short_name)
snprintf(option_text, 37, "-%s%s", def->short_name, short_val);
snprintf(option_text, 37, "-%s%s",
def->short_name, short_val);
else if (def->long_name)
snprintf(option_text, 37, " --%s%s", def->long_name, long_val);
snprintf(option_text, 37, " --%s%s",
def->long_name, long_val);
fprintf(fp, " %-37s\t%s\n", option_text, def->desc);
@@ -112,11 +127,13 @@ void arg_show_usage(FILE *fp, const struct arg_def *const *defs) {
fprintf(fp, " %-37s\t ", "");
for (listptr = def->enums; listptr->name; listptr++)
fprintf(fp, "%s%s", listptr->name, listptr[1].name ? ", " : "\n");
fprintf(fp, "%s%s", listptr->name,
listptr[1].name ? ", " : "\n");
}
}
}
unsigned int arg_parse_uint(const struct arg *arg) {
long int rawval;
char *endptr;
@@ -124,16 +141,18 @@ unsigned int arg_parse_uint(const struct arg *arg) {
rawval = strtol(arg->val, &endptr, 10);
if (arg->val[0] != '\0' && endptr[0] == '\0') {
if (rawval >= 0 && rawval <= UINT_MAX) return (unsigned int)rawval;
if (rawval >= 0 && rawval <= UINT_MAX)
return rawval;
die("Option %s: Value %ld out of range for unsigned int\n", arg->name,
rawval);
die("Option %s: Value %ld out of range for unsigned int\n",
arg->name, rawval);
}
die("Option %s: Invalid character '%c'\n", arg->name, *endptr);
return 0;
}
int arg_parse_int(const struct arg *arg) {
long int rawval;
char *endptr;
@@ -141,16 +160,18 @@ int arg_parse_int(const struct arg *arg) {
rawval = strtol(arg->val, &endptr, 10);
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 rawval;
die("Option %s: Value %ld out of range for signed int\n", arg->name,
rawval);
die("Option %s: Value %ld out of range for signed int\n",
arg->name, rawval);
}
die("Option %s: Invalid character '%c'\n", arg->name, *endptr);
return 0;
}
struct vpx_rational {
int num; /**< fraction numerator */
int den; /**< fraction denominator */
@@ -165,28 +186,25 @@ struct vpx_rational arg_parse_rational(const struct arg *arg) {
if (arg->val[0] != '\0' && endptr[0] == '/') {
if (rawval >= INT_MIN && rawval <= INT_MAX)
rat.num = (int)rawval;
else
die("Option %s: Value %ld out of range for signed int\n", arg->name,
rawval);
} else
die("Option %s: Expected / at '%c'\n", arg->name, *endptr);
rat.num = rawval;
else die("Option %s: Value %ld out of range for signed int\n",
arg->name, rawval);
} else die("Option %s: Expected / at '%c'\n", arg->name, *endptr);
/* parse denominator */
rawval = strtol(endptr + 1, &endptr, 10);
if (arg->val[0] != '\0' && endptr[0] == '\0') {
if (rawval >= INT_MIN && rawval <= INT_MAX)
rat.den = (int)rawval;
else
die("Option %s: Value %ld out of range for signed int\n", arg->name,
rawval);
} else
die("Option %s: Invalid character '%c'\n", arg->name, *endptr);
rat.den = rawval;
else die("Option %s: Value %ld out of range for signed int\n",
arg->name, rawval);
} else die("Option %s: Invalid character '%c'\n", arg->name, *endptr);
return rat;
}
int arg_parse_enum(const struct arg *arg) {
const struct arg_enum_list *listptr;
long int rawval;
@@ -197,18 +215,22 @@ int arg_parse_enum(const struct arg *arg) {
if (arg->val[0] != '\0' && endptr[0] == '\0') {
/* Got a raw value, make sure it's valid */
for (listptr = arg->def->enums; listptr->name; listptr++)
if (listptr->val == rawval) return (int)rawval;
if (listptr->val == rawval)
return rawval;
}
/* Next see if it can be parsed as a string */
for (listptr = arg->def->enums; listptr->name; listptr++)
if (!strcmp(arg->val, listptr->name)) return listptr->val;
if (!strcmp(arg->val, listptr->name))
return listptr->val;
die("Option %s: Invalid value '%s'\n", arg->name, arg->val);
return 0;
}
int arg_parse_enum_or_int(const struct arg *arg) {
if (arg->def->enums) return arg_parse_enum(arg);
if (arg->def->enums)
return arg_parse_enum(arg);
return arg_parse_int(arg);
}

13
args.h
View File

@@ -8,6 +8,7 @@
* be found in the AUTHORS file in the root of the source tree.
*/
#ifndef ARGS_H_
#define ARGS_H_
#include <stdio.h>
@@ -28,8 +29,7 @@ struct arg_enum_list {
const char *name;
int val;
};
#define ARG_ENUM_LIST_END \
{ 0 }
#define ARG_ENUM_LIST_END {0}
typedef struct arg_def {
const char *short_name;
@@ -38,12 +38,9 @@ typedef struct arg_def {
const char *desc;
const struct arg_enum_list *enums;
} arg_def_t;
#define ARG_DEF(s, l, v, d) \
{ s, l, v, d, NULL }
#define ARG_DEF_ENUM(s, l, v, d, e) \
{ s, l, v, d, e }
#define ARG_DEF_LIST_END \
{ 0 }
#define ARG_DEF(s,l,v,d) {s,l,v,d, NULL}
#define ARG_DEF_ENUM(s,l,v,d,e) {s,l,v,d,e}
#define ARG_DEF_LIST_END {0}
struct arg arg_init(char **argv);
int arg_match(struct arg *arg_, const struct arg_def *def, char **argv);

View File

@@ -29,6 +29,11 @@
# include $(CLEAR_VARS)
# include jni/libvpx/build/make/Android.mk
#
# There are currently two TARGET_ARCH_ABI targets for ARM.
# armeabi and armeabi-v7a. armeabi-v7a is selected by creating an
# Application.mk in the jni directory that contains:
# APP_ABI := armeabi-v7a
#
# By default libvpx will detect at runtime the existance of NEON extension.
# For this we import the 'cpufeatures' module from the NDK sources.
# libvpx can also be configured without this runtime detection method.
@@ -37,6 +42,9 @@
# --disable-neon-asm
# will remove any NEON dependency.
# To change to building armeabi, run ./libvpx/configure again, but with
# --target=armv6-android-gcc and modify the Application.mk file to
# set APP_ABI := armeabi
#
# Running ndk-build will build libvpx and include it in your project.
#
@@ -51,6 +59,9 @@ ASM_CNV_PATH := $(LOCAL_PATH)/$(ASM_CNV_PATH_LOCAL)
ifeq ($(TARGET_ARCH_ABI),armeabi-v7a)
include $(CONFIG_DIR)libs-armv7-android-gcc.mk
LOCAL_ARM_MODE := arm
else ifeq ($(TARGET_ARCH_ABI),armeabi)
include $(CONFIG_DIR)libs-armv6-android-gcc.mk
LOCAL_ARM_MODE := arm
else ifeq ($(TARGET_ARCH_ABI),arm64-v8a)
include $(CONFIG_DIR)libs-armv8-android-gcc.mk
LOCAL_ARM_MODE := arm
@@ -163,6 +174,9 @@ endif
ifeq ($(CONFIG_VP9), yes)
$$(rtcd_dep_template_SRCS): vp9_rtcd.h
endif
ifeq ($(CONFIG_VP10), yes)
$$(rtcd_dep_template_SRCS): vp10_rtcd.h
endif
$$(rtcd_dep_template_SRCS): vpx_scale_rtcd.h
$$(rtcd_dep_template_SRCS): vpx_dsp_rtcd.h

View File

@@ -26,7 +26,7 @@ test-no-data-check:: .DEFAULT
testdata:: .DEFAULT
utiltest: .DEFAULT
exampletest-no-data-check utiltest-no-data-check: .DEFAULT
test_%: .DEFAULT ;
# Note: md5sum is not installed on OS X, but openssl is. Openssl may not be
# installed on cygwin, so we need to autodetect here.
@@ -119,25 +119,29 @@ utiltest:
test-no-data-check::
exampletest-no-data-check utiltest-no-data-check:
# Force to realign stack always on OS/2
# Add compiler flags for intrinsic files
ifeq ($(TOOLCHAIN), x86-os2-gcc)
CFLAGS += -mstackrealign
STACKREALIGN=-mstackrealign
else
STACKREALIGN=
endif
$(BUILD_PFX)%_mmx.c.d: CFLAGS += -mmmx
$(BUILD_PFX)%_mmx.c.o: CFLAGS += -mmmx
$(BUILD_PFX)%_sse2.c.d: CFLAGS += -msse2
$(BUILD_PFX)%_sse2.c.o: CFLAGS += -msse2
$(BUILD_PFX)%_sse3.c.d: CFLAGS += -msse3
$(BUILD_PFX)%_sse3.c.o: CFLAGS += -msse3
$(BUILD_PFX)%_ssse3.c.d: CFLAGS += -mssse3
$(BUILD_PFX)%_ssse3.c.o: CFLAGS += -mssse3
$(BUILD_PFX)%_sse4.c.d: CFLAGS += -msse4.1
$(BUILD_PFX)%_sse4.c.o: CFLAGS += -msse4.1
$(BUILD_PFX)%_avx.c.d: CFLAGS += -mavx
$(BUILD_PFX)%_avx.c.o: CFLAGS += -mavx
$(BUILD_PFX)%_avx2.c.d: CFLAGS += -mavx2
$(BUILD_PFX)%_avx2.c.o: CFLAGS += -mavx2
$(BUILD_PFX)%_sse2.c.d: CFLAGS += -msse2 $(STACKREALIGN)
$(BUILD_PFX)%_sse2.c.o: CFLAGS += -msse2 $(STACKREALIGN)
$(BUILD_PFX)%_sse3.c.d: CFLAGS += -msse3 $(STACKREALIGN)
$(BUILD_PFX)%_sse3.c.o: CFLAGS += -msse3 $(STACKREALIGN)
$(BUILD_PFX)%_ssse3.c.d: CFLAGS += -mssse3 $(STACKREALIGN)
$(BUILD_PFX)%_ssse3.c.o: CFLAGS += -mssse3 $(STACKREALIGN)
$(BUILD_PFX)%_sse4.c.d: CFLAGS += -msse4.1 $(STACKREALIGN)
$(BUILD_PFX)%_sse4.c.o: CFLAGS += -msse4.1 $(STACKREALIGN)
$(BUILD_PFX)%_avx.c.d: CFLAGS += -mavx $(STACKREALIGN)
$(BUILD_PFX)%_avx.c.o: CFLAGS += -mavx $(STACKREALIGN)
$(BUILD_PFX)%_avx2.c.d: CFLAGS += -mavx2 $(STACKREALIGN)
$(BUILD_PFX)%_avx2.c.o: CFLAGS += -mavx2 $(STACKREALIGN)
$(BUILD_PFX)%vp9_reconintra.c.d: CFLAGS += $(STACKREALIGN)
$(BUILD_PFX)%vp9_reconintra.c.o: CFLAGS += $(STACKREALIGN)
$(BUILD_PFX)%.c.d: %.c
$(if $(quiet),@echo " [DEP] $@")
@@ -283,7 +287,7 @@ define archive_template
# for creating them.
$(1):
$(if $(quiet),@echo " [AR] $$@")
$(qexec)$$(AR) $$(ARFLAGS) $$@ $$^
$(qexec)$$(AR) $$(ARFLAGS) $$@ $$?
endef
define so_template
@@ -418,6 +422,7 @@ ifneq ($(call enabled,DIST-SRCS),)
DIST-SRCS-yes += build/make/gen_asm_deps.sh
DIST-SRCS-yes += build/make/Makefile
DIST-SRCS-$(CONFIG_MSVS) += build/make/gen_msvs_def.sh
DIST-SRCS-$(CONFIG_MSVS) += build/make/gen_msvs_proj.sh
DIST-SRCS-$(CONFIG_MSVS) += build/make/gen_msvs_sln.sh
DIST-SRCS-$(CONFIG_MSVS) += build/make/gen_msvs_vcxproj.sh
DIST-SRCS-$(CONFIG_MSVS) += build/make/msvs_common.sh
@@ -448,5 +453,3 @@ all: $(BUILD_TARGETS)
install:: $(INSTALL_TARGETS)
dist: $(INSTALL_TARGETS)
test::
.SUFFIXES: # Delete default suffix rules

View File

@@ -18,6 +18,12 @@
# Usage: cat inputfile | perl ads2gas_apple.pl > outputfile
#
my $chromium = 0;
foreach my $arg (@ARGV) {
$chromium = 1 if ($arg eq "-chromium");
}
print "@ This file was created from a .asm file\n";
print "@ using the ads2gas_apple.pl script.\n\n";
print "\t.set WIDE_REFERENCE, 0\n";
@@ -212,5 +218,18 @@ while (<STDIN>)
s/\bMEND\b/.endm/; # No need to tell it where to stop assembling
next if /^\s*END\s*$/;
# Clang used by Chromium differs slightly from clang in XCode in what it
# will accept in the assembly.
if ($chromium) {
s/qsubaddx/qsax/i;
s/qaddsubx/qasx/i;
s/ldrneb/ldrbne/i;
s/ldrneh/ldrhne/i;
s/(vqshrun\.s16 .*, \#)0$/${1}8/i;
# http://llvm.org/bugs/show_bug.cgi?id=16022
s/\.include/#include/;
}
print;
}

View File

@@ -73,7 +73,6 @@ Build options:
--target=TARGET target platform tuple [generic-gnu]
--cpu=CPU optimize for a specific cpu rather than a family
--extra-cflags=ECFLAGS add ECFLAGS to CFLAGS [$CFLAGS]
--extra-cxxflags=ECXXFLAGS add ECXXFLAGS to CXXFLAGS [$CXXFLAGS]
${toggle_extra_warnings} emit harmless warnings (always non-fatal)
${toggle_werror} treat warnings as errors, if possible
(not available with all compilers)
@@ -185,7 +184,6 @@ add_extralibs() {
#
# Boolean Manipulation Functions
#
enable_feature(){
set_all yes $*
}
@@ -202,24 +200,6 @@ disabled(){
eval test "x\$$1" = "xno"
}
enable_codec(){
enabled "${1}" || echo " enabling ${1}"
enable_feature "${1}"
is_in "${1}" vp8 vp9 && enable_feature "${1}_encoder" "${1}_decoder"
}
disable_codec(){
disabled "${1}" || echo " disabling ${1}"
disable_feature "${1}"
is_in "${1}" vp8 vp9 && disable_feature "${1}_encoder" "${1}_decoder"
}
# Iterates through positional parameters, checks to confirm the parameter has
# not been explicitly (force) disabled, and enables the setting controlled by
# the parameter when the setting is not disabled.
# Note: Does NOT alter RTCD generation options ($RTCD_OPTIONS).
soft_enable() {
for var in $*; do
if ! disabled $var; then
@@ -229,10 +209,6 @@ soft_enable() {
done
}
# Iterates through positional parameters, checks to confirm the parameter has
# not been explicitly (force) enabled, and disables the setting controlled by
# the parameter when the setting is not enabled.
# Note: Does NOT alter RTCD generation options ($RTCD_OPTIONS).
soft_disable() {
for var in $*; do
if ! enabled $var; then
@@ -361,10 +337,6 @@ check_add_cflags() {
check_cflags "$@" && add_cflags_only "$@"
}
check_add_cxxflags() {
check_cxxflags "$@" && add_cxxflags_only "$@"
}
check_add_asflags() {
log add_asflags "$@"
add_asflags "$@"
@@ -456,7 +428,7 @@ NM=${NM}
CFLAGS = ${CFLAGS}
CXXFLAGS = ${CXXFLAGS}
ARFLAGS = -crs\$(if \$(quiet),,v)
ARFLAGS = -rus\$(if \$(quiet),c,v)
LDFLAGS = ${LDFLAGS}
ASFLAGS = ${ASFLAGS}
extralibs = ${extralibs}
@@ -531,25 +503,24 @@ process_common_cmdline() {
--extra-cflags=*)
extra_cflags="${optval}"
;;
--extra-cxxflags=*)
extra_cxxflags="${optval}"
;;
--enable-?*|--disable-?*)
eval `echo "$opt" | sed 's/--/action=/;s/-/ option=/;s/-/_/g'`
if is_in ${option} ${ARCH_EXT_LIST}; then
if echo "${ARCH_EXT_LIST}" | grep "^ *$option\$" >/dev/null; then
[ $action = "disable" ] && RTCD_OPTIONS="${RTCD_OPTIONS}--disable-${option} "
elif [ $action = "disable" ] && ! disabled $option ; then
is_in ${option} ${CMDLINE_SELECT} || die_unknown $opt
echo "${CMDLINE_SELECT}" | grep "^ *$option\$" >/dev/null ||
die_unknown $opt
log_echo " disabling $option"
elif [ $action = "enable" ] && ! enabled $option ; then
is_in ${option} ${CMDLINE_SELECT} || die_unknown $opt
echo "${CMDLINE_SELECT}" | grep "^ *$option\$" >/dev/null ||
die_unknown $opt
log_echo " enabling $option"
fi
${action}_feature $option
;;
--require-?*)
eval `echo "$opt" | sed 's/--/action=/;s/-/ option=/;s/-/_/g'`
if is_in ${option} ${ARCH_EXT_LIST}; then
if echo "${ARCH_EXT_LIST}" none | grep "^ *$option\$" >/dev/null; then
RTCD_OPTIONS="${RTCD_OPTIONS}${opt} "
else
die_unknown $opt
@@ -646,41 +617,16 @@ show_darwin_sdk_path() {
xcodebuild -sdk $1 -version Path 2>/dev/null
}
# Print the major version number of the Darwin SDK specified by $1.
show_darwin_sdk_major_version() {
xcrun --sdk $1 --show-sdk-version 2>/dev/null | cut -d. -f1
}
# Print the Xcode version.
show_xcode_version() {
xcodebuild -version | head -n1 | cut -d' ' -f2
}
# Fails when Xcode version is less than 6.3.
check_xcode_minimum_version() {
xcode_major=$(show_xcode_version | cut -f1 -d.)
xcode_minor=$(show_xcode_version | cut -f2 -d.)
xcode_min_major=6
xcode_min_minor=3
if [ ${xcode_major} -lt ${xcode_min_major} ]; then
return 1
fi
if [ ${xcode_major} -eq ${xcode_min_major} ] \
&& [ ${xcode_minor} -lt ${xcode_min_minor} ]; then
return 1
fi
}
process_common_toolchain() {
if [ -z "$toolchain" ]; then
gcctarget="${CHOST:-$(gcc -dumpmachine 2> /dev/null)}"
# detect tgt_isa
case "$gcctarget" in
aarch64*)
tgt_isa=arm64
armv6*)
tgt_isa=armv6
;;
armv7*-hardfloat* | armv7*-gnueabihf | arm-*-gnueabihf)
armv7*-hardfloat*)
tgt_isa=armv7
float_abi=hard
;;
@@ -721,10 +667,6 @@ process_common_toolchain() {
tgt_isa=x86_64
tgt_os=darwin14
;;
*darwin15*)
tgt_isa=x86_64
tgt_os=darwin15
;;
x86_64*mingw32*)
tgt_os=win64
;;
@@ -781,27 +723,19 @@ process_common_toolchain() {
enabled shared && soft_enable pic
# Minimum iOS version for all target platforms (darwin and iphonesimulator).
# Shared library framework builds are only possible on iOS 8 and later.
if enabled shared; then
IOS_VERSION_OPTIONS="--enable-shared"
IOS_VERSION_MIN="8.0"
else
IOS_VERSION_OPTIONS=""
IOS_VERSION_MIN="6.0"
fi
# Handle darwin variants. Newer SDKs allow targeting older
# platforms, so use the newest one available.
case ${toolchain} in
arm*-darwin*)
add_cflags "-miphoneos-version-min=${IOS_VERSION_MIN}"
iphoneos_sdk_dir="$(show_darwin_sdk_path iphoneos)"
if [ -d "${iphoneos_sdk_dir}" ]; then
add_cflags "-isysroot ${iphoneos_sdk_dir}"
add_ldflags "-isysroot ${iphoneos_sdk_dir}"
ios_sdk_dir="$(show_darwin_sdk_path iphoneos)"
if [ -d "${ios_sdk_dir}" ]; then
add_cflags "-isysroot ${ios_sdk_dir}"
add_ldflags "-isysroot ${ios_sdk_dir}"
fi
;;
x86*-darwin*)
*-darwin*)
osx_sdk_dir="$(show_darwin_sdk_path macosx)"
if [ -d "${osx_sdk_dir}" ]; then
add_cflags "-isysroot ${osx_sdk_dir}"
@@ -839,10 +773,6 @@ process_common_toolchain() {
add_cflags "-mmacosx-version-min=10.10"
add_ldflags "-mmacosx-version-min=10.10"
;;
*-darwin15-*)
add_cflags "-mmacosx-version-min=10.11"
add_ldflags "-mmacosx-version-min=10.11"
;;
*-iphonesimulator-*)
add_cflags "-miphoneos-version-min=${IOS_VERSION_MIN}"
add_ldflags "-miphoneos-version-min=${IOS_VERSION_MIN}"
@@ -880,6 +810,17 @@ process_common_toolchain() {
if disabled neon && enabled neon_asm; then
die "Disabling neon while keeping neon-asm is not supported"
fi
case ${toolchain} in
*-darwin*)
# Neon is guaranteed on iOS 6+ devices, while old media extensions
# no longer assemble with iOS 9 SDK
;;
*)
soft_enable media
esac
;;
armv6)
soft_enable media
;;
esac
@@ -887,6 +828,7 @@ process_common_toolchain() {
case ${tgt_cc} in
gcc)
CROSS=${CROSS:-arm-none-linux-gnueabi-}
link_with_cc=gcc
setup_gnu_toolchain
arch_int=${tgt_isa##armv}
@@ -908,9 +850,6 @@ EOF
check_add_cflags -mfpu=neon #-ftree-vectorize
check_add_asflags -mfpu=neon
fi
elif [ ${tgt_isa} = "arm64" ] || [ ${tgt_isa} = "armv8" ]; then
check_add_cflags -march=armv8-a
check_add_asflags -march=armv8-a
else
check_add_cflags -march=${tgt_isa}
check_add_asflags -march=${tgt_isa}
@@ -978,10 +917,6 @@ EOF
;;
android*)
if [ -z "${sdk_path}" ]; then
die "Must specify --sdk-path for Android builds."
fi
SDK_PATH=${sdk_path}
COMPILER_LOCATION=`find "${SDK_PATH}" \
-name "arm-linux-androideabi-gcc*" -print -quit`
@@ -1003,10 +938,8 @@ EOF
awk '{ print $1 }' | tail -1`
fi
if [ -d "${alt_libc}" ]; then
add_cflags "--sysroot=${alt_libc}"
add_ldflags "--sysroot=${alt_libc}"
fi
# linker flag that routes around a CPU bug in some
# Cortex-A8 implementations (NDK Dev Guide)
@@ -1032,7 +965,18 @@ EOF
NM="$(${XCRUN_FIND} nm)"
RANLIB="$(${XCRUN_FIND} ranlib)"
AS_SFX=.s
# Special handling of ld for armv6 because libclang_rt.ios.a does
# not contain armv6 support in Apple's clang package:
# Apple LLVM version 5.1 (clang-503.0.40) (based on LLVM 3.4svn).
# TODO(tomfinegan): Remove this. Our minimum iOS version (6.0)
# renders support for armv6 unnecessary because the 3GS and up
# support neon.
if [ "${tgt_isa}" = "armv6" ]; then
LD="$(${XCRUN_FIND} ld)"
else
LD="${CXX:-$(${XCRUN_FIND} ld)}"
fi
# ASFLAGS is written here instead of using check_add_asflags
# because we need to overwrite all of ASFLAGS and purge the
@@ -1058,26 +1002,7 @@ EOF
[ -d "${try_dir}" ] && add_ldflags -L"${try_dir}"
done
case ${tgt_isa} in
armv7|armv7s|armv8|arm64)
if enabled neon && ! check_xcode_minimum_version; then
soft_disable neon
log_echo " neon disabled: upgrade Xcode (need v6.3+)."
if enabled neon_asm; then
soft_disable neon_asm
log_echo " neon_asm disabled: upgrade Xcode (need v6.3+)."
fi
fi
;;
esac
asm_conversion_cmd="${source_path}/build/make/ads2gas_apple.pl"
if [ "$(show_darwin_sdk_major_version iphoneos)" -gt 8 ]; then
check_add_cflags -fembed-bitcode
check_add_asflags -fembed-bitcode
check_add_ldflags -fembed-bitcode
fi
;;
linux*)
@@ -1085,7 +1010,7 @@ EOF
if enabled rvct; then
# Check if we have CodeSourcery GCC in PATH. Needed for
# libraries
which arm-none-linux-gnueabi-gcc 2>&- || \
hash arm-none-linux-gnueabi-gcc 2>&- || \
die "Couldn't find CodeSourcery GCC from PATH"
# Use armcc as a linker to enable translation of
@@ -1120,13 +1045,13 @@ EOF
if [ -n "${tune_cpu}" ]; then
case ${tune_cpu} in
p5600)
check_add_cflags -mips32r5 -mload-store-pairs
check_add_cflags -mips32r5 -funroll-loops -mload-store-pairs
check_add_cflags -msched-weight -mhard-float -mfp64
check_add_asflags -mips32r5 -mhard-float -mfp64
check_add_ldflags -mfp64
;;
i6400|p6600)
check_add_cflags -mips64r6 -mabi=64 -msched-weight
i6400)
check_add_cflags -mips64r6 -mabi=64 -funroll-loops -msched-weight
check_add_cflags -mload-store-pairs -mhard-float -mfp64
check_add_asflags -mips64r6 -mabi=64 -mhard-float -mfp64
check_add_ldflags -mips64r6 -mabi=64 -mfp64
@@ -1153,7 +1078,7 @@ EOF
CC=${CC:-${CROSS}gcc}
CXX=${CXX:-${CROSS}g++}
LD=${LD:-${CROSS}gcc}
CROSS=${CROSS-g}
CROSS=${CROSS:-g}
;;
os2)
disable_feature pic
@@ -1206,12 +1131,6 @@ EOF
soft_disable avx2
;;
esac
case $vc_version in
7|8|9)
echo "${tgt_cc} omits stdint.h, disabling webm-io..."
soft_disable webm_io
;;
esac
;;
esac
@@ -1232,24 +1151,15 @@ EOF
soft_enable runtime_cpu_detect
# We can't use 'check_cflags' until the compiler is configured and CC is
# populated.
for ext in ${ARCH_EXT_LIST_X86}; do
# disable higher order extensions to simplify asm dependencies
if [ "$disable_exts" = "yes" ]; then
if ! disabled $ext; then
RTCD_OPTIONS="${RTCD_OPTIONS}--disable-${ext} "
disable_feature $ext
fi
elif disabled $ext; then
disable_exts="yes"
else
# use the shortened version for the flag: sse4_1 -> sse4
check_gcc_machine_option ${ext%_*} $ext
fi
done
check_gcc_machine_option mmx
check_gcc_machine_option sse
check_gcc_machine_option sse2
check_gcc_machine_option sse3
check_gcc_machine_option ssse3
check_gcc_machine_option sse4 sse4_1
check_gcc_machine_option avx
check_gcc_machine_option avx2
if enabled external_build; then
log_echo " skipping assembler detection"
else
case "${AS}" in
auto|"")
which nasm >/dev/null 2>&1 && AS=nasm
@@ -1263,12 +1173,10 @@ EOF
&& AS=""
fi
[ "${AS}" = auto ] || [ -z "${AS}" ] \
&& die "Neither yasm nor nasm have been found." \
"See the prerequisites section in the README for more info."
&& die "Neither yasm nor nasm have been found"
;;
esac
log_echo " using $AS"
fi
[ "${AS##*/}" = nasm ] && add_asflags -Ox
AS_SFX=.asm
case ${tgt_os} in
@@ -1304,13 +1212,6 @@ EOF
enabled x86 && sim_arch="-arch i386" || sim_arch="-arch x86_64"
add_cflags ${sim_arch}
add_ldflags ${sim_arch}
if [ "$(show_darwin_sdk_major_version iphonesimulator)" -gt 8 ]; then
# yasm v1.3.0 doesn't know what -fembed-bitcode means, so turning it
# on is pointless (unless building a C-only lib). Warn the user, but
# do nothing here.
log "Warning: Bitcode embed disabled for simulator targets."
fi
;;
os2)
add_asflags -f aout
@@ -1363,6 +1264,10 @@ EOF
fi
fi
if [ "${tgt_isa}" = "x86_64" ] || [ "${tgt_isa}" = "x86" ]; then
soft_enable use_x86inc
fi
# Position Independent Code (PIC) support, for building relocatable
# shared objects
enabled gcc && enabled pic && check_add_cflags -fPIC

490
build/make/gen_msvs_proj.sh Executable file
View File

@@ -0,0 +1,490 @@
#!/bin/bash
##
## Copyright (c) 2010 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.
##
self=$0
self_basename=${self##*/}
self_dirname=$(dirname "$0")
. "$self_dirname/msvs_common.sh"|| exit 127
show_help() {
cat <<EOF
Usage: ${self_basename} --name=projname [options] file1 [file2 ...]
This script generates a Visual Studio project file from a list of source
code files.
Options:
--help Print this message
--exe Generate a project for building an Application
--lib Generate a project for creating a static library
--dll Generate a project for creating a dll
--static-crt Use the static C runtime (/MT)
--target=isa-os-cc Target specifier (required)
--out=filename Write output to a file [stdout]
--name=project_name Name of the project (required)
--proj-guid=GUID GUID to use for the project
--module-def=filename File containing export definitions (for DLLs)
--ver=version Version (7,8,9) of visual studio to generate for
--src-path-bare=dir Path to root of source tree
-Ipath/to/include Additional include directories
-DFLAG[=value] Preprocessor macros to define
-Lpath/to/lib Additional library search paths
-llibname Library to link against
EOF
exit 1
}
generate_filter() {
local var=$1
local name=$2
local pats=$3
local file_list_sz
local i
local f
local saveIFS="$IFS"
local pack
echo "generating filter '$name' from ${#file_list[@]} files" >&2
IFS=*
open_tag Filter \
Name=$name \
Filter=$pats \
UniqueIdentifier=`generate_uuid` \
file_list_sz=${#file_list[@]}
for i in ${!file_list[@]}; do
f=${file_list[i]}
for pat in ${pats//;/$IFS}; do
if [ "${f##*.}" == "$pat" ]; then
unset file_list[i]
objf=$(echo ${f%.*}.obj \
| sed -e "s,$src_path_bare,," \
-e 's/^[\./]\+//g' -e 's,[:/ ],_,g')
open_tag File RelativePath="$f"
if [ "$pat" == "asm" ] && $asm_use_custom_step; then
# Avoid object file name collisions, i.e. vpx_config.c and
# vpx_config.asm produce the same object file without
# this additional suffix.
objf=${objf%.obj}_asm.obj
for plat in "${platforms[@]}"; do
for cfg in Debug Release; do
open_tag FileConfiguration \
Name="${cfg}|${plat}" \
tag Tool \
Name="VCCustomBuildTool" \
Description="Assembling \$(InputFileName)" \
CommandLine="$(eval echo \$asm_${cfg}_cmdline) -o \$(IntDir)\\$objf" \
Outputs="\$(IntDir)\\$objf" \
close_tag FileConfiguration
done
done
fi
if [ "$pat" == "c" ] || \
[ "$pat" == "cc" ] || [ "$pat" == "cpp" ]; then
for plat in "${platforms[@]}"; do
for cfg in Debug Release; do
open_tag FileConfiguration \
Name="${cfg}|${plat}" \
tag Tool \
Name="VCCLCompilerTool" \
ObjectFile="\$(IntDir)\\$objf" \
close_tag FileConfiguration
done
done
fi
close_tag File
break
fi
done
done
close_tag Filter
IFS="$saveIFS"
}
# Process command line
unset target
for opt in "$@"; do
optval="${opt#*=}"
case "$opt" in
--help|-h) show_help
;;
--target=*) target="${optval}"
;;
--out=*) outfile="$optval"
;;
--name=*) name="${optval}"
;;
--proj-guid=*) guid="${optval}"
;;
--module-def=*) link_opts="${link_opts} ModuleDefinitionFile=${optval}"
;;
--exe) proj_kind="exe"
;;
--dll) proj_kind="dll"
;;
--lib) proj_kind="lib"
;;
--src-path-bare=*)
src_path_bare=$(fix_path "$optval")
src_path_bare=${src_path_bare%/}
;;
--static-crt) use_static_runtime=true
;;
--ver=*)
vs_ver="$optval"
case "$optval" in
[789])
;;
*) die Unrecognized Visual Studio Version in $opt
;;
esac
;;
-I*)
opt=${opt##-I}
opt=$(fix_path "$opt")
opt="${opt%/}"
incs="${incs}${incs:+;}&quot;${opt}&quot;"
yasmincs="${yasmincs} -I&quot;${opt}&quot;"
;;
-D*) defines="${defines}${defines:+;}${opt##-D}"
;;
-L*) # fudge . to $(OutDir)
if [ "${opt##-L}" == "." ]; then
libdirs="${libdirs}${libdirs:+;}&quot;\$(OutDir)&quot;"
else
# Also try directories for this platform/configuration
opt=${opt##-L}
opt=$(fix_path "$opt")
libdirs="${libdirs}${libdirs:+;}&quot;${opt}&quot;"
libdirs="${libdirs}${libdirs:+;}&quot;${opt}/\$(PlatformName)/\$(ConfigurationName)&quot;"
libdirs="${libdirs}${libdirs:+;}&quot;${opt}/\$(PlatformName)&quot;"
fi
;;
-l*) libs="${libs}${libs:+ }${opt##-l}.lib"
;;
-*) die_unknown $opt
;;
*)
# The paths in file_list are fixed outside of the loop.
file_list[${#file_list[@]}]="$opt"
case "$opt" in
*.asm) uses_asm=true
;;
esac
;;
esac
done
# Make one call to fix_path for file_list to improve performance.
fix_file_list
outfile=${outfile:-/dev/stdout}
guid=${guid:-`generate_uuid`}
asm_use_custom_step=false
uses_asm=${uses_asm:-false}
case "${vs_ver:-8}" in
7) vs_ver_id="7.10"
asm_use_custom_step=$uses_asm
warn_64bit='Detect64BitPortabilityProblems=true'
;;
8) vs_ver_id="8.00"
asm_use_custom_step=$uses_asm
warn_64bit='Detect64BitPortabilityProblems=true'
;;
9) vs_ver_id="9.00"
asm_use_custom_step=$uses_asm
warn_64bit='Detect64BitPortabilityProblems=false'
;;
esac
[ -n "$name" ] || die "Project name (--name) must be specified!"
[ -n "$target" ] || die "Target (--target) must be specified!"
if ${use_static_runtime:-false}; then
release_runtime=0
debug_runtime=1
lib_sfx=mt
else
release_runtime=2
debug_runtime=3
lib_sfx=md
fi
# Calculate debug lib names: If a lib ends in ${lib_sfx}.lib, then rename
# it to ${lib_sfx}d.lib. This precludes linking to release libs from a
# debug exe, so this may need to be refactored later.
for lib in ${libs}; do
if [ "$lib" != "${lib%${lib_sfx}.lib}" ]; then
lib=${lib%.lib}d.lib
fi
debug_libs="${debug_libs}${debug_libs:+ }${lib}"
done
# List Keyword for this target
case "$target" in
x86*) keyword="ManagedCProj"
;;
*) die "Unsupported target $target!"
esac
# List of all platforms supported for this target
case "$target" in
x86_64*)
platforms[0]="x64"
asm_Debug_cmdline="yasm -Xvc -g cv8 -f win64 ${yasmincs} &quot;\$(InputPath)&quot;"
asm_Release_cmdline="yasm -Xvc -f win64 ${yasmincs} &quot;\$(InputPath)&quot;"
;;
x86*)
platforms[0]="Win32"
asm_Debug_cmdline="yasm -Xvc -g cv8 -f win32 ${yasmincs} &quot;\$(InputPath)&quot;"
asm_Release_cmdline="yasm -Xvc -f win32 ${yasmincs} &quot;\$(InputPath)&quot;"
;;
*) die "Unsupported target $target!"
;;
esac
generate_vcproj() {
case "$proj_kind" in
exe) vs_ConfigurationType=1
;;
dll) vs_ConfigurationType=2
;;
*) vs_ConfigurationType=4
;;
esac
echo "<?xml version=\"1.0\" encoding=\"Windows-1252\"?>"
open_tag VisualStudioProject \
ProjectType="Visual C++" \
Version="${vs_ver_id}" \
Name="${name}" \
ProjectGUID="{${guid}}" \
RootNamespace="${name}" \
Keyword="${keyword}" \
open_tag Platforms
for plat in "${platforms[@]}"; do
tag Platform Name="$plat"
done
close_tag Platforms
open_tag Configurations
for plat in "${platforms[@]}"; do
plat_no_ws=`echo $plat | sed 's/[^A-Za-z0-9_]/_/g'`
open_tag Configuration \
Name="Debug|$plat" \
OutputDirectory="\$(SolutionDir)$plat_no_ws/\$(ConfigurationName)" \
IntermediateDirectory="$plat_no_ws/\$(ConfigurationName)/${name}" \
ConfigurationType="$vs_ConfigurationType" \
CharacterSet="1" \
case "$target" in
x86*)
case "$name" in
vpx)
tag Tool \
Name="VCCLCompilerTool" \
Optimization="0" \
AdditionalIncludeDirectories="$incs" \
PreprocessorDefinitions="WIN32;_DEBUG;_CRT_SECURE_NO_WARNINGS;_CRT_SECURE_NO_DEPRECATE;$defines" \
RuntimeLibrary="$debug_runtime" \
UsePrecompiledHeader="0" \
WarningLevel="3" \
DebugInformationFormat="2" \
$warn_64bit \
$uses_asm && tag Tool Name="YASM" IncludePaths="$incs" Debug="true"
;;
*)
tag Tool \
Name="VCCLCompilerTool" \
Optimization="0" \
AdditionalIncludeDirectories="$incs" \
PreprocessorDefinitions="WIN32;_DEBUG;_CRT_SECURE_NO_WARNINGS;_CRT_SECURE_NO_DEPRECATE;$defines" \
RuntimeLibrary="$debug_runtime" \
UsePrecompiledHeader="0" \
WarningLevel="3" \
DebugInformationFormat="2" \
$warn_64bit \
$uses_asm && tag Tool Name="YASM" IncludePaths="$incs" Debug="true"
;;
esac
;;
esac
case "$proj_kind" in
exe)
case "$target" in
x86*)
case "$name" in
*)
tag Tool \
Name="VCLinkerTool" \
AdditionalDependencies="$debug_libs \$(NoInherit)" \
AdditionalLibraryDirectories="$libdirs" \
GenerateDebugInformation="true" \
ProgramDatabaseFile="\$(OutDir)/${name}.pdb" \
;;
esac
;;
esac
;;
lib)
case "$target" in
x86*)
tag Tool \
Name="VCLibrarianTool" \
OutputFile="\$(OutDir)/${name}${lib_sfx}d.lib" \
;;
esac
;;
dll)
tag Tool \
Name="VCLinkerTool" \
AdditionalDependencies="\$(NoInherit)" \
LinkIncremental="2" \
GenerateDebugInformation="true" \
AssemblyDebug="1" \
TargetMachine="1" \
$link_opts \
;;
esac
close_tag Configuration
open_tag Configuration \
Name="Release|$plat" \
OutputDirectory="\$(SolutionDir)$plat_no_ws/\$(ConfigurationName)" \
IntermediateDirectory="$plat_no_ws/\$(ConfigurationName)/${name}" \
ConfigurationType="$vs_ConfigurationType" \
CharacterSet="1" \
WholeProgramOptimization="0" \
case "$target" in
x86*)
case "$name" in
vpx)
tag Tool \
Name="VCCLCompilerTool" \
Optimization="2" \
FavorSizeorSpeed="1" \
AdditionalIncludeDirectories="$incs" \
PreprocessorDefinitions="WIN32;NDEBUG;_CRT_SECURE_NO_WARNINGS;_CRT_SECURE_NO_DEPRECATE;$defines" \
RuntimeLibrary="$release_runtime" \
UsePrecompiledHeader="0" \
WarningLevel="3" \
DebugInformationFormat="0" \
$warn_64bit \
$uses_asm && tag Tool Name="YASM" IncludePaths="$incs"
;;
*)
tag Tool \
Name="VCCLCompilerTool" \
AdditionalIncludeDirectories="$incs" \
Optimization="2" \
FavorSizeorSpeed="1" \
PreprocessorDefinitions="WIN32;NDEBUG;_CRT_SECURE_NO_WARNINGS;_CRT_SECURE_NO_DEPRECATE;$defines" \
RuntimeLibrary="$release_runtime" \
UsePrecompiledHeader="0" \
WarningLevel="3" \
DebugInformationFormat="0" \
$warn_64bit \
$uses_asm && tag Tool Name="YASM" IncludePaths="$incs"
;;
esac
;;
esac
case "$proj_kind" in
exe)
case "$target" in
x86*)
case "$name" in
*)
tag Tool \
Name="VCLinkerTool" \
AdditionalDependencies="$libs \$(NoInherit)" \
AdditionalLibraryDirectories="$libdirs" \
;;
esac
;;
esac
;;
lib)
case "$target" in
x86*)
tag Tool \
Name="VCLibrarianTool" \
OutputFile="\$(OutDir)/${name}${lib_sfx}.lib" \
;;
esac
;;
dll) # note differences to debug version: LinkIncremental, AssemblyDebug
tag Tool \
Name="VCLinkerTool" \
AdditionalDependencies="\$(NoInherit)" \
LinkIncremental="1" \
GenerateDebugInformation="true" \
TargetMachine="1" \
$link_opts \
;;
esac
close_tag Configuration
done
close_tag Configurations
open_tag Files
generate_filter srcs "Source Files" "c;cc;cpp;def;odl;idl;hpj;bat;asm;asmx"
generate_filter hdrs "Header Files" "h;hm;inl;inc;xsd"
generate_filter resrcs "Resource Files" "rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav"
generate_filter resrcs "Build Files" "mk"
close_tag Files
tag Globals
close_tag VisualStudioProject
# This must be done from within the {} subshell
echo "Ignored files list (${#file_list[@]} items) is:" >&2
for f in "${file_list[@]}"; do
echo " $f" >&2
done
}
generate_vcproj |
sed -e '/"/s;\([^ "]\)/;\1\\;g' > ${outfile}
exit
<!--
TODO: Add any files not captured by filters.
<File
RelativePath=".\ReadMe.txt"
>
</File>
-->

View File

@@ -55,11 +55,16 @@ indent_pop() {
parse_project() {
local file=$1
if [ "$sfx" = "vcproj" ]; then
local name=`grep Name "$file" | awk 'BEGIN {FS="\""}{if (NR==1) print $2}'`
local guid=`grep ProjectGUID "$file" | awk 'BEGIN {FS="\""}{if (NR==1) print $2}'`
else
local name=`grep RootNamespace "$file" | sed 's,.*<.*>\(.*\)</.*>.*,\1,'`
local guid=`grep ProjectGuid "$file" | sed 's,.*<.*>\(.*\)</.*>.*,\1,'`
fi
# save the project GUID to a varaible, normalizing to the basename of the
# vcxproj file without the extension
# vcproj file without the extension
local var
var=${file##*/}
var=${var%%.${sfx}}
@@ -67,8 +72,13 @@ parse_project() {
eval "${var}_name=$name"
eval "${var}_guid=$guid"
if [ "$sfx" = "vcproj" ]; then
cur_config_list=`grep -A1 '<Configuration' $file |
grep Name | cut -d\" -f2`
else
cur_config_list=`grep -B1 'Label="Configuration"' $file |
grep Condition | cut -d\' -f4`
fi
new_config_list=$(for i in $config_list $cur_config_list; do
echo $i
done | sort | uniq)
@@ -93,6 +103,25 @@ process_project() {
eval "${var}_guid=$guid"
echo "Project(\"{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}\") = \"$name\", \"$file\", \"$guid\""
indent_push
eval "local deps=\"\${${var}_deps}\""
if [ -n "$deps" ] && [ "$sfx" = "vcproj" ]; then
echo "${indent}ProjectSection(ProjectDependencies) = postProject"
indent_push
for dep in $deps; do
eval "local dep_guid=\${${dep}_guid}"
[ -z "${dep_guid}" ] && die "Unknown GUID for $dep (dependency of $var)"
echo "${indent}$dep_guid = $dep_guid"
done
indent_pop
echo "${indent}EndProjectSection"
fi
indent_pop
echo "EndProject"
}
@@ -162,7 +191,11 @@ process_makefile() {
IFS=$'\r'$'\n'
local TAB=$'\t'
cat <<EOF
ifeq (\$(CONFIG_VS_VERSION),7)
MSBUILD_TOOL := devenv.com
else
MSBUILD_TOOL := msbuild.exe
endif
found_devenv := \$(shell which \$(MSBUILD_TOOL) >/dev/null 2>&1 && echo yes)
.nodevenv.once:
${TAB}@echo " * \$(MSBUILD_TOOL) not found in path."
@@ -171,7 +204,7 @@ ${TAB}@echo " * You will have to build all configurations manually using the"
${TAB}@echo " * Visual Studio IDE. To allow make to build them automatically,"
${TAB}@echo " * add the Common7/IDE directory of your Visual Studio"
${TAB}@echo " * installation to your path, eg:"
${TAB}@echo " * C:\Program Files\Microsoft Visual Studio 10.0\Common7\IDE"
${TAB}@echo " * C:\Program Files\Microsoft Visual Studio 8\Common7\IDE"
${TAB}@echo " * "
${TAB}@touch \$@
CLEAN-OBJS += \$(if \$(found_devenv),,.nodevenv.once)
@@ -188,9 +221,16 @@ clean::
${TAB}rm -rf "$platform"/"$config"
.PHONY: $nows_sln_config
ifneq (\$(found_devenv),)
ifeq (\$(CONFIG_VS_VERSION),7)
$nows_sln_config: $outfile
${TAB}\$(MSBUILD_TOOL) $outfile -build "$config"
else
$nows_sln_config: $outfile
${TAB}\$(MSBUILD_TOOL) $outfile -m -t:Build \\
${TAB}${TAB}-p:Configuration="$config" -p:Platform="$platform"
endif
else
$nows_sln_config: $outfile .nodevenv.once
${TAB}@echo " * Skipping build of $sln_config (\$(MSBUILD_TOOL) not in path)."
@@ -215,12 +255,23 @@ for opt in "$@"; do
;;
--ver=*) vs_ver="$optval"
case $optval in
10|11|12|14)
[789]|10|11|12|14)
;;
*) die Unrecognized Visual Studio Version in $opt
;;
esac
;;
--ver=*) vs_ver="$optval"
case $optval in
7) sln_vers="8.00"
sln_vers_str="Visual Studio .NET 2003"
;;
[89])
;;
*) die "Unrecognized Visual Studio Version '$optval' in $opt"
;;
esac
;;
--target=*) target="${optval}"
;;
-*) die_unknown $opt
@@ -230,7 +281,16 @@ for opt in "$@"; do
done
outfile=${outfile:-/dev/stdout}
mkoutfile=${mkoutfile:-/dev/stdout}
case "${vs_ver:-10}" in
case "${vs_ver:-8}" in
7) sln_vers="8.00"
sln_vers_str="Visual Studio .NET 2003"
;;
8) sln_vers="9.00"
sln_vers_str="Visual Studio 2005"
;;
9) sln_vers="10.00"
sln_vers_str="Visual Studio 2008"
;;
10) sln_vers="11.00"
sln_vers_str="Visual Studio 2010"
;;
@@ -244,7 +304,14 @@ case "${vs_ver:-10}" in
sln_vers_str="Visual Studio 2015"
;;
esac
case "${vs_ver:-8}" in
[789])
sfx=vcproj
;;
10|11|12|14)
sfx=vcxproj
;;
esac
for f in "${file_list[@]}"; do
parse_project $f

View File

@@ -211,7 +211,7 @@ for opt in "$@"; do
done
# Make one call to fix_path for file_list to improve performance.
fix_file_list file_list
fix_file_list
outfile=${outfile:-/dev/stdout}
guid=${guid:-`generate_uuid`}

View File

@@ -1,37 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>CFBundleDevelopmentRegion</key>
<string>en</string>
<key>CFBundleExecutable</key>
<string>VPX</string>
<key>CFBundleIdentifier</key>
<string>org.webmproject.VPX</string>
<key>CFBundleInfoDictionaryVersion</key>
<string>6.0</string>
<key>CFBundleName</key>
<string>VPX</string>
<key>CFBundlePackageType</key>
<string>FMWK</string>
<key>CFBundleShortVersionString</key>
<string>${VERSION}</string>
<key>CFBundleSignature</key>
<string>????</string>
<key>CFBundleSupportedPlatforms</key>
<array>
<string>iPhoneOS</string>
</array>
<key>CFBundleVersion</key>
<string>${VERSION}</string>
<key>MinimumOSVersion</key>
<string>${IOS_VERSION_MIN}</string>
<key>UIDeviceFamily</key>
<array>
<integer>1</integer>
<integer>2</integer>
</array>
<key>VPXFullVersion</key>
<string>${FULLVERSION}</string>
</dict>
</plist>

View File

@@ -24,44 +24,32 @@ CONFIGURE_ARGS="--disable-docs
--disable-unit-tests"
DIST_DIR="_dist"
FRAMEWORK_DIR="VPX.framework"
FRAMEWORK_LIB="VPX.framework/VPX"
HEADER_DIR="${FRAMEWORK_DIR}/Headers/vpx"
MAKE_JOBS=1
SCRIPT_DIR=$(dirname "$0")
LIBVPX_SOURCE_DIR=$(cd ${SCRIPT_DIR}/../..; pwd)
LIPO=$(xcrun -sdk iphoneos${SDK} -find lipo)
ORIG_PWD="$(pwd)"
ARM_TARGETS="arm64-darwin-gcc
TARGETS="arm64-darwin-gcc
armv7-darwin-gcc
armv7s-darwin-gcc"
SIM_TARGETS="x86-iphonesimulator-gcc
armv7s-darwin-gcc
x86-iphonesimulator-gcc
x86_64-iphonesimulator-gcc"
OSX_TARGETS="x86-darwin15-gcc
x86_64-darwin15-gcc"
TARGETS="${ARM_TARGETS} ${SIM_TARGETS}"
# Configures for the target specified by $1, and invokes make with the dist
# target using $DIST_DIR as the distribution output directory.
build_target() {
local target="$1"
local old_pwd="$(pwd)"
local target_specific_flags=""
vlog "***Building target: ${target}***"
case "${target}" in
x86-*)
target_specific_flags="--enable-pic"
vlog "Enabled PIC for ${target}"
;;
esac
mkdir "${target}"
cd "${target}"
eval "${LIBVPX_SOURCE_DIR}/configure" --target="${target}" \
${CONFIGURE_ARGS} ${EXTRA_CONFIGURE_ARGS} ${target_specific_flags} \
${devnull}
${CONFIGURE_ARGS} ${EXTRA_CONFIGURE_ARGS} ${devnull}
export DIST_DIR
eval make dist ${devnull}
eval make -j ${MAKE_JOBS} dist ${devnull}
cd "${old_pwd}"
vlog "***Done building target: ${target}***"
@@ -138,44 +126,6 @@ create_vpx_framework_config_shim() {
printf "#endif // ${include_guard}" >> "${config_file}"
}
# Verifies that $FRAMEWORK_LIB fat library contains requested builds.
verify_framework_targets() {
local requested_cpus=""
local cpu=""
# Extract CPU from full target name.
for target; do
cpu="${target%%-*}"
if [ "${cpu}" = "x86" ]; then
# lipo -info outputs i386 for libvpx x86 targets.
cpu="i386"
fi
requested_cpus="${requested_cpus}${cpu} "
done
# Get target CPUs present in framework library.
local targets_built=$(${LIPO} -info ${FRAMEWORK_LIB})
# $LIPO -info outputs a string like the following:
# Architectures in the fat file: $FRAMEWORK_LIB <architectures>
# Capture only the architecture strings.
targets_built=${targets_built##*: }
# Sort CPU strings to make the next step a simple string compare.
local actual=$(echo ${targets_built} | tr " " "\n" | sort | tr "\n" " ")
local requested=$(echo ${requested_cpus} | tr " " "\n" | sort | tr "\n" " ")
vlog "Requested ${FRAMEWORK_LIB} CPUs: ${requested}"
vlog "Actual ${FRAMEWORK_LIB} CPUs: ${actual}"
if [ "${requested}" != "${actual}" ]; then
elog "Actual ${FRAMEWORK_LIB} targets do not match requested target list."
elog " Requested target CPUs: ${requested}"
elog " Actual target CPUs: ${actual}"
return 1
fi
}
# Configures and builds each target specified by $1, and then builds
# VPX.framework.
build_framework() {
@@ -196,12 +146,7 @@ build_framework() {
for target in ${targets}; do
build_target "${target}"
target_dist_dir="${BUILD_ROOT}/${target}/${DIST_DIR}"
if [ "${ENABLE_SHARED}" = "yes" ]; then
local suffix="dylib"
else
local suffix="a"
fi
lib_list="${lib_list} ${target_dist_dir}/lib/libvpx.${suffix}"
lib_list="${lib_list} ${target_dist_dir}/lib/libvpx.a"
done
cd "${ORIG_PWD}"
@@ -220,25 +165,13 @@ build_framework() {
# Copy in vpx_version.h.
cp -p "${BUILD_ROOT}/${target}/vpx_version.h" "${HEADER_DIR}"
if [ "${ENABLE_SHARED}" = "yes" ]; then
# Adjust the dylib's name so dynamic linking in apps works as expected.
install_name_tool -id '@rpath/VPX.framework/VPX' ${FRAMEWORK_DIR}/VPX
# Copy in Info.plist.
cat "${SCRIPT_DIR}/ios-Info.plist" \
| sed "s/\${FULLVERSION}/${FULLVERSION}/g" \
| sed "s/\${VERSION}/${VERSION}/g" \
| sed "s/\${IOS_VERSION_MIN}/${IOS_VERSION_MIN}/g" \
> "${FRAMEWORK_DIR}/Info.plist"
fi
# Confirm VPX.framework/VPX contains the targets requested.
verify_framework_targets ${targets}
vlog "Created fat library ${FRAMEWORK_LIB} containing:"
vlog "Created fat library ${FRAMEWORK_DIR}/VPX containing:"
for lib in ${lib_list}; do
vlog " $(echo ${lib} | awk -F / '{print $2, $NF}')"
done
# TODO(tomfinegan): Verify that expected targets are included within
# VPX.framework/VPX via lipo -info.
}
# Trap function. Cleans up the subtree used to build all targets contained in
@@ -256,30 +189,16 @@ cleanup() {
fi
}
print_list() {
local indent="$1"
shift
local list="$@"
for entry in ${list}; do
echo "${indent}${entry}"
done
}
iosbuild_usage() {
cat << EOF
Usage: ${0##*/} [arguments]
--help: Display this message and exit.
--enable-shared: Build a dynamic framework for use on iOS 8 or later.
--extra-configure-args <args>: Extra args to pass when configuring libvpx.
--macosx: Uses darwin15 targets instead of iphonesimulator targets for x86
and x86_64. Allows linking to framework when builds target MacOSX
instead of iOS.
--jobs: Number of make jobs.
--preserve-build-output: Do not delete the build directory.
--show-build-output: Show output from each library build.
--targets <targets>: Override default target list. Defaults:
$(print_list " " ${TARGETS})
--test-link: Confirms all targets can be linked. Functionally identical to
passing --enable-examples via --extra-configure-args.
${TARGETS}
--verbose: Output information about the environment and each stage of the
build.
EOF
@@ -308,8 +227,9 @@ while [ -n "$1" ]; do
iosbuild_usage
exit
;;
--enable-shared)
ENABLE_SHARED=yes
--jobs)
MAKE_JOBS="$2"
shift
;;
--preserve-build-output)
PRESERVE_BUILD_OUTPUT=yes
@@ -317,16 +237,10 @@ while [ -n "$1" ]; do
--show-build-output)
devnull=
;;
--test-link)
EXTRA_CONFIGURE_ARGS="${EXTRA_CONFIGURE_ARGS} --enable-examples"
;;
--targets)
TARGETS="$2"
shift
;;
--macosx)
TARGETS="${ARM_TARGETS} ${OSX_TARGETS}"
;;
--verbose)
VERBOSE=yes
;;
@@ -338,21 +252,6 @@ while [ -n "$1" ]; do
shift
done
if [ "${ENABLE_SHARED}" = "yes" ]; then
CONFIGURE_ARGS="--enable-shared ${CONFIGURE_ARGS}"
fi
FULLVERSION=$("${SCRIPT_DIR}"/version.sh --bare "${LIBVPX_SOURCE_DIR}")
VERSION=$(echo "${FULLVERSION}" | sed -E 's/^v([0-9]+\.[0-9]+\.[0-9]+).*$/\1/')
if [ "$ENABLE_SHARED" = "yes" ]; then
IOS_VERSION_OPTIONS="--enable-shared"
IOS_VERSION_MIN="8.0"
else
IOS_VERSION_OPTIONS=""
IOS_VERSION_MIN="6.0"
fi
if [ "${VERBOSE}" = "yes" ]; then
cat << EOF
BUILD_ROOT=${BUILD_ROOT}
@@ -360,24 +259,16 @@ cat << EOF
CONFIGURE_ARGS=${CONFIGURE_ARGS}
EXTRA_CONFIGURE_ARGS=${EXTRA_CONFIGURE_ARGS}
FRAMEWORK_DIR=${FRAMEWORK_DIR}
FRAMEWORK_LIB=${FRAMEWORK_LIB}
HEADER_DIR=${HEADER_DIR}
MAKE_JOBS=${MAKE_JOBS}
PRESERVE_BUILD_OUTPUT=${PRESERVE_BUILD_OUTPUT}
LIBVPX_SOURCE_DIR=${LIBVPX_SOURCE_DIR}
LIPO=${LIPO}
MAKEFLAGS=${MAKEFLAGS}
ORIG_PWD=${ORIG_PWD}
PRESERVE_BUILD_OUTPUT=${PRESERVE_BUILD_OUTPUT}
TARGETS="$(print_list "" ${TARGETS})"
ENABLE_SHARED=${ENABLE_SHARED}
OSX_TARGETS="${OSX_TARGETS}"
SIM_TARGETS="${SIM_TARGETS}"
SCRIPT_DIR="${SCRIPT_DIR}"
FULLVERSION="${FULLVERSION}"
VERSION="${VERSION}"
IOS_VERSION_MIN="${IOS_VERSION_MIN}"
TARGETS="${TARGETS}"
EOF
fi
build_framework "${TARGETS}"
echo "Successfully built '${FRAMEWORK_DIR}' for:"
print_list "" ${TARGETS}
echo " ${TARGETS}"

View File

@@ -39,12 +39,11 @@ fix_path() {
}
# Corrects the paths in file_list in one pass for efficiency.
# $1 is the name of the array to be modified.
fix_file_list() {
declare -n array_ref=$1
files=$(fix_path "${array_ref[@]}")
# TODO(jzern): this could be more generic and take the array as a param.
files=$(fix_path "${file_list[@]}")
local IFS=$'\n'
array_ref=($files)
file_list=($files)
}
generate_uuid() {

View File

@@ -384,8 +384,13 @@ if ($opts{arch} eq 'x86') {
}
close CONFIG_FILE;
mips;
} elsif ($opts{arch} eq 'armv6') {
@ALL_ARCHS = filter(qw/media/);
arm;
} elsif ($opts{arch} =~ /armv7\w?/) {
@ALL_ARCHS = filter(qw/neon_asm neon/);
@ALL_ARCHS = filter(qw/media neon_asm neon/);
@REQUIRES = filter(keys %required ? keys %required : qw/media/);
&require(@REQUIRES);
arm;
} elsif ($opts{arch} eq 'armv8' || $opts{arch} eq 'arm64' ) {
@ALL_ARCHS = filter(qw/neon/);

View File

@@ -24,9 +24,8 @@ out_file=${2}
id=${3:-VERSION_STRING}
git_version_id=""
if [ -e "${source_path}/.git" ]; then
if [ -d "${source_path}/.git" ]; then
# Source Path is a git working copy. Check for local modifications.
# Note that git submodules may have a file as .git, not a directory.
export GIT_DIR="${source_path}/.git"
git_version_id=`git describe --match=v[0-9]* 2>/dev/null`
fi

View File

@@ -2,4 +2,3 @@
GERRIT_HOST: chromium-review.googlesource.com
GERRIT_PORT: 29418
CODE_REVIEW_SERVER: chromium-review.googlesource.com
GERRIT_SQUASH_UPLOADS: False

113
configure vendored
View File

@@ -35,11 +35,9 @@ Advanced options:
${toggle_debug_libs} in/exclude debug version of libraries
${toggle_static_msvcrt} use static MSVCRT (VS builds only)
${toggle_vp9_highbitdepth} use VP9 high bit depth (10/12) profiles
${toggle_better_hw_compatibility}
enable encoder to produce streams with better
hardware decoder compatibility
${toggle_vp8} VP8 codec support
${toggle_vp9} VP9 codec support
${toggle_vp10} VP10 codec support
${toggle_internal_stats} output of encoder internal stats for debug, if supported (encoders)
${toggle_postproc} postprocessing
${toggle_vp9_postproc} vp9 specific postprocessing
@@ -97,8 +95,11 @@ EOF
# all_platforms is a list of all supported target platforms. Maintain
# alphabetically by architecture, generic-gnu last.
all_platforms="${all_platforms} armv6-darwin-gcc"
all_platforms="${all_platforms} armv6-linux-rvct"
all_platforms="${all_platforms} armv6-linux-gcc"
all_platforms="${all_platforms} armv6-none-rvct"
all_platforms="${all_platforms} arm64-darwin-gcc"
all_platforms="${all_platforms} arm64-linux-gcc"
all_platforms="${all_platforms} armv7-android-gcc" #neon Cortex-A8
all_platforms="${all_platforms} armv7-darwin-gcc" #neon Cortex-A8
all_platforms="${all_platforms} armv7-linux-rvct" #neon Cortex-A8
@@ -108,7 +109,6 @@ all_platforms="${all_platforms} armv7-win32-vs11"
all_platforms="${all_platforms} armv7-win32-vs12"
all_platforms="${all_platforms} armv7-win32-vs14"
all_platforms="${all_platforms} armv7s-darwin-gcc"
all_platforms="${all_platforms} armv8-linux-gcc"
all_platforms="${all_platforms} mips32-linux-gcc"
all_platforms="${all_platforms} mips64-linux-gcc"
all_platforms="${all_platforms} sparc-solaris-gcc"
@@ -122,13 +122,15 @@ all_platforms="${all_platforms} x86-darwin11-gcc"
all_platforms="${all_platforms} x86-darwin12-gcc"
all_platforms="${all_platforms} x86-darwin13-gcc"
all_platforms="${all_platforms} x86-darwin14-gcc"
all_platforms="${all_platforms} x86-darwin15-gcc"
all_platforms="${all_platforms} x86-iphonesimulator-gcc"
all_platforms="${all_platforms} x86-linux-gcc"
all_platforms="${all_platforms} x86-linux-icc"
all_platforms="${all_platforms} x86-os2-gcc"
all_platforms="${all_platforms} x86-solaris-gcc"
all_platforms="${all_platforms} x86-win32-gcc"
all_platforms="${all_platforms} x86-win32-vs7"
all_platforms="${all_platforms} x86-win32-vs8"
all_platforms="${all_platforms} x86-win32-vs9"
all_platforms="${all_platforms} x86-win32-vs10"
all_platforms="${all_platforms} x86-win32-vs11"
all_platforms="${all_platforms} x86-win32-vs12"
@@ -140,12 +142,13 @@ all_platforms="${all_platforms} x86_64-darwin11-gcc"
all_platforms="${all_platforms} x86_64-darwin12-gcc"
all_platforms="${all_platforms} x86_64-darwin13-gcc"
all_platforms="${all_platforms} x86_64-darwin14-gcc"
all_platforms="${all_platforms} x86_64-darwin15-gcc"
all_platforms="${all_platforms} x86_64-iphonesimulator-gcc"
all_platforms="${all_platforms} x86_64-linux-gcc"
all_platforms="${all_platforms} x86_64-linux-icc"
all_platforms="${all_platforms} x86_64-solaris-gcc"
all_platforms="${all_platforms} x86_64-win64-gcc"
all_platforms="${all_platforms} x86_64-win64-vs8"
all_platforms="${all_platforms} x86_64-win64-vs9"
all_platforms="${all_platforms} x86_64-win64-vs10"
all_platforms="${all_platforms} x86_64-win64-vs11"
all_platforms="${all_platforms} x86_64-win64-vs12"
@@ -187,8 +190,12 @@ if [ ${doxy_major:-0} -ge 1 ]; then
fi
# disable codecs when their source directory does not exist
[ -d "${source_path}/vp8" ] || disable_codec vp8
[ -d "${source_path}/vp9" ] || disable_codec vp9
[ -d "${source_path}/vp8" ] || disable_feature vp8
[ -d "${source_path}/vp9" ] || disable_feature vp9
[ -d "${source_path}/vp10" ] || disable_feature vp10
# disable vp10 codec by default
disable_feature vp10
# install everything except the sources, by default. sources will have
# to be enabled when doing dist builds, since that's no longer a common
@@ -210,10 +217,13 @@ CODECS="
vp8_decoder
vp9_encoder
vp9_decoder
vp10_encoder
vp10_decoder
"
CODEC_FAMILIES="
vp8
vp9
vp10
"
ARCH_LIST="
@@ -222,7 +232,17 @@ ARCH_LIST="
x86
x86_64
"
ARCH_EXT_LIST_X86="
ARCH_EXT_LIST="
edsp
media
neon
neon_asm
mips32
dspr2
msa
mips64
mmx
sse
sse2
@@ -232,28 +252,18 @@ ARCH_EXT_LIST_X86="
avx
avx2
"
ARCH_EXT_LIST="
neon
neon_asm
mips32
dspr2
msa
mips64
${ARCH_EXT_LIST_X86}
"
HAVE_LIST="
${ARCH_EXT_LIST}
vpx_ports
stdint_h
pthread_h
sys_mman_h
unistd_h
"
EXPERIMENT_LIST="
spatial_svc
fp_mb_stats
emulate_hardware
misc_fixes
"
CONFIG_LIST="
dependency_tracking
@@ -262,6 +272,7 @@ CONFIG_LIST="
install_bins
install_libs
install_srcs
use_x86inc
debug
gprof
gcov
@@ -305,7 +316,6 @@ CONFIG_LIST="
vp9_temporal_denoising
coefficient_range_checking
vp9_highbitdepth
better_hw_compatibility
experimental
size_limit
${EXPERIMENT_LIST}
@@ -323,6 +333,7 @@ CMDLINE_SELECT="
gprof
gcov
pic
use_x86inc
optimizations
ccache
runtime_cpu_detect
@@ -363,7 +374,6 @@ CMDLINE_SELECT="
temporal_denoising
vp9_temporal_denoising
coefficient_range_checking
better_hw_compatibility
vp9_highbitdepth
experimental
"
@@ -372,19 +382,15 @@ process_cmdline() {
for opt do
optval="${opt#*=}"
case "$opt" in
--disable-codecs)
for c in ${CODEC_FAMILIES}; do disable_codec $c; done
;;
--disable-codecs) for c in ${CODECS}; do disable_feature $c; done ;;
--enable-?*|--disable-?*)
eval `echo "$opt" | sed 's/--/action=/;s/-/ option=/;s/-/_/g'`
if is_in ${option} ${EXPERIMENT_LIST}; then
if echo "${EXPERIMENT_LIST}" | grep "^ *$option\$" >/dev/null; then
if enabled experimental; then
${action}_feature $option
else
log_echo "Ignoring $opt -- not in experimental mode."
fi
elif is_in ${option} "${CODECS} ${CODEC_FAMILIES}"; then
${action}_codec ${option}
else
process_common_cmdline $opt
fi
@@ -398,6 +404,14 @@ process_cmdline() {
post_process_cmdline() {
c=""
# If the codec family is disabled, disable all components of that family.
# If the codec family is enabled, enable all components of that family.
log_echo "Configuring selected codecs"
for c in ${CODECS}; do
disabled ${c%%_*} && disable_feature ${c}
enabled ${c%%_*} && enable_feature ${c}
done
# Enable all detected codecs, if they haven't been disabled
for c in ${CODECS}; do soft_enable $c; done
@@ -492,18 +506,13 @@ process_detect() {
# Can only build shared libs on a subset of platforms. Doing this check
# here rather than at option parse time because the target auto-detect
# magic happens after the command line has been parsed.
case "${tgt_os}" in
linux|os2|darwin*|iphonesimulator*)
# Supported platforms
;;
*)
if ! enabled linux && ! enabled os2; then
if enabled gnu; then
echo "--enable-shared is only supported on ELF; assuming this is OK"
else
die "--enable-shared only supported on ELF, OS/2, and Darwin for now"
die "--enable-shared only supported on ELF and OS/2 for now"
fi
fi
;;
esac
fi
if [ -z "$CC" ] || enabled external_build; then
echo "Bypassing toolchain for environment detection."
@@ -530,12 +539,16 @@ process_detect() {
# Specialize windows and POSIX environments.
case $toolchain in
*-win*-*)
# Don't check for any headers in Windows builds.
false
case $header-$toolchain in
stdint*-gcc) true;;
*) false;;
esac && enable_feature $var
;;
*)
case $header in
stdint.h) true;;
pthread.h) true;;
sys/mman.h) true;;
unistd.h) true;;
*) false;;
esac && enable_feature $var
@@ -551,7 +564,9 @@ process_detect() {
int main(void) {return 0;}
EOF
# check system headers
check_header stdint.h
check_header pthread.h
check_header sys/mman.h
check_header unistd.h # for sysconf(3) and friends.
check_header vpx/vpx_integer.h -I${source_path} && enable_feature vpx_ports
@@ -566,14 +581,13 @@ process_toolchain() {
check_add_cflags -Wall
check_add_cflags -Wdeclaration-after-statement
check_add_cflags -Wdisabled-optimization
check_add_cflags -Wfloat-conversion
check_add_cflags -Wpointer-arith
check_add_cflags -Wtype-limits
check_add_cflags -Wcast-qual
check_add_cflags -Wvla
check_add_cflags -Wimplicit-function-declaration
check_add_cflags -Wuninitialized
check_add_cflags -Wunused
check_add_cflags -Wunused-variable
case ${CC} in
*clang*)
# libvpx and/or clang have issues with aliasing:
@@ -581,11 +595,10 @@ process_toolchain() {
# work around them until they are fixed
check_add_cflags -fno-strict-aliasing
;;
*) check_add_cflags -Wunused-but-set-variable ;;
esac
if enabled mips || [ -z "${INLINE}" ]; then
enabled extra_warnings || check_add_cflags -Wno-unused-function
fi
fi
if enabled icc; then
enabled werror && check_add_cflags -Werror
@@ -632,9 +645,17 @@ process_toolchain() {
vs*) enable_feature msvs
enable_feature solution
vs_version=${tgt_cc##vs}
case $vs_version in
[789])
VCPROJ_SFX=vcproj
gen_vcproj_cmd=${source_path}/build/make/gen_msvs_proj.sh
;;
10|11|12|14)
VCPROJ_SFX=vcxproj
gen_vcproj_cmd=${source_path}/build/make/gen_msvs_vcxproj.sh
enabled werror && gen_vcproj_cmd="${gen_vcproj_cmd} --enable-werror"
;;
esac
all_targets="${all_targets} solution"
INLINE="__forceinline"
;;
@@ -701,10 +722,6 @@ EOF
check_add_cflags ${extra_cflags} || \
die "Requested extra CFLAGS '${extra_cflags}' not supported by compiler"
fi
if [ -n "${extra_cxxflags}" ]; then
check_add_cxxflags ${extra_cxxflags} || \
die "Requested extra CXXFLAGS '${extra_cxxflags}' not supported by compiler"
fi
}

View File

@@ -36,30 +36,20 @@ LIBYUV_SRCS += third_party/libyuv/include/libyuv/basic_types.h \
third_party/libyuv/source/scale_neon64.cc \
third_party/libyuv/source/scale_win.cc \
LIBWEBM_COMMON_SRCS += third_party/libwebm/common/hdr_util.cc \
third_party/libwebm/common/hdr_util.h \
third_party/libwebm/common/webmids.h
LIBWEBM_MUXER_SRCS += third_party/libwebm/mkvmuxer/mkvmuxer.cc \
third_party/libwebm/mkvmuxer/mkvmuxerutil.cc \
third_party/libwebm/mkvmuxer/mkvwriter.cc \
third_party/libwebm/mkvmuxer/mkvmuxer.h \
third_party/libwebm/mkvmuxer/mkvmuxertypes.h \
third_party/libwebm/mkvmuxer/mkvmuxerutil.h \
third_party/libwebm/mkvparser/mkvparser.h \
third_party/libwebm/mkvmuxer/mkvwriter.h
LIBWEBM_PARSER_SRCS = third_party/libwebm/mkvparser/mkvparser.cc \
third_party/libwebm/mkvparser/mkvreader.cc \
third_party/libwebm/mkvparser/mkvparser.h \
third_party/libwebm/mkvparser/mkvreader.h
# Add compile flags and include path for libwebm sources.
ifeq ($(CONFIG_WEBM_IO),yes)
CXXFLAGS += -D__STDC_CONSTANT_MACROS -D__STDC_LIMIT_MACROS
INC_PATH-yes += $(SRC_PATH_BARE)/third_party/libwebm
endif
LIBWEBM_MUXER_SRCS += third_party/libwebm/mkvmuxer.cpp \
third_party/libwebm/mkvmuxerutil.cpp \
third_party/libwebm/mkvwriter.cpp \
third_party/libwebm/mkvmuxer.hpp \
third_party/libwebm/mkvmuxertypes.hpp \
third_party/libwebm/mkvmuxerutil.hpp \
third_party/libwebm/mkvparser.hpp \
third_party/libwebm/mkvwriter.hpp \
third_party/libwebm/webmids.hpp
LIBWEBM_PARSER_SRCS = third_party/libwebm/mkvparser.cpp \
third_party/libwebm/mkvreader.cpp \
third_party/libwebm/mkvparser.hpp \
third_party/libwebm/mkvreader.hpp
# List of examples to build. UTILS are tools meant for distribution
# while EXAMPLES demonstrate specific portions of the API.
@@ -78,8 +68,6 @@ ifeq ($(CONFIG_LIBYUV),yes)
vpxdec.SRCS += $(LIBYUV_SRCS)
endif
ifeq ($(CONFIG_WEBM_IO),yes)
vpxdec.SRCS += $(LIBWEBM_COMMON_SRCS)
vpxdec.SRCS += $(LIBWEBM_MUXER_SRCS)
vpxdec.SRCS += $(LIBWEBM_PARSER_SRCS)
vpxdec.SRCS += webmdec.cc webmdec.h
endif
@@ -101,9 +89,7 @@ ifeq ($(CONFIG_LIBYUV),yes)
vpxenc.SRCS += $(LIBYUV_SRCS)
endif
ifeq ($(CONFIG_WEBM_IO),yes)
vpxenc.SRCS += $(LIBWEBM_COMMON_SRCS)
vpxenc.SRCS += $(LIBWEBM_MUXER_SRCS)
vpxenc.SRCS += $(LIBWEBM_PARSER_SRCS)
vpxenc.SRCS += webmenc.cc webmenc.h
endif
vpxenc.GUID = 548DEC74-7A15-4B2B-AFC3-AA102E7C25C1
@@ -215,17 +201,6 @@ vp8cx_set_ref.SRCS += vpx_ports/msvc.h
vp8cx_set_ref.GUID = C5E31F7F-96F6-48BD-BD3E-10EBF6E8057A
vp8cx_set_ref.DESCRIPTION = VP8 set encoder reference frame
ifeq ($(CONFIG_VP9_ENCODER),yes)
ifeq ($(CONFIG_DECODERS),yes)
EXAMPLES-yes += vp9cx_set_ref.c
vp9cx_set_ref.SRCS += ivfenc.h ivfenc.c
vp9cx_set_ref.SRCS += tools_common.h tools_common.c
vp9cx_set_ref.SRCS += video_common.h
vp9cx_set_ref.SRCS += video_writer.h video_writer.c
vp9cx_set_ref.GUID = 65D7F14A-2EE6-4293-B958-AB5107A03B55
vp9cx_set_ref.DESCRIPTION = VP9 set encoder reference frame
endif
endif
ifeq ($(CONFIG_MULTI_RES_ENCODING),yes)
ifeq ($(CONFIG_LIBYUV),yes)

View File

@@ -65,7 +65,8 @@ static void get_image_md5(const vpx_image_t *img, unsigned char digest[16]) {
static void print_md5(FILE *stream, unsigned char digest[16]) {
int i;
for (i = 0; i < 16; ++i) fprintf(stream, "%02x", digest[i]);
for (i = 0; i < 16; ++i)
fprintf(stream, "%02x", digest[i]);
}
static const char *exec_name;
@@ -85,10 +86,12 @@ int main(int argc, char **argv) {
exec_name = argv[0];
if (argc != 3) die("Invalid number of arguments.");
if (argc != 3)
die("Invalid number of arguments.");
reader = vpx_video_reader_open(argv[1]);
if (!reader) die("Failed to open %s for reading.", argv[1]);
if (!reader)
die("Failed to open %s for reading.", argv[1]);
if (!(outfile = fopen(argv[2], "wb")))
die("Failed to open %s for writing.", argv[2]);
@@ -96,7 +99,8 @@ int main(int argc, char **argv) {
info = vpx_video_reader_get_info(reader);
decoder = get_vpx_decoder_by_fourcc(info->codec_fourcc);
if (!decoder) die("Unknown input codec.");
if (!decoder)
die("Unknown input codec.");
printf("Using %s\n", vpx_codec_iface_name(decoder->codec_interface()));
@@ -107,8 +111,8 @@ int main(int argc, char **argv) {
vpx_codec_iter_t iter = NULL;
vpx_image_t *img = NULL;
size_t frame_size = 0;
const unsigned char *frame =
vpx_video_reader_get_frame(reader, &frame_size);
const unsigned char *frame = vpx_video_reader_get_frame(reader,
&frame_size);
if (vpx_codec_decode(&codec, frame, (unsigned int)frame_size, NULL, 0))
die_codec(&codec, "Failed to decode frame");
@@ -117,13 +121,14 @@ int main(int argc, char **argv) {
get_image_md5(img, digest);
print_md5(outfile, digest);
fprintf(outfile, " img-%dx%d-%04d.i420\n", img->d_w, img->d_h,
++frame_cnt);
fprintf(outfile, " img-%dx%d-%04d.i420\n",
img->d_w, img->d_h, ++frame_cnt);
}
}
printf("Processed %d frames.\n", frame_cnt);
if (vpx_codec_destroy(&codec)) die_codec(&codec, "Failed to destroy codec.");
if (vpx_codec_destroy(&codec))
die_codec(&codec, "Failed to destroy codec.");
vpx_video_reader_close(reader);

View File

@@ -84,10 +84,12 @@ int main(int argc, char **argv) {
exec_name = argv[0];
if (argc != 4) die("Invalid number of arguments.");
if (argc != 4)
die("Invalid number of arguments.");
reader = vpx_video_reader_open(argv[1]);
if (!reader) die("Failed to open %s for reading.", argv[1]);
if (!reader)
die("Failed to open %s for reading.", argv[1]);
if (!(outfile = fopen(argv[2], "wb")))
die("Failed to open %s for writing.", argv[2]);
@@ -101,7 +103,8 @@ int main(int argc, char **argv) {
info = vpx_video_reader_get_info(reader);
decoder = get_vpx_decoder_by_fourcc(info->codec_fourcc);
if (!decoder) die("Unknown input codec.");
if (!decoder)
die("Unknown input codec.");
printf("Using %s\n", vpx_codec_iface_name(decoder->codec_interface()));
@@ -113,8 +116,8 @@ int main(int argc, char **argv) {
vpx_image_t *img = NULL;
size_t frame_size = 0;
int skip;
const unsigned char *frame =
vpx_video_reader_get_frame(reader, &frame_size);
const unsigned char *frame = vpx_video_reader_get_frame(reader,
&frame_size);
if (vpx_codec_decode(&codec, frame, (unsigned int)frame_size, NULL, 0))
die_codec(&codec, "Failed to decode frame.");
@@ -136,7 +139,8 @@ int main(int argc, char **argv) {
}
printf("Processed %d frames.\n", frame_cnt);
if (vpx_codec_destroy(&codec)) die_codec(&codec, "Failed to destroy codec.");
if (vpx_codec_destroy(&codec))
die_codec(&codec, "Failed to destroy codec.");
printf("Play: ffplay -f rawvideo -pix_fmt yuv420p -s %dx%d %s\n",
info->frame_width, info->frame_height, argv[2]);

View File

@@ -68,10 +68,12 @@ int main(int argc, char **argv) {
exec_name = argv[0];
if (argc != 3) die("Invalid number of arguments.");
if (argc != 3)
die("Invalid number of arguments.");
reader = vpx_video_reader_open(argv[1]);
if (!reader) die("Failed to open %s for reading.", argv[1]);
if (!reader)
die("Failed to open %s for reading.", argv[1]);
if (!(outfile = fopen(argv[2], "wb")))
die("Failed to open %s for writing", argv[2]);
@@ -79,7 +81,8 @@ int main(int argc, char **argv) {
info = vpx_video_reader_get_info(reader);
decoder = get_vpx_decoder_by_fourcc(info->codec_fourcc);
if (!decoder) die("Unknown input codec.");
if (!decoder)
die("Unknown input codec.");
printf("Using %s\n", vpx_codec_iface_name(decoder->codec_interface()));
@@ -88,14 +91,15 @@ int main(int argc, char **argv) {
if (res == VPX_CODEC_INCAPABLE)
die_codec(&codec, "Postproc not supported by this decoder.");
if (res) die_codec(&codec, "Failed to initialize decoder.");
if (res)
die_codec(&codec, "Failed to initialize decoder.");
while (vpx_video_reader_read_frame(reader)) {
vpx_codec_iter_t iter = NULL;
vpx_image_t *img = NULL;
size_t frame_size = 0;
const unsigned char *frame =
vpx_video_reader_get_frame(reader, &frame_size);
const unsigned char *frame = vpx_video_reader_get_frame(reader,
&frame_size);
++frame_cnt;
@@ -105,8 +109,8 @@ int main(int argc, char **argv) {
if (vpx_codec_control(&codec, VP8_SET_POSTPROC, &pp))
die_codec(&codec, "Failed to turn off postproc.");
} else if (frame_cnt % 30 == 16) {
vp8_postproc_cfg_t pp = { VP8_DEBLOCK | VP8_DEMACROBLOCK | VP8_MFQE, 4,
0 };
vp8_postproc_cfg_t pp = {VP8_DEBLOCK | VP8_DEMACROBLOCK | VP8_MFQE,
4, 0};
if (vpx_codec_control(&codec, VP8_SET_POSTPROC, &pp))
die_codec(&codec, "Failed to turn on postproc.");
};
@@ -121,7 +125,8 @@ int main(int argc, char **argv) {
}
printf("Processed %d frames.\n", frame_cnt);
if (vpx_codec_destroy(&codec)) die_codec(&codec, "Failed to destroy codec");
if (vpx_codec_destroy(&codec))
die_codec(&codec, "Failed to destroy codec");
printf("Play: ffplay -f rawvideo -pix_fmt yuv420p -s %dx%d %s\n",
info->frame_width, info->frame_height, argv[2]);

View File

@@ -34,8 +34,10 @@ void usage_exit(void) {
static int parse_dim(char *v, int *width, int *height) {
char *x = strchr(v, 'x');
if (x == NULL) x = strchr(v, 'X');
if (x == NULL) return 0;
if (x == NULL)
x = strchr(v, 'X');
if (x == NULL)
return 0;
*width = atoi(v);
*height = atoi(&x[1]);
if (*width <= 0 || *height <= 0)
@@ -91,8 +93,10 @@ int main(int argc, char *argv[]) {
else
frames = INT_MAX;
printf("Input size: %dx%d\n", width, height);
printf("Target size: %dx%d, Frames: ", target_width, target_height);
printf("Input size: %dx%d\n",
width, height);
printf("Target size: %dx%d, Frames: ",
target_width, target_height);
if (frames == INT_MAX)
printf("All\n");
else
@@ -106,10 +110,13 @@ int main(int argc, char *argv[]) {
outbuf_v = outbuf_u + target_width * target_height / 4;
f = 0;
while (f < frames) {
if (fread(inbuf, width * height * 3 / 2, 1, fpin) != 1) break;
vp9_resize_frame420(inbuf, width, inbuf_u, inbuf_v, width / 2, height,
width, outbuf, target_width, outbuf_u, outbuf_v,
target_width / 2, target_height, target_width);
if (fread(inbuf, width * height * 3 / 2, 1, fpin) != 1)
break;
vp9_resize_frame420(inbuf, width, inbuf_u, inbuf_v, width / 2,
height, width,
outbuf, target_width, outbuf_u, outbuf_v,
target_width / 2,
target_height, target_width);
fwrite(outbuf, target_width * target_height * 3 / 2, 1, fpout);
f++;
}

View File

@@ -8,6 +8,7 @@
* be found in the AUTHORS file in the root of the source tree.
*/
// VP8 Set Active and ROI Maps
// ===========================
//
@@ -85,7 +86,8 @@ static void set_roi_map(const vpx_codec_enc_cfg_t *cfg,
roi.static_threshold[3] = 0;
roi.roi_map = (uint8_t *)malloc(roi.rows * roi.cols);
for (i = 0; i < roi.rows * roi.cols; ++i) roi.roi_map[i] = i % 4;
for (i = 0; i < roi.rows * roi.cols; ++i)
roi.roi_map[i] = i % 4;
if (vpx_codec_control(codec, VP8E_SET_ROI_MAP, &roi))
die_codec(codec, "Failed to set ROI map");
@@ -102,7 +104,8 @@ static void set_active_map(const vpx_codec_enc_cfg_t *cfg,
map.cols = (cfg->g_w + 15) / 16;
map.active_map = (uint8_t *)malloc(map.rows * map.cols);
for (i = 0; i < map.rows * map.cols; ++i) map.active_map[i] = i % 2;
for (i = 0; i < map.rows * map.cols; ++i)
map.active_map[i] = i % 2;
if (vpx_codec_control(codec, VP8E_SET_ACTIVEMAP, &map))
die_codec(codec, "Failed to set active map");
@@ -122,21 +125,25 @@ static void unset_active_map(const vpx_codec_enc_cfg_t *cfg,
die_codec(codec, "Failed to set active map");
}
static int encode_frame(vpx_codec_ctx_t *codec, vpx_image_t *img,
int frame_index, VpxVideoWriter *writer) {
static int encode_frame(vpx_codec_ctx_t *codec,
vpx_image_t *img,
int frame_index,
VpxVideoWriter *writer) {
int got_pkts = 0;
vpx_codec_iter_t iter = NULL;
const vpx_codec_cx_pkt_t *pkt = NULL;
const vpx_codec_err_t res =
vpx_codec_encode(codec, img, frame_index, 1, 0, VPX_DL_GOOD_QUALITY);
if (res != VPX_CODEC_OK) die_codec(codec, "Failed to encode frame");
const vpx_codec_err_t res = vpx_codec_encode(codec, img, frame_index, 1, 0,
VPX_DL_GOOD_QUALITY);
if (res != VPX_CODEC_OK)
die_codec(codec, "Failed to encode frame");
while ((pkt = vpx_codec_get_cx_data(codec, &iter)) != NULL) {
got_pkts = 1;
if (pkt->kind == VPX_CODEC_CX_FRAME_PKT) {
const int keyframe = (pkt->data.frame.flags & VPX_FRAME_IS_KEY) != 0;
if (!vpx_video_writer_write_frame(writer, pkt->data.frame.buf,
if (!vpx_video_writer_write_frame(writer,
pkt->data.frame.buf,
pkt->data.frame.sz,
pkt->data.frame.pts)) {
die_codec(codec, "Failed to write compressed frame");
@@ -164,7 +171,8 @@ int main(int argc, char **argv) {
const double bits_per_pixel_per_frame = 0.067;
exec_name = argv[0];
if (argc != 6) die("Invalid number of arguments");
if (argc != 6)
die("Invalid number of arguments");
memset(&info, 0, sizeof(info));
@@ -179,8 +187,10 @@ int main(int argc, char **argv) {
info.time_base.numerator = 1;
info.time_base.denominator = fps;
if (info.frame_width <= 0 || info.frame_height <= 0 ||
(info.frame_width % 2) != 0 || (info.frame_height % 2) != 0) {
if (info.frame_width <= 0 ||
info.frame_height <= 0 ||
(info.frame_width % 2) != 0 ||
(info.frame_height % 2) != 0) {
die("Invalid frame size: %dx%d", info.frame_width, info.frame_height);
}
@@ -192,18 +202,20 @@ int main(int argc, char **argv) {
printf("Using %s\n", vpx_codec_iface_name(encoder->codec_interface()));
res = vpx_codec_enc_config_default(encoder->codec_interface(), &cfg, 0);
if (res) die_codec(&codec, "Failed to get default codec config.");
if (res)
die_codec(&codec, "Failed to get default codec config.");
cfg.g_w = info.frame_width;
cfg.g_h = info.frame_height;
cfg.g_timebase.num = info.time_base.numerator;
cfg.g_timebase.den = info.time_base.denominator;
cfg.rc_target_bitrate =
(unsigned int)(bits_per_pixel_per_frame * cfg.g_w * cfg.g_h * fps / 1000);
cfg.rc_target_bitrate = (unsigned int)(bits_per_pixel_per_frame * cfg.g_w *
cfg.g_h * fps / 1000);
cfg.g_lag_in_frames = 0;
writer = vpx_video_writer_open(argv[5], kContainerIVF, &info);
if (!writer) die("Failed to open %s for writing.", argv[5]);
if (!writer)
die("Failed to open %s for writing.", argv[5]);
if (!(infile = fopen(argv[4], "rb")))
die("Failed to open %s for reading.", argv[4]);
@@ -227,15 +239,15 @@ int main(int argc, char **argv) {
}
// Flush encoder.
while (encode_frame(&codec, NULL, -1, writer)) {
}
while (encode_frame(&codec, NULL, -1, writer)) {}
printf("\n");
fclose(infile);
printf("Processed %d frames.\n", frame_count);
vpx_img_free(&raw);
if (vpx_codec_destroy(&codec)) die_codec(&codec, "Failed to destroy codec.");
if (vpx_codec_destroy(&codec))
die_codec(&codec, "Failed to destroy codec.");
vpx_video_writer_close(writer);

View File

@@ -8,6 +8,7 @@
* be found in the AUTHORS file in the root of the source tree.
*/
// Simple Decoder
// ==============
//
@@ -102,10 +103,12 @@ int main(int argc, char **argv) {
exec_name = argv[0];
if (argc != 3) die("Invalid number of arguments.");
if (argc != 3)
die("Invalid number of arguments.");
reader = vpx_video_reader_open(argv[1]);
if (!reader) die("Failed to open %s for reading.", argv[1]);
if (!reader)
die("Failed to open %s for reading.", argv[1]);
if (!(outfile = fopen(argv[2], "wb")))
die("Failed to open %s for writing.", argv[2]);
@@ -113,7 +116,8 @@ int main(int argc, char **argv) {
info = vpx_video_reader_get_info(reader);
decoder = get_vpx_decoder_by_fourcc(info->codec_fourcc);
if (!decoder) die("Unknown input codec.");
if (!decoder)
die("Unknown input codec.");
printf("Using %s\n", vpx_codec_iface_name(decoder->codec_interface()));
@@ -124,8 +128,8 @@ int main(int argc, char **argv) {
vpx_codec_iter_t iter = NULL;
vpx_image_t *img = NULL;
size_t frame_size = 0;
const unsigned char *frame =
vpx_video_reader_get_frame(reader, &frame_size);
const unsigned char *frame = vpx_video_reader_get_frame(reader,
&frame_size);
if (vpx_codec_decode(&codec, frame, (unsigned int)frame_size, NULL, 0))
die_codec(&codec, "Failed to decode frame.");
@@ -136,7 +140,8 @@ int main(int argc, char **argv) {
}
printf("Processed %d frames.\n", frame_cnt);
if (vpx_codec_destroy(&codec)) die_codec(&codec, "Failed to destroy codec");
if (vpx_codec_destroy(&codec))
die_codec(&codec, "Failed to destroy codec");
printf("Play: ffplay -f rawvideo -pix_fmt yuv420p -s %dx%d %s\n",
info->frame_width, info->frame_height, argv[2]);

View File

@@ -109,27 +109,32 @@ static const char *exec_name;
void usage_exit(void) {
fprintf(stderr,
"Usage: %s <codec> <width> <height> <infile> <outfile> "
"<keyframe-interval> <error-resilient> <frames to encode>\n"
"See comments in simple_encoder.c for more information.\n",
"<keyframe-interval> [<error-resilient>]\nSee comments in "
"simple_encoder.c for more information.\n",
exec_name);
exit(EXIT_FAILURE);
}
static int encode_frame(vpx_codec_ctx_t *codec, vpx_image_t *img,
int frame_index, int flags, VpxVideoWriter *writer) {
static int encode_frame(vpx_codec_ctx_t *codec,
vpx_image_t *img,
int frame_index,
int flags,
VpxVideoWriter *writer) {
int got_pkts = 0;
vpx_codec_iter_t iter = NULL;
const vpx_codec_cx_pkt_t *pkt = NULL;
const vpx_codec_err_t res =
vpx_codec_encode(codec, img, frame_index, 1, flags, VPX_DL_GOOD_QUALITY);
if (res != VPX_CODEC_OK) die_codec(codec, "Failed to encode frame");
const vpx_codec_err_t res = vpx_codec_encode(codec, img, frame_index, 1,
flags, VPX_DL_GOOD_QUALITY);
if (res != VPX_CODEC_OK)
die_codec(codec, "Failed to encode frame");
while ((pkt = vpx_codec_get_cx_data(codec, &iter)) != NULL) {
got_pkts = 1;
if (pkt->kind == VPX_CODEC_CX_FRAME_PKT) {
const int keyframe = (pkt->data.frame.flags & VPX_FRAME_IS_KEY) != 0;
if (!vpx_video_writer_write_frame(writer, pkt->data.frame.buf,
if (!vpx_video_writer_write_frame(writer,
pkt->data.frame.buf,
pkt->data.frame.sz,
pkt->data.frame.pts)) {
die_codec(codec, "Failed to write compressed frame");
@@ -142,7 +147,6 @@ static int encode_frame(vpx_codec_ctx_t *codec, vpx_image_t *img,
return got_pkts;
}
// TODO(tomfinegan): Improve command line parsing and add args for bitrate/fps.
int main(int argc, char **argv) {
FILE *infile = NULL;
vpx_codec_ctx_t codec;
@@ -153,11 +157,12 @@ int main(int argc, char **argv) {
VpxVideoInfo info = {0};
VpxVideoWriter *writer = NULL;
const VpxInterface *encoder = NULL;
const int fps = 30;
const int bitrate = 200;
const int fps = 30; // TODO(dkovalev) add command line argument
const int bitrate = 200; // kbit/s TODO(dkovalev) add command line argument
int keyframe_interval = 0;
int max_frames = 0;
int frames_encoded = 0;
// TODO(dkovalev): Add some simple command line parsing code to make the
// command line more flexible.
const char *codec_arg = NULL;
const char *width_arg = NULL;
const char *height_arg = NULL;
@@ -167,7 +172,8 @@ int main(int argc, char **argv) {
exec_name = argv[0];
if (argc != 9) die("Invalid number of arguments");
if (argc < 7)
die("Invalid number of arguments");
codec_arg = argv[1];
width_arg = argv[2];
@@ -175,10 +181,10 @@ int main(int argc, char **argv) {
infile_arg = argv[4];
outfile_arg = argv[5];
keyframe_interval_arg = argv[6];
max_frames = strtol(argv[8], NULL, 0);
encoder = get_vpx_encoder_by_name(codec_arg);
if (!encoder) die("Unsupported codec.");
if (!encoder)
die("Unsupported codec.");
info.codec_fourcc = encoder->fourcc;
info.frame_width = strtol(width_arg, NULL, 0);
@@ -186,8 +192,10 @@ int main(int argc, char **argv) {
info.time_base.numerator = 1;
info.time_base.denominator = fps;
if (info.frame_width <= 0 || info.frame_height <= 0 ||
(info.frame_width % 2) != 0 || (info.frame_height % 2) != 0) {
if (info.frame_width <= 0 ||
info.frame_height <= 0 ||
(info.frame_width % 2) != 0 ||
(info.frame_height % 2) != 0) {
die("Invalid frame size: %dx%d", info.frame_width, info.frame_height);
}
@@ -197,22 +205,25 @@ int main(int argc, char **argv) {
}
keyframe_interval = strtol(keyframe_interval_arg, NULL, 0);
if (keyframe_interval < 0) die("Invalid keyframe interval value.");
if (keyframe_interval < 0)
die("Invalid keyframe interval value.");
printf("Using %s\n", vpx_codec_iface_name(encoder->codec_interface()));
res = vpx_codec_enc_config_default(encoder->codec_interface(), &cfg, 0);
if (res) die_codec(&codec, "Failed to get default codec config.");
if (res)
die_codec(&codec, "Failed to get default codec config.");
cfg.g_w = info.frame_width;
cfg.g_h = info.frame_height;
cfg.g_timebase.num = info.time_base.numerator;
cfg.g_timebase.den = info.time_base.denominator;
cfg.rc_target_bitrate = bitrate;
cfg.g_error_resilient = strtol(argv[7], NULL, 0);
cfg.g_error_resilient = argc > 7 ? strtol(argv[7], NULL, 0) : 0;
writer = vpx_video_writer_open(outfile_arg, kContainerIVF, &info);
if (!writer) die("Failed to open %s for writing.", outfile_arg);
if (!writer)
die("Failed to open %s for writing.", outfile_arg);
if (!(infile = fopen(infile_arg, "rb")))
die("Failed to open %s for reading.", infile_arg);
@@ -226,20 +237,18 @@ int main(int argc, char **argv) {
if (keyframe_interval > 0 && frame_count % keyframe_interval == 0)
flags |= VPX_EFLAG_FORCE_KF;
encode_frame(&codec, &raw, frame_count++, flags, writer);
frames_encoded++;
if (max_frames > 0 && frames_encoded >= max_frames) break;
}
// Flush encoder.
while (encode_frame(&codec, NULL, -1, 0, writer)) {
}
while (encode_frame(&codec, NULL, -1, 0, writer)) {};
printf("\n");
fclose(infile);
printf("Processed %d frames.\n", frame_count);
vpx_img_free(&raw);
if (vpx_codec_destroy(&codec)) die_codec(&codec, "Failed to destroy codec.");
if (vpx_codec_destroy(&codec))
die_codec(&codec, "Failed to destroy codec.");
vpx_video_writer_close(writer);

View File

@@ -59,23 +59,25 @@
static const char *exec_name;
void usage_exit(void) {
fprintf(stderr,
"Usage: %s <codec> <width> <height> <infile> <outfile> "
"<frame limit>\n",
fprintf(stderr, "Usage: %s <codec> <width> <height> <infile> <outfile>\n",
exec_name);
exit(EXIT_FAILURE);
}
static int get_frame_stats(vpx_codec_ctx_t *ctx, const vpx_image_t *img,
vpx_codec_pts_t pts, unsigned int duration,
vpx_enc_frame_flags_t flags, unsigned int deadline,
static int get_frame_stats(vpx_codec_ctx_t *ctx,
const vpx_image_t *img,
vpx_codec_pts_t pts,
unsigned int duration,
vpx_enc_frame_flags_t flags,
unsigned int deadline,
vpx_fixed_buf_t *stats) {
int got_pkts = 0;
vpx_codec_iter_t iter = NULL;
const vpx_codec_cx_pkt_t *pkt = NULL;
const vpx_codec_err_t res =
vpx_codec_encode(ctx, img, pts, duration, flags, deadline);
if (res != VPX_CODEC_OK) die_codec(ctx, "Failed to get frame stats.");
const vpx_codec_err_t res = vpx_codec_encode(ctx, img, pts, duration, flags,
deadline);
if (res != VPX_CODEC_OK)
die_codec(ctx, "Failed to get frame stats.");
while ((pkt = vpx_codec_get_cx_data(ctx, &iter)) != NULL) {
got_pkts = 1;
@@ -92,16 +94,20 @@ static int get_frame_stats(vpx_codec_ctx_t *ctx, const vpx_image_t *img,
return got_pkts;
}
static int encode_frame(vpx_codec_ctx_t *ctx, const vpx_image_t *img,
vpx_codec_pts_t pts, unsigned int duration,
vpx_enc_frame_flags_t flags, unsigned int deadline,
static int encode_frame(vpx_codec_ctx_t *ctx,
const vpx_image_t *img,
vpx_codec_pts_t pts,
unsigned int duration,
vpx_enc_frame_flags_t flags,
unsigned int deadline,
VpxVideoWriter *writer) {
int got_pkts = 0;
vpx_codec_iter_t iter = NULL;
const vpx_codec_cx_pkt_t *pkt = NULL;
const vpx_codec_err_t res =
vpx_codec_encode(ctx, img, pts, duration, flags, deadline);
if (res != VPX_CODEC_OK) die_codec(ctx, "Failed to encode frame.");
const vpx_codec_err_t res = vpx_codec_encode(ctx, img, pts, duration, flags,
deadline);
if (res != VPX_CODEC_OK)
die_codec(ctx, "Failed to encode frame.");
while ((pkt = vpx_codec_get_cx_data(ctx, &iter)) != NULL) {
got_pkts = 1;
@@ -120,9 +126,10 @@ static int encode_frame(vpx_codec_ctx_t *ctx, const vpx_image_t *img,
return got_pkts;
}
static vpx_fixed_buf_t pass0(vpx_image_t *raw, FILE *infile,
static vpx_fixed_buf_t pass0(vpx_image_t *raw,
FILE *infile,
const VpxInterface *encoder,
const vpx_codec_enc_cfg_t *cfg, int max_frames) {
const vpx_codec_enc_cfg_t *cfg) {
vpx_codec_ctx_t codec;
int frame_count = 0;
vpx_fixed_buf_t stats = {NULL, 0};
@@ -135,33 +142,37 @@ static vpx_fixed_buf_t pass0(vpx_image_t *raw, FILE *infile,
++frame_count;
get_frame_stats(&codec, raw, frame_count, 1, 0, VPX_DL_GOOD_QUALITY,
&stats);
if (max_frames > 0 && frame_count >= max_frames) break;
}
// Flush encoder.
while (get_frame_stats(&codec, NULL, frame_count, 1, 0, VPX_DL_GOOD_QUALITY,
&stats)) {
}
while (get_frame_stats(&codec, NULL, frame_count, 1, 0,
VPX_DL_GOOD_QUALITY, &stats)) {}
printf("Pass 0 complete. Processed %d frames.\n", frame_count);
if (vpx_codec_destroy(&codec)) die_codec(&codec, "Failed to destroy codec.");
if (vpx_codec_destroy(&codec))
die_codec(&codec, "Failed to destroy codec.");
return stats;
}
static void pass1(vpx_image_t *raw, FILE *infile, const char *outfile_name,
const VpxInterface *encoder, const vpx_codec_enc_cfg_t *cfg,
int max_frames) {
VpxVideoInfo info = { encoder->fourcc,
static void pass1(vpx_image_t *raw,
FILE *infile,
const char *outfile_name,
const VpxInterface *encoder,
const vpx_codec_enc_cfg_t *cfg) {
VpxVideoInfo info = {
encoder->fourcc,
cfg->g_w,
cfg->g_h,
{ cfg->g_timebase.num, cfg->g_timebase.den } };
{cfg->g_timebase.num, cfg->g_timebase.den}
};
VpxVideoWriter *writer = NULL;
vpx_codec_ctx_t codec;
int frame_count = 0;
writer = vpx_video_writer_open(outfile_name, kContainerIVF, &info);
if (!writer) die("Failed to open %s for writing", outfile_name);
if (!writer)
die("Failed to open %s for writing", outfile_name);
if (vpx_codec_enc_init(&codec, encoder->codec_interface(), cfg, 0))
die_codec(&codec, "Failed to initialize encoder");
@@ -170,17 +181,15 @@ static void pass1(vpx_image_t *raw, FILE *infile, const char *outfile_name,
while (vpx_img_read(raw, infile)) {
++frame_count;
encode_frame(&codec, raw, frame_count, 1, 0, VPX_DL_GOOD_QUALITY, writer);
if (max_frames > 0 && frame_count >= max_frames) break;
}
// Flush encoder.
while (encode_frame(&codec, NULL, -1, 1, 0, VPX_DL_GOOD_QUALITY, writer)) {
}
while (encode_frame(&codec, NULL, -1, 1, 0, VPX_DL_GOOD_QUALITY, writer)) {}
printf("\n");
if (vpx_codec_destroy(&codec)) die_codec(&codec, "Failed to destroy codec.");
if (vpx_codec_destroy(&codec))
die_codec(&codec, "Failed to destroy codec.");
vpx_video_writer_close(writer);
@@ -204,15 +213,14 @@ int main(int argc, char **argv) {
const char *const height_arg = argv[3];
const char *const infile_arg = argv[4];
const char *const outfile_arg = argv[5];
int max_frames = 0;
exec_name = argv[0];
if (argc != 7) die("Invalid number of arguments.");
max_frames = strtol(argv[6], NULL, 0);
if (argc != 6)
die("Invalid number of arguments.");
encoder = get_vpx_encoder_by_name(codec_arg);
if (!encoder) die("Unsupported codec.");
if (!encoder)
die("Unsupported codec.");
w = strtol(width_arg, NULL, 0);
h = strtol(height_arg, NULL, 0);
@@ -227,7 +235,8 @@ int main(int argc, char **argv) {
// Configuration
res = vpx_codec_enc_config_default(encoder->codec_interface(), &cfg, 0);
if (res) die_codec(&codec, "Failed to get default codec config.");
if (res)
die_codec(&codec, "Failed to get default codec config.");
cfg.g_w = w;
cfg.g_h = h;
@@ -240,13 +249,13 @@ int main(int argc, char **argv) {
// Pass 0
cfg.g_pass = VPX_RC_FIRST_PASS;
stats = pass0(&raw, infile, encoder, &cfg, max_frames);
stats = pass0(&raw, infile, encoder, &cfg);
// Pass 1
rewind(infile);
cfg.g_pass = VPX_RC_LAST_PASS;
cfg.rc_twopass_stats_in = stats;
pass1(&raw, infile, outfile_arg, encoder, &cfg, max_frames);
pass1(&raw, infile, outfile_arg, encoder, &cfg);
free(stats.buf);
vpx_img_free(&raw);

View File

@@ -29,6 +29,13 @@
#include <math.h>
#include <assert.h>
#include <sys/time.h>
#if USE_POSIX_MMAP
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/mman.h>
#include <fcntl.h>
#include <unistd.h>
#endif
#include "vpx_ports/vpx_timer.h"
#include "vpx/vpx_encoder.h"
#include "vpx/vp8cx.h"
@@ -37,7 +44,9 @@
#define interface (vpx_codec_vp8_cx())
#define fourcc 0x30385056
void usage_exit(void) { exit(EXIT_FAILURE); }
void usage_exit(void) {
exit(EXIT_FAILURE);
}
/*
* The input video frame is downsampled several times to generate a multi-level
@@ -80,7 +89,8 @@ static int read_frame_by_row(FILE *f, vpx_image_t *img) {
int res = 1;
int plane;
for (plane = 0; plane < 3; plane++) {
for (plane = 0; plane < 3; plane++)
{
unsigned char *ptr;
int w = (plane ? (1 + img->d_w) / 2 : img->d_w);
int h = (plane ? (1 + img->d_h) / 2 : img->d_h);
@@ -90,19 +100,20 @@ static int read_frame_by_row(FILE *f, vpx_image_t *img) {
* always counts in Y,U,V order, but this may not match the order of
* the data on disk.
*/
switch (plane) {
switch (plane)
{
case 1:
ptr = img->planes[img->fmt == VPX_IMG_FMT_YV12 ? VPX_PLANE_V
: VPX_PLANE_U];
ptr = img->planes[img->fmt==VPX_IMG_FMT_YV12? VPX_PLANE_V : VPX_PLANE_U];
break;
case 2:
ptr = img->planes[img->fmt == VPX_IMG_FMT_YV12 ? VPX_PLANE_U
: VPX_PLANE_V];
ptr = img->planes[img->fmt==VPX_IMG_FMT_YV12?VPX_PLANE_U : VPX_PLANE_V];
break;
default: ptr = img->planes[plane];
default:
ptr = img->planes[plane];
}
for (r = 0; r < h; r++) {
for (r = 0; r < h; r++)
{
to_read = w;
nbytes = fread(ptr, 1, to_read, f);
@@ -115,17 +126,20 @@ static int read_frame_by_row(FILE *f, vpx_image_t *img) {
ptr += img->stride[plane];
}
if (!res) break;
if (!res)
break;
}
return res;
}
static void write_ivf_file_header(FILE *outfile, const vpx_codec_enc_cfg_t *cfg,
static void write_ivf_file_header(FILE *outfile,
const vpx_codec_enc_cfg_t *cfg,
int frame_cnt) {
char header[32];
if (cfg->g_pass != VPX_RC_ONE_PASS && cfg->g_pass != VPX_RC_LAST_PASS) return;
if(cfg->g_pass != VPX_RC_ONE_PASS && cfg->g_pass != VPX_RC_LAST_PASS)
return;
header[0] = 'D';
header[1] = 'K';
header[2] = 'I';
@@ -144,11 +158,13 @@ static void write_ivf_file_header(FILE *outfile, const vpx_codec_enc_cfg_t *cfg,
}
static void write_ivf_frame_header(FILE *outfile,
const vpx_codec_cx_pkt_t *pkt) {
const vpx_codec_cx_pkt_t *pkt)
{
char header[12];
vpx_codec_pts_t pts;
if (pkt->kind != VPX_CODEC_CX_FRAME_PKT) return;
if(pkt->kind != VPX_CODEC_CX_FRAME_PKT)
return;
pts = pkt->data.frame.pts;
mem_put_le32(header, pkt->data.frame.sz);
@@ -164,11 +180,15 @@ static void write_ivf_frame_header(FILE *outfile,
* parameters will be passed in as user parameters in another version.
*/
static void set_temporal_layer_pattern(int num_temporal_layers,
vpx_codec_enc_cfg_t *cfg, int bitrate,
int *layer_flags) {
vpx_codec_enc_cfg_t *cfg,
int bitrate,
int *layer_flags)
{
assert(num_temporal_layers <= MAX_NUM_TEMPORAL_LAYERS);
switch (num_temporal_layers) {
case 1: {
switch (num_temporal_layers)
{
case 1:
{
/* 1-layer */
cfg->ts_number_layers = 1;
cfg->ts_periodicity = 1;
@@ -181,7 +201,8 @@ static void set_temporal_layer_pattern(int num_temporal_layers,
break;
}
case 2: {
case 2:
{
/* 2-layers, with sync point at first frame of layer 1. */
cfg->ts_number_layers = 2;
cfg->ts_periodicity = 2;
@@ -198,18 +219,22 @@ static void set_temporal_layer_pattern(int num_temporal_layers,
// key frame. Sync point every 8 frames.
// Layer 0: predict from L and ARF, update L and G.
layer_flags[0] = VP8_EFLAG_NO_REF_GF | VP8_EFLAG_NO_UPD_ARF;
layer_flags[0] = VP8_EFLAG_NO_REF_GF |
VP8_EFLAG_NO_UPD_ARF;
// Layer 1: sync point: predict from L and ARF, and update G.
layer_flags[1] =
VP8_EFLAG_NO_REF_GF | VP8_EFLAG_NO_UPD_LAST | VP8_EFLAG_NO_UPD_ARF;
layer_flags[1] = VP8_EFLAG_NO_REF_GF |
VP8_EFLAG_NO_UPD_LAST |
VP8_EFLAG_NO_UPD_ARF;
// Layer 0, predict from L and ARF, update L.
layer_flags[2] =
VP8_EFLAG_NO_REF_GF | VP8_EFLAG_NO_UPD_GF | VP8_EFLAG_NO_UPD_ARF;
layer_flags[2] = VP8_EFLAG_NO_REF_GF |
VP8_EFLAG_NO_UPD_GF |
VP8_EFLAG_NO_UPD_ARF;
// Layer 1: predict from L, G and ARF, and update G.
layer_flags[3] = VP8_EFLAG_NO_UPD_ARF | VP8_EFLAG_NO_UPD_LAST |
layer_flags[3] = VP8_EFLAG_NO_UPD_ARF |
VP8_EFLAG_NO_UPD_LAST |
VP8_EFLAG_NO_UPD_ENTROPY;
// Layer 0
@@ -227,7 +252,8 @@ static void set_temporal_layer_pattern(int num_temporal_layers,
}
case 3:
default: {
default:
{
// 3-layers structure where ARF is used as predictor for all frames,
// and is only updated on key frame.
// Sync points for layer 1 and 2 every 8 frames.
@@ -248,30 +274,38 @@ static void set_temporal_layer_pattern(int num_temporal_layers,
/* 0=L, 1=GF, 2=ARF */
// Layer 0: predict from L and ARF; update L and G.
layer_flags[0] = VP8_EFLAG_NO_UPD_ARF | VP8_EFLAG_NO_REF_GF;
layer_flags[0] = VP8_EFLAG_NO_UPD_ARF |
VP8_EFLAG_NO_REF_GF;
// Layer 2: sync point: predict from L and ARF; update none.
layer_flags[1] = VP8_EFLAG_NO_REF_GF | VP8_EFLAG_NO_UPD_GF |
VP8_EFLAG_NO_UPD_ARF | VP8_EFLAG_NO_UPD_LAST |
layer_flags[1] = VP8_EFLAG_NO_REF_GF |
VP8_EFLAG_NO_UPD_GF |
VP8_EFLAG_NO_UPD_ARF |
VP8_EFLAG_NO_UPD_LAST |
VP8_EFLAG_NO_UPD_ENTROPY;
// Layer 1: sync point: predict from L and ARF; update G.
layer_flags[2] =
VP8_EFLAG_NO_REF_GF | VP8_EFLAG_NO_UPD_ARF | VP8_EFLAG_NO_UPD_LAST;
layer_flags[2] = VP8_EFLAG_NO_REF_GF |
VP8_EFLAG_NO_UPD_ARF |
VP8_EFLAG_NO_UPD_LAST;
// Layer 2: predict from L, G, ARF; update none.
layer_flags[3] = VP8_EFLAG_NO_UPD_GF | VP8_EFLAG_NO_UPD_ARF |
VP8_EFLAG_NO_UPD_LAST | VP8_EFLAG_NO_UPD_ENTROPY;
layer_flags[3] = VP8_EFLAG_NO_UPD_GF |
VP8_EFLAG_NO_UPD_ARF |
VP8_EFLAG_NO_UPD_LAST |
VP8_EFLAG_NO_UPD_ENTROPY;
// Layer 0: predict from L and ARF; update L.
layer_flags[4] =
VP8_EFLAG_NO_UPD_GF | VP8_EFLAG_NO_UPD_ARF | VP8_EFLAG_NO_REF_GF;
layer_flags[4] = VP8_EFLAG_NO_UPD_GF |
VP8_EFLAG_NO_UPD_ARF |
VP8_EFLAG_NO_REF_GF;
// Layer 2: predict from L, G, ARF; update none.
layer_flags[5] = layer_flags[3];
// Layer 1: predict from L, G, ARF; update G.
layer_flags[6] = VP8_EFLAG_NO_UPD_ARF | VP8_EFLAG_NO_UPD_LAST;
layer_flags[6] = VP8_EFLAG_NO_UPD_ARF |
VP8_EFLAG_NO_UPD_LAST;
// Layer 2: predict from L, G, ARF; update none.
layer_flags[7] = layer_flags[3];
@@ -283,7 +317,8 @@ static void set_temporal_layer_pattern(int num_temporal_layers,
/* The periodicity of the pattern given the number of temporal layers. */
static int periodicity_to_num_layers[MAX_NUM_TEMPORAL_LAYERS] = {1, 8, 8};
int main(int argc, char **argv) {
int main(int argc, char **argv)
{
FILE *infile, *outfile[NUM_ENCODERS];
FILE *downsampled_input[NUM_ENCODERS - 1];
char filename[50];
@@ -302,7 +337,8 @@ int main(int argc, char **argv) {
int flags = 0;
int layer_id = 0;
int layer_flags[VPX_TS_MAX_PERIODICITY * NUM_ENCODERS] = { 0 };
int layer_flags[VPX_TS_MAX_PERIODICITY * NUM_ENCODERS]
= {0};
int flag_periodicity;
/*Currently, only realtime mode is supported in multi-resolution encoding.*/
@@ -318,7 +354,8 @@ int main(int argc, char **argv) {
double psnr_totals[NUM_ENCODERS][4] = {{0,0}};
int psnr_count[NUM_ENCODERS] = {0};
int64_t cx_time = 0;
double cx_time = 0;
struct timeval tv1, tv2, difftv;
/* Set the required target bitrates for each resolution level.
* If target bitrate for highest-resolution level is set to 0,
@@ -340,10 +377,8 @@ int main(int argc, char **argv) {
unsigned int num_temporal_layers[NUM_ENCODERS] = {3, 3, 3};
if(argc!= (7 + 3 * NUM_ENCODERS))
die(
"Usage: %s <width> <height> <frame_rate> <infile> <outfile(s)> "
"<rate_encoder(s)> <temporal_layer(s)> <key_frame_insert> <output "
"psnr?> \n",
die("Usage: %s <width> <height> <frame_rate> <infile> <outfile(s)> "
"<rate_encoder(s)> <temporal_layer(s)> <key_frame_insert> <output psnr?> \n",
argv[0]);
printf("Using %s\n",vpx_codec_iface_name(interface));
@@ -360,8 +395,10 @@ int main(int argc, char **argv) {
die("Failed to open %s for reading", argv[4]);
/* Open output file for each encoder to output bitstreams */
for (i = 0; i < NUM_ENCODERS; i++) {
if (!target_bitrate[i]) {
for (i=0; i< NUM_ENCODERS; i++)
{
if(!target_bitrate[i])
{
outfile[i] = NULL;
continue;
}
@@ -371,12 +408,14 @@ int main(int argc, char **argv) {
}
// 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);
}
// 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);
if (num_temporal_layers[i] < 1 || num_temporal_layers[i] > 3)
die("Invalid temporal layers: %d, Must be 1, 2, or 3. \n",
@@ -384,9 +423,11 @@ int main(int argc, char **argv) {
}
/* Open file to write out each spatially downsampled input stream. */
for (i = 0; i < NUM_ENCODERS - 1; i++) {
for (i=0; i< NUM_ENCODERS - 1; i++)
{
// Highest resoln is encoder 0.
if (sprintf(filename, "ds%d.yuv", NUM_ENCODERS - i) < 0) {
if (sprintf(filename,"ds%d.yuv",NUM_ENCODERS - i) < 0)
{
return EXIT_FAILURE;
}
downsampled_input[i] = fopen(filename,"wb");
@@ -396,8 +437,10 @@ int main(int argc, char **argv) {
show_psnr = strtol(argv[3 * NUM_ENCODERS + 6], NULL, 0);
/* Populate default encoder configuration */
for (i = 0; i < NUM_ENCODERS; i++) {
for (i=0; i< NUM_ENCODERS; i++)
{
res[i] = vpx_codec_enc_config_default(interface, &cfg[i], 0);
if(res[i]) {
printf("Failed to get config: %s\n", vpx_codec_err_to_string(res[i]));
@@ -437,7 +480,8 @@ int main(int argc, char **argv) {
cfg[0].g_timebase.den = framerate;
/* Other-resolution encoder settings */
for (i = 1; i < NUM_ENCODERS; i++) {
for (i=1; i< NUM_ENCODERS; i++)
{
memcpy(&cfg[i], &cfg[0], sizeof(vpx_codec_enc_cfg_t));
cfg[i].rc_target_bitrate = target_bitrate[i];
@@ -459,6 +503,7 @@ int main(int argc, char **argv) {
if((cfg[i].g_h)%2)cfg[i].g_h++;
}
// Set the number of threads per encode/spatial layer.
// (1, 1, 1) means no encoder threading.
cfg[0].g_threads = 2;
@@ -476,11 +521,14 @@ int main(int argc, char **argv) {
read_frame_p = read_frame_by_row;
for (i=0; i< NUM_ENCODERS; i++)
if (outfile[i]) write_ivf_file_header(outfile[i], &cfg[i], 0);
if(outfile[i])
write_ivf_file_header(outfile[i], &cfg[i], 0);
/* Temporal layers settings */
for (i = 0; i < NUM_ENCODERS; i++) {
set_temporal_layer_pattern(num_temporal_layers[i], &cfg[i],
for ( i=0; i<NUM_ENCODERS; i++)
{
set_temporal_layer_pattern(num_temporal_layers[i],
&cfg[i],
cfg[i].rc_target_bitrate,
&layer_flags[i * VPX_TS_MAX_PERIODICITY]);
}
@@ -492,7 +540,8 @@ int main(int argc, char **argv) {
/* The extra encoding configuration parameters can be set as follows. */
/* Set encoding speed */
for (i = 0; i < NUM_ENCODERS; i++) {
for ( i=0; i<NUM_ENCODERS; i++)
{
int speed = -6;
/* Lower speed for the lowest resolution. */
if (i == NUM_ENCODERS - 1) speed = -4;
@@ -501,28 +550,32 @@ int main(int argc, char **argv) {
}
/* Set static threshold = 1 for all encoders */
for (i = 0; i < NUM_ENCODERS; i++) {
for ( i=0; i<NUM_ENCODERS; i++)
{
if(vpx_codec_control(&codec[i], VP8E_SET_STATIC_THRESHOLD, 1))
die_codec(&codec[i], "Failed to set static threshold");
}
/* Set NOISE_SENSITIVITY to do TEMPORAL_DENOISING */
/* 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");
for (i = 1; i < NUM_ENCODERS; i++) {
for ( i=1; i< NUM_ENCODERS; i++)
{
if(vpx_codec_control(&codec[i], VP8E_SET_NOISE_SENSITIVITY, 0))
die_codec(&codec[i], "Failed to set noise_sensitivity");
}
/* Set the number of token partitions */
for (i = 0; i < NUM_ENCODERS; i++) {
for ( i=0; i<NUM_ENCODERS; i++)
{
if(vpx_codec_control(&codec[i], VP8E_SET_TOKEN_PARTITIONS, 1))
die_codec(&codec[i], "Failed to set static threshold");
}
/* Set the max intra target bitrate */
for (i = 0; i < NUM_ENCODERS; i++) {
for ( i=0; i<NUM_ENCODERS; i++)
{
unsigned int max_intra_size_pct =
(int)(((double)cfg[0].rc_buf_optimal_sz * 0.5) * framerate / 10);
if(vpx_codec_control(&codec[i], VP8E_SET_MAX_INTRA_BITRATE_PCT,
@@ -534,47 +587,55 @@ int main(int argc, char **argv) {
frame_avail = 1;
got_data = 0;
while (frame_avail || got_data) {
struct vpx_usec_timer timer;
while(frame_avail || got_data)
{
vpx_codec_iter_t iter[NUM_ENCODERS]={NULL};
const vpx_codec_cx_pkt_t *pkt[NUM_ENCODERS];
flags = 0;
frame_avail = read_frame_p(infile, &raw[0]);
if (frame_avail) {
for (i = 1; i < NUM_ENCODERS; i++) {
if(frame_avail)
{
for ( i=1; i<NUM_ENCODERS; i++)
{
/*Scale the image down a number of times by downsampling factor*/
/* FilterMode 1 or 2 give better psnr than FilterMode 0. */
I420Scale(
raw[i - 1].planes[VPX_PLANE_Y], raw[i - 1].stride[VPX_PLANE_Y],
I420Scale(raw[i-1].planes[VPX_PLANE_Y], raw[i-1].stride[VPX_PLANE_Y],
raw[i-1].planes[VPX_PLANE_U], raw[i-1].stride[VPX_PLANE_U],
raw[i-1].planes[VPX_PLANE_V], raw[i-1].stride[VPX_PLANE_V],
raw[i - 1].d_w, raw[i - 1].d_h, raw[i].planes[VPX_PLANE_Y],
raw[i].stride[VPX_PLANE_Y], raw[i].planes[VPX_PLANE_U],
raw[i].stride[VPX_PLANE_U], raw[i].planes[VPX_PLANE_V],
raw[i].stride[VPX_PLANE_V], raw[i].d_w, raw[i].d_h, 1);
raw[i-1].d_w, raw[i-1].d_h,
raw[i].planes[VPX_PLANE_Y], raw[i].stride[VPX_PLANE_Y],
raw[i].planes[VPX_PLANE_U], raw[i].stride[VPX_PLANE_U],
raw[i].planes[VPX_PLANE_V], raw[i].stride[VPX_PLANE_V],
raw[i].d_w, raw[i].d_h, 1);
/* Write out down-sampled input. */
length_frame = cfg[i].g_w * cfg[i].g_h *3/2;
if (fwrite(raw[i].planes[0], 1, length_frame,
downsampled_input[NUM_ENCODERS - i - 1]) != length_frame) {
downsampled_input[NUM_ENCODERS - i - 1]) !=
length_frame)
{
return EXIT_FAILURE;
}
}
}
/* Set the flags (reference and update) for all the encoders.*/
for (i = 0; i < NUM_ENCODERS; i++) {
for ( i=0; i<NUM_ENCODERS; i++)
{
layer_id = cfg[i].ts_layer_id[frame_cnt % cfg[i].ts_periodicity];
flags = 0;
flag_periodicity = periodicity_to_num_layers[num_temporal_layers[i] - 1];
flag_periodicity = periodicity_to_num_layers
[num_temporal_layers[i] - 1];
flags = layer_flags[i * VPX_TS_MAX_PERIODICITY +
frame_cnt % flag_periodicity];
// Key frame flag for first frame.
if (frame_cnt == 0) {
if (frame_cnt == 0)
{
flags |= VPX_EFLAG_FORCE_KF;
}
if (frame_cnt > 0 && frame_cnt == key_frame_insert) {
if (frame_cnt > 0 && frame_cnt == key_frame_insert)
{
flags = VPX_EFLAG_FORCE_KF;
}
@@ -582,70 +643,76 @@ int main(int argc, char **argv) {
vpx_codec_control(&codec[i], VP8E_SET_TEMPORAL_LAYER_ID, layer_id);
}
gettimeofday(&tv1, NULL);
/* Encode each frame at multi-levels */
/* Note the flags must be set to 0 in the encode call if they are set
for each frame with the vpx_codec_control(), as done above. */
vpx_usec_timer_start(&timer);
if (vpx_codec_encode(&codec[0], frame_avail ? &raw[0] : NULL, frame_cnt, 1,
0, arg_deadline)) {
if(vpx_codec_encode(&codec[0], frame_avail? &raw[0] : NULL,
frame_cnt, 1, 0, arg_deadline))
{
die_codec(&codec[0], "Failed to encode frame");
}
vpx_usec_timer_mark(&timer);
cx_time += vpx_usec_timer_elapsed(&timer);
for (i = NUM_ENCODERS - 1; i >= 0; i--) {
gettimeofday(&tv2, NULL);
timersub(&tv2, &tv1, &difftv);
cx_time += (double)(difftv.tv_sec * 1000000 + difftv.tv_usec);
for (i=NUM_ENCODERS-1; i>=0 ; i--)
{
got_data = 0;
while ((pkt[i] = vpx_codec_get_cx_data(&codec[i], &iter[i]))) {
while( (pkt[i] = vpx_codec_get_cx_data(&codec[i], &iter[i])) )
{
got_data = 1;
switch(pkt[i]->kind) {
case VPX_CODEC_CX_FRAME_PKT:
write_ivf_frame_header(outfile[i], pkt[i]);
(void)fwrite(pkt[i]->data.frame.buf, 1, pkt[i]->data.frame.sz,
outfile[i]);
(void) fwrite(pkt[i]->data.frame.buf, 1,
pkt[i]->data.frame.sz, outfile[i]);
break;
case VPX_CODEC_PSNR_PKT:
if (show_psnr) {
if (show_psnr)
{
int j;
psnr_sse_total[i] += pkt[i]->data.psnr.sse[0];
psnr_samples_total[i] += pkt[i]->data.psnr.samples[0];
for (j = 0; j < 4; j++) {
for (j = 0; j < 4; j++)
{
psnr_totals[i][j] += pkt[i]->data.psnr.psnr[j];
}
psnr_count[i]++;
}
break;
default: break;
default:
break;
}
printf(pkt[i]->kind == VPX_CODEC_CX_FRAME_PKT &&
(pkt[i]->data.frame.flags & VPX_FRAME_IS_KEY)
? "K"
: "");
printf(pkt[i]->kind == VPX_CODEC_CX_FRAME_PKT
&& (pkt[i]->data.frame.flags & VPX_FRAME_IS_KEY)? "K":"");
fflush(stdout);
}
}
frame_cnt++;
}
printf("\n");
printf("Frame cnt and encoding time/FPS stats for encoding: %d %f %f \n",
frame_cnt, 1000 * (float)cx_time / (double)(frame_cnt * 1000000),
printf("FPS for encoding %d %f %f \n", frame_cnt, (float)cx_time / 1000000,
1000000 * (double)frame_cnt / (double)cx_time);
fclose(infile);
printf("Processed %ld frames.\n",(long int)frame_cnt-1);
for (i = 0; i < NUM_ENCODERS; i++) {
for (i=0; i< NUM_ENCODERS; i++)
{
/* Calculate PSNR and print it out */
if ((show_psnr) && (psnr_count[i] > 0)) {
if ( (show_psnr) && (psnr_count[i]>0) )
{
int j;
double ovpsnr =
sse_to_psnr(psnr_samples_total[i], 255.0, psnr_sse_total[i]);
double ovpsnr = sse_to_psnr(psnr_samples_total[i], 255.0,
psnr_sse_total[i]);
fprintf(stderr, "\n ENC%d PSNR (Overall/Avg/Y/U/V)", i);
fprintf(stderr, " %.3lf", ovpsnr);
for (j = 0; j < 4; j++) {
for (j = 0; j < 4; j++)
{
fprintf(stderr, " %.3lf", psnr_totals[i][j]/psnr_count[i]);
}
}
@@ -655,7 +722,8 @@ int main(int argc, char **argv) {
vpx_img_free(&raw[i]);
if (!outfile[i]) continue;
if(!outfile[i])
continue;
/* Try to rewrite the file header with the actual frame count */
if(!fseek(outfile[i], 0, SEEK_SET))

View File

@@ -8,6 +8,7 @@
* be found in the AUTHORS file in the root of the source tree.
*/
// VP8 Set Reference Frame
// =======================
//
@@ -63,21 +64,25 @@ void usage_exit(void) {
exit(EXIT_FAILURE);
}
static int encode_frame(vpx_codec_ctx_t *codec, vpx_image_t *img,
int frame_index, VpxVideoWriter *writer) {
static int encode_frame(vpx_codec_ctx_t *codec,
vpx_image_t *img,
int frame_index,
VpxVideoWriter *writer) {
int got_pkts = 0;
vpx_codec_iter_t iter = NULL;
const vpx_codec_cx_pkt_t *pkt = NULL;
const vpx_codec_err_t res =
vpx_codec_encode(codec, img, frame_index, 1, 0, VPX_DL_GOOD_QUALITY);
if (res != VPX_CODEC_OK) die_codec(codec, "Failed to encode frame");
const vpx_codec_err_t res = vpx_codec_encode(codec, img, frame_index, 1, 0,
VPX_DL_GOOD_QUALITY);
if (res != VPX_CODEC_OK)
die_codec(codec, "Failed to encode frame");
while ((pkt = vpx_codec_get_cx_data(codec, &iter)) != NULL) {
got_pkts = 1;
if (pkt->kind == VPX_CODEC_CX_FRAME_PKT) {
const int keyframe = (pkt->data.frame.flags & VPX_FRAME_IS_KEY) != 0;
if (!vpx_video_writer_write_frame(writer, pkt->data.frame.buf,
if (!vpx_video_writer_write_frame(writer,
pkt->data.frame.buf,
pkt->data.frame.sz,
pkt->data.frame.pts)) {
die_codec(codec, "Failed to write compressed frame");
@@ -107,14 +112,17 @@ int main(int argc, char **argv) {
exec_name = argv[0];
if (argc != 6) die("Invalid number of arguments");
if (argc != 6)
die("Invalid number of arguments");
// TODO(dkovalev): add vp9 support and rename the file accordingly
encoder = get_vpx_encoder_by_name("vp8");
if (!encoder) die("Unsupported codec.");
if (!encoder)
die("Unsupported codec.");
update_frame_num = atoi(argv[5]);
if (!update_frame_num) die("Couldn't parse frame number '%s'\n", argv[5]);
if (!update_frame_num)
die("Couldn't parse frame number '%s'\n", argv[5]);
info.codec_fourcc = encoder->fourcc;
info.frame_width = strtol(argv[1], NULL, 0);
@@ -122,8 +130,10 @@ int main(int argc, char **argv) {
info.time_base.numerator = 1;
info.time_base.denominator = fps;
if (info.frame_width <= 0 || info.frame_height <= 0 ||
(info.frame_width % 2) != 0 || (info.frame_height % 2) != 0) {
if (info.frame_width <= 0 ||
info.frame_height <= 0 ||
(info.frame_width % 2) != 0 ||
(info.frame_height % 2) != 0) {
die("Invalid frame size: %dx%d", info.frame_width, info.frame_height);
}
@@ -135,7 +145,8 @@ int main(int argc, char **argv) {
printf("Using %s\n", vpx_codec_iface_name(encoder->codec_interface()));
res = vpx_codec_enc_config_default(encoder->codec_interface(), &cfg, 0);
if (res) die_codec(&codec, "Failed to get default codec config.");
if (res)
die_codec(&codec, "Failed to get default codec config.");
cfg.g_w = info.frame_width;
cfg.g_h = info.frame_height;
@@ -144,7 +155,8 @@ int main(int argc, char **argv) {
cfg.rc_target_bitrate = bitrate;
writer = vpx_video_writer_open(argv[4], kContainerIVF, &info);
if (!writer) die("Failed to open %s for writing.", argv[4]);
if (!writer)
die("Failed to open %s for writing.", argv[4]);
if (!(infile = fopen(argv[3], "rb")))
die("Failed to open %s for reading.", argv[3]);
@@ -166,15 +178,15 @@ int main(int argc, char **argv) {
}
// Flush encoder.
while (encode_frame(&codec, NULL, -1, writer)) {
}
while (encode_frame(&codec, NULL, -1, writer)) {}
printf("\n");
fclose(infile);
printf("Processed %d frames.\n", frame_count);
vpx_img_free(&raw);
if (vpx_codec_destroy(&codec)) die_codec(&codec, "Failed to destroy codec.");
if (vpx_codec_destroy(&codec))
die_codec(&codec, "Failed to destroy codec.");
vpx_video_writer_close(writer);

View File

@@ -21,28 +21,32 @@
static const char *exec_name;
void usage_exit(void) {
fprintf(stderr,
"vp9_lossless_encoder: Example demonstrating VP9 lossless "
fprintf(stderr, "vp9_lossless_encoder: Example demonstrating VP9 lossless "
"encoding feature. Supports raw input only.\n");
fprintf(stderr, "Usage: %s <width> <height> <infile> <outfile>\n", exec_name);
exit(EXIT_FAILURE);
}
static int encode_frame(vpx_codec_ctx_t *codec, vpx_image_t *img,
int frame_index, int flags, VpxVideoWriter *writer) {
static int encode_frame(vpx_codec_ctx_t *codec,
vpx_image_t *img,
int frame_index,
int flags,
VpxVideoWriter *writer) {
int got_pkts = 0;
vpx_codec_iter_t iter = NULL;
const vpx_codec_cx_pkt_t *pkt = NULL;
const vpx_codec_err_t res =
vpx_codec_encode(codec, img, frame_index, 1, flags, VPX_DL_GOOD_QUALITY);
if (res != VPX_CODEC_OK) die_codec(codec, "Failed to encode frame");
const vpx_codec_err_t res = vpx_codec_encode(codec, img, frame_index, 1,
flags, VPX_DL_GOOD_QUALITY);
if (res != VPX_CODEC_OK)
die_codec(codec, "Failed to encode frame");
while ((pkt = vpx_codec_get_cx_data(codec, &iter)) != NULL) {
got_pkts = 1;
if (pkt->kind == VPX_CODEC_CX_FRAME_PKT) {
const int keyframe = (pkt->data.frame.flags & VPX_FRAME_IS_KEY) != 0;
if (!vpx_video_writer_write_frame(writer, pkt->data.frame.buf,
if (!vpx_video_writer_write_frame(writer,
pkt->data.frame.buf,
pkt->data.frame.sz,
pkt->data.frame.pts)) {
die_codec(codec, "Failed to write compressed frame");
@@ -69,10 +73,12 @@ int main(int argc, char **argv) {
exec_name = argv[0];
if (argc < 5) die("Invalid number of arguments");
if (argc < 5)
die("Invalid number of arguments");
encoder = get_vpx_encoder_by_name("vp9");
if (!encoder) die("Unsupported codec.");
if (!encoder)
die("Unsupported codec.");
info.codec_fourcc = encoder->fourcc;
info.frame_width = strtol(argv[1], NULL, 0);
@@ -80,8 +86,10 @@ int main(int argc, char **argv) {
info.time_base.numerator = 1;
info.time_base.denominator = fps;
if (info.frame_width <= 0 || info.frame_height <= 0 ||
(info.frame_width % 2) != 0 || (info.frame_height % 2) != 0) {
if (info.frame_width <= 0 ||
info.frame_height <= 0 ||
(info.frame_width % 2) != 0 ||
(info.frame_height % 2) != 0) {
die("Invalid frame size: %dx%d", info.frame_width, info.frame_height);
}
@@ -93,7 +101,8 @@ int main(int argc, char **argv) {
printf("Using %s\n", vpx_codec_iface_name(encoder->codec_interface()));
res = vpx_codec_enc_config_default(encoder->codec_interface(), &cfg, 0);
if (res) die_codec(&codec, "Failed to get default codec config.");
if (res)
die_codec(&codec, "Failed to get default codec config.");
cfg.g_w = info.frame_width;
cfg.g_h = info.frame_height;
@@ -101,7 +110,8 @@ int main(int argc, char **argv) {
cfg.g_timebase.den = info.time_base.denominator;
writer = vpx_video_writer_open(argv[4], kContainerIVF, &info);
if (!writer) die("Failed to open %s for writing.", argv[4]);
if (!writer)
die("Failed to open %s for writing.", argv[4]);
if (!(infile = fopen(argv[3], "rb")))
die("Failed to open %s for reading.", argv[3]);
@@ -118,15 +128,15 @@ int main(int argc, char **argv) {
}
// Flush encoder.
while (encode_frame(&codec, NULL, -1, 0, writer)) {
}
while (encode_frame(&codec, NULL, -1, 0, writer)) {}
printf("\n");
fclose(infile);
printf("Processed %d frames.\n", frame_count);
vpx_img_free(&raw);
if (vpx_codec_destroy(&codec)) die_codec(&codec, "Failed to destroy codec.");
if (vpx_codec_destroy(&codec))
die_codec(&codec, "Failed to destroy codec.");
vpx_video_writer_close(writer);

View File

@@ -20,6 +20,7 @@
#include <string.h>
#include <time.h>
#include "../args.h"
#include "../tools_common.h"
#include "../video_writer.h"
@@ -29,7 +30,6 @@
#include "vpx/vp8cx.h"
#include "vpx/vpx_encoder.h"
#include "../vpxstats.h"
#include "vp9/encoder/vp9_encoder.h"
#define OUTPUT_RC_STATS 1
static const arg_def_t skip_frames_arg =
@@ -53,8 +53,7 @@ static const arg_def_t spatial_layers_arg =
static const arg_def_t temporal_layers_arg =
ARG_DEF("tl", "temporal-layers", 1, "number of temporal SVC layers");
static const arg_def_t temporal_layering_mode_arg =
ARG_DEF("tlm", "temporal-layering-mode", 1,
"temporal layering scheme."
ARG_DEF("tlm", "temporal-layering-mode", 1, "temporal layering scheme."
"VP9E_TEMPORAL_LAYERING_MODE");
static const arg_def_t kf_dist_arg =
ARG_DEF("k", "kf-dist", 1, "number of frames between keyframes");
@@ -75,46 +74,34 @@ static const arg_def_t min_bitrate_arg =
static const arg_def_t max_bitrate_arg =
ARG_DEF(NULL, "max-bitrate", 1, "Maximum bitrate");
static const arg_def_t lag_in_frame_arg =
ARG_DEF(NULL, "lag-in-frames", 1,
"Number of frame to input before "
ARG_DEF(NULL, "lag-in-frames", 1, "Number of frame to input before "
"generating any outputs");
static const arg_def_t rc_end_usage_arg =
ARG_DEF(NULL, "rc-end-usage", 1, "0 - 3: VBR, CBR, CQ, Q");
static const arg_def_t speed_arg =
ARG_DEF("sp", "speed", 1, "speed configuration");
static const arg_def_t aqmode_arg =
ARG_DEF("aq", "aqmode", 1, "aq-mode off/on");
#if CONFIG_VP9_HIGHBITDEPTH
static const struct arg_enum_list bitdepth_enum[] = {
{ "8", VPX_BITS_8 }, { "10", VPX_BITS_10 }, { "12", VPX_BITS_12 }, { NULL, 0 }
{"8", VPX_BITS_8},
{"10", VPX_BITS_10},
{"12", VPX_BITS_12},
{NULL, 0}
};
static const arg_def_t bitdepth_arg = ARG_DEF_ENUM(
"d", "bit-depth", 1, "Bit depth for codec 8, 10 or 12. ", bitdepth_enum);
static const arg_def_t bitdepth_arg =
ARG_DEF_ENUM("d", "bit-depth", 1, "Bit depth for codec 8, 10 or 12. ",
bitdepth_enum);
#endif // CONFIG_VP9_HIGHBITDEPTH
static const arg_def_t *svc_args[] = { &frames_arg,
&width_arg,
&height_arg,
&timebase_arg,
&bitrate_arg,
&skip_frames_arg,
&spatial_layers_arg,
&kf_dist_arg,
&scale_factors_arg,
&passes_arg,
&pass_arg,
&fpf_name_arg,
&min_q_arg,
&max_q_arg,
&min_bitrate_arg,
&max_bitrate_arg,
&temporal_layers_arg,
&temporal_layering_mode_arg,
&lag_in_frame_arg,
&threads_arg,
&aqmode_arg,
static const arg_def_t *svc_args[] = {
&frames_arg, &width_arg, &height_arg,
&timebase_arg, &bitrate_arg, &skip_frames_arg, &spatial_layers_arg,
&kf_dist_arg, &scale_factors_arg, &passes_arg, &pass_arg,
&fpf_name_arg, &min_q_arg, &max_q_arg, &min_bitrate_arg,
&max_bitrate_arg, &temporal_layers_arg, &temporal_layering_mode_arg,
&lag_in_frame_arg, &threads_arg,
#if OUTPUT_RC_STATS
&output_rc_stats_arg,
#endif
@@ -123,8 +110,8 @@ static const arg_def_t *svc_args[] = { &frames_arg,
&bitdepth_arg,
#endif
&speed_arg,
&rc_end_usage_arg,
NULL };
&rc_end_usage_arg, NULL
};
static const uint32_t default_frames_to_skip = 0;
static const uint32_t default_frames_to_code = 60 * 60;
@@ -234,13 +221,11 @@ static void parse_command_line(int argc, const char **argv_,
#endif
} else if (arg_match(&arg, &speed_arg, argi)) {
svc_ctx->speed = arg_parse_uint(&arg);
} else if (arg_match(&arg, &aqmode_arg, argi)) {
svc_ctx->aqmode = arg_parse_uint(&arg);
} else if (arg_match(&arg, &threads_arg, argi)) {
svc_ctx->threads = arg_parse_uint(&arg);
} else if (arg_match(&arg, &temporal_layering_mode_arg, argi)) {
svc_ctx->temporal_layering_mode = enc_cfg->temporal_layering_mode =
arg_parse_int(&arg);
svc_ctx->temporal_layering_mode =
enc_cfg->temporal_layering_mode = arg_parse_int(&arg);
if (svc_ctx->temporal_layering_mode) {
enc_cfg->g_error_resilient = 1;
}
@@ -370,8 +355,9 @@ static void parse_command_line(int argc, const char **argv_,
"num: %d, den: %d, bitrate: %d,\n"
"gop size: %d\n",
vpx_codec_iface_name(vpx_codec_vp9_cx()), app_input->frames_to_code,
app_input->frames_to_skip, svc_ctx->spatial_layers, enc_cfg->g_w,
enc_cfg->g_h, enc_cfg->g_timebase.num, enc_cfg->g_timebase.den,
app_input->frames_to_skip,
svc_ctx->spatial_layers, enc_cfg->g_w, enc_cfg->g_h,
enc_cfg->g_timebase.num, enc_cfg->g_timebase.den,
enc_cfg->rc_target_bitrate, enc_cfg->kf_max_dist);
}
@@ -418,17 +404,17 @@ static void set_rate_control_stats(struct RateControlStats *rc,
for (tl = 0; tl < 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)
rc->layer_framerate[layer] = framerate;
else
rc->layer_framerate[layer] = framerate / cfg->ts_rate_decimator[tl];
rc->layer_framerate[layer] =
framerate / cfg->ts_rate_decimator[tl];
if (tl > 0) {
rc->layer_pfb[layer] =
1000.0 * (cfg->layer_target_bitrate[layer] -
rc->layer_pfb[layer] = 1000.0 *
(cfg->layer_target_bitrate[layer] -
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 {
rc->layer_pfb[tlayer0] = 1000.0 * cfg->layer_target_bitrate[tlayer0] /
rc->layer_pfb[tlayer0] = 1000.0 *
cfg->layer_target_bitrate[tlayer0] /
rc->layer_framerate[tlayer0];
}
rc->layer_input_frames[layer] = 0;
@@ -457,19 +443,17 @@ static void printout_rate_control_summary(struct RateControlStats *rc,
for (sl = 0; sl < cfg->ss_number_layers; ++sl) {
for (tl = 0; tl < cfg->ts_number_layers; ++tl) {
const int layer = sl * cfg->ts_number_layers + tl;
const int num_dropped =
(tl > 0)
? (rc->layer_input_frames[layer] - rc->layer_enc_frames[layer])
: (rc->layer_input_frames[layer] - rc->layer_enc_frames[layer] -
1);
if (!sl) tot_num_frames += rc->layer_input_frames[layer];
const int num_dropped = (tl > 0) ?
(rc->layer_input_frames[layer] - rc->layer_enc_frames[layer]) :
(rc->layer_input_frames[layer] - rc->layer_enc_frames[layer] - 1);
if (!sl)
tot_num_frames += rc->layer_input_frames[layer];
rc->layer_encoding_bitrate[layer] = 0.001 * rc->layer_framerate[layer] *
rc->layer_encoding_bitrate[layer] /
tot_num_frames;
rc->layer_avg_frame_size[layer] =
rc->layer_avg_frame_size[layer] / rc->layer_enc_frames[layer];
rc->layer_avg_rate_mismatch[layer] = 100.0 *
rc->layer_avg_rate_mismatch[layer] /
rc->layer_encoding_bitrate[layer] / tot_num_frames;
rc->layer_avg_frame_size[layer] = rc->layer_avg_frame_size[layer] /
rc->layer_enc_frames[layer];
rc->layer_avg_rate_mismatch[layer] =
100.0 * rc->layer_avg_rate_mismatch[layer] /
rc->layer_enc_frames[layer];
printf("For layer#: sl%d tl%d \n", sl, tl);
printf("Bitrate (target vs actual): %d %f.0 kbps\n",
@@ -477,9 +461,9 @@ static void printout_rate_control_summary(struct RateControlStats *rc,
rc->layer_encoding_bitrate[layer]);
printf("Average frame size (target vs actual): %f %f bits\n",
rc->layer_pfb[layer], rc->layer_avg_frame_size[layer]);
printf("Average rate_mismatch: %f\n", rc->layer_avg_rate_mismatch[layer]);
printf(
"Number of input frames, encoded (non-key) frames, "
printf("Average rate_mismatch: %f\n",
rc->layer_avg_rate_mismatch[layer]);
printf("Number of input frames, encoded (non-key) frames, "
"and percent dropped frames: %d %d %f.0 \n",
rc->layer_input_frames[layer], rc->layer_enc_frames[layer],
100.0 * num_dropped / rc->layer_input_frames[layer]);
@@ -494,16 +478,16 @@ static void printout_rate_control_summary(struct RateControlStats *rc,
rc->avg_st_encoding_bitrate;
printf("Short-time stats, for window of %d frames: \n", rc->window_size);
printf("Average, rms-variance, and percent-fluct: %f %f %f \n",
rc->avg_st_encoding_bitrate, sqrt(rc->variance_st_encoding_bitrate),
rc->avg_st_encoding_bitrate,
sqrt(rc->variance_st_encoding_bitrate),
perc_fluctuation);
if (frame_cnt != tot_num_frames)
die(
"Error: Number of input frames not equal to output encoded frames != "
"%d tot_num_frames = %d\n",
frame_cnt, tot_num_frames);
die("Error: Number of input frames not equal to output encoded frames != "
"%d tot_num_frames = %d\n", frame_cnt, tot_num_frames);
}
vpx_codec_err_t parse_superframe_index(const uint8_t *data, size_t data_sz,
vpx_codec_err_t parse_superframe_index(const uint8_t *data,
size_t data_sz,
uint32_t sizes[8], int *count) {
// A chunk ending with a byte matching 0xc0 is an invalid chunk unless
// it is a super frame index. If the last byte of real video compression
@@ -516,6 +500,7 @@ vpx_codec_err_t parse_superframe_index(const uint8_t *data, size_t data_sz,
marker = *(data + data_sz - 1);
*count = 0;
if ((marker & 0xe0) == 0xc0) {
const uint32_t frames = (marker & 0x7) + 1;
const uint32_t mag = ((marker >> 3) & 0x3) + 1;
@@ -523,7 +508,8 @@ vpx_codec_err_t parse_superframe_index(const uint8_t *data, size_t data_sz,
// This chunk is marked as having a superframe index but doesn't have
// enough data for it, thus it's an invalid superframe index.
if (data_sz < index_sz) return VPX_CODEC_CORRUPT_FRAME;
if (data_sz < index_sz)
return VPX_CODEC_CORRUPT_FRAME;
{
const uint8_t marker2 = *(data + data_sz - index_sz);
@@ -531,7 +517,8 @@ vpx_codec_err_t parse_superframe_index(const uint8_t *data, size_t data_sz,
// This chunk is marked as having a superframe index but doesn't have
// the matching marker byte at the front of the index therefore it's an
// invalid chunk.
if (marker != marker2) return VPX_CODEC_CORRUPT_FRAME;
if (marker != marker2)
return VPX_CODEC_CORRUPT_FRAME;
}
{
@@ -542,7 +529,8 @@ vpx_codec_err_t parse_superframe_index(const uint8_t *data, size_t data_sz,
for (i = 0; i < frames; ++i) {
uint32_t this_sz = 0;
for (j = 0; j < mag; ++j) this_sz |= (*x++) << (j * 8);
for (j = 0; j < mag; ++j)
this_sz |= (*x++) << (j * 8);
sizes[i] = this_sz;
}
*count = frames;
@@ -552,54 +540,6 @@ vpx_codec_err_t parse_superframe_index(const uint8_t *data, size_t data_sz,
}
#endif
// Example pattern for spatial layers and 2 temporal layers used in the
// bypass/flexible mode. The pattern corresponds to the pattern
// VP9E_TEMPORAL_LAYERING_MODE_0101 (temporal_layering_mode == 2) used in
// non-flexible mode.
void set_frame_flags_bypass_mode(int sl, int tl, int num_spatial_layers,
int is_key_frame,
vpx_svc_ref_frame_config_t *ref_frame_config) {
for (sl = 0; sl < num_spatial_layers; ++sl) {
if (!tl) {
if (!sl) {
ref_frame_config->frame_flags[sl] =
VP8_EFLAG_NO_REF_GF | VP8_EFLAG_NO_REF_ARF | VP8_EFLAG_NO_UPD_GF |
VP8_EFLAG_NO_UPD_ARF;
} else {
if (is_key_frame) {
ref_frame_config->frame_flags[sl] =
VP8_EFLAG_NO_REF_LAST | VP8_EFLAG_NO_REF_ARF |
VP8_EFLAG_NO_UPD_GF | VP8_EFLAG_NO_UPD_ARF;
} else {
ref_frame_config->frame_flags[sl] =
VP8_EFLAG_NO_REF_ARF | VP8_EFLAG_NO_UPD_GF | VP8_EFLAG_NO_UPD_ARF;
}
}
} else if (tl == 1) {
if (!sl) {
ref_frame_config->frame_flags[sl] =
VP8_EFLAG_NO_REF_GF | VP8_EFLAG_NO_REF_ARF | VP8_EFLAG_NO_UPD_LAST |
VP8_EFLAG_NO_UPD_GF;
} else {
ref_frame_config->frame_flags[sl] =
VP8_EFLAG_NO_REF_ARF | VP8_EFLAG_NO_UPD_LAST | VP8_EFLAG_NO_UPD_GF;
}
}
if (tl == 0) {
ref_frame_config->lst_fb_idx[sl] = sl;
if (sl)
ref_frame_config->gld_fb_idx[sl] = sl - 1;
else
ref_frame_config->gld_fb_idx[sl] = 0;
ref_frame_config->alt_fb_idx[sl] = 0;
} else if (tl == 1) {
ref_frame_config->lst_fb_idx[sl] = sl;
ref_frame_config->gld_fb_idx[sl] = num_spatial_layers + sl - 1;
ref_frame_config->alt_fb_idx[sl] = num_spatial_layers + sl;
}
}
}
int main(int argc, const char **argv) {
AppInput app_input = {0};
VpxVideoWriter *writer = NULL;
@@ -620,7 +560,6 @@ int main(int argc, const char **argv) {
VpxVideoWriter *outfile[VPX_TS_MAX_LAYERS] = {NULL};
struct RateControlStats rc;
vpx_svc_layer_id_t layer_id;
vpx_svc_ref_frame_config_t ref_frame_config;
int sl, tl;
double sum_bitrate = 0.0;
double sum_bitrate2 = 0.0;
@@ -635,8 +574,8 @@ int main(int argc, const char **argv) {
// Allocate image buffer
#if CONFIG_VP9_HIGHBITDEPTH
if (!vpx_img_alloc(&raw, enc_cfg.g_input_bit_depth == 8 ? VPX_IMG_FMT_I420
: VPX_IMG_FMT_I42016,
if (!vpx_img_alloc(&raw, enc_cfg.g_input_bit_depth == 8 ?
VPX_IMG_FMT_I420 : VPX_IMG_FMT_I42016,
enc_cfg.g_w, enc_cfg.g_h, 32)) {
die("Failed to allocate image %dx%d\n", enc_cfg.g_w, enc_cfg.g_h);
}
@@ -667,8 +606,8 @@ int main(int argc, const char **argv) {
if (!(app_input.passes == 2 && app_input.pass == 1)) {
// We don't save the bitstream for the 1st pass on two pass rate control
writer =
vpx_video_writer_open(app_input.output_filename, kContainerIVF, &info);
writer = vpx_video_writer_open(app_input.output_filename, kContainerIVF,
&info);
if (!writer)
die("Failed to open %s for writing\n", app_input.output_filename);
}
@@ -682,21 +621,24 @@ int main(int argc, const char **argv) {
snprintf(file_name, sizeof(file_name), "%s_t%d.ivf",
app_input.output_filename, tl);
outfile[tl] = vpx_video_writer_open(file_name, kContainerIVF, &info);
if (!outfile[tl]) die("Failed to open %s for writing", file_name);
if (!outfile[tl])
die("Failed to open %s for writing", file_name);
}
}
#endif
// skip initial frames
for (i = 0; i < app_input.frames_to_skip; ++i) vpx_img_read(&raw, infile);
for (i = 0; i < app_input.frames_to_skip; ++i)
vpx_img_read(&raw, infile);
if (svc_ctx.speed != -1)
vpx_codec_control(&codec, VP8E_SET_CPUUSED, svc_ctx.speed);
if (svc_ctx.threads)
vpx_codec_control(&codec, VP9E_SET_TILE_COLUMNS, (svc_ctx.threads >> 1));
if (svc_ctx.speed >= 5 && svc_ctx.aqmode == 1)
if (svc_ctx.speed >= 5)
vpx_codec_control(&codec, VP9E_SET_AQ_MODE, 3);
// Encode frames
while (!end_of_stream) {
vpx_codec_iter_t iter = NULL;
@@ -707,45 +649,14 @@ int main(int argc, const char **argv) {
end_of_stream = 1;
}
// For BYPASS/FLEXIBLE mode, set the frame flags (reference and updates)
// and the buffer indices for each spatial layer of the current
// (super)frame to be encoded. The temporal layer_id for the current frame
// also needs to be set.
// TODO(marpan): Should rename the "VP9E_TEMPORAL_LAYERING_MODE_BYPASS"
// mode to "VP9E_LAYERING_MODE_BYPASS".
if (svc_ctx.temporal_layering_mode == VP9E_TEMPORAL_LAYERING_MODE_BYPASS) {
layer_id.spatial_layer_id = 0;
// Example for 2 temporal layers.
if (frame_cnt % 2 == 0)
layer_id.temporal_layer_id = 0;
else
layer_id.temporal_layer_id = 1;
// Note that we only set the temporal layer_id, since we are calling
// the encode for the whole superframe. The encoder will internally loop
// over all the spatial layers for the current superframe.
vpx_codec_control(&codec, VP9E_SET_SVC_LAYER_ID, &layer_id);
set_frame_flags_bypass_mode(sl, layer_id.temporal_layer_id,
svc_ctx.spatial_layers, frame_cnt == 0,
&ref_frame_config);
vpx_codec_control(&codec, VP9E_SET_SVC_REF_FRAME_CONFIG,
&ref_frame_config);
// Keep track of input frames, to account for frame drops in rate control
// stats/metrics.
for (sl = 0; sl < enc_cfg.ss_number_layers; ++sl) {
++rc.layer_input_frames[sl * enc_cfg.ts_number_layers +
layer_id.temporal_layer_id];
}
}
vpx_usec_timer_start(&timer);
res = vpx_svc_encode(
&svc_ctx, &codec, (end_of_stream ? NULL : &raw), pts, frame_duration,
svc_ctx.speed >= 5 ? VPX_DL_REALTIME : VPX_DL_GOOD_QUALITY);
res = vpx_svc_encode(&svc_ctx, &codec, (end_of_stream ? NULL : &raw),
pts, frame_duration, svc_ctx.speed >= 5 ?
VPX_DL_REALTIME : VPX_DL_GOOD_QUALITY);
vpx_usec_timer_mark(&timer);
cx_time += vpx_usec_timer_elapsed(&timer);
printf("%s", vpx_svc_get_message(&svc_ctx));
fflush(stdout);
if (res != VPX_CODEC_OK) {
die_codec(&codec, "Failed to encode frame");
}
@@ -753,13 +664,13 @@ int main(int argc, const char **argv) {
while ((cx_pkt = vpx_codec_get_cx_data(&codec, &iter)) != NULL) {
switch (cx_pkt->kind) {
case VPX_CODEC_CX_FRAME_PKT: {
SvcInternal_t *const si = (SvcInternal_t *)svc_ctx.internal;
if (cx_pkt->data.frame.sz > 0) {
#if OUTPUT_RC_STATS
uint32_t sizes[8];
int count = 0;
#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.pts);
#if OUTPUT_RC_STATS
@@ -768,21 +679,15 @@ int main(int argc, const char **argv) {
vpx_codec_control(&codec, VP9E_GET_SVC_LAYER_ID, &layer_id);
parse_superframe_index(cx_pkt->data.frame.buf,
cx_pkt->data.frame.sz, sizes, &count);
// Note computing input_layer_frames here won't account for frame
// drops in rate control stats.
// TODO(marpan): Fix this for non-bypass mode so we can get stats
// for dropped frames.
if (svc_ctx.temporal_layering_mode !=
VP9E_TEMPORAL_LAYERING_MODE_BYPASS) {
for (sl = 0; sl < enc_cfg.ss_number_layers; ++sl) {
++rc.layer_input_frames[sl * enc_cfg.ts_number_layers +
layer_id.temporal_layer_id];
}
}
for (tl = layer_id.temporal_layer_id;
tl < enc_cfg.ts_number_layers; ++tl) {
vpx_video_writer_write_frame(
outfile[tl], cx_pkt->data.frame.buf, cx_pkt->data.frame.sz,
vpx_video_writer_write_frame(outfile[tl],
cx_pkt->data.frame.buf,
cx_pkt->data.frame.sz,
cx_pkt->data.frame.pts);
}
@@ -847,17 +752,18 @@ int main(int argc, const char **argv) {
printf("SVC frame: %d, kf: %d, size: %d, pts: %d\n", frames_received,
!!(cx_pkt->data.frame.flags & VPX_FRAME_IS_KEY),
(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)
si->bytes_sum[0] += (int)cx_pkt->data.frame.sz;
++frames_received;
break;
}
case VPX_CODEC_STATS_PKT: {
stats_write(&app_input.rc_stats, cx_pkt->data.twopass_stats.buf,
stats_write(&app_input.rc_stats,
cx_pkt->data.twopass_stats.buf,
cx_pkt->data.twopass_stats.sz);
break;
}
default: { break; }
default: {
break;
}
}
}
@@ -866,16 +772,6 @@ int main(int argc, const char **argv) {
pts += frame_duration;
}
}
// Compensate for the extra frame count for the bypass mode.
if (svc_ctx.temporal_layering_mode == VP9E_TEMPORAL_LAYERING_MODE_BYPASS) {
for (sl = 0; sl < enc_cfg.ss_number_layers; ++sl) {
const int layer =
sl * enc_cfg.ts_number_layers + layer_id.temporal_layer_id;
--rc.layer_input_frames[layer];
}
}
printf("Processed %d frames\n", frame_cnt);
fclose(infile);
#if OUTPUT_RC_STATS
@@ -885,7 +781,8 @@ int main(int argc, const char **argv) {
}
#endif
if (vpx_codec_destroy(&codec)) die_codec(&codec, "Failed to destroy codec");
if (app_input.passes == 2) stats_close(&app_input.rc_stats, 1);
if (app_input.passes == 2)
stats_close(&app_input.rc_stats, 1);
if (writer) {
vpx_video_writer_close(writer);
}
@@ -897,7 +794,8 @@ int main(int argc, const char **argv) {
}
#endif
printf("Frame cnt and encoding time/FPS stats for encoding: %d %f %f \n",
frame_cnt, 1000 * (float)cx_time / (double)(frame_cnt * 1000000),
frame_cnt,
1000 * (float)cx_time / (double)(frame_cnt * 1000000),
1000000 * (double)frame_cnt / (double)cx_time);
vpx_img_free(&raw);
// display average size, psnr

View File

@@ -1,434 +0,0 @@
/*
* Copyright (c) 2016 The WebM project authors. All Rights Reserved.
*
* Use of this source code is governed by a BSD-style license
* that can be found in the LICENSE file in the root of the source
* tree. An additional intellectual property rights grant can be found
* in the file PATENTS. All contributing project authors may
* be found in the AUTHORS file in the root of the source tree.
*/
// VP9 Set Reference Frame
// ============================
//
// This is an example demonstrating how to overwrite the VP9 encoder's
// internal reference frame. In the sample we set the last frame to the
// current frame. This technique could be used to bounce between two cameras.
//
// The decoder would also have to set the reference frame to the same value
// on the same frame, or the video will become corrupt. The 'test_decode'
// variable is set to 1 in this example that tests if the encoder and decoder
// results are matching.
//
// Usage
// -----
// This example encodes a raw video. And the last argument passed in specifies
// the frame number to update the reference frame on. For example, run
// examples/vp9cx_set_ref 352 288 in.yuv out.ivf 4 30
// The parameter is parsed as follows:
//
//
// Extra Variables
// ---------------
// This example maintains the frame number passed on the command line
// in the `update_frame_num` variable.
//
//
// Configuration
// -------------
//
// The reference frame is updated on the frame specified on the command
// line.
//
// Observing The Effects
// ---------------------
// The encoder and decoder results should be matching when the same reference
// frame setting operation is done in both encoder and decoder. Otherwise,
// the encoder/decoder mismatch would be seen.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "vpx/vp8cx.h"
#include "vpx/vpx_decoder.h"
#include "vpx/vpx_encoder.h"
#include "./tools_common.h"
#include "./video_writer.h"
static const char *exec_name;
void usage_exit() {
fprintf(stderr,
"Usage: %s <width> <height> <infile> <outfile> "
"<frame> <limit(optional)>\n",
exec_name);
exit(EXIT_FAILURE);
}
static int compare_img(const vpx_image_t *const img1,
const vpx_image_t *const img2) {
uint32_t l_w = img1->d_w;
uint32_t c_w = (img1->d_w + img1->x_chroma_shift) >> img1->x_chroma_shift;
const uint32_t c_h =
(img1->d_h + img1->y_chroma_shift) >> img1->y_chroma_shift;
uint32_t i;
int match = 1;
match &= (img1->fmt == img2->fmt);
match &= (img1->d_w == img2->d_w);
match &= (img1->d_h == img2->d_h);
for (i = 0; i < img1->d_h; ++i)
match &= (memcmp(img1->planes[VPX_PLANE_Y] + i * img1->stride[VPX_PLANE_Y],
img2->planes[VPX_PLANE_Y] + i * img2->stride[VPX_PLANE_Y],
l_w) == 0);
for (i = 0; i < c_h; ++i)
match &= (memcmp(img1->planes[VPX_PLANE_U] + i * img1->stride[VPX_PLANE_U],
img2->planes[VPX_PLANE_U] + i * img2->stride[VPX_PLANE_U],
c_w) == 0);
for (i = 0; i < c_h; ++i)
match &= (memcmp(img1->planes[VPX_PLANE_V] + i * img1->stride[VPX_PLANE_V],
img2->planes[VPX_PLANE_V] + i * img2->stride[VPX_PLANE_V],
c_w) == 0);
return match;
}
#define mmin(a, b) ((a) < (b) ? (a) : (b))
static void find_mismatch(const vpx_image_t *const img1,
const vpx_image_t *const img2, int yloc[4],
int uloc[4], int vloc[4]) {
const uint32_t bsize = 64;
const uint32_t bsizey = bsize >> img1->y_chroma_shift;
const uint32_t bsizex = bsize >> img1->x_chroma_shift;
const uint32_t c_w =
(img1->d_w + img1->x_chroma_shift) >> img1->x_chroma_shift;
const uint32_t c_h =
(img1->d_h + img1->y_chroma_shift) >> img1->y_chroma_shift;
int match = 1;
uint32_t i, j;
yloc[0] = yloc[1] = yloc[2] = yloc[3] = -1;
for (i = 0, match = 1; match && i < img1->d_h; i += bsize) {
for (j = 0; match && j < img1->d_w; j += bsize) {
int k, l;
const int si = mmin(i + bsize, img1->d_h) - i;
const int sj = mmin(j + bsize, img1->d_w) - j;
for (k = 0; match && k < si; ++k) {
for (l = 0; match && l < sj; ++l) {
if (*(img1->planes[VPX_PLANE_Y] +
(i + k) * img1->stride[VPX_PLANE_Y] + j + l) !=
*(img2->planes[VPX_PLANE_Y] +
(i + k) * img2->stride[VPX_PLANE_Y] + j + l)) {
yloc[0] = i + k;
yloc[1] = j + l;
yloc[2] = *(img1->planes[VPX_PLANE_Y] +
(i + k) * img1->stride[VPX_PLANE_Y] + j + l);
yloc[3] = *(img2->planes[VPX_PLANE_Y] +
(i + k) * img2->stride[VPX_PLANE_Y] + j + l);
match = 0;
break;
}
}
}
}
}
uloc[0] = uloc[1] = uloc[2] = uloc[3] = -1;
for (i = 0, match = 1; match && i < c_h; i += bsizey) {
for (j = 0; match && j < c_w; j += bsizex) {
int k, l;
const int si = mmin(i + bsizey, c_h - i);
const int sj = mmin(j + bsizex, c_w - j);
for (k = 0; match && k < si; ++k) {
for (l = 0; match && l < sj; ++l) {
if (*(img1->planes[VPX_PLANE_U] +
(i + k) * img1->stride[VPX_PLANE_U] + j + l) !=
*(img2->planes[VPX_PLANE_U] +
(i + k) * img2->stride[VPX_PLANE_U] + j + l)) {
uloc[0] = i + k;
uloc[1] = j + l;
uloc[2] = *(img1->planes[VPX_PLANE_U] +
(i + k) * img1->stride[VPX_PLANE_U] + j + l);
uloc[3] = *(img2->planes[VPX_PLANE_U] +
(i + k) * img2->stride[VPX_PLANE_U] + j + l);
match = 0;
break;
}
}
}
}
}
vloc[0] = vloc[1] = vloc[2] = vloc[3] = -1;
for (i = 0, match = 1; match && i < c_h; i += bsizey) {
for (j = 0; match && j < c_w; j += bsizex) {
int k, l;
const int si = mmin(i + bsizey, c_h - i);
const int sj = mmin(j + bsizex, c_w - j);
for (k = 0; match && k < si; ++k) {
for (l = 0; match && l < sj; ++l) {
if (*(img1->planes[VPX_PLANE_V] +
(i + k) * img1->stride[VPX_PLANE_V] + j + l) !=
*(img2->planes[VPX_PLANE_V] +
(i + k) * img2->stride[VPX_PLANE_V] + j + l)) {
vloc[0] = i + k;
vloc[1] = j + l;
vloc[2] = *(img1->planes[VPX_PLANE_V] +
(i + k) * img1->stride[VPX_PLANE_V] + j + l);
vloc[3] = *(img2->planes[VPX_PLANE_V] +
(i + k) * img2->stride[VPX_PLANE_V] + j + l);
match = 0;
break;
}
}
}
}
}
}
static void testing_decode(vpx_codec_ctx_t *encoder, vpx_codec_ctx_t *decoder,
vpx_codec_enc_cfg_t *cfg, unsigned int frame_out,
int *mismatch_seen) {
vpx_image_t enc_img, dec_img;
struct vp9_ref_frame ref_enc, ref_dec;
if (*mismatch_seen) return;
ref_enc.idx = 0;
ref_dec.idx = 0;
if (vpx_codec_control(encoder, VP9_GET_REFERENCE, &ref_enc))
die_codec(encoder, "Failed to get encoder reference frame");
enc_img = ref_enc.img;
if (vpx_codec_control(decoder, VP9_GET_REFERENCE, &ref_dec))
die_codec(decoder, "Failed to get decoder reference frame");
dec_img = ref_dec.img;
if (!compare_img(&enc_img, &dec_img)) {
int y[4], u[4], v[4];
*mismatch_seen = 1;
find_mismatch(&enc_img, &dec_img, y, u, v);
printf(
"Encode/decode mismatch on frame %d at"
" Y[%d, %d] {%d/%d},"
" U[%d, %d] {%d/%d},"
" V[%d, %d] {%d/%d}",
frame_out, y[0], y[1], y[2], y[3], u[0], u[1], u[2], u[3], v[0], v[1],
v[2], v[3]);
}
vpx_img_free(&enc_img);
vpx_img_free(&dec_img);
}
static int encode_frame(vpx_codec_ctx_t *ecodec, vpx_codec_enc_cfg_t *cfg,
vpx_image_t *img, unsigned int frame_in,
VpxVideoWriter *writer, int test_decode,
vpx_codec_ctx_t *dcodec, unsigned int *frame_out,
int *mismatch_seen) {
int got_pkts = 0;
vpx_codec_iter_t iter = NULL;
const vpx_codec_cx_pkt_t *pkt = NULL;
int got_data;
const vpx_codec_err_t res =
vpx_codec_encode(ecodec, img, frame_in, 1, 0, VPX_DL_GOOD_QUALITY);
if (res != VPX_CODEC_OK) die_codec(ecodec, "Failed to encode frame");
got_data = 0;
while ((pkt = vpx_codec_get_cx_data(ecodec, &iter)) != NULL) {
got_pkts = 1;
if (pkt->kind == VPX_CODEC_CX_FRAME_PKT) {
const int keyframe = (pkt->data.frame.flags & VPX_FRAME_IS_KEY) != 0;
if (!(pkt->data.frame.flags & VPX_FRAME_IS_FRAGMENT)) {
*frame_out += 1;
}
if (!vpx_video_writer_write_frame(writer, pkt->data.frame.buf,
pkt->data.frame.sz,
pkt->data.frame.pts)) {
die_codec(ecodec, "Failed to write compressed frame");
}
printf(keyframe ? "K" : ".");
fflush(stdout);
got_data = 1;
// Decode 1 frame.
if (test_decode) {
if (vpx_codec_decode(dcodec, pkt->data.frame.buf,
(unsigned int)pkt->data.frame.sz, NULL, 0))
die_codec(dcodec, "Failed to decode frame.");
}
}
}
// Mismatch checking
if (got_data && test_decode) {
testing_decode(ecodec, dcodec, cfg, *frame_out, mismatch_seen);
}
return got_pkts;
}
int main(int argc, char **argv) {
FILE *infile = NULL;
// Encoder
vpx_codec_ctx_t ecodec = { 0 };
vpx_codec_enc_cfg_t cfg = { 0 };
unsigned int frame_in = 0;
vpx_image_t raw;
vpx_codec_err_t res;
VpxVideoInfo info = { 0 };
VpxVideoWriter *writer = NULL;
const VpxInterface *encoder = NULL;
// Test encoder/decoder mismatch.
int test_decode = 1;
// Decoder
vpx_codec_ctx_t dcodec;
unsigned int frame_out = 0;
// The frame number to set reference frame on
unsigned int update_frame_num = 0;
int mismatch_seen = 0;
const int fps = 30;
const int bitrate = 500;
const char *width_arg = NULL;
const char *height_arg = NULL;
const char *infile_arg = NULL;
const char *outfile_arg = NULL;
unsigned int limit = 0;
exec_name = argv[0];
if (argc < 6) die("Invalid number of arguments");
width_arg = argv[1];
height_arg = argv[2];
infile_arg = argv[3];
outfile_arg = argv[4];
encoder = get_vpx_encoder_by_name("vp9");
if (!encoder) die("Unsupported codec.");
update_frame_num = atoi(argv[5]);
// In VP9, the reference buffers (cm->buffer_pool->frame_bufs[i].buf) are
// allocated while calling vpx_codec_encode(), thus, setting reference for
// 1st frame isn't supported.
if (update_frame_num <= 1) die("Couldn't parse frame number '%s'\n", argv[5]);
if (argc > 6) {
limit = atoi(argv[6]);
if (update_frame_num > limit)
die("Update frame number couldn't larger than limit\n");
}
info.codec_fourcc = encoder->fourcc;
info.frame_width = strtol(width_arg, NULL, 0);
info.frame_height = strtol(height_arg, NULL, 0);
info.time_base.numerator = 1;
info.time_base.denominator = fps;
if (info.frame_width <= 0 || info.frame_height <= 0 ||
(info.frame_width % 2) != 0 || (info.frame_height % 2) != 0) {
die("Invalid frame size: %dx%d", info.frame_width, info.frame_height);
}
if (!vpx_img_alloc(&raw, VPX_IMG_FMT_I420, info.frame_width,
info.frame_height, 1)) {
die("Failed to allocate image.");
}
printf("Using %s\n", vpx_codec_iface_name(encoder->codec_interface()));
res = vpx_codec_enc_config_default(encoder->codec_interface(), &cfg, 0);
if (res) die_codec(&ecodec, "Failed to get default codec config.");
cfg.g_w = info.frame_width;
cfg.g_h = info.frame_height;
cfg.g_timebase.num = info.time_base.numerator;
cfg.g_timebase.den = info.time_base.denominator;
cfg.rc_target_bitrate = bitrate;
cfg.g_lag_in_frames = 3;
writer = vpx_video_writer_open(outfile_arg, kContainerIVF, &info);
if (!writer) die("Failed to open %s for writing.", outfile_arg);
if (!(infile = fopen(infile_arg, "rb")))
die("Failed to open %s for reading.", infile_arg);
if (vpx_codec_enc_init(&ecodec, encoder->codec_interface(), &cfg, 0))
die_codec(&ecodec, "Failed to initialize encoder");
// Disable alt_ref.
if (vpx_codec_control(&ecodec, VP8E_SET_ENABLEAUTOALTREF, 0))
die_codec(&ecodec, "Failed to set enable auto alt ref");
if (test_decode) {
const VpxInterface *decoder = get_vpx_decoder_by_name("vp9");
if (vpx_codec_dec_init(&dcodec, decoder->codec_interface(), NULL, 0))
die_codec(&dcodec, "Failed to initialize decoder.");
}
// Encode frames.
while (vpx_img_read(&raw, infile)) {
if (limit && frame_in >= limit) break;
if (update_frame_num > 1 && frame_out + 1 == update_frame_num) {
vpx_ref_frame_t ref;
ref.frame_type = VP8_LAST_FRAME;
ref.img = raw;
// Set reference frame in encoder.
if (vpx_codec_control(&ecodec, VP8_SET_REFERENCE, &ref))
die_codec(&ecodec, "Failed to set reference frame");
printf(" <SET_REF>");
// If set_reference in decoder is commented out, the enc/dec mismatch
// would be seen.
if (test_decode) {
if (vpx_codec_control(&dcodec, VP8_SET_REFERENCE, &ref))
die_codec(&dcodec, "Failed to set reference frame");
}
}
encode_frame(&ecodec, &cfg, &raw, frame_in, writer, test_decode, &dcodec,
&frame_out, &mismatch_seen);
frame_in++;
if (mismatch_seen) break;
}
// Flush encoder.
if (!mismatch_seen)
while (encode_frame(&ecodec, &cfg, NULL, frame_in, writer, test_decode,
&dcodec, &frame_out, &mismatch_seen)) {
}
printf("\n");
fclose(infile);
printf("Processed %d frames.\n", frame_out);
if (test_decode) {
if (!mismatch_seen)
printf("Encoder/decoder results are matching.\n");
else
printf("Encoder/decoder results are NOT matching.\n");
}
if (test_decode)
if (vpx_codec_destroy(&dcodec))
die_codec(&dcodec, "Failed to destroy decoder");
vpx_img_free(&raw);
if (vpx_codec_destroy(&ecodec))
die_codec(&ecodec, "Failed to destroy encoder.");
vpx_video_writer_close(writer);
return EXIT_SUCCESS;
}

View File

@@ -28,7 +28,9 @@
static const char *exec_name;
void usage_exit(void) { exit(EXIT_FAILURE); }
void usage_exit(void) {
exit(EXIT_FAILURE);
}
// Denoiser states, for temporal denoising.
enum denoiserState {
@@ -39,7 +41,7 @@ enum denoiserState {
kDenoiserOnAdaptive
};
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[12] = {1, 2, 2, 3, 3, 3, 3, 5, 2, 3, 3, 3};
// For rate control encoding stats.
struct RateControlMetrics {
@@ -84,13 +86,13 @@ static void set_rate_control_metrics(struct RateControlMetrics *rc,
// per-frame-bandwidth, for the rate control encoding stats below.
const double framerate = cfg->g_timebase.den / cfg->g_timebase.num;
rc->layer_framerate[0] = framerate / cfg->ts_rate_decimator[0];
rc->layer_pfb[0] =
1000.0 * rc->layer_target_bitrate[0] / rc->layer_framerate[0];
rc->layer_pfb[0] = 1000.0 * rc->layer_target_bitrate[0] /
rc->layer_framerate[0];
for (i = 0; i < cfg->ts_number_layers; ++i) {
if (i > 0) {
rc->layer_framerate[i] = framerate / cfg->ts_rate_decimator[i];
rc->layer_pfb[i] = 1000.0 * (rc->layer_target_bitrate[i] -
rc->layer_target_bitrate[i - 1]) /
rc->layer_pfb[i] = 1000.0 *
(rc->layer_target_bitrate[i] - rc->layer_target_bitrate[i - 1]) /
(rc->layer_framerate[i] - rc->layer_framerate[i - 1]);
}
rc->layer_input_frames[i] = 0;
@@ -116,27 +118,25 @@ static void printout_rate_control_summary(struct RateControlMetrics *rc,
printf("Rate control layer stats for %d layer(s):\n\n",
cfg->ts_number_layers);
for (i = 0; i < cfg->ts_number_layers; ++i) {
const int num_dropped =
(i > 0) ? (rc->layer_input_frames[i] - rc->layer_enc_frames[i])
: (rc->layer_input_frames[i] - rc->layer_enc_frames[i] - 1);
const int num_dropped = (i > 0) ?
(rc->layer_input_frames[i] - rc->layer_enc_frames[i]) :
(rc->layer_input_frames[i] - rc->layer_enc_frames[i] - 1);
tot_num_frames += rc->layer_input_frames[i];
rc->layer_encoding_bitrate[i] = 0.001 * rc->layer_framerate[i] *
rc->layer_encoding_bitrate[i] /
tot_num_frames;
rc->layer_avg_frame_size[i] =
rc->layer_avg_frame_size[i] / rc->layer_enc_frames[i];
rc->layer_avg_rate_mismatch[i] =
100.0 * rc->layer_avg_rate_mismatch[i] / rc->layer_enc_frames[i];
rc->layer_encoding_bitrate[i] / tot_num_frames;
rc->layer_avg_frame_size[i] = rc->layer_avg_frame_size[i] /
rc->layer_enc_frames[i];
rc->layer_avg_rate_mismatch[i] = 100.0 * rc->layer_avg_rate_mismatch[i] /
rc->layer_enc_frames[i];
printf("For layer#: %d \n", i);
printf("Bitrate (target vs actual): %d %f \n", rc->layer_target_bitrate[i],
rc->layer_encoding_bitrate[i]);
printf("Average frame size (target vs actual): %f %f \n", rc->layer_pfb[i],
rc->layer_avg_frame_size[i]);
printf("Average rate_mismatch: %f \n", rc->layer_avg_rate_mismatch[i]);
printf(
"Number of input frames, encoded (non-key) frames, "
"and perc dropped frames: %d %d %f \n",
rc->layer_input_frames[i], rc->layer_enc_frames[i],
printf("Number of input frames, encoded (non-key) frames, "
"and perc dropped frames: %d %d %f \n", rc->layer_input_frames[i],
rc->layer_enc_frames[i],
100.0 * num_dropped / rc->layer_input_frames[i]);
printf("\n");
}
@@ -148,7 +148,8 @@ static void printout_rate_control_summary(struct RateControlMetrics *rc,
rc->avg_st_encoding_bitrate;
printf("Short-time stats, for window of %d frames: \n",rc->window_size);
printf("Average, rms-variance, and percent-fluct: %f %f %f \n",
rc->avg_st_encoding_bitrate, sqrt(rc->variance_st_encoding_bitrate),
rc->avg_st_encoding_bitrate,
sqrt(rc->variance_st_encoding_bitrate),
perc_fluctuation);
if ((frame_cnt - 1) != tot_num_frames)
die("Error: Number of input frames not equal to output! \n");
@@ -173,8 +174,8 @@ static void set_temporal_layer_pattern(int layering_mode,
cfg->ts_rate_decimator[0] = 1;
memcpy(cfg->ts_layer_id, ids, sizeof(ids));
// Update L only.
layer_flags[0] =
VPX_EFLAG_FORCE_KF | VP8_EFLAG_NO_UPD_GF | VP8_EFLAG_NO_UPD_ARF;
layer_flags[0] = VPX_EFLAG_FORCE_KF | VP8_EFLAG_NO_UPD_GF |
VP8_EFLAG_NO_UPD_ARF;
break;
}
case 1: {
@@ -189,15 +190,13 @@ static void set_temporal_layer_pattern(int layering_mode,
#if 1
// 0=L, 1=GF, Intra-layer prediction enabled.
layer_flags[0] = VPX_EFLAG_FORCE_KF | VP8_EFLAG_NO_UPD_GF |
VP8_EFLAG_NO_UPD_ARF | VP8_EFLAG_NO_REF_GF |
VP8_EFLAG_NO_UPD_ARF | VP8_EFLAG_NO_REF_GF | VP8_EFLAG_NO_REF_ARF;
layer_flags[1] = VP8_EFLAG_NO_UPD_ARF | VP8_EFLAG_NO_UPD_LAST |
VP8_EFLAG_NO_REF_ARF;
layer_flags[1] =
VP8_EFLAG_NO_UPD_ARF | VP8_EFLAG_NO_UPD_LAST | VP8_EFLAG_NO_REF_ARF;
#else
// 0=L, 1=GF, Intra-layer prediction disabled.
layer_flags[0] = VPX_EFLAG_FORCE_KF | VP8_EFLAG_NO_UPD_GF |
VP8_EFLAG_NO_UPD_ARF | VP8_EFLAG_NO_REF_GF |
VP8_EFLAG_NO_REF_ARF;
VP8_EFLAG_NO_UPD_ARF | VP8_EFLAG_NO_REF_GF | VP8_EFLAG_NO_REF_ARF;
layer_flags[1] = VP8_EFLAG_NO_UPD_ARF | VP8_EFLAG_NO_UPD_LAST |
VP8_EFLAG_NO_REF_ARF | VP8_EFLAG_NO_REF_LAST;
#endif
@@ -214,11 +213,10 @@ static void set_temporal_layer_pattern(int layering_mode,
memcpy(cfg->ts_layer_id, ids, sizeof(ids));
// 0=L, 1=GF, Intra-layer prediction enabled.
layer_flags[0] = VPX_EFLAG_FORCE_KF | VP8_EFLAG_NO_REF_GF |
VP8_EFLAG_NO_REF_ARF | VP8_EFLAG_NO_UPD_GF |
VP8_EFLAG_NO_UPD_ARF;
layer_flags[1] = layer_flags[2] =
VP8_EFLAG_NO_REF_GF | VP8_EFLAG_NO_REF_ARF | VP8_EFLAG_NO_UPD_ARF |
VP8_EFLAG_NO_UPD_LAST;
VP8_EFLAG_NO_REF_ARF | VP8_EFLAG_NO_UPD_GF | VP8_EFLAG_NO_UPD_ARF;
layer_flags[1] =
layer_flags[2] = VP8_EFLAG_NO_REF_GF | VP8_EFLAG_NO_REF_ARF |
VP8_EFLAG_NO_UPD_ARF | VP8_EFLAG_NO_UPD_LAST;
break;
}
case 3: {
@@ -233,12 +231,13 @@ static void set_temporal_layer_pattern(int layering_mode,
memcpy(cfg->ts_layer_id, ids, sizeof(ids));
// 0=L, 1=GF, 2=ARF, Intra-layer prediction enabled.
layer_flags[0] = VPX_EFLAG_FORCE_KF | VP8_EFLAG_NO_REF_GF |
VP8_EFLAG_NO_REF_ARF | VP8_EFLAG_NO_UPD_GF |
VP8_EFLAG_NO_UPD_ARF;
layer_flags[3] =
VP8_EFLAG_NO_REF_ARF | VP8_EFLAG_NO_UPD_ARF | VP8_EFLAG_NO_UPD_LAST;
layer_flags[1] = layer_flags[2] = layer_flags[4] = layer_flags[5] =
VP8_EFLAG_NO_UPD_GF | VP8_EFLAG_NO_UPD_LAST;
VP8_EFLAG_NO_REF_ARF | VP8_EFLAG_NO_UPD_GF | VP8_EFLAG_NO_UPD_ARF;
layer_flags[3] = VP8_EFLAG_NO_REF_ARF | VP8_EFLAG_NO_UPD_ARF |
VP8_EFLAG_NO_UPD_LAST;
layer_flags[1] =
layer_flags[2] =
layer_flags[4] =
layer_flags[5] = VP8_EFLAG_NO_UPD_GF | VP8_EFLAG_NO_UPD_LAST;
break;
}
case 4: {
@@ -253,13 +252,12 @@ static void set_temporal_layer_pattern(int layering_mode,
memcpy(cfg->ts_layer_id, ids, sizeof(ids));
// 0=L, 1=GF, 2=ARF, Intra-layer prediction disabled.
layer_flags[0] = VPX_EFLAG_FORCE_KF | VP8_EFLAG_NO_REF_GF |
VP8_EFLAG_NO_REF_ARF | VP8_EFLAG_NO_UPD_GF |
VP8_EFLAG_NO_UPD_ARF;
VP8_EFLAG_NO_REF_ARF | VP8_EFLAG_NO_UPD_GF | VP8_EFLAG_NO_UPD_ARF;
layer_flags[2] = VP8_EFLAG_NO_REF_GF | VP8_EFLAG_NO_REF_ARF |
VP8_EFLAG_NO_UPD_ARF | VP8_EFLAG_NO_UPD_LAST;
layer_flags[1] = layer_flags[3] =
VP8_EFLAG_NO_REF_ARF | VP8_EFLAG_NO_UPD_LAST | VP8_EFLAG_NO_UPD_GF |
VP8_EFLAG_NO_UPD_ARF;
layer_flags[1] =
layer_flags[3] = VP8_EFLAG_NO_REF_ARF | VP8_EFLAG_NO_UPD_LAST |
VP8_EFLAG_NO_UPD_GF | VP8_EFLAG_NO_UPD_ARF;
break;
}
case 5: {
@@ -275,13 +273,12 @@ static void set_temporal_layer_pattern(int layering_mode,
// 0=L, 1=GF, 2=ARF, Intra-layer prediction enabled in layer 1, disabled
// in layer 2.
layer_flags[0] = VPX_EFLAG_FORCE_KF | VP8_EFLAG_NO_REF_GF |
VP8_EFLAG_NO_REF_ARF | VP8_EFLAG_NO_UPD_GF |
VP8_EFLAG_NO_UPD_ARF;
layer_flags[2] =
VP8_EFLAG_NO_REF_ARF | VP8_EFLAG_NO_UPD_LAST | VP8_EFLAG_NO_UPD_ARF;
layer_flags[1] = layer_flags[3] =
VP8_EFLAG_NO_REF_ARF | VP8_EFLAG_NO_UPD_LAST | VP8_EFLAG_NO_UPD_GF |
VP8_EFLAG_NO_REF_ARF | VP8_EFLAG_NO_UPD_GF | VP8_EFLAG_NO_UPD_ARF;
layer_flags[2] = VP8_EFLAG_NO_REF_ARF | VP8_EFLAG_NO_UPD_LAST |
VP8_EFLAG_NO_UPD_ARF;
layer_flags[1] =
layer_flags[3] = VP8_EFLAG_NO_REF_ARF | VP8_EFLAG_NO_UPD_LAST |
VP8_EFLAG_NO_UPD_GF | VP8_EFLAG_NO_UPD_ARF;
break;
}
case 6: {
@@ -296,12 +293,11 @@ static void set_temporal_layer_pattern(int layering_mode,
memcpy(cfg->ts_layer_id, ids, sizeof(ids));
// 0=L, 1=GF, 2=ARF, Intra-layer prediction enabled.
layer_flags[0] = VPX_EFLAG_FORCE_KF | VP8_EFLAG_NO_REF_GF |
VP8_EFLAG_NO_REF_ARF | VP8_EFLAG_NO_UPD_GF |
VP8_EFLAG_NO_REF_ARF | VP8_EFLAG_NO_UPD_GF | VP8_EFLAG_NO_UPD_ARF;
layer_flags[2] = VP8_EFLAG_NO_REF_ARF | VP8_EFLAG_NO_UPD_LAST |
VP8_EFLAG_NO_UPD_ARF;
layer_flags[2] =
VP8_EFLAG_NO_REF_ARF | VP8_EFLAG_NO_UPD_LAST | VP8_EFLAG_NO_UPD_ARF;
layer_flags[1] = layer_flags[3] =
VP8_EFLAG_NO_UPD_LAST | VP8_EFLAG_NO_UPD_GF;
layer_flags[1] =
layer_flags[3] = VP8_EFLAG_NO_UPD_LAST | VP8_EFLAG_NO_UPD_GF;
break;
}
case 7: {
@@ -318,14 +314,21 @@ static void set_temporal_layer_pattern(int layering_mode,
cfg->ts_rate_decimator[4] = 1;
memcpy(cfg->ts_layer_id, ids, sizeof(ids));
layer_flags[0] = VPX_EFLAG_FORCE_KF;
layer_flags[1] = layer_flags[3] = layer_flags[5] = layer_flags[7] =
layer_flags[9] = layer_flags[11] = layer_flags[13] = layer_flags[15] =
VP8_EFLAG_NO_UPD_LAST | VP8_EFLAG_NO_UPD_GF |
layer_flags[1] =
layer_flags[3] =
layer_flags[5] =
layer_flags[7] =
layer_flags[9] =
layer_flags[11] =
layer_flags[13] =
layer_flags[15] = VP8_EFLAG_NO_UPD_LAST | VP8_EFLAG_NO_UPD_GF |
VP8_EFLAG_NO_UPD_ARF;
layer_flags[2] = layer_flags[6] = layer_flags[10] = layer_flags[14] =
VP8_EFLAG_NO_UPD_ARF | VP8_EFLAG_NO_UPD_GF;
layer_flags[4] = layer_flags[12] =
VP8_EFLAG_NO_REF_LAST | VP8_EFLAG_NO_UPD_ARF;
layer_flags[2] =
layer_flags[6] =
layer_flags[10] =
layer_flags[14] = VP8_EFLAG_NO_UPD_ARF | VP8_EFLAG_NO_UPD_GF;
layer_flags[4] =
layer_flags[12] = VP8_EFLAG_NO_REF_LAST | VP8_EFLAG_NO_UPD_ARF;
layer_flags[8] = VP8_EFLAG_NO_REF_LAST | VP8_EFLAG_NO_REF_GF;
break;
}
@@ -343,14 +346,14 @@ static void set_temporal_layer_pattern(int layering_mode,
// key frame. Sync point every 8 frames.
// Layer 0: predict from L and ARF, update L and G.
layer_flags[0] =
VPX_EFLAG_FORCE_KF | VP8_EFLAG_NO_REF_GF | VP8_EFLAG_NO_UPD_ARF;
layer_flags[0] = VPX_EFLAG_FORCE_KF | VP8_EFLAG_NO_REF_GF |
VP8_EFLAG_NO_UPD_ARF;
// Layer 1: sync point: predict from L and ARF, and update G.
layer_flags[1] =
VP8_EFLAG_NO_REF_GF | VP8_EFLAG_NO_UPD_LAST | VP8_EFLAG_NO_UPD_ARF;
layer_flags[1] = VP8_EFLAG_NO_REF_GF | VP8_EFLAG_NO_UPD_LAST |
VP8_EFLAG_NO_UPD_ARF;
// Layer 0, predict from L and ARF, update L.
layer_flags[2] =
VP8_EFLAG_NO_REF_GF | VP8_EFLAG_NO_UPD_GF | VP8_EFLAG_NO_UPD_ARF;
layer_flags[2] = VP8_EFLAG_NO_REF_GF | VP8_EFLAG_NO_UPD_GF |
VP8_EFLAG_NO_UPD_ARF;
// Layer 1: predict from L, G and ARF, and update G.
layer_flags[3] = VP8_EFLAG_NO_UPD_ARF | VP8_EFLAG_NO_UPD_LAST |
VP8_EFLAG_NO_UPD_ENTROPY;
@@ -376,18 +379,17 @@ static void set_temporal_layer_pattern(int layering_mode,
memcpy(cfg->ts_layer_id, ids, sizeof(ids));
// 0=L, 1=GF, 2=ARF.
layer_flags[0] = VPX_EFLAG_FORCE_KF | VP8_EFLAG_NO_REF_GF |
VP8_EFLAG_NO_REF_ARF | VP8_EFLAG_NO_UPD_GF |
VP8_EFLAG_NO_UPD_ARF;
VP8_EFLAG_NO_REF_ARF | VP8_EFLAG_NO_UPD_GF | VP8_EFLAG_NO_UPD_ARF;
layer_flags[1] = VP8_EFLAG_NO_REF_GF | VP8_EFLAG_NO_REF_ARF |
VP8_EFLAG_NO_UPD_LAST | VP8_EFLAG_NO_UPD_GF;
layer_flags[2] = VP8_EFLAG_NO_REF_GF | VP8_EFLAG_NO_REF_ARF |
VP8_EFLAG_NO_UPD_LAST | VP8_EFLAG_NO_UPD_ARF;
layer_flags[3] = layer_flags[5] =
VP8_EFLAG_NO_UPD_LAST | VP8_EFLAG_NO_UPD_GF;
layer_flags[3] =
layer_flags[5] = VP8_EFLAG_NO_UPD_LAST | VP8_EFLAG_NO_UPD_GF;
layer_flags[4] = VP8_EFLAG_NO_REF_GF | VP8_EFLAG_NO_REF_ARF |
VP8_EFLAG_NO_UPD_GF | VP8_EFLAG_NO_UPD_ARF;
layer_flags[6] =
VP8_EFLAG_NO_REF_ARF | VP8_EFLAG_NO_UPD_LAST | VP8_EFLAG_NO_UPD_ARF;
layer_flags[6] = VP8_EFLAG_NO_REF_ARF | VP8_EFLAG_NO_UPD_LAST |
VP8_EFLAG_NO_UPD_ARF;
layer_flags[7] = VP8_EFLAG_NO_UPD_LAST | VP8_EFLAG_NO_UPD_GF |
VP8_EFLAG_NO_UPD_ARF | VP8_EFLAG_NO_UPD_ENTROPY;
break;
@@ -407,21 +409,21 @@ static void set_temporal_layer_pattern(int layering_mode,
memcpy(cfg->ts_layer_id, ids, sizeof(ids));
// 0=L, 1=GF, 2=ARF.
// Layer 0: predict from L and ARF; update L and G.
layer_flags[0] =
VPX_EFLAG_FORCE_KF | VP8_EFLAG_NO_UPD_ARF | VP8_EFLAG_NO_REF_GF;
layer_flags[0] = VPX_EFLAG_FORCE_KF | VP8_EFLAG_NO_UPD_ARF |
VP8_EFLAG_NO_REF_GF;
// Layer 2: sync point: predict from L and ARF; update none.
layer_flags[1] = VP8_EFLAG_NO_REF_GF | VP8_EFLAG_NO_UPD_GF |
VP8_EFLAG_NO_UPD_ARF | VP8_EFLAG_NO_UPD_LAST |
VP8_EFLAG_NO_UPD_ENTROPY;
// Layer 1: sync point: predict from L and ARF; update G.
layer_flags[2] =
VP8_EFLAG_NO_REF_GF | VP8_EFLAG_NO_UPD_ARF | VP8_EFLAG_NO_UPD_LAST;
layer_flags[2] = VP8_EFLAG_NO_REF_GF | VP8_EFLAG_NO_UPD_ARF |
VP8_EFLAG_NO_UPD_LAST;
// Layer 2: predict from L, G, ARF; update none.
layer_flags[3] = VP8_EFLAG_NO_UPD_GF | VP8_EFLAG_NO_UPD_ARF |
VP8_EFLAG_NO_UPD_LAST | VP8_EFLAG_NO_UPD_ENTROPY;
// Layer 0: predict from L and ARF; update L.
layer_flags[4] =
VP8_EFLAG_NO_UPD_GF | VP8_EFLAG_NO_UPD_ARF | VP8_EFLAG_NO_REF_GF;
layer_flags[4] = VP8_EFLAG_NO_UPD_GF | VP8_EFLAG_NO_UPD_ARF |
VP8_EFLAG_NO_REF_GF;
// Layer 2: predict from L, G, ARF; update none.
layer_flags[5] = layer_flags[3];
// Layer 1: predict from L, G, ARF; update G.
@@ -430,32 +432,7 @@ static void set_temporal_layer_pattern(int layering_mode,
layer_flags[7] = layer_flags[3];
break;
}
case 11: {
// 3-layers structure with one reference frame.
// This works same as temporal_layering_mode 3.
// This was added to compare with vp9_spatial_svc_encoder.
// 3-layers, 4-frame period.
int ids[4] = { 0, 2, 1, 2 };
cfg->ts_periodicity = 4;
*flag_periodicity = 4;
cfg->ts_number_layers = 3;
cfg->ts_rate_decimator[0] = 4;
cfg->ts_rate_decimator[1] = 2;
cfg->ts_rate_decimator[2] = 1;
memcpy(cfg->ts_layer_id, ids, sizeof(ids));
// 0=L, 1=GF, 2=ARF, Intra-layer prediction disabled.
layer_flags[0] = VP8_EFLAG_NO_REF_GF | VP8_EFLAG_NO_REF_ARF |
VP8_EFLAG_NO_UPD_GF | VP8_EFLAG_NO_UPD_ARF;
layer_flags[2] = VP8_EFLAG_NO_REF_GF | VP8_EFLAG_NO_REF_ARF |
VP8_EFLAG_NO_UPD_ARF | VP8_EFLAG_NO_UPD_LAST;
layer_flags[1] = VP8_EFLAG_NO_REF_GF | VP8_EFLAG_NO_REF_ARF |
VP8_EFLAG_NO_UPD_LAST | VP8_EFLAG_NO_UPD_GF;
layer_flags[3] = VP8_EFLAG_NO_REF_LAST | VP8_EFLAG_NO_REF_ARF |
VP8_EFLAG_NO_UPD_LAST | VP8_EFLAG_NO_UPD_GF;
break;
}
case 12:
case 11:
default: {
// 3-layers structure as in case 10, but no sync/refresh points for
// layer 1 and 2.
@@ -469,8 +446,8 @@ static void set_temporal_layer_pattern(int layering_mode,
memcpy(cfg->ts_layer_id, ids, sizeof(ids));
// 0=L, 1=GF, 2=ARF.
// Layer 0: predict from L and ARF; update L.
layer_flags[0] =
VP8_EFLAG_NO_UPD_GF | VP8_EFLAG_NO_UPD_ARF | VP8_EFLAG_NO_REF_GF;
layer_flags[0] = VP8_EFLAG_NO_UPD_GF | VP8_EFLAG_NO_UPD_ARF |
VP8_EFLAG_NO_REF_GF;
layer_flags[4] = layer_flags[0];
// Layer 1: predict from L, G, ARF; update G.
layer_flags[2] = VP8_EFLAG_NO_UPD_ARF | VP8_EFLAG_NO_UPD_LAST;
@@ -530,22 +507,19 @@ int main(int argc, char **argv) {
// Check usage and arguments.
if (argc < min_args) {
#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_0> ... <Rate_nlayers-1> <bit-depth> \n",
argv[0]);
"<Rate_0> ... <Rate_nlayers-1> <bit-depth> \n", argv[0]);
#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_0> ... <Rate_nlayers-1> \n",
argv[0]);
"<Rate_0> ... <Rate_nlayers-1> \n", argv[0]);
#endif // CONFIG_VP9_HIGHBITDEPTH
}
encoder = get_vpx_encoder_by_name(argv[3]);
if (!encoder) die("Unsupported codec.");
if (!encoder)
die("Unsupported codec.");
printf("Using %s\n", vpx_codec_iface_name(encoder->codec_interface()));
@@ -556,7 +530,7 @@ int main(int argc, char **argv) {
}
layering_mode = strtol(argv[10], NULL, 0);
if (layering_mode < 0 || layering_mode > 13) {
if (layering_mode < 0 || layering_mode > 12) {
die("Invalid layering mode (0..12) %s", argv[10]);
}
@@ -578,10 +552,12 @@ int main(int argc, char **argv) {
bit_depth = VPX_BITS_12;
input_bit_depth = 12;
break;
default: die("Invalid bit depth (8, 10, 12) %s", argv[argc - 1]);
default:
die("Invalid bit depth (8, 10, 12) %s", argv[argc-1]);
}
if (!vpx_img_alloc(
&raw, bit_depth == VPX_BITS_8 ? VPX_IMG_FMT_I420 : VPX_IMG_FMT_I42016,
if (!vpx_img_alloc(&raw,
bit_depth == VPX_BITS_8 ? VPX_IMG_FMT_I420 :
VPX_IMG_FMT_I42016,
width, height, 32)) {
die("Failed to allocate image", width, height);
}
@@ -620,7 +596,8 @@ int main(int argc, char **argv) {
}
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] = strtol(argv[i], NULL, 0);
if (strncmp(encoder->name, "vp8", 3) == 0)
cfg.ts_target_bitrate[i - 11] = rc.layer_target_bitrate[i - 11];
@@ -633,7 +610,8 @@ int main(int argc, char **argv) {
cfg.rc_end_usage = VPX_CBR;
cfg.rc_min_quantizer = 2;
cfg.rc_max_quantizer = 56;
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_overshoot_pct = 50;
cfg.rc_buf_initial_sz = 500;
@@ -656,7 +634,9 @@ int main(int argc, char **argv) {
cfg.temporal_layering_mode = VP9E_TEMPORAL_LAYERING_MODE_BYPASS;
set_temporal_layer_pattern(layering_mode, &cfg, layer_flags,
set_temporal_layer_pattern(layering_mode,
&cfg,
layer_flags,
&flag_periodicity);
set_rate_control_metrics(&rc, &cfg);
@@ -683,7 +663,8 @@ int main(int argc, char **argv) {
snprintf(file_name, sizeof(file_name), "%s_%d.ivf", argv[2], i);
outfile[i] = vpx_video_writer_open(file_name, kContainerIVF, &info);
if (!outfile[i]) die("Failed to open %s for writing", file_name);
if (!outfile[i])
die("Failed to open %s for writing", file_name);
assert(outfile[i] != NULL);
}
@@ -703,15 +684,14 @@ int main(int argc, char **argv) {
if (strncmp(encoder->name, "vp8", 3) == 0) {
vpx_codec_control(&codec, VP8E_SET_CPUUSED, -speed);
vpx_codec_control(&codec, VP8E_SET_NOISE_SENSITIVITY, kDenoiserOff);
vpx_codec_control(&codec, VP8E_SET_STATIC_THRESHOLD, 1);
vpx_codec_control(&codec, VP8E_SET_STATIC_THRESHOLD, 0);
} else if (strncmp(encoder->name, "vp9", 3) == 0) {
vpx_svc_extra_cfg_t svc_params;
memset(&svc_params, 0, sizeof(svc_params));
vpx_codec_control(&codec, VP8E_SET_CPUUSED, speed);
vpx_codec_control(&codec, VP9E_SET_AQ_MODE, 3);
vpx_codec_control(&codec, VP9E_SET_FRAME_PERIODIC_BOOST, 0);
vpx_codec_control(&codec, VP9E_SET_NOISE_SENSITIVITY, kDenoiserOff);
vpx_codec_control(&codec, VP8E_SET_STATIC_THRESHOLD, 1);
vpx_codec_control(&codec, VP9E_SET_NOISE_SENSITIVITY, 0);
vpx_codec_control(&codec, VP8E_SET_STATIC_THRESHOLD, 0);
vpx_codec_control(&codec, VP9E_SET_TUNE_CONTENT, 0);
vpx_codec_control(&codec, VP9E_SET_TILE_COLUMNS, (cfg.g_threads >> 1));
if (vpx_codec_control(&codec, VP9E_SET_SVC, layering_mode > 0 ? 1: 0))
@@ -755,9 +735,11 @@ int main(int argc, char **argv) {
layer_id.temporal_layer_id);
}
flags = layer_flags[frame_cnt % flag_periodicity];
if (layering_mode == 0) flags = 0;
if (layering_mode == 0)
flags = 0;
frame_avail = vpx_img_read(&raw, infile);
if (frame_avail) ++rc.layer_input_frames[layer_id.temporal_layer_id];
if (frame_avail)
++rc.layer_input_frames[layer_id.temporal_layer_id];
vpx_usec_timer_start(&timer);
if (vpx_codec_encode(&codec, frame_avail? &raw : NULL, pts, 1, flags,
VPX_DL_REALTIME)) {
@@ -818,7 +800,8 @@ int main(int argc, char **argv) {
}
}
break;
default: break;
default:
break;
}
}
++frame_cnt;
@@ -828,13 +811,16 @@ int main(int argc, char **argv) {
printout_rate_control_summary(&rc, &cfg, frame_cnt);
printf("\n");
printf("Frame cnt and encoding time/FPS stats for encoding: %d %f %f \n",
frame_cnt, 1000 * (float)cx_time / (double)(frame_cnt * 1000000),
frame_cnt,
1000 * (float)cx_time / (double)(frame_cnt * 1000000),
1000000 * (double)frame_cnt / (double)cx_time);
if (vpx_codec_destroy(&codec)) die_codec(&codec, "Failed to destroy codec");
if (vpx_codec_destroy(&codec))
die_codec(&codec, "Failed to destroy codec");
// Try to rewrite the output file headers with the actual frame count.
for (i = 0; i < cfg.ts_number_layers; ++i) vpx_video_writer_close(outfile[i]);
for (i = 0; i < cfg.ts_number_layers; ++i)
vpx_video_writer_close(outfile[i]);
vpx_img_free(&raw);
return EXIT_SUCCESS;

View File

@@ -23,7 +23,7 @@ static void fix_framerate(int *num, int *den) {
// we can guess the framerate using only the timebase in this
// case. Other files would require reading ahead to guess the
// timebase, like we do for webm.
if (*den > 0 && *den < 1000000000 && *num > 0 && *num < 1000) {
if (*num < 1000) {
// Correct for the factor of 2 applied to the timebase in the encoder.
if (*num & 1)
*den *= 2;
@@ -46,8 +46,7 @@ int file_is_ivf(struct VpxInputContext *input_ctx) {
is_ivf = 1;
if (mem_get_le16(raw_hdr + 4) != 0) {
fprintf(stderr,
"Error: Unrecognized IVF version! This file may not"
fprintf(stderr, "Error: Unrecognized IVF version! This file may not"
" decode properly.");
}
@@ -70,13 +69,14 @@ int file_is_ivf(struct VpxInputContext *input_ctx) {
return is_ivf;
}
int ivf_read_frame(FILE *infile, uint8_t **buffer, size_t *bytes_read,
size_t *buffer_size) {
int ivf_read_frame(FILE *infile, uint8_t **buffer,
size_t *bytes_read, size_t *buffer_size) {
char raw_header[IVF_FRAME_HDR_SZ] = {0};
size_t frame_size = 0;
if (fread(raw_header, IVF_FRAME_HDR_SZ, 1, infile) != 1) {
if (!feof(infile)) warn("Failed to read frame size\n");
if (!feof(infile))
warn("Failed to read frame size\n");
} else {
frame_size = mem_get_le32(raw_header);

View File

@@ -18,8 +18,8 @@ extern "C" {
int file_is_ivf(struct VpxInputContext *input);
int ivf_read_frame(FILE *infile, uint8_t **buffer, size_t *bytes_read,
size_t *buffer_size);
int ivf_read_frame(FILE *infile, uint8_t **buffer,
size_t *bytes_read, size_t *buffer_size);
#ifdef __cplusplus
} /* extern "C" */

View File

@@ -13,8 +13,10 @@
#include "vpx/vpx_encoder.h"
#include "vpx_ports/mem_ops.h"
void ivf_write_file_header(FILE *outfile, const struct vpx_codec_enc_cfg *cfg,
unsigned int fourcc, int frame_cnt) {
void ivf_write_file_header(FILE *outfile,
const struct vpx_codec_enc_cfg *cfg,
unsigned int fourcc,
int frame_cnt) {
char header[32];
header[0] = 'D';

View File

@@ -19,8 +19,10 @@ struct vpx_codec_cx_pkt;
extern "C" {
#endif
void ivf_write_file_header(FILE *outfile, const struct vpx_codec_enc_cfg *cfg,
uint32_t fourcc, int frame_cnt);
void ivf_write_file_header(FILE *outfile,
const struct vpx_codec_enc_cfg *cfg,
uint32_t fourcc,
int frame_cnt);
void ivf_write_frame_header(FILE *outfile, int64_t pts, size_t frame_size);

55
libs.mk
View File

@@ -109,6 +109,40 @@ endif
VP9_PREFIX=vp9/
$(BUILD_PFX)$(VP9_PREFIX)%.c.o: CFLAGS += -Wextra
# VP10 make file
ifeq ($(CONFIG_VP10),yes)
VP10_PREFIX=vp10/
include $(SRC_PATH_BARE)/$(VP10_PREFIX)vp10_common.mk
endif
ifeq ($(CONFIG_VP10_ENCODER),yes)
VP10_PREFIX=vp10/
include $(SRC_PATH_BARE)/$(VP10_PREFIX)vp10cx.mk
CODEC_SRCS-yes += $(addprefix $(VP10_PREFIX),$(call enabled,VP10_CX_SRCS))
CODEC_EXPORTS-yes += $(addprefix $(VP10_PREFIX),$(VP10_CX_EXPORTS))
CODEC_SRCS-yes += $(VP10_PREFIX)vp10cx.mk vpx/vp8.h vpx/vp8cx.h
INSTALL-LIBS-yes += include/vpx/vp8.h include/vpx/vp8cx.h
INSTALL-LIBS-$(CONFIG_SPATIAL_SVC) += include/vpx/svc_context.h
INSTALL_MAPS += include/vpx/% $(SRC_PATH_BARE)/$(VP10_PREFIX)/%
CODEC_DOC_SRCS += vpx/vp8.h vpx/vp8cx.h
CODEC_DOC_SECTIONS += vp9 vp9_encoder
endif
ifeq ($(CONFIG_VP10_DECODER),yes)
VP10_PREFIX=vp10/
include $(SRC_PATH_BARE)/$(VP10_PREFIX)vp10dx.mk
CODEC_SRCS-yes += $(addprefix $(VP10_PREFIX),$(call enabled,VP10_DX_SRCS))
CODEC_EXPORTS-yes += $(addprefix $(VP10_PREFIX),$(VP10_DX_EXPORTS))
CODEC_SRCS-yes += $(VP10_PREFIX)vp10dx.mk vpx/vp8.h vpx/vp8dx.h
INSTALL-LIBS-yes += include/vpx/vp8.h include/vpx/vp8dx.h
INSTALL_MAPS += include/vpx/% $(SRC_PATH_BARE)/$(VP10_PREFIX)/%
CODEC_DOC_SRCS += vpx/vp8.h vpx/vp8dx.h
CODEC_DOC_SECTIONS += vp9 vp9_decoder
endif
VP10_PREFIX=vp10/
$(BUILD_PFX)$(VP10_PREFIX)%.c.o: CFLAGS += -Wextra
ifeq ($(CONFIG_ENCODERS),yes)
CODEC_DOC_SECTIONS += encoder
endif
@@ -149,9 +183,6 @@ INSTALL-SRCS-$(CONFIG_CODEC_SRCS) += third_party/x86inc/x86inc.asm
endif
CODEC_EXPORTS-yes += vpx/exports_com
CODEC_EXPORTS-$(CONFIG_ENCODERS) += vpx/exports_enc
ifeq ($(CONFIG_SPATIAL_SVC),yes)
CODEC_EXPORTS-$(CONFIG_ENCODERS) += vpx/exports_spatial_svc
endif
CODEC_EXPORTS-$(CONFIG_DECODERS) += vpx/exports_dec
INSTALL-LIBS-yes += include/vpx/vpx_codec.h
@@ -229,7 +260,7 @@ OBJS-yes += $(LIBVPX_OBJS)
LIBS-$(if yes,$(CONFIG_STATIC)) += $(BUILD_PFX)libvpx.a $(BUILD_PFX)libvpx_g.a
$(BUILD_PFX)libvpx_g.a: $(LIBVPX_OBJS)
SO_VERSION_MAJOR := 4
SO_VERSION_MAJOR := 2
SO_VERSION_MINOR := 0
SO_VERSION_PATCH := 0
ifeq ($(filter darwin%,$(TGT_OS)),$(TGT_OS))
@@ -239,12 +270,6 @@ EXPORT_FILE := libvpx.syms
LIBVPX_SO_SYMLINKS := $(addprefix $(LIBSUBDIR)/, \
libvpx.dylib )
else
ifeq ($(filter iphonesimulator%,$(TGT_OS)),$(TGT_OS))
LIBVPX_SO := libvpx.$(SO_VERSION_MAJOR).dylib
SHARED_LIB_SUF := .dylib
EXPORT_FILE := libvpx.syms
LIBVPX_SO_SYMLINKS := $(addprefix $(LIBSUBDIR)/, libvpx.dylib)
else
ifeq ($(filter os2%,$(TGT_OS)),$(TGT_OS))
LIBVPX_SO := libvpx$(SO_VERSION_MAJOR).dll
SHARED_LIB_SUF := _dll.a
@@ -260,7 +285,6 @@ LIBVPX_SO_SYMLINKS := $(addprefix $(LIBSUBDIR)/, \
libvpx.so.$(SO_VERSION_MAJOR).$(SO_VERSION_MINOR))
endif
endif
endif
LIBS-$(CONFIG_SHARED) += $(BUILD_PFX)$(LIBVPX_SO)\
$(notdir $(LIBVPX_SO_SYMLINKS)) \
@@ -370,12 +394,6 @@ $(filter %$(ASM).o,$(OBJS-yes)): $(BUILD_PFX)vpx_config.asm
$(shell $(SRC_PATH_BARE)/build/make/version.sh "$(SRC_PATH_BARE)" $(BUILD_PFX)vpx_version.h)
CLEAN-OBJS += $(BUILD_PFX)vpx_version.h
#
# Add include path for libwebm sources.
#
ifeq ($(CONFIG_WEBM_IO),yes)
CXXFLAGS += -I$(SRC_PATH_BARE)/third_party/libwebm
endif
##
## libvpx test directives
@@ -411,10 +429,12 @@ testdata:: $(LIBVPX_TEST_DATA)
if [ -n "$${sha1sum}" ]; then\
set -e;\
echo "Checking test data:";\
if [ -n "$(LIBVPX_TEST_DATA)" ]; then\
for f in $(call enabled,LIBVPX_TEST_DATA); do\
grep $$f $(SRC_PATH_BARE)/test/test-data.sha1 |\
(cd $(LIBVPX_TEST_DATA_PATH); $${sha1sum} -c);\
done; \
fi; \
else\
echo "Skipping test data integrity check, sha1sum not found.";\
fi
@@ -451,7 +471,6 @@ test_libvpx.$(VCPROJ_SFX): $(LIBVPX_TEST_SRCS) vpx.$(VCPROJ_SFX) gtest.$(VCPROJ_
$(if $(CONFIG_STATIC_MSVCRT),--static-crt) \
--out=$@ $(INTERNAL_CFLAGS) $(CFLAGS) \
-I. -I"$(SRC_PATH_BARE)/third_party/googletest/src/include" \
$(if $(CONFIG_WEBM_IO),-I"$(SRC_PATH_BARE)/third_party/libwebm") \
-L. -l$(CODEC_LIB) -l$(GTEST_LIB) $^
PROJECTS-$(CONFIG_MSVS) += test_libvpx.$(VCPROJ_SFX)

View File

@@ -24,13 +24,15 @@
#include "md5_utils.h"
static void byteSwap(UWORD32 *buf, unsigned words) {
static void
byteSwap(UWORD32 *buf, unsigned words) {
md5byte *p;
/* Only swap bytes for big endian machines */
int i = 1;
if (*(char *)&i == 1) return;
if (*(char *)&i == 1)
return;
p = (md5byte *)buf;
@@ -45,7 +47,8 @@ static void byteSwap(UWORD32 *buf, unsigned words) {
* Start MD5 accumulation. Set bit count to 0 and buffer to mysterious
* initialization constants.
*/
void MD5Init(struct MD5Context *ctx) {
void
MD5Init(struct MD5Context *ctx) {
ctx->buf[0] = 0x67452301;
ctx->buf[1] = 0xefcdab89;
ctx->buf[2] = 0x98badcfe;
@@ -59,7 +62,8 @@ void MD5Init(struct MD5Context *ctx) {
* Update context to reflect the concatenation of another buffer full
* of bytes.
*/
void MD5Update(struct MD5Context *ctx, md5byte const *buf, unsigned len) {
void
MD5Update(struct MD5Context *ctx, md5byte const *buf, unsigned len) {
UWORD32 t;
/* Update byte count */
@@ -100,7 +104,8 @@ void MD5Update(struct MD5Context *ctx, md5byte const *buf, unsigned len) {
* Final wrapup - pad to 64-byte boundary with the bit pattern
* 1 0* (64-bit count of bits processed, MSB-first)
*/
void MD5Final(md5byte digest[16], struct MD5Context *ctx) {
void
MD5Final(md5byte digest[16], struct MD5Context *ctx) {
int count = ctx->bytes[0] & 0x3f; /* Number of bytes in ctx->in */
md5byte *p = (md5byte *)ctx->in + count;
@@ -145,24 +150,13 @@ void MD5Final(md5byte digest[16], struct MD5Context *ctx) {
#define MD5STEP(f,w,x,y,z,in,s) \
(w += f(x,y,z) + in, w = (w<<s | w>>(32-s)) + x)
#if defined(__clang__) && defined(__has_attribute)
#if __has_attribute(no_sanitize)
#define VPX_NO_UNSIGNED_OVERFLOW_CHECK \
__attribute__((no_sanitize("unsigned-integer-overflow")))
#endif
#endif
#ifndef VPX_NO_UNSIGNED_OVERFLOW_CHECK
#define VPX_NO_UNSIGNED_OVERFLOW_CHECK
#endif
/*
* The core of the MD5 algorithm, this alters an existing MD5 hash to
* reflect the addition of 16 longwords of new data. MD5Update blocks
* the data and converts bytes into longwords for this routine.
*/
VPX_NO_UNSIGNED_OVERFLOW_CHECK void MD5Transform(UWORD32 buf[4],
UWORD32 const in[16]) {
void
MD5Transform(UWORD32 buf[4], UWORD32 const in[16]) {
register UWORD32 a, b, c, d;
a = buf[0];
@@ -244,6 +238,4 @@ VPX_NO_UNSIGNED_OVERFLOW_CHECK void MD5Transform(UWORD32 buf[4],
buf[3] += d;
}
#undef VPX_NO_UNSIGNED_OVERFLOW_CHECK
#endif

View File

@@ -45,7 +45,8 @@ struct rate_hist *init_rate_histogram(const vpx_codec_enc_cfg_t *cfg,
hist->samples = cfg->rc_buf_sz * 5 / 4 * fps->num / fps->den / 1000;
// prevent division by zero
if (hist->samples == 0) hist->samples = 1;
if (hist->samples == 0)
hist->samples = 1;
hist->frames = 0;
hist->total = 0;
@@ -84,9 +85,11 @@ void update_rate_histogram(struct rate_hist *hist,
hist->pts[idx] = now;
hist->sz[idx] = (int)pkt->data.frame.sz;
if (now < cfg->rc_buf_initial_sz) return;
if (now < cfg->rc_buf_initial_sz)
return;
if (!cfg->rc_target_bitrate) return;
if (!cfg->rc_target_bitrate)
return;
then = now;
@@ -95,16 +98,20 @@ void update_rate_histogram(struct rate_hist *hist,
const int i_idx = (i - 1) % hist->samples;
then = hist->pts[i_idx];
if (now - then > cfg->rc_buf_sz) break;
if (now - then > cfg->rc_buf_sz)
break;
sum_sz += hist->sz[i_idx];
}
if (now == then) return;
if (now == then)
return;
avg_bitrate = sum_sz * 8 * 1000 / (now - then);
idx = (int)(avg_bitrate * (RATE_BINS / 2) / (cfg->rc_target_bitrate * 1000));
if (idx < 0) idx = 0;
if (idx > RATE_BINS - 1) idx = RATE_BINS - 1;
if (idx < 0)
idx = 0;
if (idx > RATE_BINS - 1)
idx = RATE_BINS - 1;
if (hist->bucket[idx].low > avg_bitrate)
hist->bucket[idx].low = (int)avg_bitrate;
if (hist->bucket[idx].high < avg_bitrate)
@@ -113,8 +120,8 @@ void update_rate_histogram(struct rate_hist *hist,
hist->total++;
}
static int merge_hist_buckets(struct hist_bucket *bucket, int max_buckets,
int *num_buckets) {
static int merge_hist_buckets(struct hist_bucket *bucket,
int max_buckets, int *num_buckets) {
int small_bucket = 0, merge_bucket = INT_MAX, big_bucket = 0;
int buckets = *num_buckets;
int i;
@@ -122,8 +129,10 @@ static int merge_hist_buckets(struct hist_bucket *bucket, int max_buckets,
/* Find the extrema for this list of buckets */
big_bucket = small_bucket = 0;
for (i = 0; i < buckets; i++) {
if (bucket[i].count < bucket[small_bucket].count) small_bucket = i;
if (bucket[i].count > bucket[big_bucket].count) big_bucket = i;
if (bucket[i].count < bucket[small_bucket].count)
small_bucket = i;
if (bucket[i].count > bucket[big_bucket].count)
big_bucket = i;
}
/* If we have too many buckets, merge the smallest with an adjacent
@@ -165,10 +174,13 @@ static int merge_hist_buckets(struct hist_bucket *bucket, int max_buckets,
*/
big_bucket = small_bucket = 0;
for (i = 0; i < buckets; i++) {
if (i > merge_bucket) bucket[i] = bucket[i + 1];
if (i > merge_bucket)
bucket[i] = bucket[i + 1];
if (bucket[i].count < bucket[small_bucket].count) small_bucket = i;
if (bucket[i].count > bucket[big_bucket].count) big_bucket = i;
if (bucket[i].count < bucket[small_bucket].count)
small_bucket = i;
if (bucket[i].count > bucket[big_bucket].count)
big_bucket = i;
}
}
@@ -176,8 +188,8 @@ static int merge_hist_buckets(struct hist_bucket *bucket, int max_buckets,
return bucket[big_bucket].count;
}
static void show_histogram(const struct hist_bucket *bucket, int buckets,
int total, int scale) {
static void show_histogram(const struct hist_bucket *bucket,
int buckets, int total, int scale) {
const char *pat1, *pat2;
int i;
@@ -220,7 +232,8 @@ static void show_histogram(const struct hist_bucket *bucket, int buckets,
pct = (float)(100.0 * bucket[i].count / total);
len = HIST_BAR_MAX * bucket[i].count / scale;
if (len < 1) len = 1;
if (len < 1)
len = 1;
assert(len <= HIST_BAR_MAX);
if (bucket[i].low == bucket[i].high)
@@ -228,7 +241,8 @@ static void show_histogram(const struct hist_bucket *bucket, int buckets,
else
fprintf(stderr, pat2, bucket[i].low, bucket[i].high);
for (j = 0; j < HIST_BAR_MAX; j++) fprintf(stderr, j < len ? "=" : " ");
for (j = 0; j < HIST_BAR_MAX; j++)
fprintf(stderr, j < len ? "=" : " ");
fprintf(stderr, "\t%5d (%6.2f%%)\n", bucket[i].count, pct);
}
}
@@ -254,13 +268,14 @@ void show_q_histogram(const int counts[64], int max_buckets) {
show_histogram(bucket, buckets, total, scale);
}
void show_rate_histogram(struct rate_hist *hist, const vpx_codec_enc_cfg_t *cfg,
int max_buckets) {
void show_rate_histogram(struct rate_hist *hist,
const vpx_codec_enc_cfg_t *cfg, int max_buckets) {
int i, scale;
int buckets = 0;
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];
}

View File

@@ -23,19 +23,15 @@ class ACMRandom {
explicit ACMRandom(int seed) : random_(seed) {}
void Reset(int seed) { random_.Reseed(seed); }
void Reset(int seed) {
random_.Reseed(seed);
}
uint16_t Rand16(void) {
const uint32_t value =
random_.Generate(testing::internal::Random::kMaxRange);
return (value >> 15) & 0xffff;
}
int16_t Rand9Signed(void) {
// Use 9 bits: values between 255 (0x0FF) and -256 (0x100).
const uint32_t value = random_.Generate(512);
return static_cast<int16_t>(value) - 256;
}
uint8_t Rand8(void) {
const uint32_t value =
random_.Generate(testing::internal::Random::kMaxRange);
@@ -50,11 +46,17 @@ class ACMRandom {
return r < 128 ? r << 4 : r >> 4;
}
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);
}
static int DeterministicSeed(void) { return 0xbaba; }
static int DeterministicSeed(void) {
return 0xbaba;
}
private:
testing::internal::Random random_;

View File

@@ -1,128 +0,0 @@
/*
* Copyright (c) 2015 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 <algorithm>
#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/y4m_video_source.h"
namespace {
// Check if any pixel in a 16x16 macroblock varies between frames.
int CheckMb(const vpx_image_t &current, const vpx_image_t &previous, int mb_r,
int mb_c) {
for (int plane = 0; plane < 3; plane++) {
int r = 16 * mb_r;
int c0 = 16 * mb_c;
int r_top = std::min(r + 16, static_cast<int>(current.d_h));
int c_top = std::min(c0 + 16, static_cast<int>(current.d_w));
r = std::max(r, 0);
c0 = std::max(c0, 0);
if (plane > 0 && current.x_chroma_shift) {
c_top = (c_top + 1) >> 1;
c0 >>= 1;
}
if (plane > 0 && current.y_chroma_shift) {
r_top = (r_top + 1) >> 1;
r >>= 1;
}
for (; r < r_top; ++r) {
for (int c = c0; c < c_top; ++c) {
if (current.planes[plane][current.stride[plane] * r + c] !=
previous.planes[plane][previous.stride[plane] * r + c]) {
return 1;
}
}
}
}
return 0;
}
void GenerateMap(int mb_rows, int mb_cols, const vpx_image_t &current,
const vpx_image_t &previous, uint8_t *map) {
for (int mb_r = 0; mb_r < mb_rows; ++mb_r) {
for (int mb_c = 0; mb_c < mb_cols; ++mb_c) {
map[mb_r * mb_cols + mb_c] = CheckMb(current, previous, mb_r, mb_c);
}
}
}
const int kAqModeCyclicRefresh = 3;
class ActiveMapRefreshTest
: public ::libvpx_test::EncoderTest,
public ::libvpx_test::CodecTestWith2Params<libvpx_test::TestMode, int> {
protected:
ActiveMapRefreshTest() : EncoderTest(GET_PARAM(0)) {}
virtual ~ActiveMapRefreshTest() {}
virtual void SetUp() {
InitializeConfig();
SetMode(GET_PARAM(1));
cpu_used_ = GET_PARAM(2);
}
virtual void PreEncodeFrameHook(::libvpx_test::VideoSource *video,
::libvpx_test::Encoder *encoder) {
::libvpx_test::Y4mVideoSource *y4m_video =
static_cast<libvpx_test::Y4mVideoSource *>(video);
if (video->frame() == 1) {
encoder->Control(VP8E_SET_CPUUSED, cpu_used_);
encoder->Control(VP9E_SET_AQ_MODE, kAqModeCyclicRefresh);
} else if (video->frame() >= 2 && video->img()) {
vpx_image_t *current = video->img();
vpx_image_t *previous = y4m_holder_->img();
ASSERT_TRUE(previous != NULL);
vpx_active_map_t map = vpx_active_map_t();
const int width = static_cast<int>(current->d_w);
const int height = static_cast<int>(current->d_h);
const int mb_width = (width + 15) / 16;
const int mb_height = (height + 15) / 16;
uint8_t *active_map = new uint8_t[mb_width * mb_height];
GenerateMap(mb_height, mb_width, *current, *previous, active_map);
map.cols = mb_width;
map.rows = mb_height;
map.active_map = active_map;
encoder->Control(VP8E_SET_ACTIVEMAP, &map);
delete[] active_map;
}
if (video->img()) {
y4m_video->SwapBuffers(y4m_holder_);
}
}
int cpu_used_;
::libvpx_test::Y4mVideoSource *y4m_holder_;
};
TEST_P(ActiveMapRefreshTest, Test) {
cfg_.g_lag_in_frames = 0;
cfg_.g_profile = 1;
cfg_.rc_target_bitrate = 600;
cfg_.rc_resize_allowed = 0;
cfg_.rc_min_quantizer = 8;
cfg_.rc_max_quantizer = 30;
cfg_.g_pass = VPX_RC_ONE_PASS;
cfg_.rc_end_usage = VPX_CBR;
cfg_.kf_max_dist = 90000;
::libvpx_test::Y4mVideoSource video("desktop_credits.y4m", 0, 30);
::libvpx_test::Y4mVideoSource video_holder("desktop_credits.y4m", 0, 30);
video_holder.Begin();
y4m_holder_ = &video_holder;
ASSERT_NO_FATAL_FAILURE(RunLoop(&video));
}
VP9_INSTANTIATE_TEST_CASE(ActiveMapRefreshTest,
::testing::Values(::libvpx_test::kRealTime),
::testing::Range(5, 6));
} // namespace

View File

@@ -39,7 +39,6 @@ class ActiveMapTest
encoder->Control(VP8E_SET_CPUUSED, cpu_used_);
} else if (video->frame() == 3) {
vpx_active_map_t map = vpx_active_map_t();
/* clang-format off */
uint8_t active_map[9 * 13] = {
1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 0, 0, 0,
1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 0, 0, 0,
@@ -51,7 +50,6 @@ class ActiveMapTest
0, 0, 0, 0, 0, 0, 1, 1, 0, 1, 0, 1, 1,
1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 0,
};
/* clang-format on */
map.cols = (kWidth + 15) / 16;
map.rows = (kHeight + 15) / 16;
ASSERT_EQ(map.cols, 13u);
@@ -79,13 +77,13 @@ TEST_P(ActiveMapTest, Test) {
cfg_.rc_end_usage = VPX_CBR;
cfg_.kf_max_dist = 90000;
::libvpx_test::I420VideoSource video("hantro_odd.yuv", kWidth, kHeight, 30, 1,
0, 20);
::libvpx_test::I420VideoSource video("hantro_odd.yuv", kWidth, kHeight, 30,
1, 0, 20);
ASSERT_NO_FATAL_FAILURE(RunLoop(&video));
}
VP9_INSTANTIATE_TEST_CASE(ActiveMapTest,
::testing::Values(::libvpx_test::kRealTime),
::testing::Range(0, 9));
::testing::Range(0, 6));
} // namespace

View File

@@ -1,136 +0,0 @@
/*
* Copyright (c) 2016 The WebM project authors. All Rights Reserved.
*
* Use of this source code is governed by a BSD-style license
* that can be found in the LICENSE file in the root of the source
* tree. An additional intellectual property rights grant can be found
* in the file PATENTS. All contributing project authors may
* be found in the AUTHORS file in the root of the source tree.
*/
#include <math.h>
#include "test/clear_system_state.h"
#include "test/register_state_check.h"
#include "third_party/googletest/src/include/gtest/gtest.h"
#include "./vpx_dsp_rtcd.h"
#include "vpx/vpx_integer.h"
#include "vpx_dsp/postproc.h"
#include "vpx_mem/vpx_mem.h"
namespace {
static const int kNoiseSize = 3072;
// TODO(jimbankoski): make width and height integers not unsigned.
typedef void (*AddNoiseFunc)(uint8_t *start, const int8_t *noise,
int blackclamp, int whiteclamp, int width,
int height, int pitch);
class AddNoiseTest : public ::testing::TestWithParam<AddNoiseFunc> {
public:
virtual void TearDown() { libvpx_test::ClearSystemState(); }
virtual ~AddNoiseTest() {}
};
double stddev6(char a, char b, char c, char d, char e, char f) {
const double n = (a + b + c + d + e + f) / 6.0;
const double v = ((a - n) * (a - n) + (b - n) * (b - n) + (c - n) * (c - n) +
(d - n) * (d - n) + (e - n) * (e - n) + (f - n) * (f - n)) /
6.0;
return sqrt(v);
}
TEST_P(AddNoiseTest, CheckNoiseAdded) {
const int width = 64;
const int height = 64;
const int image_size = width * height;
int8_t noise[kNoiseSize];
const int clamp = vpx_setup_noise(4.4, noise, kNoiseSize);
uint8_t *const s =
reinterpret_cast<uint8_t *>(vpx_calloc(image_size, sizeof(*s)));
ASSERT_TRUE(s != NULL);
memset(s, 99, image_size * sizeof(*s));
ASM_REGISTER_STATE_CHECK(
GetParam()(s, noise, clamp, clamp, width, height, width));
// Check to make sure we don't end up having either the same or no added
// noise either vertically or horizontally.
for (int i = 0; i < image_size - 6 * width - 6; ++i) {
const double hd = stddev6(s[i] - 99, s[i + 1] - 99, s[i + 2] - 99,
s[i + 3] - 99, s[i + 4] - 99, s[i + 5] - 99);
const double vd = stddev6(s[i] - 99, s[i + width] - 99,
s[i + 2 * width] - 99, s[i + 3 * width] - 99,
s[i + 4 * width] - 99, s[i + 5 * width] - 99);
EXPECT_NE(hd, 0);
EXPECT_NE(vd, 0);
}
// Initialize pixels in the image to 255 and check for roll over.
memset(s, 255, image_size);
ASM_REGISTER_STATE_CHECK(
GetParam()(s, noise, clamp, clamp, width, height, width));
// Check to make sure don't roll over.
for (int i = 0; i < image_size; ++i) {
EXPECT_GT(static_cast<int>(s[i]), clamp) << "i = " << i;
}
// Initialize pixels in the image to 0 and check for roll under.
memset(s, 0, image_size);
ASM_REGISTER_STATE_CHECK(
GetParam()(s, noise, clamp, clamp, width, height, width));
// Check to make sure don't roll under.
for (int i = 0; i < image_size; ++i) {
EXPECT_LT(static_cast<int>(s[i]), 255 - clamp) << "i = " << i;
}
vpx_free(s);
}
TEST_P(AddNoiseTest, CheckCvsAssembly) {
const int width = 64;
const int height = 64;
const int image_size = width * height;
int8_t noise[kNoiseSize];
const int clamp = vpx_setup_noise(4.4, noise, kNoiseSize);
uint8_t *const s = reinterpret_cast<uint8_t *>(vpx_calloc(image_size, 1));
uint8_t *const d = reinterpret_cast<uint8_t *>(vpx_calloc(image_size, 1));
ASSERT_TRUE(s != NULL);
ASSERT_TRUE(d != NULL);
memset(s, 99, image_size);
memset(d, 99, image_size);
srand(0);
ASM_REGISTER_STATE_CHECK(
GetParam()(s, noise, clamp, clamp, width, height, width));
srand(0);
ASM_REGISTER_STATE_CHECK(
vpx_plane_add_noise_c(d, noise, clamp, clamp, width, height, width));
for (int i = 0; i < image_size; ++i) {
EXPECT_EQ(static_cast<int>(s[i]), static_cast<int>(d[i])) << "i = " << i;
}
vpx_free(d);
vpx_free(s);
}
INSTANTIATE_TEST_CASE_P(C, AddNoiseTest,
::testing::Values(vpx_plane_add_noise_c));
#if HAVE_SSE2
INSTANTIATE_TEST_CASE_P(SSE2, AddNoiseTest,
::testing::Values(vpx_plane_add_noise_sse2));
#endif
#if HAVE_MSA
INSTANTIATE_TEST_CASE_P(MSA, AddNoiseTest,
::testing::Values(vpx_plane_add_noise_msa));
#endif
} // namespace

View File

@@ -14,8 +14,6 @@
#include "test/util.h"
namespace {
#if CONFIG_VP8_ENCODER
// lookahead range: [kLookAheadMin, kLookAheadMax).
const int kLookAheadMin = 5;
const int kLookAheadMax = 26;
@@ -31,7 +29,9 @@ class AltRefTest : public ::libvpx_test::EncoderTest,
SetMode(libvpx_test::kTwoPassGood);
}
virtual void BeginPassHook(unsigned int pass) { altref_count_ = 0; }
virtual void BeginPassHook(unsigned int pass) {
altref_count_ = 0;
}
virtual void PreEncodeFrameHook(libvpx_test::VideoSource *video,
libvpx_test::Encoder *encoder) {
@@ -63,90 +63,7 @@ TEST_P(AltRefTest, MonotonicTimestamps) {
EXPECT_GE(altref_count(), 1);
}
VP8_INSTANTIATE_TEST_CASE(AltRefTest,
::testing::Range(kLookAheadMin, kLookAheadMax));
#endif // CONFIG_VP8_ENCODER
class AltRefForcedKeyTestLarge
: public ::libvpx_test::EncoderTest,
public ::libvpx_test::CodecTestWith2Params<libvpx_test::TestMode, int> {
protected:
AltRefForcedKeyTestLarge()
: EncoderTest(GET_PARAM(0)), encoding_mode_(GET_PARAM(1)),
cpu_used_(GET_PARAM(2)), forced_kf_frame_num_(1), frame_num_(0) {}
virtual ~AltRefForcedKeyTestLarge() {}
virtual void SetUp() {
InitializeConfig();
SetMode(encoding_mode_);
cfg_.rc_end_usage = VPX_VBR;
cfg_.g_threads = 0;
}
virtual void PreEncodeFrameHook(::libvpx_test::VideoSource *video,
::libvpx_test::Encoder *encoder) {
if (video->frame() == 0) {
encoder->Control(VP8E_SET_CPUUSED, cpu_used_);
encoder->Control(VP8E_SET_ENABLEAUTOALTREF, 1);
#if CONFIG_VP9_ENCODER
// override test default for tile columns if necessary.
if (GET_PARAM(0) == &libvpx_test::kVP9) {
encoder->Control(VP9E_SET_TILE_COLUMNS, 6);
}
#endif
}
frame_flags_ =
(video->frame() == forced_kf_frame_num_) ? VPX_EFLAG_FORCE_KF : 0;
}
virtual void FramePktHook(const vpx_codec_cx_pkt_t *pkt) {
if (frame_num_ == forced_kf_frame_num_) {
ASSERT_TRUE(!!(pkt->data.frame.flags & VPX_FRAME_IS_KEY))
<< "Frame #" << frame_num_ << " isn't a keyframe!";
}
++frame_num_;
}
::libvpx_test::TestMode encoding_mode_;
int cpu_used_;
unsigned int forced_kf_frame_num_;
unsigned int frame_num_;
};
TEST_P(AltRefForcedKeyTestLarge, Frame1IsKey) {
const vpx_rational timebase = { 1, 30 };
const int lag_values[] = { 3, 15, 25, -1 };
forced_kf_frame_num_ = 1;
for (int i = 0; lag_values[i] != -1; ++i) {
frame_num_ = 0;
cfg_.g_lag_in_frames = lag_values[i];
libvpx_test::I420VideoSource video("hantro_collage_w352h288.yuv", 352, 288,
timebase.den, timebase.num, 0, 30);
ASSERT_NO_FATAL_FAILURE(RunLoop(&video));
}
}
TEST_P(AltRefForcedKeyTestLarge, ForcedFrameIsKey) {
const vpx_rational timebase = { 1, 30 };
const int lag_values[] = { 3, 15, 25, -1 };
for (int i = 0; lag_values[i] != -1; ++i) {
frame_num_ = 0;
forced_kf_frame_num_ = lag_values[i] - 1;
cfg_.g_lag_in_frames = lag_values[i];
libvpx_test::I420VideoSource video("hantro_collage_w352h288.yuv", 352, 288,
timebase.den, timebase.num, 0, 30);
ASSERT_NO_FATAL_FAILURE(RunLoop(&video));
}
}
VP8_INSTANTIATE_TEST_CASE(AltRefForcedKeyTestLarge,
::testing::Values(::libvpx_test::kOnePassGood),
::testing::Range(0, 9));
VP9_INSTANTIATE_TEST_CASE(AltRefForcedKeyTestLarge,
::testing::Values(::libvpx_test::kOnePassGood),
::testing::Range(0, 9));
} // namespace

View File

@@ -1,396 +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 <limits.h>
#include <stdio.h>
#include <string.h>
#include "third_party/googletest/src/include/gtest/gtest.h"
#include "./vpx_config.h"
#include "./vpx_dsp_rtcd.h"
#include "test/acm_random.h"
#include "test/clear_system_state.h"
#include "test/register_state_check.h"
#include "test/util.h"
#include "vpx_mem/vpx_mem.h"
using libvpx_test::ACMRandom;
namespace {
class AverageTestBase : public ::testing::Test {
public:
AverageTestBase(int width, int height) : width_(width), height_(height) {}
static void SetUpTestCase() {
source_data_ = reinterpret_cast<uint8_t *>(
vpx_memalign(kDataAlignment, kDataBlockSize));
}
static void TearDownTestCase() {
vpx_free(source_data_);
source_data_ = NULL;
}
virtual void TearDown() { libvpx_test::ClearSystemState(); }
protected:
// Handle blocks up to 4 blocks 64x64 with stride up to 128
static const int kDataAlignment = 16;
static const int kDataBlockSize = 64 * 128;
virtual void SetUp() {
source_stride_ = (width_ + 31) & ~31;
rnd_.Reset(ACMRandom::DeterministicSeed());
}
// Sum Pixels
unsigned int ReferenceAverage8x8(const uint8_t *source, int pitch) {
unsigned int average = 0;
for (int h = 0; h < 8; ++h) {
for (int w = 0; w < 8; ++w) average += source[h * pitch + w];
}
return ((average + 32) >> 6);
}
unsigned int ReferenceAverage4x4(const uint8_t *source, int pitch) {
unsigned int average = 0;
for (int h = 0; h < 4; ++h) {
for (int w = 0; w < 4; ++w) average += source[h * pitch + w];
}
return ((average + 8) >> 4);
}
void FillConstant(uint8_t fill_constant) {
for (int i = 0; i < width_ * height_; ++i) {
source_data_[i] = fill_constant;
}
}
void FillRandom() {
for (int i = 0; i < width_ * height_; ++i) {
source_data_[i] = rnd_.Rand8();
}
}
int width_, height_;
static uint8_t *source_data_;
int source_stride_;
ACMRandom rnd_;
};
typedef unsigned int (*AverageFunction)(const uint8_t *s, int pitch);
typedef std::tr1::tuple<int, int, int, int, AverageFunction> AvgFunc;
class AverageTest : public AverageTestBase,
public ::testing::WithParamInterface<AvgFunc> {
public:
AverageTest() : AverageTestBase(GET_PARAM(0), GET_PARAM(1)) {}
protected:
void CheckAverages() {
unsigned int expected = 0;
if (GET_PARAM(3) == 8) {
expected =
ReferenceAverage8x8(source_data_ + GET_PARAM(2), source_stride_);
} else if (GET_PARAM(3) == 4) {
expected =
ReferenceAverage4x4(source_data_ + GET_PARAM(2), source_stride_);
}
ASM_REGISTER_STATE_CHECK(
GET_PARAM(4)(source_data_ + GET_PARAM(2), source_stride_));
unsigned int actual =
GET_PARAM(4)(source_data_ + GET_PARAM(2), source_stride_);
EXPECT_EQ(expected, actual);
}
};
typedef void (*IntProRowFunc)(int16_t hbuf[16], uint8_t const *ref,
const int ref_stride, const int height);
typedef std::tr1::tuple<int, IntProRowFunc, IntProRowFunc> IntProRowParam;
class IntProRowTest : public AverageTestBase,
public ::testing::WithParamInterface<IntProRowParam> {
public:
IntProRowTest()
: AverageTestBase(16, GET_PARAM(0)), hbuf_asm_(NULL), hbuf_c_(NULL) {
asm_func_ = GET_PARAM(1);
c_func_ = GET_PARAM(2);
}
protected:
virtual void SetUp() {
hbuf_asm_ = reinterpret_cast<int16_t *>(
vpx_memalign(kDataAlignment, sizeof(*hbuf_asm_) * 16));
hbuf_c_ = reinterpret_cast<int16_t *>(
vpx_memalign(kDataAlignment, sizeof(*hbuf_c_) * 16));
}
virtual void TearDown() {
vpx_free(hbuf_c_);
hbuf_c_ = NULL;
vpx_free(hbuf_asm_);
hbuf_asm_ = NULL;
}
void RunComparison() {
ASM_REGISTER_STATE_CHECK(c_func_(hbuf_c_, source_data_, 0, height_));
ASM_REGISTER_STATE_CHECK(asm_func_(hbuf_asm_, source_data_, 0, height_));
EXPECT_EQ(0, memcmp(hbuf_c_, hbuf_asm_, sizeof(*hbuf_c_) * 16))
<< "Output mismatch";
}
private:
IntProRowFunc asm_func_;
IntProRowFunc c_func_;
int16_t *hbuf_asm_;
int16_t *hbuf_c_;
};
typedef int16_t (*IntProColFunc)(uint8_t const *ref, const int width);
typedef std::tr1::tuple<int, IntProColFunc, IntProColFunc> IntProColParam;
class IntProColTest : public AverageTestBase,
public ::testing::WithParamInterface<IntProColParam> {
public:
IntProColTest() : AverageTestBase(GET_PARAM(0), 1), sum_asm_(0), sum_c_(0) {
asm_func_ = GET_PARAM(1);
c_func_ = GET_PARAM(2);
}
protected:
void RunComparison() {
ASM_REGISTER_STATE_CHECK(sum_c_ = c_func_(source_data_, width_));
ASM_REGISTER_STATE_CHECK(sum_asm_ = asm_func_(source_data_, width_));
EXPECT_EQ(sum_c_, sum_asm_) << "Output mismatch";
}
private:
IntProColFunc asm_func_;
IntProColFunc c_func_;
int16_t sum_asm_;
int16_t sum_c_;
};
typedef int (*SatdFunc)(const int16_t *coeffs, int length);
typedef std::tr1::tuple<int, SatdFunc> SatdTestParam;
class SatdTest : public ::testing::Test,
public ::testing::WithParamInterface<SatdTestParam> {
protected:
virtual void SetUp() {
satd_size_ = GET_PARAM(0);
satd_func_ = GET_PARAM(1);
rnd_.Reset(ACMRandom::DeterministicSeed());
src_ = reinterpret_cast<int16_t *>(
vpx_memalign(16, sizeof(*src_) * satd_size_));
ASSERT_TRUE(src_ != NULL);
}
virtual void TearDown() {
libvpx_test::ClearSystemState();
vpx_free(src_);
}
void FillConstant(const int16_t val) {
for (int i = 0; i < satd_size_; ++i) src_[i] = val;
}
void FillRandom() {
for (int i = 0; i < satd_size_; ++i) src_[i] = rnd_.Rand16();
}
void Check(const int expected) {
int total;
ASM_REGISTER_STATE_CHECK(total = satd_func_(src_, satd_size_));
EXPECT_EQ(expected, total);
}
int satd_size_;
private:
int16_t *src_;
SatdFunc satd_func_;
ACMRandom rnd_;
};
uint8_t *AverageTestBase::source_data_ = NULL;
TEST_P(AverageTest, MinValue) {
FillConstant(0);
CheckAverages();
}
TEST_P(AverageTest, MaxValue) {
FillConstant(255);
CheckAverages();
}
TEST_P(AverageTest, Random) {
// The reference frame, but not the source frame, may be unaligned for
// certain types of searches.
for (int i = 0; i < 1000; i++) {
FillRandom();
CheckAverages();
}
}
TEST_P(IntProRowTest, MinValue) {
FillConstant(0);
RunComparison();
}
TEST_P(IntProRowTest, MaxValue) {
FillConstant(255);
RunComparison();
}
TEST_P(IntProRowTest, Random) {
FillRandom();
RunComparison();
}
TEST_P(IntProColTest, MinValue) {
FillConstant(0);
RunComparison();
}
TEST_P(IntProColTest, MaxValue) {
FillConstant(255);
RunComparison();
}
TEST_P(IntProColTest, Random) {
FillRandom();
RunComparison();
}
TEST_P(SatdTest, MinValue) {
const int kMin = -32640;
const int expected = -kMin * satd_size_;
FillConstant(kMin);
Check(expected);
}
TEST_P(SatdTest, MaxValue) {
const int kMax = 32640;
const int expected = kMax * satd_size_;
FillConstant(kMax);
Check(expected);
}
TEST_P(SatdTest, Random) {
int expected;
switch (satd_size_) {
case 16: expected = 205298; break;
case 64: expected = 1113950; break;
case 256: expected = 4268415; break;
case 1024: expected = 16954082; break;
default:
FAIL() << "Invalid satd size (" << satd_size_
<< ") valid: 16/64/256/1024";
}
FillRandom();
Check(expected);
}
using std::tr1::make_tuple;
INSTANTIATE_TEST_CASE_P(
C, AverageTest,
::testing::Values(make_tuple(16, 16, 1, 8, &vpx_avg_8x8_c),
make_tuple(16, 16, 1, 4, &vpx_avg_4x4_c)));
INSTANTIATE_TEST_CASE_P(C, SatdTest,
::testing::Values(make_tuple(16, &vpx_satd_c),
make_tuple(64, &vpx_satd_c),
make_tuple(256, &vpx_satd_c),
make_tuple(1024, &vpx_satd_c)));
#if HAVE_SSE2
INSTANTIATE_TEST_CASE_P(
SSE2, AverageTest,
::testing::Values(make_tuple(16, 16, 0, 8, &vpx_avg_8x8_sse2),
make_tuple(16, 16, 5, 8, &vpx_avg_8x8_sse2),
make_tuple(32, 32, 15, 8, &vpx_avg_8x8_sse2),
make_tuple(16, 16, 0, 4, &vpx_avg_4x4_sse2),
make_tuple(16, 16, 5, 4, &vpx_avg_4x4_sse2),
make_tuple(32, 32, 15, 4, &vpx_avg_4x4_sse2)));
INSTANTIATE_TEST_CASE_P(
SSE2, IntProRowTest,
::testing::Values(make_tuple(16, &vpx_int_pro_row_sse2, &vpx_int_pro_row_c),
make_tuple(32, &vpx_int_pro_row_sse2, &vpx_int_pro_row_c),
make_tuple(64, &vpx_int_pro_row_sse2,
&vpx_int_pro_row_c)));
INSTANTIATE_TEST_CASE_P(
SSE2, IntProColTest,
::testing::Values(make_tuple(16, &vpx_int_pro_col_sse2, &vpx_int_pro_col_c),
make_tuple(32, &vpx_int_pro_col_sse2, &vpx_int_pro_col_c),
make_tuple(64, &vpx_int_pro_col_sse2,
&vpx_int_pro_col_c)));
INSTANTIATE_TEST_CASE_P(SSE2, SatdTest,
::testing::Values(make_tuple(16, &vpx_satd_sse2),
make_tuple(64, &vpx_satd_sse2),
make_tuple(256, &vpx_satd_sse2),
make_tuple(1024, &vpx_satd_sse2)));
#endif
#if HAVE_NEON
INSTANTIATE_TEST_CASE_P(
NEON, AverageTest,
::testing::Values(make_tuple(16, 16, 0, 8, &vpx_avg_8x8_neon),
make_tuple(16, 16, 5, 8, &vpx_avg_8x8_neon),
make_tuple(32, 32, 15, 8, &vpx_avg_8x8_neon),
make_tuple(16, 16, 0, 4, &vpx_avg_4x4_neon),
make_tuple(16, 16, 5, 4, &vpx_avg_4x4_neon),
make_tuple(32, 32, 15, 4, &vpx_avg_4x4_neon)));
INSTANTIATE_TEST_CASE_P(
NEON, IntProRowTest,
::testing::Values(make_tuple(16, &vpx_int_pro_row_neon, &vpx_int_pro_row_c),
make_tuple(32, &vpx_int_pro_row_neon, &vpx_int_pro_row_c),
make_tuple(64, &vpx_int_pro_row_neon,
&vpx_int_pro_row_c)));
INSTANTIATE_TEST_CASE_P(
NEON, IntProColTest,
::testing::Values(make_tuple(16, &vpx_int_pro_col_neon, &vpx_int_pro_col_c),
make_tuple(32, &vpx_int_pro_col_neon, &vpx_int_pro_col_c),
make_tuple(64, &vpx_int_pro_col_neon,
&vpx_int_pro_col_c)));
INSTANTIATE_TEST_CASE_P(NEON, SatdTest,
::testing::Values(make_tuple(16, &vpx_satd_neon),
make_tuple(64, &vpx_satd_neon),
make_tuple(256, &vpx_satd_neon),
make_tuple(1024, &vpx_satd_neon)));
#endif
#if HAVE_MSA
INSTANTIATE_TEST_CASE_P(
MSA, AverageTest,
::testing::Values(make_tuple(16, 16, 0, 8, &vpx_avg_8x8_msa),
make_tuple(16, 16, 5, 8, &vpx_avg_8x8_msa),
make_tuple(32, 32, 15, 8, &vpx_avg_8x8_msa),
make_tuple(16, 16, 0, 4, &vpx_avg_4x4_msa),
make_tuple(16, 16, 5, 4, &vpx_avg_4x4_msa),
make_tuple(32, 32, 15, 4, &vpx_avg_4x4_msa)));
#endif
} // namespace

View File

@@ -26,7 +26,9 @@
#include "vpx_mem/vpx_mem.h"
extern "C" double vp9_get_blockiness(const unsigned char *img1, int img1_pitch,
extern "C"
double vp9_get_blockiness(const unsigned char *img1, int img1_pitch,
const unsigned char *img2, int img2_pitch,
int width, int height);
@@ -51,7 +53,9 @@ class BlockinessTestBase : public ::testing::Test {
reference_data_ = NULL;
}
virtual void TearDown() { libvpx_test::ClearSystemState(); }
virtual void TearDown() {
libvpx_test::ClearSystemState();
}
protected:
// Handle frames up to 640x480
@@ -64,8 +68,8 @@ class BlockinessTestBase : public ::testing::Test {
rnd_.Reset(ACMRandom::DeterministicSeed());
}
void FillConstant(uint8_t *data, int stride, uint8_t fill_constant, int width,
int height) {
void FillConstant(uint8_t *data, int stride, uint8_t fill_constant,
int width, int height) {
for (int h = 0; h < height; ++h) {
for (int w = 0; w < width; ++w) {
data[h * stride + w] = fill_constant;
@@ -100,14 +104,13 @@ class BlockinessTestBase : public ::testing::Test {
void FillCheckerboard(uint8_t *data, int stride) {
for (int h = 0; h < height_; h += 4) {
for (int w = 0; w < width_; w += 4) {
if (((h / 4) ^ (w / 4)) & 1) {
if (((h/4) ^ (w/4)) & 1)
FillConstant(data + h * stride + w, stride, 255, 4, 4);
} else {
else
FillConstant(data + h * stride + w, stride, 0, 4, 4);
}
}
}
}
void Blur(uint8_t *data, int stride, int taps) {
int sum = 0;
@@ -149,9 +152,10 @@ class BlockinessVP9Test
BlockinessVP9Test() : BlockinessTestBase(GET_PARAM(0), GET_PARAM(1)) {}
protected:
double GetBlockiness() const {
return vp9_get_blockiness(source_data_, source_stride_, reference_data_,
reference_stride_, width_, height_);
int CheckBlockiness() {
return vp9_get_blockiness(source_data_, source_stride_,
reference_data_, reference_stride_,
width_, height_);
}
};
#endif // CONFIG_VP9_ENCODER
@@ -164,17 +168,16 @@ TEST_P(BlockinessVP9Test, SourceBlockierThanReference) {
// Source is blockier than reference.
FillRandomBlocky(source_data_, source_stride_);
FillConstant(reference_data_, reference_stride_, 128);
const double super_blocky = GetBlockiness();
int super_blocky = CheckBlockiness();
EXPECT_DOUBLE_EQ(0.0, super_blocky)
<< "Blocky source should produce 0 blockiness.";
EXPECT_EQ(0, super_blocky) << "Blocky source should produce 0 blockiness.";
}
TEST_P(BlockinessVP9Test, ReferenceBlockierThanSource) {
// Source is blockier than reference.
FillConstant(source_data_, source_stride_, 128);
FillRandomBlocky(reference_data_, reference_stride_);
const double super_blocky = GetBlockiness();
int super_blocky = CheckBlockiness();
EXPECT_GT(super_blocky, 0.0)
<< "Blocky reference should score high for blockiness.";
@@ -184,10 +187,10 @@ TEST_P(BlockinessVP9Test, BlurringDecreasesBlockiness) {
// Source is blockier than reference.
FillConstant(source_data_, source_stride_, 128);
FillRandomBlocky(reference_data_, reference_stride_);
const double super_blocky = GetBlockiness();
int super_blocky = CheckBlockiness();
Blur(reference_data_, reference_stride_, 4);
const double less_blocky = GetBlockiness();
int less_blocky = CheckBlockiness();
EXPECT_GT(super_blocky, less_blocky)
<< "A straight blur should decrease blockiness.";
@@ -198,16 +201,17 @@ TEST_P(BlockinessVP9Test, WorstCaseBlockiness) {
FillConstant(source_data_, source_stride_, 128);
FillCheckerboard(reference_data_, reference_stride_);
const double super_blocky = GetBlockiness();
int super_blocky = CheckBlockiness();
Blur(reference_data_, reference_stride_, 4);
const double less_blocky = GetBlockiness();
int less_blocky = CheckBlockiness();
EXPECT_GT(super_blocky, less_blocky)
<< "A straight blur should decrease blockiness.";
}
#endif // CONFIG_VP9_ENCODER
using std::tr1::make_tuple;
//------------------------------------------------------------------------------
@@ -215,7 +219,9 @@ using std::tr1::make_tuple;
#if CONFIG_VP9_ENCODER
const BlockinessParam c_vp9_tests[] = {
make_tuple(320, 240), make_tuple(318, 242), make_tuple(318, 238),
make_tuple(320, 240),
make_tuple(318, 242),
make_tuple(318, 238),
};
INSTANTIATE_TEST_CASE_P(C, BlockinessVP9Test, ::testing::ValuesIn(c_vp9_tests));
#endif

View File

@@ -17,8 +17,7 @@
namespace {
class BordersTest
: public ::libvpx_test::EncoderTest,
class BordersTest : public ::libvpx_test::EncoderTest,
public ::libvpx_test::CodecTestWithParam<libvpx_test::TestMode> {
protected:
BordersTest() : EncoderTest(GET_PARAM(0)) {}
@@ -53,7 +52,7 @@ TEST_P(BordersTest, TestEncodeHighBitrate) {
// extend into the border and test the border condition.
cfg_.g_lag_in_frames = 25;
cfg_.rc_2pass_vbr_minsection_pct = 5;
cfg_.rc_2pass_vbr_maxsection_pct = 2000;
cfg_.rc_2pass_vbr_minsection_pct = 2000;
cfg_.rc_target_bitrate = 2000;
cfg_.rc_max_quantizer = 10;
@@ -79,6 +78,9 @@ TEST_P(BordersTest, TestLowBitrate) {
ASSERT_NO_FATAL_FAILURE(RunLoop(&video));
}
VP9_INSTANTIATE_TEST_CASE(BordersTest,
::testing::Values(::libvpx_test::kTwoPassGood));
VP9_INSTANTIATE_TEST_CASE(BordersTest, ::testing::Values(
::libvpx_test::kTwoPassGood));
VP10_INSTANTIATE_TEST_CASE(BordersTest, ::testing::Values(
::libvpx_test::kTwoPassGood));
} // namespace

View File

@@ -21,14 +21,14 @@
namespace {
#if CONFIG_WEBM_IO
const int kLegacyByteAlignment = 0;
const int kLegacyYPlaneByteAlignment = 32;
const int kNumPlanesToCheck = 3;
const char kVP9TestFile[] = "vp90-2-02-size-lf-1920x1080.webm";
const char kVP9Md5File[] = "vp90-2-02-size-lf-1920x1080.webm.md5";
#if CONFIG_WEBM_IO
struct ByteAlignmentTestParam {
int byte_alignment;
vpx_codec_err_t expected_value;
@@ -55,7 +55,10 @@ const ByteAlignmentTestParam kBaTestParams[] = {
class ByteAlignmentTest
: public ::testing::TestWithParam<ByteAlignmentTestParam> {
protected:
ByteAlignmentTest() : video_(NULL), decoder_(NULL), md5_file_(NULL) {}
ByteAlignmentTest()
: video_(NULL),
decoder_(NULL),
md5_file_(NULL) {}
virtual void SetUp() {
video_ = new libvpx_test::WebMVideoSource(kVP9TestFile);
@@ -71,7 +74,8 @@ class ByteAlignmentTest
}
virtual void TearDown() {
if (md5_file_ != NULL) fclose(md5_file_);
if (md5_file_ != NULL)
fclose(md5_file_);
delete decoder_;
delete video_;
@@ -85,7 +89,8 @@ class ByteAlignmentTest
const vpx_codec_err_t res =
decoder_->DecodeFrame(video_->cxdata(), video_->frame_size());
CheckDecodedFrames(byte_alignment_to_check);
if (res == VPX_CODEC_OK) video_->Next();
if (res == VPX_CODEC_OK)
video_->Next();
return res;
}
@@ -93,7 +98,8 @@ class ByteAlignmentTest
for (; video_->cxdata() != NULL; video_->Next()) {
const vpx_codec_err_t res =
decoder_->DecodeFrame(video_->cxdata(), video_->frame_size());
if (res != VPX_CODEC_OK) return res;
if (res != VPX_CODEC_OK)
return res;
CheckDecodedFrames(byte_alignment_to_check);
}
return VPX_CODEC_OK;

View File

@@ -13,10 +13,10 @@
#include "./vpx_config.h"
#include "vpx/vpx_decoder.h"
#include "vpx/vpx_encoder.h"
#if CONFIG_VP8_ENCODER || CONFIG_VP9_ENCODER
#if CONFIG_VP8_ENCODER || CONFIG_VP9_ENCODER || CONFIG_VP10_ENCODER
#include "vpx/vp8cx.h"
#endif
#if CONFIG_VP8_DECODER || CONFIG_VP9_DECODER
#if CONFIG_VP8_DECODER || CONFIG_VP9_DECODER || CONFIG_VP10_DECODER
#include "vpx/vp8dx.h"
#endif
@@ -32,10 +32,13 @@ class CodecFactory {
virtual ~CodecFactory() {}
virtual Decoder *CreateDecoder(vpx_codec_dec_cfg_t cfg) const = 0;
virtual Decoder* CreateDecoder(vpx_codec_dec_cfg_t cfg,
unsigned long deadline) const = 0;
virtual Decoder* CreateDecoder(vpx_codec_dec_cfg_t cfg,
const vpx_codec_flags_t flags) const = 0;
const vpx_codec_flags_t flags,
unsigned long deadline) // NOLINT(runtime/int)
const = 0;
virtual Encoder* CreateEncoder(vpx_codec_enc_cfg_t cfg,
unsigned long deadline,
@@ -51,19 +54,19 @@ class CodecFactory {
* definition.
*/
template<class T1>
class CodecTestWithParam
: public ::testing::TestWithParam<
std::tr1::tuple<const libvpx_test::CodecFactory *, T1> > {};
class CodecTestWithParam : public ::testing::TestWithParam<
std::tr1::tuple< const libvpx_test::CodecFactory*, T1 > > {
};
template<class T1, class T2>
class CodecTestWith2Params
: public ::testing::TestWithParam<
std::tr1::tuple<const libvpx_test::CodecFactory *, T1, T2> > {};
class CodecTestWith2Params : public ::testing::TestWithParam<
std::tr1::tuple< const libvpx_test::CodecFactory*, T1, T2 > > {
};
template<class T1, class T2, class T3>
class CodecTestWith3Params
: public ::testing::TestWithParam<
std::tr1::tuple<const libvpx_test::CodecFactory *, T1, T2, T3> > {};
class CodecTestWith3Params : public ::testing::TestWithParam<
std::tr1::tuple< const libvpx_test::CodecFactory*, T1, T2, T3 > > {
};
/*
* VP8 Codec Definitions
@@ -71,10 +74,12 @@ class CodecTestWith3Params
#if CONFIG_VP8
class VP8Decoder : public Decoder {
public:
explicit VP8Decoder(vpx_codec_dec_cfg_t cfg) : Decoder(cfg) {}
VP8Decoder(vpx_codec_dec_cfg_t cfg, unsigned long deadline)
: Decoder(cfg, deadline) {}
VP8Decoder(vpx_codec_dec_cfg_t cfg, const vpx_codec_flags_t flag)
: Decoder(cfg, flag) {}
VP8Decoder(vpx_codec_dec_cfg_t cfg, const vpx_codec_flags_t flag,
unsigned long deadline) // NOLINT
: Decoder(cfg, flag, deadline) {}
protected:
virtual vpx_codec_iface_t* CodecInterface() const {
@@ -106,14 +111,16 @@ class VP8CodecFactory : public CodecFactory {
public:
VP8CodecFactory() : CodecFactory() {}
virtual Decoder *CreateDecoder(vpx_codec_dec_cfg_t cfg) const {
return CreateDecoder(cfg, 0);
virtual Decoder* CreateDecoder(vpx_codec_dec_cfg_t cfg,
unsigned long deadline) const {
return CreateDecoder(cfg, 0, deadline);
}
virtual Decoder* CreateDecoder(vpx_codec_dec_cfg_t cfg,
const vpx_codec_flags_t flags) const {
const vpx_codec_flags_t flags,
unsigned long deadline) const { // NOLINT
#if CONFIG_VP8_DECODER
return new VP8Decoder(cfg, flags);
return new VP8Decoder(cfg, flags, deadline);
#else
return NULL;
#endif
@@ -143,8 +150,7 @@ class VP8CodecFactory : public CodecFactory {
const libvpx_test::VP8CodecFactory kVP8;
#define VP8_INSTANTIATE_TEST_CASE(test, ...)\
INSTANTIATE_TEST_CASE_P( \
VP8, test, \
INSTANTIATE_TEST_CASE_P(VP8, test, \
::testing::Combine( \
::testing::Values(static_cast<const libvpx_test::CodecFactory*>( \
&libvpx_test::kVP8)), \
@@ -153,16 +159,19 @@ const libvpx_test::VP8CodecFactory kVP8;
#define VP8_INSTANTIATE_TEST_CASE(test, ...)
#endif // CONFIG_VP8
/*
* VP9 Codec Definitions
*/
#if CONFIG_VP9
class VP9Decoder : public Decoder {
public:
explicit VP9Decoder(vpx_codec_dec_cfg_t cfg) : Decoder(cfg) {}
VP9Decoder(vpx_codec_dec_cfg_t cfg, unsigned long deadline)
: Decoder(cfg, deadline) {}
VP9Decoder(vpx_codec_dec_cfg_t cfg, const vpx_codec_flags_t flag)
: Decoder(cfg, flag) {}
VP9Decoder(vpx_codec_dec_cfg_t cfg, const vpx_codec_flags_t flag,
unsigned long deadline) // NOLINT
: Decoder(cfg, flag, deadline) {}
protected:
virtual vpx_codec_iface_t* CodecInterface() const {
@@ -194,14 +203,16 @@ class VP9CodecFactory : public CodecFactory {
public:
VP9CodecFactory() : CodecFactory() {}
virtual Decoder *CreateDecoder(vpx_codec_dec_cfg_t cfg) const {
return CreateDecoder(cfg, 0);
virtual Decoder* CreateDecoder(vpx_codec_dec_cfg_t cfg,
unsigned long deadline) const {
return CreateDecoder(cfg, 0, deadline);
}
virtual Decoder* CreateDecoder(vpx_codec_dec_cfg_t cfg,
const vpx_codec_flags_t flags) const {
const vpx_codec_flags_t flags,
unsigned long deadline) const { // NOLINT
#if CONFIG_VP9_DECODER
return new VP9Decoder(cfg, flags);
return new VP9Decoder(cfg, flags, deadline);
#else
return NULL;
#endif
@@ -222,6 +233,8 @@ class VP9CodecFactory : public CodecFactory {
int usage) const {
#if CONFIG_VP9_ENCODER
return vpx_codec_enc_config_default(&vpx_codec_vp9_cx_algo, cfg, usage);
#elif CONFIG_VP10_ENCODER
return vpx_codec_enc_config_default(&vpx_codec_vp10_cx_algo, cfg, usage);
#else
return VPX_CODEC_INCAPABLE;
#endif
@@ -231,8 +244,7 @@ class VP9CodecFactory : public CodecFactory {
const libvpx_test::VP9CodecFactory kVP9;
#define VP9_INSTANTIATE_TEST_CASE(test, ...)\
INSTANTIATE_TEST_CASE_P( \
VP9, test, \
INSTANTIATE_TEST_CASE_P(VP9, test, \
::testing::Combine( \
::testing::Values(static_cast<const libvpx_test::CodecFactory*>( \
&libvpx_test::kVP9)), \
@@ -241,5 +253,96 @@ const libvpx_test::VP9CodecFactory kVP9;
#define VP9_INSTANTIATE_TEST_CASE(test, ...)
#endif // CONFIG_VP9
/*
* VP10 Codec Definitions
*/
#if CONFIG_VP10
class VP10Decoder : public Decoder {
public:
VP10Decoder(vpx_codec_dec_cfg_t cfg, unsigned long deadline)
: Decoder(cfg, deadline) {}
VP10Decoder(vpx_codec_dec_cfg_t cfg, const vpx_codec_flags_t flag,
unsigned long deadline) // NOLINT
: Decoder(cfg, flag, deadline) {}
protected:
virtual vpx_codec_iface_t* CodecInterface() const {
#if CONFIG_VP10_DECODER
return &vpx_codec_vp10_dx_algo;
#else
return NULL;
#endif
}
};
class VP10Encoder : public Encoder {
public:
VP10Encoder(vpx_codec_enc_cfg_t cfg, unsigned long deadline,
const unsigned long init_flags, TwopassStatsStore *stats)
: Encoder(cfg, deadline, init_flags, stats) {}
protected:
virtual vpx_codec_iface_t* CodecInterface() const {
#if CONFIG_VP10_ENCODER
return &vpx_codec_vp10_cx_algo;
#else
return NULL;
#endif
}
};
class VP10CodecFactory : public CodecFactory {
public:
VP10CodecFactory() : CodecFactory() {}
virtual Decoder* CreateDecoder(vpx_codec_dec_cfg_t cfg,
unsigned long deadline) const {
return CreateDecoder(cfg, 0, deadline);
}
virtual Decoder* CreateDecoder(vpx_codec_dec_cfg_t cfg,
const vpx_codec_flags_t flags,
unsigned long deadline) const { // NOLINT
#if CONFIG_VP10_DECODER
return new VP10Decoder(cfg, flags, deadline);
#else
return NULL;
#endif
}
virtual Encoder* CreateEncoder(vpx_codec_enc_cfg_t cfg,
unsigned long deadline,
const unsigned long init_flags,
TwopassStatsStore *stats) const {
#if CONFIG_VP10_ENCODER
return new VP10Encoder(cfg, deadline, init_flags, stats);
#else
return NULL;
#endif
}
virtual vpx_codec_err_t DefaultEncoderConfig(vpx_codec_enc_cfg_t *cfg,
int usage) const {
#if CONFIG_VP10_ENCODER
return vpx_codec_enc_config_default(&vpx_codec_vp10_cx_algo, cfg, usage);
#else
return VPX_CODEC_INCAPABLE;
#endif
}
};
const libvpx_test::VP10CodecFactory kVP10;
#define VP10_INSTANTIATE_TEST_CASE(test, ...)\
INSTANTIATE_TEST_CASE_P(VP10, test, \
::testing::Combine( \
::testing::Values(static_cast<const libvpx_test::CodecFactory*>( \
&libvpx_test::kVP10)), \
__VA_ARGS__))
#else
#define VP10_INSTANTIATE_TEST_CASE(test, ...)
#endif // CONFIG_VP10
} // namespace libvpx_test
#endif // TEST_CODEC_FACTORY_H_

View File

@@ -15,13 +15,11 @@
namespace {
class ConfigTest
: public ::libvpx_test::EncoderTest,
class ConfigTest : public ::libvpx_test::EncoderTest,
public ::libvpx_test::CodecTestWithParam<libvpx_test::TestMode> {
protected:
ConfigTest()
: EncoderTest(GET_PARAM(0)), frame_count_in_(0), frame_count_out_(0),
frame_count_max_(0) {}
ConfigTest() : EncoderTest(GET_PARAM(0)),
frame_count_in_(0), frame_count_out_(0), frame_count_max_(0) {}
virtual ~ConfigTest() {}
virtual void SetUp() {

View File

@@ -26,9 +26,11 @@
#include "vpx_dsp/ssim.h"
#include "vpx_mem/vpx_mem.h"
extern "C" double vpx_get_ssim_metrics(uint8_t *img1, int img1_pitch,
uint8_t *img2, int img2_pitch, int width,
int height, Ssimv *sv2, Metrics *m,
extern "C"
double vpx_get_ssim_metrics(uint8_t *img1, int img1_pitch,
uint8_t *img2, int img2_pitch,
int width, int height,
Ssimv *sv2, Metrics *m,
int do_inconsistency);
using libvpx_test::ACMRandom;
@@ -50,7 +52,9 @@ class ConsistencyTestBase : public ::testing::Test {
ssim_array_ = new Ssimv[kDataBufferSize / 16];
}
static void ClearSsim() { memset(ssim_array_, 0, kDataBufferSize / 16); }
static void ClearSsim() {
memset(ssim_array_, 0, kDataBufferSize / 16);
}
static void TearDownTestCase() {
vpx_free(source_data_[0]);
source_data_[0] = NULL;
@@ -64,7 +68,9 @@ class ConsistencyTestBase : public ::testing::Test {
delete[] ssim_array_;
}
virtual void TearDown() { libvpx_test::ClearSystemState(); }
virtual void TearDown() {
libvpx_test::ClearSystemState();
}
protected:
// Handle frames up to 640x480
@@ -137,7 +143,8 @@ class ConsistencyVP9Test
protected:
double CheckConsistency(int frame) {
EXPECT_LT(frame, 2)<< "Frame to check has to be less than 2.";
return vpx_get_ssim_metrics(source_data_[frame], source_stride_,
return
vpx_get_ssim_metrics(source_data_[frame], source_stride_,
reference_data_[frame], reference_stride_,
width_, height_, ssim_array_, &metrics_, 1);
}
@@ -198,6 +205,7 @@ TEST_P(ConsistencyVP9Test, ConsistencyIsZero) {
}
#endif // CONFIG_VP9_ENCODER
using std::tr1::make_tuple;
//------------------------------------------------------------------------------
@@ -205,7 +213,9 @@ using std::tr1::make_tuple;
#if CONFIG_VP9_ENCODER
const ConsistencyParam c_vp9_tests[] = {
make_tuple(320, 240), make_tuple(318, 242), make_tuple(318, 238),
make_tuple(320, 240),
make_tuple(318, 242),
make_tuple(318, 238),
};
INSTANTIATE_TEST_CASE_P(C, ConsistencyVP9Test,
::testing::ValuesIn(c_vp9_tests));

File diff suppressed because it is too large Load Diff

View File

@@ -23,9 +23,10 @@ class CpuSpeedTest
public ::libvpx_test::CodecTestWith2Params<libvpx_test::TestMode, int> {
protected:
CpuSpeedTest()
: EncoderTest(GET_PARAM(0)), encoding_mode_(GET_PARAM(1)),
set_cpu_used_(GET_PARAM(2)), min_psnr_(kMaxPSNR),
tune_content_(VP9E_CONTENT_DEFAULT) {}
: EncoderTest(GET_PARAM(0)),
encoding_mode_(GET_PARAM(1)),
set_cpu_used_(GET_PARAM(2)),
min_psnr_(kMaxPSNR) {}
virtual ~CpuSpeedTest() {}
virtual void SetUp() {
@@ -40,13 +41,14 @@ class CpuSpeedTest
}
}
virtual void BeginPassHook(unsigned int /*pass*/) { min_psnr_ = kMaxPSNR; }
virtual void BeginPassHook(unsigned int /*pass*/) {
min_psnr_ = kMaxPSNR;
}
virtual void PreEncodeFrameHook(::libvpx_test::VideoSource *video,
::libvpx_test::Encoder *encoder) {
if (video->frame() == 1) {
encoder->Control(VP8E_SET_CPUUSED, set_cpu_used_);
encoder->Control(VP9E_SET_TUNE_CONTENT, tune_content_);
if (encoding_mode_ != ::libvpx_test::kRealTime) {
encoder->Control(VP8E_SET_ENABLEAUTOALTREF, 1);
encoder->Control(VP8E_SET_ARNR_MAXFRAMES, 7);
@@ -57,13 +59,13 @@ class CpuSpeedTest
}
virtual void PSNRPktHook(const vpx_codec_cx_pkt_t *pkt) {
if (pkt->data.psnr.psnr[0] < min_psnr_) min_psnr_ = pkt->data.psnr.psnr[0];
if (pkt->data.psnr.psnr[0] < min_psnr_)
min_psnr_ = pkt->data.psnr.psnr[0];
}
::libvpx_test::TestMode encoding_mode_;
int set_cpu_used_;
double min_psnr_;
int tune_content_;
};
TEST_P(CpuSpeedTest, TestQ0) {
@@ -72,7 +74,7 @@ TEST_P(CpuSpeedTest, TestQ0) {
// the encoder to producing lots of big partitions which will likely
// extend into the border and test the border condition.
cfg_.rc_2pass_vbr_minsection_pct = 5;
cfg_.rc_2pass_vbr_maxsection_pct = 2000;
cfg_.rc_2pass_vbr_minsection_pct = 2000;
cfg_.rc_target_bitrate = 400;
cfg_.rc_max_quantizer = 0;
cfg_.rc_min_quantizer = 0;
@@ -90,7 +92,7 @@ TEST_P(CpuSpeedTest, TestScreencastQ0) {
::libvpx_test::Y4mVideoSource video("screendata.y4m", 0, 25);
cfg_.g_timebase = video.timebase();
cfg_.rc_2pass_vbr_minsection_pct = 5;
cfg_.rc_2pass_vbr_maxsection_pct = 2000;
cfg_.rc_2pass_vbr_minsection_pct = 2000;
cfg_.rc_target_bitrate = 400;
cfg_.rc_max_quantizer = 0;
cfg_.rc_min_quantizer = 0;
@@ -101,28 +103,13 @@ TEST_P(CpuSpeedTest, TestScreencastQ0) {
EXPECT_GE(min_psnr_, kMaxPSNR);
}
TEST_P(CpuSpeedTest, TestTuneScreen) {
::libvpx_test::Y4mVideoSource video("screendata.y4m", 0, 25);
cfg_.g_timebase = video.timebase();
cfg_.rc_2pass_vbr_minsection_pct = 5;
cfg_.rc_2pass_vbr_minsection_pct = 2000;
cfg_.rc_target_bitrate = 2000;
cfg_.rc_max_quantizer = 63;
cfg_.rc_min_quantizer = 0;
tune_content_ = VP9E_CONTENT_SCREEN;
init_flags_ = VPX_CODEC_USE_PSNR;
ASSERT_NO_FATAL_FAILURE(RunLoop(&video));
}
TEST_P(CpuSpeedTest, TestEncodeHighBitrate) {
// Validate that this non multiple of 64 wide clip encodes and decodes
// without a mismatch when passing in a very low max q. This pushes
// the encoder to producing lots of big partitions which will likely
// extend into the border and test the border condition.
cfg_.rc_2pass_vbr_minsection_pct = 5;
cfg_.rc_2pass_vbr_maxsection_pct = 2000;
cfg_.rc_2pass_vbr_minsection_pct = 2000;
cfg_.rc_target_bitrate = 12000;
cfg_.rc_max_quantizer = 10;
cfg_.rc_min_quantizer = 0;
@@ -138,7 +125,7 @@ TEST_P(CpuSpeedTest, TestLowBitrate) {
// when passing in a very high min q. This pushes the encoder to producing
// lots of small partitions which might will test the other condition.
cfg_.rc_2pass_vbr_minsection_pct = 5;
cfg_.rc_2pass_vbr_maxsection_pct = 2000;
cfg_.rc_2pass_vbr_minsection_pct = 2000;
cfg_.rc_target_bitrate = 200;
cfg_.rc_min_quantizer = 40;
@@ -148,9 +135,14 @@ TEST_P(CpuSpeedTest, TestLowBitrate) {
ASSERT_NO_FATAL_FAILURE(RunLoop(&video));
}
VP9_INSTANTIATE_TEST_CASE(CpuSpeedTest,
::testing::Values(::libvpx_test::kTwoPassGood,
::libvpx_test::kOnePassGood,
VP9_INSTANTIATE_TEST_CASE(
CpuSpeedTest,
::testing::Values(::libvpx_test::kTwoPassGood, ::libvpx_test::kOnePassGood,
::libvpx_test::kRealTime),
::testing::Range(0, 9));
VP10_INSTANTIATE_TEST_CASE(
CpuSpeedTest,
::testing::Values(::libvpx_test::kTwoPassGood, ::libvpx_test::kOnePassGood),
::testing::Range(0, 3));
} // namespace

View File

@@ -29,7 +29,9 @@ class CQTest : public ::libvpx_test::EncoderTest,
// maps the cqlevel to the bitrate produced.
typedef std::map<int, uint32_t> BitrateMap;
static void SetUpTestCase() { bitrates_.clear(); }
static void SetUpTestCase() {
bitrates_.clear();
}
static void TearDownTestCase() {
ASSERT_TRUE(!HasFailure())
@@ -126,6 +128,7 @@ TEST_P(CQTest, LinearPSNRIsHigherForCQLevel) {
EXPECT_GE(cq_psnr_lin, vbr_psnr_lin);
}
VP8_INSTANTIATE_TEST_CASE(CQTest, ::testing::Range(kCQLevelMin, kCQLevelMax,
VP8_INSTANTIATE_TEST_CASE(CQTest,
::testing::Range(kCQLevelMin, kCQLevelMax,
kCQLevelStep));
} // namespace

View File

@@ -18,8 +18,7 @@
namespace {
class DatarateTestLarge
: public ::libvpx_test::EncoderTest,
class DatarateTestLarge : public ::libvpx_test::EncoderTest,
public ::libvpx_test::CodecTestWithParam<libvpx_test::TestMode> {
public:
DatarateTestLarge() : EncoderTest(GET_PARAM(0)) {}
@@ -46,9 +45,8 @@ class DatarateTestLarge
virtual void PreEncodeFrameHook(::libvpx_test::VideoSource *video,
::libvpx_test::Encoder *encoder) {
if (video->frame() == 0) {
if (video->frame() == 0)
encoder->Control(VP8E_SET_NOISE_SENSITIVITY, denoiser_on_);
}
if (denoiser_offon_test_) {
ASSERT_GT(denoiser_offon_period_, 0)
@@ -73,7 +71,8 @@ class DatarateTestLarge
// http://code.google.com/p/webm/issues/detail?id=496 is fixed.
// For now the codec assumes buffer starts at starting buffer rate
// plus one frame's time.
if (last_pts_ == 0) duration = 1;
if (last_pts_ == 0)
duration = 1;
// Add to the buffer the bits we'd expect from a constant bitrate server.
bits_in_buffer_model_ += static_cast<int64_t>(
@@ -84,14 +83,14 @@ class DatarateTestLarge
* empty - and then stop showing frames until we've got enough bits to
* show one. As noted in comment below (issue 495), this does not currently
* apply to key frames. For now exclude key frames in condition below. */
const bool key_frame =
(pkt->data.frame.flags & VPX_FRAME_IS_KEY) ? true : false;
const bool key_frame = (pkt->data.frame.flags & VPX_FRAME_IS_KEY)
? true: false;
if (!key_frame) {
ASSERT_GE(bits_in_buffer_model_, 0) << "Buffer Underrun at frame "
<< pkt->data.frame.pts;
}
const int64_t frame_size_in_bits = pkt->data.frame.sz * 8;
const size_t frame_size_in_bits = pkt->data.frame.sz * 8;
// Subtract from the buffer the bits associated with a played back frame.
bits_in_buffer_model_ -= frame_size_in_bits;
@@ -100,7 +99,8 @@ class DatarateTestLarge
bits_total_ += frame_size_in_bits;
// If first drop not set and we have a drop set it to this time.
if (!first_drop_ && duration > 1) first_drop_ = last_pts_ + 1;
if (!first_drop_ && duration > 1)
first_drop_ = last_pts_ + 1;
// Update the most recent pts.
last_pts_ = pkt->data.frame.pts;
@@ -119,8 +119,8 @@ class DatarateTestLarge
duration_ = (last_pts_ + 1) * timebase_;
// Effective file datarate includes the time spent prebuffering.
effective_datarate_ = (bits_total_ - bits_in_last_frame_) / 1000.0 /
(cfg_.rc_buf_initial_sz / 1000.0 + duration_);
effective_datarate_ = (bits_total_ - bits_in_last_frame_) / 1000.0
/ (cfg_.rc_buf_initial_sz / 1000.0 + duration_);
file_datarate_ = file_size_in_kb / duration_;
}
@@ -135,7 +135,7 @@ class DatarateTestLarge
double duration_;
double file_datarate_;
double effective_datarate_;
int64_t bits_in_last_frame_;
size_t bits_in_last_frame_;
int denoiser_on_;
int denoiser_offon_test_;
int denoiser_offon_period_;
@@ -256,8 +256,7 @@ TEST_P(DatarateTestLarge, ChangingDropFrameThresh) {
}
}
class DatarateTestVP9Large
: public ::libvpx_test::EncoderTest,
class DatarateTestVP9Large : public ::libvpx_test::EncoderTest,
public ::libvpx_test::CodecTestWith2Params<libvpx_test::TestMode, int> {
public:
DatarateTestVP9Large() : EncoderTest(GET_PARAM(0)) {}
@@ -308,8 +307,8 @@ class DatarateTestVP9Large
if (num_temp_layers == 2) {
if (frame_num % 2 == 0) {
// Layer 0: predict from L and ARF, update L.
frame_flags =
VP8_EFLAG_NO_REF_GF | VP8_EFLAG_NO_UPD_GF | VP8_EFLAG_NO_UPD_ARF;
frame_flags = VP8_EFLAG_NO_REF_GF | VP8_EFLAG_NO_UPD_GF |
VP8_EFLAG_NO_UPD_ARF;
} else {
// Layer 1: predict from L, G and ARF, and update G.
frame_flags = VP8_EFLAG_NO_UPD_ARF | VP8_EFLAG_NO_UPD_LAST |
@@ -318,15 +317,15 @@ class DatarateTestVP9Large
} else if (num_temp_layers == 3) {
if (frame_num % 4 == 0) {
// Layer 0: predict from L and ARF; update L.
frame_flags =
VP8_EFLAG_NO_UPD_GF | VP8_EFLAG_NO_UPD_ARF | VP8_EFLAG_NO_REF_GF;
frame_flags = VP8_EFLAG_NO_UPD_GF | VP8_EFLAG_NO_UPD_ARF |
VP8_EFLAG_NO_REF_GF;
} else if ((frame_num - 2) % 4 == 0) {
// Layer 1: predict from L, G, ARF; update G.
frame_flags = VP8_EFLAG_NO_UPD_ARF | VP8_EFLAG_NO_UPD_LAST;
} else if ((frame_num - 1) % 2 == 0) {
// Layer 2: predict from L, G, ARF; update none.
frame_flags =
VP8_EFLAG_NO_UPD_GF | VP8_EFLAG_NO_UPD_ARF | VP8_EFLAG_NO_UPD_LAST;
frame_flags = VP8_EFLAG_NO_UPD_GF | VP8_EFLAG_NO_UPD_ARF |
VP8_EFLAG_NO_UPD_LAST;
}
}
return frame_flags;
@@ -354,7 +353,8 @@ class DatarateTestVP9Large
virtual void PreEncodeFrameHook(::libvpx_test::VideoSource *video,
::libvpx_test::Encoder *encoder) {
if (video->frame() == 0) encoder->Control(VP8E_SET_CPUUSED, set_cpu_used_);
if (video->frame() == 0)
encoder->Control(VP8E_SET_CPUUSED, set_cpu_used_);
if (denoiser_offon_test_) {
ASSERT_GT(denoiser_offon_period_, 0)
@@ -374,8 +374,8 @@ class DatarateTestVP9Large
vpx_svc_layer_id_t layer_id;
layer_id.spatial_layer_id = 0;
frame_flags_ = SetFrameFlags(video->frame(), cfg_.ts_number_layers);
layer_id.temporal_layer_id =
SetLayerId(video->frame(), cfg_.ts_number_layers);
layer_id.temporal_layer_id = SetLayerId(video->frame(),
cfg_.ts_number_layers);
encoder->Control(VP9E_SET_SVC_LAYER_ID, &layer_id);
}
const vpx_rational_t tb = video->timebase();
@@ -383,13 +383,15 @@ class DatarateTestVP9Large
duration_ = 0;
}
virtual void FramePktHook(const vpx_codec_cx_pkt_t *pkt) {
// Time since last timestamp = duration.
vpx_codec_pts_t duration = pkt->data.frame.pts - last_pts_;
if (duration > 1) {
// If first drop not set and we have a drop set it to this time.
if (!first_drop_) first_drop_ = last_pts_ + 1;
if (!first_drop_)
first_drop_ = last_pts_ + 1;
// Update the number of frame drops.
num_drops_ += static_cast<int>(duration - 1);
// Update counter for total number of frames (#frames input to encoder).
@@ -448,55 +450,7 @@ class DatarateTestVP9Large
int denoiser_offon_period_;
};
// Check basic rate targeting for VBR mode with 0 lag.
TEST_P(DatarateTestVP9Large, BasicRateTargetingVBRLagZero) {
cfg_.rc_min_quantizer = 0;
cfg_.rc_max_quantizer = 63;
cfg_.g_error_resilient = 0;
cfg_.rc_end_usage = VPX_VBR;
cfg_.g_lag_in_frames = 0;
::libvpx_test::I420VideoSource video("hantro_collage_w352h288.yuv", 352, 288,
30, 1, 0, 300);
for (int i = 400; i <= 800; i += 400) {
cfg_.rc_target_bitrate = i;
ResetModel();
ASSERT_NO_FATAL_FAILURE(RunLoop(&video));
ASSERT_GE(effective_datarate_[0], cfg_.rc_target_bitrate * 0.75)
<< " The datarate for the file is lower than target by too much!";
ASSERT_LE(effective_datarate_[0], cfg_.rc_target_bitrate * 1.25)
<< " The datarate for the file is greater than target by too much!";
}
}
// Check basic rate targeting for VBR mode with non-zero lag.
TEST_P(DatarateTestVP9Large, BasicRateTargetingVBRLagNonZero) {
cfg_.rc_min_quantizer = 0;
cfg_.rc_max_quantizer = 63;
cfg_.g_error_resilient = 0;
cfg_.rc_end_usage = VPX_VBR;
// For non-zero lag, rate control will work (be within bounds) for
// real-time mode.
if (deadline_ == VPX_DL_REALTIME) {
cfg_.g_lag_in_frames = 15;
} else {
cfg_.g_lag_in_frames = 0;
}
::libvpx_test::I420VideoSource video("hantro_collage_w352h288.yuv", 352, 288,
30, 1, 0, 300);
for (int i = 400; i <= 800; i += 400) {
cfg_.rc_target_bitrate = i;
ResetModel();
ASSERT_NO_FATAL_FAILURE(RunLoop(&video));
ASSERT_GE(effective_datarate_[0], cfg_.rc_target_bitrate * 0.75)
<< " The datarate for the file is lower than target by too much!";
ASSERT_LE(effective_datarate_[0], cfg_.rc_target_bitrate * 1.25)
<< " The datarate for the file is greater than target by too much!";
}
}
// Check basic rate targeting for CBR mode.
// Check basic rate targeting,
TEST_P(DatarateTestVP9Large, BasicRateTargeting) {
cfg_.rc_buf_initial_sz = 500;
cfg_.rc_buf_optimal_sz = 500;
@@ -520,7 +474,7 @@ TEST_P(DatarateTestVP9Large, BasicRateTargeting) {
}
}
// Check basic rate targeting for CBR.
// Check basic rate targeting,
TEST_P(DatarateTestVP9Large, BasicRateTargeting444) {
::libvpx_test::Y4mVideoSource video("rush_hour_444.y4m", 0, 140);
@@ -565,9 +519,6 @@ TEST_P(DatarateTestVP9Large, ChangingDropFrameThresh) {
cfg_.rc_end_usage = VPX_CBR;
cfg_.rc_target_bitrate = 200;
cfg_.g_lag_in_frames = 0;
// TODO(marpan): Investigate datarate target failures with a smaller keyframe
// interval (128).
cfg_.kf_max_dist = 9999;
::libvpx_test::I420VideoSource video("hantro_collage_w352h288.yuv", 352, 288,
30, 1, 0, 140);
@@ -587,7 +538,7 @@ TEST_P(DatarateTestVP9Large, ChangingDropFrameThresh) {
<< " The first dropped frame for drop_thresh " << i
<< " > first dropped frame for drop_thresh "
<< i - kDropFrameThreshTestStep;
ASSERT_GE(num_drops_, last_num_drops * 0.85)
ASSERT_GE(num_drops_, last_num_drops * 0.90)
<< " The number of dropped frames for drop_thresh " << i
<< " < number of dropped frames for drop_thresh "
<< i - kDropFrameThreshTestStep;
@@ -615,7 +566,8 @@ TEST_P(DatarateTestVP9Large, BasicRateTargeting2TemporalLayers) {
cfg_.temporal_layering_mode = VP9E_TEMPORAL_LAYERING_MODE_BYPASS;
if (deadline_ == VPX_DL_REALTIME) cfg_.g_error_resilient = 1;
if (deadline_ == VPX_DL_REALTIME)
cfg_.g_error_resilient = 1;
::libvpx_test::I420VideoSource video("hantro_collage_w352h288.yuv", 352, 288,
30, 1, 0, 200);
@@ -629,12 +581,10 @@ TEST_P(DatarateTestVP9Large, BasicRateTargeting2TemporalLayers) {
for (int j = 0; j < static_cast<int>(cfg_.ts_number_layers); ++j) {
ASSERT_GE(effective_datarate_[j], cfg_.layer_target_bitrate[j] * 0.85)
<< " The datarate for the file is lower than target by too much, "
"for layer: "
<< j;
"for layer: " << j;
ASSERT_LE(effective_datarate_[j], cfg_.layer_target_bitrate[j] * 1.15)
<< " The datarate for the file is greater than target by too much, "
"for layer: "
<< j;
"for layer: " << j;
}
}
}
@@ -674,14 +624,12 @@ TEST_P(DatarateTestVP9Large, BasicRateTargeting3TemporalLayers) {
// Adjust the thresholds to be tighter than .75.
ASSERT_GE(effective_datarate_[j], cfg_.layer_target_bitrate[j] * 0.75)
<< " The datarate for the file is lower than target by too much, "
"for layer: "
<< j;
"for layer: " << j;
// TODO(yaowu): Work out more stable rc control strategy and
// Adjust the thresholds to be tighter than 1.25.
ASSERT_LE(effective_datarate_[j], cfg_.layer_target_bitrate[j] * 1.25)
<< " The datarate for the file is greater than target by too much, "
"for layer: "
<< j;
"for layer: " << j;
}
}
}
@@ -721,12 +669,10 @@ TEST_P(DatarateTestVP9Large, BasicRateTargeting3TemporalLayersFrameDropping) {
for (int j = 0; j < static_cast<int>(cfg_.ts_number_layers); ++j) {
ASSERT_GE(effective_datarate_[j], cfg_.layer_target_bitrate[j] * 0.85)
<< " The datarate for the file is lower than target by too much, "
"for layer: "
<< j;
"for layer: " << j;
ASSERT_LE(effective_datarate_[j], cfg_.layer_target_bitrate[j] * 1.15)
<< " The datarate for the file is greater than target by too much, "
"for layer: "
<< j;
"for layer: " << j;
// Expect some frame drops in this test: for this 200 frames test,
// expect at least 10% and not more than 60% drops.
ASSERT_GE(num_drops_, 20);
@@ -796,15 +742,11 @@ TEST_P(DatarateTestVP9Large, DenoiserOffOn) {
}
#endif // CONFIG_VP9_TEMPORAL_DENOISING
class DatarateOnePassCbrSvc
: public ::libvpx_test::EncoderTest,
class DatarateOnePassCbrSvc : public ::libvpx_test::EncoderTest,
public ::libvpx_test::CodecTestWith2Params<libvpx_test::TestMode, int> {
public:
DatarateOnePassCbrSvc() : EncoderTest(GET_PARAM(0)) {
memset(&svc_params_, 0, sizeof(svc_params_));
}
DatarateOnePassCbrSvc() : EncoderTest(GET_PARAM(0)) {}
virtual ~DatarateOnePassCbrSvc() {}
protected:
virtual void SetUp() {
InitializeConfig();
@@ -822,19 +764,20 @@ class DatarateOnePassCbrSvc
mismatch_psnr_ = 0.0;
mismatch_nframes_ = 0;
}
virtual void BeginPassHook(unsigned int /*pass*/) {}
virtual void BeginPassHook(unsigned int /*pass*/) {
}
virtual void PreEncodeFrameHook(::libvpx_test::VideoSource *video,
::libvpx_test::Encoder *encoder) {
if (video->frame() == 0) {
int i;
for (i = 0; i < VPX_MAX_LAYERS; ++i) {
for (i = 0; i < 2; ++i) {
svc_params_.max_quantizers[i] = 63;
svc_params_.min_quantizers[i] = 0;
}
svc_params_.speed_per_layer[0] = 5;
for (i = 1; i < VPX_SS_MAX_LAYERS; ++i) {
svc_params_.speed_per_layer[i] = 7;
}
svc_params_.scaling_factor_num[0] = 144;
svc_params_.scaling_factor_den[0] = 288;
svc_params_.scaling_factor_num[1] = 288;
svc_params_.scaling_factor_den[1] = 288;
encoder->Control(VP9E_SET_SVC, 1);
encoder->Control(VP9E_SET_SVC_PARAMETERS, &svc_params_);
encoder->Control(VP8E_SET_CPUUSED, speed_setting_);
@@ -848,11 +791,12 @@ class DatarateOnePassCbrSvc
}
virtual void FramePktHook(const vpx_codec_cx_pkt_t *pkt) {
vpx_codec_pts_t duration = pkt->data.frame.pts - last_pts_;
if (last_pts_ == 0) duration = 1;
if (last_pts_ == 0)
duration = 1;
bits_in_buffer_model_ += static_cast<int64_t>(
duration * timebase_ * cfg_.rc_target_bitrate * 1000);
const bool key_frame =
(pkt->data.frame.flags & VPX_FRAME_IS_KEY) ? true : false;
const bool key_frame = (pkt->data.frame.flags & VPX_FRAME_IS_KEY)
? true: false;
if (!key_frame) {
ASSERT_GE(bits_in_buffer_model_, 0) << "Buffer Underrun at frame "
<< pkt->data.frame.pts;
@@ -860,7 +804,8 @@ class DatarateOnePassCbrSvc
const size_t frame_size_in_bits = pkt->data.frame.sz * 8;
bits_in_buffer_model_ -= frame_size_in_bits;
bits_total_ += frame_size_in_bits;
if (!first_drop_ && duration > 1) first_drop_ = last_pts_ + 1;
if (!first_drop_ && duration > 1)
first_drop_ = last_pts_ + 1;
last_pts_ = pkt->data.frame.pts;
bits_in_last_frame_ = frame_size_in_bits;
++frame_number_;
@@ -869,17 +814,22 @@ class DatarateOnePassCbrSvc
if (bits_total_) {
const double file_size_in_kb = bits_total_ / 1000.; // bits per kilobit
duration_ = (last_pts_ + 1) * timebase_;
effective_datarate_ = (bits_total_ - bits_in_last_frame_) / 1000.0
/ (cfg_.rc_buf_initial_sz / 1000.0 + duration_);
file_datarate_ = file_size_in_kb / duration_;
}
}
virtual void MismatchHook(const vpx_image_t *img1, const vpx_image_t *img2) {
virtual void MismatchHook(const vpx_image_t *img1,
const vpx_image_t *img2) {
double mismatch_psnr = compute_psnr(img1, img2);
mismatch_psnr_ += mismatch_psnr;
++mismatch_nframes_;
}
unsigned int GetMismatchFrames() { return mismatch_nframes_; }
unsigned int GetMismatchFrames() {
return mismatch_nframes_;
}
vpx_codec_pts_t last_pts_;
int64_t bits_in_buffer_model_;
@@ -889,6 +839,7 @@ class DatarateOnePassCbrSvc
int64_t bits_total_;
double duration_;
double file_datarate_;
double effective_datarate_;
size_t bits_in_last_frame_;
vpx_svc_extra_cfg_t svc_params_;
int speed_setting_;
@@ -897,37 +848,44 @@ class DatarateOnePassCbrSvc
};
static void assign_layer_bitrates(vpx_codec_enc_cfg_t *const enc_cfg,
const vpx_svc_extra_cfg_t *svc_params,
int spatial_layers, int temporal_layers,
int temporal_layering_mode) {
int spatial_layers,
int temporal_layers,
int temporal_layering_mode,
unsigned int total_rate) {
int sl, spatial_layer_target;
float total = 0;
float alloc_ratio[VPX_MAX_LAYERS] = {0};
for (sl = 0; sl < spatial_layers; ++sl) {
if (svc_params->scaling_factor_den[sl] > 0) {
alloc_ratio[sl] = (float)(svc_params->scaling_factor_num[sl] * 1.0 /
svc_params->scaling_factor_den[sl]);
alloc_ratio[sl] = (float)(svc_params->scaling_factor_num[sl] *
1.0 / svc_params->scaling_factor_den[sl]);
total += alloc_ratio[sl];
}
}
for (sl = 0; sl < spatial_layers; ++sl) {
enc_cfg->ss_target_bitrate[sl] = spatial_layer_target =
(unsigned int)(enc_cfg->rc_target_bitrate * alloc_ratio[sl] / total);
(unsigned int)(enc_cfg->rc_target_bitrate *
alloc_ratio[sl] / total);
const int index = sl * temporal_layers;
if (temporal_layering_mode == 3) {
enc_cfg->layer_target_bitrate[index] = spatial_layer_target >> 1;
enc_cfg->layer_target_bitrate[index] =
spatial_layer_target >> 1;
enc_cfg->layer_target_bitrate[index + 1] =
(spatial_layer_target >> 1) + (spatial_layer_target >> 2);
enc_cfg->layer_target_bitrate[index + 2] = spatial_layer_target;
enc_cfg->layer_target_bitrate[index + 2] =
spatial_layer_target;
} else if (temporal_layering_mode == 2) {
enc_cfg->layer_target_bitrate[index] = spatial_layer_target * 2 / 3;
enc_cfg->layer_target_bitrate[index + 1] = spatial_layer_target;
enc_cfg->layer_target_bitrate[index] =
spatial_layer_target * 2 / 3;
enc_cfg->layer_target_bitrate[index + 1] =
spatial_layer_target;
}
}
}
// Check basic rate targeting for 1 pass CBR SVC: 2 spatial layers and
// 3 temporal layers. Run CIF clip with 1 thread.
TEST_P(DatarateOnePassCbrSvc, OnePassCbrSvc2SpatialLayers) {
TEST_P(DatarateOnePassCbrSvc, OnePassCbrSvc) {
cfg_.rc_buf_initial_sz = 500;
cfg_.rc_buf_optimal_sz = 500;
cfg_.rc_buf_sz = 1000;
@@ -947,71 +905,31 @@ TEST_P(DatarateOnePassCbrSvc, OnePassCbrSvc2SpatialLayers) {
svc_params_.scaling_factor_den[0] = 288;
svc_params_.scaling_factor_num[1] = 288;
svc_params_.scaling_factor_den[1] = 288;
cfg_.rc_dropframe_thresh = 10;
cfg_.kf_max_dist = 9999;
// TODO(wonkap/marpan): No frame drop for now, we need to implement correct
// frame dropping for SVC.
cfg_.rc_dropframe_thresh = 0;
::libvpx_test::I420VideoSource video("hantro_collage_w352h288.yuv", 352, 288,
30, 1, 0, 200);
// TODO(wonkap/marpan): Check that effective_datarate for each layer hits the
// layer target_bitrate.
for (int i = 200; i <= 800; i += 200) {
// layer target_bitrate. Also check if test can pass at lower bitrate (~200k).
for (int i = 400; i <= 800; i += 200) {
cfg_.rc_target_bitrate = i;
ResetModel();
assign_layer_bitrates(&cfg_, &svc_params_, cfg_.ss_number_layers,
cfg_.ts_number_layers, cfg_.temporal_layering_mode);
cfg_.ts_number_layers, cfg_.temporal_layering_mode,
cfg_.rc_target_bitrate);
ASSERT_NO_FATAL_FAILURE(RunLoop(&video));
ASSERT_GE(cfg_.rc_target_bitrate, file_datarate_ * 0.85)
ASSERT_GE(cfg_.rc_target_bitrate, effective_datarate_ * 0.85)
<< " The datarate for the file exceeds the target by too much!";
ASSERT_LE(cfg_.rc_target_bitrate, file_datarate_ * 1.15)
<< " The datarate for the file is lower than the target by too much!";
EXPECT_EQ(static_cast<unsigned int>(0), GetMismatchFrames());
}
}
// Check basic rate targeting for 1 pass CBR SVC: 2 spatial layers and 3
// temporal layers. Run CIF clip with 1 thread, and few short key frame periods.
TEST_P(DatarateOnePassCbrSvc, OnePassCbrSvc2SpatialLayersSmallKf) {
cfg_.rc_buf_initial_sz = 500;
cfg_.rc_buf_optimal_sz = 500;
cfg_.rc_buf_sz = 1000;
cfg_.rc_min_quantizer = 0;
cfg_.rc_max_quantizer = 63;
cfg_.rc_end_usage = VPX_CBR;
cfg_.g_lag_in_frames = 0;
cfg_.ss_number_layers = 2;
cfg_.ts_number_layers = 3;
cfg_.ts_rate_decimator[0] = 4;
cfg_.ts_rate_decimator[1] = 2;
cfg_.ts_rate_decimator[2] = 1;
cfg_.g_error_resilient = 1;
cfg_.g_threads = 1;
cfg_.temporal_layering_mode = 3;
svc_params_.scaling_factor_num[0] = 144;
svc_params_.scaling_factor_den[0] = 288;
svc_params_.scaling_factor_num[1] = 288;
svc_params_.scaling_factor_den[1] = 288;
cfg_.rc_dropframe_thresh = 10;
::libvpx_test::I420VideoSource video("hantro_collage_w352h288.yuv", 352, 288,
30, 1, 0, 200);
cfg_.rc_target_bitrate = 400;
// For this 3 temporal layer case, pattern repeats every 4 frames, so choose
// 4 key neighboring key frame periods (so key frame will land on 0-2-1-2).
for (int j = 64; j <= 67; j++) {
cfg_.kf_max_dist = j;
ResetModel();
assign_layer_bitrates(&cfg_, &svc_params_, cfg_.ss_number_layers,
cfg_.ts_number_layers, cfg_.temporal_layering_mode);
ASSERT_NO_FATAL_FAILURE(RunLoop(&video));
ASSERT_GE(cfg_.rc_target_bitrate, file_datarate_ * 0.85)
<< " The datarate for the file exceeds the target by too much!";
ASSERT_LE(cfg_.rc_target_bitrate, file_datarate_ * 1.15)
<< " The datarate for the file is lower than the target by too much!";
EXPECT_EQ(static_cast<unsigned int>(0), GetMismatchFrames());
EXPECT_EQ(GetMismatchFrames(), (unsigned int) 0);
}
}
// Check basic rate targeting for 1 pass CBR SVC: 2 spatial layers and
// 3 temporal layers. Run HD clip with 4 threads.
TEST_P(DatarateOnePassCbrSvc, OnePassCbrSvc2SpatialLayers4threads) {
TEST_P(DatarateOnePassCbrSvc, OnePassCbrSvc4threads) {
cfg_.rc_buf_initial_sz = 500;
cfg_.rc_buf_optimal_sz = 500;
cfg_.rc_buf_sz = 1000;
@@ -1031,152 +949,30 @@ TEST_P(DatarateOnePassCbrSvc, OnePassCbrSvc2SpatialLayers4threads) {
svc_params_.scaling_factor_den[0] = 288;
svc_params_.scaling_factor_num[1] = 288;
svc_params_.scaling_factor_den[1] = 288;
cfg_.rc_dropframe_thresh = 10;
cfg_.kf_max_dist = 9999;
::libvpx_test::I420VideoSource video("niklas_1280_720_30.y4m", 1280, 720, 30,
1, 0, 300);
// TODO(wonkap/marpan): No frame drop for now, we need to implement correct
// frame dropping for SVC.
cfg_.rc_dropframe_thresh = 0;
::libvpx_test::I420VideoSource video("niklas_1280_720_30.y4m", 1280, 720,
30, 1, 0, 300);
cfg_.rc_target_bitrate = 800;
ResetModel();
assign_layer_bitrates(&cfg_, &svc_params_, cfg_.ss_number_layers,
cfg_.ts_number_layers, cfg_.temporal_layering_mode);
cfg_.ts_number_layers, cfg_.temporal_layering_mode,
cfg_.rc_target_bitrate);
ASSERT_NO_FATAL_FAILURE(RunLoop(&video));
ASSERT_GE(cfg_.rc_target_bitrate, file_datarate_ * 0.85)
ASSERT_GE(cfg_.rc_target_bitrate, effective_datarate_ * 0.85)
<< " The datarate for the file exceeds the target by too much!";
ASSERT_LE(cfg_.rc_target_bitrate, file_datarate_ * 1.15)
<< " The datarate for the file is lower than the target by too much!";
EXPECT_EQ(static_cast<unsigned int>(0), GetMismatchFrames());
}
// Check basic rate targeting for 1 pass CBR SVC: 3 spatial layers and
// 3 temporal layers. Run CIF clip with 1 thread.
TEST_P(DatarateOnePassCbrSvc, OnePassCbrSvc3SpatialLayers) {
cfg_.rc_buf_initial_sz = 500;
cfg_.rc_buf_optimal_sz = 500;
cfg_.rc_buf_sz = 1000;
cfg_.rc_min_quantizer = 0;
cfg_.rc_max_quantizer = 63;
cfg_.rc_end_usage = VPX_CBR;
cfg_.g_lag_in_frames = 0;
cfg_.ss_number_layers = 3;
cfg_.ts_number_layers = 3;
cfg_.ts_rate_decimator[0] = 4;
cfg_.ts_rate_decimator[1] = 2;
cfg_.ts_rate_decimator[2] = 1;
cfg_.g_error_resilient = 1;
cfg_.g_threads = 1;
cfg_.temporal_layering_mode = 3;
svc_params_.scaling_factor_num[0] = 72;
svc_params_.scaling_factor_den[0] = 288;
svc_params_.scaling_factor_num[1] = 144;
svc_params_.scaling_factor_den[1] = 288;
svc_params_.scaling_factor_num[2] = 288;
svc_params_.scaling_factor_den[2] = 288;
cfg_.rc_dropframe_thresh = 10;
cfg_.kf_max_dist = 9999;
::libvpx_test::I420VideoSource video("niklas_1280_720_30.y4m", 1280, 720, 30,
1, 0, 300);
cfg_.rc_target_bitrate = 800;
ResetModel();
assign_layer_bitrates(&cfg_, &svc_params_, cfg_.ss_number_layers,
cfg_.ts_number_layers, cfg_.temporal_layering_mode);
ASSERT_NO_FATAL_FAILURE(RunLoop(&video));
ASSERT_GE(cfg_.rc_target_bitrate, file_datarate_ * 0.85)
<< " The datarate for the file exceeds the target by too much!";
ASSERT_LE(cfg_.rc_target_bitrate, file_datarate_ * 1.22)
<< " The datarate for the file is lower than the target by too much!";
EXPECT_EQ(static_cast<unsigned int>(0), GetMismatchFrames());
}
// Check basic rate targeting for 1 pass CBR SVC: 3 spatial layers and 3
// temporal layers. Run CIF clip with 1 thread, and few short key frame periods.
TEST_P(DatarateOnePassCbrSvc, OnePassCbrSvc3SpatialLayersSmallKf) {
cfg_.rc_buf_initial_sz = 500;
cfg_.rc_buf_optimal_sz = 500;
cfg_.rc_buf_sz = 1000;
cfg_.rc_min_quantizer = 0;
cfg_.rc_max_quantizer = 63;
cfg_.rc_end_usage = VPX_CBR;
cfg_.g_lag_in_frames = 0;
cfg_.ss_number_layers = 3;
cfg_.ts_number_layers = 3;
cfg_.ts_rate_decimator[0] = 4;
cfg_.ts_rate_decimator[1] = 2;
cfg_.ts_rate_decimator[2] = 1;
cfg_.g_error_resilient = 1;
cfg_.g_threads = 1;
cfg_.temporal_layering_mode = 3;
svc_params_.scaling_factor_num[0] = 72;
svc_params_.scaling_factor_den[0] = 288;
svc_params_.scaling_factor_num[1] = 144;
svc_params_.scaling_factor_den[1] = 288;
svc_params_.scaling_factor_num[2] = 288;
svc_params_.scaling_factor_den[2] = 288;
cfg_.rc_dropframe_thresh = 10;
::libvpx_test::I420VideoSource video("niklas_1280_720_30.y4m", 1280, 720, 30,
1, 0, 300);
cfg_.rc_target_bitrate = 800;
// For this 3 temporal layer case, pattern repeats every 4 frames, so choose
// 4 key neighboring key frame periods (so key frame will land on 0-2-1-2).
for (int j = 32; j <= 35; j++) {
cfg_.kf_max_dist = j;
ResetModel();
assign_layer_bitrates(&cfg_, &svc_params_, cfg_.ss_number_layers,
cfg_.ts_number_layers, cfg_.temporal_layering_mode);
ASSERT_NO_FATAL_FAILURE(RunLoop(&video));
ASSERT_GE(cfg_.rc_target_bitrate, file_datarate_ * 0.85)
<< " The datarate for the file exceeds the target by too much!";
ASSERT_LE(cfg_.rc_target_bitrate, file_datarate_ * 1.30)
<< " The datarate for the file is lower than the target by too much!";
EXPECT_EQ(static_cast<unsigned int>(0), GetMismatchFrames());
}
}
// Check basic rate targeting for 1 pass CBR SVC: 3 spatial layers and
// 3 temporal layers. Run HD clip with 4 threads.
TEST_P(DatarateOnePassCbrSvc, OnePassCbrSvc3SpatialLayers4threads) {
cfg_.rc_buf_initial_sz = 500;
cfg_.rc_buf_optimal_sz = 500;
cfg_.rc_buf_sz = 1000;
cfg_.rc_min_quantizer = 0;
cfg_.rc_max_quantizer = 63;
cfg_.rc_end_usage = VPX_CBR;
cfg_.g_lag_in_frames = 0;
cfg_.ss_number_layers = 3;
cfg_.ts_number_layers = 3;
cfg_.ts_rate_decimator[0] = 4;
cfg_.ts_rate_decimator[1] = 2;
cfg_.ts_rate_decimator[2] = 1;
cfg_.g_error_resilient = 1;
cfg_.g_threads = 4;
cfg_.temporal_layering_mode = 3;
svc_params_.scaling_factor_num[0] = 72;
svc_params_.scaling_factor_den[0] = 288;
svc_params_.scaling_factor_num[1] = 144;
svc_params_.scaling_factor_den[1] = 288;
svc_params_.scaling_factor_num[2] = 288;
svc_params_.scaling_factor_den[2] = 288;
cfg_.rc_dropframe_thresh = 10;
cfg_.kf_max_dist = 9999;
::libvpx_test::I420VideoSource video("niklas_1280_720_30.y4m", 1280, 720, 30,
1, 0, 300);
cfg_.rc_target_bitrate = 800;
ResetModel();
assign_layer_bitrates(&cfg_, &svc_params_, cfg_.ss_number_layers,
cfg_.ts_number_layers, cfg_.temporal_layering_mode);
ASSERT_NO_FATAL_FAILURE(RunLoop(&video));
ASSERT_GE(cfg_.rc_target_bitrate, file_datarate_ * 0.85)
<< " The datarate for the file exceeds the target by too much!";
ASSERT_LE(cfg_.rc_target_bitrate, file_datarate_ * 1.22)
<< " The datarate for the file is lower than the target by too much!";
EXPECT_EQ(static_cast<unsigned int>(0), GetMismatchFrames());
EXPECT_EQ(GetMismatchFrames(), (unsigned int) 0);
}
VP8_INSTANTIATE_TEST_CASE(DatarateTestLarge, ALL_TEST_MODES);
VP9_INSTANTIATE_TEST_CASE(DatarateTestVP9Large,
::testing::Values(::libvpx_test::kOnePassGood,
::libvpx_test::kRealTime),
::testing::Range(2, 9));
::testing::Range(2, 7));
VP9_INSTANTIATE_TEST_CASE(DatarateOnePassCbrSvc,
::testing::Values(::libvpx_test::kRealTime),
::testing::Range(5, 9));
::testing::Range(5, 8));
} // namespace

View File

@@ -25,12 +25,20 @@
#include "vpx/vpx_codec.h"
#include "vpx/vpx_integer.h"
#include "vpx_ports/mem.h"
#include "vpx_ports/msvc.h" // for round()
using libvpx_test::ACMRandom;
namespace {
#ifdef _MSC_VER
static int round(double x) {
if (x < 0)
return static_cast<int>(ceil(x - 0.5));
else
return static_cast<int>(floor(x + 0.5));
}
#endif
const int kNumCoeffs = 256;
const double C1 = 0.995184726672197;
const double C2 = 0.98078528040323;
@@ -208,17 +216,21 @@ void reference_16x16_dct_2d(int16_t input[256], double output[256]) {
// First transform columns
for (int i = 0; i < 16; ++i) {
double temp_in[16], temp_out[16];
for (int j = 0; j < 16; ++j) temp_in[j] = input[j * 16 + i];
for (int j = 0; j < 16; ++j)
temp_in[j] = input[j * 16 + i];
butterfly_16x16_dct_1d(temp_in, temp_out);
for (int j = 0; j < 16; ++j) output[j * 16 + i] = temp_out[j];
for (int j = 0; j < 16; ++j)
output[j * 16 + i] = temp_out[j];
}
// Then transform rows
for (int i = 0; i < 16; ++i) {
double temp_in[16], temp_out[16];
for (int j = 0; j < 16; ++j) temp_in[j] = output[j + i * 16];
for (int j = 0; j < 16; ++j)
temp_in[j] = output[j + i * 16];
butterfly_16x16_dct_1d(temp_in, temp_out);
// Scale by some magic number
for (int j = 0; j < 16; ++j) output[j + i * 16] = temp_out[j] / 2;
for (int j = 0; j < 16; ++j)
output[j + i * 16] = temp_out[j]/2;
}
}
@@ -244,7 +256,8 @@ void idct16x16_ref(const tran_low_t *in, uint8_t *dest, int stride,
vpx_idct16x16_256_add_c(in, dest, stride);
}
void fht16x16_ref(const int16_t *in, tran_low_t *out, int stride, int tx_type) {
void fht16x16_ref(const int16_t *in, tran_low_t *out, int stride,
int tx_type) {
vp9_fht16x16_c(in, out, stride, tx_type);
}
@@ -263,12 +276,12 @@ void idct16x16_12(const tran_low_t *in, uint8_t *out, int stride) {
}
void idct16x16_10_ref(const tran_low_t *in, uint8_t *out, int stride,
int /*tx_type*/) {
int tx_type) {
idct16x16_10(in, out, stride);
}
void idct16x16_12_ref(const tran_low_t *in, uint8_t *out, int stride,
int /*tx_type*/) {
int tx_type) {
idct16x16_12(in, out, stride);
}
@@ -280,7 +293,6 @@ 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);
}
#if HAVE_SSE2
void idct16x16_10_add_10_c(const tran_low_t *in, uint8_t *out, int stride) {
vpx_highbd_idct16x16_10_add_c(in, out, stride, 10);
}
@@ -289,6 +301,7 @@ 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);
}
#if HAVE_SSE2
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);
}
@@ -346,10 +359,11 @@ class Trans16x16TestBase {
}
}
ASM_REGISTER_STATE_CHECK(
RunFwdTxfm(test_input_block, test_temp_block, pitch_));
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_));
ASM_REGISTER_STATE_CHECK(
RunInvTxfm(test_temp_block, dst, pitch_));
#if CONFIG_VP9_HIGHBITDEPTH
} else {
ASM_REGISTER_STATE_CHECK(
@@ -359,13 +373,14 @@ class Trans16x16TestBase {
for (int j = 0; j < kNumCoeffs; ++j) {
#if CONFIG_VP9_HIGHBITDEPTH
const int32_t diff =
const uint32_t diff =
bit_depth_ == VPX_BITS_8 ? dst[j] - src[j] : dst16[j] - src16[j];
#else
const int32_t diff = dst[j] - src[j];
const uint32_t diff = dst[j] - src[j];
#endif
const uint32_t error = diff * diff;
if (max_error < error) max_error = error;
if (max_error < error)
max_error = error;
total_error += error;
}
}
@@ -386,9 +401,8 @@ class Trans16x16TestBase {
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) {
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_));
@@ -412,14 +426,16 @@ class Trans16x16TestBase {
input_extreme_block[j] = rnd.Rand8() % 2 ? mask_ : -mask_;
}
if (i == 0) {
for (int j = 0; j < kNumCoeffs; ++j) input_extreme_block[j] = mask_;
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_;
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_));
ASM_REGISTER_STATE_CHECK(RunFwdTxfm(input_extreme_block,
output_block, pitch_));
// The minimum quant value is 4.
for (int j = 0; j < kNumCoeffs; ++j) {
@@ -448,12 +464,12 @@ class Trans16x16TestBase {
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_;
}
if (i == 1) {
for (int j = 0; j < kNumCoeffs; ++j) input_extreme_block[j] = -mask_;
}
if (i == 0)
for (int j = 0; j < kNumCoeffs; ++j)
input_extreme_block[j] = mask_;
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_);
@@ -467,9 +483,8 @@ class Trans16x16TestBase {
// quantization with maximum allowed step sizes
output_ref_block[0] = (output_ref_block[0] / dc_thred) * dc_thred;
for (int j = 1; j < kNumCoeffs; ++j) {
for (int j = 1; j < kNumCoeffs; ++j)
output_ref_block[j] = (output_ref_block[j] / ac_thred) * ac_thred;
}
if (bit_depth_ == VPX_BITS_8) {
inv_txfm_ref(output_ref_block, ref, pitch_, tx_type_);
ASM_REGISTER_STATE_CHECK(RunInvTxfm(output_ref_block, dst, pitch_));
@@ -477,15 +492,17 @@ class Trans16x16TestBase {
} else {
inv_txfm_ref(output_ref_block, CONVERT_TO_BYTEPTR(ref16), pitch_,
tx_type_);
ASM_REGISTER_STATE_CHECK(
RunInvTxfm(output_ref_block, CONVERT_TO_BYTEPTR(dst16), pitch_));
ASM_REGISTER_STATE_CHECK(RunInvTxfm(output_ref_block,
CONVERT_TO_BYTEPTR(dst16), pitch_));
#endif
}
if (bit_depth_ == VPX_BITS_8) {
for (int j = 0; j < kNumCoeffs; ++j) EXPECT_EQ(ref[j], dst[j]);
for (int j = 0; j < kNumCoeffs; ++j)
EXPECT_EQ(ref[j], dst[j]);
#if CONFIG_VP9_HIGHBITDEPTH
} else {
for (int j = 0; j < kNumCoeffs; ++j) EXPECT_EQ(ref16[j], dst16[j]);
for (int j = 0; j < kNumCoeffs; ++j)
EXPECT_EQ(ref16[j], dst16[j]);
#endif
}
}
@@ -522,16 +539,15 @@ class Trans16x16TestBase {
}
reference_16x16_dct_2d(in, out_r);
for (int j = 0; j < kNumCoeffs; ++j) {
for (int j = 0; j < kNumCoeffs; ++j)
coeff[j] = static_cast<tran_low_t>(round(out_r[j]));
}
if (bit_depth_ == VPX_BITS_8) {
ASM_REGISTER_STATE_CHECK(RunInvTxfm(coeff, dst, 16));
#if CONFIG_VP9_HIGHBITDEPTH
} else {
ASM_REGISTER_STATE_CHECK(
RunInvTxfm(coeff, CONVERT_TO_BYTEPTR(dst16), 16));
ASM_REGISTER_STATE_CHECK(RunInvTxfm(coeff, CONVERT_TO_BYTEPTR(dst16),
16));
#endif // CONFIG_VP9_HIGHBITDEPTH
}
@@ -543,7 +559,8 @@ class Trans16x16TestBase {
const uint32_t diff = dst[j] - src[j];
#endif // CONFIG_VP9_HIGHBITDEPTH
const uint32_t error = diff * diff;
EXPECT_GE(1u, error) << "Error: 16x16 IDCT has error " << error
EXPECT_GE(1u, error)
<< "Error: 16x16 IDCT has error " << error
<< " at index " << j;
}
}
@@ -586,8 +603,8 @@ class Trans16x16TestBase {
} else {
#if CONFIG_VP9_HIGHBITDEPTH
ref_txfm(coeff, CONVERT_TO_BYTEPTR(ref16), pitch_);
ASM_REGISTER_STATE_CHECK(
RunInvTxfm(coeff, CONVERT_TO_BYTEPTR(dst16), pitch_));
ASM_REGISTER_STATE_CHECK(RunInvTxfm(coeff, CONVERT_TO_BYTEPTR(dst16),
pitch_));
#endif // CONFIG_VP9_HIGHBITDEPTH
}
@@ -599,8 +616,9 @@ class Trans16x16TestBase {
const uint32_t diff = dst[j] - ref[j];
#endif // CONFIG_VP9_HIGHBITDEPTH
const uint32_t error = diff * diff;
EXPECT_EQ(0u, error) << "Error: 16x16 IDCT Comparison has error "
<< error << " at index " << j;
EXPECT_EQ(0u, error)
<< "Error: 16x16 IDCT Comparison has error " << error
<< " at index " << j;
}
}
}
@@ -613,7 +631,8 @@ class Trans16x16TestBase {
IhtFunc inv_txfm_ref;
};
class Trans16x16DCT : public Trans16x16TestBase,
class Trans16x16DCT
: public Trans16x16TestBase,
public ::testing::TestWithParam<Dct16x16Param> {
public:
virtual ~Trans16x16DCT() {}
@@ -629,9 +648,15 @@ class Trans16x16DCT : public Trans16x16TestBase,
mask_ = (1 << bit_depth_) - 1;
#if CONFIG_VP9_HIGHBITDEPTH
switch (bit_depth_) {
case VPX_BITS_10: inv_txfm_ref = idct16x16_10_ref; break;
case VPX_BITS_12: inv_txfm_ref = idct16x16_12_ref; break;
default: inv_txfm_ref = idct16x16_ref; break;
case VPX_BITS_10:
inv_txfm_ref = idct16x16_10_ref;
break;
case VPX_BITS_12:
inv_txfm_ref = idct16x16_12_ref;
break;
default:
inv_txfm_ref = idct16x16_ref;
break;
}
#else
inv_txfm_ref = idct16x16_ref;
@@ -651,11 +676,17 @@ class Trans16x16DCT : public Trans16x16TestBase,
IdctFunc inv_txfm_;
};
TEST_P(Trans16x16DCT, AccuracyCheck) { RunAccuracyCheck(); }
TEST_P(Trans16x16DCT, AccuracyCheck) {
RunAccuracyCheck();
}
TEST_P(Trans16x16DCT, CoeffCheck) { RunCoeffCheck(); }
TEST_P(Trans16x16DCT, CoeffCheck) {
RunCoeffCheck();
}
TEST_P(Trans16x16DCT, MemCheck) { RunMemCheck(); }
TEST_P(Trans16x16DCT, MemCheck) {
RunMemCheck();
}
TEST_P(Trans16x16DCT, QuantCheck) {
// Use maximally allowed quantization step sizes for DC and AC
@@ -663,9 +694,12 @@ TEST_P(Trans16x16DCT, QuantCheck) {
RunQuantCheck(1336, 1828);
}
TEST_P(Trans16x16DCT, InvAccuracyCheck) { RunInvAccuracyCheck(); }
TEST_P(Trans16x16DCT, InvAccuracyCheck) {
RunInvAccuracyCheck();
}
class Trans16x16HT : public Trans16x16TestBase,
class Trans16x16HT
: public Trans16x16TestBase,
public ::testing::TestWithParam<Ht16x16Param> {
public:
virtual ~Trans16x16HT() {}
@@ -681,9 +715,15 @@ class Trans16x16HT : public Trans16x16TestBase,
mask_ = (1 << bit_depth_) - 1;
#if CONFIG_VP9_HIGHBITDEPTH
switch (bit_depth_) {
case VPX_BITS_10: inv_txfm_ref = iht16x16_10; break;
case VPX_BITS_12: inv_txfm_ref = iht16x16_12; break;
default: inv_txfm_ref = iht16x16_ref; break;
case VPX_BITS_10:
inv_txfm_ref = iht16x16_10;
break;
case VPX_BITS_12:
inv_txfm_ref = iht16x16_12;
break;
default:
inv_txfm_ref = iht16x16_ref;
break;
}
#else
inv_txfm_ref = iht16x16_ref;
@@ -703,11 +743,17 @@ class Trans16x16HT : public Trans16x16TestBase,
IhtFunc inv_txfm_;
};
TEST_P(Trans16x16HT, AccuracyCheck) { RunAccuracyCheck(); }
TEST_P(Trans16x16HT, AccuracyCheck) {
RunAccuracyCheck();
}
TEST_P(Trans16x16HT, CoeffCheck) { RunCoeffCheck(); }
TEST_P(Trans16x16HT, CoeffCheck) {
RunCoeffCheck();
}
TEST_P(Trans16x16HT, MemCheck) { RunMemCheck(); }
TEST_P(Trans16x16HT, MemCheck) {
RunMemCheck();
}
TEST_P(Trans16x16HT, QuantCheck) {
// The encoder skips any non-DC intra prediction modes,
@@ -715,7 +761,8 @@ TEST_P(Trans16x16HT, QuantCheck) {
RunQuantCheck(429, 729);
}
class InvTrans16x16DCT : public Trans16x16TestBase,
class InvTrans16x16DCT
: public Trans16x16TestBase,
public ::testing::TestWithParam<Idct16x16Param> {
public:
virtual ~InvTrans16x16DCT() {}
@@ -731,7 +778,7 @@ class InvTrans16x16DCT : public Trans16x16TestBase,
virtual void TearDown() { libvpx_test::ClearSystemState(); }
protected:
void RunFwdTxfm(int16_t * /*in*/, tran_low_t * /*out*/, int /*stride*/) {}
void RunFwdTxfm(int16_t *in, tran_low_t *out, int stride) {}
void RunInvTxfm(tran_low_t *out, uint8_t *dst, int stride) {
inv_txfm_(out, dst, stride);
}
@@ -745,66 +792,6 @@ TEST_P(InvTrans16x16DCT, CompareReference) {
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;
#if CONFIG_VP9_HIGHBITDEPTH
@@ -815,10 +802,10 @@ INSTANTIATE_TEST_CASE_P(
make_tuple(&vpx_highbd_fdct16x16_c, &idct16x16_12, 0, VPX_BITS_12),
make_tuple(&vpx_fdct16x16_c, &vpx_idct16x16_256_add_c, 0, VPX_BITS_8)));
#else
INSTANTIATE_TEST_CASE_P(C, Trans16x16DCT,
::testing::Values(make_tuple(&vpx_fdct16x16_c,
&vpx_idct16x16_256_add_c,
0, VPX_BITS_8)));
INSTANTIATE_TEST_CASE_P(
C, Trans16x16DCT,
::testing::Values(
make_tuple(&vpx_fdct16x16_c, &vpx_idct16x16_256_add_c, 0, VPX_BITS_8)));
#endif // CONFIG_VP9_HIGHBITDEPTH
#if CONFIG_VP9_HIGHBITDEPTH
@@ -837,11 +824,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, 2, VPX_BITS_8),
make_tuple(&vp9_fht16x16_c, &vp9_iht16x16_256_add_c, 3, VPX_BITS_8)));
INSTANTIATE_TEST_CASE_P(
C, PartialTrans16x16Test,
::testing::Values(make_tuple(&vpx_highbd_fdct16x16_1_c, VPX_BITS_8),
make_tuple(&vpx_highbd_fdct16x16_1_c, VPX_BITS_10),
make_tuple(&vpx_highbd_fdct16x16_1_c, VPX_BITS_12)));
#else
INSTANTIATE_TEST_CASE_P(
C, Trans16x16HT,
@@ -850,35 +832,32 @@ INSTANTIATE_TEST_CASE_P(
make_tuple(&vp9_fht16x16_c, &vp9_iht16x16_256_add_c, 1, VPX_BITS_8),
make_tuple(&vp9_fht16x16_c, &vp9_iht16x16_256_add_c, 2, VPX_BITS_8),
make_tuple(&vp9_fht16x16_c, &vp9_iht16x16_256_add_c, 3, VPX_BITS_8)));
INSTANTIATE_TEST_CASE_P(C, PartialTrans16x16Test,
::testing::Values(make_tuple(&vpx_fdct16x16_1_c,
VPX_BITS_8)));
#endif // CONFIG_VP9_HIGHBITDEPTH
#if HAVE_NEON && !CONFIG_VP9_HIGHBITDEPTH && !CONFIG_EMULATE_HARDWARE
#if HAVE_NEON_ASM && !CONFIG_VP9_HIGHBITDEPTH && !CONFIG_EMULATE_HARDWARE
INSTANTIATE_TEST_CASE_P(
NEON, Trans16x16DCT,
::testing::Values(make_tuple(&vpx_fdct16x16_c, &vpx_idct16x16_256_add_neon,
0, VPX_BITS_8)));
::testing::Values(
make_tuple(&vpx_fdct16x16_c,
&vpx_idct16x16_256_add_neon, 0, VPX_BITS_8)));
#endif
#if HAVE_SSE2 && !CONFIG_VP9_HIGHBITDEPTH && !CONFIG_EMULATE_HARDWARE
INSTANTIATE_TEST_CASE_P(
SSE2, Trans16x16DCT,
::testing::Values(make_tuple(&vpx_fdct16x16_sse2,
::testing::Values(
make_tuple(&vpx_fdct16x16_sse2,
&vpx_idct16x16_256_add_sse2, 0, VPX_BITS_8)));
INSTANTIATE_TEST_CASE_P(
SSE2, Trans16x16HT,
::testing::Values(make_tuple(&vp9_fht16x16_sse2, &vp9_iht16x16_256_add_sse2,
0, VPX_BITS_8),
make_tuple(&vp9_fht16x16_sse2, &vp9_iht16x16_256_add_sse2,
1, VPX_BITS_8),
make_tuple(&vp9_fht16x16_sse2, &vp9_iht16x16_256_add_sse2,
2, VPX_BITS_8),
make_tuple(&vp9_fht16x16_sse2, &vp9_iht16x16_256_add_sse2,
3, VPX_BITS_8)));
INSTANTIATE_TEST_CASE_P(SSE2, PartialTrans16x16Test,
::testing::Values(make_tuple(&vpx_fdct16x16_1_sse2,
::testing::Values(
make_tuple(&vp9_fht16x16_sse2, &vp9_iht16x16_256_add_sse2, 0,
VPX_BITS_8),
make_tuple(&vp9_fht16x16_sse2, &vp9_iht16x16_256_add_sse2, 1,
VPX_BITS_8),
make_tuple(&vp9_fht16x16_sse2, &vp9_iht16x16_256_add_sse2, 2,
VPX_BITS_8),
make_tuple(&vp9_fht16x16_sse2, &vp9_iht16x16_256_add_sse2, 3,
VPX_BITS_8)));
#endif // HAVE_SSE2 && !CONFIG_VP9_HIGHBITDEPTH && !CONFIG_EMULATE_HARDWARE
@@ -886,14 +865,16 @@ INSTANTIATE_TEST_CASE_P(SSE2, PartialTrans16x16Test,
INSTANTIATE_TEST_CASE_P(
SSE2, Trans16x16DCT,
::testing::Values(
make_tuple(&vpx_highbd_fdct16x16_sse2, &idct16x16_10, 0, VPX_BITS_10),
make_tuple(&vpx_highbd_fdct16x16_c, &idct16x16_256_add_10_sse2, 0,
VPX_BITS_10),
make_tuple(&vpx_highbd_fdct16x16_sse2, &idct16x16_12, 0, VPX_BITS_12),
make_tuple(&vpx_highbd_fdct16x16_c, &idct16x16_256_add_12_sse2, 0,
VPX_BITS_12),
make_tuple(&vpx_fdct16x16_sse2, &vpx_idct16x16_256_add_c, 0,
VPX_BITS_8)));
make_tuple(&vpx_highbd_fdct16x16_sse2,
&idct16x16_10, 0, VPX_BITS_10),
make_tuple(&vpx_highbd_fdct16x16_c,
&idct16x16_256_add_10_sse2, 0, VPX_BITS_10),
make_tuple(&vpx_highbd_fdct16x16_sse2,
&idct16x16_12, 0, VPX_BITS_12),
make_tuple(&vpx_highbd_fdct16x16_c,
&idct16x16_256_add_12_sse2, 0, VPX_BITS_12),
make_tuple(&vpx_fdct16x16_sse2,
&vpx_idct16x16_256_add_c, 0, VPX_BITS_8)));
INSTANTIATE_TEST_CASE_P(
SSE2, Trans16x16HT,
::testing::Values(
@@ -906,24 +887,23 @@ INSTANTIATE_TEST_CASE_P(
// that to test both branches.
INSTANTIATE_TEST_CASE_P(
SSE2, InvTrans16x16DCT,
::testing::Values(make_tuple(&idct16x16_10_add_10_c,
::testing::Values(
make_tuple(&idct16x16_10_add_10_c,
&idct16x16_10_add_10_sse2, 3167, VPX_BITS_10),
make_tuple(&idct16x16_10, &idct16x16_256_add_10_sse2,
3167, VPX_BITS_10),
make_tuple(&idct16x16_10,
&idct16x16_256_add_10_sse2, 3167, VPX_BITS_10),
make_tuple(&idct16x16_10_add_12_c,
&idct16x16_10_add_12_sse2, 3167, VPX_BITS_12),
make_tuple(&idct16x16_12, &idct16x16_256_add_12_sse2,
3167, VPX_BITS_12)));
INSTANTIATE_TEST_CASE_P(SSE2, PartialTrans16x16Test,
::testing::Values(make_tuple(&vpx_fdct16x16_1_sse2,
VPX_BITS_8)));
make_tuple(&idct16x16_12,
&idct16x16_256_add_12_sse2, 3167, VPX_BITS_12)));
#endif // HAVE_SSE2 && CONFIG_VP9_HIGHBITDEPTH && !CONFIG_EMULATE_HARDWARE
#if HAVE_MSA && !CONFIG_VP9_HIGHBITDEPTH && !CONFIG_EMULATE_HARDWARE
INSTANTIATE_TEST_CASE_P(MSA, Trans16x16DCT,
::testing::Values(make_tuple(&vpx_fdct16x16_msa,
&vpx_idct16x16_256_add_msa,
0, VPX_BITS_8)));
INSTANTIATE_TEST_CASE_P(
MSA, Trans16x16DCT,
::testing::Values(
make_tuple(&vpx_fdct16x16_msa,
&vpx_idct16x16_256_add_msa, 0, VPX_BITS_8)));
INSTANTIATE_TEST_CASE_P(
MSA, Trans16x16HT,
::testing::Values(
@@ -932,8 +912,5 @@ INSTANTIATE_TEST_CASE_P(
make_tuple(&vp9_fht16x16_msa, &vp9_iht16x16_256_add_msa, 2, VPX_BITS_8),
make_tuple(&vp9_fht16x16_msa, &vp9_iht16x16_256_add_msa, 3,
VPX_BITS_8)));
INSTANTIATE_TEST_CASE_P(MSA, PartialTrans16x16Test,
::testing::Values(make_tuple(&vpx_fdct16x16_1_msa,
VPX_BITS_8)));
#endif // HAVE_MSA && !CONFIG_VP9_HIGHBITDEPTH && !CONFIG_EMULATE_HARDWARE
} // namespace

View File

@@ -25,11 +25,18 @@
#include "vpx/vpx_codec.h"
#include "vpx/vpx_integer.h"
#include "vpx_ports/mem.h"
#include "vpx_ports/msvc.h" // for round()
using libvpx_test::ACMRandom;
namespace {
#ifdef _MSC_VER
static int round(double x) {
if (x < 0)
return static_cast<int>(ceil(x - 0.5));
else
return static_cast<int>(floor(x + 0.5));
}
#endif
const int kNumCoeffs = 1024;
const double kPi = 3.141592653589793238462643383279502884;
@@ -37,10 +44,10 @@ void reference_32x32_dct_1d(const double in[32], double out[32]) {
const double kInvSqrt2 = 0.707106781186547524400844362104;
for (int k = 0; k < 32; k++) {
out[k] = 0.0;
for (int n = 0; n < 32; n++) {
for (int n = 0; n < 32; n++)
out[k] += in[n] * cos(kPi * (2 * n + 1) * k / 64.0);
}
if (k == 0) out[k] = out[k] * kInvSqrt2;
if (k == 0)
out[k] = out[k] * kInvSqrt2;
}
}
@@ -49,17 +56,21 @@ void reference_32x32_dct_2d(const int16_t input[kNumCoeffs],
// First transform columns
for (int i = 0; i < 32; ++i) {
double temp_in[32], temp_out[32];
for (int j = 0; j < 32; ++j) temp_in[j] = input[j * 32 + i];
for (int j = 0; j < 32; ++j)
temp_in[j] = input[j*32 + i];
reference_32x32_dct_1d(temp_in, temp_out);
for (int j = 0; j < 32; ++j) output[j * 32 + i] = temp_out[j];
for (int j = 0; j < 32; ++j)
output[j * 32 + i] = temp_out[j];
}
// Then transform rows
for (int i = 0; i < 32; ++i) {
double temp_in[32], temp_out[32];
for (int j = 0; j < 32; ++j) temp_in[j] = output[j + i * 32];
for (int j = 0; j < 32; ++j)
temp_in[j] = output[j + i*32];
reference_32x32_dct_1d(temp_in, temp_out);
// Scale by some magic number
for (int j = 0; j < 32; ++j) output[j + i * 32] = temp_out[j] / 4;
for (int j = 0; j < 32; ++j)
output[j + i * 32] = temp_out[j] / 4;
}
}
@@ -70,6 +81,10 @@ typedef std::tr1::tuple<FwdTxfmFunc, InvTxfmFunc, int, vpx_bit_depth_t>
Trans32x32Param;
#if CONFIG_VP9_HIGHBITDEPTH
void idct32x32_8(const tran_low_t *in, uint8_t *out, int stride) {
vpx_highbd_idct32x32_1024_add_c(in, out, stride, 8);
}
void idct32x32_10(const tran_low_t *in, uint8_t *out, int stride) {
vpx_highbd_idct32x32_1024_add_c(in, out, stride, 10);
}
@@ -136,20 +151,21 @@ TEST_P(Trans32x32Test, AccuracyCheck) {
ASM_REGISTER_STATE_CHECK(inv_txfm_(test_temp_block, dst, 32));
#if CONFIG_VP9_HIGHBITDEPTH
} else {
ASM_REGISTER_STATE_CHECK(
inv_txfm_(test_temp_block, CONVERT_TO_BYTEPTR(dst16), 32));
ASM_REGISTER_STATE_CHECK(inv_txfm_(test_temp_block,
CONVERT_TO_BYTEPTR(dst16), 32));
#endif
}
for (int j = 0; j < kNumCoeffs; ++j) {
#if CONFIG_VP9_HIGHBITDEPTH
const int32_t diff =
const uint32_t diff =
bit_depth_ == VPX_BITS_8 ? dst[j] - src[j] : dst16[j] - src16[j];
#else
const int32_t diff = dst[j] - src[j];
const uint32_t diff = dst[j] - src[j];
#endif
const uint32_t error = diff * diff;
if (max_error < error) max_error = error;
if (max_error < error)
max_error = error;
total_error += error;
}
}
@@ -175,9 +191,8 @@ TEST_P(Trans32x32Test, CoeffCheck) {
DECLARE_ALIGNED(16, tran_low_t, output_block[kNumCoeffs]);
for (int i = 0; i < count_test_block; ++i) {
for (int j = 0; j < kNumCoeffs; ++j) {
for (int j = 0; j < kNumCoeffs; ++j)
input_block[j] = (rnd.Rand16() & mask_) - (rnd.Rand16() & mask_);
}
const int stride = 32;
vpx_fdct32x32_c(input_block, output_ref_block, stride);
@@ -209,9 +224,11 @@ TEST_P(Trans32x32Test, MemCheck) {
input_extreme_block[j] = rnd.Rand8() & 1 ? mask_ : -mask_;
}
if (i == 0) {
for (int j = 0; j < kNumCoeffs; ++j) input_extreme_block[j] = mask_;
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_;
for (int j = 0; j < kNumCoeffs; ++j)
input_extreme_block[j] = -mask_;
}
const int stride = 32;
@@ -268,9 +285,8 @@ TEST_P(Trans32x32Test, InverseAccuracy) {
}
reference_32x32_dct_2d(in, out_r);
for (int j = 0; j < kNumCoeffs; ++j) {
for (int j = 0; j < kNumCoeffs; ++j)
coeff[j] = static_cast<tran_low_t>(round(out_r[j]));
}
if (bit_depth_ == VPX_BITS_8) {
ASM_REGISTER_STATE_CHECK(inv_txfm_(coeff, dst, 32));
#if CONFIG_VP9_HIGHBITDEPTH
@@ -286,122 +302,59 @@ TEST_P(Trans32x32Test, InverseAccuracy) {
const int diff = dst[j] - src[j];
#endif
const int error = diff * diff;
EXPECT_GE(1, error) << "Error: 32x32 IDCT has error " << error
EXPECT_GE(1, error)
<< "Error: 32x32 IDCT has error " << error
<< " at index " << j;
}
}
}
class PartialTrans32x32Test
: public ::testing::TestWithParam<
std::tr1::tuple<FwdTxfmFunc, vpx_bit_depth_t> > {
public:
virtual ~PartialTrans32x32Test() {}
virtual void SetUp() {
fwd_txfm_ = GET_PARAM(0);
bit_depth_ = GET_PARAM(1);
}
virtual void TearDown() { libvpx_test::ClearSystemState(); }
protected:
vpx_bit_depth_t bit_depth_;
FwdTxfmFunc fwd_txfm_;
};
TEST_P(PartialTrans32x32Test, Extremes) {
#if CONFIG_VP9_HIGHBITDEPTH
const int16_t maxval =
static_cast<int16_t>(clip_pixel_highbd(1 << 30, bit_depth_));
#else
const int16_t maxval = 255;
#endif
const int minval = -maxval;
DECLARE_ALIGNED(16, int16_t, input[kNumCoeffs]);
DECLARE_ALIGNED(16, tran_low_t, output[kNumCoeffs]);
for (int i = 0; i < kNumCoeffs; ++i) input[i] = maxval;
output[0] = 0;
ASM_REGISTER_STATE_CHECK(fwd_txfm_(input, output, 32));
EXPECT_EQ((maxval * kNumCoeffs) >> 3, output[0]);
for (int i = 0; i < kNumCoeffs; ++i) input[i] = minval;
output[0] = 0;
ASM_REGISTER_STATE_CHECK(fwd_txfm_(input, output, 32));
EXPECT_EQ((minval * kNumCoeffs) >> 3, output[0]);
}
TEST_P(PartialTrans32x32Test, Random) {
#if CONFIG_VP9_HIGHBITDEPTH
const int16_t maxval =
static_cast<int16_t>(clip_pixel_highbd(1 << 30, bit_depth_));
#else
const int16_t maxval = 255;
#endif
DECLARE_ALIGNED(16, int16_t, input[kNumCoeffs]);
DECLARE_ALIGNED(16, tran_low_t, output[kNumCoeffs]);
ACMRandom rnd(ACMRandom::DeterministicSeed());
int sum = 0;
for (int i = 0; i < kNumCoeffs; ++i) {
const int val = (i & 1) ? -rnd(maxval + 1) : rnd(maxval + 1);
input[i] = val;
sum += val;
}
output[0] = 0;
ASM_REGISTER_STATE_CHECK(fwd_txfm_(input, output, 32));
EXPECT_EQ(sum >> 3, output[0]);
}
using std::tr1::make_tuple;
#if CONFIG_VP9_HIGHBITDEPTH
INSTANTIATE_TEST_CASE_P(
C, Trans32x32Test,
::testing::Values(
make_tuple(&vpx_highbd_fdct32x32_c, &idct32x32_10, 0, VPX_BITS_10),
make_tuple(&vpx_highbd_fdct32x32_rd_c, &idct32x32_10, 1, VPX_BITS_10),
make_tuple(&vpx_highbd_fdct32x32_c, &idct32x32_12, 0, VPX_BITS_12),
make_tuple(&vpx_highbd_fdct32x32_rd_c, &idct32x32_12, 1, VPX_BITS_12),
make_tuple(&vpx_fdct32x32_c, &vpx_idct32x32_1024_add_c, 0, VPX_BITS_8),
make_tuple(&vpx_fdct32x32_rd_c, &vpx_idct32x32_1024_add_c, 1,
VPX_BITS_8)));
INSTANTIATE_TEST_CASE_P(
C, PartialTrans32x32Test,
::testing::Values(make_tuple(&vpx_highbd_fdct32x32_1_c, VPX_BITS_8),
make_tuple(&vpx_highbd_fdct32x32_1_c, VPX_BITS_10),
make_tuple(&vpx_highbd_fdct32x32_1_c, VPX_BITS_12)));
make_tuple(&vpx_highbd_fdct32x32_c,
&idct32x32_10, 0, VPX_BITS_10),
make_tuple(&vpx_highbd_fdct32x32_rd_c,
&idct32x32_10, 1, VPX_BITS_10),
make_tuple(&vpx_highbd_fdct32x32_c,
&idct32x32_12, 0, VPX_BITS_12),
make_tuple(&vpx_highbd_fdct32x32_rd_c,
&idct32x32_12, 1, VPX_BITS_12),
make_tuple(&vpx_fdct32x32_c,
&vpx_idct32x32_1024_add_c, 0, VPX_BITS_8),
make_tuple(&vpx_fdct32x32_rd_c,
&vpx_idct32x32_1024_add_c, 1, VPX_BITS_8)));
#else
INSTANTIATE_TEST_CASE_P(
C, Trans32x32Test,
::testing::Values(make_tuple(&vpx_fdct32x32_c, &vpx_idct32x32_1024_add_c, 0,
VPX_BITS_8),
make_tuple(&vpx_fdct32x32_rd_c, &vpx_idct32x32_1024_add_c,
1, VPX_BITS_8)));
INSTANTIATE_TEST_CASE_P(C, PartialTrans32x32Test,
::testing::Values(make_tuple(&vpx_fdct32x32_1_c,
VPX_BITS_8)));
::testing::Values(
make_tuple(&vpx_fdct32x32_c,
&vpx_idct32x32_1024_add_c, 0, VPX_BITS_8),
make_tuple(&vpx_fdct32x32_rd_c,
&vpx_idct32x32_1024_add_c, 1, VPX_BITS_8)));
#endif // CONFIG_VP9_HIGHBITDEPTH
#if HAVE_NEON && !CONFIG_VP9_HIGHBITDEPTH && !CONFIG_EMULATE_HARDWARE
#if HAVE_NEON_ASM && !CONFIG_VP9_HIGHBITDEPTH && !CONFIG_EMULATE_HARDWARE
INSTANTIATE_TEST_CASE_P(
NEON, Trans32x32Test,
::testing::Values(make_tuple(&vpx_fdct32x32_c, &vpx_idct32x32_1024_add_neon,
0, VPX_BITS_8),
::testing::Values(
make_tuple(&vpx_fdct32x32_c,
&vpx_idct32x32_1024_add_neon, 0, VPX_BITS_8),
make_tuple(&vpx_fdct32x32_rd_c,
&vpx_idct32x32_1024_add_neon, 1, VPX_BITS_8)));
#endif // HAVE_NEON && !CONFIG_VP9_HIGHBITDEPTH && !CONFIG_EMULATE_HARDWARE
#endif // HAVE_NEON_ASM && !CONFIG_VP9_HIGHBITDEPTH && !CONFIG_EMULATE_HARDWARE
#if HAVE_SSE2 && !CONFIG_VP9_HIGHBITDEPTH && !CONFIG_EMULATE_HARDWARE
INSTANTIATE_TEST_CASE_P(
SSE2, Trans32x32Test,
::testing::Values(make_tuple(&vpx_fdct32x32_sse2,
::testing::Values(
make_tuple(&vpx_fdct32x32_sse2,
&vpx_idct32x32_1024_add_sse2, 0, VPX_BITS_8),
make_tuple(&vpx_fdct32x32_rd_sse2,
&vpx_idct32x32_1024_add_sse2, 1, VPX_BITS_8)));
INSTANTIATE_TEST_CASE_P(SSE2, PartialTrans32x32Test,
::testing::Values(make_tuple(&vpx_fdct32x32_1_sse2,
VPX_BITS_8)));
#endif // HAVE_SSE2 && !CONFIG_VP9_HIGHBITDEPTH && !CONFIG_EMULATE_HARDWARE
#if HAVE_SSE2 && CONFIG_VP9_HIGHBITDEPTH && !CONFIG_EMULATE_HARDWARE
@@ -418,15 +371,13 @@ INSTANTIATE_TEST_CASE_P(
VPX_BITS_8),
make_tuple(&vpx_fdct32x32_rd_sse2, &vpx_idct32x32_1024_add_c, 1,
VPX_BITS_8)));
INSTANTIATE_TEST_CASE_P(SSE2, PartialTrans32x32Test,
::testing::Values(make_tuple(&vpx_fdct32x32_1_sse2,
VPX_BITS_8)));
#endif // HAVE_SSE2 && CONFIG_VP9_HIGHBITDEPTH && !CONFIG_EMULATE_HARDWARE
#if HAVE_AVX2 && !CONFIG_VP9_HIGHBITDEPTH && !CONFIG_EMULATE_HARDWARE
INSTANTIATE_TEST_CASE_P(
AVX2, Trans32x32Test,
::testing::Values(make_tuple(&vpx_fdct32x32_avx2,
::testing::Values(
make_tuple(&vpx_fdct32x32_avx2,
&vpx_idct32x32_1024_add_sse2, 0, VPX_BITS_8),
make_tuple(&vpx_fdct32x32_rd_avx2,
&vpx_idct32x32_1024_add_sse2, 1, VPX_BITS_8)));
@@ -435,12 +386,10 @@ INSTANTIATE_TEST_CASE_P(
#if HAVE_MSA && !CONFIG_VP9_HIGHBITDEPTH && !CONFIG_EMULATE_HARDWARE
INSTANTIATE_TEST_CASE_P(
MSA, Trans32x32Test,
::testing::Values(make_tuple(&vpx_fdct32x32_msa,
::testing::Values(
make_tuple(&vpx_fdct32x32_msa,
&vpx_idct32x32_1024_add_msa, 0, VPX_BITS_8),
make_tuple(&vpx_fdct32x32_rd_msa,
&vpx_idct32x32_1024_add_msa, 1, VPX_BITS_8)));
INSTANTIATE_TEST_CASE_P(MSA, PartialTrans32x32Test,
::testing::Values(make_tuple(&vpx_fdct32x32_1_msa,
VPX_BITS_8)));
#endif // HAVE_MSA && !CONFIG_VP9_HIGHBITDEPTH && !CONFIG_EMULATE_HARDWARE
} // namespace

View File

@@ -26,6 +26,9 @@ TEST(DecodeAPI, InvalidParams) {
#endif
#if CONFIG_VP9_DECODER
&vpx_codec_vp9_dx_algo,
#endif
#if CONFIG_VP10_DECODER
&vpx_codec_vp10_dx_algo,
#endif
};
uint8_t buf[1] = {0};
@@ -51,7 +54,8 @@ TEST(DecodeAPI, InvalidParams) {
vpx_codec_decode(&dec, buf, NELEMENTS(buf), NULL, 0));
EXPECT_EQ(VPX_CODEC_INVALID_PARAM,
vpx_codec_decode(&dec, NULL, NELEMENTS(buf), NULL, 0));
EXPECT_EQ(VPX_CODEC_INVALID_PARAM, vpx_codec_decode(&dec, buf, 0, NULL, 0));
EXPECT_EQ(VPX_CODEC_INVALID_PARAM,
vpx_codec_decode(&dec, buf, 0, NULL, 0));
EXPECT_EQ(VPX_CODEC_OK, vpx_codec_destroy(&dec));
}
@@ -76,9 +80,12 @@ TEST(DecodeAPI, OptionalParams) {
// Test VP9 codec controls after a decode error to ensure the code doesn't
// misbehave.
void TestVp9Controls(vpx_codec_ctx_t *dec) {
static const int kControls[] = { VP8D_GET_LAST_REF_UPDATES,
static const int kControls[] = {
VP8D_GET_LAST_REF_UPDATES,
VP8D_GET_FRAME_CORRUPTED,
VP9D_GET_DISPLAY_SIZE, VP9D_GET_FRAME_SIZE };
VP9D_GET_DISPLAY_SIZE,
VP9D_GET_FRAME_SIZE
};
int val[2];
for (int i = 0; i < NELEMENTS(kControls); ++i) {
@@ -87,7 +94,9 @@ void TestVp9Controls(vpx_codec_ctx_t *dec) {
case VP8D_GET_FRAME_CORRUPTED:
EXPECT_EQ(VPX_CODEC_ERROR, res) << kControls[i];
break;
default: EXPECT_EQ(VPX_CODEC_OK, res) << kControls[i]; break;
default:
EXPECT_EQ(VPX_CODEC_OK, res) << kControls[i];
break;
}
EXPECT_EQ(VPX_CODEC_INVALID_PARAM,
vpx_codec_control_(dec, kControls[i], NULL));
@@ -137,39 +146,6 @@ TEST(DecodeAPI, Vp9InvalidDecode) {
TestVp9Controls(&dec);
EXPECT_EQ(VPX_CODEC_OK, vpx_codec_destroy(&dec));
}
TEST(DecodeAPI, Vp9PeekSI) {
const vpx_codec_iface_t *const codec = &vpx_codec_vp9_dx_algo;
// The first 9 bytes are valid and the rest of the bytes are made up. Until
// size 10, this should return VPX_CODEC_UNSUP_BITSTREAM and after that it
// should return VPX_CODEC_CORRUPT_FRAME.
const uint8_t data[32] = {
0x85, 0xa4, 0xc1, 0xa1, 0x38, 0x81, 0xa3, 0x49, 0x83, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
};
for (uint32_t data_sz = 1; data_sz <= 32; ++data_sz) {
// Verify behavior of vpx_codec_decode. vpx_codec_decode doesn't even get
// to decoder_peek_si_internal on frames of size < 8.
if (data_sz >= 8) {
vpx_codec_ctx_t dec;
EXPECT_EQ(VPX_CODEC_OK, vpx_codec_dec_init(&dec, codec, NULL, 0));
EXPECT_EQ(
(data_sz < 10) ? VPX_CODEC_UNSUP_BITSTREAM : VPX_CODEC_CORRUPT_FRAME,
vpx_codec_decode(&dec, data, data_sz, NULL, 0));
vpx_codec_iter_t iter = NULL;
EXPECT_EQ(NULL, vpx_codec_get_frame(&dec, &iter));
EXPECT_EQ(VPX_CODEC_OK, vpx_codec_destroy(&dec));
}
// Verify behavior of vpx_codec_peek_stream_info.
vpx_codec_stream_info_t si;
si.sz = sizeof(si);
EXPECT_EQ((data_sz < 10) ? VPX_CODEC_UNSUP_BITSTREAM : VPX_CODEC_OK,
vpx_codec_peek_stream_info(codec, data, data_sz, &si));
}
}
#endif // CONFIG_VP9_DECODER
} // namespace

View File

@@ -28,6 +28,7 @@ namespace {
#define VIDEO_NAME 0
#define THREADS 1
const int kMaxPsnr = 100;
const double kUsecsInSec = 1000000.0;
const char kNewEncodeOutputFile[] = "new_encode.ivf";
@@ -69,7 +70,8 @@ const DecodePerfParam kVP9DecodePerfVectors[] = {
power/temp/min max frame decode times/etc
*/
class DecodePerfTest : public ::testing::TestWithParam<DecodePerfParam> {};
class DecodePerfTest : public ::testing::TestWithParam<DecodePerfParam> {
};
TEST_P(DecodePerfTest, PerfTest) {
const char *const video_name = GET_PARAM(VIDEO_NAME);
@@ -90,7 +92,8 @@ TEST_P(DecodePerfTest, PerfTest) {
}
vpx_usec_timer_mark(&t);
const double elapsed_secs = double(vpx_usec_timer_elapsed(&t)) / kUsecsInSec;
const double elapsed_secs = double(vpx_usec_timer_elapsed(&t))
/ kUsecsInSec;
const unsigned frames = video.frame_number();
const double fps = double(frames) / elapsed_secs;
@@ -108,13 +111,17 @@ TEST_P(DecodePerfTest, PerfTest) {
INSTANTIATE_TEST_CASE_P(VP9, DecodePerfTest,
::testing::ValuesIn(kVP9DecodePerfVectors));
class VP9NewEncodeDecodePerfTest
: public ::libvpx_test::EncoderTest,
class VP9NewEncodeDecodePerfTest :
public ::libvpx_test::EncoderTest,
public ::libvpx_test::CodecTestWithParam<libvpx_test::TestMode> {
protected:
VP9NewEncodeDecodePerfTest()
: EncoderTest(GET_PARAM(0)), encoding_mode_(GET_PARAM(1)), speed_(0),
outfile_(0), out_frames_(0) {}
: EncoderTest(GET_PARAM(0)),
encoding_mode_(GET_PARAM(1)),
speed_(0),
outfile_(0),
out_frames_(0) {
}
virtual ~VP9NewEncodeDecodePerfTest() {}
@@ -153,9 +160,8 @@ class VP9NewEncodeDecodePerfTest
virtual void EndPassHook() {
if (outfile_ != NULL) {
if (!fseek(outfile_, 0, SEEK_SET)) {
if (!fseek(outfile_, 0, SEEK_SET))
ivf_write_file_header(outfile_, &cfg_, VP9_FOURCC, out_frames_);
}
fclose(outfile_);
outfile_ = NULL;
}
@@ -165,9 +171,8 @@ class VP9NewEncodeDecodePerfTest
++out_frames_;
// Write initial file header if first frame.
if (pkt->data.frame.pts == 0) {
if (pkt->data.frame.pts == 0)
ivf_write_file_header(outfile_, &cfg_, VP9_FOURCC, out_frames_);
}
// Write frame header and data.
ivf_write_frame_header(outfile_, out_frames_, pkt->data.frame.sz);
@@ -175,9 +180,11 @@ class VP9NewEncodeDecodePerfTest
pkt->data.frame.sz);
}
virtual bool DoDecode() const { return false; }
virtual bool DoDecode() { return false; }
void set_speed(unsigned int speed) { speed_ = speed; }
void set_speed(unsigned int speed) {
speed_ = speed;
}
private:
libvpx_test::TestMode encoding_mode_;
@@ -189,7 +196,10 @@ class VP9NewEncodeDecodePerfTest
struct EncodePerfTestVideo {
EncodePerfTestVideo(const char *name_, uint32_t width_, uint32_t height_,
uint32_t bitrate_, int frames_)
: name(name_), width(width_), height(height_), bitrate(bitrate_),
: name(name_),
width(width_),
height(height_),
bitrate(bitrate_),
frames(frames_) {}
const char *name;
uint32_t width;
@@ -215,8 +225,10 @@ TEST_P(VP9NewEncodeDecodePerfTest, PerfTest) {
const char *video_name = kVP9EncodePerfTestVectors[i].name;
libvpx_test::I420VideoSource video(
video_name, kVP9EncodePerfTestVectors[i].width,
kVP9EncodePerfTestVectors[i].height, timebase.den, timebase.num, 0,
video_name,
kVP9EncodePerfTestVectors[i].width,
kVP9EncodePerfTestVectors[i].height,
timebase.den, timebase.num, 0,
kVP9EncodePerfTestVectors[i].frames);
set_speed(2);
@@ -256,6 +268,6 @@ TEST_P(VP9NewEncodeDecodePerfTest, PerfTest) {
printf("}\n");
}
VP9_INSTANTIATE_TEST_CASE(VP9NewEncodeDecodePerfTest,
::testing::Values(::libvpx_test::kTwoPassGood));
VP9_INSTANTIATE_TEST_CASE(
VP9NewEncodeDecodePerfTest, ::testing::Values(::libvpx_test::kTwoPassGood));
} // namespace

View File

@@ -21,8 +21,9 @@ const char kVP8Name[] = "WebM Project VP8";
vpx_codec_err_t Decoder::PeekStream(const uint8_t *cxdata, size_t size,
vpx_codec_stream_info_t *stream_info) {
return vpx_codec_peek_stream_info(
CodecInterface(), cxdata, static_cast<unsigned int>(size), stream_info);
return vpx_codec_peek_stream_info(CodecInterface(),
cxdata, static_cast<unsigned int>(size),
stream_info);
}
vpx_codec_err_t Decoder::DecodeFrame(const uint8_t *cxdata, size_t size) {
@@ -34,8 +35,9 @@ vpx_codec_err_t Decoder::DecodeFrame(const uint8_t *cxdata, size_t size,
vpx_codec_err_t res_dec;
InitOnce();
API_REGISTER_STATE_CHECK(
res_dec = vpx_codec_decode(
&decoder_, cxdata, static_cast<unsigned int>(size), user_priv, 0));
res_dec = vpx_codec_decode(&decoder_,
cxdata, static_cast<unsigned int>(size),
user_priv, 0));
return res_dec;
}
@@ -65,7 +67,7 @@ void DecoderTest::HandlePeekResult(Decoder *const decoder,
void DecoderTest::RunLoop(CompressedVideoSource *video,
const vpx_codec_dec_cfg_t &dec_cfg) {
Decoder *const decoder = codec_->CreateDecoder(dec_cfg, flags_);
Decoder* const decoder = codec_->CreateDecoder(dec_cfg, flags_, 0);
ASSERT_TRUE(decoder != NULL);
bool end_of_file = false;
@@ -78,14 +80,16 @@ void DecoderTest::RunLoop(CompressedVideoSource *video,
stream_info.sz = sizeof(stream_info);
if (video->cxdata() != NULL) {
const vpx_codec_err_t res_peek = decoder->PeekStream(
video->cxdata(), video->frame_size(), &stream_info);
const vpx_codec_err_t res_peek = decoder->PeekStream(video->cxdata(),
video->frame_size(),
&stream_info);
HandlePeekResult(decoder, video, res_peek);
ASSERT_FALSE(::testing::Test::HasFailure());
vpx_codec_err_t res_dec =
decoder->DecodeFrame(video->cxdata(), video->frame_size());
if (!HandleDecodeResult(res_dec, *video, decoder)) break;
vpx_codec_err_t res_dec = decoder->DecodeFrame(video->cxdata(),
video->frame_size());
if (!HandleDecodeResult(res_dec, *video, decoder))
break;
} else {
// Signal end of the file to the decoder.
const vpx_codec_err_t res_dec = decoder->DecodeFrame(NULL, 0);
@@ -97,10 +101,9 @@ void DecoderTest::RunLoop(CompressedVideoSource *video,
const vpx_image_t *img = NULL;
// Get decompressed data
while ((img = dec_iter.Next())) {
while ((img = dec_iter.Next()))
DecompressedFrameHook(*img, video->frame_number());
}
}
delete decoder;
}
@@ -113,6 +116,8 @@ void DecoderTest::set_cfg(const vpx_codec_dec_cfg_t &dec_cfg) {
memcpy(&cfg_, &dec_cfg, sizeof(cfg_));
}
void DecoderTest::set_flags(const vpx_codec_flags_t flags) { flags_ = flags; }
void DecoderTest::set_flags(const vpx_codec_flags_t flags) {
flags_ = flags;
}
} // namespace libvpx_test

View File

@@ -26,7 +26,9 @@ class DxDataIterator {
explicit DxDataIterator(vpx_codec_ctx_t *decoder)
: decoder_(decoder), iter_(NULL) {}
const vpx_image_t *Next() { return vpx_codec_get_frame(decoder_, &iter_); }
const vpx_image_t *Next() {
return vpx_codec_get_frame(decoder_, &iter_);
}
private:
vpx_codec_ctx_t *decoder_;
@@ -38,17 +40,20 @@ class DxDataIterator {
// as more tests are added.
class Decoder {
public:
explicit Decoder(vpx_codec_dec_cfg_t cfg)
: cfg_(cfg), flags_(0), init_done_(false) {
Decoder(vpx_codec_dec_cfg_t cfg, unsigned long deadline)
: cfg_(cfg), flags_(0), deadline_(deadline), init_done_(false) {
memset(&decoder_, 0, sizeof(decoder_));
}
Decoder(vpx_codec_dec_cfg_t cfg, const vpx_codec_flags_t flag)
: cfg_(cfg), flags_(flag), init_done_(false) {
Decoder(vpx_codec_dec_cfg_t cfg, const vpx_codec_flags_t flag,
unsigned long deadline) // NOLINT
: cfg_(cfg), flags_(flag), deadline_(deadline), init_done_(false) {
memset(&decoder_, 0, sizeof(decoder_));
}
virtual ~Decoder() { vpx_codec_destroy(&decoder_); }
virtual ~Decoder() {
vpx_codec_destroy(&decoder_);
}
vpx_codec_err_t PeekStream(const uint8_t *cxdata, size_t size,
vpx_codec_stream_info_t *stream_info);
@@ -58,9 +63,17 @@ class Decoder {
vpx_codec_err_t DecodeFrame(const uint8_t *cxdata, size_t size,
void *user_priv);
DxDataIterator GetDxData() { return DxDataIterator(&decoder_); }
DxDataIterator GetDxData() {
return DxDataIterator(&decoder_);
}
void Control(int ctrl_id, int arg) { Control(ctrl_id, arg, VPX_CODEC_OK); }
void set_deadline(unsigned long deadline) {
deadline_ = deadline;
}
void Control(int ctrl_id, int arg) {
Control(ctrl_id, arg, VPX_CODEC_OK);
}
void Control(int ctrl_id, const void *arg) {
InitOnce();
@@ -84,8 +97,8 @@ class Decoder {
vpx_get_frame_buffer_cb_fn_t cb_get,
vpx_release_frame_buffer_cb_fn_t cb_release, void *user_priv) {
InitOnce();
return vpx_codec_set_frame_buffer_functions(&decoder_, cb_get, cb_release,
user_priv);
return vpx_codec_set_frame_buffer_functions(
&decoder_, cb_get, cb_release, user_priv);
}
const char* GetDecoderName() const {
@@ -94,15 +107,18 @@ class Decoder {
bool IsVP8() const;
vpx_codec_ctx_t *GetDecoder() { return &decoder_; }
vpx_codec_ctx_t * GetDecoder() {
return &decoder_;
}
protected:
virtual vpx_codec_iface_t* CodecInterface() const = 0;
void InitOnce() {
if (!init_done_) {
const vpx_codec_err_t res =
vpx_codec_dec_init(&decoder_, CodecInterface(), &cfg_, flags_);
const vpx_codec_err_t res = vpx_codec_dec_init(&decoder_,
CodecInterface(),
&cfg_, flags_);
ASSERT_EQ(VPX_CODEC_OK, res) << DecodeError();
init_done_ = true;
}
@@ -111,6 +127,7 @@ class Decoder {
vpx_codec_ctx_t decoder_;
vpx_codec_dec_cfg_t cfg_;
vpx_codec_flags_t flags_;
unsigned int deadline_;
bool init_done_;
};
@@ -148,7 +165,9 @@ class DecoderTest {
protected:
explicit DecoderTest(const CodecFactory *codec)
: codec_(codec), cfg_(), flags_(0) {}
: codec_(codec),
cfg_(),
flags_(0) {}
virtual ~DecoderTest() {}

View File

@@ -1,65 +0,0 @@
/*
* Copyright (c) 2016 The WebM project authors. All Rights Reserved.
*
* Use of this source code is governed by a BSD-style license
* that can be found in the LICENSE file in the root of the source
* tree. An additional intellectual property rights grant can be found
* in the file PATENTS. All contributing project authors may
* be found in the AUTHORS file in the root of the source tree.
*/
#include "third_party/googletest/src/include/gtest/gtest.h"
#include "./vpx_config.h"
#include "vpx/vp8cx.h"
#include "vpx/vpx_encoder.h"
namespace {
#define NELEMENTS(x) static_cast<int>(sizeof(x) / sizeof(x[0]))
TEST(EncodeAPI, InvalidParams) {
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
};
uint8_t buf[1] = { 0 };
vpx_image_t img;
vpx_codec_ctx_t enc;
vpx_codec_enc_cfg_t cfg;
EXPECT_EQ(&img, vpx_img_wrap(&img, VPX_IMG_FMT_I420, 1, 1, 1, buf));
EXPECT_EQ(VPX_CODEC_INVALID_PARAM, vpx_codec_enc_init(NULL, NULL, NULL, 0));
EXPECT_EQ(VPX_CODEC_INVALID_PARAM, vpx_codec_enc_init(&enc, NULL, NULL, 0));
EXPECT_EQ(VPX_CODEC_INVALID_PARAM, vpx_codec_encode(NULL, NULL, 0, 0, 0, 0));
EXPECT_EQ(VPX_CODEC_INVALID_PARAM, vpx_codec_encode(NULL, &img, 0, 0, 0, 0));
EXPECT_EQ(VPX_CODEC_INVALID_PARAM, vpx_codec_destroy(NULL));
EXPECT_EQ(VPX_CODEC_INVALID_PARAM,
vpx_codec_enc_config_default(NULL, NULL, 0));
EXPECT_EQ(VPX_CODEC_INVALID_PARAM,
vpx_codec_enc_config_default(NULL, &cfg, 0));
EXPECT_TRUE(vpx_codec_error(NULL) != NULL);
for (int i = 0; i < NELEMENTS(kCodecs); ++i) {
SCOPED_TRACE(vpx_codec_iface_name(kCodecs[i]));
EXPECT_EQ(VPX_CODEC_INVALID_PARAM,
vpx_codec_enc_init(NULL, kCodecs[i], NULL, 0));
EXPECT_EQ(VPX_CODEC_INVALID_PARAM,
vpx_codec_enc_init(&enc, kCodecs[i], NULL, 0));
EXPECT_EQ(VPX_CODEC_INVALID_PARAM,
vpx_codec_enc_config_default(kCodecs[i], &cfg, 1));
EXPECT_EQ(VPX_CODEC_OK, vpx_codec_enc_config_default(kCodecs[i], &cfg, 0));
EXPECT_EQ(VPX_CODEC_OK, vpx_codec_enc_init(&enc, kCodecs[i], &cfg, 0));
EXPECT_EQ(VPX_CODEC_OK, vpx_codec_encode(&enc, NULL, 0, 0, 0, 0));
EXPECT_EQ(VPX_CODEC_OK, vpx_codec_destroy(&enc));
}
}
} // namespace

View File

@@ -26,7 +26,10 @@ const double kUsecsInSec = 1000000.0;
struct EncodePerfTestVideo {
EncodePerfTestVideo(const char *name_, uint32_t width_, uint32_t height_,
uint32_t bitrate_, int frames_)
: name(name_), width(width_), height(height_), bitrate(bitrate_),
: name(name_),
width(width_),
height(height_),
bitrate(bitrate_),
frames(frames_) {}
const char *name;
uint32_t width;
@@ -42,8 +45,8 @@ const EncodePerfTestVideo kVP9EncodePerfTestVectors[] = {
EncodePerfTestVideo("macmarcostationary_640_480_30.yuv", 640, 480, 200, 718),
EncodePerfTestVideo("niklas_640_480_30.yuv", 640, 480, 200, 471),
EncodePerfTestVideo("tacomanarrows_640_480_30.yuv", 640, 480, 200, 300),
EncodePerfTestVideo("tacomasmallcameramovement_640_480_30.yuv", 640, 480, 200,
300),
EncodePerfTestVideo("tacomasmallcameramovement_640_480_30.yuv",
640, 480, 200, 300),
EncodePerfTestVideo("thaloundeskmtg_640_480_30.yuv", 640, 480, 200, 300),
EncodePerfTestVideo("niklas_1280_720_30.yuv", 1280, 720, 600, 470),
};
@@ -58,8 +61,12 @@ class VP9EncodePerfTest
public ::libvpx_test::CodecTestWithParam<libvpx_test::TestMode> {
protected:
VP9EncodePerfTest()
: EncoderTest(GET_PARAM(0)), min_psnr_(kMaxPsnr), nframes_(0),
encoding_mode_(GET_PARAM(1)), speed_(0), threads_(1) {}
: EncoderTest(GET_PARAM(0)),
min_psnr_(kMaxPsnr),
nframes_(0),
encoding_mode_(GET_PARAM(1)),
speed_(0),
threads_(1) {}
virtual ~VP9EncodePerfTest() {}
@@ -105,13 +112,19 @@ class VP9EncodePerfTest
}
// for performance reasons don't decode
virtual bool DoDecode() const { return false; }
virtual bool DoDecode() { return 0; }
double min_psnr() const { return min_psnr_; }
double min_psnr() const {
return min_psnr_;
}
void set_speed(unsigned int speed) { speed_ = speed; }
void set_speed(unsigned int speed) {
speed_ = speed;
}
void set_threads(unsigned int threads) { threads_ = threads; }
void set_threads(unsigned int threads) {
threads_ = threads;
}
private:
double min_psnr_;
@@ -126,12 +139,11 @@ TEST_P(VP9EncodePerfTest, PerfTest) {
for (size_t j = 0; j < NELEMENTS(kEncodePerfTestSpeeds); ++j) {
for (size_t k = 0; k < NELEMENTS(kEncodePerfTestThreads); ++k) {
if (kVP9EncodePerfTestVectors[i].width < 512 &&
kEncodePerfTestThreads[k] > 1) {
kEncodePerfTestThreads[k] > 1)
continue;
} else if (kVP9EncodePerfTestVectors[i].width < 1024 &&
kEncodePerfTestThreads[k] > 2) {
else if (kVP9EncodePerfTestVectors[i].width < 1024 &&
kEncodePerfTestThreads[k] > 2)
continue;
}
set_threads(kEncodePerfTestThreads[k]);
SetUp();
@@ -145,8 +157,10 @@ TEST_P(VP9EncodePerfTest, PerfTest) {
const unsigned frames = kVP9EncodePerfTestVectors[i].frames;
const char *video_name = kVP9EncodePerfTestVectors[i].name;
libvpx_test::I420VideoSource video(
video_name, kVP9EncodePerfTestVectors[i].width,
kVP9EncodePerfTestVectors[i].height, timebase.den, timebase.num, 0,
video_name,
kVP9EncodePerfTestVectors[i].width,
kVP9EncodePerfTestVectors[i].height,
timebase.den, timebase.num, 0,
kVP9EncodePerfTestVectors[i].frames);
set_speed(kEncodePerfTestSpeeds[j]);
@@ -183,6 +197,6 @@ TEST_P(VP9EncodePerfTest, PerfTest) {
}
}
VP9_INSTANTIATE_TEST_CASE(VP9EncodePerfTest,
::testing::Values(::libvpx_test::kRealTime));
VP9_INSTANTIATE_TEST_CASE(
VP9EncodePerfTest, ::testing::Values(::libvpx_test::kRealTime));
} // namespace

View File

@@ -30,7 +30,8 @@ void Encoder::InitEncoder(VideoSource *video) {
cfg_.g_timebase = video->timebase();
cfg_.rc_twopass_stats_in = stats_->buf();
res = vpx_codec_enc_init(&encoder_, CodecInterface(), &cfg_, init_flags_);
res = vpx_codec_enc_init(&encoder_, CodecInterface(), &cfg_,
init_flags_);
ASSERT_EQ(VPX_CODEC_OK, res) << EncoderError();
#if CONFIG_VP9_ENCODER
@@ -41,6 +42,15 @@ void Encoder::InitEncoder(VideoSource *video) {
log2_tile_columns);
ASSERT_EQ(VPX_CODEC_OK, res) << EncoderError();
} else
#endif
#if CONFIG_VP10_ENCODER
if (CodecInterface() == &vpx_codec_vp10_cx_algo) {
// Default to 1 tile column for VP10.
const int log2_tile_columns = 0;
res = vpx_codec_control_(&encoder_, VP9E_SET_TILE_COLUMNS,
log2_tile_columns);
ASSERT_EQ(VPX_CODEC_OK, res) << EncoderError();
} else
#endif
{
#if CONFIG_VP8_ENCODER
@@ -52,17 +62,17 @@ void Encoder::InitEncoder(VideoSource *video) {
}
void Encoder::EncodeFrame(VideoSource *video, const unsigned long frame_flags) {
if (video->img()) {
if (video->img())
EncodeFrameInternal(*video, frame_flags);
} else {
else
Flush();
}
// Handle twopass stats
CxDataIterator iter = GetCxData();
while (const vpx_codec_cx_pkt_t *pkt = iter.Next()) {
if (pkt->kind != VPX_CODEC_STATS_PKT) continue;
if (pkt->kind != VPX_CODEC_STATS_PKT)
continue;
stats_->Append(*pkt);
}
@@ -82,15 +92,15 @@ void Encoder::EncodeFrameInternal(const VideoSource &video,
}
// Encode the frame
API_REGISTER_STATE_CHECK(res = vpx_codec_encode(&encoder_, img, video.pts(),
video.duration(), frame_flags,
deadline_));
API_REGISTER_STATE_CHECK(
res = vpx_codec_encode(&encoder_, img, video.pts(), video.duration(),
frame_flags, deadline_));
ASSERT_EQ(VPX_CODEC_OK, res) << EncoderError();
}
void Encoder::Flush() {
const vpx_codec_err_t res =
vpx_codec_encode(&encoder_, NULL, 0, 0, 0, deadline_);
const vpx_codec_err_t res = vpx_codec_encode(&encoder_, NULL, 0, 0, 0,
deadline_);
if (!encoder_.priv)
ASSERT_EQ(VPX_CODEC_ERROR, res) << EncoderError();
else
@@ -105,52 +115,55 @@ void EncoderTest::InitializeConfig() {
void EncoderTest::SetMode(TestMode mode) {
switch (mode) {
case kRealTime: deadline_ = VPX_DL_REALTIME; break;
case kRealTime:
deadline_ = VPX_DL_REALTIME;
break;
case kOnePassGood:
case kTwoPassGood: deadline_ = VPX_DL_GOOD_QUALITY; break;
case kTwoPassGood:
deadline_ = VPX_DL_GOOD_QUALITY;
break;
case kOnePassBest:
case kTwoPassBest: deadline_ = VPX_DL_BEST_QUALITY; break;
case kTwoPassBest:
deadline_ = VPX_DL_BEST_QUALITY;
break;
default: ASSERT_TRUE(false) << "Unexpected mode " << mode;
default:
ASSERT_TRUE(false) << "Unexpected mode " << mode;
}
if (mode == kTwoPassGood || mode == kTwoPassBest) {
if (mode == kTwoPassGood || mode == kTwoPassBest)
passes_ = 2;
} else {
else
passes_ = 1;
}
}
// The function should return "true" most of the time, therefore no early
// break-out is implemented within the match checking process.
static bool compare_img(const vpx_image_t *img1, const vpx_image_t *img2) {
bool match = (img1->fmt == img2->fmt) && (img1->cs == img2->cs) &&
(img1->d_w == img2->d_w) && (img1->d_h == img2->d_h);
static bool compare_img(const vpx_image_t *img1,
const vpx_image_t *img2) {
bool match = (img1->fmt == img2->fmt) &&
(img1->cs == img2->cs) &&
(img1->d_w == img2->d_w) &&
(img1->d_h == img2->d_h);
const unsigned int width_y = img1->d_w;
const unsigned int height_y = img1->d_h;
unsigned int i;
for (i = 0; i < height_y; ++i) {
for (i = 0; i < height_y; ++i)
match = (memcmp(img1->planes[VPX_PLANE_Y] + i * img1->stride[VPX_PLANE_Y],
img2->planes[VPX_PLANE_Y] + i * img2->stride[VPX_PLANE_Y],
width_y) == 0) &&
match;
}
width_y) == 0) && match;
const unsigned int width_uv = (img1->d_w + 1) >> 1;
const unsigned int height_uv = (img1->d_h + 1) >> 1;
for (i = 0; i < height_uv; ++i) {
for (i = 0; i < height_uv; ++i)
match = (memcmp(img1->planes[VPX_PLANE_U] + i * img1->stride[VPX_PLANE_U],
img2->planes[VPX_PLANE_U] + i * img2->stride[VPX_PLANE_U],
width_uv) == 0) &&
match;
}
for (i = 0; i < height_uv; ++i) {
width_uv) == 0) && match;
for (i = 0; i < height_uv; ++i)
match = (memcmp(img1->planes[VPX_PLANE_V] + i * img1->stride[VPX_PLANE_V],
img2->planes[VPX_PLANE_V] + i * img2->stride[VPX_PLANE_V],
width_uv) == 0) &&
match;
}
width_uv) == 0) && match;
return match;
}
@@ -168,37 +181,34 @@ void EncoderTest::RunLoop(VideoSource *video) {
for (unsigned int pass = 0; pass < passes_; pass++) {
last_pts_ = 0;
if (passes_ == 1) {
if (passes_ == 1)
cfg_.g_pass = VPX_RC_ONE_PASS;
} else if (pass == 0) {
else if (pass == 0)
cfg_.g_pass = VPX_RC_FIRST_PASS;
} else {
else
cfg_.g_pass = VPX_RC_LAST_PASS;
}
BeginPassHook(pass);
testing::internal::scoped_ptr<Encoder> encoder(
codec_->CreateEncoder(cfg_, deadline_, init_flags_, &stats_));
ASSERT_TRUE(encoder.get() != NULL);
Encoder* const encoder = codec_->CreateEncoder(cfg_, deadline_, init_flags_,
&stats_);
ASSERT_TRUE(encoder != NULL);
ASSERT_NO_FATAL_FAILURE(video->Begin());
video->Begin();
encoder->InitEncoder(video);
ASSERT_FALSE(::testing::Test::HasFatalFailure());
unsigned long dec_init_flags = 0; // NOLINT
// Use fragment decoder if encoder outputs partitions.
// NOTE: fragment decoder and partition encoder are only supported by VP8.
if (init_flags_ & VPX_CODEC_USE_OUTPUT_PARTITION) {
if (init_flags_ & VPX_CODEC_USE_OUTPUT_PARTITION)
dec_init_flags |= VPX_CODEC_USE_INPUT_FRAGMENTS;
}
testing::internal::scoped_ptr<Decoder> decoder(
codec_->CreateDecoder(dec_cfg, dec_init_flags));
Decoder* const decoder = codec_->CreateDecoder(dec_cfg, dec_init_flags, 0);
bool again;
for (again = true; again; video->Next()) {
again = (video->img() != NULL);
PreEncodeFrameHook(video);
PreEncodeFrameHook(video, encoder.get());
PreEncodeFrameHook(video, encoder);
encoder->EncodeFrame(video, frame_flags_);
CxDataIterator iter = encoder->GetCxData();
@@ -211,11 +221,12 @@ void EncoderTest::RunLoop(VideoSource *video) {
switch (pkt->kind) {
case VPX_CODEC_CX_FRAME_PKT:
has_cxdata = true;
if (decoder.get() != NULL && DoDecode()) {
if (decoder && DoDecode()) {
vpx_codec_err_t res_dec = decoder->DecodeFrame(
(const uint8_t*)pkt->data.frame.buf, pkt->data.frame.sz);
if (!HandleDecodeResult(res_dec, *video, decoder.get())) break;
if (!HandleDecodeResult(res_dec, *video, decoder))
break;
has_dxdata = true;
}
@@ -224,16 +235,20 @@ void EncoderTest::RunLoop(VideoSource *video) {
FramePktHook(pkt);
break;
case VPX_CODEC_PSNR_PKT: PSNRPktHook(pkt); break;
case VPX_CODEC_PSNR_PKT:
PSNRPktHook(pkt);
break;
default: break;
default:
break;
}
}
// Flush the decoder when there are no more fragments.
if ((init_flags_ & VPX_CODEC_USE_OUTPUT_PARTITION) && has_dxdata) {
const vpx_codec_err_t res_dec = decoder->DecodeFrame(NULL, 0);
if (!HandleDecodeResult(res_dec, *video, decoder.get())) break;
if (!HandleDecodeResult(res_dec, *video, decoder))
break;
}
if (has_dxdata && has_cxdata) {
@@ -246,14 +261,21 @@ void EncoderTest::RunLoop(VideoSource *video) {
MismatchHook(img_enc, img_dec);
}
}
if (img_dec) DecompressedFrameHook(*img_dec, video->pts());
if (img_dec)
DecompressedFrameHook(*img_dec, video->pts());
}
if (!Continue()) break;
if (!Continue())
break;
}
EndPassHook();
if (!Continue()) break;
if (decoder)
delete decoder;
delete encoder;
if (!Continue())
break;
}
}

View File

@@ -16,7 +16,7 @@
#include "third_party/googletest/src/include/gtest/gtest.h"
#include "./vpx_config.h"
#if CONFIG_VP8_ENCODER || CONFIG_VP9_ENCODER
#if CONFIG_VP8_ENCODER || CONFIG_VP9_ENCODER || CONFIG_VP10_ENCODER
#include "vpx/vp8cx.h"
#endif
#include "vpx/vpx_encoder.h"
@@ -33,17 +33,19 @@ enum TestMode {
kTwoPassGood,
kTwoPassBest
};
#define ALL_TEST_MODES \
::testing::Values(::libvpx_test::kRealTime, ::libvpx_test::kOnePassGood, \
::libvpx_test::kOnePassBest, ::libvpx_test::kTwoPassGood, \
#define ALL_TEST_MODES ::testing::Values(::libvpx_test::kRealTime, \
::libvpx_test::kOnePassGood, \
::libvpx_test::kOnePassBest, \
::libvpx_test::kTwoPassGood, \
::libvpx_test::kTwoPassBest)
#define ONE_PASS_TEST_MODES \
::testing::Values(::libvpx_test::kRealTime, ::libvpx_test::kOnePassGood, \
#define ONE_PASS_TEST_MODES ::testing::Values(::libvpx_test::kRealTime, \
::libvpx_test::kOnePassGood, \
::libvpx_test::kOnePassBest)
#define TWO_PASS_TEST_MODES \
::testing::Values(::libvpx_test::kTwoPassGood, ::libvpx_test::kTwoPassBest)
#define TWO_PASS_TEST_MODES ::testing::Values(::libvpx_test::kTwoPassGood, \
::libvpx_test::kTwoPassBest)
// Provides an object to handle the libvpx get_cx_data() iteration pattern
class CxDataIterator {
@@ -73,12 +75,15 @@ class TwopassStatsStore {
return buf;
}
void Reset() { buffer_.clear(); }
void Reset() {
buffer_.clear();
}
protected:
std::string buffer_;
};
// Provides a simplified interface to manage one video encoding pass, given
// a configuration and video source.
//
@@ -92,9 +97,13 @@ class Encoder {
memset(&encoder_, 0, sizeof(encoder_));
}
virtual ~Encoder() { vpx_codec_destroy(&encoder_); }
virtual ~Encoder() {
vpx_codec_destroy(&encoder_);
}
CxDataIterator GetCxData() { return CxDataIterator(&encoder_); }
CxDataIterator GetCxData() {
return CxDataIterator(&encoder_);
}
void InitEncoder(VideoSource *video);
@@ -106,14 +115,11 @@ class Encoder {
void EncodeFrame(VideoSource *video, const unsigned long frame_flags);
// Convenience wrapper for EncodeFrame()
void EncodeFrame(VideoSource *video) { EncodeFrame(video, 0); }
void Control(int ctrl_id, int arg) {
const vpx_codec_err_t res = vpx_codec_control_(&encoder_, ctrl_id, arg);
ASSERT_EQ(VPX_CODEC_OK, res) << EncoderError();
void EncodeFrame(VideoSource *video) {
EncodeFrame(video, 0);
}
void Control(int ctrl_id, int *arg) {
void Control(int ctrl_id, int arg) {
const vpx_codec_err_t res = vpx_codec_control_(&encoder_, ctrl_id, arg);
ASSERT_EQ(VPX_CODEC_OK, res) << EncoderError();
}
@@ -132,7 +138,7 @@ class Encoder {
const vpx_codec_err_t res = vpx_codec_control_(&encoder_, ctrl_id, arg);
ASSERT_EQ(VPX_CODEC_OK, res) << EncoderError();
}
#if CONFIG_VP8_ENCODER || CONFIG_VP9_ENCODER
#if CONFIG_VP8_ENCODER || CONFIG_VP9_ENCODER || CONFIG_VP10_ENCODER
void Control(int ctrl_id, vpx_active_map_t *arg) {
const vpx_codec_err_t res = vpx_codec_control_(&encoder_, ctrl_id, arg);
ASSERT_EQ(VPX_CODEC_OK, res) << EncoderError();
@@ -145,7 +151,9 @@ class Encoder {
cfg_ = *cfg;
}
void set_deadline(unsigned long deadline) { deadline_ = deadline; }
void set_deadline(unsigned long deadline) {
deadline_ = deadline;
}
protected:
virtual vpx_codec_iface_t* CodecInterface() const = 0;
@@ -228,7 +236,8 @@ class EncoderTest {
virtual bool DoDecode() const { return 1; }
// Hook to handle encode/decode mismatch
virtual void MismatchHook(const vpx_image_t *img1, const vpx_image_t *img2);
virtual void MismatchHook(const vpx_image_t *img1,
const vpx_image_t *img2);
// Hook to be called on every decompressed frame.
virtual void DecompressedFrameHook(const vpx_image_t& /*img*/,

View File

@@ -19,13 +19,16 @@ namespace {
const int kMaxErrorFrames = 12;
const int kMaxDroppableFrames = 12;
class ErrorResilienceTestLarge
: public ::libvpx_test::EncoderTest,
class ErrorResilienceTestLarge : public ::libvpx_test::EncoderTest,
public ::libvpx_test::CodecTestWith2Params<libvpx_test::TestMode, bool> {
protected:
ErrorResilienceTestLarge()
: EncoderTest(GET_PARAM(0)), svc_support_(GET_PARAM(2)), psnr_(0.0),
nframes_(0), mismatch_psnr_(0.0), mismatch_nframes_(0),
: EncoderTest(GET_PARAM(0)),
svc_support_(GET_PARAM(2)),
psnr_(0.0),
nframes_(0),
mismatch_psnr_(0.0),
mismatch_nframes_(0),
encoding_mode_(GET_PARAM(1)) {
Reset();
}
@@ -63,26 +66,32 @@ class ErrorResilienceTestLarge
// LAST is updated on base/layer 0, GOLDEN updated on layer 1.
// Non-zero pattern_switch parameter means pattern will switch to
// not using LAST for frame_num >= pattern_switch.
int SetFrameFlags(int frame_num, int num_temp_layers, int pattern_switch) {
int SetFrameFlags(int frame_num,
int num_temp_layers,
int pattern_switch) {
int frame_flags = 0;
if (num_temp_layers == 2) {
if (frame_num % 2 == 0) {
if (frame_num < pattern_switch || pattern_switch == 0) {
// Layer 0: predict from LAST and ARF, update LAST.
frame_flags =
VP8_EFLAG_NO_REF_GF | VP8_EFLAG_NO_UPD_GF | VP8_EFLAG_NO_UPD_ARF;
frame_flags = VP8_EFLAG_NO_REF_GF |
VP8_EFLAG_NO_UPD_GF |
VP8_EFLAG_NO_UPD_ARF;
} else {
// Layer 0: predict from GF and ARF, update GF.
frame_flags = VP8_EFLAG_NO_REF_LAST | VP8_EFLAG_NO_UPD_LAST |
frame_flags = VP8_EFLAG_NO_REF_LAST |
VP8_EFLAG_NO_UPD_LAST |
VP8_EFLAG_NO_UPD_ARF;
}
} else {
if (frame_num < pattern_switch || pattern_switch == 0) {
// Layer 1: predict from L, GF, and ARF, update GF.
frame_flags = VP8_EFLAG_NO_UPD_ARF | VP8_EFLAG_NO_UPD_LAST;
frame_flags = VP8_EFLAG_NO_UPD_ARF |
VP8_EFLAG_NO_UPD_LAST;
} else {
// Layer 1: predict from GF and ARF, update GF.
frame_flags = VP8_EFLAG_NO_REF_LAST | VP8_EFLAG_NO_UPD_LAST |
frame_flags = VP8_EFLAG_NO_REF_LAST |
VP8_EFLAG_NO_UPD_LAST |
VP8_EFLAG_NO_UPD_ARF;
}
}
@@ -91,17 +100,19 @@ class ErrorResilienceTestLarge
}
virtual void PreEncodeFrameHook(libvpx_test::VideoSource *video,
::libvpx_test::Encoder * /*encoder*/) {
frame_flags_ &=
~(VP8_EFLAG_NO_UPD_LAST | VP8_EFLAG_NO_UPD_GF | VP8_EFLAG_NO_UPD_ARF);
::libvpx_test::Encoder *encoder) {
frame_flags_ &= ~(VP8_EFLAG_NO_UPD_LAST |
VP8_EFLAG_NO_UPD_GF |
VP8_EFLAG_NO_UPD_ARF);
// For temporal layer case.
if (cfg_.ts_number_layers > 1) {
frame_flags_ =
SetFrameFlags(video->frame(), cfg_.ts_number_layers, pattern_switch_);
frame_flags_ = SetFrameFlags(video->frame(),
cfg_.ts_number_layers,
pattern_switch_);
for (unsigned int i = 0; i < droppable_nframes_; ++i) {
if (droppable_frames_[i] == video->frame()) {
std::cout << "Encoding droppable frame: " << droppable_frames_[i]
<< "\n";
std::cout << "Encoding droppable frame: "
<< droppable_frames_[i] << "\n";
}
}
} else {
@@ -109,9 +120,10 @@ class ErrorResilienceTestLarge
(cfg_.g_pass == VPX_RC_LAST_PASS || cfg_.g_pass == VPX_RC_ONE_PASS)) {
for (unsigned int i = 0; i < droppable_nframes_; ++i) {
if (droppable_frames_[i] == video->frame()) {
std::cout << "Encoding droppable frame: " << droppable_frames_[i]
<< "\n";
frame_flags_ |= (VP8_EFLAG_NO_UPD_LAST | VP8_EFLAG_NO_UPD_GF |
std::cout << "Encoding droppable frame: "
<< droppable_frames_[i] << "\n";
frame_flags_ |= (VP8_EFLAG_NO_UPD_LAST |
VP8_EFLAG_NO_UPD_GF |
VP8_EFLAG_NO_UPD_ARF);
return;
}
@@ -121,12 +133,14 @@ class ErrorResilienceTestLarge
}
double GetAveragePsnr() const {
if (nframes_) return psnr_ / nframes_;
if (nframes_)
return psnr_ / nframes_;
return 0.0;
}
double GetAverageMismatchPsnr() const {
if (mismatch_nframes_) return mismatch_psnr_ / mismatch_nframes_;
if (mismatch_nframes_)
return mismatch_psnr_ / mismatch_nframes_;
return 0.0;
}
@@ -144,7 +158,8 @@ class ErrorResilienceTestLarge
return 1;
}
virtual void MismatchHook(const vpx_image_t *img1, const vpx_image_t *img2) {
virtual void MismatchHook(const vpx_image_t *img1,
const vpx_image_t *img2) {
double mismatch_psnr = compute_psnr(img1, img2);
mismatch_psnr_ += mismatch_psnr;
++mismatch_nframes_;
@@ -152,32 +167,32 @@ class ErrorResilienceTestLarge
}
void SetErrorFrames(int num, unsigned int *list) {
if (num > kMaxErrorFrames) {
if (num > kMaxErrorFrames)
num = kMaxErrorFrames;
} else if (num < 0) {
else if (num < 0)
num = 0;
}
error_nframes_ = num;
for (unsigned int i = 0; i < error_nframes_; ++i) {
for (unsigned int i = 0; i < error_nframes_; ++i)
error_frames_[i] = list[i];
}
}
void SetDroppableFrames(int num, unsigned int *list) {
if (num > kMaxDroppableFrames) {
if (num > kMaxDroppableFrames)
num = kMaxDroppableFrames;
} else if (num < 0) {
else if (num < 0)
num = 0;
}
droppable_nframes_ = num;
for (unsigned int i = 0; i < droppable_nframes_; ++i) {
for (unsigned int i = 0; i < droppable_nframes_; ++i)
droppable_frames_[i] = list[i];
}
unsigned int GetMismatchFrames() {
return mismatch_nframes_;
}
unsigned int GetMismatchFrames() { return mismatch_nframes_; }
void SetPatternSwitch(int frame_switch) { pattern_switch_ = frame_switch; }
void SetPatternSwitch(int frame_switch) {
pattern_switch_ = frame_switch;
}
bool svc_support_;
@@ -250,13 +265,14 @@ TEST_P(ErrorResilienceTestLarge, DropFramesWithoutRecovery) {
// In addition to isolated loss/drop, add a long consecutive series
// (of size 9) of dropped frames.
unsigned int num_droppable_frames = 11;
unsigned int droppable_frame_list[] = { 5, 16, 22, 23, 24, 25,
26, 27, 28, 29, 30 };
unsigned int droppable_frame_list[] = {5, 16, 22, 23, 24, 25, 26, 27, 28,
29, 30};
SetDroppableFrames(num_droppable_frames, droppable_frame_list);
SetErrorFrames(num_droppable_frames, droppable_frame_list);
ASSERT_NO_FATAL_FAILURE(RunLoop(&video));
// Test that no mismatches have been found
std::cout << " Mismatch frames: " << GetMismatchFrames() << "\n";
std::cout << " Mismatch frames: "
<< GetMismatchFrames() << "\n";
EXPECT_EQ(GetMismatchFrames(), (unsigned int) 0);
// Reset previously set of error/droppable frames.
@@ -290,7 +306,8 @@ TEST_P(ErrorResilienceTestLarge, DropFramesWithoutRecovery) {
// layer, so successful decoding is expected.
TEST_P(ErrorResilienceTestLarge, 2LayersDropEnhancement) {
// This test doesn't run if SVC is not supported.
if (!svc_support_) return;
if (!svc_support_)
return;
const vpx_rational timebase = { 33333333, 1000000000 };
cfg_.g_timebase = timebase;
@@ -325,7 +342,8 @@ TEST_P(ErrorResilienceTestLarge, 2LayersDropEnhancement) {
SetErrorFrames(num_droppable_frames, droppable_frame_list);
ASSERT_NO_FATAL_FAILURE(RunLoop(&video));
// Test that no mismatches have been found
std::cout << " Mismatch frames: " << GetMismatchFrames() << "\n";
std::cout << " Mismatch frames: "
<< GetMismatchFrames() << "\n";
EXPECT_EQ(GetMismatchFrames(), (unsigned int) 0);
// Reset previously set of error/droppable frames.
@@ -337,7 +355,8 @@ TEST_P(ErrorResilienceTestLarge, 2LayersDropEnhancement) {
// sequence, the LAST ref is not used anymore.
TEST_P(ErrorResilienceTestLarge, 2LayersNoRefLast) {
// This test doesn't run if SVC is not supported.
if (!svc_support_) return;
if (!svc_support_)
return;
const vpx_rational timebase = { 33333333, 1000000000 };
cfg_.g_timebase = timebase;
@@ -366,19 +385,20 @@ TEST_P(ErrorResilienceTestLarge, 2LayersNoRefLast) {
ASSERT_NO_FATAL_FAILURE(RunLoop(&video));
// Test that no mismatches have been found
std::cout << " Mismatch frames: " << GetMismatchFrames() << "\n";
std::cout << " Mismatch frames: "
<< GetMismatchFrames() << "\n";
EXPECT_EQ(GetMismatchFrames(), (unsigned int) 0);
// Reset previously set of error/droppable frames.
Reset();
}
class ErrorResilienceTestLargeCodecControls
: public ::libvpx_test::EncoderTest,
class ErrorResilienceTestLargeCodecControls : public ::libvpx_test::EncoderTest,
public ::libvpx_test::CodecTestWithParam<libvpx_test::TestMode> {
protected:
ErrorResilienceTestLargeCodecControls()
: EncoderTest(GET_PARAM(0)), encoding_mode_(GET_PARAM(1)) {
: EncoderTest(GET_PARAM(0)),
encoding_mode_(GET_PARAM(1)) {
Reset();
}
@@ -417,8 +437,8 @@ class ErrorResilienceTestLargeCodecControls
if (num_temp_layers == 2) {
if (frame_num % 2 == 0) {
// Layer 0: predict from L and ARF, update L.
frame_flags =
VP8_EFLAG_NO_REF_GF | VP8_EFLAG_NO_UPD_GF | VP8_EFLAG_NO_UPD_ARF;
frame_flags = VP8_EFLAG_NO_REF_GF | VP8_EFLAG_NO_UPD_GF |
VP8_EFLAG_NO_UPD_ARF;
} else {
// Layer 1: predict from L, G and ARF, and update G.
frame_flags = VP8_EFLAG_NO_UPD_ARF | VP8_EFLAG_NO_UPD_LAST |
@@ -431,8 +451,8 @@ class ErrorResilienceTestLargeCodecControls
VP8_EFLAG_NO_REF_GF | VP8_EFLAG_NO_REF_ARF;
} else if ((frame_num - 2) % 4 == 0) {
// Layer 1: predict from L, G, update G.
frame_flags =
VP8_EFLAG_NO_UPD_ARF | VP8_EFLAG_NO_UPD_LAST | VP8_EFLAG_NO_REF_ARF;
frame_flags = VP8_EFLAG_NO_UPD_ARF | VP8_EFLAG_NO_UPD_LAST |
VP8_EFLAG_NO_REF_ARF;
} else if ((frame_num - 1) % 2 == 0) {
// Layer 2: predict from L, G, ARF; update ARG.
frame_flags = VP8_EFLAG_NO_UPD_GF | VP8_EFLAG_NO_UPD_LAST;
@@ -504,15 +524,13 @@ class ErrorResilienceTestLargeCodecControls
++layer) {
if (bits_total_[layer]) {
// Effective file datarate:
effective_datarate_[layer] =
(bits_total_[layer] / 1000.0) / duration_;
effective_datarate_[layer] = (bits_total_[layer] / 1000.0) / duration_;
}
}
}
}
double effective_datarate_[3];
private:
libvpx_test::TestMode encoding_mode_;
vpx_codec_pts_t last_pts_;
@@ -564,12 +582,10 @@ TEST_P(ErrorResilienceTestLargeCodecControls, CodecControl3TemporalLayers) {
for (int j = 0; j < static_cast<int>(cfg_.ts_number_layers); ++j) {
ASSERT_GE(effective_datarate_[j], cfg_.ts_target_bitrate[j] * 0.75)
<< " The datarate for the file is lower than target by too much, "
"for layer: "
<< j;
"for layer: " << j;
ASSERT_LE(effective_datarate_[j], cfg_.ts_target_bitrate[j] * 1.25)
<< " The datarate for the file is greater than target by too much, "
"for layer: "
<< j;
"for layer: " << j;
}
}
}
@@ -580,4 +596,7 @@ VP8_INSTANTIATE_TEST_CASE(ErrorResilienceTestLargeCodecControls,
ONE_PASS_TEST_MODES);
VP9_INSTANTIATE_TEST_CASE(ErrorResilienceTestLarge, ONE_PASS_TEST_MODES,
::testing::Values(true));
// SVC-related tests don't run for VP10 since SVC is not supported.
VP10_INSTANTIATE_TEST_CASE(ErrorResilienceTestLarge, ONE_PASS_TEST_MODES,
::testing::Values(false));
} // namespace

View File

@@ -24,6 +24,7 @@
namespace {
const int kVideoNameParam = 1;
const char kVP9TestFile[] = "vp90-2-02-size-lf-1920x1080.webm";
struct ExternalFrameBuffer {
uint8_t *data;
@@ -34,7 +35,9 @@ struct ExternalFrameBuffer {
// Class to manipulate a list of external frame buffers.
class ExternalFrameBufferList {
public:
ExternalFrameBufferList() : num_buffers_(0), ext_fb_list_(NULL) {}
ExternalFrameBufferList()
: num_buffers_(0),
ext_fb_list_(NULL) {}
virtual ~ExternalFrameBufferList() {
for (int i = 0; i < num_buffers_; ++i) {
@@ -45,7 +48,8 @@ class ExternalFrameBufferList {
// Creates the list to hold the external buffers. Returns true on success.
bool CreateBufferList(int num_buffers) {
if (num_buffers < 0) return false;
if (num_buffers < 0)
return false;
num_buffers_ = num_buffers;
ext_fb_list_ = new ExternalFrameBuffer[num_buffers_];
@@ -61,7 +65,8 @@ class ExternalFrameBufferList {
int GetFreeFrameBuffer(size_t min_size, vpx_codec_frame_buffer_t *fb) {
EXPECT_TRUE(fb != NULL);
const int idx = FindFreeBufferIndex();
if (idx == num_buffers_) return -1;
if (idx == num_buffers_)
return -1;
if (ext_fb_list_[idx].size < min_size) {
delete [] ext_fb_list_[idx].data;
@@ -79,7 +84,8 @@ class ExternalFrameBufferList {
int GetZeroFrameBuffer(size_t min_size, vpx_codec_frame_buffer_t *fb) {
EXPECT_TRUE(fb != NULL);
const int idx = FindFreeBufferIndex();
if (idx == num_buffers_) return -1;
if (idx == num_buffers_)
return -1;
if (ext_fb_list_[idx].size < min_size) {
delete [] ext_fb_list_[idx].data;
@@ -128,7 +134,8 @@ class ExternalFrameBufferList {
int i;
// Find a free frame buffer.
for (i = 0; i < num_buffers_; ++i) {
if (!ext_fb_list_[i].in_use) break;
if (!ext_fb_list_[i].in_use)
break;
}
return i;
}
@@ -148,8 +155,6 @@ class ExternalFrameBufferList {
ExternalFrameBuffer *ext_fb_list_;
};
#if CONFIG_WEBM_IO
// Callback used by libvpx to request the application to return a frame
// buffer of at least |min_size| in bytes.
int get_vp9_frame_buffer(void *user_priv, size_t min_size,
@@ -161,7 +166,8 @@ int get_vp9_frame_buffer(void *user_priv, size_t min_size,
// Callback used by libvpx to tell the application that |fb| is not needed
// anymore.
int release_vp9_frame_buffer(void *user_priv, vpx_codec_frame_buffer_t *fb) {
int release_vp9_frame_buffer(void *user_priv,
vpx_codec_frame_buffer_t *fb) {
ExternalFrameBufferList *const fb_list =
reinterpret_cast<ExternalFrameBufferList*>(user_priv);
return fb_list->ReturnFrameBuffer(fb);
@@ -191,8 +197,6 @@ int do_not_release_vp9_frame_buffer(void *user_priv,
return 0;
}
#endif // CONFIG_WEBM_IO
// Class for testing passing in external frame buffers to libvpx.
class ExternalFrameBufferMD5Test
: public ::libvpx_test::DecoderTest,
@@ -200,10 +204,12 @@ class ExternalFrameBufferMD5Test
protected:
ExternalFrameBufferMD5Test()
: DecoderTest(GET_PARAM(::libvpx_test::kCodecFactoryParam)),
md5_file_(NULL), num_buffers_(0) {}
md5_file_(NULL),
num_buffers_(0) {}
virtual ~ExternalFrameBufferMD5Test() {
if (md5_file_ != NULL) fclose(md5_file_);
if (md5_file_ != NULL)
fclose(md5_file_);
}
virtual void PreDecodeFrameHook(
@@ -213,8 +219,8 @@ class ExternalFrameBufferMD5Test
// Have libvpx use frame buffers we create.
ASSERT_TRUE(fb_list_.CreateBufferList(num_buffers_));
ASSERT_EQ(VPX_CODEC_OK,
decoder->SetFrameBufferFunctions(GetVP9FrameBuffer,
ReleaseVP9FrameBuffer, this));
decoder->SetFrameBufferFunctions(
GetVP9FrameBuffer, ReleaseVP9FrameBuffer, this));
}
}
@@ -272,12 +278,13 @@ class ExternalFrameBufferMD5Test
};
#if CONFIG_WEBM_IO
const char kVP9TestFile[] = "vp90-2-02-size-lf-1920x1080.webm";
// Class for testing passing in external frame buffers to libvpx.
class ExternalFrameBufferTest : public ::testing::Test {
protected:
ExternalFrameBufferTest() : video_(NULL), decoder_(NULL), num_buffers_(0) {}
ExternalFrameBufferTest()
: video_(NULL),
decoder_(NULL),
num_buffers_(0) {}
virtual void SetUp() {
video_ = new libvpx_test::WebMVideoSource(kVP9TestFile);
@@ -297,7 +304,8 @@ class ExternalFrameBufferTest : public ::testing::Test {
// Passes the external frame buffer information to libvpx.
vpx_codec_err_t SetFrameBufferFunctions(
int num_buffers, vpx_get_frame_buffer_cb_fn_t cb_get,
int num_buffers,
vpx_get_frame_buffer_cb_fn_t cb_get,
vpx_release_frame_buffer_cb_fn_t cb_release) {
if (num_buffers > 0) {
num_buffers_ = num_buffers;
@@ -311,7 +319,8 @@ class ExternalFrameBufferTest : public ::testing::Test {
const vpx_codec_err_t res =
decoder_->DecodeFrame(video_->cxdata(), video_->frame_size());
CheckDecodedFrames();
if (res == VPX_CODEC_OK) video_->Next();
if (res == VPX_CODEC_OK)
video_->Next();
return res;
}
@@ -319,7 +328,8 @@ class ExternalFrameBufferTest : public ::testing::Test {
for (; video_->cxdata() != NULL; video_->Next()) {
const vpx_codec_err_t res =
decoder_->DecodeFrame(video_->cxdata(), video_->frame_size());
if (res != VPX_CODEC_OK) return res;
if (res != VPX_CODEC_OK)
return res;
CheckDecodedFrames();
}
return VPX_CODEC_OK;
@@ -350,6 +360,7 @@ class ExternalFrameBufferTest : public ::testing::Test {
// Otherwise, the test failed.
TEST_P(ExternalFrameBufferMD5Test, ExtFBMD5Match) {
const std::string filename = GET_PARAM(kVideoNameParam);
libvpx_test::CompressedVideoSource *video = NULL;
// Number of buffers equals #VP9_MAXIMUM_REF_BUFFERS +
// #VPX_MAXIMUM_WORK_BUFFERS + four jitter buffers.
@@ -364,19 +375,18 @@ TEST_P(ExternalFrameBufferMD5Test, ExtFBMD5Match) {
#endif
// Open compressed video file.
testing::internal::scoped_ptr<libvpx_test::CompressedVideoSource> video;
if (filename.substr(filename.length() - 3, 3) == "ivf") {
video.reset(new libvpx_test::IVFVideoSource(filename));
video = new libvpx_test::IVFVideoSource(filename);
} else {
#if CONFIG_WEBM_IO
video.reset(new libvpx_test::WebMVideoSource(filename));
video = new libvpx_test::WebMVideoSource(filename);
#else
fprintf(stderr, "WebM IO is disabled, skipping test vector %s\n",
filename.c_str());
return;
#endif
}
ASSERT_TRUE(video.get() != NULL);
ASSERT_TRUE(video != NULL);
video->Init();
// Construct md5 file name.
@@ -384,7 +394,8 @@ TEST_P(ExternalFrameBufferMD5Test, ExtFBMD5Match) {
OpenMD5File(md5_filename);
// Decode frame, and check the md5 matching.
ASSERT_NO_FATAL_FAILURE(RunLoop(video.get()));
ASSERT_NO_FATAL_FAILURE(RunLoop(video));
delete video;
}
#if CONFIG_WEBM_IO
@@ -393,8 +404,8 @@ TEST_F(ExternalFrameBufferTest, MinFrameBuffers) {
// #VP9_MAXIMUM_REF_BUFFERS + #VPX_MAXIMUM_WORK_BUFFERS.
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));
SetFrameBufferFunctions(
num_buffers, get_vp9_frame_buffer, release_vp9_frame_buffer));
ASSERT_EQ(VPX_CODEC_OK, DecodeRemainingFrames());
}
@@ -405,8 +416,8 @@ TEST_F(ExternalFrameBufferTest, EightJitterBuffers) {
const int num_buffers =
VP9_MAXIMUM_REF_BUFFERS + VPX_MAXIMUM_WORK_BUFFERS + jitter_buffers;
ASSERT_EQ(VPX_CODEC_OK,
SetFrameBufferFunctions(num_buffers, get_vp9_frame_buffer,
release_vp9_frame_buffer));
SetFrameBufferFunctions(
num_buffers, get_vp9_frame_buffer, release_vp9_frame_buffer));
ASSERT_EQ(VPX_CODEC_OK, DecodeRemainingFrames());
}
@@ -416,8 +427,8 @@ TEST_F(ExternalFrameBufferTest, NotEnoughBuffers) {
// only use 5 frame buffers at one time.
const int num_buffers = 2;
ASSERT_EQ(VPX_CODEC_OK,
SetFrameBufferFunctions(num_buffers, get_vp9_frame_buffer,
release_vp9_frame_buffer));
SetFrameBufferFunctions(
num_buffers, get_vp9_frame_buffer, release_vp9_frame_buffer));
ASSERT_EQ(VPX_CODEC_OK, DecodeOneFrame());
ASSERT_EQ(VPX_CODEC_MEM_ERROR, DecodeRemainingFrames());
}
@@ -441,7 +452,8 @@ TEST_F(ExternalFrameBufferTest, NullRealloc) {
TEST_F(ExternalFrameBufferTest, ReallocOneLessByte) {
const int num_buffers = VP9_MAXIMUM_REF_BUFFERS + VPX_MAXIMUM_WORK_BUFFERS;
ASSERT_EQ(VPX_CODEC_OK, SetFrameBufferFunctions(
ASSERT_EQ(VPX_CODEC_OK,
SetFrameBufferFunctions(
num_buffers, get_vp9_one_less_byte_frame_buffer,
release_vp9_frame_buffer));
ASSERT_EQ(VPX_CODEC_MEM_ERROR, DecodeOneFrame());
@@ -449,9 +461,9 @@ TEST_F(ExternalFrameBufferTest, ReallocOneLessByte) {
TEST_F(ExternalFrameBufferTest, NullGetFunction) {
const int num_buffers = VP9_MAXIMUM_REF_BUFFERS + VPX_MAXIMUM_WORK_BUFFERS;
ASSERT_EQ(
VPX_CODEC_INVALID_PARAM,
SetFrameBufferFunctions(num_buffers, NULL, release_vp9_frame_buffer));
ASSERT_EQ(VPX_CODEC_INVALID_PARAM,
SetFrameBufferFunctions(num_buffers, NULL,
release_vp9_frame_buffer));
}
TEST_F(ExternalFrameBufferTest, NullReleaseFunction) {
@@ -464,13 +476,12 @@ TEST_F(ExternalFrameBufferTest, SetAfterDecode) {
const int num_buffers = VP9_MAXIMUM_REF_BUFFERS + VPX_MAXIMUM_WORK_BUFFERS;
ASSERT_EQ(VPX_CODEC_OK, DecodeOneFrame());
ASSERT_EQ(VPX_CODEC_ERROR,
SetFrameBufferFunctions(num_buffers, get_vp9_frame_buffer,
release_vp9_frame_buffer));
SetFrameBufferFunctions(
num_buffers, get_vp9_frame_buffer, release_vp9_frame_buffer));
}
#endif // CONFIG_WEBM_IO
VP9_INSTANTIATE_TEST_CASE(
ExternalFrameBufferMD5Test,
VP9_INSTANTIATE_TEST_CASE(ExternalFrameBufferMD5Test,
::testing::ValuesIn(libvpx_test::kVP9TestVectors,
libvpx_test::kVP9TestVectors +
libvpx_test::kNumVP9TestVectors));

View File

@@ -40,7 +40,7 @@ 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*/) {
int tx_type) {
vpx_fdct4x4_c(in, out, stride);
}
@@ -49,7 +49,7 @@ void fht4x4_ref(const int16_t *in, tran_low_t *out, int stride, int tx_type) {
}
void fwht4x4_ref(const int16_t *in, tran_low_t *out, int stride,
int /*tx_type*/) {
int tx_type) {
vp9_fwht4x4_c(in, out, stride);
}
@@ -128,33 +128,35 @@ class Trans4x4TestBase {
}
}
ASM_REGISTER_STATE_CHECK(
RunFwdTxfm(test_input_block, test_temp_block, pitch_));
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_));
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 =
const uint32_t 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];
const uint32_t diff = dst[j] - src[j];
#endif
const uint32_t error = diff * diff;
if (max_error < error) max_error = error;
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;
<< "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
@@ -170,9 +172,8 @@ class Trans4x4TestBase {
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) {
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_));
@@ -196,14 +197,16 @@ class Trans4x4TestBase {
input_extreme_block[j] = rnd.Rand8() % 2 ? mask_ : -mask_;
}
if (i == 0) {
for (int j = 0; j < kNumCoeffs; ++j) input_extreme_block[j] = mask_;
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_;
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_));
ASM_REGISTER_STATE_CHECK(RunFwdTxfm(input_extreme_block,
output_block, pitch_));
// The minimum quant value is 4.
for (int j = 0; j < kNumCoeffs; ++j) {
@@ -248,21 +251,22 @@ class Trans4x4TestBase {
ASM_REGISTER_STATE_CHECK(RunInvTxfm(coeff, dst, pitch_));
#if CONFIG_VP9_HIGHBITDEPTH
} else {
ASM_REGISTER_STATE_CHECK(
RunInvTxfm(coeff, CONVERT_TO_BYTEPTR(dst16), pitch_));
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 =
const uint32_t diff =
bit_depth_ == VPX_BITS_8 ? dst[j] - src[j] : dst16[j] - src16[j];
#else
const int diff = dst[j] - src[j];
const uint32_t 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;
<< "Error: 4x4 IDCT has error " << error
<< " at index " << j;
}
}
}
@@ -274,7 +278,8 @@ class Trans4x4TestBase {
int mask_;
};
class Trans4x4DCT : public Trans4x4TestBase,
class Trans4x4DCT
: public Trans4x4TestBase,
public ::testing::TestWithParam<Dct4x4Param> {
public:
virtual ~Trans4x4DCT() {}
@@ -302,15 +307,24 @@ class Trans4x4DCT : public Trans4x4TestBase,
IdctFunc inv_txfm_;
};
TEST_P(Trans4x4DCT, AccuracyCheck) { RunAccuracyCheck(1); }
TEST_P(Trans4x4DCT, AccuracyCheck) {
RunAccuracyCheck(1);
}
TEST_P(Trans4x4DCT, CoeffCheck) { RunCoeffCheck(); }
TEST_P(Trans4x4DCT, CoeffCheck) {
RunCoeffCheck();
}
TEST_P(Trans4x4DCT, MemCheck) { RunMemCheck(); }
TEST_P(Trans4x4DCT, MemCheck) {
RunMemCheck();
}
TEST_P(Trans4x4DCT, InvAccuracyCheck) { RunInvAccuracyCheck(1); }
TEST_P(Trans4x4DCT, InvAccuracyCheck) {
RunInvAccuracyCheck(1);
}
class Trans4x4HT : public Trans4x4TestBase,
class Trans4x4HT
: public Trans4x4TestBase,
public ::testing::TestWithParam<Ht4x4Param> {
public:
virtual ~Trans4x4HT() {}
@@ -339,15 +353,24 @@ class Trans4x4HT : public Trans4x4TestBase,
IhtFunc inv_txfm_;
};
TEST_P(Trans4x4HT, AccuracyCheck) { RunAccuracyCheck(1); }
TEST_P(Trans4x4HT, AccuracyCheck) {
RunAccuracyCheck(1);
}
TEST_P(Trans4x4HT, CoeffCheck) { RunCoeffCheck(); }
TEST_P(Trans4x4HT, CoeffCheck) {
RunCoeffCheck();
}
TEST_P(Trans4x4HT, MemCheck) { RunMemCheck(); }
TEST_P(Trans4x4HT, MemCheck) {
RunMemCheck();
}
TEST_P(Trans4x4HT, InvAccuracyCheck) { RunInvAccuracyCheck(1); }
TEST_P(Trans4x4HT, InvAccuracyCheck) {
RunInvAccuracyCheck(1);
}
class Trans4x4WHT : public Trans4x4TestBase,
class Trans4x4WHT
: public Trans4x4TestBase,
public ::testing::TestWithParam<Dct4x4Param> {
public:
virtual ~Trans4x4WHT() {}
@@ -375,13 +398,21 @@ class Trans4x4WHT : public Trans4x4TestBase,
IdctFunc inv_txfm_;
};
TEST_P(Trans4x4WHT, AccuracyCheck) { RunAccuracyCheck(0); }
TEST_P(Trans4x4WHT, AccuracyCheck) {
RunAccuracyCheck(0);
}
TEST_P(Trans4x4WHT, CoeffCheck) { RunCoeffCheck(); }
TEST_P(Trans4x4WHT, CoeffCheck) {
RunCoeffCheck();
}
TEST_P(Trans4x4WHT, MemCheck) { RunMemCheck(); }
TEST_P(Trans4x4WHT, MemCheck) {
RunMemCheck();
}
TEST_P(Trans4x4WHT, InvAccuracyCheck) { RunInvAccuracyCheck(0); }
TEST_P(Trans4x4WHT, InvAccuracyCheck) {
RunInvAccuracyCheck(0);
}
using std::tr1::make_tuple;
#if CONFIG_VP9_HIGHBITDEPTH
@@ -392,10 +423,10 @@ INSTANTIATE_TEST_CASE_P(
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)));
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
@@ -432,17 +463,18 @@ INSTANTIATE_TEST_CASE_P(
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)));
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)));
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
@@ -455,19 +487,28 @@ INSTANTIATE_TEST_CASE_P(
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
#if CONFIG_USE_X86INC && HAVE_MMX && !CONFIG_VP9_HIGHBITDEPTH && \
!CONFIG_EMULATE_HARDWARE
INSTANTIATE_TEST_CASE_P(
MMX, Trans4x4WHT,
::testing::Values(
make_tuple(&vp9_fwht4x4_mmx, &vpx_iwht4x4_16_add_c, 0, VPX_BITS_8)));
#endif
#if CONFIG_USE_X86INC && HAVE_SSE2 && !CONFIG_VP9_HIGHBITDEPTH && \
!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, 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(
@@ -485,7 +526,8 @@ INSTANTIATE_TEST_CASE_P(
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)));
make_tuple(&vpx_fdct4x4_sse2, &vpx_idct4x4_16_add_c, 0,
VPX_BITS_8)));
INSTANTIATE_TEST_CASE_P(
SSE2, Trans4x4HT,
@@ -497,10 +539,10 @@ INSTANTIATE_TEST_CASE_P(
#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, 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(

View File

@@ -47,14 +47,14 @@ typedef std::tr1::tuple<FdctFunc, IdctFunc, int, vpx_bit_depth_t> Dct8x8Param;
typedef std::tr1::tuple<FhtFunc, IhtFunc, int, vpx_bit_depth_t> Ht8x8Param;
typedef std::tr1::tuple<IdctFunc, IdctFunc, int, vpx_bit_depth_t> Idct8x8Param;
void reference_8x8_dct_1d(const double in[8], double out[8]) {
void reference_8x8_dct_1d(const double in[8], double out[8], int stride) {
const double kInvSqrt2 = 0.707106781186547524400844362104;
for (int k = 0; k < 8; k++) {
out[k] = 0.0;
for (int n = 0; n < 8; n++) {
for (int n = 0; n < 8; n++)
out[k] += in[n] * cos(kPi * (2 * n + 1) * k / 16.0);
}
if (k == 0) out[k] = out[k] * kInvSqrt2;
if (k == 0)
out[k] = out[k] * kInvSqrt2;
}
}
@@ -63,22 +63,26 @@ void reference_8x8_dct_2d(const int16_t input[kNumCoeffs],
// First transform columns
for (int i = 0; i < 8; ++i) {
double temp_in[8], temp_out[8];
for (int j = 0; j < 8; ++j) temp_in[j] = input[j * 8 + i];
reference_8x8_dct_1d(temp_in, temp_out);
for (int j = 0; j < 8; ++j) output[j * 8 + i] = temp_out[j];
for (int j = 0; j < 8; ++j)
temp_in[j] = input[j*8 + i];
reference_8x8_dct_1d(temp_in, temp_out, 1);
for (int j = 0; j < 8; ++j)
output[j * 8 + i] = temp_out[j];
}
// Then transform rows
for (int i = 0; i < 8; ++i) {
double temp_in[8], temp_out[8];
for (int j = 0; j < 8; ++j) temp_in[j] = output[j + i * 8];
reference_8x8_dct_1d(temp_in, temp_out);
for (int j = 0; j < 8; ++j)
temp_in[j] = output[j + i*8];
reference_8x8_dct_1d(temp_in, temp_out, 1);
// Scale by some magic number
for (int j = 0; j < 8; ++j) output[j + i * 8] = temp_out[j] * 2;
for (int j = 0; j < 8; ++j)
output[j + i * 8] = temp_out[j] * 2;
}
}
void fdct8x8_ref(const int16_t *in, tran_low_t *out, int stride,
int /*tx_type*/) {
void fdct8x8_ref(const int16_t *in, tran_low_t *out, int stride, int tx_type) {
vpx_fdct8x8_c(in, out, stride);
}
@@ -103,8 +107,6 @@ 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);
}
#if HAVE_SSE2
void idct8x8_10_add_10_c(const tran_low_t *in, uint8_t *out, int stride) {
vpx_highbd_idct8x8_10_add_c(in, out, stride, 10);
}
@@ -113,6 +115,7 @@ void idct8x8_10_add_12_c(const tran_low_t *in, uint8_t *out, int stride) {
vpx_highbd_idct8x8_10_add_c(in, out, stride, 12);
}
#if HAVE_SSE2
void idct8x8_10_add_10_sse2(const tran_low_t *in, uint8_t *out, int stride) {
vpx_highbd_idct8x8_10_add_sse2(in, out, stride, 10);
}
@@ -150,21 +153,19 @@ class FwdTrans8x8TestBase {
for (int i = 0; i < count_test_block; ++i) {
// Initialize a test block with input range [-255, 255].
for (int j = 0; j < 64; ++j) {
for (int j = 0; j < 64; ++j)
test_input_block[j] = ((rnd.Rand16() >> (16 - bit_depth_)) & mask_) -
((rnd.Rand16() >> (16 - bit_depth_)) & mask_);
}
ASM_REGISTER_STATE_CHECK(
RunFwdTxfm(test_input_block, test_output_block, pitch_));
for (int j = 0; j < 64; ++j) {
if (test_output_block[j] < 0) {
if (test_output_block[j] < 0)
++count_sign_block[j][0];
} else if (test_output_block[j] > 0) {
else if (test_output_block[j] > 0)
++count_sign_block[j][1];
}
}
}
for (int j = 0; j < 64; ++j) {
const int diff = abs(count_sign_block[j][0] - count_sign_block[j][1]);
@@ -174,28 +175,27 @@ class FwdTrans8x8TestBase {
<< 1. * max_diff / count_test_block * 100 << "%"
<< " for input range [-255, 255] at index " << j
<< " count0: " << count_sign_block[j][0]
<< " count1: " << count_sign_block[j][1] << " diff: " << diff;
<< " count1: " << count_sign_block[j][1]
<< " diff: " << diff;
}
memset(count_sign_block, 0, sizeof(count_sign_block));
for (int i = 0; i < count_test_block; ++i) {
// Initialize a test block with input range [-mask_ / 16, mask_ / 16].
for (int j = 0; j < 64; ++j) {
test_input_block[j] =
((rnd.Rand16() & mask_) >> 4) - ((rnd.Rand16() & mask_) >> 4);
}
for (int j = 0; j < 64; ++j)
test_input_block[j] = ((rnd.Rand16() & mask_) >> 4) -
((rnd.Rand16() & mask_) >> 4);
ASM_REGISTER_STATE_CHECK(
RunFwdTxfm(test_input_block, test_output_block, pitch_));
for (int j = 0; j < 64; ++j) {
if (test_output_block[j] < 0) {
if (test_output_block[j] < 0)
++count_sign_block[j][0];
} else if (test_output_block[j] > 0) {
else if (test_output_block[j] > 0)
++count_sign_block[j][1];
}
}
}
for (int j = 0; j < 64; ++j) {
const int diff = abs(count_sign_block[j][0] - count_sign_block[j][1]);
@@ -205,7 +205,8 @@ class FwdTrans8x8TestBase {
<< 1. * max_diff / count_test_block * 100 << "%"
<< " for input range [-15, 15] at index " << j
<< " count0: " << count_sign_block[j][0]
<< " count1: " << count_sign_block[j][1] << " diff: " << diff;
<< " count1: " << count_sign_block[j][1]
<< " diff: " << diff;
}
}
@@ -253,7 +254,8 @@ class FwdTrans8x8TestBase {
}
}
if (bit_depth_ == VPX_BITS_8) {
ASM_REGISTER_STATE_CHECK(RunInvTxfm(test_temp_block, dst, pitch_));
ASM_REGISTER_STATE_CHECK(
RunInvTxfm(test_temp_block, dst, pitch_));
#if CONFIG_VP9_HIGHBITDEPTH
} else {
ASM_REGISTER_STATE_CHECK(
@@ -269,7 +271,8 @@ class FwdTrans8x8TestBase {
const int diff = dst[j] - src[j];
#endif
const int error = diff * diff;
if (max_error < error) max_error = error;
if (max_error < error)
max_error = error;
total_error += error;
}
}
@@ -336,7 +339,8 @@ class FwdTrans8x8TestBase {
ASM_REGISTER_STATE_CHECK(
fwd_txfm_ref(test_input_block, ref_temp_block, pitch_, tx_type_));
if (bit_depth_ == VPX_BITS_8) {
ASM_REGISTER_STATE_CHECK(RunInvTxfm(test_temp_block, dst, pitch_));
ASM_REGISTER_STATE_CHECK(
RunInvTxfm(test_temp_block, dst, pitch_));
#if CONFIG_VP9_HIGHBITDEPTH
} else {
ASM_REGISTER_STATE_CHECK(
@@ -352,7 +356,8 @@ class FwdTrans8x8TestBase {
const int diff = dst[j] - src[j];
#endif
const int error = diff * diff;
if (max_error < error) max_error = error;
if (max_error < error)
max_error = error;
total_error += error;
const int coeff_diff = test_temp_block[j] - ref_temp_block[j];
@@ -404,29 +409,29 @@ class FwdTrans8x8TestBase {
}
reference_8x8_dct_2d(in, out_r);
for (int j = 0; j < kNumCoeffs; ++j) {
for (int j = 0; j < kNumCoeffs; ++j)
coeff[j] = static_cast<tran_low_t>(round(out_r[j]));
}
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_));
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 =
const uint32_t diff =
bit_depth_ == VPX_BITS_8 ? dst[j] - src[j] : dst16[j] - src16[j];
#else
const int diff = dst[j] - src[j];
const uint32_t diff = dst[j] - src[j];
#endif
const uint32_t error = diff * diff;
EXPECT_GE(1u << 2 * (bit_depth_ - 8), error)
<< "Error: 8x8 IDCT has error " << error << " at index " << j;
<< "Error: 8x8 IDCT has error " << error
<< " at index " << j;
}
}
}
@@ -442,21 +447,20 @@ class FwdTrans8x8TestBase {
double out_r[kNumCoeffs];
// Initialize a test block with input range [-mask_, mask_].
for (int j = 0; j < kNumCoeffs; ++j) {
for (int j = 0; j < kNumCoeffs; ++j)
in[j] = rnd.Rand8() % 2 == 0 ? mask_ : -mask_;
}
RunFwdTxfm(in, coeff, pitch_);
reference_8x8_dct_2d(in, out_r);
for (int j = 0; j < kNumCoeffs; ++j) {
for (int j = 0; j < kNumCoeffs; ++j)
coeff_r[j] = static_cast<tran_low_t>(round(out_r[j]));
}
for (int j = 0; j < kNumCoeffs; ++j) {
const int32_t diff = coeff[j] - coeff_r[j];
const uint32_t diff = coeff[j] - coeff_r[j];
const uint32_t error = diff * diff;
EXPECT_GE(9u << 2 * (bit_depth_ - 8), error)
<< "Error: 8x8 DCT has error " << error << " at index " << j;
<< "Error: 8x8 DCT has error " << error
<< " at index " << j;
}
}
}
@@ -498,20 +502,21 @@ class FwdTrans8x8TestBase {
#if CONFIG_VP9_HIGHBITDEPTH
} else {
ref_txfm(coeff, CONVERT_TO_BYTEPTR(ref16), pitch_);
ASM_REGISTER_STATE_CHECK(
RunInvTxfm(coeff, CONVERT_TO_BYTEPTR(dst16), pitch_));
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 =
const uint32_t diff =
bit_depth_ == VPX_BITS_8 ? dst[j] - ref[j] : dst16[j] - ref16[j];
#else
const int diff = dst[j] - ref[j];
const uint32_t diff = dst[j] - ref[j];
#endif
const uint32_t error = diff * diff;
EXPECT_EQ(0u, error) << "Error: 8x8 IDCT has error " << error
EXPECT_EQ(0u, error)
<< "Error: 8x8 IDCT has error " << error
<< " at index " << j;
}
}
@@ -523,7 +528,8 @@ class FwdTrans8x8TestBase {
int mask_;
};
class FwdTrans8x8DCT : public FwdTrans8x8TestBase,
class FwdTrans8x8DCT
: public FwdTrans8x8TestBase,
public ::testing::TestWithParam<Dct8x8Param> {
public:
virtual ~FwdTrans8x8DCT() {}
@@ -552,17 +558,28 @@ class FwdTrans8x8DCT : public FwdTrans8x8TestBase,
IdctFunc inv_txfm_;
};
TEST_P(FwdTrans8x8DCT, SignBiasCheck) { RunSignBiasCheck(); }
TEST_P(FwdTrans8x8DCT, SignBiasCheck) {
RunSignBiasCheck();
}
TEST_P(FwdTrans8x8DCT, RoundTripErrorCheck) { RunRoundTripErrorCheck(); }
TEST_P(FwdTrans8x8DCT, RoundTripErrorCheck) {
RunRoundTripErrorCheck();
}
TEST_P(FwdTrans8x8DCT, ExtremalCheck) { RunExtremalCheck(); }
TEST_P(FwdTrans8x8DCT, ExtremalCheck) {
RunExtremalCheck();
}
TEST_P(FwdTrans8x8DCT, FwdAccuracyCheck) { RunFwdAccuracyCheck(); }
TEST_P(FwdTrans8x8DCT, FwdAccuracyCheck) {
RunFwdAccuracyCheck();
}
TEST_P(FwdTrans8x8DCT, InvAccuracyCheck) { RunInvAccuracyCheck(); }
TEST_P(FwdTrans8x8DCT, InvAccuracyCheck) {
RunInvAccuracyCheck();
}
class FwdTrans8x8HT : public FwdTrans8x8TestBase,
class FwdTrans8x8HT
: public FwdTrans8x8TestBase,
public ::testing::TestWithParam<Ht8x8Param> {
public:
virtual ~FwdTrans8x8HT() {}
@@ -591,13 +608,20 @@ class FwdTrans8x8HT : public FwdTrans8x8TestBase,
IhtFunc inv_txfm_;
};
TEST_P(FwdTrans8x8HT, SignBiasCheck) { RunSignBiasCheck(); }
TEST_P(FwdTrans8x8HT, SignBiasCheck) {
RunSignBiasCheck();
}
TEST_P(FwdTrans8x8HT, RoundTripErrorCheck) { RunRoundTripErrorCheck(); }
TEST_P(FwdTrans8x8HT, RoundTripErrorCheck) {
RunRoundTripErrorCheck();
}
TEST_P(FwdTrans8x8HT, ExtremalCheck) { RunExtremalCheck(); }
TEST_P(FwdTrans8x8HT, ExtremalCheck) {
RunExtremalCheck();
}
class InvTrans8x8DCT : public FwdTrans8x8TestBase,
class InvTrans8x8DCT
: public FwdTrans8x8TestBase,
public ::testing::TestWithParam<Idct8x8Param> {
public:
virtual ~InvTrans8x8DCT() {}
@@ -617,7 +641,7 @@ class InvTrans8x8DCT : public FwdTrans8x8TestBase,
void RunInvTxfm(tran_low_t *out, uint8_t *dst, int stride) {
inv_txfm_(out, dst, stride);
}
void RunFwdTxfm(int16_t * /*out*/, tran_low_t * /*dst*/, int /*stride*/) {}
void RunFwdTxfm(int16_t *out, tran_low_t *dst, int stride) {}
IdctFunc ref_txfm_;
IdctFunc inv_txfm_;
@@ -638,10 +662,10 @@ INSTANTIATE_TEST_CASE_P(
make_tuple(&vpx_highbd_fdct8x8_c, &idct8x8_10, 0, VPX_BITS_10),
make_tuple(&vpx_highbd_fdct8x8_c, &idct8x8_12, 0, VPX_BITS_12)));
#else
INSTANTIATE_TEST_CASE_P(C, FwdTrans8x8DCT,
::testing::Values(make_tuple(&vpx_fdct8x8_c,
&vpx_idct8x8_64_add_c, 0,
VPX_BITS_8)));
INSTANTIATE_TEST_CASE_P(
C, FwdTrans8x8DCT,
::testing::Values(
make_tuple(&vpx_fdct8x8_c, &vpx_idct8x8_64_add_c, 0, VPX_BITS_8)));
#endif // CONFIG_VP9_HIGHBITDEPTH
#if CONFIG_VP9_HIGHBITDEPTH
@@ -671,10 +695,11 @@ INSTANTIATE_TEST_CASE_P(
#endif // CONFIG_VP9_HIGHBITDEPTH
#if HAVE_NEON_ASM && !CONFIG_VP9_HIGHBITDEPTH && !CONFIG_EMULATE_HARDWARE
INSTANTIATE_TEST_CASE_P(NEON, FwdTrans8x8DCT,
::testing::Values(make_tuple(&vpx_fdct8x8_neon,
&vpx_idct8x8_64_add_neon,
0, VPX_BITS_8)));
INSTANTIATE_TEST_CASE_P(
NEON, FwdTrans8x8DCT,
::testing::Values(
make_tuple(&vpx_fdct8x8_neon, &vpx_idct8x8_64_add_neon, 0,
VPX_BITS_8)));
#endif // HAVE_NEON_ASM && !CONFIG_VP9_HIGHBITDEPTH && !CONFIG_EMULATE_HARDWARE
#if HAVE_NEON && !CONFIG_VP9_HIGHBITDEPTH && !CONFIG_EMULATE_HARDWARE
@@ -688,10 +713,11 @@ INSTANTIATE_TEST_CASE_P(
#endif // HAVE_NEON && !CONFIG_VP9_HIGHBITDEPTH && !CONFIG_EMULATE_HARDWARE
#if HAVE_SSE2 && !CONFIG_VP9_HIGHBITDEPTH && !CONFIG_EMULATE_HARDWARE
INSTANTIATE_TEST_CASE_P(SSE2, FwdTrans8x8DCT,
::testing::Values(make_tuple(&vpx_fdct8x8_sse2,
&vpx_idct8x8_64_add_sse2,
0, VPX_BITS_8)));
INSTANTIATE_TEST_CASE_P(
SSE2, FwdTrans8x8DCT,
::testing::Values(
make_tuple(&vpx_fdct8x8_sse2, &vpx_idct8x8_64_add_sse2, 0,
VPX_BITS_8)));
INSTANTIATE_TEST_CASE_P(
SSE2, FwdTrans8x8HT,
::testing::Values(
@@ -704,14 +730,14 @@ INSTANTIATE_TEST_CASE_P(
#if HAVE_SSE2 && CONFIG_VP9_HIGHBITDEPTH && !CONFIG_EMULATE_HARDWARE
INSTANTIATE_TEST_CASE_P(
SSE2, FwdTrans8x8DCT,
::testing::Values(make_tuple(&vpx_fdct8x8_sse2, &vpx_idct8x8_64_add_c, 0,
VPX_BITS_8),
make_tuple(&vpx_highbd_fdct8x8_c, &idct8x8_64_add_10_sse2,
12, VPX_BITS_10),
::testing::Values(
make_tuple(&vpx_fdct8x8_sse2, &vpx_idct8x8_64_add_c, 0, VPX_BITS_8),
make_tuple(&vpx_highbd_fdct8x8_c,
&idct8x8_64_add_10_sse2, 12, VPX_BITS_10),
make_tuple(&vpx_highbd_fdct8x8_sse2,
&idct8x8_64_add_10_sse2, 12, VPX_BITS_10),
make_tuple(&vpx_highbd_fdct8x8_c, &idct8x8_64_add_12_sse2,
12, VPX_BITS_12),
make_tuple(&vpx_highbd_fdct8x8_c,
&idct8x8_64_add_12_sse2, 12, VPX_BITS_12),
make_tuple(&vpx_highbd_fdct8x8_sse2,
&idct8x8_64_add_12_sse2, 12, VPX_BITS_12)));
@@ -728,27 +754,30 @@ INSTANTIATE_TEST_CASE_P(
INSTANTIATE_TEST_CASE_P(
SSE2, InvTrans8x8DCT,
::testing::Values(
make_tuple(&idct8x8_10_add_10_c, &idct8x8_10_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,
VPX_BITS_12),
make_tuple(&idct8x8_12, &idct8x8_64_add_12_sse2, 6225, VPX_BITS_12)));
make_tuple(&idct8x8_10_add_10_c,
&idct8x8_10_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, 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
#if HAVE_SSSE3 && ARCH_X86_64 && !CONFIG_VP9_HIGHBITDEPTH && \
!CONFIG_EMULATE_HARDWARE
INSTANTIATE_TEST_CASE_P(SSSE3, FwdTrans8x8DCT,
::testing::Values(make_tuple(&vpx_fdct8x8_ssse3,
&vpx_idct8x8_64_add_ssse3,
0, VPX_BITS_8)));
#if HAVE_SSSE3 && CONFIG_USE_X86INC && ARCH_X86_64 && \
!CONFIG_VP9_HIGHBITDEPTH && !CONFIG_EMULATE_HARDWARE
INSTANTIATE_TEST_CASE_P(
SSSE3, FwdTrans8x8DCT,
::testing::Values(
make_tuple(&vpx_fdct8x8_ssse3, &vpx_idct8x8_64_add_ssse3, 0,
VPX_BITS_8)));
#endif
#if HAVE_MSA && !CONFIG_VP9_HIGHBITDEPTH && !CONFIG_EMULATE_HARDWARE
INSTANTIATE_TEST_CASE_P(MSA, FwdTrans8x8DCT,
::testing::Values(make_tuple(&vpx_fdct8x8_msa,
&vpx_idct8x8_64_add_msa, 0,
VPX_BITS_8)));
INSTANTIATE_TEST_CASE_P(
MSA, FwdTrans8x8DCT,
::testing::Values(
make_tuple(&vpx_fdct8x8_msa, &vpx_idct8x8_64_add_msa, 0, VPX_BITS_8)));
INSTANTIATE_TEST_CASE_P(
MSA, FwdTrans8x8HT,
::testing::Values(

View File

@@ -13,11 +13,12 @@
namespace {
class VP9FrameSizeTestsLarge : public ::libvpx_test::EncoderTest,
class VP9FrameSizeTestsLarge
: public ::libvpx_test::EncoderTest,
public ::testing::Test {
protected:
VP9FrameSizeTestsLarge()
: EncoderTest(&::libvpx_test::kVP9), expected_res_(VPX_CODEC_OK) {}
VP9FrameSizeTestsLarge() : EncoderTest(&::libvpx_test::kVP9),
expected_res_(VPX_CODEC_OK) {}
virtual ~VP9FrameSizeTestsLarge() {}
virtual void SetUp() {

View File

@@ -1,220 +0,0 @@
/*
* Copyright (c) 2016 The WebM project authors. All Rights Reserved.
*
* Use of this source code is governed by a BSD-style license
* that can be found in the LICENSE file in the root of the source
* tree. An additional intellectual property rights grant can be found
* in the file PATENTS. All contributing project authors may
* be found in the AUTHORS file in the root of the source tree.
*/
#include <algorithm>
#include "third_party/googletest/src/include/gtest/gtest.h"
#include "./vpx_dsp_rtcd.h"
#include "test/acm_random.h"
#include "test/register_state_check.h"
namespace {
using ::libvpx_test::ACMRandom;
typedef void (*HadamardFunc)(const int16_t *a, int a_stride, int16_t *b);
void hadamard_loop(const int16_t *a, int a_stride, int16_t *out) {
int16_t b[8];
for (int i = 0; i < 8; i += 2) {
b[i + 0] = a[i * a_stride] + a[(i + 1) * a_stride];
b[i + 1] = a[i * a_stride] - a[(i + 1) * a_stride];
}
int16_t c[8];
for (int i = 0; i < 8; i += 4) {
c[i + 0] = b[i + 0] + b[i + 2];
c[i + 1] = b[i + 1] + b[i + 3];
c[i + 2] = b[i + 0] - b[i + 2];
c[i + 3] = b[i + 1] - b[i + 3];
}
out[0] = c[0] + c[4];
out[7] = c[1] + c[5];
out[3] = c[2] + c[6];
out[4] = c[3] + c[7];
out[2] = c[0] - c[4];
out[6] = c[1] - c[5];
out[1] = c[2] - c[6];
out[5] = c[3] - c[7];
}
void reference_hadamard8x8(const int16_t *a, int a_stride, int16_t *b) {
int16_t buf[64];
for (int i = 0; i < 8; ++i) {
hadamard_loop(a + i, a_stride, buf + i * 8);
}
for (int i = 0; i < 8; ++i) {
hadamard_loop(buf + i, 8, b + i * 8);
}
}
void reference_hadamard16x16(const int16_t *a, int a_stride, int16_t *b) {
/* The source is a 16x16 block. The destination is rearranged to 8x32.
* Input is 9 bit. */
reference_hadamard8x8(a + 0 + 0 * a_stride, a_stride, b + 0);
reference_hadamard8x8(a + 8 + 0 * a_stride, a_stride, b + 64);
reference_hadamard8x8(a + 0 + 8 * a_stride, a_stride, b + 128);
reference_hadamard8x8(a + 8 + 8 * a_stride, a_stride, b + 192);
/* Overlay the 8x8 blocks and combine. */
for (int i = 0; i < 64; ++i) {
/* 8x8 steps the range up to 15 bits. */
const int16_t a0 = b[0];
const int16_t a1 = b[64];
const int16_t a2 = b[128];
const int16_t a3 = b[192];
/* Prevent the result from escaping int16_t. */
const int16_t b0 = (a0 + a1) >> 1;
const int16_t b1 = (a0 - a1) >> 1;
const int16_t b2 = (a2 + a3) >> 1;
const int16_t b3 = (a2 - a3) >> 1;
/* Store a 16 bit value. */
b[0] = b0 + b2;
b[64] = b1 + b3;
b[128] = b0 - b2;
b[192] = b1 - b3;
++b;
}
}
class HadamardTestBase : public ::testing::TestWithParam<HadamardFunc> {
public:
virtual void SetUp() {
h_func_ = GetParam();
rnd_.Reset(ACMRandom::DeterministicSeed());
}
protected:
HadamardFunc h_func_;
ACMRandom rnd_;
};
class Hadamard8x8Test : public HadamardTestBase {};
TEST_P(Hadamard8x8Test, CompareReferenceRandom) {
DECLARE_ALIGNED(16, int16_t, a[64]);
DECLARE_ALIGNED(16, int16_t, b[64]);
int16_t b_ref[64];
for (int i = 0; i < 64; ++i) {
a[i] = rnd_.Rand9Signed();
}
memset(b, 0, sizeof(b));
memset(b_ref, 0, sizeof(b_ref));
reference_hadamard8x8(a, 8, b_ref);
ASM_REGISTER_STATE_CHECK(h_func_(a, 8, b));
// The order of the output is not important. Sort before checking.
std::sort(b, b + 64);
std::sort(b_ref, b_ref + 64);
EXPECT_EQ(0, memcmp(b, b_ref, sizeof(b)));
}
TEST_P(Hadamard8x8Test, VaryStride) {
DECLARE_ALIGNED(16, int16_t, a[64 * 8]);
DECLARE_ALIGNED(16, int16_t, b[64]);
int16_t b_ref[64];
for (int i = 0; i < 64 * 8; ++i) {
a[i] = rnd_.Rand9Signed();
}
for (int i = 8; i < 64; i += 8) {
memset(b, 0, sizeof(b));
memset(b_ref, 0, sizeof(b_ref));
reference_hadamard8x8(a, i, b_ref);
ASM_REGISTER_STATE_CHECK(h_func_(a, i, b));
// The order of the output is not important. Sort before checking.
std::sort(b, b + 64);
std::sort(b_ref, b_ref + 64);
EXPECT_EQ(0, memcmp(b, b_ref, sizeof(b)));
}
}
INSTANTIATE_TEST_CASE_P(C, Hadamard8x8Test,
::testing::Values(&vpx_hadamard_8x8_c));
#if HAVE_SSE2
INSTANTIATE_TEST_CASE_P(SSE2, Hadamard8x8Test,
::testing::Values(&vpx_hadamard_8x8_sse2));
#endif // HAVE_SSE2
#if HAVE_SSSE3 && ARCH_X86_64
INSTANTIATE_TEST_CASE_P(SSSE3, Hadamard8x8Test,
::testing::Values(&vpx_hadamard_8x8_ssse3));
#endif // HAVE_SSSE3 && ARCH_X86_64
#if HAVE_NEON
INSTANTIATE_TEST_CASE_P(NEON, Hadamard8x8Test,
::testing::Values(&vpx_hadamard_8x8_neon));
#endif // HAVE_NEON
class Hadamard16x16Test : public HadamardTestBase {};
TEST_P(Hadamard16x16Test, CompareReferenceRandom) {
DECLARE_ALIGNED(16, int16_t, a[16 * 16]);
DECLARE_ALIGNED(16, int16_t, b[16 * 16]);
int16_t b_ref[16 * 16];
for (int i = 0; i < 16 * 16; ++i) {
a[i] = rnd_.Rand9Signed();
}
memset(b, 0, sizeof(b));
memset(b_ref, 0, sizeof(b_ref));
reference_hadamard16x16(a, 16, b_ref);
ASM_REGISTER_STATE_CHECK(h_func_(a, 16, b));
// The order of the output is not important. Sort before checking.
std::sort(b, b + 16 * 16);
std::sort(b_ref, b_ref + 16 * 16);
EXPECT_EQ(0, memcmp(b, b_ref, sizeof(b)));
}
TEST_P(Hadamard16x16Test, VaryStride) {
DECLARE_ALIGNED(16, int16_t, a[16 * 16 * 8]);
DECLARE_ALIGNED(16, int16_t, b[16 * 16]);
int16_t b_ref[16 * 16];
for (int i = 0; i < 16 * 16 * 8; ++i) {
a[i] = rnd_.Rand9Signed();
}
for (int i = 8; i < 64; i += 8) {
memset(b, 0, sizeof(b));
memset(b_ref, 0, sizeof(b_ref));
reference_hadamard16x16(a, i, b_ref);
ASM_REGISTER_STATE_CHECK(h_func_(a, i, b));
// The order of the output is not important. Sort before checking.
std::sort(b, b + 16 * 16);
std::sort(b_ref, b_ref + 16 * 16);
EXPECT_EQ(0, memcmp(b, b_ref, sizeof(b)));
}
}
INSTANTIATE_TEST_CASE_P(C, Hadamard16x16Test,
::testing::Values(&vpx_hadamard_16x16_c));
#if HAVE_SSE2
INSTANTIATE_TEST_CASE_P(SSE2, Hadamard16x16Test,
::testing::Values(&vpx_hadamard_16x16_sse2));
#endif // HAVE_SSE2
#if HAVE_NEON
INSTANTIATE_TEST_CASE_P(NEON, Hadamard16x16Test,
::testing::Values(&vpx_hadamard_16x16_neon));
#endif // HAVE_NEON
} // namespace

View File

@@ -21,11 +21,14 @@ namespace libvpx_test {
// so that we can do actual file encodes.
class I420VideoSource : public YUVVideoSource {
public:
I420VideoSource(const std::string &file_name, unsigned int width,
unsigned int height, int rate_numerator, int rate_denominator,
I420VideoSource(const std::string &file_name,
unsigned int width, unsigned int height,
int rate_numerator, int rate_denominator,
unsigned int start, int limit)
: YUVVideoSource(file_name, VPX_IMG_FMT_I420, width, height,
rate_numerator, rate_denominator, start, limit) {}
: YUVVideoSource(file_name, VPX_IMG_FMT_I420,
width, height,
rate_numerator, rate_denominator,
start, limit) {}
};
} // namespace libvpx_test

View File

@@ -17,21 +17,29 @@
#include "./vpx_dsp_rtcd.h"
#include "test/acm_random.h"
#include "vpx/vpx_integer.h"
#include "vpx_ports/msvc.h" // for round()
using libvpx_test::ACMRandom;
namespace {
#ifdef _MSC_VER
static int round(double x) {
if (x < 0)
return static_cast<int>(ceil(x - 0.5));
else
return static_cast<int>(floor(x + 0.5));
}
#endif
void reference_dct_1d(double input[8], double output[8]) {
const double kPi = 3.141592653589793238462643383279502884;
const double kInvSqrt2 = 0.707106781186547524400844362104;
for (int k = 0; k < 8; k++) {
output[k] = 0.0;
for (int n = 0; n < 8; n++) {
for (int n = 0; n < 8; n++)
output[k] += input[n]*cos(kPi*(2*n+1)*k/16.0);
}
if (k == 0) output[k] = output[k] * kInvSqrt2;
if (k == 0)
output[k] = output[k]*kInvSqrt2;
}
}
@@ -39,19 +47,24 @@ void reference_dct_2d(int16_t input[64], double output[64]) {
// First transform columns
for (int i = 0; i < 8; ++i) {
double temp_in[8], temp_out[8];
for (int j = 0; j < 8; ++j) temp_in[j] = input[j * 8 + i];
for (int j = 0; j < 8; ++j)
temp_in[j] = input[j*8 + i];
reference_dct_1d(temp_in, temp_out);
for (int j = 0; j < 8; ++j) output[j * 8 + i] = temp_out[j];
for (int j = 0; j < 8; ++j)
output[j*8 + i] = temp_out[j];
}
// Then transform rows
for (int i = 0; i < 8; ++i) {
double temp_in[8], temp_out[8];
for (int j = 0; j < 8; ++j) temp_in[j] = output[j + i * 8];
for (int j = 0; j < 8; ++j)
temp_in[j] = output[j + i*8];
reference_dct_1d(temp_in, temp_out);
for (int j = 0; j < 8; ++j) output[j + i * 8] = temp_out[j];
for (int j = 0; j < 8; ++j)
output[j + i*8] = temp_out[j];
}
// Scale by some magic number
for (int i = 0; i < 64; ++i) output[i] *= 2;
for (int i = 0; i < 64; ++i)
output[i] *= 2;
}
TEST(VP9Idct8x8Test, AccuracyCheck) {
@@ -68,17 +81,18 @@ TEST(VP9Idct8x8Test, AccuracyCheck) {
dst[j] = rnd.Rand8();
}
// Initialize a test block with input range [-255, 255].
for (int j = 0; j < 64; ++j) input[j] = src[j] - dst[j];
for (int j = 0; j < 64; ++j)
input[j] = src[j] - dst[j];
reference_dct_2d(input, output_r);
for (int j = 0; j < 64; ++j) {
coeff[j] = static_cast<tran_low_t>(round(output_r[j]));
}
for (int j = 0; j < 64; ++j)
coeff[j] = round(output_r[j]);
vpx_idct8x8_64_add_c(coeff, dst, 8);
for (int j = 0; j < 64; ++j) {
const int diff = dst[j] - src[j];
const int error = diff * diff;
EXPECT_GE(1, error) << "Error: 8x8 FDCT/IDCT has error " << error
EXPECT_GE(1, error)
<< "Error: 8x8 FDCT/IDCT has error " << error
<< " at index " << j;
}
}

View File

@@ -43,26 +43,24 @@ class IDCTTest : public ::testing::TestWithParam<IdctFunc> {
TEST_P(IDCTTest, TestGuardBlocks) {
int i;
for (i = 0; i < 256; 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) {
int i;
ASM_REGISTER_STATE_CHECK(UUT(input, output, 16, output, 16));
for (i = 0; i < 256; i++) {
for (i = 0; i < 256; i++)
if ((i & 0xF) < 4 && i < 64)
EXPECT_EQ(0, output[i]) << "i==" << i;
else
EXPECT_EQ(255, output[i]) << "i==" << i;
}
}
TEST_P(IDCTTest, TestAllOnes) {
int i;
@@ -70,13 +68,12 @@ TEST_P(IDCTTest, TestAllOnes) {
input[0] = 4;
ASM_REGISTER_STATE_CHECK(UUT(input, output, 16, output, 16));
for (i = 0; i < 256; i++) {
for (i = 0; i < 256; i++)
if ((i & 0xF) < 4 && i < 64)
EXPECT_EQ(1, output[i]) << "i==" << i;
else
EXPECT_EQ(255, output[i]) << "i==" << i;
}
}
TEST_P(IDCTTest, TestAddOne) {
int i;
@@ -85,13 +82,12 @@ TEST_P(IDCTTest, TestAddOne) {
input[0] = 4;
ASM_REGISTER_STATE_CHECK(UUT(input, predict, 16, output, 16));
for (i = 0; i < 256; i++) {
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;
}
}
TEST_P(IDCTTest, TestWithData) {
int i;
@@ -100,7 +96,7 @@ TEST_P(IDCTTest, TestWithData) {
ASM_REGISTER_STATE_CHECK(UUT(input, output, 16, output, 16));
for (i = 0; i < 256; i++) {
for (i = 0; i < 256; i++)
if ((i & 0xF) > 3 || i > 63)
EXPECT_EQ(255, output[i]) << "i==" << i;
else if (i == 0)
@@ -112,7 +108,6 @@ TEST_P(IDCTTest, TestWithData) {
else
EXPECT_EQ(0, output[i]) << "i==" << i;
}
}
INSTANTIATE_TEST_CASE_P(C, IDCTTest, ::testing::Values(vp8_short_idct4x4llm_c));
#if HAVE_MMX

406
test/intrapred_test.cc Normal file
View File

@@ -0,0 +1,406 @@
/*
* 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 <string.h>
#include "third_party/googletest/src/include/gtest/gtest.h"
#include "./vpx_config.h"
#include "./vp8_rtcd.h"
#include "test/acm_random.h"
#include "test/clear_system_state.h"
#include "test/register_state_check.h"
#include "vp8/common/blockd.h"
#include "vpx_mem/vpx_mem.h"
namespace {
using libvpx_test::ACMRandom;
class IntraPredBase {
public:
virtual ~IntraPredBase() { libvpx_test::ClearSystemState(); }
protected:
void SetupMacroblock(MACROBLOCKD *mbptr,
MODE_INFO *miptr,
uint8_t *data,
int block_size,
int stride,
int num_planes) {
mbptr_ = mbptr;
miptr_ = miptr;
mbptr_->up_available = 1;
mbptr_->left_available = 1;
mbptr_->mode_info_context = miptr_;
stride_ = stride;
block_size_ = block_size;
num_planes_ = num_planes;
for (int p = 0; p < num_planes; p++)
data_ptr_[p] = data + stride * (block_size + 1) * p +
stride + block_size;
}
void FillRandom() {
// Fill edges with random data
ACMRandom rnd(ACMRandom::DeterministicSeed());
for (int p = 0; p < num_planes_; p++) {
for (int x = -1 ; x <= block_size_; x++)
data_ptr_[p][x - stride_] = rnd.Rand8();
for (int y = 0; y < block_size_; y++)
data_ptr_[p][y * stride_ - 1] = rnd.Rand8();
}
}
virtual void Predict(MB_PREDICTION_MODE mode) = 0;
void SetLeftUnavailable() {
mbptr_->left_available = 0;
for (int p = 0; p < num_planes_; p++)
for (int i = -1; i < block_size_; ++i)
data_ptr_[p][stride_ * i - 1] = 129;
}
void SetTopUnavailable() {
mbptr_->up_available = 0;
for (int p = 0; p < num_planes_; p++)
memset(&data_ptr_[p][-1 - stride_], 127, block_size_ + 2);
}
void SetTopLeftUnavailable() {
SetLeftUnavailable();
SetTopUnavailable();
}
int BlockSizeLog2Min1() const {
switch (block_size_) {
case 16:
return 3;
case 8:
return 2;
default:
return 0;
}
}
// check DC prediction output against a reference
void CheckDCPrediction() const {
for (int p = 0; p < num_planes_; p++) {
// calculate expected DC
int expected;
if (mbptr_->up_available || mbptr_->left_available) {
int sum = 0, shift = BlockSizeLog2Min1() + mbptr_->up_available +
mbptr_->left_available;
if (mbptr_->up_available)
for (int x = 0; x < block_size_; x++)
sum += data_ptr_[p][x - stride_];
if (mbptr_->left_available)
for (int y = 0; y < block_size_; y++)
sum += data_ptr_[p][y * stride_ - 1];
expected = (sum + (1 << (shift - 1))) >> shift;
} else {
expected = 0x80;
}
// check that all subsequent lines are equal to the first
for (int y = 1; y < block_size_; ++y)
ASSERT_EQ(0, memcmp(data_ptr_[p], &data_ptr_[p][y * stride_],
block_size_));
// within the first line, ensure that each pixel has the same value
for (int x = 1; x < block_size_; ++x)
ASSERT_EQ(data_ptr_[p][0], data_ptr_[p][x]);
// now ensure that that pixel has the expected (DC) value
ASSERT_EQ(expected, data_ptr_[p][0]);
}
}
// check V prediction output against a reference
void CheckVPrediction() const {
// check that all lines equal the top border
for (int p = 0; p < num_planes_; p++)
for (int y = 0; y < block_size_; y++)
ASSERT_EQ(0, memcmp(&data_ptr_[p][-stride_],
&data_ptr_[p][y * stride_], block_size_));
}
// check H prediction output against a reference
void CheckHPrediction() const {
// for each line, ensure that each pixel is equal to the left border
for (int p = 0; p < num_planes_; p++)
for (int y = 0; y < block_size_; y++)
for (int x = 0; x < block_size_; x++)
ASSERT_EQ(data_ptr_[p][-1 + y * stride_],
data_ptr_[p][x + y * stride_]);
}
static int ClipByte(int value) {
if (value > 255)
return 255;
else if (value < 0)
return 0;
return value;
}
// check TM prediction output against a reference
void CheckTMPrediction() const {
for (int p = 0; p < num_planes_; p++)
for (int y = 0; y < block_size_; y++)
for (int x = 0; x < block_size_; x++) {
const int expected = ClipByte(data_ptr_[p][x - stride_]
+ data_ptr_[p][stride_ * y - 1]
- data_ptr_[p][-1 - stride_]);
ASSERT_EQ(expected, data_ptr_[p][y * stride_ + x]);
}
}
// Actual test
void RunTest() {
{
SCOPED_TRACE("DC_PRED");
FillRandom();
Predict(DC_PRED);
CheckDCPrediction();
}
{
SCOPED_TRACE("DC_PRED LEFT");
FillRandom();
SetLeftUnavailable();
Predict(DC_PRED);
CheckDCPrediction();
}
{
SCOPED_TRACE("DC_PRED TOP");
FillRandom();
SetTopUnavailable();
Predict(DC_PRED);
CheckDCPrediction();
}
{
SCOPED_TRACE("DC_PRED TOP_LEFT");
FillRandom();
SetTopLeftUnavailable();
Predict(DC_PRED);
CheckDCPrediction();
}
{
SCOPED_TRACE("H_PRED");
FillRandom();
Predict(H_PRED);
CheckHPrediction();
}
{
SCOPED_TRACE("V_PRED");
FillRandom();
Predict(V_PRED);
CheckVPrediction();
}
{
SCOPED_TRACE("TM_PRED");
FillRandom();
Predict(TM_PRED);
CheckTMPrediction();
}
}
MACROBLOCKD *mbptr_;
MODE_INFO *miptr_;
uint8_t *data_ptr_[2]; // in the case of Y, only [0] is used
int stride_;
int block_size_;
int num_planes_;
};
typedef void (*IntraPredYFunc)(MACROBLOCKD *x,
uint8_t *yabove_row,
uint8_t *yleft,
int left_stride,
uint8_t *ypred_ptr,
int y_stride);
class IntraPredYTest
: public IntraPredBase,
public ::testing::TestWithParam<IntraPredYFunc> {
public:
static void SetUpTestCase() {
mb_ = reinterpret_cast<MACROBLOCKD*>(
vpx_memalign(32, sizeof(MACROBLOCKD)));
mi_ = reinterpret_cast<MODE_INFO*>(
vpx_memalign(32, sizeof(MODE_INFO)));
data_array_ = reinterpret_cast<uint8_t*>(
vpx_memalign(kDataAlignment, kDataBufferSize));
}
static void TearDownTestCase() {
vpx_free(data_array_);
vpx_free(mi_);
vpx_free(mb_);
data_array_ = NULL;
}
protected:
static const int kBlockSize = 16;
static const int kDataAlignment = 16;
static const int kStride = kBlockSize * 3;
// We use 48 so that the data pointer of the first pixel in each row of
// each macroblock is 16-byte aligned, and this gives us access to the
// top-left and top-right corner pixels belonging to the top-left/right
// macroblocks.
// We use 17 lines so we have one line above us for top-prediction.
static const int kDataBufferSize = kStride * (kBlockSize + 1);
virtual void SetUp() {
pred_fn_ = GetParam();
SetupMacroblock(mb_, mi_, data_array_, kBlockSize, kStride, 1);
}
virtual void Predict(MB_PREDICTION_MODE mode) {
mbptr_->mode_info_context->mbmi.mode = mode;
ASM_REGISTER_STATE_CHECK(pred_fn_(mbptr_,
data_ptr_[0] - kStride,
data_ptr_[0] - 1, kStride,
data_ptr_[0], kStride));
}
IntraPredYFunc pred_fn_;
static uint8_t* data_array_;
static MACROBLOCKD * mb_;
static MODE_INFO *mi_;
};
MACROBLOCKD* IntraPredYTest::mb_ = NULL;
MODE_INFO* IntraPredYTest::mi_ = NULL;
uint8_t* IntraPredYTest::data_array_ = NULL;
TEST_P(IntraPredYTest, IntraPredTests) {
RunTest();
}
INSTANTIATE_TEST_CASE_P(C, IntraPredYTest,
::testing::Values(
vp8_build_intra_predictors_mby_s_c));
#if HAVE_SSE2
INSTANTIATE_TEST_CASE_P(SSE2, IntraPredYTest,
::testing::Values(
vp8_build_intra_predictors_mby_s_sse2));
#endif
#if HAVE_SSSE3
INSTANTIATE_TEST_CASE_P(SSSE3, IntraPredYTest,
::testing::Values(
vp8_build_intra_predictors_mby_s_ssse3));
#endif
#if HAVE_NEON
INSTANTIATE_TEST_CASE_P(NEON, IntraPredYTest,
::testing::Values(
vp8_build_intra_predictors_mby_s_neon));
#endif
#if HAVE_MSA
INSTANTIATE_TEST_CASE_P(MSA, IntraPredYTest,
::testing::Values(
vp8_build_intra_predictors_mby_s_msa));
#endif
typedef void (*IntraPredUvFunc)(MACROBLOCKD *x,
uint8_t *uabove_row,
uint8_t *vabove_row,
uint8_t *uleft,
uint8_t *vleft,
int left_stride,
uint8_t *upred_ptr,
uint8_t *vpred_ptr,
int pred_stride);
class IntraPredUVTest
: public IntraPredBase,
public ::testing::TestWithParam<IntraPredUvFunc> {
public:
static void SetUpTestCase() {
mb_ = reinterpret_cast<MACROBLOCKD*>(
vpx_memalign(32, sizeof(MACROBLOCKD)));
mi_ = reinterpret_cast<MODE_INFO*>(
vpx_memalign(32, sizeof(MODE_INFO)));
data_array_ = reinterpret_cast<uint8_t*>(
vpx_memalign(kDataAlignment, kDataBufferSize));
}
static void TearDownTestCase() {
vpx_free(data_array_);
vpx_free(mi_);
vpx_free(mb_);
data_array_ = NULL;
}
protected:
static const int kBlockSize = 8;
static const int kDataAlignment = 8;
static const int kStride = kBlockSize * 3;
// We use 24 so that the data pointer of the first pixel in each row of
// each macroblock is 8-byte aligned, and this gives us access to the
// top-left and top-right corner pixels belonging to the top-left/right
// macroblocks.
// We use 9 lines so we have one line above us for top-prediction.
// [0] = U, [1] = V
static const int kDataBufferSize = 2 * kStride * (kBlockSize + 1);
virtual void SetUp() {
pred_fn_ = GetParam();
SetupMacroblock(mb_, mi_, data_array_, kBlockSize, kStride, 2);
}
virtual void Predict(MB_PREDICTION_MODE mode) {
mbptr_->mode_info_context->mbmi.uv_mode = mode;
pred_fn_(mbptr_, data_ptr_[0] - kStride, data_ptr_[1] - kStride,
data_ptr_[0] - 1, data_ptr_[1] - 1, kStride,
data_ptr_[0], data_ptr_[1], kStride);
}
IntraPredUvFunc pred_fn_;
// We use 24 so that the data pointer of the first pixel in each row of
// each macroblock is 8-byte aligned, and this gives us access to the
// top-left and top-right corner pixels belonging to the top-left/right
// macroblocks.
// We use 9 lines so we have one line above us for top-prediction.
// [0] = U, [1] = V
static uint8_t* data_array_;
static MACROBLOCKD* mb_;
static MODE_INFO* mi_;
};
MACROBLOCKD* IntraPredUVTest::mb_ = NULL;
MODE_INFO* IntraPredUVTest::mi_ = NULL;
uint8_t* IntraPredUVTest::data_array_ = NULL;
TEST_P(IntraPredUVTest, IntraPredTests) {
RunTest();
}
INSTANTIATE_TEST_CASE_P(C, IntraPredUVTest,
::testing::Values(
vp8_build_intra_predictors_mbuv_s_c));
#if HAVE_SSE2
INSTANTIATE_TEST_CASE_P(SSE2, IntraPredUVTest,
::testing::Values(
vp8_build_intra_predictors_mbuv_s_sse2));
#endif
#if HAVE_SSSE3
INSTANTIATE_TEST_CASE_P(SSSE3, IntraPredUVTest,
::testing::Values(
vp8_build_intra_predictors_mbuv_s_ssse3));
#endif
#if HAVE_NEON
INSTANTIATE_TEST_CASE_P(NEON, IntraPredUVTest,
::testing::Values(
vp8_build_intra_predictors_mbuv_s_neon));
#endif
#if HAVE_MSA
INSTANTIATE_TEST_CASE_P(MSA, IntraPredUVTest,
::testing::Values(
vp8_build_intra_predictors_mbuv_s_msa));
#endif
} // namespace

View File

@@ -34,13 +34,15 @@ std::ostream &operator<<(std::ostream &os, const DecodeParam &dp) {
return os << "threads: " << dp.threads << " file: " << dp.filename;
}
class InvalidFileTest : public ::libvpx_test::DecoderTest,
class InvalidFileTest
: public ::libvpx_test::DecoderTest,
public ::libvpx_test::CodecTestWithParam<DecodeParam> {
protected:
InvalidFileTest() : DecoderTest(GET_PARAM(0)), res_file_(NULL) {}
virtual ~InvalidFileTest() {
if (res_file_ != NULL) fclose(res_file_);
if (res_file_ != NULL)
fclose(res_file_);
}
void OpenResFile(const std::string &res_file_name_) {
@@ -61,47 +63,32 @@ class InvalidFileTest : public ::libvpx_test::DecoderTest,
EXPECT_NE(res, EOF) << "Read result data failed";
// Check results match.
const DecodeParam input = GET_PARAM(1);
if (input.threads > 1) {
// The serial decode check is too strict for tile-threaded decoding as
// there is no guarantee on the decode order nor which specific error
// will take precedence. Currently a tile-level error is not forwarded so
// the frame will simply be marked corrupt.
EXPECT_TRUE(res_dec == expected_res_dec ||
res_dec == VPX_CODEC_CORRUPT_FRAME)
<< "Results don't match: frame number = " << video.frame_number()
<< ". (" << decoder->DecodeError()
<< "). Expected: " << expected_res_dec << " or "
<< VPX_CODEC_CORRUPT_FRAME;
} else {
EXPECT_EQ(expected_res_dec, res_dec)
<< "Results don't match: frame number = " << video.frame_number()
<< ". (" << decoder->DecodeError() << ")";
}
return !HasFailure();
}
void RunTest() {
const DecodeParam input = GET_PARAM(1);
libvpx_test::CompressedVideoSource *video = NULL;
vpx_codec_dec_cfg_t cfg = vpx_codec_dec_cfg_t();
cfg.threads = input.threads;
const std::string filename = input.filename;
// Open compressed video file.
testing::internal::scoped_ptr<libvpx_test::CompressedVideoSource> video;
if (filename.substr(filename.length() - 3, 3) == "ivf") {
video.reset(new libvpx_test::IVFVideoSource(filename));
video = new libvpx_test::IVFVideoSource(filename);
} else if (filename.substr(filename.length() - 4, 4) == "webm") {
#if CONFIG_WEBM_IO
video.reset(new libvpx_test::WebMVideoSource(filename));
video = new libvpx_test::WebMVideoSource(filename);
#else
fprintf(stderr, "WebM IO is disabled, skipping test vector %s\n",
filename.c_str());
return;
#endif
}
ASSERT_TRUE(video.get() != NULL);
video->Init();
// Construct result file name. The file holds a list of expected integer
@@ -111,14 +98,17 @@ class InvalidFileTest : public ::libvpx_test::DecoderTest,
OpenResFile(res_filename);
// Decode frame, and check the md5 matching.
ASSERT_NO_FATAL_FAILURE(RunLoop(video.get(), cfg));
ASSERT_NO_FATAL_FAILURE(RunLoop(video, cfg));
delete video;
}
private:
FILE *res_file_;
};
TEST_P(InvalidFileTest, ReturnCode) { RunTest(); }
TEST_P(InvalidFileTest, ReturnCode) {
RunTest();
}
const DecodeParam kVP9InvalidFileTests[] = {
{1, "invalid-vp90-02-v2.webm"},
@@ -128,12 +118,6 @@ const DecodeParam kVP9InvalidFileTests[] = {
{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-z.ivf"},
// This file will cause a large allocation which is expected to fail in 32-bit
// environments. Test x86 for coverage purposes as the allocation failure will
// be in platform agnostic code.
#if ARCH_X86
{ 1, "invalid-vp90-2-00-quantizer-63.ivf.kf_65527x61446.ivf" },
#endif
{1, "invalid-vp90-2-12-droppable_1.ivf.s3676_r01-05_b6-.ivf"},
{1, "invalid-vp90-2-05-resize.ivf.s59293_r01-05_b6-.ivf"},
{1, "invalid-vp90-2-09-subpixel-00.ivf.s20492_r01-05_b6-.v2.ivf"},
@@ -156,7 +140,9 @@ class InvalidFileInvalidPeekTest : public InvalidFileTest {
const vpx_codec_err_t /*res_peek*/) {}
};
TEST_P(InvalidFileInvalidPeekTest, ReturnCode) { RunTest(); }
TEST_P(InvalidFileInvalidPeekTest, ReturnCode) {
RunTest();
}
const DecodeParam kVP9InvalidFileInvalidPeekTests[] = {
{1, "invalid-vp90-01-v3.webm"},
@@ -167,11 +153,9 @@ VP9_INSTANTIATE_TEST_CASE(InvalidFileInvalidPeekTest,
const DecodeParam kMultiThreadedVP9InvalidFileTests[] = {
{4, "invalid-vp90-2-08-tile_1x4_frame_parallel_all_key.webm"},
{ 4,
"invalid-"
{4, "invalid-"
"vp90-2-08-tile_1x2_frame_parallel.webm.ivf.s47039_r01-05_b6-.ivf"},
{ 4,
"invalid-vp90-2-08-tile_1x8_frame_parallel.webm.ivf.s288_r01-05_b6-.ivf" },
{4, "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"},
{4, "invalid-vp90-2-09-subpixel-00.ivf.s19552_r01-05_b6-.v2.ivf"},
};

View File

@@ -29,13 +29,19 @@ static unsigned int MemGetLe32(const uint8_t *mem) {
class IVFVideoSource : public CompressedVideoSource {
public:
explicit IVFVideoSource(const std::string &file_name)
: file_name_(file_name), input_file_(NULL), compressed_frame_buf_(NULL),
frame_sz_(0), frame_(0), end_of_file_(false) {}
: file_name_(file_name),
input_file_(NULL),
compressed_frame_buf_(NULL),
frame_sz_(0),
frame_(0),
end_of_file_(false) {
}
virtual ~IVFVideoSource() {
delete[] compressed_frame_buf_;
if (input_file_) fclose(input_file_);
if (input_file_)
fclose(input_file_);
}
virtual void Init() {
@@ -55,9 +61,8 @@ class IVFVideoSource : public CompressedVideoSource {
ASSERT_EQ(kIvfFileHdrSize, fread(file_hdr, 1, kIvfFileHdrSize, input_file_))
<< "File header read failed.";
// Check file header
ASSERT_TRUE(file_hdr[0] == 'D' && file_hdr[1] == 'K' &&
file_hdr[2] == 'I' && file_hdr[3] == 'F')
<< "Input is not an IVF file.";
ASSERT_TRUE(file_hdr[0] == 'D' && file_hdr[1] == 'K' && file_hdr[2] == 'I'
&& file_hdr[3] == 'F') << "Input is not an IVF file.";
FillFrame();
}
@@ -71,8 +76,8 @@ class IVFVideoSource : public CompressedVideoSource {
ASSERT_TRUE(input_file_ != NULL);
uint8_t frame_hdr[kIvfFrameHdrSize];
// Check frame header and read a frame from input_file.
if (fread(frame_hdr, 1, kIvfFrameHdrSize, input_file_) !=
kIvfFrameHdrSize) {
if (fread(frame_hdr, 1, kIvfFrameHdrSize, input_file_)
!= kIvfFrameHdrSize) {
end_of_file_ = true;
} else {
end_of_file_ = false;

View File

@@ -17,8 +17,7 @@
namespace {
class KeyframeTest
: public ::libvpx_test::EncoderTest,
class KeyframeTest : public ::libvpx_test::EncoderTest,
public ::libvpx_test::CodecTestWithParam<libvpx_test::TestMode> {
protected:
KeyframeTest() : EncoderTest(GET_PARAM(0)) {}
@@ -35,13 +34,11 @@ class KeyframeTest
virtual void PreEncodeFrameHook(::libvpx_test::VideoSource *video,
::libvpx_test::Encoder *encoder) {
if (kf_do_force_kf_) {
if (kf_do_force_kf_)
frame_flags_ = (video->frame() % 3) ? 0 : VPX_EFLAG_FORCE_KF;
}
if (set_cpu_used_ && video->frame() == 1) {
if (set_cpu_used_ && video->frame() == 1)
encoder->Control(VP8E_SET_CPUUSED, set_cpu_used_);
}
}
virtual void FramePktHook(const vpx_codec_cx_pkt_t *pkt) {
if (pkt->data.frame.flags & VPX_FRAME_IS_KEY) {
@@ -68,7 +65,8 @@ TEST_P(KeyframeTest, TestRandomVideoSource) {
// In realtime mode - auto placed keyframes are exceedingly rare, don't
// bother with this check if(GetParam() > 0)
if (GET_PARAM(1) > 0) EXPECT_GT(kf_count_, 1);
if (GET_PARAM(1) > 0)
EXPECT_GT(kf_count_, 1);
}
TEST_P(KeyframeTest, TestDisableKeyframes) {
@@ -116,7 +114,8 @@ TEST_P(KeyframeTest, TestAutoKeyframe) {
// may not produce a keyframe like we expect. This is necessary when running
// on very slow environments (like Valgrind). The step -11 was determined
// experimentally as the fastest mode that still throws the keyframe.
if (deadline_ == VPX_DL_REALTIME) set_cpu_used_ = -11;
if (deadline_ == VPX_DL_REALTIME)
set_cpu_used_ = -11;
// This clip has a cut scene every 30 frames -> Frame 0, 30, 60, 90, 120.
// I check only the first 40 frames to make sure there's a keyframe at frame

View File

@@ -1,116 +0,0 @@
/*
* Copyright (c) 2016 The WebM project authors. All Rights Reserved.
*
* Use of this source code is governed by a BSD-style license
* that can be found in the LICENSE file in the root of the source
* tree. An additional intellectual property rights grant can be found
* in the file PATENTS. All contributing project authors may
* be found in the AUTHORS file in the root of the source tree.
*/
#include "third_party/googletest/src/include/gtest/gtest.h"
#include "test/codec_factory.h"
#include "test/encode_test_driver.h"
#include "test/i420_video_source.h"
#include "test/util.h"
namespace {
class LevelTest
: public ::libvpx_test::EncoderTest,
public ::libvpx_test::CodecTestWith2Params<libvpx_test::TestMode, int> {
protected:
LevelTest()
: EncoderTest(GET_PARAM(0)), encoding_mode_(GET_PARAM(1)),
cpu_used_(GET_PARAM(2)), min_gf_internal_(24), target_level_(0),
level_(0) {}
virtual ~LevelTest() {}
virtual void SetUp() {
InitializeConfig();
SetMode(encoding_mode_);
if (encoding_mode_ != ::libvpx_test::kRealTime) {
cfg_.g_lag_in_frames = 25;
cfg_.rc_end_usage = VPX_VBR;
} else {
cfg_.g_lag_in_frames = 0;
cfg_.rc_end_usage = VPX_CBR;
}
cfg_.rc_2pass_vbr_minsection_pct = 5;
cfg_.rc_2pass_vbr_maxsection_pct = 2000;
cfg_.rc_target_bitrate = 400;
cfg_.rc_max_quantizer = 63;
cfg_.rc_min_quantizer = 0;
}
virtual void PreEncodeFrameHook(::libvpx_test::VideoSource *video,
::libvpx_test::Encoder *encoder) {
if (video->frame() == 0) {
encoder->Control(VP8E_SET_CPUUSED, cpu_used_);
encoder->Control(VP9E_SET_TARGET_LEVEL, target_level_);
encoder->Control(VP9E_SET_MIN_GF_INTERVAL, min_gf_internal_);
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);
}
}
encoder->Control(VP9E_GET_LEVEL, &level_);
ASSERT_LE(level_, 51);
ASSERT_GE(level_, 0);
}
::libvpx_test::TestMode encoding_mode_;
int cpu_used_;
int min_gf_internal_;
int target_level_;
int level_;
};
// Test for keeping level stats only
TEST_P(LevelTest, TestTargetLevel0) {
::libvpx_test::I420VideoSource video("hantro_odd.yuv", 208, 144, 30, 1, 0,
40);
target_level_ = 0;
min_gf_internal_ = 4;
ASSERT_NO_FATAL_FAILURE(RunLoop(&video));
ASSERT_EQ(11, level_);
cfg_.rc_target_bitrate = 1600;
ASSERT_NO_FATAL_FAILURE(RunLoop(&video));
ASSERT_EQ(20, level_);
}
// Test for level control being turned off
TEST_P(LevelTest, TestTargetLevel255) {
::libvpx_test::I420VideoSource video("hantro_odd.yuv", 208, 144, 30, 1, 0,
30);
target_level_ = 255;
ASSERT_NO_FATAL_FAILURE(RunLoop(&video));
}
TEST_P(LevelTest, TestTargetLevelApi) {
::libvpx_test::I420VideoSource video("hantro_odd.yuv", 208, 144, 30, 1, 0, 1);
static const vpx_codec_iface_t *codec = &vpx_codec_vp9_cx_algo;
vpx_codec_ctx_t enc;
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_init(&enc, codec, &cfg, 0));
for (int level = 0; level <= 256; ++level) {
if (level == 10 || level == 11 || level == 20 || level == 21 ||
level == 30 || level == 31 || level == 40 || level == 41 ||
level == 50 || level == 51 || level == 52 || level == 60 ||
level == 61 || level == 62 || level == 0 || level == 255)
EXPECT_EQ(VPX_CODEC_OK,
vpx_codec_control(&enc, VP9E_SET_TARGET_LEVEL, level));
else
EXPECT_EQ(VPX_CODEC_INVALID_PARAM,
vpx_codec_control(&enc, VP9E_SET_TARGET_LEVEL, level));
}
EXPECT_EQ(VPX_CODEC_OK, vpx_codec_destroy(&enc));
}
VP9_INSTANTIATE_TEST_CASE(LevelTest,
::testing::Values(::libvpx_test::kTwoPassGood,
::libvpx_test::kOnePassGood),
::testing::Range(0, 9));
} // namespace

View File

@@ -35,85 +35,122 @@ const int kNumCoeffs = 1024;
const int number_of_iterations = 10000;
#if CONFIG_VP9_HIGHBITDEPTH
typedef uint16_t Pixel;
#define PIXEL_WIDTH 16
typedef void (*loop_op_t)(Pixel *s, int p, const uint8_t *blimit,
const uint8_t *limit, const uint8_t *thresh, int bd);
typedef void (*dual_loop_op_t)(Pixel *s, int p, const uint8_t *blimit0,
typedef void (*loop_op_t)(uint16_t *s, int p, const uint8_t *blimit,
const uint8_t *limit, const uint8_t *thresh,
int count, int bd);
typedef void (*dual_loop_op_t)(uint16_t *s, int p, const uint8_t *blimit0,
const uint8_t *limit0, const uint8_t *thresh0,
const uint8_t *blimit1, const uint8_t *limit1,
const uint8_t *thresh1, int bd);
#else
typedef uint8_t Pixel;
#define PIXEL_WIDTH 8
typedef void (*loop_op_t)(Pixel *s, int p, const uint8_t *blimit,
const uint8_t *limit, const uint8_t *thresh);
typedef void (*dual_loop_op_t)(Pixel *s, int p, const uint8_t *blimit0,
typedef void (*loop_op_t)(uint8_t *s, int p, const uint8_t *blimit,
const uint8_t *limit, const uint8_t *thresh,
int count);
typedef void (*dual_loop_op_t)(uint8_t *s, int p, const uint8_t *blimit0,
const uint8_t *limit0, const uint8_t *thresh0,
const uint8_t *blimit1, const uint8_t *limit1,
const uint8_t *thresh1);
#endif // CONFIG_VP9_HIGHBITDEPTH
typedef std::tr1::tuple<loop_op_t, loop_op_t, int> loop8_param_t;
typedef std::tr1::tuple<loop_op_t, loop_op_t, int, int> loop8_param_t;
typedef std::tr1::tuple<dual_loop_op_t, dual_loop_op_t, int> dualloop8_param_t;
void InitInput(Pixel *s, Pixel *ref_s, ACMRandom *rnd, const uint8_t limit,
const int mask, const int32_t p, const int i) {
uint16_t tmp_s[kNumCoeffs];
for (int j = 0; j < kNumCoeffs;) {
const uint8_t val = rnd->Rand8();
if (val & 0x80) { // 50% chance to choose a new value.
tmp_s[j] = rnd->Rand16();
j++;
} else { // 50% chance to repeat previous value in row X times.
int k = 0;
while (k++ < ((val & 0x1f) + 1) && j < kNumCoeffs) {
if (j < 1) {
tmp_s[j] = rnd->Rand16();
} else if (val & 0x20) { // Increment by a value within the limit.
tmp_s[j] = tmp_s[j - 1] + (limit - 1);
} else { // Decrement by a value within the limit.
tmp_s[j] = tmp_s[j - 1] - (limit - 1);
}
j++;
}
}
#if HAVE_SSE2
#if CONFIG_VP9_HIGHBITDEPTH
void wrapper_vertical_16_sse2(uint16_t *s, int p, const uint8_t *blimit,
const uint8_t *limit, const uint8_t *thresh,
int count, int bd) {
vpx_highbd_lpf_vertical_16_sse2(s, p, blimit, limit, thresh, bd);
}
for (int j = 0; j < kNumCoeffs;) {
const uint8_t val = rnd->Rand8();
if (val & 0x80) {
j++;
} else { // 50% chance to repeat previous value in column X times.
int k = 0;
while (k++ < ((val & 0x1f) + 1) && j < kNumCoeffs) {
if (j < 1) {
tmp_s[j] = rnd->Rand16();
} else if (val & 0x20) { // Increment by a value within the limit.
tmp_s[(j % 32) * 32 + j / 32] =
tmp_s[((j - 1) % 32) * 32 + (j - 1) / 32] + (limit - 1);
} else { // Decrement by a value within the limit.
tmp_s[(j % 32) * 32 + j / 32] =
tmp_s[((j - 1) % 32) * 32 + (j - 1) / 32] - (limit - 1);
}
j++;
}
}
void wrapper_vertical_16_c(uint16_t *s, int p, const uint8_t *blimit,
const uint8_t *limit, const uint8_t *thresh,
int count, int bd) {
vpx_highbd_lpf_vertical_16_c(s, p, blimit, limit, thresh, bd);
}
for (int j = 0; j < kNumCoeffs; j++) {
if (i % 2) {
s[j] = tmp_s[j] & mask;
} else {
s[j] = tmp_s[p * (j % p) + j / p] & mask;
void wrapper_vertical_16_dual_sse2(uint16_t *s, int p, const uint8_t *blimit,
const uint8_t *limit, const uint8_t *thresh,
int count, int bd) {
vpx_highbd_lpf_vertical_16_dual_sse2(s, p, blimit, limit, thresh, bd);
}
ref_s[j] = s[j];
void wrapper_vertical_16_dual_c(uint16_t *s, int p, const uint8_t *blimit,
const uint8_t *limit, const uint8_t *thresh,
int count, int bd) {
vpx_highbd_lpf_vertical_16_dual_c(s, p, blimit, limit, thresh, bd);
}
#else
void wrapper_vertical_16_sse2(uint8_t *s, int p, const uint8_t *blimit,
const uint8_t *limit, const uint8_t *thresh,
int count) {
vpx_lpf_vertical_16_sse2(s, p, blimit, limit, thresh);
}
void wrapper_vertical_16_c(uint8_t *s, int p, const uint8_t *blimit,
const uint8_t *limit, const uint8_t *thresh,
int count) {
vpx_lpf_vertical_16_c(s, p, blimit, limit, thresh);
}
void wrapper_vertical_16_dual_sse2(uint8_t *s, int p, const uint8_t *blimit,
const uint8_t *limit, const uint8_t *thresh,
int count) {
vpx_lpf_vertical_16_dual_sse2(s, p, blimit, limit, thresh);
}
void wrapper_vertical_16_dual_c(uint8_t *s, int p, const uint8_t *blimit,
const uint8_t *limit, const uint8_t *thresh,
int count) {
vpx_lpf_vertical_16_dual_c(s, p, blimit, limit, thresh);
}
#endif // CONFIG_VP9_HIGHBITDEPTH
#endif // HAVE_SSE2
#if HAVE_NEON_ASM
#if CONFIG_VP9_HIGHBITDEPTH
// No neon high bitdepth functions.
#else
void wrapper_vertical_16_neon(uint8_t *s, int p, const uint8_t *blimit,
const uint8_t *limit, const uint8_t *thresh,
int count) {
vpx_lpf_vertical_16_neon(s, p, blimit, limit, thresh);
}
void wrapper_vertical_16_c(uint8_t *s, int p, const uint8_t *blimit,
const uint8_t *limit, const uint8_t *thresh,
int count) {
vpx_lpf_vertical_16_c(s, p, blimit, limit, thresh);
}
void wrapper_vertical_16_dual_neon(uint8_t *s, int p, const uint8_t *blimit,
const uint8_t *limit, const uint8_t *thresh,
int count) {
vpx_lpf_vertical_16_dual_neon(s, p, blimit, limit, thresh);
}
void wrapper_vertical_16_dual_c(uint8_t *s, int p, const uint8_t *blimit,
const uint8_t *limit, const uint8_t *thresh,
int count) {
vpx_lpf_vertical_16_dual_c(s, p, blimit, limit, thresh);
}
#endif // CONFIG_VP9_HIGHBITDEPTH
#endif // HAVE_NEON_ASM
#if HAVE_MSA && (!CONFIG_VP9_HIGHBITDEPTH)
void wrapper_vertical_16_msa(uint8_t *s, int p, const uint8_t *blimit,
const uint8_t *limit, const uint8_t *thresh,
int count) {
vpx_lpf_vertical_16_msa(s, p, blimit, limit, thresh);
}
void wrapper_vertical_16_c(uint8_t *s, int p, const uint8_t *blimit,
const uint8_t *limit, const uint8_t *thresh,
int count) {
vpx_lpf_vertical_16_c(s, p, blimit, limit, thresh);
}
#endif // HAVE_MSA && (!CONFIG_VP9_HIGHBITDEPTH)
class Loop8Test6Param : public ::testing::TestWithParam<loop8_param_t> {
public:
virtual ~Loop8Test6Param() {}
@@ -121,6 +158,7 @@ class Loop8Test6Param : public ::testing::TestWithParam<loop8_param_t> {
loopfilter_op_ = GET_PARAM(0);
ref_loopfilter_op_ = GET_PARAM(1);
bit_depth_ = GET_PARAM(2);
count_ = GET_PARAM(3);
mask_ = (1 << bit_depth_) - 1;
}
@@ -128,6 +166,7 @@ class Loop8Test6Param : public ::testing::TestWithParam<loop8_param_t> {
protected:
int bit_depth_;
int count_;
int mask_;
loop_op_t loopfilter_op_;
loop_op_t ref_loopfilter_op_;
@@ -155,34 +194,72 @@ class Loop8Test9Param : public ::testing::TestWithParam<dualloop8_param_t> {
TEST_P(Loop8Test6Param, OperationCheck) {
ACMRandom rnd(ACMRandom::DeterministicSeed());
const int count_test_block = number_of_iterations;
const int32_t p = kNumCoeffs / 32;
DECLARE_ALIGNED(PIXEL_WIDTH, Pixel, s[kNumCoeffs]);
DECLARE_ALIGNED(PIXEL_WIDTH, Pixel, ref_s[kNumCoeffs]);
#if CONFIG_VP9_HIGHBITDEPTH
int32_t bd = bit_depth_;
DECLARE_ALIGNED(16, uint16_t, s[kNumCoeffs]);
DECLARE_ALIGNED(16, uint16_t, ref_s[kNumCoeffs]);
#else
DECLARE_ALIGNED(8, uint8_t, s[kNumCoeffs]);
DECLARE_ALIGNED(8, uint8_t, ref_s[kNumCoeffs]);
#endif // CONFIG_VP9_HIGHBITDEPTH
int err_count_total = 0;
int first_failure = -1;
for (int i = 0; i < count_test_block; ++i) {
int err_count = 0;
uint8_t tmp = static_cast<uint8_t>(rnd(3 * MAX_LOOP_FILTER + 4));
DECLARE_ALIGNED(16, const uint8_t,
blimit[16]) = { tmp, tmp, tmp, tmp, tmp, tmp, tmp, tmp,
tmp, tmp, tmp, tmp, tmp, tmp, tmp, tmp };
DECLARE_ALIGNED(16, const uint8_t, blimit[16]) = {
tmp, tmp, tmp, tmp, tmp, tmp, tmp, tmp,
tmp, tmp, tmp, tmp, tmp, tmp, tmp, tmp
};
tmp = static_cast<uint8_t>(rnd(MAX_LOOP_FILTER));
DECLARE_ALIGNED(16, const uint8_t,
limit[16]) = { tmp, tmp, tmp, tmp, tmp, tmp, tmp, tmp,
tmp, tmp, tmp, tmp, tmp, tmp, tmp, tmp };
DECLARE_ALIGNED(16, const uint8_t, limit[16]) = {
tmp, tmp, tmp, tmp, tmp, tmp, tmp, tmp,
tmp, tmp, tmp, tmp, tmp, tmp, tmp, tmp
};
tmp = rnd.Rand8();
DECLARE_ALIGNED(16, const uint8_t,
thresh[16]) = { tmp, tmp, tmp, tmp, tmp, tmp, tmp, tmp,
tmp, tmp, tmp, tmp, tmp, tmp, tmp, tmp };
InitInput(s, ref_s, &rnd, *limit, mask_, p, i);
DECLARE_ALIGNED(16, const uint8_t, thresh[16]) = {
tmp, tmp, tmp, tmp, tmp, tmp, tmp, tmp,
tmp, tmp, tmp, tmp, tmp, tmp, tmp, tmp
};
int32_t p = kNumCoeffs/32;
uint16_t tmp_s[kNumCoeffs];
int j = 0;
while (j < kNumCoeffs) {
uint8_t val = rnd.Rand8();
if (val & 0x80) { // 50% chance to choose a new value.
tmp_s[j] = rnd.Rand16();
j++;
} else { // 50% chance to repeat previous value in row X times
int k = 0;
while (k++ < ((val & 0x1f) + 1) && j < kNumCoeffs) {
if (j < 1) {
tmp_s[j] = rnd.Rand16();
} else if (val & 0x20) { // Increment by an value within the limit
tmp_s[j] = (tmp_s[j - 1] + (*limit - 1));
} else { // Decrement by an value within the limit
tmp_s[j] = (tmp_s[j - 1] - (*limit - 1));
}
j++;
}
}
}
for (j = 0; j < kNumCoeffs; j++) {
if (i % 2) {
s[j] = tmp_s[j] & mask_;
} else {
s[j] = tmp_s[p * (j % p) + j / p] & mask_;
}
ref_s[j] = s[j];
}
#if CONFIG_VP9_HIGHBITDEPTH
ref_loopfilter_op_(ref_s + 8 + p * 8, p, blimit, limit, thresh, bit_depth_);
ref_loopfilter_op_(ref_s + 8 + p * 8, p, blimit, limit, thresh, count_, bd);
ASM_REGISTER_STATE_CHECK(
loopfilter_op_(s + 8 + p * 8, p, blimit, limit, thresh, bit_depth_));
loopfilter_op_(s + 8 + p * 8, p, blimit, limit, thresh, count_, bd));
#else
ref_loopfilter_op_(ref_s + 8 + p * 8, p, blimit, limit, thresh);
ref_loopfilter_op_(ref_s+8+p*8, p, blimit, limit, thresh, count_);
ASM_REGISTER_STATE_CHECK(
loopfilter_op_(s + 8 + p * 8, p, blimit, limit, thresh));
loopfilter_op_(s + 8 + p * 8, p, blimit, limit, thresh, count_));
#endif // CONFIG_VP9_HIGHBITDEPTH
for (int j = 0; j < kNumCoeffs; ++j) {
@@ -202,8 +279,14 @@ TEST_P(Loop8Test6Param, OperationCheck) {
TEST_P(Loop8Test6Param, ValueCheck) {
ACMRandom rnd(ACMRandom::DeterministicSeed());
const int count_test_block = number_of_iterations;
DECLARE_ALIGNED(PIXEL_WIDTH, Pixel, s[kNumCoeffs]);
DECLARE_ALIGNED(PIXEL_WIDTH, Pixel, ref_s[kNumCoeffs]);
#if CONFIG_VP9_HIGHBITDEPTH
const int32_t bd = bit_depth_;
DECLARE_ALIGNED(16, uint16_t, s[kNumCoeffs]);
DECLARE_ALIGNED(16, uint16_t, ref_s[kNumCoeffs]);
#else
DECLARE_ALIGNED(8, uint8_t, s[kNumCoeffs]);
DECLARE_ALIGNED(8, uint8_t, ref_s[kNumCoeffs]);
#endif // CONFIG_VP9_HIGHBITDEPTH
int err_count_total = 0;
int first_failure = -1;
@@ -222,32 +305,34 @@ TEST_P(Loop8Test6Param, ValueCheck) {
for (int i = 0; i < count_test_block; ++i) {
int err_count = 0;
uint8_t tmp = static_cast<uint8_t>(rnd(3 * MAX_LOOP_FILTER + 4));
DECLARE_ALIGNED(16, const uint8_t,
blimit[16]) = { tmp, tmp, tmp, tmp, tmp, tmp, tmp, tmp,
tmp, tmp, tmp, tmp, tmp, tmp, tmp, tmp };
DECLARE_ALIGNED(16, const uint8_t, blimit[16]) = {
tmp, tmp, tmp, tmp, tmp, tmp, tmp, tmp,
tmp, tmp, tmp, tmp, tmp, tmp, tmp, tmp
};
tmp = static_cast<uint8_t>(rnd(MAX_LOOP_FILTER));
DECLARE_ALIGNED(16, const uint8_t,
limit[16]) = { tmp, tmp, tmp, tmp, tmp, tmp, tmp, tmp,
tmp, tmp, tmp, tmp, tmp, tmp, tmp, tmp };
DECLARE_ALIGNED(16, const uint8_t, limit[16]) = {
tmp, tmp, tmp, tmp, tmp, tmp, tmp, tmp,
tmp, tmp, tmp, tmp, tmp, tmp, tmp, tmp
};
tmp = rnd.Rand8();
DECLARE_ALIGNED(16, const uint8_t,
thresh[16]) = { tmp, tmp, tmp, tmp, tmp, tmp, tmp, tmp,
tmp, tmp, tmp, tmp, tmp, tmp, tmp, tmp };
DECLARE_ALIGNED(16, const uint8_t, thresh[16]) = {
tmp, tmp, tmp, tmp, tmp, tmp, tmp, tmp,
tmp, tmp, tmp, tmp, tmp, tmp, tmp, tmp
};
int32_t p = kNumCoeffs / 32;
for (int j = 0; j < kNumCoeffs; ++j) {
s[j] = rnd.Rand16() & mask_;
ref_s[j] = s[j];
}
#if CONFIG_VP9_HIGHBITDEPTH
ref_loopfilter_op_(ref_s + 8 + p * 8, p, blimit, limit, thresh, bit_depth_);
ref_loopfilter_op_(ref_s + 8 + p * 8, p, blimit, limit, thresh, count_, bd);
ASM_REGISTER_STATE_CHECK(
loopfilter_op_(s + 8 + p * 8, p, blimit, limit, thresh, bit_depth_));
loopfilter_op_(s + 8 + p * 8, p, blimit, limit, thresh, count_, bd));
#else
ref_loopfilter_op_(ref_s + 8 + p * 8, p, blimit, limit, thresh);
ref_loopfilter_op_(ref_s+8+p*8, p, blimit, limit, thresh, count_);
ASM_REGISTER_STATE_CHECK(
loopfilter_op_(s + 8 + p * 8, p, blimit, limit, thresh));
loopfilter_op_(s + 8 + p * 8, p, blimit, limit, thresh, count_));
#endif // CONFIG_VP9_HIGHBITDEPTH
for (int j = 0; j < kNumCoeffs; ++j) {
err_count += ref_s[j] != s[j];
}
@@ -265,52 +350,92 @@ TEST_P(Loop8Test6Param, ValueCheck) {
TEST_P(Loop8Test9Param, OperationCheck) {
ACMRandom rnd(ACMRandom::DeterministicSeed());
const int count_test_block = number_of_iterations;
DECLARE_ALIGNED(PIXEL_WIDTH, Pixel, s[kNumCoeffs]);
DECLARE_ALIGNED(PIXEL_WIDTH, Pixel, ref_s[kNumCoeffs]);
#if CONFIG_VP9_HIGHBITDEPTH
const int32_t bd = bit_depth_;
DECLARE_ALIGNED(16, uint16_t, s[kNumCoeffs]);
DECLARE_ALIGNED(16, uint16_t, ref_s[kNumCoeffs]);
#else
DECLARE_ALIGNED(8, uint8_t, s[kNumCoeffs]);
DECLARE_ALIGNED(8, uint8_t, ref_s[kNumCoeffs]);
#endif // CONFIG_VP9_HIGHBITDEPTH
int err_count_total = 0;
int first_failure = -1;
for (int i = 0; i < count_test_block; ++i) {
int err_count = 0;
uint8_t tmp = static_cast<uint8_t>(rnd(3 * MAX_LOOP_FILTER + 4));
DECLARE_ALIGNED(16, const uint8_t,
blimit0[16]) = { tmp, tmp, tmp, tmp, tmp, tmp, tmp, tmp,
tmp, tmp, tmp, tmp, tmp, tmp, tmp, tmp };
DECLARE_ALIGNED(16, const uint8_t, blimit0[16]) = {
tmp, tmp, tmp, tmp, tmp, tmp, tmp, tmp,
tmp, tmp, tmp, tmp, tmp, tmp, tmp, tmp
};
tmp = static_cast<uint8_t>(rnd(MAX_LOOP_FILTER));
DECLARE_ALIGNED(16, const uint8_t,
limit0[16]) = { tmp, tmp, tmp, tmp, tmp, tmp, tmp, tmp,
tmp, tmp, tmp, tmp, tmp, tmp, tmp, tmp };
DECLARE_ALIGNED(16, const uint8_t, limit0[16]) = {
tmp, tmp, tmp, tmp, tmp, tmp, tmp, tmp,
tmp, tmp, tmp, tmp, tmp, tmp, tmp, tmp
};
tmp = rnd.Rand8();
DECLARE_ALIGNED(16, const uint8_t,
thresh0[16]) = { tmp, tmp, tmp, tmp, tmp, tmp, tmp, tmp,
tmp, tmp, tmp, tmp, tmp, tmp, tmp, tmp };
DECLARE_ALIGNED(16, const uint8_t, thresh0[16]) = {
tmp, tmp, tmp, tmp, tmp, tmp, tmp, tmp,
tmp, tmp, tmp, tmp, tmp, tmp, tmp, tmp
};
tmp = static_cast<uint8_t>(rnd(3 * MAX_LOOP_FILTER + 4));
DECLARE_ALIGNED(16, const uint8_t,
blimit1[16]) = { tmp, tmp, tmp, tmp, tmp, tmp, tmp, tmp,
tmp, tmp, tmp, tmp, tmp, tmp, tmp, tmp };
DECLARE_ALIGNED(16, const uint8_t, blimit1[16]) = {
tmp, tmp, tmp, tmp, tmp, tmp, tmp, tmp,
tmp, tmp, tmp, tmp, tmp, tmp, tmp, tmp
};
tmp = static_cast<uint8_t>(rnd(MAX_LOOP_FILTER));
DECLARE_ALIGNED(16, const uint8_t,
limit1[16]) = { tmp, tmp, tmp, tmp, tmp, tmp, tmp, tmp,
tmp, tmp, tmp, tmp, tmp, tmp, tmp, tmp };
DECLARE_ALIGNED(16, const uint8_t, limit1[16]) = {
tmp, tmp, tmp, tmp, tmp, tmp, tmp, tmp,
tmp, tmp, tmp, tmp, tmp, tmp, tmp, tmp
};
tmp = rnd.Rand8();
DECLARE_ALIGNED(16, const uint8_t,
thresh1[16]) = { tmp, tmp, tmp, tmp, tmp, tmp, tmp, tmp,
tmp, tmp, tmp, tmp, tmp, tmp, tmp, tmp };
DECLARE_ALIGNED(16, const uint8_t, thresh1[16]) = {
tmp, tmp, tmp, tmp, tmp, tmp, tmp, tmp,
tmp, tmp, tmp, tmp, tmp, tmp, tmp, tmp
};
int32_t p = kNumCoeffs / 32;
uint16_t tmp_s[kNumCoeffs];
int j = 0;
const uint8_t limit = *limit0 < *limit1 ? *limit0 : *limit1;
InitInput(s, ref_s, &rnd, limit, mask_, p, i);
while (j < kNumCoeffs) {
uint8_t val = rnd.Rand8();
if (val & 0x80) { // 50% chance to choose a new value.
tmp_s[j] = rnd.Rand16();
j++;
} else { // 50% chance to repeat previous value in row X times.
int k = 0;
while (k++ < ((val & 0x1f) + 1) && j < kNumCoeffs) {
if (j < 1) {
tmp_s[j] = rnd.Rand16();
} else if (val & 0x20) { // Increment by a value within the limit.
tmp_s[j] = (tmp_s[j - 1] + (limit - 1));
} else { // Decrement by an value within the limit.
tmp_s[j] = (tmp_s[j - 1] - (limit - 1));
}
j++;
}
}
}
for (j = 0; j < kNumCoeffs; j++) {
if (i % 2) {
s[j] = tmp_s[j] & mask_;
} else {
s[j] = tmp_s[p * (j % p) + j / p] & mask_;
}
ref_s[j] = s[j];
}
#if CONFIG_VP9_HIGHBITDEPTH
ref_loopfilter_op_(ref_s + 8 + p * 8, p, blimit0, limit0, thresh0, blimit1,
limit1, thresh1, bit_depth_);
ASM_REGISTER_STATE_CHECK(loopfilter_op_(s + 8 + p * 8, p, blimit0, limit0,
thresh0, blimit1, limit1, thresh1,
bit_depth_));
ref_loopfilter_op_(ref_s + 8 + p * 8, p, blimit0, limit0, thresh0,
blimit1, limit1, thresh1, bd);
ASM_REGISTER_STATE_CHECK(
loopfilter_op_(s + 8 + p * 8, p, blimit0, limit0, thresh0,
blimit1, limit1, thresh1, bd));
#else
ref_loopfilter_op_(ref_s + 8 + p * 8, p, blimit0, limit0, thresh0, blimit1,
limit1, thresh1);
ASM_REGISTER_STATE_CHECK(loopfilter_op_(s + 8 + p * 8, p, blimit0, limit0,
thresh0, blimit1, limit1, thresh1));
ref_loopfilter_op_(ref_s + 8 + p * 8, p, blimit0, limit0, thresh0,
blimit1, limit1, thresh1);
ASM_REGISTER_STATE_CHECK(
loopfilter_op_(s + 8 + p * 8, p, blimit0, limit0, thresh0,
blimit1, limit1, thresh1));
#endif // CONFIG_VP9_HIGHBITDEPTH
for (int j = 0; j < kNumCoeffs; ++j) {
err_count += ref_s[j] != s[j];
}
@@ -328,54 +453,66 @@ TEST_P(Loop8Test9Param, OperationCheck) {
TEST_P(Loop8Test9Param, ValueCheck) {
ACMRandom rnd(ACMRandom::DeterministicSeed());
const int count_test_block = number_of_iterations;
DECLARE_ALIGNED(PIXEL_WIDTH, Pixel, s[kNumCoeffs]);
DECLARE_ALIGNED(PIXEL_WIDTH, Pixel, ref_s[kNumCoeffs]);
#if CONFIG_VP9_HIGHBITDEPTH
DECLARE_ALIGNED(16, uint16_t, s[kNumCoeffs]);
DECLARE_ALIGNED(16, uint16_t, ref_s[kNumCoeffs]);
#else
DECLARE_ALIGNED(8, uint8_t, s[kNumCoeffs]);
DECLARE_ALIGNED(8, uint8_t, ref_s[kNumCoeffs]);
#endif // CONFIG_VP9_HIGHBITDEPTH
int err_count_total = 0;
int first_failure = -1;
for (int i = 0; i < count_test_block; ++i) {
int err_count = 0;
uint8_t tmp = static_cast<uint8_t>(rnd(3 * MAX_LOOP_FILTER + 4));
DECLARE_ALIGNED(16, const uint8_t,
blimit0[16]) = { tmp, tmp, tmp, tmp, tmp, tmp, tmp, tmp,
tmp, tmp, tmp, tmp, tmp, tmp, tmp, tmp };
DECLARE_ALIGNED(16, const uint8_t, blimit0[16]) = {
tmp, tmp, tmp, tmp, tmp, tmp, tmp, tmp,
tmp, tmp, tmp, tmp, tmp, tmp, tmp, tmp
};
tmp = static_cast<uint8_t>(rnd(MAX_LOOP_FILTER));
DECLARE_ALIGNED(16, const uint8_t,
limit0[16]) = { tmp, tmp, tmp, tmp, tmp, tmp, tmp, tmp,
tmp, tmp, tmp, tmp, tmp, tmp, tmp, tmp };
DECLARE_ALIGNED(16, const uint8_t, limit0[16]) = {
tmp, tmp, tmp, tmp, tmp, tmp, tmp, tmp,
tmp, tmp, tmp, tmp, tmp, tmp, tmp, tmp
};
tmp = rnd.Rand8();
DECLARE_ALIGNED(16, const uint8_t,
thresh0[16]) = { tmp, tmp, tmp, tmp, tmp, tmp, tmp, tmp,
tmp, tmp, tmp, tmp, tmp, tmp, tmp, tmp };
DECLARE_ALIGNED(16, const uint8_t, thresh0[16]) = {
tmp, tmp, tmp, tmp, tmp, tmp, tmp, tmp,
tmp, tmp, tmp, tmp, tmp, tmp, tmp, tmp
};
tmp = static_cast<uint8_t>(rnd(3 * MAX_LOOP_FILTER + 4));
DECLARE_ALIGNED(16, const uint8_t,
blimit1[16]) = { tmp, tmp, tmp, tmp, tmp, tmp, tmp, tmp,
tmp, tmp, tmp, tmp, tmp, tmp, tmp, tmp };
DECLARE_ALIGNED(16, const uint8_t, blimit1[16]) = {
tmp, tmp, tmp, tmp, tmp, tmp, tmp, tmp,
tmp, tmp, tmp, tmp, tmp, tmp, tmp, tmp
};
tmp = static_cast<uint8_t>(rnd(MAX_LOOP_FILTER));
DECLARE_ALIGNED(16, const uint8_t,
limit1[16]) = { tmp, tmp, tmp, tmp, tmp, tmp, tmp, tmp,
tmp, tmp, tmp, tmp, tmp, tmp, tmp, tmp };
DECLARE_ALIGNED(16, const uint8_t, limit1[16]) = {
tmp, tmp, tmp, tmp, tmp, tmp, tmp, tmp,
tmp, tmp, tmp, tmp, tmp, tmp, tmp, tmp
};
tmp = rnd.Rand8();
DECLARE_ALIGNED(16, const uint8_t,
thresh1[16]) = { tmp, tmp, tmp, tmp, tmp, tmp, tmp, tmp,
tmp, tmp, tmp, tmp, tmp, tmp, tmp, tmp };
DECLARE_ALIGNED(16, const uint8_t, thresh1[16]) = {
tmp, tmp, tmp, tmp, tmp, tmp, tmp, tmp,
tmp, tmp, tmp, tmp, tmp, tmp, tmp, tmp
};
int32_t p = kNumCoeffs / 32; // TODO(pdlf) can we have non-square here?
for (int j = 0; j < kNumCoeffs; ++j) {
s[j] = rnd.Rand16() & mask_;
ref_s[j] = s[j];
}
#if CONFIG_VP9_HIGHBITDEPTH
ref_loopfilter_op_(ref_s + 8 + p * 8, p, blimit0, limit0, thresh0, blimit1,
limit1, thresh1, bit_depth_);
ASM_REGISTER_STATE_CHECK(loopfilter_op_(s + 8 + p * 8, p, blimit0, limit0,
thresh0, blimit1, limit1, thresh1,
bit_depth_));
const int32_t bd = bit_depth_;
ref_loopfilter_op_(ref_s + 8 + p * 8, p, blimit0, limit0, thresh0,
blimit1, limit1, thresh1, bd);
ASM_REGISTER_STATE_CHECK(
loopfilter_op_(s + 8 + p * 8, p, blimit0, limit0,
thresh0, blimit1, limit1, thresh1, bd));
#else
ref_loopfilter_op_(ref_s + 8 + p * 8, p, blimit0, limit0, thresh0, blimit1,
limit1, thresh1);
ASM_REGISTER_STATE_CHECK(loopfilter_op_(s + 8 + p * 8, p, blimit0, limit0,
thresh0, blimit1, limit1, thresh1));
ref_loopfilter_op_(ref_s + 8 + p * 8, p, blimit0, limit0, thresh0,
blimit1, limit1, thresh1);
ASM_REGISTER_STATE_CHECK(
loopfilter_op_(s + 8 + p * 8, p, blimit0, limit0, thresh0,
blimit1, limit1, thresh1));
#endif // CONFIG_VP9_HIGHBITDEPTH
for (int j = 0; j < kNumCoeffs; ++j) {
err_count += ref_s[j] != s[j];
}
@@ -396,86 +533,84 @@ using std::tr1::make_tuple;
#if CONFIG_VP9_HIGHBITDEPTH
INSTANTIATE_TEST_CASE_P(
SSE2, Loop8Test6Param,
::testing::Values(make_tuple(&vpx_highbd_lpf_horizontal_4_sse2,
&vpx_highbd_lpf_horizontal_4_c, 8),
make_tuple(&vpx_highbd_lpf_vertical_4_sse2,
&vpx_highbd_lpf_vertical_4_c, 8),
make_tuple(&vpx_highbd_lpf_horizontal_8_sse2,
&vpx_highbd_lpf_horizontal_8_c, 8),
make_tuple(&vpx_highbd_lpf_horizontal_edge_8_sse2,
&vpx_highbd_lpf_horizontal_edge_8_c, 8),
make_tuple(&vpx_highbd_lpf_horizontal_edge_16_sse2,
&vpx_highbd_lpf_horizontal_edge_16_c, 8),
make_tuple(&vpx_highbd_lpf_vertical_8_sse2,
&vpx_highbd_lpf_vertical_8_c, 8),
make_tuple(&vpx_highbd_lpf_vertical_16_sse2,
&vpx_highbd_lpf_vertical_16_c, 8),
::testing::Values(
make_tuple(&vpx_highbd_lpf_horizontal_4_sse2,
&vpx_highbd_lpf_horizontal_4_c, 10),
&vpx_highbd_lpf_horizontal_4_c, 8, 1),
make_tuple(&vpx_highbd_lpf_vertical_4_sse2,
&vpx_highbd_lpf_vertical_4_c, 10),
&vpx_highbd_lpf_vertical_4_c, 8, 1),
make_tuple(&vpx_highbd_lpf_horizontal_8_sse2,
&vpx_highbd_lpf_horizontal_8_c, 10),
make_tuple(&vpx_highbd_lpf_horizontal_edge_8_sse2,
&vpx_highbd_lpf_horizontal_edge_8_c, 10),
make_tuple(&vpx_highbd_lpf_horizontal_edge_16_sse2,
&vpx_highbd_lpf_horizontal_edge_16_c, 10),
&vpx_highbd_lpf_horizontal_8_c, 8, 1),
make_tuple(&vpx_highbd_lpf_horizontal_16_sse2,
&vpx_highbd_lpf_horizontal_16_c, 8, 1),
make_tuple(&vpx_highbd_lpf_horizontal_16_sse2,
&vpx_highbd_lpf_horizontal_16_c, 8, 2),
make_tuple(&vpx_highbd_lpf_vertical_8_sse2,
&vpx_highbd_lpf_vertical_8_c, 10),
make_tuple(&vpx_highbd_lpf_vertical_16_sse2,
&vpx_highbd_lpf_vertical_16_c, 10),
&vpx_highbd_lpf_vertical_8_c, 8, 1),
make_tuple(&wrapper_vertical_16_sse2,
&wrapper_vertical_16_c, 8, 1),
make_tuple(&vpx_highbd_lpf_horizontal_4_sse2,
&vpx_highbd_lpf_horizontal_4_c, 12),
&vpx_highbd_lpf_horizontal_4_c, 10, 1),
make_tuple(&vpx_highbd_lpf_vertical_4_sse2,
&vpx_highbd_lpf_vertical_4_c, 12),
&vpx_highbd_lpf_vertical_4_c, 10, 1),
make_tuple(&vpx_highbd_lpf_horizontal_8_sse2,
&vpx_highbd_lpf_horizontal_8_c, 12),
make_tuple(&vpx_highbd_lpf_horizontal_edge_8_sse2,
&vpx_highbd_lpf_horizontal_edge_8_c, 12),
make_tuple(&vpx_highbd_lpf_horizontal_edge_16_sse2,
&vpx_highbd_lpf_horizontal_edge_16_c, 12),
&vpx_highbd_lpf_horizontal_8_c, 10, 1),
make_tuple(&vpx_highbd_lpf_horizontal_16_sse2,
&vpx_highbd_lpf_horizontal_16_c, 10, 1),
make_tuple(&vpx_highbd_lpf_horizontal_16_sse2,
&vpx_highbd_lpf_horizontal_16_c, 10, 2),
make_tuple(&vpx_highbd_lpf_vertical_8_sse2,
&vpx_highbd_lpf_vertical_8_c, 12),
make_tuple(&vpx_highbd_lpf_vertical_16_sse2,
&vpx_highbd_lpf_vertical_16_c, 12),
make_tuple(&vpx_highbd_lpf_vertical_16_dual_sse2,
&vpx_highbd_lpf_vertical_16_dual_c, 8),
make_tuple(&vpx_highbd_lpf_vertical_16_dual_sse2,
&vpx_highbd_lpf_vertical_16_dual_c, 10),
make_tuple(&vpx_highbd_lpf_vertical_16_dual_sse2,
&vpx_highbd_lpf_vertical_16_dual_c, 12)));
&vpx_highbd_lpf_vertical_8_c, 10, 1),
make_tuple(&wrapper_vertical_16_sse2,
&wrapper_vertical_16_c, 10, 1),
make_tuple(&vpx_highbd_lpf_horizontal_4_sse2,
&vpx_highbd_lpf_horizontal_4_c, 12, 1),
make_tuple(&vpx_highbd_lpf_vertical_4_sse2,
&vpx_highbd_lpf_vertical_4_c, 12, 1),
make_tuple(&vpx_highbd_lpf_horizontal_8_sse2,
&vpx_highbd_lpf_horizontal_8_c, 12, 1),
make_tuple(&vpx_highbd_lpf_horizontal_16_sse2,
&vpx_highbd_lpf_horizontal_16_c, 12, 1),
make_tuple(&vpx_highbd_lpf_horizontal_16_sse2,
&vpx_highbd_lpf_horizontal_16_c, 12, 2),
make_tuple(&vpx_highbd_lpf_vertical_8_sse2,
&vpx_highbd_lpf_vertical_8_c, 12, 1),
make_tuple(&wrapper_vertical_16_sse2,
&wrapper_vertical_16_c, 12, 1),
make_tuple(&wrapper_vertical_16_dual_sse2,
&wrapper_vertical_16_dual_c, 8, 1),
make_tuple(&wrapper_vertical_16_dual_sse2,
&wrapper_vertical_16_dual_c, 10, 1),
make_tuple(&wrapper_vertical_16_dual_sse2,
&wrapper_vertical_16_dual_c, 12, 1)));
#else
INSTANTIATE_TEST_CASE_P(
SSE2, Loop8Test6Param,
::testing::Values(
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_edge_8_sse2,
&vpx_lpf_horizontal_edge_8_c, 8),
make_tuple(&vpx_lpf_horizontal_edge_16_sse2,
&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_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_dual_sse2, &vpx_lpf_vertical_16_dual_c,
8)));
make_tuple(&vpx_lpf_horizontal_8_sse2, &vpx_lpf_horizontal_8_c, 8, 1),
make_tuple(&vpx_lpf_horizontal_16_sse2, &vpx_lpf_horizontal_16_c, 8, 1),
make_tuple(&vpx_lpf_horizontal_16_sse2, &vpx_lpf_horizontal_16_c, 8, 2),
make_tuple(&vpx_lpf_vertical_8_sse2, &vpx_lpf_vertical_8_c, 8, 1),
make_tuple(&wrapper_vertical_16_sse2, &wrapper_vertical_16_c, 8, 1),
make_tuple(&wrapper_vertical_16_dual_sse2,
&wrapper_vertical_16_dual_c, 8, 1)));
#endif // CONFIG_VP9_HIGHBITDEPTH
#endif
#if HAVE_AVX2 && (!CONFIG_VP9_HIGHBITDEPTH)
INSTANTIATE_TEST_CASE_P(
AVX2, Loop8Test6Param,
::testing::Values(make_tuple(&vpx_lpf_horizontal_edge_8_avx2,
&vpx_lpf_horizontal_edge_8_c, 8),
make_tuple(&vpx_lpf_horizontal_edge_16_avx2,
&vpx_lpf_horizontal_edge_16_c, 8)));
::testing::Values(
make_tuple(&vpx_lpf_horizontal_16_avx2, &vpx_lpf_horizontal_16_c, 8, 1),
make_tuple(&vpx_lpf_horizontal_16_avx2, &vpx_lpf_horizontal_16_c, 8,
2)));
#endif
#if HAVE_SSE2
#if CONFIG_VP9_HIGHBITDEPTH
INSTANTIATE_TEST_CASE_P(
SSE2, Loop8Test9Param,
::testing::Values(make_tuple(&vpx_highbd_lpf_horizontal_4_dual_sse2,
::testing::Values(
make_tuple(&vpx_highbd_lpf_horizontal_4_dual_sse2,
&vpx_highbd_lpf_horizontal_4_dual_c, 8),
make_tuple(&vpx_highbd_lpf_horizontal_8_dual_sse2,
&vpx_highbd_lpf_horizontal_8_dual_c, 8),
@@ -502,7 +637,8 @@ INSTANTIATE_TEST_CASE_P(
#else
INSTANTIATE_TEST_CASE_P(
SSE2, Loop8Test9Param,
::testing::Values(make_tuple(&vpx_lpf_horizontal_4_dual_sse2,
::testing::Values(
make_tuple(&vpx_lpf_horizontal_4_dual_sse2,
&vpx_lpf_horizontal_4_dual_c, 8),
make_tuple(&vpx_lpf_horizontal_8_dual_sse2,
&vpx_lpf_horizontal_8_dual_c, 8),
@@ -520,23 +656,35 @@ INSTANTIATE_TEST_CASE_P(
INSTANTIATE_TEST_CASE_P(
NEON, Loop8Test6Param,
::testing::Values(
make_tuple(&vpx_lpf_horizontal_edge_8_neon,
&vpx_lpf_horizontal_edge_8_c, 8),
make_tuple(&vpx_lpf_horizontal_edge_16_neon,
&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_dual_neon, &vpx_lpf_vertical_16_dual_c,
8),
make_tuple(&vpx_lpf_horizontal_8_neon, &vpx_lpf_horizontal_8_c, 8),
make_tuple(&vpx_lpf_vertical_8_neon, &vpx_lpf_vertical_8_c, 8),
make_tuple(&vpx_lpf_horizontal_4_neon, &vpx_lpf_horizontal_4_c, 8),
make_tuple(&vpx_lpf_vertical_4_neon, &vpx_lpf_vertical_4_c, 8)));
#if HAVE_NEON_ASM
// Using #if inside the macro is unsupported on MSVS but the tests are not
// currently built for MSVS with ARM and NEON.
make_tuple(&vpx_lpf_horizontal_16_neon,
&vpx_lpf_horizontal_16_c, 8, 1),
make_tuple(&vpx_lpf_horizontal_16_neon,
&vpx_lpf_horizontal_16_c, 8, 2),
make_tuple(&wrapper_vertical_16_neon,
&wrapper_vertical_16_c, 8, 1),
make_tuple(&wrapper_vertical_16_dual_neon,
&wrapper_vertical_16_dual_c, 8, 1),
#endif // HAVE_NEON_ASM
make_tuple(&vpx_lpf_horizontal_8_neon,
&vpx_lpf_horizontal_8_c, 8, 1),
make_tuple(&vpx_lpf_vertical_8_neon,
&vpx_lpf_vertical_8_c, 8, 1),
make_tuple(&vpx_lpf_horizontal_4_neon,
&vpx_lpf_horizontal_4_c, 8, 1),
make_tuple(&vpx_lpf_vertical_4_neon,
&vpx_lpf_vertical_4_c, 8, 1)));
INSTANTIATE_TEST_CASE_P(
NEON, Loop8Test9Param,
::testing::Values(make_tuple(&vpx_lpf_horizontal_8_dual_neon,
::testing::Values(
#if HAVE_NEON_ASM
make_tuple(&vpx_lpf_horizontal_8_dual_neon,
&vpx_lpf_horizontal_8_dual_c, 8),
make_tuple(&vpx_lpf_vertical_8_dual_neon,
&vpx_lpf_vertical_8_dual_c, 8),
#endif // HAVE_NEON_ASM
make_tuple(&vpx_lpf_horizontal_4_dual_neon,
&vpx_lpf_horizontal_4_dual_c, 8),
make_tuple(&vpx_lpf_vertical_4_dual_neon,
@@ -544,49 +692,20 @@ INSTANTIATE_TEST_CASE_P(
#endif // CONFIG_VP9_HIGHBITDEPTH
#endif // HAVE_NEON
#if HAVE_DSPR2 && !CONFIG_VP9_HIGHBITDEPTH
INSTANTIATE_TEST_CASE_P(
DSPR2, Loop8Test6Param,
::testing::Values(
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_edge_8, &vpx_lpf_horizontal_edge_8, 8),
make_tuple(&vpx_lpf_horizontal_edge_16, &vpx_lpf_horizontal_edge_16, 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_16_dspr2, &vpx_lpf_vertical_16_c, 8),
make_tuple(&vpx_lpf_vertical_16_dual_dspr2, &vpx_lpf_vertical_16_dual_c,
8)));
INSTANTIATE_TEST_CASE_P(
DSPR2, Loop8Test9Param,
::testing::Values(make_tuple(&vpx_lpf_horizontal_4_dual_dspr2,
&vpx_lpf_horizontal_4_dual_c, 8),
make_tuple(&vpx_lpf_horizontal_8_dual_dspr2,
&vpx_lpf_horizontal_8_dual_c, 8),
make_tuple(&vpx_lpf_vertical_4_dual_dspr2,
&vpx_lpf_vertical_4_dual_c, 8),
make_tuple(&vpx_lpf_vertical_8_dual_dspr2,
&vpx_lpf_vertical_8_dual_c, 8)));
#endif // HAVE_DSPR2 && !CONFIG_VP9_HIGHBITDEPTH
#if HAVE_MSA && (!CONFIG_VP9_HIGHBITDEPTH)
INSTANTIATE_TEST_CASE_P(
MSA, Loop8Test6Param,
::testing::Values(
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_edge_8_msa, &vpx_lpf_horizontal_edge_8_c,
8),
make_tuple(&vpx_lpf_horizontal_edge_16_msa,
&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_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_horizontal_8_msa, &vpx_lpf_horizontal_8_c, 8, 1),
make_tuple(&vpx_lpf_horizontal_16_msa, &vpx_lpf_horizontal_16_c, 8, 1),
make_tuple(&vpx_lpf_horizontal_16_msa, &vpx_lpf_horizontal_16_c, 8, 2),
make_tuple(&vpx_lpf_vertical_8_msa, &vpx_lpf_vertical_8_c, 8, 1),
make_tuple(&wrapper_vertical_16_msa, &wrapper_vertical_16_c, 8, 1)));
INSTANTIATE_TEST_CASE_P(
MSA, Loop8Test9Param,
::testing::Values(make_tuple(&vpx_lpf_horizontal_4_dual_msa,
::testing::Values(
make_tuple(&vpx_lpf_horizontal_4_dual_msa,
&vpx_lpf_horizontal_4_dual_c, 8),
make_tuple(&vpx_lpf_horizontal_8_dual_msa,
&vpx_lpf_horizontal_8_dual_c, 8),

View File

@@ -17,7 +17,9 @@
namespace libvpx_test {
class MD5 {
public:
MD5() { MD5Init(&md5_); }
MD5() {
MD5Init(&md5_);
}
void Add(const vpx_image_t *img) {
for (int plane = 0; plane < 3; ++plane) {
@@ -28,13 +30,10 @@ class MD5 {
// This works only for chroma_shift of 0 and 1.
const int bytes_per_sample =
(img->fmt & VPX_IMG_FMT_HIGHBITDEPTH) ? 2 : 1;
const int h =
plane ? (img->d_h + img->y_chroma_shift) >> img->y_chroma_shift
: img->d_h;
const int w =
(plane ? (img->d_w + img->x_chroma_shift) >> img->x_chroma_shift
: img->d_w) *
bytes_per_sample;
const int h = plane ? (img->d_h + img->y_chroma_shift) >>
img->y_chroma_shift : img->d_h;
const int w = (plane ? (img->d_w + img->x_chroma_shift) >>
img->x_chroma_shift : img->d_w) * bytes_per_sample;
for (int y = 0; y < h; ++y) {
MD5Update(&md5_, buf, w);

View File

@@ -1,130 +0,0 @@
/*
* Copyright (c) 2016 The WebM project authors. All Rights Reserved.
*
* Use of this source code is governed by a BSD-style license
* that can be found in the LICENSE file in the root of the source
* tree. An additional intellectual property rights grant can be found
* in the file PATENTS. All contributing project authors may
* be found in the AUTHORS file in the root of the source tree.
*/
#include <stdlib.h>
#include <string.h>
#include "third_party/googletest/src/include/gtest/gtest.h"
#include "./vpx_dsp_rtcd.h"
#include "vpx/vpx_integer.h"
#include "test/acm_random.h"
#include "test/register_state_check.h"
namespace {
using ::libvpx_test::ACMRandom;
typedef void (*MinMaxFunc)(const uint8_t *a, int a_stride, const uint8_t *b,
int b_stride, int *min, int *max);
class MinMaxTest : public ::testing::TestWithParam<MinMaxFunc> {
public:
virtual void SetUp() {
mm_func_ = GetParam();
rnd_.Reset(ACMRandom::DeterministicSeed());
}
protected:
MinMaxFunc mm_func_;
ACMRandom rnd_;
};
void reference_minmax(const uint8_t *a, int a_stride, const uint8_t *b,
int b_stride, int *min_ret, int *max_ret) {
int min = 255;
int max = 0;
for (int i = 0; i < 8; i++) {
for (int j = 0; j < 8; j++) {
const int diff = abs(a[i * a_stride + j] - b[i * b_stride + j]);
if (min > diff) min = diff;
if (max < diff) max = diff;
}
}
*min_ret = min;
*max_ret = max;
}
TEST_P(MinMaxTest, MinValue) {
for (int i = 0; i < 64; i++) {
uint8_t a[64], b[64];
memset(a, 0, sizeof(a));
memset(b, 255, sizeof(b));
b[i] = i; // Set a minimum difference of i.
int min, max;
ASM_REGISTER_STATE_CHECK(mm_func_(a, 8, b, 8, &min, &max));
EXPECT_EQ(255, max);
EXPECT_EQ(i, min);
}
}
TEST_P(MinMaxTest, MaxValue) {
for (int i = 0; i < 64; i++) {
uint8_t a[64], b[64];
memset(a, 0, sizeof(a));
memset(b, 0, sizeof(b));
b[i] = i; // Set a maximum difference of i.
int min, max;
ASM_REGISTER_STATE_CHECK(mm_func_(a, 8, b, 8, &min, &max));
EXPECT_EQ(i, max);
EXPECT_EQ(0, min);
}
}
TEST_P(MinMaxTest, CompareReference) {
uint8_t a[64], b[64];
for (int j = 0; j < 64; j++) {
a[j] = rnd_.Rand8();
b[j] = rnd_.Rand8();
}
int min_ref, max_ref, min, max;
reference_minmax(a, 8, b, 8, &min_ref, &max_ref);
ASM_REGISTER_STATE_CHECK(mm_func_(a, 8, b, 8, &min, &max));
EXPECT_EQ(max_ref, max);
EXPECT_EQ(min_ref, min);
}
TEST_P(MinMaxTest, CompareReferenceAndVaryStride) {
uint8_t a[8 * 64], b[8 * 64];
for (int i = 0; i < 8 * 64; i++) {
a[i] = rnd_.Rand8();
b[i] = rnd_.Rand8();
}
for (int a_stride = 8; a_stride <= 64; a_stride += 8) {
for (int b_stride = 8; b_stride <= 64; b_stride += 8) {
int min_ref, max_ref, min, max;
reference_minmax(a, a_stride, b, b_stride, &min_ref, &max_ref);
ASM_REGISTER_STATE_CHECK(mm_func_(a, a_stride, b, b_stride, &min, &max));
EXPECT_EQ(max_ref, max) << "when a_stride = " << a_stride
<< " and b_stride = " << b_stride;
EXPECT_EQ(min_ref, min) << "when a_stride = " << a_stride
<< " and b_stride = " << b_stride;
}
}
}
INSTANTIATE_TEST_CASE_P(C, MinMaxTest, ::testing::Values(&vpx_minmax_8x8_c));
#if HAVE_SSE2
INSTANTIATE_TEST_CASE_P(SSE2, MinMaxTest,
::testing::Values(&vpx_minmax_8x8_sse2));
#endif
#if HAVE_NEON
INSTANTIATE_TEST_CASE_P(NEON, MinMaxTest,
::testing::Values(&vpx_minmax_8x8_neon));
#endif
} // namespace

View File

@@ -29,8 +29,10 @@ using libvpx_test::ACMRandom;
namespace {
typedef void (*FwdTxfmFunc)(const int16_t *in, tran_low_t *out, int stride);
typedef void (*InvTxfmFunc)(const tran_low_t *in, uint8_t *out, int stride);
typedef std::tr1::tuple<FwdTxfmFunc, InvTxfmFunc, InvTxfmFunc, TX_SIZE, int>
PartialInvTxfmParam;
typedef std::tr1::tuple<FwdTxfmFunc,
InvTxfmFunc,
InvTxfmFunc,
TX_SIZE, int> PartialInvTxfmParam;
const int kMaxNumCoeffs = 1024;
class PartialIDctTest : public ::testing::TestWithParam<PartialInvTxfmParam> {
public:
@@ -57,11 +59,21 @@ TEST_P(PartialIDctTest, RunQuantCheck) {
ACMRandom rnd(ACMRandom::DeterministicSeed());
int size;
switch (tx_size_) {
case TX_4X4: size = 4; break;
case TX_8X8: size = 8; break;
case TX_16X16: size = 16; break;
case TX_32X32: size = 32; break;
default: FAIL() << "Wrong Size!"; break;
case TX_4X4:
size = 4;
break;
case TX_8X8:
size = 8;
break;
case TX_16X16:
size = 16;
break;
case TX_32X32:
size = 32;
break;
default:
FAIL() << "Wrong Size!";
break;
}
DECLARE_ALIGNED(16, tran_low_t, test_coef_block1[kMaxNumCoeffs]);
DECLARE_ALIGNED(16, tran_low_t, test_coef_block2[kMaxNumCoeffs]);
@@ -87,9 +99,11 @@ TEST_P(PartialIDctTest, RunQuantCheck) {
for (int i = 0; i < count_test_block; ++i) {
// Initialize a test block with input range [-255, 255].
if (i == 0) {
for (int j = 0; j < block_size; ++j) input_extreme_block[j] = 255;
for (int j = 0; j < block_size; ++j)
input_extreme_block[j] = 255;
} else if (i == 1) {
for (int j = 0; j < block_size; ++j) input_extreme_block[j] = -255;
for (int j = 0; j < block_size; ++j)
input_extreme_block[j] = -255;
} else {
for (int j = 0; j < block_size; ++j) {
input_extreme_block[j] = rnd.Rand8() % 2 ? 255 : -255;
@@ -100,10 +114,9 @@ TEST_P(PartialIDctTest, RunQuantCheck) {
// quantization with maximum allowed step sizes
test_coef_block1[0] = (output_ref_block[0] / 1336) * 1336;
for (int j = 1; j < last_nonzero_; ++j) {
test_coef_block1[vp9_default_scan_orders[tx_size_].scan[j]] =
(output_ref_block[j] / 1828) * 1828;
}
for (int j = 1; j < last_nonzero_; ++j)
test_coef_block1[vp9_default_scan_orders[tx_size_].scan[j]]
= (output_ref_block[j] / 1828) * 1828;
}
ASM_REGISTER_STATE_CHECK(full_itxfm_(test_coef_block1, dst1, size));
@@ -112,7 +125,8 @@ TEST_P(PartialIDctTest, RunQuantCheck) {
for (int j = 0; j < block_size; ++j) {
const int diff = dst1[j] - dst2[j];
const int error = diff * diff;
if (max_error < error) max_error = error;
if (max_error < error)
max_error = error;
}
}
@@ -124,11 +138,21 @@ TEST_P(PartialIDctTest, ResultsMatch) {
ACMRandom rnd(ACMRandom::DeterministicSeed());
int size;
switch (tx_size_) {
case TX_4X4: size = 4; break;
case TX_8X8: size = 8; break;
case TX_16X16: size = 16; break;
case TX_32X32: size = 32; break;
default: FAIL() << "Wrong Size!"; break;
case TX_4X4:
size = 4;
break;
case TX_8X8:
size = 8;
break;
case TX_16X16:
size = 16;
break;
case TX_32X32:
size = 32;
break;
default:
FAIL() << "Wrong Size!";
break;
}
DECLARE_ALIGNED(16, tran_low_t, test_coef_block1[kMaxNumCoeffs]);
DECLARE_ALIGNED(16, tran_low_t, test_coef_block2[kMaxNumCoeffs]);
@@ -165,7 +189,8 @@ TEST_P(PartialIDctTest, ResultsMatch) {
for (int j = 0; j < block_size; ++j) {
const int diff = dst1[j] - dst2[j];
const int error = diff * diff;
if (max_error < error) max_error = error;
if (max_error < error)
max_error = error;
}
}
@@ -176,82 +201,143 @@ using std::tr1::make_tuple;
INSTANTIATE_TEST_CASE_P(
C, PartialIDctTest,
::testing::Values(make_tuple(&vpx_fdct32x32_c, &vpx_idct32x32_1024_add_c,
&vpx_idct32x32_34_add_c, TX_32X32, 34),
make_tuple(&vpx_fdct32x32_c, &vpx_idct32x32_1024_add_c,
&vpx_idct32x32_1_add_c, TX_32X32, 1),
make_tuple(&vpx_fdct16x16_c, &vpx_idct16x16_256_add_c,
&vpx_idct16x16_10_add_c, TX_16X16, 10),
make_tuple(&vpx_fdct16x16_c, &vpx_idct16x16_256_add_c,
&vpx_idct16x16_1_add_c, TX_16X16, 1),
make_tuple(&vpx_fdct8x8_c, &vpx_idct8x8_64_add_c,
&vpx_idct8x8_12_add_c, TX_8X8, 12),
make_tuple(&vpx_fdct8x8_c, &vpx_idct8x8_64_add_c,
&vpx_idct8x8_1_add_c, TX_8X8, 1),
make_tuple(&vpx_fdct4x4_c, &vpx_idct4x4_16_add_c,
&vpx_idct4x4_1_add_c, TX_4X4, 1)));
::testing::Values(
make_tuple(&vpx_fdct32x32_c,
&vpx_idct32x32_1024_add_c,
&vpx_idct32x32_34_add_c,
TX_32X32, 34),
make_tuple(&vpx_fdct32x32_c,
&vpx_idct32x32_1024_add_c,
&vpx_idct32x32_1_add_c,
TX_32X32, 1),
make_tuple(&vpx_fdct16x16_c,
&vpx_idct16x16_256_add_c,
&vpx_idct16x16_10_add_c,
TX_16X16, 10),
make_tuple(&vpx_fdct16x16_c,
&vpx_idct16x16_256_add_c,
&vpx_idct16x16_1_add_c,
TX_16X16, 1),
make_tuple(&vpx_fdct8x8_c,
&vpx_idct8x8_64_add_c,
&vpx_idct8x8_12_add_c,
TX_8X8, 12),
make_tuple(&vpx_fdct8x8_c,
&vpx_idct8x8_64_add_c,
&vpx_idct8x8_1_add_c,
TX_8X8, 1),
make_tuple(&vpx_fdct4x4_c,
&vpx_idct4x4_16_add_c,
&vpx_idct4x4_1_add_c,
TX_4X4, 1)));
#if HAVE_NEON && !CONFIG_VP9_HIGHBITDEPTH && !CONFIG_EMULATE_HARDWARE
INSTANTIATE_TEST_CASE_P(
NEON, PartialIDctTest,
::testing::Values(make_tuple(&vpx_fdct32x32_c, &vpx_idct32x32_1024_add_c,
&vpx_idct32x32_1_add_neon, TX_32X32, 1),
make_tuple(&vpx_fdct16x16_c, &vpx_idct16x16_256_add_c,
&vpx_idct16x16_10_add_neon, TX_16X16, 10),
make_tuple(&vpx_fdct16x16_c, &vpx_idct16x16_256_add_c,
&vpx_idct16x16_1_add_neon, TX_16X16, 1),
make_tuple(&vpx_fdct8x8_c, &vpx_idct8x8_64_add_c,
&vpx_idct8x8_12_add_neon, TX_8X8, 12),
make_tuple(&vpx_fdct8x8_c, &vpx_idct8x8_64_add_c,
&vpx_idct8x8_1_add_neon, TX_8X8, 1),
make_tuple(&vpx_fdct4x4_c, &vpx_idct4x4_16_add_c,
&vpx_idct4x4_1_add_neon, TX_4X4, 1)));
::testing::Values(
make_tuple(&vpx_fdct32x32_c,
&vpx_idct32x32_1024_add_c,
&vpx_idct32x32_1_add_neon,
TX_32X32, 1),
make_tuple(&vpx_fdct16x16_c,
&vpx_idct16x16_256_add_c,
&vpx_idct16x16_10_add_neon,
TX_16X16, 10),
make_tuple(&vpx_fdct16x16_c,
&vpx_idct16x16_256_add_c,
&vpx_idct16x16_1_add_neon,
TX_16X16, 1),
make_tuple(&vpx_fdct8x8_c,
&vpx_idct8x8_64_add_c,
&vpx_idct8x8_12_add_neon,
TX_8X8, 12),
make_tuple(&vpx_fdct8x8_c,
&vpx_idct8x8_64_add_c,
&vpx_idct8x8_1_add_neon,
TX_8X8, 1),
make_tuple(&vpx_fdct4x4_c,
&vpx_idct4x4_16_add_c,
&vpx_idct4x4_1_add_neon,
TX_4X4, 1)));
#endif // HAVE_NEON && !CONFIG_VP9_HIGHBITDEPTH && !CONFIG_EMULATE_HARDWARE
#if HAVE_SSE2 && !CONFIG_VP9_HIGHBITDEPTH && !CONFIG_EMULATE_HARDWARE
INSTANTIATE_TEST_CASE_P(
SSE2, PartialIDctTest,
::testing::Values(make_tuple(&vpx_fdct32x32_c, &vpx_idct32x32_1024_add_c,
&vpx_idct32x32_34_add_sse2, TX_32X32, 34),
make_tuple(&vpx_fdct32x32_c, &vpx_idct32x32_1024_add_c,
&vpx_idct32x32_1_add_sse2, TX_32X32, 1),
make_tuple(&vpx_fdct16x16_c, &vpx_idct16x16_256_add_c,
&vpx_idct16x16_10_add_sse2, TX_16X16, 10),
make_tuple(&vpx_fdct16x16_c, &vpx_idct16x16_256_add_c,
&vpx_idct16x16_1_add_sse2, TX_16X16, 1),
make_tuple(&vpx_fdct8x8_c, &vpx_idct8x8_64_add_c,
&vpx_idct8x8_12_add_sse2, TX_8X8, 12),
make_tuple(&vpx_fdct8x8_c, &vpx_idct8x8_64_add_c,
&vpx_idct8x8_1_add_sse2, TX_8X8, 1),
make_tuple(&vpx_fdct4x4_c, &vpx_idct4x4_16_add_c,
&vpx_idct4x4_1_add_sse2, TX_4X4, 1)));
::testing::Values(
make_tuple(&vpx_fdct32x32_c,
&vpx_idct32x32_1024_add_c,
&vpx_idct32x32_34_add_sse2,
TX_32X32, 34),
make_tuple(&vpx_fdct32x32_c,
&vpx_idct32x32_1024_add_c,
&vpx_idct32x32_1_add_sse2,
TX_32X32, 1),
make_tuple(&vpx_fdct16x16_c,
&vpx_idct16x16_256_add_c,
&vpx_idct16x16_10_add_sse2,
TX_16X16, 10),
make_tuple(&vpx_fdct16x16_c,
&vpx_idct16x16_256_add_c,
&vpx_idct16x16_1_add_sse2,
TX_16X16, 1),
make_tuple(&vpx_fdct8x8_c,
&vpx_idct8x8_64_add_c,
&vpx_idct8x8_12_add_sse2,
TX_8X8, 12),
make_tuple(&vpx_fdct8x8_c,
&vpx_idct8x8_64_add_c,
&vpx_idct8x8_1_add_sse2,
TX_8X8, 1),
make_tuple(&vpx_fdct4x4_c,
&vpx_idct4x4_16_add_c,
&vpx_idct4x4_1_add_sse2,
TX_4X4, 1)));
#endif
#if HAVE_SSSE3 && ARCH_X86_64 && !CONFIG_VP9_HIGHBITDEPTH && \
!CONFIG_EMULATE_HARDWARE
#if HAVE_SSSE3 && CONFIG_USE_X86INC && ARCH_X86_64 && \
!CONFIG_VP9_HIGHBITDEPTH && !CONFIG_EMULATE_HARDWARE
INSTANTIATE_TEST_CASE_P(
SSSE3_64, PartialIDctTest,
::testing::Values(make_tuple(&vpx_fdct8x8_c, &vpx_idct8x8_64_add_c,
&vpx_idct8x8_12_add_ssse3, TX_8X8, 12)));
::testing::Values(
make_tuple(&vpx_fdct8x8_c,
&vpx_idct8x8_64_add_c,
&vpx_idct8x8_12_add_ssse3,
TX_8X8, 12)));
#endif
#if HAVE_MSA && !CONFIG_VP9_HIGHBITDEPTH && !CONFIG_EMULATE_HARDWARE
INSTANTIATE_TEST_CASE_P(
MSA, PartialIDctTest,
::testing::Values(make_tuple(&vpx_fdct32x32_c, &vpx_idct32x32_1024_add_c,
&vpx_idct32x32_34_add_msa, TX_32X32, 34),
make_tuple(&vpx_fdct32x32_c, &vpx_idct32x32_1024_add_c,
&vpx_idct32x32_1_add_msa, TX_32X32, 1),
make_tuple(&vpx_fdct16x16_c, &vpx_idct16x16_256_add_c,
&vpx_idct16x16_10_add_msa, TX_16X16, 10),
make_tuple(&vpx_fdct16x16_c, &vpx_idct16x16_256_add_c,
&vpx_idct16x16_1_add_msa, TX_16X16, 1),
make_tuple(&vpx_fdct8x8_c, &vpx_idct8x8_64_add_c,
&vpx_idct8x8_12_add_msa, TX_8X8, 10),
make_tuple(&vpx_fdct8x8_c, &vpx_idct8x8_64_add_c,
&vpx_idct8x8_1_add_msa, TX_8X8, 1),
make_tuple(&vpx_fdct4x4_c, &vpx_idct4x4_16_add_c,
&vpx_idct4x4_1_add_msa, TX_4X4, 1)));
::testing::Values(
make_tuple(&vpx_fdct32x32_c,
&vpx_idct32x32_1024_add_c,
&vpx_idct32x32_34_add_msa,
TX_32X32, 34),
make_tuple(&vpx_fdct32x32_c,
&vpx_idct32x32_1024_add_c,
&vpx_idct32x32_1_add_msa,
TX_32X32, 1),
make_tuple(&vpx_fdct16x16_c,
&vpx_idct16x16_256_add_c,
&vpx_idct16x16_10_add_msa,
TX_16X16, 10),
make_tuple(&vpx_fdct16x16_c,
&vpx_idct16x16_256_add_c,
&vpx_idct16x16_1_add_msa,
TX_16X16, 1),
make_tuple(&vpx_fdct8x8_c,
&vpx_idct8x8_64_add_c,
&vpx_idct8x8_12_add_msa,
TX_8X8, 10),
make_tuple(&vpx_fdct8x8_c,
&vpx_idct8x8_64_add_c,
&vpx_idct8x8_1_add_msa,
TX_8X8, 1),
make_tuple(&vpx_fdct4x4_c,
&vpx_idct4x4_16_add_c,
&vpx_idct4x4_1_add_msa,
TX_4X4, 1)));
#endif // HAVE_MSA && !CONFIG_VP9_HIGHBITDEPTH && !CONFIG_EMULATE_HARDWARE
} // namespace

View File

@@ -11,26 +11,32 @@
#include "test/register_state_check.h"
#include "third_party/googletest/src/include/gtest/gtest.h"
#include "./vpx_config.h"
#include "./vpx_dsp_rtcd.h"
#include "./vp8_rtcd.h"
#include "vpx/vpx_integer.h"
#include "vpx_mem/vpx_mem.h"
typedef void (*PostProcFunc)(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 (*PostProcFunc)(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);
namespace {
class VPxPostProcessingFilterTest
class VP8PostProcessingFilterTest
: public ::testing::TestWithParam<PostProcFunc> {
public:
virtual void TearDown() { libvpx_test::ClearSystemState(); }
virtual void TearDown() {
libvpx_test::ClearSystemState();
}
};
// Test routine for the VPx post-processing function
// vpx_post_proc_down_and_across_mb_row_c.
// Test routine for the VP8 post-processing function
// vp8_post_proc_down_and_across_mb_row_c.
TEST_P(VPxPostProcessingFilterTest, FilterOutputCheck) {
TEST_P(VP8PostProcessingFilterTest, FilterOutputCheck) {
// Size of the underlying data block that will be filtered.
const int block_width = 16;
const int block_height = 16;
@@ -74,18 +80,19 @@ TEST_P(VPxPostProcessingFilterTest, FilterOutputCheck) {
// Initialize pixels in the output to 99.
(void)memset(dst_image, 99, output_size);
ASM_REGISTER_STATE_CHECK(GetParam()(src_image_ptr, dst_image_ptr,
input_stride, output_stride, block_width,
flimits, 16));
ASM_REGISTER_STATE_CHECK(
GetParam()(src_image_ptr, dst_image_ptr, input_stride,
output_stride, block_width, flimits, 16));
static const uint8_t expected_data[block_height] = { 4, 3, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 3, 4 };
static const uint8_t expected_data[block_height] = {
4, 3, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 3, 4
};
pixel_ptr = dst_image_ptr;
for (int i = 0; i < block_height; ++i) {
for (int j = 0; j < block_width; ++j) {
EXPECT_EQ(expected_data[i], pixel_ptr[j])
<< "VPxPostProcessingFilterTest failed with invalid filter output";
<< "VP8PostProcessingFilterTest failed with invalid filter output";
}
pixel_ptr += output_stride;
}
@@ -95,20 +102,17 @@ TEST_P(VPxPostProcessingFilterTest, FilterOutputCheck) {
vpx_free(flimits);
};
INSTANTIATE_TEST_CASE_P(
C, VPxPostProcessingFilterTest,
::testing::Values(vpx_post_proc_down_and_across_mb_row_c));
INSTANTIATE_TEST_CASE_P(C, VP8PostProcessingFilterTest,
::testing::Values(vp8_post_proc_down_and_across_mb_row_c));
#if HAVE_SSE2
INSTANTIATE_TEST_CASE_P(
SSE2, VPxPostProcessingFilterTest,
::testing::Values(vpx_post_proc_down_and_across_mb_row_sse2));
INSTANTIATE_TEST_CASE_P(SSE2, VP8PostProcessingFilterTest,
::testing::Values(vp8_post_proc_down_and_across_mb_row_sse2));
#endif
#if HAVE_MSA
INSTANTIATE_TEST_CASE_P(
MSA, VPxPostProcessingFilterTest,
::testing::Values(vpx_post_proc_down_and_across_mb_row_msa));
INSTANTIATE_TEST_CASE_P(MSA, VP8PostProcessingFilterTest,
::testing::Values(vp8_post_proc_down_and_across_mb_row_msa));
#endif
} // namespace

View File

@@ -1,63 +0,0 @@
/*
* Copyright (c) 2016 The WebM project authors. All Rights Reserved.
*
* Use of this source code is governed by a BSD-style license
* that can be found in the LICENSE file in the root of the source
* tree. An additional intellectual property rights grant can be found
* in the file PATENTS. All contributing project authors may
* be found in the AUTHORS file in the root of the source tree.
*/
#include "test/codec_factory.h"
#include "test/encode_test_driver.h"
#include "test/util.h"
#include "test/video_source.h"
#include "third_party/googletest/src/include/gtest/gtest.h"
namespace {
const int kVideoSourceWidth = 320;
const int kVideoSourceHeight = 240;
const int kFramesToEncode = 2;
class RealtimeTest
: public ::libvpx_test::EncoderTest,
public ::libvpx_test::CodecTestWithParam<libvpx_test::TestMode> {
protected:
RealtimeTest() : EncoderTest(GET_PARAM(0)), frame_packets_(0) {}
virtual ~RealtimeTest() {}
virtual void SetUp() {
InitializeConfig();
cfg_.g_lag_in_frames = 0;
SetMode(::libvpx_test::kRealTime);
}
virtual void BeginPassHook(unsigned int /*pass*/) {
// TODO(tomfinegan): We're changing the pass value here to make sure
// we get frames when real time mode is combined with |g_pass| set to
// VPX_RC_FIRST_PASS. This is necessary because EncoderTest::RunLoop() sets
// the pass value based on the mode passed into EncoderTest::SetMode(),
// which overrides the one specified in SetUp() above.
cfg_.g_pass = VPX_RC_FIRST_PASS;
}
virtual void FramePktHook(const vpx_codec_cx_pkt_t * /*pkt*/) {
frame_packets_++;
}
int frame_packets_;
};
TEST_P(RealtimeTest, RealtimeFirstPassProducesFrames) {
::libvpx_test::RandomVideoSource video;
video.SetSize(kVideoSourceWidth, kVideoSourceHeight);
video.set_limit(kFramesToEncode);
ASSERT_NO_FATAL_FAILURE(RunLoop(&video));
EXPECT_EQ(kFramesToEncode, frame_packets_);
}
VP8_INSTANTIATE_TEST_CASE(RealtimeTest,
::testing::Values(::libvpx_test::kRealTime));
VP9_INSTANTIATE_TEST_CASE(RealtimeTest,
::testing::Values(::libvpx_test::kRealTime));
} // namespace

View File

@@ -30,16 +30,20 @@
#if defined(_WIN64)
#undef NOMINMAX
#define NOMINMAX
#define WIN32_LEAN_AND_MEAN
#define _WIN32_LEAN_AND_MEAN
#include <windows.h>
#include <winnt.h>
namespace testing {
namespace internal {
inline bool operator==(const M128A& lhs, const M128A& rhs) {
return (lhs.Low == rhs.Low && lhs.High == rhs.High);
}
} // namespace internal
} // namespace testing
namespace libvpx_test {
// Compares the state of xmm[6-15] at construction with their state at
@@ -48,7 +52,7 @@ namespace libvpx_test {
class RegisterStateCheck {
public:
RegisterStateCheck() { initialized_ = StoreRegisters(&pre_context_); }
~RegisterStateCheck() { Check(); }
~RegisterStateCheck() { EXPECT_TRUE(Check()); }
private:
static bool StoreRegisters(CONTEXT* const context) {
@@ -61,10 +65,10 @@ class RegisterStateCheck {
}
// Compares the register state. Returns true if the states match.
void Check() const {
ASSERT_TRUE(initialized_);
bool Check() const {
if (!initialized_) return false;
CONTEXT post_context;
ASSERT_TRUE(StoreRegisters(&post_context));
if (!StoreRegisters(&post_context)) return false;
const M128A* xmm_pre = &pre_context_.Xmm6;
const M128A* xmm_post = &post_context.Xmm6;
@@ -73,22 +77,22 @@ class RegisterStateCheck {
++xmm_pre;
++xmm_post;
}
return !testing::Test::HasNonfatalFailure();
}
bool initialized_;
CONTEXT pre_context_;
};
#define ASM_REGISTER_STATE_CHECK(statement) \
do { \
#define ASM_REGISTER_STATE_CHECK(statement) do { \
libvpx_test::RegisterStateCheck reg_check; \
statement; \
} while (false)
} // namespace libvpx_test
#elif defined(CONFIG_SHARED) && defined(HAVE_NEON_ASM) && \
defined(CONFIG_VP9) && !CONFIG_SHARED && HAVE_NEON_ASM && CONFIG_VP9
#elif defined(CONFIG_SHARED) && defined(HAVE_NEON_ASM) && defined(CONFIG_VP9) \
&& !CONFIG_SHARED && HAVE_NEON_ASM && CONFIG_VP9
extern "C" {
// Save the d8-d15 registers into store.
@@ -102,25 +106,32 @@ namespace libvpx_test {
// arm platform.
class RegisterStateCheck {
public:
RegisterStateCheck() { vpx_push_neon(pre_store_); }
~RegisterStateCheck() { Check(); }
RegisterStateCheck() { initialized_ = StoreRegisters(pre_store_); }
~RegisterStateCheck() { EXPECT_TRUE(Check()); }
private:
static bool StoreRegisters(int64_t store[8]) {
vpx_push_neon(store);
return true;
}
// Compares the register state. Returns true if the states match.
void Check() const {
bool Check() const {
if (!initialized_) return false;
int64_t post_store[8];
vpx_push_neon(post_store);
for (int i = 0; i < 8; ++i) {
EXPECT_EQ(pre_store_[i], post_store[i]) << "d" << i + 8
<< " has been modified";
EXPECT_EQ(pre_store_[i], post_store[i]) << "d"
<< i + 8 << " has been modified";
}
return !testing::Test::HasNonfatalFailure();
}
bool initialized_;
int64_t pre_store_[8];
};
#define ASM_REGISTER_STATE_CHECK(statement) \
do { \
#define ASM_REGISTER_STATE_CHECK(statement) do { \
libvpx_test::RegisterStateCheck reg_check; \
statement; \
} while (false)
@@ -149,12 +160,12 @@ class RegisterStateCheckMMX {
RegisterStateCheckMMX() {
__asm__ volatile("fstenv %0" : "=rm"(pre_fpu_env_));
}
~RegisterStateCheckMMX() { Check(); }
~RegisterStateCheckMMX() { EXPECT_TRUE(Check()); }
private:
// Checks the FPU tag word pre/post execution, returning false if not cleared
// to 0xffff.
void Check() const {
bool Check() const {
EXPECT_EQ(0xffff, pre_fpu_env_[4])
<< "FPU was in an inconsistent state prior to call";
@@ -162,13 +173,13 @@ class RegisterStateCheckMMX {
__asm__ volatile("fstenv %0" : "=rm"(post_fpu_env));
EXPECT_EQ(0xffff, post_fpu_env[4])
<< "FPU was left in an inconsistent state after call";
return !testing::Test::HasNonfatalFailure();
}
uint16_t pre_fpu_env_[14];
};
#define API_REGISTER_STATE_CHECK(statement) \
do { \
#define API_REGISTER_STATE_CHECK(statement) do { \
libvpx_test::RegisterStateCheckMMX reg_check; \
ASM_REGISTER_STATE_CHECK(statement); \
} while (false)

View File

@@ -7,8 +7,6 @@
* in the file PATENTS. All contributing project authors may
* be found in the AUTHORS file in the root of the source tree.
*/
#include <stdio.h>
#include <climits>
#include <vector>
#include "third_party/googletest/src/include/gtest/gtest.h"
@@ -68,7 +66,8 @@ static void write_ivf_frame_header(const vpx_codec_cx_pkt_t *const pkt,
char header[12];
vpx_codec_pts_t pts;
if (pkt->kind != VPX_CODEC_CX_FRAME_PKT) return;
if (pkt->kind != VPX_CODEC_CX_FRAME_PKT)
return;
pts = pkt->data.frame.pts;
mem_put_le32(header, static_cast<unsigned int>(pkt->data.frame.sz));
@@ -82,6 +81,45 @@ static void write_ivf_frame_header(const vpx_codec_cx_pkt_t *const pkt,
const unsigned int kInitialWidth = 320;
const unsigned int kInitialHeight = 240;
unsigned int ScaleForFrameNumber(unsigned int frame, unsigned int val) {
if (frame < 10)
return val;
if (frame < 20)
return val / 2;
if (frame < 30)
return val * 2 / 3;
if (frame < 40)
return val / 4;
if (frame < 50)
return val * 7 / 8;
return val;
}
class ResizingVideoSource : public ::libvpx_test::DummyVideoSource {
public:
ResizingVideoSource() {
SetSize(kInitialWidth, kInitialHeight);
limit_ = 60;
}
virtual ~ResizingVideoSource() {}
protected:
virtual void Next() {
++frame_;
SetSize(ScaleForFrameNumber(frame_, kInitialWidth),
ScaleForFrameNumber(frame_, kInitialHeight));
FillFrame();
}
};
class ResizeTest : public ::libvpx_test::EncoderTest,
public ::libvpx_test::CodecTestWithParam<libvpx_test::TestMode> {
protected:
ResizeTest() : EncoderTest(GET_PARAM(0)) {}
virtual ~ResizeTest() {}
struct FrameInfo {
FrameInfo(vpx_codec_pts_t _pts, unsigned int _w, unsigned int _h)
: pts(_pts), w(_w), h(_h) {}
@@ -91,187 +129,6 @@ struct FrameInfo {
unsigned int h;
};
void ScaleForFrameNumber(unsigned int frame, unsigned int initial_w,
unsigned int initial_h, unsigned int *w,
unsigned int *h, int flag_codec) {
if (frame < 10) {
*w = initial_w;
*h = initial_h;
return;
}
if (frame < 20) {
*w = initial_w * 3 / 4;
*h = initial_h * 3 / 4;
return;
}
if (frame < 30) {
*w = initial_w / 2;
*h = initial_h / 2;
return;
}
if (frame < 40) {
*w = initial_w;
*h = initial_h;
return;
}
if (frame < 50) {
*w = initial_w * 3 / 4;
*h = initial_h * 3 / 4;
return;
}
if (frame < 60) {
*w = initial_w / 2;
*h = initial_h / 2;
return;
}
if (frame < 70) {
*w = initial_w;
*h = initial_h;
return;
}
if (frame < 80) {
*w = initial_w * 3 / 4;
*h = initial_h * 3 / 4;
return;
}
if (frame < 90) {
*w = initial_w / 2;
*h = initial_h / 2;
return;
}
if (frame < 100) {
*w = initial_w * 3 / 4;
*h = initial_h * 3 / 4;
return;
}
if (frame < 110) {
*w = initial_w;
*h = initial_h;
return;
}
if (frame < 120) {
*w = initial_w * 3 / 4;
*h = initial_h * 3 / 4;
return;
}
if (frame < 130) {
*w = initial_w / 2;
*h = initial_h / 2;
return;
}
if (frame < 140) {
*w = initial_w * 3 / 4;
*h = initial_h * 3 / 4;
return;
}
if (frame < 150) {
*w = initial_w;
*h = initial_h;
return;
}
if (frame < 160) {
*w = initial_w * 3 / 4;
*h = initial_h * 3 / 4;
return;
}
if (frame < 170) {
*w = initial_w / 2;
*h = initial_h / 2;
return;
}
if (frame < 180) {
*w = initial_w * 3 / 4;
*h = initial_h * 3 / 4;
return;
}
if (frame < 190) {
*w = initial_w;
*h = initial_h;
return;
}
if (frame < 200) {
*w = initial_w * 3 / 4;
*h = initial_h * 3 / 4;
return;
}
if (frame < 210) {
*w = initial_w / 2;
*h = initial_h / 2;
return;
}
if (frame < 220) {
*w = initial_w * 3 / 4;
*h = initial_h * 3 / 4;
return;
}
if (frame < 230) {
*w = initial_w;
*h = initial_h;
return;
}
if (frame < 240) {
*w = initial_w * 3 / 4;
*h = initial_h * 3 / 4;
return;
}
if (frame < 250) {
*w = initial_w / 2;
*h = initial_h / 2;
return;
}
if (frame < 260) {
*w = initial_w;
*h = initial_h;
return;
}
// Go down very low.
if (frame < 270) {
*w = initial_w / 4;
*h = initial_h / 4;
return;
}
if (flag_codec == 1) {
// Cases that only works for VP9.
// For VP9: Swap width and height of original.
if (frame < 320) {
*w = initial_h;
*h = initial_w;
return;
}
}
*w = initial_w;
*h = initial_h;
}
class ResizingVideoSource : public ::libvpx_test::DummyVideoSource {
public:
ResizingVideoSource() {
SetSize(kInitialWidth, kInitialHeight);
limit_ = 350;
}
int flag_codec_;
virtual ~ResizingVideoSource() {}
protected:
virtual void Next() {
++frame_;
unsigned int width;
unsigned int height;
ScaleForFrameNumber(frame_, kInitialWidth, kInitialHeight, &width, &height,
flag_codec_);
SetSize(width, height);
FillFrame();
}
};
class ResizeTest
: public ::libvpx_test::EncoderTest,
public ::libvpx_test::CodecTestWithParam<libvpx_test::TestMode> {
protected:
ResizeTest() : EncoderTest(GET_PARAM(0)) {}
virtual ~ResizeTest() {}
virtual void SetUp() {
InitializeConfig();
SetMode(GET_PARAM(1));
@@ -287,21 +144,19 @@ class ResizeTest
TEST_P(ResizeTest, TestExternalResizeWorks) {
ResizingVideoSource video;
video.flag_codec_ = 0;
cfg_.g_lag_in_frames = 0;
ASSERT_NO_FATAL_FAILURE(RunLoop(&video));
for (std::vector<FrameInfo>::const_iterator info = frame_info_list_.begin();
info != frame_info_list_.end(); ++info) {
const unsigned int frame = static_cast<unsigned>(info->pts);
unsigned int expected_w;
unsigned int expected_h;
ScaleForFrameNumber(frame, kInitialWidth, kInitialHeight, &expected_w,
&expected_h, 0);
EXPECT_EQ(expected_w, info->w) << "Frame " << frame
<< " had unexpected width";
EXPECT_EQ(expected_h, info->h) << "Frame " << frame
<< " had unexpected height";
const unsigned int expected_w = ScaleForFrameNumber(frame, kInitialWidth);
const unsigned int expected_h = ScaleForFrameNumber(frame, kInitialHeight);
EXPECT_EQ(expected_w, info->w)
<< "Frame " << frame << " had unexpected width";
EXPECT_EQ(expected_h, info->h)
<< "Frame " << frame << " had unexpected height";
}
}
@@ -312,7 +167,10 @@ class ResizeInternalTest : public ResizeTest {
protected:
#if WRITE_COMPRESSED_STREAM
ResizeInternalTest()
: ResizeTest(), frame0_psnr_(0.0), outfile_(NULL), out_frames_(0) {}
: ResizeTest(),
frame0_psnr_(0.0),
outfile_(NULL),
out_frames_(0) {}
#else
ResizeInternalTest() : ResizeTest(), frame0_psnr_(0.0) {}
#endif
@@ -338,19 +196,6 @@ class ResizeInternalTest : public ResizeTest {
virtual void PreEncodeFrameHook(libvpx_test::VideoSource *video,
libvpx_test::Encoder *encoder) {
if (change_config_) {
int new_q = 60;
if (video->frame() == 0) {
struct vpx_scaling_mode mode = { VP8E_ONETWO, VP8E_ONETWO };
encoder->Control(VP8E_SET_SCALEMODE, &mode);
}
if (video->frame() == 1) {
struct vpx_scaling_mode mode = { VP8E_NORMAL, VP8E_NORMAL };
encoder->Control(VP8E_SET_SCALEMODE, &mode);
cfg_.rc_min_quantizer = cfg_.rc_max_quantizer = new_q;
encoder->Config(&cfg_);
}
} else {
if (video->frame() == kStepDownFrame) {
struct vpx_scaling_mode mode = {VP8E_FOURFIVE, VP8E_THREEFIVE};
encoder->Control(VP8E_SET_SCALEMODE, &mode);
@@ -360,10 +205,10 @@ class ResizeInternalTest : public ResizeTest {
encoder->Control(VP8E_SET_SCALEMODE, &mode);
}
}
}
virtual void PSNRPktHook(const vpx_codec_cx_pkt_t *pkt) {
if (frame0_psnr_ == 0.) frame0_psnr_ = pkt->data.psnr.psnr[0];
if (!frame0_psnr_)
frame0_psnr_ = pkt->data.psnr.psnr[0];
EXPECT_NEAR(pkt->data.psnr.psnr[0], frame0_psnr_, 2.0);
}
@@ -372,7 +217,8 @@ class ResizeInternalTest : public ResizeTest {
++out_frames_;
// Write initial file header if first frame.
if (pkt->data.frame.pts == 0) write_ivf_file_header(&cfg_, 0, outfile_);
if (pkt->data.frame.pts == 0)
write_ivf_file_header(&cfg_, 0, outfile_);
// Write frame header and data.
write_ivf_frame_header(pkt, outfile_);
@@ -381,7 +227,6 @@ class ResizeInternalTest : public ResizeTest {
#endif
double frame0_psnr_;
bool change_config_;
#if WRITE_COMPRESSED_STREAM
FILE *outfile_;
unsigned int out_frames_;
@@ -392,7 +237,6 @@ TEST_P(ResizeInternalTest, TestInternalResizeWorks) {
::libvpx_test::I420VideoSource video("hantro_collage_w352h288.yuv", 352, 288,
30, 1, 0, 10);
init_flags_ = VPX_CODEC_USE_PSNR;
change_config_ = false;
// q picked such that initial keyframe on this clip is ~30dB PSNR
cfg_.rc_min_quantizer = cfg_.rc_max_quantizer = 48;
@@ -417,199 +261,11 @@ TEST_P(ResizeInternalTest, TestInternalResizeWorks) {
}
}
TEST_P(ResizeInternalTest, TestInternalResizeChangeConfig) {
::libvpx_test::I420VideoSource video("hantro_collage_w352h288.yuv", 352, 288,
30, 1, 0, 10);
cfg_.g_w = 352;
cfg_.g_h = 288;
change_config_ = true;
ASSERT_NO_FATAL_FAILURE(RunLoop(&video));
}
class ResizeRealtimeTest
: public ::libvpx_test::EncoderTest,
public ::libvpx_test::CodecTestWith2Params<libvpx_test::TestMode, int> {
protected:
ResizeRealtimeTest() : EncoderTest(GET_PARAM(0)) {}
virtual ~ResizeRealtimeTest() {}
virtual void PreEncodeFrameHook(libvpx_test::VideoSource *video,
libvpx_test::Encoder *encoder) {
if (video->frame() == 0) {
encoder->Control(VP9E_SET_AQ_MODE, 3);
encoder->Control(VP8E_SET_CPUUSED, set_cpu_used_);
}
if (change_bitrate_ && video->frame() == 120) {
change_bitrate_ = false;
cfg_.rc_target_bitrate = 500;
encoder->Config(&cfg_);
}
}
virtual void SetUp() {
InitializeConfig();
SetMode(GET_PARAM(1));
set_cpu_used_ = GET_PARAM(2);
}
virtual void DecompressedFrameHook(const vpx_image_t &img,
vpx_codec_pts_t pts) {
frame_info_list_.push_back(FrameInfo(pts, img.d_w, img.d_h));
}
virtual void MismatchHook(const vpx_image_t *img1, const vpx_image_t *img2) {
double mismatch_psnr = compute_psnr(img1, img2);
mismatch_psnr_ += mismatch_psnr;
++mismatch_nframes_;
}
unsigned int GetMismatchFrames() { return mismatch_nframes_; }
void DefaultConfig() {
cfg_.rc_buf_initial_sz = 500;
cfg_.rc_buf_optimal_sz = 600;
cfg_.rc_buf_sz = 1000;
cfg_.rc_min_quantizer = 2;
cfg_.rc_max_quantizer = 56;
cfg_.rc_undershoot_pct = 50;
cfg_.rc_overshoot_pct = 50;
cfg_.rc_end_usage = VPX_CBR;
cfg_.kf_mode = VPX_KF_AUTO;
cfg_.g_lag_in_frames = 0;
cfg_.kf_min_dist = cfg_.kf_max_dist = 3000;
// Enable dropped frames.
cfg_.rc_dropframe_thresh = 1;
// Enable error_resilience mode.
cfg_.g_error_resilient = 1;
// Enable dynamic resizing.
cfg_.rc_resize_allowed = 1;
// Run at low bitrate.
cfg_.rc_target_bitrate = 200;
}
std::vector<FrameInfo> frame_info_list_;
int set_cpu_used_;
bool change_bitrate_;
double mismatch_psnr_;
int mismatch_nframes_;
};
TEST_P(ResizeRealtimeTest, TestExternalResizeWorks) {
ResizingVideoSource video;
video.flag_codec_ = 1;
DefaultConfig();
// Disable internal resize for this test.
cfg_.rc_resize_allowed = 0;
change_bitrate_ = false;
mismatch_psnr_ = 0.0;
mismatch_nframes_ = 0;
ASSERT_NO_FATAL_FAILURE(RunLoop(&video));
for (std::vector<FrameInfo>::const_iterator info = frame_info_list_.begin();
info != frame_info_list_.end(); ++info) {
const unsigned int frame = static_cast<unsigned>(info->pts);
unsigned int expected_w;
unsigned int expected_h;
ScaleForFrameNumber(frame, kInitialWidth, kInitialHeight, &expected_w,
&expected_h, 1);
EXPECT_EQ(expected_w, info->w) << "Frame " << frame
<< " had unexpected width";
EXPECT_EQ(expected_h, info->h) << "Frame " << frame
<< " had unexpected height";
EXPECT_EQ(static_cast<unsigned int>(0), GetMismatchFrames());
}
}
// Verify the dynamic resizer behavior for real time, 1 pass CBR mode.
// Run at low bitrate, with resize_allowed = 1, and verify that we get
// one resize down event.
TEST_P(ResizeRealtimeTest, TestInternalResizeDown) {
::libvpx_test::I420VideoSource video("hantro_collage_w352h288.yuv", 352, 288,
30, 1, 0, 299);
DefaultConfig();
cfg_.g_w = 352;
cfg_.g_h = 288;
change_bitrate_ = false;
mismatch_psnr_ = 0.0;
mismatch_nframes_ = 0;
ASSERT_NO_FATAL_FAILURE(RunLoop(&video));
unsigned int last_w = cfg_.g_w;
unsigned int last_h = cfg_.g_h;
int resize_count = 0;
for (std::vector<FrameInfo>::const_iterator info = frame_info_list_.begin();
info != frame_info_list_.end(); ++info) {
if (info->w != last_w || info->h != last_h) {
// Verify that resize down occurs.
ASSERT_LT(info->w, last_w);
ASSERT_LT(info->h, last_h);
last_w = info->w;
last_h = info->h;
resize_count++;
}
}
#if CONFIG_VP9_DECODER
// Verify that we get 1 resize down event in this test.
ASSERT_EQ(1, resize_count) << "Resizing should occur.";
EXPECT_EQ(static_cast<unsigned int>(0), GetMismatchFrames());
#else
printf("Warning: VP9 decoder unavailable, unable to check resize count!\n");
#endif
}
// Verify the dynamic resizer behavior for real time, 1 pass CBR mode.
// Start at low target bitrate, raise the bitrate in the middle of the clip,
// scaling-up should occur after bitrate changed.
TEST_P(ResizeRealtimeTest, TestInternalResizeDownUpChangeBitRate) {
::libvpx_test::I420VideoSource video("hantro_collage_w352h288.yuv", 352, 288,
30, 1, 0, 359);
DefaultConfig();
cfg_.g_w = 352;
cfg_.g_h = 288;
change_bitrate_ = true;
mismatch_psnr_ = 0.0;
mismatch_nframes_ = 0;
// Disable dropped frames.
cfg_.rc_dropframe_thresh = 0;
// Starting bitrate low.
cfg_.rc_target_bitrate = 80;
ASSERT_NO_FATAL_FAILURE(RunLoop(&video));
unsigned int last_w = cfg_.g_w;
unsigned int last_h = cfg_.g_h;
int resize_count = 0;
for (std::vector<FrameInfo>::const_iterator info = frame_info_list_.begin();
info != frame_info_list_.end(); ++info) {
if (info->w != last_w || info->h != last_h) {
resize_count++;
if (resize_count == 1) {
// Verify that resize down occurs.
ASSERT_LT(info->w, last_w);
ASSERT_LT(info->h, last_h);
} else if (resize_count == 2) {
// Verify that resize up occurs.
ASSERT_GT(info->w, last_w);
ASSERT_GT(info->h, last_h);
}
last_w = info->w;
last_h = info->h;
}
}
#if CONFIG_VP9_DECODER
// Verify that we get 2 resize events in this test.
ASSERT_EQ(resize_count, 2) << "Resizing should occur twice.";
EXPECT_EQ(static_cast<unsigned int>(0), GetMismatchFrames());
#else
printf("Warning: VP9 decoder unavailable, unable to check resize count!\n");
#endif
}
vpx_img_fmt_t CspForFrameNumber(int frame) {
if (frame < 10) return VPX_IMG_FMT_I420;
if (frame < 20) return VPX_IMG_FMT_I444;
if (frame < 10)
return VPX_IMG_FMT_I420;
if (frame < 20)
return VPX_IMG_FMT_I444;
return VPX_IMG_FMT_I420;
}
@@ -617,7 +273,10 @@ class ResizeCspTest : public ResizeTest {
protected:
#if WRITE_COMPRESSED_STREAM
ResizeCspTest()
: ResizeTest(), frame0_psnr_(0.0), outfile_(NULL), out_frames_(0) {}
: ResizeTest(),
frame0_psnr_(0.0),
outfile_(NULL),
out_frames_(0) {}
#else
ResizeCspTest() : ResizeTest(), frame0_psnr_(0.0) {}
#endif
@@ -656,7 +315,8 @@ class ResizeCspTest : public ResizeTest {
}
virtual void PSNRPktHook(const vpx_codec_cx_pkt_t *pkt) {
if (frame0_psnr_ == 0.) frame0_psnr_ = pkt->data.psnr.psnr[0];
if (!frame0_psnr_)
frame0_psnr_ = pkt->data.psnr.psnr[0];
EXPECT_NEAR(pkt->data.psnr.psnr[0], frame0_psnr_, 2.0);
}
@@ -665,7 +325,8 @@ class ResizeCspTest : public ResizeTest {
++out_frames_;
// Write initial file header if first frame.
if (pkt->data.frame.pts == 0) write_ivf_file_header(&cfg_, 0, outfile_);
if (pkt->data.frame.pts == 0)
write_ivf_file_header(&cfg_, 0, outfile_);
// Write frame header and data.
write_ivf_frame_header(pkt, outfile_);
@@ -710,9 +371,6 @@ VP9_INSTANTIATE_TEST_CASE(ResizeTest,
::testing::Values(::libvpx_test::kRealTime));
VP9_INSTANTIATE_TEST_CASE(ResizeInternalTest,
::testing::Values(::libvpx_test::kOnePassBest));
VP9_INSTANTIATE_TEST_CASE(ResizeRealtimeTest,
::testing::Values(::libvpx_test::kRealTime),
::testing::Range(5, 9));
VP9_INSTANTIATE_TEST_CASE(ResizeCspTest,
::testing::Values(::libvpx_test::kRealTime));
} // namespace

File diff suppressed because it is too large Load Diff

View File

@@ -8,6 +8,7 @@
* be found in the AUTHORS file in the root of the source tree.
*/
#include <math.h>
#include <stddef.h>
#include <stdio.h>
@@ -32,10 +33,14 @@ TEST(VP8RoiMapTest, ParameterCheck) {
unsigned int threshold[MAX_MB_SEGMENTS] = { 0, 100, 200, 300 };
const int internalq_trans[] = {
0, 1, 2, 3, 4, 5, 7, 8, 9, 10, 12, 13, 15, 17, 18, 19,
20, 21, 23, 24, 25, 26, 27, 28, 29, 30, 31, 33, 35, 37, 39, 41,
43, 45, 47, 49, 51, 53, 55, 57, 59, 61, 64, 67, 70, 73, 76, 79,
82, 85, 88, 91, 94, 97, 100, 103, 106, 109, 112, 115, 118, 121, 124, 127,
0, 1, 2, 3, 4, 5, 7, 8,
9, 10, 12, 13, 15, 17, 18, 19,
20, 21, 23, 24, 25, 26, 27, 28,
29, 30, 31, 33, 35, 37, 39, 41,
43, 45, 47, 49, 51, 53, 55, 57,
59, 61, 64, 67, 70, 73, 76, 79,
82, 85, 88, 91, 94, 97, 100, 103,
106, 109, 112, 115, 118, 121, 124, 127,
};
// Initialize elements of cpi with valid defaults.
@@ -61,9 +66,9 @@ TEST(VP8RoiMapTest, ParameterCheck) {
memset(&roi_map[mbs -(mbs >> 2)], 3, (mbs >> 2));
// Do a test call with valid parameters.
int roi_retval =
vp8_set_roimap(&cpi, roi_map, cpi.common.mb_rows, cpi.common.mb_cols,
delta_q, delta_lf, threshold);
int roi_retval = vp8_set_roimap(&cpi, roi_map, cpi.common.mb_rows,
cpi.common.mb_cols, delta_q, delta_lf,
threshold);
EXPECT_EQ(0, roi_retval)
<< "vp8_set_roimap roi failed with default test parameters";
@@ -99,7 +104,8 @@ TEST(VP8RoiMapTest, ParameterCheck) {
static_cast<unsigned int>(cpi.segment_encode_breakout[i]);
if (threshold[i] != breakout) {
EXPECT_EQ(threshold[i], breakout) << "breakout threshold error";
EXPECT_EQ(threshold[i], breakout)
<< "breakout threshold error";
break;
}
}
@@ -112,6 +118,7 @@ TEST(VP8RoiMapTest, ParameterCheck) {
EXPECT_EQ(1, cpi.mb.e_mbd.update_mb_segmentation_data)
<< "update_mb_segmentation_data error";
// Try a range of delta q and lf parameters (some legal, some not)
for (int i = 0; i < 1000; ++i) {
int rand_deltas[4];
@@ -121,54 +128,57 @@ TEST(VP8RoiMapTest, ParameterCheck) {
rand_deltas[2] = rnd(160) - 80;
rand_deltas[3] = rnd(160) - 80;
deltas_valid =
((abs(rand_deltas[0]) <= 63) && (abs(rand_deltas[1]) <= 63) &&
(abs(rand_deltas[2]) <= 63) && (abs(rand_deltas[3]) <= 63))
? 0
: -1;
deltas_valid = ((abs(rand_deltas[0]) <= 63) &&
(abs(rand_deltas[1]) <= 63) &&
(abs(rand_deltas[2]) <= 63) &&
(abs(rand_deltas[3]) <= 63)) ? 0 : -1;
// Test with random delta q values.
roi_retval =
vp8_set_roimap(&cpi, roi_map, cpi.common.mb_rows, cpi.common.mb_cols,
rand_deltas, delta_lf, threshold);
roi_retval = vp8_set_roimap(&cpi, roi_map, cpi.common.mb_rows,
cpi.common.mb_cols, rand_deltas,
delta_lf, threshold);
EXPECT_EQ(deltas_valid, roi_retval) << "dq range check error";
// One delta_q error shown at a time
if (deltas_valid != roi_retval) break;
if (deltas_valid != roi_retval)
break;
// Test with random loop filter values.
roi_retval =
vp8_set_roimap(&cpi, roi_map, cpi.common.mb_rows, cpi.common.mb_cols,
delta_q, rand_deltas, threshold);
roi_retval = vp8_set_roimap(&cpi, roi_map, cpi.common.mb_rows,
cpi.common.mb_cols, delta_q,
rand_deltas, threshold);
EXPECT_EQ(deltas_valid, roi_retval) << "dlf range check error";
// One delta loop filter error shown at a time
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);
roi_retval = vp8_set_roimap(&cpi, roi_map, cpi.common.mb_rows,
cpi.common.mb_cols, delta_q,
delta_lf, threshold);
EXPECT_EQ(-1, roi_retval) << "cyclic refresh check error";
cpi.cyclic_refresh_mode_enabled = 0;
// Test invalid number of rows or colums.
roi_retval =
vp8_set_roimap(&cpi, roi_map, cpi.common.mb_rows + 1,
cpi.common.mb_cols, delta_q, delta_lf, threshold);
roi_retval = vp8_set_roimap(&cpi, roi_map, cpi.common.mb_rows + 1,
cpi.common.mb_cols, delta_q,
delta_lf, threshold);
EXPECT_EQ(-1, roi_retval) << "MB rows bounds check error";
roi_retval =
vp8_set_roimap(&cpi, roi_map, cpi.common.mb_rows,
cpi.common.mb_cols - 1, delta_q, delta_lf, threshold);
roi_retval = vp8_set_roimap(&cpi, roi_map, cpi.common.mb_rows,
cpi.common.mb_cols - 1, delta_q,
delta_lf, threshold);
EXPECT_EQ(-1, roi_retval) << "MB cols bounds check error";
}
// Free allocated memory
if (cpi.segmentation_map) vpx_free(cpi.segmentation_map);
if (roi_map) vpx_free(roi_map);
if (cpi.segmentation_map)
vpx_free(cpi.segmentation_map);
if (roi_map)
vpx_free(roi_map);
};
} // namespace

View File

@@ -23,7 +23,7 @@ simple_encoder_verify_environment() {
fi
}
# Runs simple_encoder using the codec specified by $1 with a frame limit of 100.
# Runs simple_encoder using the codec specified by $1.
simple_encoder() {
local encoder="${LIBVPX_BIN_PATH}/simple_encoder${VPX_TEST_EXE_SUFFIX}"
local codec="$1"
@@ -35,7 +35,7 @@ simple_encoder() {
fi
eval "${VPX_TEST_PREFIX}" "${encoder}" "${codec}" "${YUV_RAW_INPUT_WIDTH}" \
"${YUV_RAW_INPUT_HEIGHT}" "${YUV_RAW_INPUT}" "${output_file}" 9999 0 100 \
"${YUV_RAW_INPUT_HEIGHT}" "${YUV_RAW_INPUT}" "${output_file}" 9999 \
${devnull}
[ -e "${output_file}" ] || return 1
@@ -47,13 +47,16 @@ simple_encoder_vp8() {
fi
}
simple_encoder_vp9() {
# TODO(tomfinegan): Add a frame limit param to simple_encoder and enable this
# test. VP9 is just too slow right now: This test takes 4m30s+ on a fast
# machine.
DISABLED_simple_encoder_vp9() {
if [ "$(vp9_encode_available)" = "yes" ]; then
simple_encoder vp9 || return 1
fi
}
simple_encoder_tests="simple_encoder_vp8
simple_encoder_vp9"
DISABLED_simple_encoder_vp9"
run_tests simple_encoder_verify_environment "${simple_encoder_tests}"

View File

@@ -25,19 +25,22 @@
namespace {
typedef void (*SixtapPredictFunc)(uint8_t *src_ptr, int src_pixels_per_line,
int xoffset, int yoffset, uint8_t *dst_ptr,
typedef void (*SixtapPredictFunc)(uint8_t *src_ptr,
int src_pixels_per_line,
int xoffset,
int yoffset,
uint8_t *dst_ptr,
int dst_pitch);
typedef std::tr1::tuple<int, int, SixtapPredictFunc> SixtapPredictParam;
class SixtapPredictTest : public ::testing::TestWithParam<SixtapPredictParam> {
class SixtapPredictTest
: public ::testing::TestWithParam<SixtapPredictParam> {
public:
static void SetUpTestCase() {
src_ = reinterpret_cast<uint8_t*>(vpx_memalign(kDataAlignment, kSrcSize));
dst_ = reinterpret_cast<uint8_t*>(vpx_memalign(kDataAlignment, kDstSize));
dst_c_ =
reinterpret_cast<uint8_t *>(vpx_memalign(kDataAlignment, kDstSize));
dst_c_ = reinterpret_cast<uint8_t*>(vpx_memalign(kDataAlignment, kDstSize));
}
static void TearDownTestCase() {
@@ -49,7 +52,9 @@ class SixtapPredictTest : public ::testing::TestWithParam<SixtapPredictParam> {
dst_c_ = NULL;
}
virtual void TearDown() { libvpx_test::ClearSystemState(); }
virtual void TearDown() {
libvpx_test::ClearSystemState();
}
protected:
// Make test arrays big enough for 16x16 functions. Six-tap filters
@@ -87,77 +92,75 @@ uint8_t *SixtapPredictTest::dst_c_ = NULL;
TEST_P(SixtapPredictTest, TestWithPresetData) {
// Test input
static const uint8_t test_data[kSrcSize] = {
216, 184, 4, 191, 82, 92, 41, 0, 1, 226, 236, 172, 20, 182, 42,
226, 177, 79, 94, 77, 179, 203, 206, 198, 22, 192, 19, 75, 17, 192,
44, 233, 120, 48, 168, 203, 141, 210, 203, 143, 180, 184, 59, 201, 110,
102, 171, 32, 182, 10, 109, 105, 213, 60, 47, 236, 253, 67, 55, 14,
3, 99, 247, 124, 148, 159, 71, 34, 114, 19, 177, 38, 203, 237, 239,
58, 83, 155, 91, 10, 166, 201, 115, 124, 5, 163, 104, 2, 231, 160,
16, 234, 4, 8, 103, 153, 167, 174, 187, 26, 193, 109, 64, 141, 90,
48, 200, 174, 204, 36, 184, 114, 237, 43, 238, 242, 207, 86, 245, 182,
247, 6, 161, 251, 14, 8, 148, 182, 182, 79, 208, 120, 188, 17, 6,
23, 65, 206, 197, 13, 242, 126, 128, 224, 170, 110, 211, 121, 197, 200,
47, 188, 207, 208, 184, 221, 216, 76, 148, 143, 156, 100, 8, 89, 117,
14, 112, 183, 221, 54, 197, 208, 180, 69, 176, 94, 180, 131, 215, 121,
76, 7, 54, 28, 216, 238, 249, 176, 58, 142, 64, 215, 242, 72, 49,
104, 87, 161, 32, 52, 216, 230, 4, 141, 44, 181, 235, 224, 57, 195,
89, 134, 203, 144, 162, 163, 126, 156, 84, 185, 42, 148, 145, 29, 221,
194, 134, 52, 100, 166, 105, 60, 140, 110, 201, 184, 35, 181, 153, 93,
121, 243, 227, 68, 131, 134, 232, 2, 35, 60, 187, 77, 209, 76, 106,
174, 15, 241, 227, 115, 151, 77, 175, 36, 187, 121, 221, 223, 47, 118,
61, 168, 105, 32, 237, 236, 167, 213, 238, 202, 17, 170, 24, 226, 247,
131, 145, 6, 116, 117, 121, 11, 194, 41, 48, 126, 162, 13, 93, 209,
131, 154, 122, 237, 187, 103, 217, 99, 60, 200, 45, 78, 115, 69, 49,
106, 200, 194, 112, 60, 56, 234, 72, 251, 19, 120, 121, 182, 134, 215,
135, 10, 114, 2, 247, 46, 105, 209, 145, 165, 153, 191, 243, 12, 5,
36, 119, 206, 231, 231, 11, 32, 209, 83, 27, 229, 204, 149, 155, 83,
109, 35, 93, 223, 37, 84, 14, 142, 37, 160, 52, 191, 96, 40, 204,
101, 77, 67, 52, 53, 43, 63, 85, 253, 147, 113, 226, 96, 6, 125,
179, 115, 161, 17, 83, 198, 101, 98, 85, 139, 3, 137, 75, 99, 178,
23, 201, 255, 91, 253, 52, 134, 60, 138, 131, 208, 251, 101, 48, 2,
227, 228, 118, 132, 245, 202, 75, 91, 44, 160, 231, 47, 41, 50, 147,
220, 74, 92, 219, 165, 89, 16
216, 184, 4, 191, 82, 92, 41, 0, 1, 226, 236, 172, 20, 182, 42, 226, 177,
79, 94, 77, 179, 203, 206, 198, 22, 192, 19, 75, 17, 192, 44, 233, 120,
48, 168, 203, 141, 210, 203, 143, 180, 184, 59, 201, 110, 102, 171, 32,
182, 10, 109, 105, 213, 60, 47, 236, 253, 67, 55, 14, 3, 99, 247, 124,
148, 159, 71, 34, 114, 19, 177, 38, 203, 237, 239, 58, 83, 155, 91, 10,
166, 201, 115, 124, 5, 163, 104, 2, 231, 160, 16, 234, 4, 8, 103, 153,
167, 174, 187, 26, 193, 109, 64, 141, 90, 48, 200, 174, 204, 36, 184,
114, 237, 43, 238, 242, 207, 86, 245, 182, 247, 6, 161, 251, 14, 8, 148,
182, 182, 79, 208, 120, 188, 17, 6, 23, 65, 206, 197, 13, 242, 126, 128,
224, 170, 110, 211, 121, 197, 200, 47, 188, 207, 208, 184, 221, 216, 76,
148, 143, 156, 100, 8, 89, 117, 14, 112, 183, 221, 54, 197, 208, 180, 69,
176, 94, 180, 131, 215, 121, 76, 7, 54, 28, 216, 238, 249, 176, 58, 142,
64, 215, 242, 72, 49, 104, 87, 161, 32, 52, 216, 230, 4, 141, 44, 181,
235, 224, 57, 195, 89, 134, 203, 144, 162, 163, 126, 156, 84, 185, 42,
148, 145, 29, 221, 194, 134, 52, 100, 166, 105, 60, 140, 110, 201, 184,
35, 181, 153, 93, 121, 243, 227, 68, 131, 134, 232, 2, 35, 60, 187, 77,
209, 76, 106, 174, 15, 241, 227, 115, 151, 77, 175, 36, 187, 121, 221,
223, 47, 118, 61, 168, 105, 32, 237, 236, 167, 213, 238, 202, 17, 170,
24, 226, 247, 131, 145, 6, 116, 117, 121, 11, 194, 41, 48, 126, 162, 13,
93, 209, 131, 154, 122, 237, 187, 103, 217, 99, 60, 200, 45, 78, 115, 69,
49, 106, 200, 194, 112, 60, 56, 234, 72, 251, 19, 120, 121, 182, 134, 215,
135, 10, 114, 2, 247, 46, 105, 209, 145, 165, 153, 191, 243, 12, 5, 36,
119, 206, 231, 231, 11, 32, 209, 83, 27, 229, 204, 149, 155, 83, 109, 35,
93, 223, 37, 84, 14, 142, 37, 160, 52, 191, 96, 40, 204, 101, 77, 67, 52,
53, 43, 63, 85, 253, 147, 113, 226, 96, 6, 125, 179, 115, 161, 17, 83,
198, 101, 98, 85, 139, 3, 137, 75, 99, 178, 23, 201, 255, 91, 253, 52,
134, 60, 138, 131, 208, 251, 101, 48, 2, 227, 228, 118, 132, 245, 202,
75, 91, 44, 160, 231, 47, 41, 50, 147, 220, 74, 92, 219, 165, 89, 16
};
// Expected result
static const uint8_t expected_dst[kDstSize] = {
117, 102, 74, 135, 42, 98, 175, 206, 70, 73, 222, 197, 50, 24, 39,
49, 38, 105, 90, 47, 169, 40, 171, 215, 200, 73, 109, 141, 53, 85,
177, 164, 79, 208, 124, 89, 212, 18, 81, 145, 151, 164, 217, 153, 91,
154, 102, 102, 159, 75, 164, 152, 136, 51, 213, 219, 186, 116, 193, 224,
186, 36, 231, 208, 84, 211, 155, 167, 35, 59, 42, 76, 216, 149, 73,
201, 78, 149, 184, 100, 96, 196, 189, 198, 188, 235, 195, 117, 129, 120,
129, 49, 25, 133, 113, 69, 221, 114, 70, 143, 99, 157, 108, 189, 140,
78, 6, 55, 65, 240, 255, 245, 184, 72, 90, 100, 116, 131, 39, 60,
234, 167, 33, 160, 88, 185, 200, 157, 159, 176, 127, 151, 138, 102, 168,
106, 170, 86, 82, 219, 189, 76, 33, 115, 197, 106, 96, 198, 136, 97,
141, 237, 151, 98, 137, 191, 185, 2, 57, 95, 142, 91, 255, 185, 97,
137, 76, 162, 94, 173, 131, 193, 161, 81, 106, 72, 135, 222, 234, 137,
66, 137, 106, 243, 210, 147, 95, 15, 137, 110, 85, 66, 16, 96, 167,
147, 150, 173, 203, 140, 118, 196, 84, 147, 160, 19, 95, 101, 123, 74,
132, 202, 82, 166, 12, 131, 166, 189, 170, 159, 85, 79, 66, 57, 152,
132, 203, 194, 0, 1, 56, 146, 180, 224, 156, 28, 83, 181, 79, 76,
80, 46, 160, 175, 59, 106, 43, 87, 75, 136, 85, 189, 46, 71, 200,
90
117, 102, 74, 135, 42, 98, 175, 206, 70, 73, 222, 197, 50, 24, 39, 49, 38,
105, 90, 47, 169, 40, 171, 215, 200, 73, 109, 141, 53, 85, 177, 164, 79,
208, 124, 89, 212, 18, 81, 145, 151, 164, 217, 153, 91, 154, 102, 102,
159, 75, 164, 152, 136, 51, 213, 219, 186, 116, 193, 224, 186, 36, 231,
208, 84, 211, 155, 167, 35, 59, 42, 76, 216, 149, 73, 201, 78, 149, 184,
100, 96, 196, 189, 198, 188, 235, 195, 117, 129, 120, 129, 49, 25, 133,
113, 69, 221, 114, 70, 143, 99, 157, 108, 189, 140, 78, 6, 55, 65, 240,
255, 245, 184, 72, 90, 100, 116, 131, 39, 60, 234, 167, 33, 160, 88, 185,
200, 157, 159, 176, 127, 151, 138, 102, 168, 106, 170, 86, 82, 219, 189,
76, 33, 115, 197, 106, 96, 198, 136, 97, 141, 237, 151, 98, 137, 191,
185, 2, 57, 95, 142, 91, 255, 185, 97, 137, 76, 162, 94, 173, 131, 193,
161, 81, 106, 72, 135, 222, 234, 137, 66, 137, 106, 243, 210, 147, 95,
15, 137, 110, 85, 66, 16, 96, 167, 147, 150, 173, 203, 140, 118, 196,
84, 147, 160, 19, 95, 101, 123, 74, 132, 202, 82, 166, 12, 131, 166,
189, 170, 159, 85, 79, 66, 57, 152, 132, 203, 194, 0, 1, 56, 146, 180,
224, 156, 28, 83, 181, 79, 76, 80, 46, 160, 175, 59, 106, 43, 87, 75,
136, 85, 189, 46, 71, 200, 90
};
uint8_t *src = const_cast<uint8_t*>(test_data);
ASM_REGISTER_STATE_CHECK(sixtap_predict_(&src[kSrcStride * 2 + 2 + 1],
kSrcStride, 2, 2, dst_, kDstStride));
ASM_REGISTER_STATE_CHECK(
sixtap_predict_(&src[kSrcStride * 2 + 2 + 1], kSrcStride,
2, 2, dst_, kDstStride));
for (int i = 0; i < height_; ++i) {
for (int i = 0; i < height_; ++i)
for (int j = 0; j < width_; ++j)
ASSERT_EQ(expected_dst[i * kDstStride + j], dst_[i * kDstStride + j])
<< "i==" << (i * width_ + j);
}
}
using libvpx_test::ACMRandom;
TEST_P(SixtapPredictTest, TestWithRandomData) {
ACMRandom rnd(ACMRandom::DeterministicSeed());
for (int i = 0; i < kSrcSize; ++i) src_[i] = rnd.Rand8();
for (int i = 0; i < kSrcSize; ++i)
src_[i] = rnd.Rand8();
// Run tests for all possible offsets.
for (int xoffset = 0; xoffset < 8; ++xoffset) {
@@ -169,63 +172,84 @@ TEST_P(SixtapPredictTest, TestWithRandomData) {
xoffset, yoffset, dst_c_, kDstStride);
// Run test.
ASM_REGISTER_STATE_CHECK(sixtap_predict_(&src_[kSrcStride * 2 + 2 + 1],
kSrcStride, xoffset, yoffset,
dst_, kDstStride));
ASM_REGISTER_STATE_CHECK(
sixtap_predict_(&src_[kSrcStride * 2 + 2 + 1], kSrcStride,
xoffset, yoffset, dst_, kDstStride));
for (int i = 0; i < height_; ++i) {
for (int i = 0; i < height_; ++i)
for (int j = 0; j < width_; ++j)
ASSERT_EQ(dst_c_[i * kDstStride + j], dst_[i * kDstStride + j])
<< "i==" << (i * width_ + j);
}
}
}
}
using std::tr1::make_tuple;
const SixtapPredictFunc sixtap_16x16_c = vp8_sixtap_predict16x16_c;
const SixtapPredictFunc sixtap_8x8_c = vp8_sixtap_predict8x8_c;
const SixtapPredictFunc sixtap_8x4_c = vp8_sixtap_predict8x4_c;
const SixtapPredictFunc sixtap_4x4_c = vp8_sixtap_predict4x4_c;
INSTANTIATE_TEST_CASE_P(
C, SixtapPredictTest,
::testing::Values(make_tuple(16, 16, &vp8_sixtap_predict16x16_c),
make_tuple(8, 8, &vp8_sixtap_predict8x8_c),
make_tuple(8, 4, &vp8_sixtap_predict8x4_c),
make_tuple(4, 4, &vp8_sixtap_predict4x4_c)));
C, SixtapPredictTest, ::testing::Values(
make_tuple(16, 16, sixtap_16x16_c),
make_tuple(8, 8, sixtap_8x8_c),
make_tuple(8, 4, sixtap_8x4_c),
make_tuple(4, 4, sixtap_4x4_c)));
#if HAVE_NEON
const SixtapPredictFunc sixtap_16x16_neon = vp8_sixtap_predict16x16_neon;
const SixtapPredictFunc sixtap_8x8_neon = vp8_sixtap_predict8x8_neon;
const SixtapPredictFunc sixtap_8x4_neon = vp8_sixtap_predict8x4_neon;
INSTANTIATE_TEST_CASE_P(
NEON, SixtapPredictTest,
::testing::Values(make_tuple(16, 16, &vp8_sixtap_predict16x16_neon),
make_tuple(8, 8, &vp8_sixtap_predict8x8_neon),
make_tuple(8, 4, &vp8_sixtap_predict8x4_neon)));
DISABLED_NEON, SixtapPredictTest, ::testing::Values(
make_tuple(16, 16, sixtap_16x16_neon),
make_tuple(8, 8, sixtap_8x8_neon),
make_tuple(8, 4, sixtap_8x4_neon)));
#endif
#if HAVE_MMX
const SixtapPredictFunc sixtap_16x16_mmx = vp8_sixtap_predict16x16_mmx;
const SixtapPredictFunc sixtap_8x8_mmx = vp8_sixtap_predict8x8_mmx;
const SixtapPredictFunc sixtap_8x4_mmx = vp8_sixtap_predict8x4_mmx;
const SixtapPredictFunc sixtap_4x4_mmx = vp8_sixtap_predict4x4_mmx;
INSTANTIATE_TEST_CASE_P(
MMX, SixtapPredictTest,
::testing::Values(make_tuple(16, 16, &vp8_sixtap_predict16x16_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)));
MMX, SixtapPredictTest, ::testing::Values(
make_tuple(16, 16, sixtap_16x16_mmx),
make_tuple(8, 8, sixtap_8x8_mmx),
make_tuple(8, 4, sixtap_8x4_mmx),
make_tuple(4, 4, sixtap_4x4_mmx)));
#endif
#if HAVE_SSE2
const SixtapPredictFunc sixtap_16x16_sse2 = vp8_sixtap_predict16x16_sse2;
const SixtapPredictFunc sixtap_8x8_sse2 = vp8_sixtap_predict8x8_sse2;
const SixtapPredictFunc sixtap_8x4_sse2 = vp8_sixtap_predict8x4_sse2;
INSTANTIATE_TEST_CASE_P(
SSE2, SixtapPredictTest,
::testing::Values(make_tuple(16, 16, &vp8_sixtap_predict16x16_sse2),
make_tuple(8, 8, &vp8_sixtap_predict8x8_sse2),
make_tuple(8, 4, &vp8_sixtap_predict8x4_sse2)));
SSE2, SixtapPredictTest, ::testing::Values(
make_tuple(16, 16, sixtap_16x16_sse2),
make_tuple(8, 8, sixtap_8x8_sse2),
make_tuple(8, 4, sixtap_8x4_sse2)));
#endif
#if HAVE_SSSE3
const SixtapPredictFunc sixtap_16x16_ssse3 = vp8_sixtap_predict16x16_ssse3;
const SixtapPredictFunc sixtap_8x8_ssse3 = vp8_sixtap_predict8x8_ssse3;
const SixtapPredictFunc sixtap_8x4_ssse3 = vp8_sixtap_predict8x4_ssse3;
const SixtapPredictFunc sixtap_4x4_ssse3 = vp8_sixtap_predict4x4_ssse3;
INSTANTIATE_TEST_CASE_P(
SSSE3, SixtapPredictTest,
::testing::Values(make_tuple(16, 16, &vp8_sixtap_predict16x16_ssse3),
make_tuple(8, 8, &vp8_sixtap_predict8x8_ssse3),
make_tuple(8, 4, &vp8_sixtap_predict8x4_ssse3),
make_tuple(4, 4, &vp8_sixtap_predict4x4_ssse3)));
SSSE3, SixtapPredictTest, ::testing::Values(
make_tuple(16, 16, sixtap_16x16_ssse3),
make_tuple(8, 8, sixtap_8x8_ssse3),
make_tuple(8, 4, sixtap_8x4_ssse3),
make_tuple(4, 4, sixtap_4x4_ssse3)));
#endif
#if HAVE_MSA
const SixtapPredictFunc sixtap_16x16_msa = vp8_sixtap_predict16x16_msa;
const SixtapPredictFunc sixtap_8x8_msa = vp8_sixtap_predict8x8_msa;
const SixtapPredictFunc sixtap_8x4_msa = vp8_sixtap_predict8x4_msa;
const SixtapPredictFunc sixtap_4x4_msa = vp8_sixtap_predict4x4_msa;
INSTANTIATE_TEST_CASE_P(
MSA, SixtapPredictTest,
::testing::Values(make_tuple(16, 16, &vp8_sixtap_predict16x16_msa),
make_tuple(8, 8, &vp8_sixtap_predict8x8_msa),
make_tuple(8, 4, &vp8_sixtap_predict8x4_msa),
make_tuple(4, 4, &vp8_sixtap_predict4x4_msa)));
MSA, SixtapPredictTest, ::testing::Values(
make_tuple(16, 16, sixtap_16x16_msa),
make_tuple(8, 8, sixtap_8x8_msa),
make_tuple(8, 4, sixtap_8x4_msa),
make_tuple(4, 4, sixtap_4x4_msa)));
#endif
} // namespace

View File

@@ -1,113 +0,0 @@
/*
* Copyright (c) 2016 The WebM project authors. All Rights Reserved.
*
* Use of this source code is governed by a BSD-style license
* that can be found in the LICENSE file in the root of the source
* tree. An additional intellectual property rights grant can be found
* in the file PATENTS. All contributing project authors may
* be found in the AUTHORS file in the root of the source tree.
*/
#include <cmath>
#include <cstdlib>
#include <string>
#include "third_party/googletest/src/include/gtest/gtest.h"
#include "./vpx_config.h"
#include "./vpx_dsp_rtcd.h"
#include "test/acm_random.h"
#include "test/clear_system_state.h"
#include "test/register_state_check.h"
#include "test/util.h"
#include "vpx_ports/mem.h"
using libvpx_test::ACMRandom;
namespace {
const int kNumIterations = 10000;
typedef uint64_t (*SSI16Func)(const int16_t *src, int stride, int size);
typedef std::tr1::tuple<SSI16Func, SSI16Func> SumSquaresParam;
class SumSquaresTest : public ::testing::TestWithParam<SumSquaresParam> {
public:
virtual ~SumSquaresTest() {}
virtual void SetUp() {
ref_func_ = GET_PARAM(0);
tst_func_ = GET_PARAM(1);
}
virtual void TearDown() { libvpx_test::ClearSystemState(); }
protected:
SSI16Func ref_func_;
SSI16Func tst_func_;
};
TEST_P(SumSquaresTest, OperationCheck) {
ACMRandom rnd(ACMRandom::DeterministicSeed());
DECLARE_ALIGNED(16, int16_t, src[256 * 256]);
const int msb = 11; // Up to 12 bit input
const int limit = 1 << (msb + 1);
for (int k = 0; k < kNumIterations; k++) {
const int size = 4 << rnd(6); // Up to 128x128
int stride = 4 << rnd(7); // Up to 256 stride
while (stride < size) { // Make sure it's valid
stride = 4 << rnd(7);
}
for (int i = 0; i < size; ++i) {
for (int j = 0; j < size; ++j) {
src[i * stride + j] = rnd(2) ? rnd(limit) : -rnd(limit);
}
}
const uint64_t res_ref = ref_func_(src, stride, size);
uint64_t res_tst;
ASM_REGISTER_STATE_CHECK(res_tst = tst_func_(src, stride, size));
ASSERT_EQ(res_ref, res_tst) << "Error: Sum Squares Test"
<< " C output does not match optimized output.";
}
}
TEST_P(SumSquaresTest, ExtremeValues) {
ACMRandom rnd(ACMRandom::DeterministicSeed());
DECLARE_ALIGNED(16, int16_t, src[256 * 256]);
const int msb = 11; // Up to 12 bit input
const int limit = 1 << (msb + 1);
for (int k = 0; k < kNumIterations; k++) {
const int size = 4 << rnd(6); // Up to 128x128
int stride = 4 << rnd(7); // Up to 256 stride
while (stride < size) { // Make sure it's valid
stride = 4 << rnd(7);
}
const int val = rnd(2) ? limit - 1 : -(limit - 1);
for (int i = 0; i < size; ++i) {
for (int j = 0; j < size; ++j) {
src[i * stride + j] = val;
}
}
const uint64_t res_ref = ref_func_(src, stride, size);
uint64_t res_tst;
ASM_REGISTER_STATE_CHECK(res_tst = tst_func_(src, stride, size));
ASSERT_EQ(res_ref, res_tst) << "Error: Sum Squares Test"
<< " C output does not match optimized output.";
}
}
using std::tr1::make_tuple;
#if HAVE_SSE2
INSTANTIATE_TEST_CASE_P(
SSE2, SumSquaresTest,
::testing::Values(make_tuple(&vpx_sum_squares_2d_i16_c,
&vpx_sum_squares_2d_i16_sse2)));
#endif // HAVE_SSE2
} // namespace

View File

@@ -16,28 +16,23 @@
namespace {
const int kTestMode = 0;
typedef std::tr1::tuple<libvpx_test::TestMode, int> SuperframeTestParam;
class SuperframeTest
: public ::libvpx_test::EncoderTest,
public ::libvpx_test::CodecTestWithParam<SuperframeTestParam> {
class SuperframeTest : public ::libvpx_test::EncoderTest,
public ::libvpx_test::CodecTestWithParam<libvpx_test::TestMode> {
protected:
SuperframeTest()
: EncoderTest(GET_PARAM(0)), modified_buf_(NULL), last_sf_pts_(0) {}
SuperframeTest() : EncoderTest(GET_PARAM(0)), modified_buf_(NULL),
last_sf_pts_(0) {}
virtual ~SuperframeTest() {}
virtual void SetUp() {
InitializeConfig();
const SuperframeTestParam input = GET_PARAM(1);
const libvpx_test::TestMode mode = std::tr1::get<kTestMode>(input);
SetMode(mode);
SetMode(GET_PARAM(1));
sf_count_ = 0;
sf_count_max_ = INT_MAX;
}
virtual void TearDown() { delete[] modified_buf_; }
virtual void TearDown() {
delete[] modified_buf_;
}
virtual void PreEncodeFrameHook(libvpx_test::VideoSource *video,
libvpx_test::Encoder *encoder) {
@@ -48,19 +43,23 @@ class SuperframeTest
virtual const vpx_codec_cx_pkt_t * MutateEncoderOutputHook(
const vpx_codec_cx_pkt_t *pkt) {
if (pkt->kind != VPX_CODEC_CX_FRAME_PKT) return pkt;
if (pkt->kind != VPX_CODEC_CX_FRAME_PKT)
return pkt;
const uint8_t *buffer = reinterpret_cast<uint8_t*>(pkt->data.frame.buf);
const uint8_t marker = buffer[pkt->data.frame.sz - 1];
const int frames = (marker & 0x7) + 1;
const int mag = ((marker >> 3) & 3) + 1;
const unsigned int index_sz = 2 + mag * frames;
if ((marker & 0xe0) == 0xc0 && pkt->data.frame.sz >= index_sz &&
if ((marker & 0xe0) == 0xc0 &&
pkt->data.frame.sz >= index_sz &&
buffer[pkt->data.frame.sz - index_sz] == marker) {
// frame is a superframe. strip off the index.
if (modified_buf_) delete[] modified_buf_;
if (modified_buf_)
delete[] modified_buf_;
modified_buf_ = new uint8_t[pkt->data.frame.sz - index_sz];
memcpy(modified_buf_, pkt->data.frame.buf, pkt->data.frame.sz - index_sz);
memcpy(modified_buf_, pkt->data.frame.buf,
pkt->data.frame.sz - index_sz);
modified_pkt_ = *pkt;
modified_pkt_.data.frame.buf = modified_buf_;
modified_pkt_.data.frame.sz -= index_sz;
@@ -71,8 +70,8 @@ class SuperframeTest
}
// Make sure we do a few frames after the last SF
abort_ |=
sf_count_ > sf_count_max_ && pkt->data.frame.pts - last_sf_pts_ >= 5;
abort_ |= sf_count_ > sf_count_max_ &&
pkt->data.frame.pts - last_sf_pts_ >= 5;
return pkt;
}
@@ -93,8 +92,9 @@ TEST_P(SuperframeTest, TestSuperframeIndexIsOptional) {
EXPECT_EQ(sf_count_, 1);
}
VP9_INSTANTIATE_TEST_CASE(
SuperframeTest,
::testing::Combine(::testing::Values(::libvpx_test::kTwoPassGood),
::testing::Values(0)));
VP9_INSTANTIATE_TEST_CASE(SuperframeTest, ::testing::Values(
::libvpx_test::kTwoPassGood));
VP10_INSTANTIATE_TEST_CASE(SuperframeTest, ::testing::Values(
::libvpx_test::kTwoPassGood));
} // namespace

View File

@@ -33,8 +33,10 @@ class SvcTest : public ::testing::Test {
static const uint32_t kHeight = 288;
SvcTest()
: codec_iface_(0), test_file_name_("hantro_collage_w352h288.yuv"),
codec_initialized_(false), decoder_(0) {
: codec_iface_(0),
test_file_name_("hantro_collage_w352h288.yuv"),
codec_initialized_(false),
decoder_(0) {
memset(&svc_, 0, sizeof(svc_));
memset(&codec_, 0, sizeof(codec_));
memset(&codec_enc_, 0, sizeof(codec_enc_));
@@ -111,9 +113,10 @@ class SvcTest : public ::testing::Test {
codec_enc_.g_pass = VPX_RC_FIRST_PASS;
InitializeEncoder();
libvpx_test::I420VideoSource video(
test_file_name_, codec_enc_.g_w, codec_enc_.g_h,
codec_enc_.g_timebase.den, codec_enc_.g_timebase.num, 0, 30);
libvpx_test::I420VideoSource video(test_file_name_,
codec_enc_.g_w, codec_enc_.g_h,
codec_enc_.g_timebase.den,
codec_enc_.g_timebase.num, 0, 30);
video.Begin();
for (int i = 0; i < n; ++i) {
@@ -125,8 +128,8 @@ class SvcTest : public ::testing::Test {
}
// Flush encoder and test EOS packet.
res = vpx_svc_encode(&svc_, &codec_, NULL, video.pts(), video.duration(),
VPX_DL_GOOD_QUALITY);
res = vpx_svc_encode(&svc_, &codec_, NULL, video.pts(),
video.duration(), VPX_DL_GOOD_QUALITY);
ASSERT_EQ(VPX_CODEC_OK, res);
GetStatsData(stats_buf);
@@ -160,8 +163,8 @@ class SvcTest : public ::testing::Test {
}
}
void Pass2EncodeNFrames(std::string *const stats_buf, const int n,
const int layers,
void Pass2EncodeNFrames(std::string *const stats_buf,
const int n, const int layers,
struct vpx_fixed_buf *const outputs) {
vpx_codec_err_t res;
size_t frame_received = 0;
@@ -179,9 +182,10 @@ class SvcTest : public ::testing::Test {
}
InitializeEncoder();
libvpx_test::I420VideoSource video(
test_file_name_, codec_enc_.g_w, codec_enc_.g_h,
codec_enc_.g_timebase.den, codec_enc_.g_timebase.num, 0, 30);
libvpx_test::I420VideoSource video(test_file_name_,
codec_enc_.g_w, codec_enc_.g_h,
codec_enc_.g_timebase.den,
codec_enc_.g_timebase.num, 0, 30);
video.Begin();
for (int i = 0; i < n; ++i) {
@@ -193,8 +197,8 @@ class SvcTest : public ::testing::Test {
}
// Flush encoder.
res = vpx_svc_encode(&svc_, &codec_, NULL, 0, video.duration(),
VPX_DL_GOOD_QUALITY);
res = vpx_svc_encode(&svc_, &codec_, NULL, 0,
video.duration(), VPX_DL_GOOD_QUALITY);
EXPECT_EQ(VPX_CODEC_OK, res);
StoreFrames(n, outputs, &frame_received);
@@ -213,8 +217,9 @@ class SvcTest : public ::testing::Test {
for (int i = 0; i < n; ++i) {
ASSERT_TRUE(inputs[i].buf != NULL);
ASSERT_GT(inputs[i].sz, 0U);
const vpx_codec_err_t res_dec = decoder_->DecodeFrame(
static_cast<const uint8_t *>(inputs[i].buf), inputs[i].sz);
const vpx_codec_err_t res_dec =
decoder_->DecodeFrame(static_cast<const uint8_t *>(inputs[i].buf),
inputs[i].sz);
ASSERT_EQ(VPX_CODEC_OK, res_dec) << decoder_->DecodeError();
++decoded_frames;
@@ -242,9 +247,10 @@ class SvcTest : public ::testing::Test {
ASSERT_TRUE(inputs[i].buf != NULL);
ASSERT_GT(inputs[i].sz, 0U);
vpx_codec_err_t res = vp9_parse_superframe_index(
static_cast<const uint8_t *>(inputs[i].buf), inputs[i].sz,
frame_sizes, &frame_count, NULL, NULL);
vpx_codec_err_t res =
vp9_parse_superframe_index(static_cast<const uint8_t*>(inputs[i].buf),
inputs[i].sz, frame_sizes, &frame_count,
NULL, NULL);
ASSERT_EQ(VPX_CODEC_OK, res);
if (frame_count == 0) {
@@ -258,15 +264,16 @@ class SvcTest : public ::testing::Test {
// Looking for a visible frame.
if (frame_data[0] & 0x02) {
++frames_found;
if (frames_found == remained_spatial_layers) break;
if (frames_found == remained_spatial_layers)
break;
}
frame_data += frame_sizes[frame];
}
ASSERT_LT(frame, frame_count)
<< "Couldn't find a visible frame. "
ASSERT_LT(frame, frame_count) << "Couldn't find a visible frame. "
<< "remained_spatial_layers: " << remained_spatial_layers
<< " super_frame: " << i;
if (frame == frame_count - 1) continue;
if (frame == frame_count - 1)
continue;
frame_data += frame_sizes[frame];
@@ -532,7 +539,8 @@ TEST_F(SvcTest, TwoPassEncode2SNRLayers) {
// Second pass encode
codec_enc_.g_pass = VPX_RC_LAST_PASS;
vpx_svc_set_options(&svc_, "auto-alt-refs=1,1 scale-factors=1/1,1/1");
vpx_svc_set_options(&svc_,
"auto-alt-refs=1,1 scale-factors=1/1,1/1");
vpx_fixed_buf outputs[20];
memset(&outputs[0], 0, sizeof(outputs));
Pass2EncodeNFrames(&stats_buf, 20, 2, &outputs[0]);
@@ -548,7 +556,8 @@ TEST_F(SvcTest, TwoPassEncode3SNRLayersDecode321Layers) {
// Second pass encode
codec_enc_.g_pass = VPX_RC_LAST_PASS;
vpx_svc_set_options(&svc_, "auto-alt-refs=1,1,1 scale-factors=1/1,1/1,1/1");
vpx_svc_set_options(&svc_,
"auto-alt-refs=1,1,1 scale-factors=1/1,1/1,1/1");
vpx_fixed_buf outputs[20];
memset(&outputs[0], 0, sizeof(outputs));
Pass2EncodeNFrames(&stats_buf, 20, 3, &outputs[0]);
@@ -563,7 +572,8 @@ TEST_F(SvcTest, TwoPassEncode3SNRLayersDecode321Layers) {
TEST_F(SvcTest, SetMultipleFrameContextsOption) {
svc_.spatial_layers = 5;
vpx_codec_err_t res = vpx_svc_set_options(&svc_, "multi-frame-contexts=1");
vpx_codec_err_t res =
vpx_svc_set_options(&svc_, "multi-frame-contexts=1");
EXPECT_EQ(VPX_CODEC_OK, res);
res = vpx_svc_init(&svc_, &codec_, vpx_codec_vp9_cx(), &codec_enc_);
EXPECT_EQ(VPX_CODEC_INVALID_PARAM, res);
@@ -616,8 +626,7 @@ TEST_F(SvcTest, TwoPassEncode2SNRLayersWithMultipleFrameContexts) {
// Second pass encode
codec_enc_.g_pass = VPX_RC_LAST_PASS;
codec_enc_.g_error_resilient = 0;
vpx_svc_set_options(&svc_,
"auto-alt-refs=1,1 scale-factors=1/1,1/1 "
vpx_svc_set_options(&svc_, "auto-alt-refs=1,1 scale-factors=1/1,1/1 "
"multi-frame-contexts=1");
vpx_fixed_buf outputs[10];
memset(&outputs[0], 0, sizeof(outputs));
@@ -636,8 +645,7 @@ TEST_F(SvcTest,
// Second pass encode
codec_enc_.g_pass = VPX_RC_LAST_PASS;
codec_enc_.g_error_resilient = 0;
vpx_svc_set_options(&svc_,
"auto-alt-refs=1,1,1 scale-factors=1/1,1/1,1/1 "
vpx_svc_set_options(&svc_, "auto-alt-refs=1,1,1 scale-factors=1/1,1/1,1/1 "
"multi-frame-contexts=1");
vpx_fixed_buf outputs[10];
memset(&outputs[0], 0, sizeof(outputs));
@@ -681,8 +689,7 @@ TEST_F(SvcTest, TwoPassEncode2TemporalLayersWithMultipleFrameContexts) {
codec_enc_.g_pass = VPX_RC_LAST_PASS;
svc_.temporal_layers = 2;
codec_enc_.g_error_resilient = 0;
vpx_svc_set_options(&svc_,
"auto-alt-refs=1 scale-factors=1/1 "
vpx_svc_set_options(&svc_, "auto-alt-refs=1 scale-factors=1/1 "
"multi-frame-contexts=1");
vpx_fixed_buf outputs[10];
memset(&outputs[0], 0, sizeof(outputs));
@@ -707,7 +714,8 @@ TEST_F(SvcTest, TwoPassEncode2TemporalLayersDecodeBaseLayer) {
Pass2EncodeNFrames(&stats_buf, 10, 1, &outputs[0]);
vpx_fixed_buf base_layer[5];
for (int i = 0; i < 5; ++i) base_layer[i] = outputs[i * 2];
for (int i = 0; i < 5; ++i)
base_layer[i] = outputs[i * 2];
DecodeNFrames(&base_layer[0], 5);
FreeBitstreamBuffers(&outputs[0], 10);
@@ -725,15 +733,15 @@ TEST_F(SvcTest,
codec_enc_.g_pass = VPX_RC_LAST_PASS;
svc_.temporal_layers = 2;
codec_enc_.g_error_resilient = 0;
vpx_svc_set_options(&svc_,
"auto-alt-refs=1 scale-factors=1/1 "
vpx_svc_set_options(&svc_, "auto-alt-refs=1 scale-factors=1/1 "
"multi-frame-contexts=1");
vpx_fixed_buf outputs[10];
memset(&outputs[0], 0, sizeof(outputs));
Pass2EncodeNFrames(&stats_buf, 10, 1, &outputs[0]);
vpx_fixed_buf base_layer[5];
for (int i = 0; i < 5; ++i) base_layer[i] = outputs[i * 2];
for (int i = 0; i < 5; ++i)
base_layer[i] = outputs[i * 2];
DecodeNFrames(&base_layer[0], 5);
FreeBitstreamBuffers(&outputs[0], 10);
@@ -761,7 +769,8 @@ TEST_F(SvcTest, TwoPassEncode2TemporalLayersWithTiles) {
FreeBitstreamBuffers(&outputs[0], 10);
}
TEST_F(SvcTest, TwoPassEncode2TemporalLayersWithMultipleFrameContextsAndTiles) {
TEST_F(SvcTest,
TwoPassEncode2TemporalLayersWithMultipleFrameContextsAndTiles) {
// First pass encode
std::string stats_buf;
vpx_svc_set_options(&svc_, "scale-factors=1/1");
@@ -776,8 +785,7 @@ TEST_F(SvcTest, TwoPassEncode2TemporalLayersWithMultipleFrameContextsAndTiles) {
codec_enc_.g_h = 144;
tile_columns_ = 1;
tile_rows_ = 1;
vpx_svc_set_options(&svc_,
"auto-alt-refs=1 scale-factors=1/1 "
vpx_svc_set_options(&svc_, "auto-alt-refs=1 scale-factors=1/1 "
"multi-frame-contexts=1");
vpx_fixed_buf outputs[10];
memset(&outputs[0], 0, sizeof(outputs));

View File

@@ -18,7 +18,6 @@ LIBVPX_TEST_DATA-$(CONFIG_ENCODERS) += park_joy_90p_8_422.y4m
LIBVPX_TEST_DATA-$(CONFIG_ENCODERS) += park_joy_90p_8_444.y4m
LIBVPX_TEST_DATA-$(CONFIG_ENCODERS) += park_joy_90p_8_440.yuv
LIBVPX_TEST_DATA-$(CONFIG_VP9_ENCODER) += desktop_credits.y4m
LIBVPX_TEST_DATA-$(CONFIG_VP9_ENCODER) += niklas_1280_720_30.y4m
LIBVPX_TEST_DATA-$(CONFIG_VP9_ENCODER) += rush_hour_444.y4m
LIBVPX_TEST_DATA-$(CONFIG_VP9_ENCODER) += screendata.y4m
@@ -418,18 +417,6 @@ LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-02-size-66x64.webm
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-02-size-66x64.webm.md5
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-02-size-66x66.webm
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-02-size-66x66.webm.md5
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-02-size-130x132.webm
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-02-size-130x132.webm.md5
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-02-size-132x130.webm
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-02-size-132x130.webm.md5
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-02-size-132x132.webm
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-02-size-132x132.webm.md5
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-02-size-178x180.webm
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-02-size-178x180.webm.md5
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-02-size-180x178.webm
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-02-size-180x178.webm.md5
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-02-size-180x180.webm
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-02-size-180x180.webm.md5
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-02-size-lf-1920x1080.webm
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-02-size-lf-1920x1080.webm.md5
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-03-deltaq.webm
@@ -562,8 +549,6 @@ LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-03-size-226x224.webm
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-03-size-226x224.webm.md5
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-03-size-226x226.webm
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-03-size-226x226.webm.md5
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-03-size-352x288.webm
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-03-size-352x288.webm.md5
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-05-resize.ivf
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-05-resize.ivf.md5
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-06-bilinear.webm
@@ -656,34 +641,6 @@ LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-14-resize-fp-tiles-8-2.webm
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-14-resize-fp-tiles-8-2.webm.md5
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-14-resize-fp-tiles-8-4.webm
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-14-resize-fp-tiles-8-4.webm.md5
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-14-resize-10frames-fp-tiles-1-2-4-8.webm
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-14-resize-10frames-fp-tiles-1-2-4-8.webm.md5
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-14-resize-10frames-fp-tiles-1-2.webm
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-14-resize-10frames-fp-tiles-1-2.webm.md5
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-14-resize-10frames-fp-tiles-1-4.webm
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-14-resize-10frames-fp-tiles-1-4.webm.md5
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-14-resize-10frames-fp-tiles-1-8.webm
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-14-resize-10frames-fp-tiles-1-8.webm.md5
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-14-resize-10frames-fp-tiles-2-1.webm
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-14-resize-10frames-fp-tiles-2-1.webm.md5
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-14-resize-10frames-fp-tiles-2-4.webm
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-14-resize-10frames-fp-tiles-2-4.webm.md5
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-14-resize-10frames-fp-tiles-2-8.webm
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-14-resize-10frames-fp-tiles-2-8.webm.md5
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-14-resize-10frames-fp-tiles-4-1.webm
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-14-resize-10frames-fp-tiles-4-1.webm.md5
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-14-resize-10frames-fp-tiles-4-2.webm
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-14-resize-10frames-fp-tiles-4-2.webm.md5
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-14-resize-10frames-fp-tiles-4-8.webm
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-14-resize-10frames-fp-tiles-4-8.webm.md5
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-14-resize-10frames-fp-tiles-8-1.webm
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-14-resize-10frames-fp-tiles-8-1.webm.md5
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-14-resize-10frames-fp-tiles-8-2.webm
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-14-resize-10frames-fp-tiles-8-2.webm.md5
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-14-resize-10frames-fp-tiles-8-4-2-1.webm
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-14-resize-10frames-fp-tiles-8-4-2-1.webm.md5
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-14-resize-10frames-fp-tiles-8-4.webm
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-14-resize-10frames-fp-tiles-8-4.webm.md5
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-15-segkey.webm
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-15-segkey.webm.md5
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-15-segkey_adpq.webm
@@ -742,8 +699,6 @@ LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += invalid-vp90-2-00-quantizer-11.webm.iv
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += invalid-vp90-2-00-quantizer-11.webm.ivf.s52984_r01-05_b6-.ivf.res
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += invalid-vp90-2-00-quantizer-11.webm.ivf.s52984_r01-05_b6-z.ivf
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += invalid-vp90-2-00-quantizer-11.webm.ivf.s52984_r01-05_b6-z.ivf.res
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += invalid-vp90-2-00-quantizer-63.ivf.kf_65527x61446.ivf
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += invalid-vp90-2-00-quantizer-63.ivf.kf_65527x61446.ivf.res
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += invalid-vp90-2-03-size-202x210.webm.ivf.s113306_r01-05_b6-.ivf
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += invalid-vp90-2-03-size-202x210.webm.ivf.s113306_r01-05_b6-.ivf.res
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += invalid-vp90-2-03-size-224x196.webm.ivf.s44156_r01-05_b6-.ivf
@@ -813,53 +768,3 @@ endif # CONFIG_ENCODE_PERF_TESTS
# sort and remove duplicates
LIBVPX_TEST_DATA-yes := $(sort $(LIBVPX_TEST_DATA-yes))
# VP9 dynamic resizing test (decoder)
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-21-resize_inter_320x180_5_1-2.webm
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-21-resize_inter_320x180_5_1-2.webm.md5
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-21-resize_inter_320x180_5_3-4.webm
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-21-resize_inter_320x180_5_3-4.webm.md5
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-21-resize_inter_320x180_7_1-2.webm
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-21-resize_inter_320x180_7_1-2.webm.md5
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-21-resize_inter_320x180_7_3-4.webm
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-21-resize_inter_320x180_7_3-4.webm.md5
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-21-resize_inter_320x240_5_1-2.webm
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-21-resize_inter_320x240_5_1-2.webm.md5
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-21-resize_inter_320x240_5_3-4.webm
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-21-resize_inter_320x240_5_3-4.webm.md5
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-21-resize_inter_320x240_7_1-2.webm
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-21-resize_inter_320x240_7_1-2.webm.md5
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-21-resize_inter_320x240_7_3-4.webm
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-21-resize_inter_320x240_7_3-4.webm.md5
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-21-resize_inter_640x360_5_1-2.webm
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-21-resize_inter_640x360_5_1-2.webm.md5
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-21-resize_inter_640x360_5_3-4.webm
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-21-resize_inter_640x360_5_3-4.webm.md5
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-21-resize_inter_640x360_7_1-2.webm
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-21-resize_inter_640x360_7_1-2.webm.md5
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-21-resize_inter_640x360_7_3-4.webm
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-21-resize_inter_640x360_7_3-4.webm.md5
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-21-resize_inter_640x480_5_1-2.webm
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-21-resize_inter_640x480_5_1-2.webm.md5
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-21-resize_inter_640x480_5_3-4.webm
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-21-resize_inter_640x480_5_3-4.webm.md5
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-21-resize_inter_640x480_7_1-2.webm
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-21-resize_inter_640x480_7_1-2.webm.md5
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-21-resize_inter_640x480_7_3-4.webm
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-21-resize_inter_640x480_7_3-4.webm.md5
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-21-resize_inter_1280x720_5_1-2.webm
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-21-resize_inter_1280x720_5_1-2.webm.md5
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-21-resize_inter_1280x720_5_3-4.webm
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-21-resize_inter_1280x720_5_3-4.webm.md5
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-21-resize_inter_1280x720_7_1-2.webm
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-21-resize_inter_1280x720_7_1-2.webm.md5
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-21-resize_inter_1280x720_7_3-4.webm
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-21-resize_inter_1280x720_7_3-4.webm.md5
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-21-resize_inter_1920x1080_5_1-2.webm
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-21-resize_inter_1920x1080_5_1-2.webm.md5
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-21-resize_inter_1920x1080_5_3-4.webm
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-21-resize_inter_1920x1080_5_3-4.webm.md5
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-21-resize_inter_1920x1080_7_1-2.webm
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.md5

View File

@@ -550,8 +550,6 @@ d17bc08eedfc60c4c23d576a6c964a21bf854d1f *vp90-2-03-size-226x202.webm
83c6d8f2969b759e10e5c6542baca1265c874c29 *vp90-2-03-size-226x224.webm.md5
fe0af2ee47b1e5f6a66db369e2d7e9d870b38dce *vp90-2-03-size-226x226.webm
94ad19b8b699cea105e2ff18f0df2afd7242bcf7 *vp90-2-03-size-226x226.webm.md5
52bc1dfd3a97b24d922eb8a31d07527891561f2a *vp90-2-03-size-352x288.webm
3084d6d0a1eec22e85a394422fbc8faae58930a5 *vp90-2-03-size-352x288.webm.md5
b6524e4084d15b5d0caaa3d3d1368db30cbee69c *vp90-2-03-deltaq.webm
65f45ec9a55537aac76104818278e0978f94a678 *vp90-2-03-deltaq.webm.md5
4dbb87494c7f565ffc266c98d17d0d8c7a5c5aba *vp90-2-05-resize.ivf
@@ -745,94 +743,3 @@ d06285d109ecbaef63b0cbcc44d70a129186f51c *invalid-vp90-2-03-size-224x196.webm.iv
e60d859b0ef2b331b21740cf6cb83fabe469b079 *invalid-vp90-2-03-size-202x210.webm.ivf.s113306_r01-05_b6-.ivf
0ae808dca4d3c1152a9576e14830b6faa39f1b4a *invalid-vp90-2-03-size-202x210.webm.ivf.s113306_r01-05_b6-.ivf.res
9cfc855459e7549fd015c79e8eca512b2f2cb7e3 *niklas_1280_720_30.y4m
5b5763b388b1b52a81bb82b39f7ec25c4bd3d0e1 *desktop_credits.y4m
85771f6ab44e4a0226e206c0cde8351dd5918953 *vp90-2-02-size-130x132.webm
512dad5eabbed37b4bbbc64ce153f1a5484427b8 *vp90-2-02-size-130x132.webm.md5
01f7127d40360289db63b27f61cb9afcda350e95 *vp90-2-02-size-132x130.webm
4a94275328ae076cf60f966c097a8721010fbf5a *vp90-2-02-size-132x130.webm.md5
f41c0400b5716b4b70552c40dd03d44be131e1cc *vp90-2-02-size-132x132.webm
1a69e989f697e424bfe3e3e8a77bb0c0992c8e47 *vp90-2-02-size-132x132.webm.md5
94a5cbfacacba100e0c5f7861c72a1b417feca0f *vp90-2-02-size-178x180.webm
dedfecf1d784bcf70629592fa5e6f01d5441ccc9 *vp90-2-02-size-178x180.webm.md5
4828b62478c04014bba3095a83106911a71cf387 *vp90-2-02-size-180x178.webm
423da2b861050c969d78ed8e8f8f14045d1d8199 *vp90-2-02-size-180x178.webm.md5
338f7c9282f43e29940f5391118aadd17e4f9234 *vp90-2-02-size-180x180.webm
6c2ef013392310778dca5dd5351160eca66b0a60 *vp90-2-02-size-180x180.webm.md5
679fa7d6807e936ff937d7b282e7dbd8ac76447e *vp90-2-14-resize-10frames-fp-tiles-1-2-4-8.webm
fc7267ab8fc2bf5d6c234e34ee6c078a967b4888 *vp90-2-14-resize-10frames-fp-tiles-1-2-4-8.webm.md5
9d33a137c819792209c5ce4e4e1ee5da73d574fe *vp90-2-14-resize-10frames-fp-tiles-1-2.webm
0c78a154956a8605d050bdd75e0dcc4d39c040a6 *vp90-2-14-resize-10frames-fp-tiles-1-2.webm.md5
d6a8d8c57f66a91d23e8e7df480f9ae841e56c37 *vp90-2-14-resize-10frames-fp-tiles-1-4.webm
e9b4e8c7b33b5fda745d340c3f47e6623ae40cf2 *vp90-2-14-resize-10frames-fp-tiles-1-4.webm.md5
aa6fe043a0c4a42b49c87ebbe812d4afd9945bec *vp90-2-14-resize-10frames-fp-tiles-1-8.webm
028520578994c2d013d4c0129033d4f2ff31bbe0 *vp90-2-14-resize-10frames-fp-tiles-1-8.webm.md5
d1d5463c9ea7b5cc5f609ddedccddf656f348d1a *vp90-2-14-resize-10frames-fp-tiles-2-1.webm
92d5872f5bdffbed721703b7e959b4f885e3d77a *vp90-2-14-resize-10frames-fp-tiles-2-1.webm.md5
677cb29de1215d97346015af5807a9b1faad54cf *vp90-2-14-resize-10frames-fp-tiles-2-4.webm
a5db19f977094ec3fd60b4f7671b3e6740225e12 *vp90-2-14-resize-10frames-fp-tiles-2-4.webm.md5
cdd3c52ba21067efdbb2de917fe2a965bf27332e *vp90-2-14-resize-10frames-fp-tiles-2-8.webm
db17ec5d894ea8b8d0b7f32206d0dd3d46dcfa6d *vp90-2-14-resize-10frames-fp-tiles-2-8.webm.md5
0f6093c472125d05b764d7d1965c1d56771c0ea2 *vp90-2-14-resize-10frames-fp-tiles-4-1.webm
bc7c79e1bee07926dd970462ce6f64fc30eec3e1 *vp90-2-14-resize-10frames-fp-tiles-4-1.webm.md5
c5142e2bff4091338196c8ea8bc9266e64f548bc *vp90-2-14-resize-10frames-fp-tiles-4-2.webm
22aa3dd430b69fd3d92f6561bac86deeed90486d *vp90-2-14-resize-10frames-fp-tiles-4-2.webm.md5
ede8b1466d2f26e1b1bd9602addb9cd1017e1d8c *vp90-2-14-resize-10frames-fp-tiles-4-8.webm
508d5ebb9c0eac2a4100281a3ee052ec2fc19217 *vp90-2-14-resize-10frames-fp-tiles-4-8.webm.md5
2b292e3392854cd1d76ae597a6f53656cf741cfa *vp90-2-14-resize-10frames-fp-tiles-8-1.webm
1c24e54fa19e94e1722f24676404444e941c3d31 *vp90-2-14-resize-10frames-fp-tiles-8-1.webm.md5
61beda21064e09634564caa6697ab90bd53c9af7 *vp90-2-14-resize-10frames-fp-tiles-8-2.webm
9c0657b4d9e1d0e4c9d28a90e5a8630a65519124 *vp90-2-14-resize-10frames-fp-tiles-8-2.webm.md5
1758c50a11a7c92522749b4a251664705f1f0d4b *vp90-2-14-resize-10frames-fp-tiles-8-4-2-1.webm
4f454a06750614314ae15a44087b79016fe2db97 *vp90-2-14-resize-10frames-fp-tiles-8-4-2-1.webm.md5
3920c95ba94f1f048a731d9d9b416043b44aa4bd *vp90-2-14-resize-10frames-fp-tiles-8-4.webm
4eb347a0456d2c49a1e1d8de5aa1c51acc39887e *vp90-2-14-resize-10frames-fp-tiles-8-4.webm.md5
4b95a74c032a473b6683d7ad5754db1b0ec378e9 *vp90-2-21-resize_inter_1280x720_5_1-2.webm
a7826dd386bedfe69d02736969bfb47fb6a40a5e *vp90-2-21-resize_inter_1280x720_5_1-2.webm.md5
5cfff79e82c4d69964ccb8e75b4f0c53b9295167 *vp90-2-21-resize_inter_1280x720_5_3-4.webm
a18f57db4a25e1f543a99f2ceb182e00db0ee22f *vp90-2-21-resize_inter_1280x720_5_3-4.webm.md5
d26db0811bf30eb4131d928669713e2485f8e833 *vp90-2-21-resize_inter_1280x720_7_1-2.webm
fd6f9f332cd5bea4c0f0d57be4297bea493cc5a1 *vp90-2-21-resize_inter_1280x720_7_1-2.webm.md5
5c7d73d4d268e2ba9593b31cb091fd339505c7fd *vp90-2-21-resize_inter_1280x720_7_3-4.webm
7bbb949cabc1e70dadcc74582739f63b833034e0 *vp90-2-21-resize_inter_1280x720_7_3-4.webm.md5
f2d2a41a60eb894aff0c5854afca15931f1445a8 *vp90-2-21-resize_inter_1920x1080_5_1-2.webm
66d7789992613ac9d678ff905ff1059daa1b89e4 *vp90-2-21-resize_inter_1920x1080_5_1-2.webm.md5
764edb75fe7dd64e73a1b4f3b4b2b1bf237a4dea *vp90-2-21-resize_inter_1920x1080_5_3-4.webm
f78bea1075983fd990e7f25d4f31438f9b5efa34 *vp90-2-21-resize_inter_1920x1080_5_3-4.webm.md5
96496f2ade764a5de9f0c27917c7df1f120fb2ef *vp90-2-21-resize_inter_1920x1080_7_1-2.webm
2632b635135ed5ecd67fd22dec7990d29c4f4cb5 *vp90-2-21-resize_inter_1920x1080_7_1-2.webm.md5
74889ea42001bf41428cb742ca74e65129c886dc *vp90-2-21-resize_inter_1920x1080_7_3-4.webm
d2cf3b25956415bb579d368e7098097e482dd73a *vp90-2-21-resize_inter_1920x1080_7_3-4.webm.md5
4658986a8ce36ebfcc80a1903e446eaab3985336 *vp90-2-21-resize_inter_320x180_5_1-2.webm
8a3d8cf325109ffa913cc9426c32eea8c202a09a *vp90-2-21-resize_inter_320x180_5_1-2.webm.md5
16303aa45176520ee42c2c425247aadc1506b881 *vp90-2-21-resize_inter_320x180_5_3-4.webm
41cab1ddf7715b680a4dbce42faa9bcd72af4e5c *vp90-2-21-resize_inter_320x180_5_3-4.webm.md5
56648adcee66dd0e5cb6ac947f5ee1b9cc8ba129 *vp90-2-21-resize_inter_320x180_7_1-2.webm
70047377787003cc03dda7b2394e6d7eaa666d9e *vp90-2-21-resize_inter_320x180_7_1-2.webm.md5
d2ff99165488499cc55f75929f1ce5ca9c9e359b *vp90-2-21-resize_inter_320x180_7_3-4.webm
e69019e378114a4643db283b66d1a7e304761a56 *vp90-2-21-resize_inter_320x180_7_3-4.webm.md5
4834d129bed0f4289d3a88f2ae3a1736f77621b0 *vp90-2-21-resize_inter_320x240_5_1-2.webm
a75653c53d22b623c1927fc0088da21dafef21f4 *vp90-2-21-resize_inter_320x240_5_1-2.webm.md5
19818e1b7fd1c1e63d8873c31b0babe29dd33ba6 *vp90-2-21-resize_inter_320x240_5_3-4.webm
8d89814ff469a186312111651b16601dfbce4336 *vp90-2-21-resize_inter_320x240_5_3-4.webm.md5
ac8057bae52498f324ce92a074d5f8207cc4a4a7 *vp90-2-21-resize_inter_320x240_7_1-2.webm
2643440898c83c08cc47bc744245af696b877c24 *vp90-2-21-resize_inter_320x240_7_1-2.webm.md5
cf4a4cd38ac8b18c42d8c25a3daafdb39132256b *vp90-2-21-resize_inter_320x240_7_3-4.webm
70ba8ec9120b26e9b0ffa2c79b432f16cbcb50ec *vp90-2-21-resize_inter_320x240_7_3-4.webm.md5
669f10409fe1c4a054010162ca47773ea1fdbead *vp90-2-21-resize_inter_640x360_5_1-2.webm
6355a04249004a35fb386dd1024214234f044383 *vp90-2-21-resize_inter_640x360_5_1-2.webm.md5
c23763b950b8247c1775d1f8158d93716197676c *vp90-2-21-resize_inter_640x360_5_3-4.webm
59e6fc381e3ec3b7bdaac586334e0bc944d18fb6 *vp90-2-21-resize_inter_640x360_5_3-4.webm.md5
71b45cbfdd068baa1f679a69e5e6f421d256a85f *vp90-2-21-resize_inter_640x360_7_1-2.webm
1416fc761b690c54a955c4cf017fa078520e8c18 *vp90-2-21-resize_inter_640x360_7_1-2.webm.md5
6c409903279448a697e4db63bab1061784bcd8d2 *vp90-2-21-resize_inter_640x360_7_3-4.webm
60de1299793433a630b71130cf76c9f5965758e2 *vp90-2-21-resize_inter_640x360_7_3-4.webm.md5
852b597b8af096d90c80bf0ed6ed3b336b851f19 *vp90-2-21-resize_inter_640x480_5_1-2.webm
f6856f19236ee46ed462bd0a2e7e72b9c3b9cea6 *vp90-2-21-resize_inter_640x480_5_1-2.webm.md5
792a16c6f60043bd8dceb515f0b95b8891647858 *vp90-2-21-resize_inter_640x480_5_3-4.webm
68ffe59877e9a7863805e1c0a3ce18ce037d7c9d *vp90-2-21-resize_inter_640x480_5_3-4.webm.md5
61e044c4759972a35ea3db8c1478a988910a4ef4 *vp90-2-21-resize_inter_640x480_7_1-2.webm
7739bfca167b1b43fea72f807f01e097b7cb98d8 *vp90-2-21-resize_inter_640x480_7_1-2.webm.md5
7291af354b4418917eee00e3a7e366086a0b7a10 *vp90-2-21-resize_inter_640x480_7_3-4.webm
4a18b09ccb36564193f0215f599d745d95bb558c *vp90-2-21-resize_inter_640x480_7_3-4.webm.md5
a000d568431d07379dd5a8ec066061c07e560b47 invalid-vp90-2-00-quantizer-63.ivf.kf_65527x61446.ivf
1e75aad3433c5c21c194a7b53fc393970f0a8d7f invalid-vp90-2-00-quantizer-63.ivf.kf_65527x61446.ivf.res

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