This commit is contained in:
Anthony Minessale 2019-09-11 15:51:47 +00:00 committed by Andrey Volk
parent 34fcadbd53
commit ceb051af4e
821 changed files with 89961 additions and 48650 deletions

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

94
libs/libvpx/configure vendored
View File

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

View File

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

View File

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

View File

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

View File

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

File diff suppressed because it is too large Load Diff

View File

@ -68,128 +68,6 @@ void usage_exit() {
exit(EXIT_FAILURE); 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, static void testing_decode(vpx_codec_ctx_t *encoder, vpx_codec_ctx_t *decoder,
unsigned int frame_out, int *mismatch_seen) { unsigned int frame_out, int *mismatch_seen) {
vpx_image_t enc_img, dec_img; vpx_image_t enc_img, dec_img;

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

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

@ -0,0 +1,38 @@
/*
* Copyright (c) 2018 The WebM project authors. All Rights Reserved.
*
* Use of this source code is governed by a BSD-style license
* that can be found in the LICENSE file in the root of the source
* tree. An additional intellectual property rights grant can be found
* in the file PATENTS. All contributing project authors may
* be found in the AUTHORS file in the root of the source tree.
*/
#include <stdio.h>
#include <algorithm>
#include "test/bench.h"
#include "vpx_ports/vpx_timer.h"
void AbstractBench::RunNTimes(int n) {
for (int r = 0; r < VPX_BENCH_ROBUST_ITER; r++) {
vpx_usec_timer timer;
vpx_usec_timer_start(&timer);
for (int j = 0; j < n; ++j) {
Run();
}
vpx_usec_timer_mark(&timer);
times_[r] = static_cast<int>(vpx_usec_timer_elapsed(&timer));
}
}
void AbstractBench::PrintMedian(const char *title) {
std::sort(times_, times_ + VPX_BENCH_ROBUST_ITER);
const int med = times_[VPX_BENCH_ROBUST_ITER >> 1];
int sad = 0;
for (int t = 0; t < VPX_BENCH_ROBUST_ITER; t++) {
sad += abs(times_[t] - med);
}
printf("[%10s] %s %.1f ms ( ±%.1f ms )\n", "BENCH ", title, med / 1000.0,
sad / (VPX_BENCH_ROBUST_ITER * 1000.0));
}

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

@ -0,0 +1,30 @@
/*
* Copyright (c) 2018 The WebM project authors. All Rights Reserved.
*
* Use of this source code is governed by a BSD-style license
* that can be found in the LICENSE file in the root of the source
* tree. An additional intellectual property rights grant can be found
* in the file PATENTS. All contributing project authors may
* be found in the AUTHORS file in the root of the source tree.
*/
#ifndef VPX_TEST_BENCH_H_
#define VPX_TEST_BENCH_H_
// Number of iterations used to compute median run time.
#define VPX_BENCH_ROBUST_ITER 15
class AbstractBench {
public:
void RunNTimes(int n);
void PrintMedian(const char *title);
protected:
// Implement this method and put the code to benchmark in it.
virtual void Run() = 0;
private:
int times_[VPX_BENCH_ROBUST_ITER];
};
#endif // VPX_TEST_BENCH_H_

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

File diff suppressed because it is too large Load Diff

View File

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

View File

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

View File

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

File diff suppressed because it is too large Load Diff

View File

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

View File

@ -0,0 +1,103 @@
/*
* Copyright (c) 2018 The WebM project authors. All Rights Reserved.
*
* Use of this source code is governed by a BSD-style license
* that can be found in the LICENSE file in the root of the source
* tree. An additional intellectual property rights grant can be found
* in the file PATENTS. All contributing project authors may
* be found in the AUTHORS file in the root of the source tree.
*/
#include <tuple>
#include "third_party/googletest/src/include/gtest/gtest.h"
#include "test/codec_factory.h"
#include "test/encode_test_driver.h"
#include "test/util.h"
#include "test/i420_video_source.h"
#include "vpx_mem/vpx_mem.h"
namespace {
class DecodeCorruptedFrameTest
: public ::libvpx_test::EncoderTest,
public ::testing::TestWithParam<
std::tuple<const libvpx_test::CodecFactory *> > {
public:
DecodeCorruptedFrameTest() : EncoderTest(GET_PARAM(0)) {}
protected:
virtual ~DecodeCorruptedFrameTest() {}
virtual void SetUp() {
InitializeConfig();
SetMode(::libvpx_test::kRealTime);
cfg_.g_lag_in_frames = 0;
cfg_.rc_end_usage = VPX_CBR;
cfg_.rc_buf_sz = 1000;
cfg_.rc_buf_initial_sz = 500;
cfg_.rc_buf_optimal_sz = 600;
// Set small key frame distance such that we insert more key frames.
cfg_.kf_max_dist = 3;
dec_cfg_.threads = 1;
}
virtual void PreEncodeFrameHook(::libvpx_test::VideoSource *video,
::libvpx_test::Encoder *encoder) {
if (video->frame() == 0) encoder->Control(VP8E_SET_CPUUSED, 7);
}
virtual void MismatchHook(const vpx_image_t * /*img1*/,
const vpx_image_t * /*img2*/) {}
virtual const vpx_codec_cx_pkt_t *MutateEncoderOutputHook(
const vpx_codec_cx_pkt_t *pkt) {
// Don't edit frame packet on key frame.
if (pkt->data.frame.flags & VPX_FRAME_IS_KEY) return pkt;
if (pkt->kind != VPX_CODEC_CX_FRAME_PKT) return pkt;
memcpy(&modified_pkt_, pkt, sizeof(*pkt));
// Halve the size so it's corrupted to decoder.
modified_pkt_.data.frame.sz = modified_pkt_.data.frame.sz / 2;
return &modified_pkt_;
}
virtual bool HandleDecodeResult(const vpx_codec_err_t res_dec,
const libvpx_test::VideoSource & /*video*/,
libvpx_test::Decoder *decoder) {
EXPECT_NE(res_dec, VPX_CODEC_MEM_ERROR) << decoder->DecodeError();
return VPX_CODEC_MEM_ERROR != res_dec;
}
vpx_codec_cx_pkt_t modified_pkt_;
};
TEST_P(DecodeCorruptedFrameTest, DecodeCorruptedFrame) {
cfg_.rc_target_bitrate = 200;
cfg_.g_error_resilient = 0;
::libvpx_test::I420VideoSource video("hantro_collage_w352h288.yuv", 352, 288,
30, 1, 0, 300);
ASSERT_NO_FATAL_FAILURE(RunLoop(&video));
}
#if CONFIG_VP9
INSTANTIATE_TEST_CASE_P(
VP9, DecodeCorruptedFrameTest,
::testing::Values(
static_cast<const libvpx_test::CodecFactory *>(&libvpx_test::kVP9)));
#endif // CONFIG_VP9
#if CONFIG_VP8
INSTANTIATE_TEST_CASE_P(
VP8, DecodeCorruptedFrameTest,
::testing::Values(
static_cast<const libvpx_test::CodecFactory *>(&libvpx_test::kVP8)));
#endif // CONFIG_VP8
} // namespace

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

File diff suppressed because it is too large Load Diff

View File

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

View File

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

View File

@ -0,0 +1,67 @@
/*
* Copyright (c) 2018 The WebM project authors. All Rights Reserved.
*
* Use of this source code is governed by a BSD-style license
* that can be found in the LICENSE file in the root of the source
* tree. An additional intellectual property rights grant can be found
* in the file PATENTS. All contributing project authors may
* be found in the AUTHORS file in the root of the source tree.
*/
#ifndef VPX_TEST_SVC_TEST_H_
#define VPX_TEST_SVC_TEST_H_
#include "./vpx_config.h"
#include "third_party/googletest/src/include/gtest/gtest.h"
#include "test/codec_factory.h"
#include "test/encode_test_driver.h"
#include "test/i420_video_source.h"
#include "test/util.h"
#include "test/y4m_video_source.h"
#include "vpx/vpx_codec.h"
#include "vpx_ports/bitops.h"
namespace svc_test {
class OnePassCbrSvc : public ::libvpx_test::EncoderTest {
public:
explicit OnePassCbrSvc(const ::libvpx_test::CodecFactory *codec)
: EncoderTest(codec), base_speed_setting_(0), speed_setting_(0),
superframe_count_(0), temporal_layer_id_(0), number_temporal_layers_(0),
number_spatial_layers_(0) {
memset(&svc_params_, 0, sizeof(svc_params_));
memset(bits_in_buffer_model_, 0,
sizeof(bits_in_buffer_model_[0]) * VPX_MAX_LAYERS);
memset(layer_target_avg_bandwidth_, 0,
sizeof(layer_target_avg_bandwidth_[0]) * VPX_MAX_LAYERS);
}
protected:
virtual ~OnePassCbrSvc() {}
virtual void SetConfig(const int num_temporal_layer) = 0;
virtual void SetSvcConfig(const int num_spatial_layer,
const int num_temporal_layer);
virtual void PreEncodeFrameHookSetup(::libvpx_test::VideoSource *video,
::libvpx_test::Encoder *encoder);
virtual void PostEncodeFrameHook(::libvpx_test::Encoder *encoder);
virtual void AssignLayerBitrates();
virtual void MismatchHook(const vpx_image_t *, const vpx_image_t *) {}
vpx_svc_extra_cfg_t svc_params_;
int64_t bits_in_buffer_model_[VPX_MAX_LAYERS];
int layer_target_avg_bandwidth_[VPX_MAX_LAYERS];
int base_speed_setting_;
int speed_setting_;
int superframe_count_;
int temporal_layer_id_;
int number_temporal_layers_;
int number_spatial_layers_;
};
} // namespace svc_test
#endif // VPX_TEST_SVC_TEST_H_

View File

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

View File

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

View File

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

View File

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

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