[libvpx] Update to v1.8.1 from https://chromium.googlesource.com/webm/libvpx
This commit is contained in:
parent
34fcadbd53
commit
ceb051af4e
|
@ -4,12 +4,13 @@
|
|||
Aaron Watry <awatry@gmail.com>
|
||||
Abo Talib Mahfoodh <ab.mahfoodh@gmail.com>
|
||||
Adrian Grange <agrange@google.com>
|
||||
Aℓex Converse <aconverse@google.com>
|
||||
Ahmad Sharif <asharif@google.com>
|
||||
Aidan Welch <aidansw@yahoo.com>
|
||||
Aleksey Vasenev <margtu-fivt@ya.ru>
|
||||
Alexander Potapenko <glider@google.com>
|
||||
Alexander Voronov <avoronov@graphics.cs.msu.ru>
|
||||
Alexandra Hájková <alexandra.khirnova@gmail.com>
|
||||
Aℓex Converse <aconverse@google.com>
|
||||
Alexis Ballier <aballier@gentoo.org>
|
||||
Alok Ahuja <waveletcoeff@gmail.com>
|
||||
Alpha Lam <hclam@google.com>
|
||||
|
@ -26,11 +27,13 @@ Brion Vibber <bvibber@wikimedia.org>
|
|||
changjun.yang <changjun.yang@intel.com>
|
||||
Charles 'Buck' Krasic <ckrasic@google.com>
|
||||
Cheng Chen <chengchen@google.com>
|
||||
Chi Yo Tsai <chiyotsai@google.com>
|
||||
chm <chm@rock-chips.com>
|
||||
Chris Cunningham <chcunningham@chromium.org>
|
||||
Christian Duvivier <cduvivier@google.com>
|
||||
Daniele Castagna <dcastagna@chromium.org>
|
||||
Daniel Kang <ddkang@google.com>
|
||||
Dan Zhu <zxdan@google.com>
|
||||
Deb Mukherjee <debargha@google.com>
|
||||
Deepa K G <deepa.kg@ittiam.com>
|
||||
Dim Temp <dimtemp0@gmail.com>
|
||||
|
@ -38,11 +41,13 @@ Dmitry Kovalev <dkovalev@google.com>
|
|||
Dragan Mrdjan <dmrdjan@mips.com>
|
||||
Ed Baker <edward.baker@intel.com>
|
||||
Ehsan Akhgari <ehsan.akhgari@gmail.com>
|
||||
Elliott Karpilovsky <elliottk@google.com>
|
||||
Erik Niemeyer <erik.a.niemeyer@intel.com>
|
||||
Fabio Pedretti <fabio.ped@libero.it>
|
||||
Frank Galligan <fgalligan@google.com>
|
||||
Fredrik Söderquist <fs@opera.com>
|
||||
Fritz Koenig <frkoenig@google.com>
|
||||
Fyodor Kyslov <kyslov@google.com>
|
||||
Gabriel Marin <gmx@chromium.org>
|
||||
Gaute Strokkenes <gaute.strokkenes@broadcom.com>
|
||||
Geza Lore <gezalore@gmail.com>
|
||||
|
@ -55,7 +60,9 @@ Guillermo Ballester Valor <gbvalor@gmail.com>
|
|||
Hangyu Kuang <hkuang@google.com>
|
||||
Hanno Böck <hanno@hboeck.de>
|
||||
Han Shen <shenhan@google.com>
|
||||
Harish Mahendrakar <harish.mahendrakar@ittiam.com>
|
||||
Henrik Lundin <hlundin@google.com>
|
||||
Hien Ho <hienho@google.com>
|
||||
Hui Su <huisu@google.com>
|
||||
Ivan Krasin <krasin@chromium.org>
|
||||
Ivan Maltz <ivanmaltz@google.com>
|
||||
|
@ -81,6 +88,7 @@ Johann Koenig <johannkoenig@google.com>
|
|||
John Koleszar <jkoleszar@google.com>
|
||||
Johnny Klonaris <google@jawknee.com>
|
||||
John Stark <jhnstrk@gmail.com>
|
||||
Jon Kunkee <jkunkee@microsoft.com>
|
||||
Joshua Bleecher Snyder <josh@treelinelabs.com>
|
||||
Joshua Litt <joshualitt@google.com>
|
||||
Julia Robson <juliamrobson@gmail.com>
|
||||
|
@ -91,15 +99,19 @@ KO Myung-Hun <komh@chollian.net>
|
|||
Kyle Siefring <kylesiefring@gmail.com>
|
||||
Lawrence Velázquez <larryv@macports.org>
|
||||
Linfeng Zhang <linfengz@google.com>
|
||||
Liu Peng <pengliu.mail@gmail.com>
|
||||
Lou Quillio <louquillio@google.com>
|
||||
Luca Barbato <lu_zero@gentoo.org>
|
||||
Luc Trudeau <luc@trud.ca>
|
||||
Makoto Kato <makoto.kt@gmail.com>
|
||||
Mans Rullgard <mans@mansr.com>
|
||||
Marco Paniconi <marpan@google.com>
|
||||
Mark Mentovai <mark@chromium.org>
|
||||
Martin Ettl <ettl.martin78@googlemail.com>
|
||||
Martin Storsjo <martin@martin.st>
|
||||
Martin Storsjö <martin@martin.st>
|
||||
Matthew Heaney <matthewjheaney@chromium.org>
|
||||
Matthias Räncker <theonetruecamper@gmx.de>
|
||||
Michael Horowitz <mhoro@webrtc.org>
|
||||
Michael Kohler <michaelkohler@live.com>
|
||||
Mike Frysinger <vapier@chromium.org>
|
||||
Mike Hommey <mhommey@mozilla.com>
|
||||
|
@ -107,10 +119,12 @@ Mikhal Shemer <mikhal@google.com>
|
|||
Min Chen <chenm003@gmail.com>
|
||||
Minghai Shang <minghai@google.com>
|
||||
Min Ye <yeemmi@google.com>
|
||||
Mirko Bonadei <mbonadei@google.com>
|
||||
Moriyoshi Koizumi <mozo@mozo.jp>
|
||||
Morton Jonuschat <yabawock@gmail.com>
|
||||
Nathan E. Egge <negge@mozilla.com>
|
||||
Nico Weber <thakis@chromium.org>
|
||||
Niveditha Rau <niveditha.rau@gmail.com>
|
||||
Parag Salasakar <img.mips1@gmail.com>
|
||||
Pascal Massimino <pascal.massimino@gmail.com>
|
||||
Patrik Westin <patrik.westin@gmail.com>
|
||||
|
@ -129,9 +143,13 @@ Rafael de Lucena Valle <rafaeldelucena@gmail.com>
|
|||
Rahul Chaudhry <rahulchaudhry@google.com>
|
||||
Ralph Giles <giles@xiph.org>
|
||||
Ranjit Kumar Tulabandu <ranjit.tulabandu@ittiam.com>
|
||||
Raphael Kubo da Costa <raphael.kubo.da.costa@intel.com>
|
||||
Ravi Chaudhary <ravi.chaudhary@ittiam.com>
|
||||
Ritu Baldwa <ritu.baldwa@ittiam.com>
|
||||
Rob Bradford <rob@linux.intel.com>
|
||||
Ronald S. Bultje <rsbultje@gmail.com>
|
||||
Rui Ueyama <ruiu@google.com>
|
||||
Sai Deng <sdeng@google.com>
|
||||
Sami Pietilä <samipietila@google.com>
|
||||
Sarah Parker <sarahparker@google.com>
|
||||
Sasi Inguva <isasi@google.com>
|
||||
|
@ -139,12 +157,15 @@ Scott Graham <scottmg@chromium.org>
|
|||
Scott LaVarnway <slavarnway@google.com>
|
||||
Sean McGovern <gseanmcg@gmail.com>
|
||||
Sergey Kolomenkin <kolomenkin@gmail.com>
|
||||
Sergey Silkin <ssilkin@google.com>
|
||||
Sergey Ulanov <sergeyu@chromium.org>
|
||||
Shimon Doodkin <helpmepro1@gmail.com>
|
||||
Shiyou Yin <yinshiyou-hf@loongson.cn>
|
||||
Shubham Tandle <shubham.tandle@ittiam.com>
|
||||
Shunyao Li <shunyaoli@google.com>
|
||||
Stefan Holmer <holmer@google.com>
|
||||
Suman Sunkara <sunkaras@google.com>
|
||||
Supradeep T R <supradeep.tr@ittiam.com>
|
||||
Sylvestre Ledru <sylvestre@mozilla.com>
|
||||
Taekhyun Kim <takim@nvidia.com>
|
||||
Takanori MATSUURA <t.matsuu@gmail.com>
|
||||
|
@ -157,11 +178,15 @@ Timothy B. Terriberry <tterribe@xiph.org>
|
|||
Tom Finegan <tomfinegan@google.com>
|
||||
Tristan Matthews <le.businessman@gmail.com>
|
||||
Urvang Joshi <urvang@google.com>
|
||||
Venkatarama NG. Avadhani <venkatarama.avadhani@ittiam.com>
|
||||
Vignesh Venkatasubramanian <vigneshv@google.com>
|
||||
Vlad Tsyrklevich <vtsyrklevich@chromium.org>
|
||||
Wan-Teh Chang <wtc@google.com>
|
||||
xiwei gu <guxiwei-hf@loongson.cn>
|
||||
Yaowu Xu <yaowu@google.com>
|
||||
Yi Luo <luoyi@google.com>
|
||||
Yongzhe Wang <yongzhe@google.com>
|
||||
Yue Chen <yuec@google.com>
|
||||
Yunqing Wang <yunqingwang@google.com>
|
||||
Yury Gitman <yuryg@google.com>
|
||||
Zoe Liu <zoeliu@google.com>
|
||||
|
|
|
@ -1,4 +1,63 @@
|
|||
2017-01-04 v1.7.0 "Mandarin Duck"
|
||||
2019-07-15 v1.8.1 "Orpington Duck"
|
||||
This release collects incremental improvements to many aspects of the library.
|
||||
|
||||
- Upgrading:
|
||||
VP8E_SET_CPUUSED now accepts values up to 9 for vp9.
|
||||
VPX_CTRL_VP9E_SET_MAX_INTER_BITRATE_PCT had a spelling fix (was VP8E).
|
||||
The --sdk-path option has been removed. If you were using it to build for
|
||||
Android please read build/make/Android.mk for alternatives.
|
||||
All PPC optimizations have been disabled:
|
||||
https://bugs.chromium.org/p/webm/issues/detail?id=1522.
|
||||
|
||||
- Enhancements:
|
||||
Various changes to improve encoder rate control, quality and speed
|
||||
for practically every use case.
|
||||
|
||||
- Bug fixes:
|
||||
vp9-rtc: Fix color artifacts for speed >= 8.
|
||||
|
||||
2019-01-31 v1.8.0 "Northern Shoveler Duck"
|
||||
This release focused on encoding performance for realtime and VOD use cases.
|
||||
|
||||
- Upgrading:
|
||||
This adds and improves several vp9 controls. Most are related to SVC:
|
||||
VP9E_SET_SVC_FRAME_DROP_LAYER:
|
||||
- Frame dropping in SVC.
|
||||
VP9E_SET_SVC_INTER_LAYER_PRED:
|
||||
- Inter-layer prediction in SVC.
|
||||
VP9E_SET_SVC_GF_TEMPORAL_REF:
|
||||
- Enable long term temporal reference in SVC.
|
||||
VP9E_SET_SVC_REF_FRAME_CONFIG/VP9E_GET_SVC_REF_FRAME_CONFIG:
|
||||
- Extend and improve this control for better flexibility in setting SVC
|
||||
pattern dynamically.
|
||||
VP9E_SET_POSTENCODE_DROP:
|
||||
- Allow for post-encode frame dropping (applies to non-SVC too).
|
||||
VP9E_SET_SVC_SPATIAL_LAYER_SYNC:
|
||||
- Enable spatial layer sync frames.
|
||||
VP9E_SET_SVC_LAYER_ID:
|
||||
- Extend api to specify temporal id for each spatial layers.
|
||||
VP9E_SET_ROI_MAP:
|
||||
- Extend Region of Interest functionality to VP9.
|
||||
|
||||
- Enhancements:
|
||||
2 pass vp9 encoding has improved substantially. When using --auto-alt-ref=6,
|
||||
we see approximately 8% for VBR and 10% for CQ. When using --auto-alt-ref=1,
|
||||
the gains are approximately 4% for VBR and 5% for CQ.
|
||||
|
||||
For real-time encoding, speed 7 has improved by ~5-10%. Encodes targeted at
|
||||
screen sharing have improved when the content changes significantly (slide
|
||||
sharing) or scrolls. There is a new speed 9 setting for mobile devices which
|
||||
is about 10-20% faster than speed 8.
|
||||
|
||||
- Bug fixes:
|
||||
VP9 denoiser issue.
|
||||
VP9 partition issue for 1080p.
|
||||
VP9 rate control improvments.
|
||||
Postprocessing Multi Frame Quality Enhancement (MFQE) issue.
|
||||
VP8 multithread decoder issues.
|
||||
A variety of fuzzing issues.
|
||||
|
||||
2018-01-04 v1.7.0 "Mandarin Duck"
|
||||
This release focused on high bit depth performance (10/12 bit) and vp9
|
||||
encoding improvements.
|
||||
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
README - 24 January 2018
|
||||
README - 15 July 2019
|
||||
|
||||
Welcome to the WebM VP8/VP9 Codec SDK!
|
||||
|
||||
|
@ -9,22 +9,26 @@ COMPILING THE APPLICATIONS/LIBRARIES:
|
|||
|
||||
1. Prerequisites
|
||||
|
||||
* All x86 targets require the Yasm[1] assembler be installed.
|
||||
* All Windows builds require that Cygwin[2] be installed.
|
||||
* Building the documentation requires Doxygen[3]. If you do not
|
||||
* All x86 targets require the Yasm[1] assembler be installed[2].
|
||||
* All Windows builds require that Cygwin[3] be installed.
|
||||
* Building the documentation requires Doxygen[4]. If you do not
|
||||
have this package, the install-docs option will be disabled.
|
||||
* Downloading the data for the unit tests requires curl[4] and sha1sum.
|
||||
* Downloading the data for the unit tests requires curl[5] and sha1sum.
|
||||
sha1sum is provided via the GNU coreutils, installed by default on
|
||||
many *nix platforms, as well as MinGW and Cygwin. If coreutils is not
|
||||
available, a compatible version of sha1sum can be built from
|
||||
source[5]. These requirements are optional if not running the unit
|
||||
source[6]. These requirements are optional if not running the unit
|
||||
tests.
|
||||
|
||||
[1]: http://www.tortall.net/projects/yasm
|
||||
[2]: http://www.cygwin.com
|
||||
[3]: http://www.doxygen.org
|
||||
[4]: http://curl.haxx.se
|
||||
[5]: http://www.microbrew.org/tools/md5sha1sum/
|
||||
[2]: For Visual Studio the base yasm binary (not vsyasm) should be in the
|
||||
PATH for Visual Studio. For VS2017 it is sufficient to rename
|
||||
yasm-<version>-<arch>.exe to yasm.exe and place it in:
|
||||
Program Files (x86)/Microsoft Visual Studio/2017/<level>/Common7/Tools/
|
||||
[3]: http://www.cygwin.com
|
||||
[4]: http://www.doxygen.org
|
||||
[5]: http://curl.haxx.se
|
||||
[6]: http://www.microbrew.org/tools/md5sha1sum/
|
||||
|
||||
2. Out-of-tree builds
|
||||
Out of tree builds are a supported method of building the application. For
|
||||
|
@ -41,7 +45,16 @@ COMPILING THE APPLICATIONS/LIBRARIES:
|
|||
used to get a list of supported options:
|
||||
$ ../libvpx/configure --help
|
||||
|
||||
4. Cross development
|
||||
4. Compiler analyzers
|
||||
Compilers have added sanitizers which instrument binaries with information
|
||||
about address calculation, memory usage, threading, undefined behavior, and
|
||||
other common errors. To simplify building libvpx with some of these features
|
||||
use tools/set_analyzer_env.sh before running configure. It will set the
|
||||
compiler and necessary flags for building as well as environment variables
|
||||
read by the analyzer when testing the binaries.
|
||||
$ source ../libvpx/tools/set_analyzer_env.sh address
|
||||
|
||||
5. Cross development
|
||||
For cross development, the most notable option is the --target option. The
|
||||
most up-to-date list of supported targets can be found at the bottom of the
|
||||
--help output of the configure script. As of this writing, the list of
|
||||
|
@ -50,20 +63,20 @@ COMPILING THE APPLICATIONS/LIBRARIES:
|
|||
arm64-android-gcc
|
||||
arm64-darwin-gcc
|
||||
arm64-linux-gcc
|
||||
arm64-win64-gcc
|
||||
arm64-win64-vs15
|
||||
armv7-android-gcc
|
||||
armv7-darwin-gcc
|
||||
armv7-linux-rvct
|
||||
armv7-linux-gcc
|
||||
armv7-none-rvct
|
||||
armv7-win32-vs11
|
||||
armv7-win32-vs12
|
||||
armv7-win32-gcc
|
||||
armv7-win32-vs14
|
||||
armv7-win32-vs15
|
||||
armv7s-darwin-gcc
|
||||
armv8-linux-gcc
|
||||
mips32-linux-gcc
|
||||
mips64-linux-gcc
|
||||
ppc64-linux-gcc
|
||||
ppc64le-linux-gcc
|
||||
sparc-solaris-gcc
|
||||
x86-android-gcc
|
||||
|
@ -78,15 +91,13 @@ COMPILING THE APPLICATIONS/LIBRARIES:
|
|||
x86-darwin14-gcc
|
||||
x86-darwin15-gcc
|
||||
x86-darwin16-gcc
|
||||
x86-darwin17-gcc
|
||||
x86-iphonesimulator-gcc
|
||||
x86-linux-gcc
|
||||
x86-linux-icc
|
||||
x86-os2-gcc
|
||||
x86-solaris-gcc
|
||||
x86-win32-gcc
|
||||
x86-win32-vs10
|
||||
x86-win32-vs11
|
||||
x86-win32-vs12
|
||||
x86-win32-vs14
|
||||
x86-win32-vs15
|
||||
x86_64-android-gcc
|
||||
|
@ -98,14 +109,12 @@ COMPILING THE APPLICATIONS/LIBRARIES:
|
|||
x86_64-darwin14-gcc
|
||||
x86_64-darwin15-gcc
|
||||
x86_64-darwin16-gcc
|
||||
x86_64-darwin17-gcc
|
||||
x86_64-iphonesimulator-gcc
|
||||
x86_64-linux-gcc
|
||||
x86_64-linux-icc
|
||||
x86_64-solaris-gcc
|
||||
x86_64-win64-gcc
|
||||
x86_64-win64-vs10
|
||||
x86_64-win64-vs11
|
||||
x86_64-win64-vs12
|
||||
x86_64-win64-vs14
|
||||
x86_64-win64-vs15
|
||||
generic-gnu
|
||||
|
@ -123,7 +132,7 @@ COMPILING THE APPLICATIONS/LIBRARIES:
|
|||
environment variables: CC, AR, LD, AS, STRIP, NM. Additional flags can be
|
||||
passed to these executables with CFLAGS, LDFLAGS, and ASFLAGS.
|
||||
|
||||
5. Configuration errors
|
||||
6. Configuration errors
|
||||
If the configuration step fails, the first step is to look in the error log.
|
||||
This defaults to config.log. This should give a good indication of what went
|
||||
wrong. If not, contact us for support.
|
||||
|
|
|
@ -8,8 +8,8 @@
|
|||
* be found in the AUTHORS file in the root of the source tree.
|
||||
*/
|
||||
|
||||
#ifndef ARGS_H_
|
||||
#define ARGS_H_
|
||||
#ifndef VPX_ARGS_H_
|
||||
#define VPX_ARGS_H_
|
||||
#include <stdio.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
@ -60,4 +60,4 @@ int arg_parse_enum_or_int(const struct arg *arg);
|
|||
} // extern "C"
|
||||
#endif
|
||||
|
||||
#endif // ARGS_H_
|
||||
#endif // VPX_ARGS_H_
|
||||
|
|
|
@ -1,2 +0,0 @@
|
|||
*-vs8/*.rules -crlf
|
||||
*-msvs/*.rules -crlf
|
|
@ -1 +0,0 @@
|
|||
x86*-win32-vs*
|
|
@ -14,7 +14,7 @@
|
|||
# Run the configure script from the jni directory. Base libvpx
|
||||
# encoder/decoder configuration will look similar to:
|
||||
# ./libvpx/configure --target=armv7-android-gcc --disable-examples \
|
||||
# --sdk-path=/opt/android-ndk-r6b/
|
||||
# --enable-external-build
|
||||
#
|
||||
# When targeting Android, realtime-only is enabled by default. This can
|
||||
# be overridden by adding the command line flag:
|
||||
|
@ -29,37 +29,20 @@
|
|||
# include $(CLEAR_VARS)
|
||||
# include jni/libvpx/build/make/Android.mk
|
||||
#
|
||||
# By default libvpx will detect at runtime the existance of NEON extension.
|
||||
# For this we import the 'cpufeatures' module from the NDK sources.
|
||||
# libvpx can also be configured without this runtime detection method.
|
||||
# Configuring with --disable-runtime-cpu-detect will assume presence of NEON.
|
||||
# Configuring with --disable-runtime-cpu-detect --disable-neon \
|
||||
# --disable-neon-asm
|
||||
# will remove any NEON dependency.
|
||||
# By default libvpx will use the 'cpufeatures' module from the NDK. This allows
|
||||
# the library to be built with all available optimizations (SSE2->AVX512 for
|
||||
# x86, NEON for arm, DSPr2 for mips). This can be disabled with
|
||||
# --disable-runtime-cpu-detect
|
||||
# but the resulting library *must* be run on devices supporting all of the
|
||||
# enabled extensions. They can be disabled individually with
|
||||
# --disable-{sse2, sse3, ssse3, sse4_1, avx, avx2, avx512}
|
||||
# --disable-neon[-asm]
|
||||
# --disable-{dspr2, msa}
|
||||
|
||||
#
|
||||
# Running ndk-build will build libvpx and include it in your project.
|
||||
#
|
||||
|
||||
# Alternatively, building the examples and unit tests can be accomplished in the
|
||||
# following way:
|
||||
#
|
||||
# Create a standalone toolchain from the NDK:
|
||||
# https://developer.android.com/ndk/guides/standalone_toolchain.html
|
||||
#
|
||||
# For example - to test on arm64 devices with clang:
|
||||
# $NDK/build/tools/make_standalone_toolchain.py \
|
||||
# --arch arm64 --install-dir=/tmp/my-android-toolchain
|
||||
# export PATH=/tmp/my-android-toolchain/bin:$PATH
|
||||
# CROSS=aarch64-linux-android- CC=clang CXX=clang++ /path/to/libvpx/configure \
|
||||
# --target=arm64-android-gcc
|
||||
#
|
||||
# Push the resulting binaries to a device and run them:
|
||||
# adb push test_libvpx /data/tmp/test_libvpx
|
||||
# adb shell /data/tmp/test_libvpx --gtest_filter=\*Sixtap\*
|
||||
#
|
||||
# Make sure to push the test data as well and set LIBVPX_TEST_DATA
|
||||
|
||||
CONFIG_DIR := $(LOCAL_PATH)/
|
||||
LIBVPX_PATH := $(LOCAL_PATH)/libvpx
|
||||
ASM_CNV_PATH_LOCAL := $(TARGET_ARCH_ABI)/ads2gas
|
||||
|
|
|
@ -99,6 +99,7 @@ distclean: clean
|
|||
rm -f Makefile; \
|
||||
rm -f config.log config.mk; \
|
||||
rm -f vpx_config.[hc] vpx_config.asm; \
|
||||
rm -f arm_neon.h; \
|
||||
else \
|
||||
rm -f $(target)-$(TOOLCHAIN).mk; \
|
||||
fi
|
||||
|
|
|
@ -23,16 +23,17 @@ use lib $FindBin::Bin;
|
|||
use thumb;
|
||||
|
||||
my $thumb = 0;
|
||||
my $elf = 1;
|
||||
|
||||
foreach my $arg (@ARGV) {
|
||||
$thumb = 1 if ($arg eq "-thumb");
|
||||
$elf = 0 if ($arg eq "-noelf");
|
||||
}
|
||||
|
||||
print "@ This file was created from a .asm file\n";
|
||||
print "@ using the ads2gas.pl script.\n";
|
||||
print "\t.equ DO1STROUNDING, 0\n";
|
||||
if ($thumb) {
|
||||
print "\t.syntax unified\n";
|
||||
if ($thumb) {
|
||||
print "\t.thumb\n";
|
||||
}
|
||||
|
||||
|
@ -140,7 +141,11 @@ while (<STDIN>)
|
|||
|
||||
# Make function visible to linker, and make additional symbol with
|
||||
# prepended underscore
|
||||
if ($elf) {
|
||||
s/EXPORT\s+\|([\$\w]*)\|/.global $1 \n\t.type $1, function/;
|
||||
} else {
|
||||
s/EXPORT\s+\|([\$\w]*)\|/.global $1/;
|
||||
}
|
||||
s/IMPORT\s+\|([\$\w]*)\|/.global $1/;
|
||||
|
||||
s/EXPORT\s+([\$\w]*)/.global $1/;
|
||||
|
@ -181,11 +186,16 @@ while (<STDIN>)
|
|||
# eabi_attributes numerical equivalents can be found in the
|
||||
# "ARM IHI 0045C" document.
|
||||
|
||||
if ($elf) {
|
||||
# REQUIRE8 Stack is required to be 8-byte aligned
|
||||
s/\sREQUIRE8/.eabi_attribute 24, 1 \@Tag_ABI_align_needed/g;
|
||||
|
||||
# PRESERVE8 Stack 8-byte align is preserved
|
||||
s/\sPRESERVE8/.eabi_attribute 25, 1 \@Tag_ABI_align_preserved/g;
|
||||
} else {
|
||||
s/\sREQUIRE8//;
|
||||
s/\sPRESERVE8//;
|
||||
}
|
||||
|
||||
# Use PROC and ENDP to give the symbols a .size directive.
|
||||
# This makes them show up properly in debugging tools like gdb and valgrind.
|
||||
|
@ -202,7 +212,7 @@ while (<STDIN>)
|
|||
my $proc;
|
||||
s/\bENDP\b/@ $&/;
|
||||
$proc = pop(@proc_stack);
|
||||
$_ = "\t.size $proc, .-$proc".$_ if ($proc);
|
||||
$_ = "\t.size $proc, .-$proc".$_ if ($proc and $elf);
|
||||
}
|
||||
|
||||
# EQU directive
|
||||
|
@ -225,4 +235,4 @@ while (<STDIN>)
|
|||
}
|
||||
|
||||
# Mark that this object doesn't need an executable stack.
|
||||
printf ("\t.section\t.note.GNU-stack,\"\",\%\%progbits\n");
|
||||
printf ("\t.section\t.note.GNU-stack,\"\",\%\%progbits\n") if $elf;
|
||||
|
|
|
@ -20,9 +20,7 @@
|
|||
|
||||
print "@ This file was created from a .asm file\n";
|
||||
print "@ using the ads2gas_apple.pl script.\n\n";
|
||||
print "\t.set WIDE_REFERENCE, 0\n";
|
||||
print "\t.set ARCHITECTURE, 5\n";
|
||||
print "\t.set DO1STROUNDING, 0\n";
|
||||
print "\t.syntax unified\n";
|
||||
|
||||
my %register_aliases;
|
||||
my %macro_aliases;
|
||||
|
|
|
@ -319,6 +319,12 @@ check_ld() {
|
|||
&& check_cmd ${LD} ${LDFLAGS} "$@" -o ${TMP_X} ${TMP_O} ${extralibs}
|
||||
}
|
||||
|
||||
check_lib() {
|
||||
log check_lib "$@"
|
||||
check_cc $@ \
|
||||
&& check_cmd ${LD} ${LDFLAGS} -o ${TMP_X} ${TMP_O} "$@" ${extralibs}
|
||||
}
|
||||
|
||||
check_header(){
|
||||
log check_header "$@"
|
||||
header=$1
|
||||
|
@ -420,6 +426,26 @@ check_gcc_machine_options() {
|
|||
fi
|
||||
}
|
||||
|
||||
check_gcc_avx512_compiles() {
|
||||
if disabled gcc; then
|
||||
return
|
||||
fi
|
||||
|
||||
check_cc -mavx512f <<EOF
|
||||
#include <immintrin.h>
|
||||
void f(void) {
|
||||
__m512i x = _mm512_set1_epi16(0);
|
||||
(void)x;
|
||||
}
|
||||
EOF
|
||||
compile_result=$?
|
||||
if [ ${compile_result} -ne 0 ]; then
|
||||
log_echo " disabling avx512: not supported by compiler"
|
||||
disable_feature avx512
|
||||
RTCD_OPTIONS="${RTCD_OPTIONS}--disable-avx512 "
|
||||
fi
|
||||
}
|
||||
|
||||
write_common_config_banner() {
|
||||
print_webm_license config.mk "##" ""
|
||||
echo '# This file automatically generated by configure. Do not edit!' >> config.mk
|
||||
|
@ -481,6 +507,7 @@ AS_SFX = ${AS_SFX:-.asm}
|
|||
EXE_SFX = ${EXE_SFX}
|
||||
VCPROJ_SFX = ${VCPROJ_SFX}
|
||||
RTCD_OPTIONS = ${RTCD_OPTIONS}
|
||||
LIBYUV_CXXFLAGS = ${LIBYUV_CXXFLAGS}
|
||||
EOF
|
||||
|
||||
if enabled rvct; then cat >> $1 << EOF
|
||||
|
@ -520,6 +547,24 @@ EOF
|
|||
cmp "$1" ${TMP_H} >/dev/null 2>&1 || mv ${TMP_H} "$1"
|
||||
}
|
||||
|
||||
write_win_arm64_neon_h_workaround() {
|
||||
print_webm_license ${TMP_H} "/*" " */"
|
||||
cat >> ${TMP_H} << EOF
|
||||
/* This file automatically generated by configure. Do not edit! */
|
||||
#ifndef VPX_WIN_ARM_NEON_H_WORKAROUND
|
||||
#define VPX_WIN_ARM_NEON_H_WORKAROUND
|
||||
/* The Windows SDK has arm_neon.h, but unlike on other platforms it is
|
||||
* ARM32-only. ARM64 NEON support is provided by arm64_neon.h, a proper
|
||||
* superset of arm_neon.h. Work around this by providing a more local
|
||||
* arm_neon.h that simply #includes arm64_neon.h.
|
||||
*/
|
||||
#include <arm64_neon.h>
|
||||
#endif /* VPX_WIN_ARM_NEON_H_WORKAROUND */
|
||||
EOF
|
||||
mkdir -p `dirname "$1"`
|
||||
cmp "$1" ${TMP_H} >/dev/null 2>&1 || mv ${TMP_H} "$1"
|
||||
}
|
||||
|
||||
process_common_cmdline() {
|
||||
for opt in "$@"; do
|
||||
optval="${opt#*=}"
|
||||
|
@ -602,11 +647,7 @@ process_common_cmdline() {
|
|||
--libdir=*)
|
||||
libdir="${optval}"
|
||||
;;
|
||||
--sdk-path=*)
|
||||
[ -d "${optval}" ] || die "Not a directory: ${optval}"
|
||||
sdk_path="${optval}"
|
||||
;;
|
||||
--libc|--as|--prefix|--libdir|--sdk-path)
|
||||
--libc|--as|--prefix|--libdir)
|
||||
die "Option ${opt} requires argument"
|
||||
;;
|
||||
--help|-h)
|
||||
|
@ -713,11 +754,8 @@ process_common_toolchain() {
|
|||
*sparc*)
|
||||
tgt_isa=sparc
|
||||
;;
|
||||
power*64*-*)
|
||||
tgt_isa=ppc64
|
||||
;;
|
||||
power*)
|
||||
tgt_isa=ppc
|
||||
power*64le*-*)
|
||||
tgt_isa=ppc64le
|
||||
;;
|
||||
*mips64el*)
|
||||
tgt_isa=mips64
|
||||
|
@ -837,7 +875,7 @@ process_common_toolchain() {
|
|||
IOS_VERSION_MIN="8.0"
|
||||
else
|
||||
IOS_VERSION_OPTIONS=""
|
||||
IOS_VERSION_MIN="6.0"
|
||||
IOS_VERSION_MIN="7.0"
|
||||
fi
|
||||
|
||||
# Handle darwin variants. Newer SDKs allow targeting older
|
||||
|
@ -957,7 +995,6 @@ process_common_toolchain() {
|
|||
setup_gnu_toolchain
|
||||
arch_int=${tgt_isa##armv}
|
||||
arch_int=${arch_int%%te}
|
||||
check_add_asflags --defsym ARCHITECTURE=${arch_int}
|
||||
tune_cflags="-mtune="
|
||||
if [ ${tgt_isa} = "armv7" ] || [ ${tgt_isa} = "armv7s" ]; then
|
||||
if [ -z "${float_abi}" ]; then
|
||||
|
@ -984,6 +1021,16 @@ EOF
|
|||
|
||||
enabled debug && add_asflags -g
|
||||
asm_conversion_cmd="${source_path}/build/make/ads2gas.pl"
|
||||
|
||||
case ${tgt_os} in
|
||||
win*)
|
||||
asm_conversion_cmd="$asm_conversion_cmd -noelf"
|
||||
AS="$CC -c"
|
||||
EXE_SFX=.exe
|
||||
enable_feature thumb
|
||||
;;
|
||||
esac
|
||||
|
||||
if enabled thumb; then
|
||||
asm_conversion_cmd="$asm_conversion_cmd -thumb"
|
||||
check_add_cflags -mthumb
|
||||
|
@ -991,19 +1038,42 @@ EOF
|
|||
fi
|
||||
;;
|
||||
vs*)
|
||||
# A number of ARM-based Windows platforms are constrained by their
|
||||
# respective SDKs' limitations. Fortunately, these are all 32-bit ABIs
|
||||
# and so can be selected as 'win32'.
|
||||
if [ ${tgt_os} = "win32" ]; then
|
||||
asm_conversion_cmd="${source_path}/build/make/ads2armasm_ms.pl"
|
||||
AS_SFX=.S
|
||||
msvs_arch_dir=arm-msvs
|
||||
disable_feature multithread
|
||||
disable_feature unit_tests
|
||||
vs_version=${tgt_cc##vs}
|
||||
if [ $vs_version -ge 12 ]; then
|
||||
# MSVC 2013 doesn't allow doing plain .exe projects for ARM,
|
||||
if [ ${tgt_cc##vs} -ge 12 ]; then
|
||||
# MSVC 2013 doesn't allow doing plain .exe projects for ARM32,
|
||||
# only "AppContainerApplication" which requires an AppxManifest.
|
||||
# Therefore disable the examples, just build the library.
|
||||
disable_feature examples
|
||||
disable_feature tools
|
||||
fi
|
||||
else
|
||||
# Windows 10 on ARM, on the other hand, has full Windows SDK support
|
||||
# for building Win32 ARM64 applications in addition to ARM64
|
||||
# Windows Store apps. It is the only 64-bit ARM ABI that
|
||||
# Windows supports, so it is the default definition of 'win64'.
|
||||
# ARM64 build support officially shipped in Visual Studio 15.9.0.
|
||||
|
||||
# Because the ARM64 Windows SDK's arm_neon.h is ARM32-specific
|
||||
# while LLVM's is not, probe its validity.
|
||||
if enabled neon; then
|
||||
if [ -n "${CC}" ]; then
|
||||
check_header arm_neon.h || check_header arm64_neon.h && \
|
||||
enable_feature win_arm64_neon_h_workaround
|
||||
else
|
||||
# If a probe is not possible, assume this is the pure Windows
|
||||
# SDK and so the workaround is necessary.
|
||||
enable_feature win_arm64_neon_h_workaround
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
;;
|
||||
rvct)
|
||||
CC=armcc
|
||||
|
@ -1030,7 +1100,6 @@ EOF
|
|||
fi
|
||||
arch_int=${tgt_isa##armv}
|
||||
arch_int=${arch_int%%te}
|
||||
check_add_asflags --pd "\"ARCHITECTURE SETA ${arch_int}\""
|
||||
enabled debug && add_asflags -g
|
||||
add_cflags --gnu
|
||||
add_cflags --enum_is_int
|
||||
|
@ -1045,51 +1114,10 @@ EOF
|
|||
;;
|
||||
|
||||
android*)
|
||||
if [ -n "${sdk_path}" ]; then
|
||||
SDK_PATH=${sdk_path}
|
||||
COMPILER_LOCATION=`find "${SDK_PATH}" \
|
||||
-name "arm-linux-androideabi-gcc*" -print -quit`
|
||||
TOOLCHAIN_PATH=${COMPILER_LOCATION%/*}/arm-linux-androideabi-
|
||||
CC=${TOOLCHAIN_PATH}gcc
|
||||
CXX=${TOOLCHAIN_PATH}g++
|
||||
AR=${TOOLCHAIN_PATH}ar
|
||||
LD=${TOOLCHAIN_PATH}gcc
|
||||
AS=${TOOLCHAIN_PATH}as
|
||||
STRIP=${TOOLCHAIN_PATH}strip
|
||||
NM=${TOOLCHAIN_PATH}nm
|
||||
|
||||
if [ -z "${alt_libc}" ]; then
|
||||
alt_libc=`find "${SDK_PATH}" -name arch-arm -print | \
|
||||
awk '{n = split($0,a,"/"); \
|
||||
split(a[n-1],b,"-"); \
|
||||
print $0 " " b[2]}' | \
|
||||
sort -g -k 2 | \
|
||||
awk '{ print $1 }' | tail -1`
|
||||
fi
|
||||
|
||||
if [ -d "${alt_libc}" ]; then
|
||||
add_cflags "--sysroot=${alt_libc}"
|
||||
add_ldflags "--sysroot=${alt_libc}"
|
||||
fi
|
||||
|
||||
# linker flag that routes around a CPU bug in some
|
||||
# Cortex-A8 implementations (NDK Dev Guide)
|
||||
add_ldflags "-Wl,--fix-cortex-a8"
|
||||
|
||||
enable_feature pic
|
||||
soft_enable realtime_only
|
||||
if [ ${tgt_isa} = "armv7" ]; then
|
||||
soft_enable runtime_cpu_detect
|
||||
fi
|
||||
if enabled runtime_cpu_detect; then
|
||||
add_cflags "-I${SDK_PATH}/sources/android/cpufeatures"
|
||||
fi
|
||||
else
|
||||
echo "Assuming standalone build with NDK toolchain."
|
||||
echo "See build/make/Android.mk for details."
|
||||
check_add_ldflags -static
|
||||
soft_enable unit_tests
|
||||
fi
|
||||
;;
|
||||
|
||||
darwin*)
|
||||
|
@ -1204,6 +1232,11 @@ EOF
|
|||
esac
|
||||
|
||||
if enabled msa; then
|
||||
# TODO(libyuv:793)
|
||||
# The new mips functions in libyuv do not build
|
||||
# with the toolchains we currently use for testing.
|
||||
soft_disable libyuv
|
||||
|
||||
add_cflags -mmsa
|
||||
add_asflags -mmsa
|
||||
add_ldflags -mmsa
|
||||
|
@ -1219,13 +1252,25 @@ EOF
|
|||
check_add_asflags -march=${tgt_isa}
|
||||
check_add_asflags -KPIC
|
||||
;;
|
||||
ppc*)
|
||||
ppc64le*)
|
||||
link_with_cc=gcc
|
||||
setup_gnu_toolchain
|
||||
check_gcc_machine_option "vsx"
|
||||
# Do not enable vsx by default.
|
||||
# https://bugs.chromium.org/p/webm/issues/detail?id=1522
|
||||
enabled vsx || RTCD_OPTIONS="${RTCD_OPTIONS}--disable-vsx "
|
||||
if [ -n "${tune_cpu}" ]; then
|
||||
case ${tune_cpu} in
|
||||
power?)
|
||||
tune_cflags="-mcpu="
|
||||
;;
|
||||
esac
|
||||
fi
|
||||
;;
|
||||
x86*)
|
||||
case ${tgt_os} in
|
||||
android)
|
||||
soft_enable realtime_only
|
||||
;;
|
||||
win*)
|
||||
enabled gcc && add_cflags -fno-common
|
||||
;;
|
||||
|
@ -1277,28 +1322,13 @@ EOF
|
|||
# Skip the check by setting AS arbitrarily
|
||||
AS=msvs
|
||||
msvs_arch_dir=x86-msvs
|
||||
vc_version=${tgt_cc##vs}
|
||||
case $vc_version in
|
||||
7|8|9|10|11|12|13|14)
|
||||
case ${tgt_cc##vs} in
|
||||
14)
|
||||
echo "${tgt_cc} does not support avx512, disabling....."
|
||||
RTCD_OPTIONS="${RTCD_OPTIONS}--disable-avx512 "
|
||||
soft_disable avx512
|
||||
;;
|
||||
esac
|
||||
case $vc_version in
|
||||
7|8|9|10)
|
||||
echo "${tgt_cc} does not support avx/avx2, disabling....."
|
||||
RTCD_OPTIONS="${RTCD_OPTIONS}--disable-avx --disable-avx2 "
|
||||
soft_disable avx
|
||||
soft_disable avx2
|
||||
;;
|
||||
esac
|
||||
case $vc_version in
|
||||
7|8|9)
|
||||
echo "${tgt_cc} omits stdint.h, disabling webm-io..."
|
||||
soft_disable webm_io
|
||||
;;
|
||||
esac
|
||||
;;
|
||||
esac
|
||||
|
||||
|
@ -1331,16 +1361,12 @@ EOF
|
|||
else
|
||||
if [ "$ext" = "avx512" ]; then
|
||||
check_gcc_machine_options $ext avx512f avx512cd avx512bw avx512dq avx512vl
|
||||
check_gcc_avx512_compiles
|
||||
else
|
||||
# use the shortened version for the flag: sse4_1 -> sse4
|
||||
check_gcc_machine_option ${ext%_*} $ext
|
||||
fi
|
||||
fi
|
||||
|
||||
# https://bugs.chromium.org/p/webm/issues/detail?id=1464
|
||||
# The assembly optimizations for vpx_sub_pixel_variance do not link with
|
||||
# gcc 6.
|
||||
enabled sse2 && soft_enable pic
|
||||
done
|
||||
|
||||
if enabled external_build; then
|
||||
|
@ -1400,7 +1426,8 @@ EOF
|
|||
add_cflags ${sim_arch}
|
||||
add_ldflags ${sim_arch}
|
||||
|
||||
if [ "$(show_darwin_sdk_major_version iphonesimulator)" -gt 8 ]; then
|
||||
if [ "$(disabled external_build)" ] &&
|
||||
[ "$(show_darwin_sdk_major_version iphonesimulator)" -gt 8 ]; then
|
||||
# yasm v1.3.0 doesn't know what -fembed-bitcode means, so turning it
|
||||
# on is pointless (unless building a C-only lib). Warn the user, but
|
||||
# do nothing here.
|
||||
|
@ -1490,7 +1517,11 @@ EOF
|
|||
# bionic includes basic pthread functionality, obviating -lpthread.
|
||||
;;
|
||||
*)
|
||||
check_header pthread.h && add_extralibs -lpthread
|
||||
check_header pthread.h && check_lib -lpthread <<EOF && add_extralibs -lpthread || disable_feature pthread_h
|
||||
#include <pthread.h>
|
||||
#include <stddef.h>
|
||||
int main(void) { return pthread_create(NULL, NULL, NULL, NULL); }
|
||||
EOF
|
||||
;;
|
||||
esac
|
||||
fi
|
||||
|
|
|
@ -261,6 +261,11 @@ case "$target" in
|
|||
asm_Debug_cmdline="yasm -Xvc -g cv8 -f win32 ${yasmincs} "%(FullPath)""
|
||||
asm_Release_cmdline="yasm -Xvc -f win32 ${yasmincs} "%(FullPath)""
|
||||
;;
|
||||
arm64*)
|
||||
platforms[0]="ARM64"
|
||||
asm_Debug_cmdline="armasm64 -nologo -oldit "%(FullPath)""
|
||||
asm_Release_cmdline="armasm64 -nologo -oldit "%(FullPath)""
|
||||
;;
|
||||
arm*)
|
||||
platforms[0]="ARM"
|
||||
asm_Debug_cmdline="armasm -nologo -oldit "%(FullPath)""
|
||||
|
@ -307,6 +312,16 @@ generate_vcxproj() {
|
|||
tag_content ApplicationType "Windows Store"
|
||||
tag_content ApplicationTypeRevision 8.1
|
||||
fi
|
||||
if [ "${platforms[0]}" = "ARM64" ]; then
|
||||
# Require the first Visual Studio version to have ARM64 support.
|
||||
tag_content MinimumVisualStudioVersion 15.9
|
||||
fi
|
||||
if [ $vs_ver -eq 15 ] && [ "${platforms[0]}" = "ARM64" ]; then
|
||||
# Since VS 15 does not have a 'use latest SDK version' facility,
|
||||
# specifically require the contemporaneous SDK with official ARM64
|
||||
# support.
|
||||
tag_content WindowsTargetPlatformVersion 10.0.17763.0
|
||||
fi
|
||||
close_tag PropertyGroup
|
||||
|
||||
tag Import \
|
||||
|
|
|
@ -132,7 +132,8 @@ create_vpx_framework_config_shim() {
|
|||
done
|
||||
|
||||
# Consume the last line of output from the loop: We don't want it.
|
||||
sed -i '' -e '$d' "${config_file}"
|
||||
sed -i.bak -e '$d' "${config_file}"
|
||||
rm "${config_file}.bak"
|
||||
|
||||
printf "#endif\n\n" >> "${config_file}"
|
||||
printf "#endif // ${include_guard}" >> "${config_file}"
|
||||
|
@ -244,7 +245,7 @@ build_framework() {
|
|||
# Trap function. Cleans up the subtree used to build all targets contained in
|
||||
# $TARGETS.
|
||||
cleanup() {
|
||||
local readonly res=$?
|
||||
local res=$?
|
||||
cd "${ORIG_PWD}"
|
||||
|
||||
if [ $res -ne 0 ]; then
|
||||
|
@ -350,7 +351,7 @@ if [ "$ENABLE_SHARED" = "yes" ]; then
|
|||
IOS_VERSION_MIN="8.0"
|
||||
else
|
||||
IOS_VERSION_OPTIONS=""
|
||||
IOS_VERSION_MIN="6.0"
|
||||
IOS_VERSION_MIN="7.0"
|
||||
fi
|
||||
|
||||
if [ "${VERBOSE}" = "yes" ]; then
|
||||
|
|
|
@ -41,6 +41,15 @@ fix_path() {
|
|||
# Corrects the paths in file_list in one pass for efficiency.
|
||||
# $1 is the name of the array to be modified.
|
||||
fix_file_list() {
|
||||
if [ "${FIXPATH}" = "echo_path" ] ; then
|
||||
# When used with echo_path, fix_file_list is a no-op. Avoid warning about
|
||||
# unsupported 'declare -n' when it is not important.
|
||||
return 0
|
||||
elif [ "${BASH_VERSINFO}" -lt 4 ] ; then
|
||||
echo "Cygwin path conversion has failed. Please use a version of bash"
|
||||
echo "which supports nameref (-n), introduced in bash 4.3"
|
||||
return 1
|
||||
fi
|
||||
declare -n array_ref=$1
|
||||
files=$(fix_path "${array_ref[@]}")
|
||||
local IFS=$'\n'
|
||||
|
|
|
@ -400,12 +400,13 @@ EOF
|
|||
#
|
||||
|
||||
&require("c");
|
||||
&require(keys %required);
|
||||
if ($opts{arch} eq 'x86') {
|
||||
@ALL_ARCHS = filter(qw/mmx sse sse2 sse3 ssse3 sse4_1 avx avx2 avx512/);
|
||||
x86;
|
||||
} elsif ($opts{arch} eq 'x86_64') {
|
||||
@ALL_ARCHS = filter(qw/mmx sse sse2 sse3 ssse3 sse4_1 avx avx2 avx512/);
|
||||
@REQUIRES = filter(keys %required ? keys %required : qw/mmx sse sse2/);
|
||||
@REQUIRES = filter(qw/mmx sse sse2/);
|
||||
&require(@REQUIRES);
|
||||
x86;
|
||||
} elsif ($opts{arch} eq 'mips32' || $opts{arch} eq 'mips64') {
|
||||
|
@ -433,6 +434,7 @@ if ($opts{arch} eq 'x86') {
|
|||
arm;
|
||||
} elsif ($opts{arch} eq 'armv8' || $opts{arch} eq 'arm64' ) {
|
||||
@ALL_ARCHS = filter(qw/neon/);
|
||||
&require("neon");
|
||||
arm;
|
||||
} elsif ($opts{arch} =~ /^ppc/ ) {
|
||||
@ALL_ARCHS = filter(qw/vsx/);
|
||||
|
|
|
@ -54,13 +54,6 @@ sub FixThumbInstructions($$)
|
|||
# "addne r0, r0, r2".
|
||||
s/^(\s*)((ldr|str)(ne)?[bhd]?)(\s+)(\w+),(\s*\w+,)?\s*\[(\w+)\],\s*(\w+)/$1$2$5$6,$7 [$8]\n$1add$4$5$8, $8, $9/g;
|
||||
|
||||
# Convert a conditional addition to the pc register into a series of
|
||||
# instructions. This converts "addlt pc, pc, r3, lsl #2" into
|
||||
# "itttt lt", "movlt.n r12, pc", "addlt.w r12, #12",
|
||||
# "addlt.w r12, r12, r3, lsl #2", "movlt.n pc, r12".
|
||||
# This assumes that r12 is free at this point.
|
||||
s/^(\s*)addlt(\s+)pc,\s*pc,\s*(\w+),\s*lsl\s*#(\d+)/$1itttt$2lt\n$1movlt.n$2r12, pc\n$1addlt.w$2r12, #12\n$1addlt.w$2r12, r12, $3, lsl #($4-$branch_shift_offset)\n$1movlt.n$2pc, r12/g;
|
||||
|
||||
# Convert "mov pc, lr" into "bx lr", since the former only works
|
||||
# for switching from arm to thumb (and only in armv7), but not
|
||||
# from thumb to arm.
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
# This file is used by gcl to get repository specific information.
|
||||
GERRIT_HOST: chromium-review.googlesource.com
|
||||
GERRIT_PORT: 29418
|
||||
# This file is used by git cl to get repository specific information.
|
||||
GERRIT_HOST: True
|
||||
CODE_REVIEW_SERVER: chromium-review.googlesource.com
|
||||
GERRIT_SQUASH_UPLOADS: False
|
||||
|
|
|
@ -31,7 +31,6 @@ Advanced options:
|
|||
--libc=PATH path to alternate libc
|
||||
--size-limit=WxH max size to allow in the decoder
|
||||
--as={yasm|nasm|auto} use specified assembler [auto, yasm preferred]
|
||||
--sdk-path=PATH path to root of sdk (android builds only)
|
||||
${toggle_codec_srcs} in/exclude codec library source code
|
||||
${toggle_debug_libs} in/exclude debug version of libraries
|
||||
${toggle_static_msvcrt} use static MSVCRT (VS builds only)
|
||||
|
@ -101,20 +100,20 @@ EOF
|
|||
all_platforms="${all_platforms} arm64-android-gcc"
|
||||
all_platforms="${all_platforms} arm64-darwin-gcc"
|
||||
all_platforms="${all_platforms} arm64-linux-gcc"
|
||||
all_platforms="${all_platforms} arm64-win64-gcc"
|
||||
all_platforms="${all_platforms} arm64-win64-vs15"
|
||||
all_platforms="${all_platforms} armv7-android-gcc" #neon Cortex-A8
|
||||
all_platforms="${all_platforms} armv7-darwin-gcc" #neon Cortex-A8
|
||||
all_platforms="${all_platforms} armv7-linux-rvct" #neon Cortex-A8
|
||||
all_platforms="${all_platforms} armv7-linux-gcc" #neon Cortex-A8
|
||||
all_platforms="${all_platforms} armv7-none-rvct" #neon Cortex-A8
|
||||
all_platforms="${all_platforms} armv7-win32-vs11"
|
||||
all_platforms="${all_platforms} armv7-win32-vs12"
|
||||
all_platforms="${all_platforms} armv7-win32-gcc"
|
||||
all_platforms="${all_platforms} armv7-win32-vs14"
|
||||
all_platforms="${all_platforms} armv7-win32-vs15"
|
||||
all_platforms="${all_platforms} armv7s-darwin-gcc"
|
||||
all_platforms="${all_platforms} armv8-linux-gcc"
|
||||
all_platforms="${all_platforms} mips32-linux-gcc"
|
||||
all_platforms="${all_platforms} mips64-linux-gcc"
|
||||
all_platforms="${all_platforms} ppc64-linux-gcc"
|
||||
all_platforms="${all_platforms} ppc64le-linux-gcc"
|
||||
all_platforms="${all_platforms} sparc-solaris-gcc"
|
||||
all_platforms="${all_platforms} x86-android-gcc"
|
||||
|
@ -137,9 +136,6 @@ all_platforms="${all_platforms} x86-linux-icc"
|
|||
all_platforms="${all_platforms} x86-os2-gcc"
|
||||
all_platforms="${all_platforms} x86-solaris-gcc"
|
||||
all_platforms="${all_platforms} x86-win32-gcc"
|
||||
all_platforms="${all_platforms} x86-win32-vs10"
|
||||
all_platforms="${all_platforms} x86-win32-vs11"
|
||||
all_platforms="${all_platforms} x86-win32-vs12"
|
||||
all_platforms="${all_platforms} x86-win32-vs14"
|
||||
all_platforms="${all_platforms} x86-win32-vs15"
|
||||
all_platforms="${all_platforms} x86_64-android-gcc"
|
||||
|
@ -159,9 +155,6 @@ all_platforms="${all_platforms} x86_64-linux-gcc"
|
|||
all_platforms="${all_platforms} x86_64-linux-icc"
|
||||
all_platforms="${all_platforms} x86_64-solaris-gcc"
|
||||
all_platforms="${all_platforms} x86_64-win64-gcc"
|
||||
all_platforms="${all_platforms} x86_64-win64-vs10"
|
||||
all_platforms="${all_platforms} x86_64-win64-vs11"
|
||||
all_platforms="${all_platforms} x86_64-win64-vs12"
|
||||
all_platforms="${all_platforms} x86_64-win64-vs14"
|
||||
all_platforms="${all_platforms} x86_64-win64-vs15"
|
||||
all_platforms="${all_platforms} generic-gnu"
|
||||
|
@ -278,9 +271,9 @@ HAVE_LIST="
|
|||
unistd_h
|
||||
"
|
||||
EXPERIMENT_LIST="
|
||||
spatial_svc
|
||||
fp_mb_stats
|
||||
emulate_hardware
|
||||
non_greedy_mv
|
||||
"
|
||||
CONFIG_LIST="
|
||||
dependency_tracking
|
||||
|
@ -330,12 +323,15 @@ CONFIG_LIST="
|
|||
multi_res_encoding
|
||||
temporal_denoising
|
||||
vp9_temporal_denoising
|
||||
consistent_recode
|
||||
coefficient_range_checking
|
||||
vp9_highbitdepth
|
||||
better_hw_compatibility
|
||||
experimental
|
||||
size_limit
|
||||
always_adjust_bpm
|
||||
bitstream_debug
|
||||
mismatch_debug
|
||||
${EXPERIMENT_LIST}
|
||||
"
|
||||
CMDLINE_SELECT="
|
||||
|
@ -391,11 +387,14 @@ CMDLINE_SELECT="
|
|||
multi_res_encoding
|
||||
temporal_denoising
|
||||
vp9_temporal_denoising
|
||||
consistent_recode
|
||||
coefficient_range_checking
|
||||
better_hw_compatibility
|
||||
vp9_highbitdepth
|
||||
experimental
|
||||
always_adjust_bpm
|
||||
bitstream_debug
|
||||
mismatch_debug
|
||||
"
|
||||
|
||||
process_cmdline() {
|
||||
|
@ -426,6 +425,12 @@ process_cmdline() {
|
|||
}
|
||||
|
||||
post_process_cmdline() {
|
||||
if enabled coefficient_range_checking; then
|
||||
echo "coefficient-range-checking is for decoders only, disabling encoders:"
|
||||
soft_disable vp8_encoder
|
||||
soft_disable vp9_encoder
|
||||
fi
|
||||
|
||||
c=""
|
||||
|
||||
# Enable all detected codecs, if they haven't been disabled
|
||||
|
@ -447,6 +452,7 @@ process_targets() {
|
|||
enabled child || write_common_config_banner
|
||||
write_common_target_config_h ${BUILD_PFX}vpx_config.h
|
||||
write_common_config_targets
|
||||
enabled win_arm64_neon_h_workaround && write_win_arm64_neon_h_workaround ${BUILD_PFX}arm_neon.h
|
||||
|
||||
# Calculate the default distribution name, based on the enabled features
|
||||
cf=""
|
||||
|
@ -523,7 +529,7 @@ process_detect() {
|
|||
# here rather than at option parse time because the target auto-detect
|
||||
# magic happens after the command line has been parsed.
|
||||
case "${tgt_os}" in
|
||||
linux|os2|darwin*|iphonesimulator*)
|
||||
linux|os2|solaris|darwin*|iphonesimulator*)
|
||||
# Supported platforms
|
||||
;;
|
||||
*)
|
||||
|
@ -575,16 +581,30 @@ process_detect() {
|
|||
check_ld() {
|
||||
true
|
||||
}
|
||||
check_lib() {
|
||||
true
|
||||
}
|
||||
fi
|
||||
check_header stdio.h || die "Unable to invoke compiler: ${CC} ${CFLAGS}"
|
||||
check_ld <<EOF || die "Toolchain is unable to link executables"
|
||||
int main(void) {return 0;}
|
||||
EOF
|
||||
# check system headers
|
||||
check_header pthread.h
|
||||
|
||||
# Use both check_header and check_lib here, since check_lib
|
||||
# could be a stub that always returns true.
|
||||
check_header pthread.h && check_lib -lpthread <<EOF || disable_feature pthread_h
|
||||
#include <pthread.h>
|
||||
#include <stddef.h>
|
||||
int main(void) { return pthread_create(NULL, NULL, NULL, NULL); }
|
||||
EOF
|
||||
check_header unistd.h # for sysconf(3) and friends.
|
||||
|
||||
check_header vpx/vpx_integer.h -I${source_path} && enable_feature vpx_ports
|
||||
|
||||
if enabled neon && ! enabled external_build; then
|
||||
check_header arm_neon.h || die "Unable to find arm_neon.h"
|
||||
fi
|
||||
}
|
||||
|
||||
process_toolchain() {
|
||||
|
@ -603,22 +623,39 @@ process_toolchain() {
|
|||
check_add_cflags -Wcast-qual
|
||||
check_add_cflags -Wvla
|
||||
check_add_cflags -Wimplicit-function-declaration
|
||||
check_add_cflags -Wmissing-declarations
|
||||
check_add_cflags -Wmissing-prototypes
|
||||
check_add_cflags -Wuninitialized
|
||||
check_add_cflags -Wunused
|
||||
# -Wextra has some tricky cases. Rather than fix them all now, get the
|
||||
# flag for as many files as possible and fix the remaining issues
|
||||
# piecemeal.
|
||||
# https://bugs.chromium.org/p/webm/issues/detail?id=1069
|
||||
check_add_cflags -Wextra
|
||||
# check_add_cflags also adds to cxxflags. gtest does not do well with
|
||||
# -Wundef so add it explicitly to CFLAGS only.
|
||||
# these flags so add them explicitly to CFLAGS only.
|
||||
check_cflags -Wundef && add_cflags_only -Wundef
|
||||
check_cflags -Wframe-larger-than=52000 && \
|
||||
add_cflags_only -Wframe-larger-than=52000
|
||||
if enabled mips || [ -z "${INLINE}" ]; then
|
||||
enabled extra_warnings || check_add_cflags -Wno-unused-function
|
||||
fi
|
||||
# Enforce c89 for c files. Don't be too strict about it though. Allow
|
||||
# gnu extensions like "//" for comments.
|
||||
check_cflags -std=gnu89 && add_cflags_only -std=gnu89
|
||||
# Avoid this warning for third_party C++ sources. Some reorganization
|
||||
# would be needed to apply this only to test/*.cc.
|
||||
check_cflags -Wshorten-64-to-32 && add_cflags_only -Wshorten-64-to-32
|
||||
|
||||
# Quiet gcc 6 vs 7 abi warnings:
|
||||
# https://gcc.gnu.org/bugzilla/show_bug.cgi?id=77728
|
||||
if enabled arm; then
|
||||
check_add_cxxflags -Wno-psabi
|
||||
fi
|
||||
|
||||
# disable some warnings specific to libyuv.
|
||||
check_cxxflags -Wno-missing-declarations \
|
||||
&& LIBYUV_CXXFLAGS="${LIBYUV_CXXFLAGS} -Wno-missing-declarations"
|
||||
check_cxxflags -Wno-missing-prototypes \
|
||||
&& LIBYUV_CXXFLAGS="${LIBYUV_CXXFLAGS} -Wno-missing-prototypes"
|
||||
check_cxxflags -Wno-unused-parameter \
|
||||
&& LIBYUV_CXXFLAGS="${LIBYUV_CXXFLAGS} -Wno-unused-parameter"
|
||||
fi
|
||||
|
||||
if enabled icc; then
|
||||
|
@ -689,7 +726,7 @@ process_toolchain() {
|
|||
soft_enable libyuv
|
||||
;;
|
||||
*-android-*)
|
||||
soft_enable webm_io
|
||||
check_add_cxxflags -std=c++11 && soft_enable webm_io
|
||||
soft_enable libyuv
|
||||
# GTestLog must be modified to use Android logging utilities.
|
||||
;;
|
||||
|
@ -698,30 +735,23 @@ process_toolchain() {
|
|||
# x86 targets.
|
||||
;;
|
||||
*-iphonesimulator-*)
|
||||
soft_enable webm_io
|
||||
check_add_cxxflags -std=c++11 && soft_enable webm_io
|
||||
soft_enable libyuv
|
||||
;;
|
||||
*-win*)
|
||||
# Some mingw toolchains don't have pthread available by default.
|
||||
# Treat these more like visual studio where threading in gtest
|
||||
# would be disabled for the same reason.
|
||||
check_cxx "$@" <<EOF && soft_enable unit_tests
|
||||
int z;
|
||||
EOF
|
||||
check_cxx "$@" <<EOF && soft_enable webm_io
|
||||
int z;
|
||||
EOF
|
||||
check_add_cxxflags -std=c++11 && soft_enable unit_tests \
|
||||
&& soft_enable webm_io
|
||||
check_cxx "$@" <<EOF && soft_enable libyuv
|
||||
int z;
|
||||
EOF
|
||||
;;
|
||||
*)
|
||||
enabled pthread_h && check_cxx "$@" <<EOF && soft_enable unit_tests
|
||||
int z;
|
||||
EOF
|
||||
check_cxx "$@" <<EOF && soft_enable webm_io
|
||||
int z;
|
||||
EOF
|
||||
enabled pthread_h && check_add_cxxflags -std=c++11 \
|
||||
&& soft_enable unit_tests
|
||||
check_add_cxxflags -std=c++11 && soft_enable webm_io
|
||||
check_cxx "$@" <<EOF && soft_enable libyuv
|
||||
int z;
|
||||
EOF
|
||||
|
|
|
@ -23,7 +23,7 @@ LIBYUV_SRCS += third_party/libyuv/include/libyuv/basic_types.h \
|
|||
third_party/libyuv/source/row_any.cc \
|
||||
third_party/libyuv/source/row_common.cc \
|
||||
third_party/libyuv/source/row_gcc.cc \
|
||||
third_party/libyuv/source/row_mips.cc \
|
||||
third_party/libyuv/source/row_msa.cc \
|
||||
third_party/libyuv/source/row_neon.cc \
|
||||
third_party/libyuv/source/row_neon64.cc \
|
||||
third_party/libyuv/source/row_win.cc \
|
||||
|
@ -31,7 +31,7 @@ LIBYUV_SRCS += third_party/libyuv/include/libyuv/basic_types.h \
|
|||
third_party/libyuv/source/scale_any.cc \
|
||||
third_party/libyuv/source/scale_common.cc \
|
||||
third_party/libyuv/source/scale_gcc.cc \
|
||||
third_party/libyuv/source/scale_mips.cc \
|
||||
third_party/libyuv/source/scale_msa.cc \
|
||||
third_party/libyuv/source/scale_neon.cc \
|
||||
third_party/libyuv/source/scale_neon64.cc \
|
||||
third_party/libyuv/source/scale_win.cc \
|
||||
|
@ -72,11 +72,12 @@ vpxdec.SRCS += vpx_ports/vpx_timer.h
|
|||
vpxdec.SRCS += vpx/vpx_integer.h
|
||||
vpxdec.SRCS += args.c args.h
|
||||
vpxdec.SRCS += ivfdec.c ivfdec.h
|
||||
vpxdec.SRCS += y4minput.c y4minput.h
|
||||
vpxdec.SRCS += tools_common.c tools_common.h
|
||||
vpxdec.SRCS += y4menc.c y4menc.h
|
||||
ifeq ($(CONFIG_LIBYUV),yes)
|
||||
vpxdec.SRCS += $(LIBYUV_SRCS)
|
||||
$(BUILD_PFX)third_party/libyuv/%.cc.o: CXXFLAGS += -Wno-unused-parameter
|
||||
$(BUILD_PFX)third_party/libyuv/%.cc.o: CXXFLAGS += ${LIBYUV_CXXFLAGS}
|
||||
endif
|
||||
ifeq ($(CONFIG_WEBM_IO),yes)
|
||||
vpxdec.SRCS += $(LIBWEBM_COMMON_SRCS)
|
||||
|
@ -109,18 +110,20 @@ ifeq ($(CONFIG_WEBM_IO),yes)
|
|||
endif
|
||||
vpxenc.GUID = 548DEC74-7A15-4B2B-AFC3-AA102E7C25C1
|
||||
vpxenc.DESCRIPTION = Full featured encoder
|
||||
ifeq ($(CONFIG_SPATIAL_SVC),yes)
|
||||
|
||||
EXAMPLES-$(CONFIG_VP9_ENCODER) += vp9_spatial_svc_encoder.c
|
||||
vp9_spatial_svc_encoder.SRCS += args.c args.h
|
||||
vp9_spatial_svc_encoder.SRCS += ivfenc.c ivfenc.h
|
||||
vp9_spatial_svc_encoder.SRCS += y4minput.c y4minput.h
|
||||
vp9_spatial_svc_encoder.SRCS += tools_common.c tools_common.h
|
||||
vp9_spatial_svc_encoder.SRCS += video_common.h
|
||||
vp9_spatial_svc_encoder.SRCS += video_writer.h video_writer.c
|
||||
vp9_spatial_svc_encoder.SRCS += vpx_ports/msvc.h
|
||||
vp9_spatial_svc_encoder.SRCS += vpxstats.c vpxstats.h
|
||||
vp9_spatial_svc_encoder.SRCS += examples/svc_encodeframe.c
|
||||
vp9_spatial_svc_encoder.SRCS += examples/svc_context.h
|
||||
vp9_spatial_svc_encoder.GUID = 4A38598D-627D-4505-9C7B-D4020C84100D
|
||||
vp9_spatial_svc_encoder.DESCRIPTION = VP9 Spatial SVC Encoder
|
||||
endif
|
||||
|
||||
ifneq ($(CONFIG_SHARED),yes)
|
||||
EXAMPLES-$(CONFIG_VP9_ENCODER) += resize_util.c
|
||||
|
@ -128,6 +131,7 @@ endif
|
|||
|
||||
EXAMPLES-$(CONFIG_ENCODERS) += vpx_temporal_svc_encoder.c
|
||||
vpx_temporal_svc_encoder.SRCS += ivfenc.c ivfenc.h
|
||||
vpx_temporal_svc_encoder.SRCS += y4minput.c y4minput.h
|
||||
vpx_temporal_svc_encoder.SRCS += tools_common.c tools_common.h
|
||||
vpx_temporal_svc_encoder.SRCS += video_common.h
|
||||
vpx_temporal_svc_encoder.SRCS += video_writer.h video_writer.c
|
||||
|
@ -137,6 +141,7 @@ vpx_temporal_svc_encoder.DESCRIPTION = Temporal SVC Encoder
|
|||
EXAMPLES-$(CONFIG_DECODERS) += simple_decoder.c
|
||||
simple_decoder.GUID = D3BBF1E9-2427-450D-BBFF-B2843C1D44CC
|
||||
simple_decoder.SRCS += ivfdec.h ivfdec.c
|
||||
simple_decoder.SRCS += y4minput.c y4minput.h
|
||||
simple_decoder.SRCS += tools_common.h tools_common.c
|
||||
simple_decoder.SRCS += video_common.h
|
||||
simple_decoder.SRCS += video_reader.h video_reader.c
|
||||
|
@ -146,6 +151,7 @@ simple_decoder.SRCS += vpx_ports/msvc.h
|
|||
simple_decoder.DESCRIPTION = Simplified decoder loop
|
||||
EXAMPLES-$(CONFIG_DECODERS) += postproc.c
|
||||
postproc.SRCS += ivfdec.h ivfdec.c
|
||||
postproc.SRCS += y4minput.c y4minput.h
|
||||
postproc.SRCS += tools_common.h tools_common.c
|
||||
postproc.SRCS += video_common.h
|
||||
postproc.SRCS += video_reader.h video_reader.c
|
||||
|
@ -157,6 +163,7 @@ postproc.DESCRIPTION = Decoder postprocessor control
|
|||
EXAMPLES-$(CONFIG_DECODERS) += decode_to_md5.c
|
||||
decode_to_md5.SRCS += md5_utils.h md5_utils.c
|
||||
decode_to_md5.SRCS += ivfdec.h ivfdec.c
|
||||
decode_to_md5.SRCS += y4minput.c y4minput.h
|
||||
decode_to_md5.SRCS += tools_common.h tools_common.c
|
||||
decode_to_md5.SRCS += video_common.h
|
||||
decode_to_md5.SRCS += video_reader.h video_reader.c
|
||||
|
@ -167,6 +174,7 @@ decode_to_md5.GUID = 59120B9B-2735-4BFE-B022-146CA340FE42
|
|||
decode_to_md5.DESCRIPTION = Frame by frame MD5 checksum
|
||||
EXAMPLES-$(CONFIG_ENCODERS) += simple_encoder.c
|
||||
simple_encoder.SRCS += ivfenc.h ivfenc.c
|
||||
simple_encoder.SRCS += y4minput.c y4minput.h
|
||||
simple_encoder.SRCS += tools_common.h tools_common.c
|
||||
simple_encoder.SRCS += video_common.h
|
||||
simple_encoder.SRCS += video_writer.h video_writer.c
|
||||
|
@ -175,6 +183,7 @@ simple_encoder.GUID = 4607D299-8A71-4D2C-9B1D-071899B6FBFD
|
|||
simple_encoder.DESCRIPTION = Simplified encoder loop
|
||||
EXAMPLES-$(CONFIG_VP9_ENCODER) += vp9_lossless_encoder.c
|
||||
vp9_lossless_encoder.SRCS += ivfenc.h ivfenc.c
|
||||
vp9_lossless_encoder.SRCS += y4minput.c y4minput.h
|
||||
vp9_lossless_encoder.SRCS += tools_common.h tools_common.c
|
||||
vp9_lossless_encoder.SRCS += video_common.h
|
||||
vp9_lossless_encoder.SRCS += video_writer.h video_writer.c
|
||||
|
@ -183,6 +192,7 @@ vp9_lossless_encoder.GUID = B63C7C88-5348-46DC-A5A6-CC151EF93366
|
|||
vp9_lossless_encoder.DESCRIPTION = Simplified lossless VP9 encoder
|
||||
EXAMPLES-$(CONFIG_ENCODERS) += twopass_encoder.c
|
||||
twopass_encoder.SRCS += ivfenc.h ivfenc.c
|
||||
twopass_encoder.SRCS += y4minput.c y4minput.h
|
||||
twopass_encoder.SRCS += tools_common.h tools_common.c
|
||||
twopass_encoder.SRCS += video_common.h
|
||||
twopass_encoder.SRCS += video_writer.h video_writer.c
|
||||
|
@ -191,6 +201,7 @@ twopass_encoder.GUID = 73494FA6-4AF9-4763-8FBB-265C92402FD8
|
|||
twopass_encoder.DESCRIPTION = Two-pass encoder loop
|
||||
EXAMPLES-$(CONFIG_DECODERS) += decode_with_drops.c
|
||||
decode_with_drops.SRCS += ivfdec.h ivfdec.c
|
||||
decode_with_drops.SRCS += y4minput.c y4minput.h
|
||||
decode_with_drops.SRCS += tools_common.h tools_common.c
|
||||
decode_with_drops.SRCS += video_common.h
|
||||
decode_with_drops.SRCS += video_reader.h video_reader.c
|
||||
|
@ -201,6 +212,7 @@ decode_with_drops.GUID = CE5C53C4-8DDA-438A-86ED-0DDD3CDB8D26
|
|||
decode_with_drops.DESCRIPTION = Drops frames while decoding
|
||||
EXAMPLES-$(CONFIG_ENCODERS) += set_maps.c
|
||||
set_maps.SRCS += ivfenc.h ivfenc.c
|
||||
set_maps.SRCS += y4minput.c y4minput.h
|
||||
set_maps.SRCS += tools_common.h tools_common.c
|
||||
set_maps.SRCS += video_common.h
|
||||
set_maps.SRCS += video_writer.h video_writer.c
|
||||
|
@ -209,6 +221,7 @@ set_maps.GUID = ECB2D24D-98B8-4015-A465-A4AF3DCC145F
|
|||
set_maps.DESCRIPTION = Set active and ROI maps
|
||||
EXAMPLES-$(CONFIG_VP8_ENCODER) += vp8cx_set_ref.c
|
||||
vp8cx_set_ref.SRCS += ivfenc.h ivfenc.c
|
||||
vp8cx_set_ref.SRCS += y4minput.c y4minput.h
|
||||
vp8cx_set_ref.SRCS += tools_common.h tools_common.c
|
||||
vp8cx_set_ref.SRCS += video_common.h
|
||||
vp8cx_set_ref.SRCS += video_writer.h video_writer.c
|
||||
|
@ -220,6 +233,7 @@ ifeq ($(CONFIG_VP9_ENCODER),yes)
|
|||
ifeq ($(CONFIG_DECODERS),yes)
|
||||
EXAMPLES-yes += vp9cx_set_ref.c
|
||||
vp9cx_set_ref.SRCS += ivfenc.h ivfenc.c
|
||||
vp9cx_set_ref.SRCS += y4minput.c y4minput.h
|
||||
vp9cx_set_ref.SRCS += tools_common.h tools_common.c
|
||||
vp9cx_set_ref.SRCS += video_common.h
|
||||
vp9cx_set_ref.SRCS += video_writer.h video_writer.c
|
||||
|
@ -232,6 +246,7 @@ ifeq ($(CONFIG_MULTI_RES_ENCODING),yes)
|
|||
ifeq ($(CONFIG_LIBYUV),yes)
|
||||
EXAMPLES-$(CONFIG_VP8_ENCODER) += vp8_multi_resolution_encoder.c
|
||||
vp8_multi_resolution_encoder.SRCS += ivfenc.h ivfenc.c
|
||||
vp8_multi_resolution_encoder.SRCS += y4minput.c y4minput.h
|
||||
vp8_multi_resolution_encoder.SRCS += tools_common.h tools_common.c
|
||||
vp8_multi_resolution_encoder.SRCS += video_writer.h video_writer.c
|
||||
vp8_multi_resolution_encoder.SRCS += vpx_ports/msvc.h
|
||||
|
@ -403,3 +418,4 @@ CLEAN-OBJS += examples.doxy samples.dox $(ALL_EXAMPLES:.c=.dox)
|
|||
DOCS-yes += examples.doxy samples.dox
|
||||
examples.doxy: samples.dox $(ALL_EXAMPLES:.c=.dox)
|
||||
@echo "INPUT += $^" > $@
|
||||
@echo "ENABLED_SECTIONS += samples" >> $@
|
||||
|
|
|
@ -13,11 +13,11 @@
|
|||
* spatial SVC frame
|
||||
*/
|
||||
|
||||
#ifndef VPX_SVC_CONTEXT_H_
|
||||
#define VPX_SVC_CONTEXT_H_
|
||||
#ifndef VPX_EXAMPLES_SVC_CONTEXT_H_
|
||||
#define VPX_EXAMPLES_SVC_CONTEXT_H_
|
||||
|
||||
#include "./vp8cx.h"
|
||||
#include "./vpx_encoder.h"
|
||||
#include "vpx/vp8cx.h"
|
||||
#include "vpx/vpx_encoder.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
|
@ -35,8 +35,6 @@ typedef struct {
|
|||
int temporal_layers; // number of temporal layers
|
||||
int temporal_layering_mode;
|
||||
SVC_LOG_LEVEL log_level; // amount of information to display
|
||||
int log_print; // when set, printf log messages instead of returning the
|
||||
// message with svc_get_message
|
||||
int output_rc_stat; // for outputting rc stats
|
||||
int speed; // speed setting for codec
|
||||
int threads;
|
||||
|
@ -71,7 +69,6 @@ typedef struct SvcInternal {
|
|||
int layer;
|
||||
int use_multiple_frame_contexts;
|
||||
|
||||
char message_buffer[2048];
|
||||
vpx_codec_ctx_t *codec_ctx;
|
||||
} SvcInternal_t;
|
||||
|
||||
|
@ -106,15 +103,10 @@ void vpx_svc_release(SvcContext *svc_ctx);
|
|||
/**
|
||||
* dump accumulated statistics and reset accumulated values
|
||||
*/
|
||||
const char *vpx_svc_dump_statistics(SvcContext *svc_ctx);
|
||||
|
||||
/**
|
||||
* get status message from previous encode
|
||||
*/
|
||||
const char *vpx_svc_get_message(const SvcContext *svc_ctx);
|
||||
void vpx_svc_dump_statistics(SvcContext *svc_ctx);
|
||||
|
||||
#ifdef __cplusplus
|
||||
} // extern "C"
|
||||
#endif
|
||||
|
||||
#endif // VPX_SVC_CONTEXT_H_
|
||||
#endif // VPX_EXAMPLES_SVC_CONTEXT_H_
|
|
@ -22,7 +22,7 @@
|
|||
#include <string.h>
|
||||
#define VPX_DISABLE_CTRL_TYPECHECKS 1
|
||||
#include "./vpx_config.h"
|
||||
#include "vpx/svc_context.h"
|
||||
#include "./svc_context.h"
|
||||
#include "vpx/vp8cx.h"
|
||||
#include "vpx/vpx_encoder.h"
|
||||
#include "vpx_mem/vpx_mem.h"
|
||||
|
@ -95,17 +95,11 @@ static const SvcInternal_t *get_const_svc_internal(const SvcContext *svc_ctx) {
|
|||
return (const SvcInternal_t *)svc_ctx->internal;
|
||||
}
|
||||
|
||||
static void svc_log_reset(SvcContext *svc_ctx) {
|
||||
SvcInternal_t *const si = (SvcInternal_t *)svc_ctx->internal;
|
||||
si->message_buffer[0] = '\0';
|
||||
}
|
||||
|
||||
static int svc_log(SvcContext *svc_ctx, SVC_LOG_LEVEL level, const char *fmt,
|
||||
...) {
|
||||
char buf[512];
|
||||
int retval = 0;
|
||||
va_list ap;
|
||||
SvcInternal_t *const si = get_svc_internal(svc_ctx);
|
||||
|
||||
if (level > svc_ctx->log_level) {
|
||||
return retval;
|
||||
|
@ -115,16 +109,8 @@ static int svc_log(SvcContext *svc_ctx, SVC_LOG_LEVEL level, const char *fmt,
|
|||
retval = vsnprintf(buf, sizeof(buf), fmt, ap);
|
||||
va_end(ap);
|
||||
|
||||
if (svc_ctx->log_print) {
|
||||
printf("%s", buf);
|
||||
} else {
|
||||
strncat(si->message_buffer, buf,
|
||||
sizeof(si->message_buffer) - strlen(si->message_buffer) - 1);
|
||||
}
|
||||
|
||||
if (level == SVC_LOG_ERROR) {
|
||||
si->codec_ctx->err_detail = si->message_buffer;
|
||||
}
|
||||
return retval;
|
||||
}
|
||||
|
||||
|
@ -169,6 +155,7 @@ static vpx_codec_err_t parse_layer_options_from_string(SvcContext *svc_ctx,
|
|||
return VPX_CODEC_INVALID_PARAM;
|
||||
|
||||
input_string = strdup(input);
|
||||
if (input_string == NULL) return VPX_CODEC_MEM_ERROR;
|
||||
token = strtok_r(input_string, delim, &save_ptr);
|
||||
for (i = 0; i < num_layers; ++i) {
|
||||
if (token != NULL) {
|
||||
|
@ -208,6 +195,7 @@ static vpx_codec_err_t parse_options(SvcContext *svc_ctx, const char *options) {
|
|||
|
||||
if (options == NULL) return VPX_CODEC_OK;
|
||||
input_string = strdup(options);
|
||||
if (input_string == NULL) return VPX_CODEC_MEM_ERROR;
|
||||
|
||||
// parse option name
|
||||
option_name = strtok_r(input_string, "=", &input_ptr);
|
||||
|
@ -294,8 +282,8 @@ vpx_codec_err_t vpx_svc_set_options(SvcContext *svc_ctx, const char *options) {
|
|||
return VPX_CODEC_OK;
|
||||
}
|
||||
|
||||
vpx_codec_err_t assign_layer_bitrates(const SvcContext *svc_ctx,
|
||||
vpx_codec_enc_cfg_t *const enc_cfg) {
|
||||
static vpx_codec_err_t assign_layer_bitrates(
|
||||
const SvcContext *svc_ctx, vpx_codec_enc_cfg_t *const enc_cfg) {
|
||||
int i;
|
||||
const SvcInternal_t *const si = get_const_svc_internal(svc_ctx);
|
||||
int sl, tl, spatial_layer_target;
|
||||
|
@ -471,8 +459,7 @@ vpx_codec_err_t vpx_svc_init(SvcContext *svc_ctx, vpx_codec_ctx_t *codec_ctx,
|
|||
svc_log(svc_ctx, SVC_LOG_ERROR,
|
||||
"spatial layers * temporal layers exceeds the maximum number of "
|
||||
"allowed layers of %d\n",
|
||||
svc_ctx->spatial_layers * svc_ctx->temporal_layers,
|
||||
(int)VPX_MAX_LAYERS);
|
||||
svc_ctx->spatial_layers * svc_ctx->temporal_layers, VPX_MAX_LAYERS);
|
||||
return VPX_CODEC_INVALID_PARAM;
|
||||
}
|
||||
res = assign_layer_bitrates(svc_ctx, enc_cfg);
|
||||
|
@ -485,11 +472,6 @@ vpx_codec_err_t vpx_svc_init(SvcContext *svc_ctx, vpx_codec_ctx_t *codec_ctx,
|
|||
return VPX_CODEC_INVALID_PARAM;
|
||||
}
|
||||
|
||||
#if CONFIG_SPATIAL_SVC
|
||||
for (i = 0; i < svc_ctx->spatial_layers; ++i)
|
||||
enc_cfg->ss_enable_auto_alt_ref[i] = si->enable_auto_alt_ref[i];
|
||||
#endif
|
||||
|
||||
if (svc_ctx->temporal_layers > 1) {
|
||||
int i;
|
||||
for (i = 0; i < svc_ctx->temporal_layers; ++i) {
|
||||
|
@ -514,7 +496,17 @@ vpx_codec_err_t vpx_svc_init(SvcContext *svc_ctx, vpx_codec_ctx_t *codec_ctx,
|
|||
enc_cfg->rc_buf_initial_sz = 500;
|
||||
enc_cfg->rc_buf_optimal_sz = 600;
|
||||
enc_cfg->rc_buf_sz = 1000;
|
||||
enc_cfg->rc_dropframe_thresh = 0;
|
||||
}
|
||||
|
||||
for (tl = 0; tl < svc_ctx->temporal_layers; ++tl) {
|
||||
for (sl = 0; sl < svc_ctx->spatial_layers; ++sl) {
|
||||
i = sl * svc_ctx->temporal_layers + tl;
|
||||
if (enc_cfg->rc_end_usage == VPX_CBR &&
|
||||
enc_cfg->g_pass == VPX_RC_ONE_PASS) {
|
||||
si->svc_params.max_quantizers[i] = enc_cfg->rc_max_quantizer;
|
||||
si->svc_params.min_quantizers[i] = enc_cfg->rc_min_quantizer;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (enc_cfg->g_error_resilient == 0 && si->use_multiple_frame_contexts == 0)
|
||||
|
@ -548,8 +540,6 @@ vpx_codec_err_t vpx_svc_encode(SvcContext *svc_ctx, vpx_codec_ctx_t *codec_ctx,
|
|||
return VPX_CODEC_INVALID_PARAM;
|
||||
}
|
||||
|
||||
svc_log_reset(svc_ctx);
|
||||
|
||||
res =
|
||||
vpx_codec_encode(codec_ctx, rawimg, pts, (uint32_t)duration, 0, deadline);
|
||||
if (res != VPX_CODEC_OK) {
|
||||
|
@ -559,56 +549,7 @@ vpx_codec_err_t vpx_svc_encode(SvcContext *svc_ctx, vpx_codec_ctx_t *codec_ctx,
|
|||
iter = NULL;
|
||||
while ((cx_pkt = vpx_codec_get_cx_data(codec_ctx, &iter))) {
|
||||
switch (cx_pkt->kind) {
|
||||
#if CONFIG_SPATIAL_SVC && defined(VPX_TEST_SPATIAL_SVC)
|
||||
case VPX_CODEC_SPATIAL_SVC_LAYER_PSNR: {
|
||||
int i;
|
||||
for (i = 0; i < svc_ctx->spatial_layers; ++i) {
|
||||
int j;
|
||||
svc_log(svc_ctx, SVC_LOG_DEBUG,
|
||||
"SVC frame: %d, layer: %d, PSNR(Total/Y/U/V): "
|
||||
"%2.3f %2.3f %2.3f %2.3f \n",
|
||||
si->psnr_pkt_received, i, cx_pkt->data.layer_psnr[i].psnr[0],
|
||||
cx_pkt->data.layer_psnr[i].psnr[1],
|
||||
cx_pkt->data.layer_psnr[i].psnr[2],
|
||||
cx_pkt->data.layer_psnr[i].psnr[3]);
|
||||
svc_log(svc_ctx, SVC_LOG_DEBUG,
|
||||
"SVC frame: %d, layer: %d, SSE(Total/Y/U/V): "
|
||||
"%2.3f %2.3f %2.3f %2.3f \n",
|
||||
si->psnr_pkt_received, i, cx_pkt->data.layer_psnr[i].sse[0],
|
||||
cx_pkt->data.layer_psnr[i].sse[1],
|
||||
cx_pkt->data.layer_psnr[i].sse[2],
|
||||
cx_pkt->data.layer_psnr[i].sse[3]);
|
||||
|
||||
for (j = 0; j < COMPONENTS; ++j) {
|
||||
si->psnr_sum[i][j] += cx_pkt->data.layer_psnr[i].psnr[j];
|
||||
si->sse_sum[i][j] += cx_pkt->data.layer_psnr[i].sse[j];
|
||||
}
|
||||
}
|
||||
++si->psnr_pkt_received;
|
||||
break;
|
||||
}
|
||||
case VPX_CODEC_SPATIAL_SVC_LAYER_SIZES: {
|
||||
int i;
|
||||
for (i = 0; i < svc_ctx->spatial_layers; ++i)
|
||||
si->bytes_sum[i] += cx_pkt->data.layer_sizes[i];
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
case VPX_CODEC_PSNR_PKT: {
|
||||
#if CONFIG_SPATIAL_SVC && defined(VPX_TEST_SPATIAL_SVC)
|
||||
int j;
|
||||
svc_log(svc_ctx, SVC_LOG_DEBUG,
|
||||
"frame: %d, layer: %d, PSNR(Total/Y/U/V): "
|
||||
"%2.3f %2.3f %2.3f %2.3f \n",
|
||||
si->psnr_pkt_received, 0, cx_pkt->data.layer_psnr[0].psnr[0],
|
||||
cx_pkt->data.layer_psnr[0].psnr[1],
|
||||
cx_pkt->data.layer_psnr[0].psnr[2],
|
||||
cx_pkt->data.layer_psnr[0].psnr[3]);
|
||||
for (j = 0; j < COMPONENTS; ++j) {
|
||||
si->psnr_sum[0][j] += cx_pkt->data.layer_psnr[0].psnr[j];
|
||||
si->sse_sum[0][j] += cx_pkt->data.layer_psnr[0].sse[j];
|
||||
}
|
||||
#endif
|
||||
}
|
||||
++si->psnr_pkt_received;
|
||||
break;
|
||||
|
@ -619,19 +560,13 @@ vpx_codec_err_t vpx_svc_encode(SvcContext *svc_ctx, vpx_codec_ctx_t *codec_ctx,
|
|||
return VPX_CODEC_OK;
|
||||
}
|
||||
|
||||
const char *vpx_svc_get_message(const SvcContext *svc_ctx) {
|
||||
const SvcInternal_t *const si = get_const_svc_internal(svc_ctx);
|
||||
if (svc_ctx == NULL || si == NULL) return NULL;
|
||||
return si->message_buffer;
|
||||
}
|
||||
|
||||
static double calc_psnr(double d) {
|
||||
if (d == 0) return 100;
|
||||
return -10.0 * log(d) / log(10.0);
|
||||
}
|
||||
|
||||
// dump accumulated statistics and reset accumulated values
|
||||
const char *vpx_svc_dump_statistics(SvcContext *svc_ctx) {
|
||||
void vpx_svc_dump_statistics(SvcContext *svc_ctx) {
|
||||
int number_of_frames;
|
||||
int i, j;
|
||||
uint32_t bytes_total = 0;
|
||||
|
@ -641,21 +576,19 @@ const char *vpx_svc_dump_statistics(SvcContext *svc_ctx) {
|
|||
double y_scale;
|
||||
|
||||
SvcInternal_t *const si = get_svc_internal(svc_ctx);
|
||||
if (svc_ctx == NULL || si == NULL) return NULL;
|
||||
|
||||
svc_log_reset(svc_ctx);
|
||||
if (svc_ctx == NULL || si == NULL) return;
|
||||
|
||||
number_of_frames = si->psnr_pkt_received;
|
||||
if (number_of_frames <= 0) return vpx_svc_get_message(svc_ctx);
|
||||
if (number_of_frames <= 0) return;
|
||||
|
||||
svc_log(svc_ctx, SVC_LOG_INFO, "\n");
|
||||
for (i = 0; i < svc_ctx->spatial_layers; ++i) {
|
||||
svc_log(svc_ctx, SVC_LOG_INFO,
|
||||
"Layer %d Average PSNR=[%2.3f, %2.3f, %2.3f, %2.3f], Bytes=[%u]\n",
|
||||
i, (double)si->psnr_sum[i][0] / number_of_frames,
|
||||
(double)si->psnr_sum[i][1] / number_of_frames,
|
||||
(double)si->psnr_sum[i][2] / number_of_frames,
|
||||
(double)si->psnr_sum[i][3] / number_of_frames, si->bytes_sum[i]);
|
||||
i, si->psnr_sum[i][0] / number_of_frames,
|
||||
si->psnr_sum[i][1] / number_of_frames,
|
||||
si->psnr_sum[i][2] / number_of_frames,
|
||||
si->psnr_sum[i][3] / number_of_frames, si->bytes_sum[i]);
|
||||
// the following psnr calculation is deduced from ffmpeg.c#print_report
|
||||
y_scale = si->width * si->height * 255.0 * 255.0 * number_of_frames;
|
||||
scale[1] = y_scale;
|
||||
|
@ -686,7 +619,6 @@ const char *vpx_svc_dump_statistics(SvcContext *svc_ctx) {
|
|||
si->psnr_pkt_received = 0;
|
||||
|
||||
svc_log(svc_ctx, SVC_LOG_INFO, "Total Bytes=[%u]\n", bytes_total);
|
||||
return vpx_svc_get_message(svc_ctx);
|
||||
}
|
||||
|
||||
void vpx_svc_release(SvcContext *svc_ctx) {
|
|
@ -61,7 +61,7 @@ void usage_exit(void) { exit(EXIT_FAILURE); }
|
|||
|
||||
int (*read_frame_p)(FILE *f, vpx_image_t *img);
|
||||
|
||||
static int read_frame(FILE *f, vpx_image_t *img) {
|
||||
static int mulres_read_frame(FILE *f, vpx_image_t *img) {
|
||||
size_t nbytes, to_read;
|
||||
int res = 1;
|
||||
|
||||
|
@ -75,7 +75,7 @@ static int read_frame(FILE *f, vpx_image_t *img) {
|
|||
return res;
|
||||
}
|
||||
|
||||
static int read_frame_by_row(FILE *f, vpx_image_t *img) {
|
||||
static int mulres_read_frame_by_row(FILE *f, vpx_image_t *img) {
|
||||
size_t nbytes, to_read;
|
||||
int res = 1;
|
||||
int plane;
|
||||
|
@ -471,9 +471,9 @@ int main(int argc, char **argv) {
|
|||
die("Failed to allocate image", cfg[i].g_w, cfg[i].g_h);
|
||||
|
||||
if (raw[0].stride[VPX_PLANE_Y] == (int)raw[0].d_w)
|
||||
read_frame_p = read_frame;
|
||||
read_frame_p = mulres_read_frame;
|
||||
else
|
||||
read_frame_p = read_frame_by_row;
|
||||
read_frame_p = mulres_read_frame_by_row;
|
||||
|
||||
for (i = 0; i < NUM_ENCODERS; i++)
|
||||
if (outfile[i]) write_ivf_file_header(outfile[i], &cfg[i], 0);
|
||||
|
|
|
@ -25,13 +25,19 @@
|
|||
#include "../video_writer.h"
|
||||
|
||||
#include "../vpx_ports/vpx_timer.h"
|
||||
#include "vpx/svc_context.h"
|
||||
#include "./svc_context.h"
|
||||
#include "vpx/vp8cx.h"
|
||||
#include "vpx/vpx_encoder.h"
|
||||
#include "../vpxstats.h"
|
||||
#include "vp9/encoder/vp9_encoder.h"
|
||||
#include "./y4minput.h"
|
||||
|
||||
#define OUTPUT_RC_STATS 1
|
||||
|
||||
#define SIMULCAST_MODE 0
|
||||
|
||||
static const arg_def_t outputfile =
|
||||
ARG_DEF("o", "output", 1, "Output filename");
|
||||
static const arg_def_t skip_frames_arg =
|
||||
ARG_DEF("s", "skip-frames", 1, "input frames to skip");
|
||||
static const arg_def_t frames_arg =
|
||||
|
@ -86,6 +92,19 @@ static const arg_def_t aqmode_arg =
|
|||
ARG_DEF("aq", "aqmode", 1, "aq-mode off/on");
|
||||
static const arg_def_t bitrates_arg =
|
||||
ARG_DEF("bl", "bitrates", 1, "bitrates[sl * num_tl + tl]");
|
||||
static const arg_def_t dropframe_thresh_arg =
|
||||
ARG_DEF(NULL, "drop-frame", 1, "Temporal resampling threshold (buf %)");
|
||||
static const struct arg_enum_list tune_content_enum[] = {
|
||||
{ "default", VP9E_CONTENT_DEFAULT },
|
||||
{ "screen", VP9E_CONTENT_SCREEN },
|
||||
{ "film", VP9E_CONTENT_FILM },
|
||||
{ NULL, 0 }
|
||||
};
|
||||
|
||||
static const arg_def_t tune_content_arg = ARG_DEF_ENUM(
|
||||
NULL, "tune-content", 1, "Tune content type", tune_content_enum);
|
||||
static const arg_def_t inter_layer_pred_arg = ARG_DEF(
|
||||
NULL, "inter-layer-pred", 1, "0 - 3: On, Off, Key-frames, Constrained");
|
||||
|
||||
#if CONFIG_VP9_HIGHBITDEPTH
|
||||
static const struct arg_enum_list bitdepth_enum[] = {
|
||||
|
@ -97,6 +116,7 @@ static const arg_def_t bitdepth_arg = ARG_DEF_ENUM(
|
|||
#endif // CONFIG_VP9_HIGHBITDEPTH
|
||||
|
||||
static const arg_def_t *svc_args[] = { &frames_arg,
|
||||
&outputfile,
|
||||
&width_arg,
|
||||
&height_arg,
|
||||
&timebase_arg,
|
||||
|
@ -127,6 +147,9 @@ static const arg_def_t *svc_args[] = { &frames_arg,
|
|||
&speed_arg,
|
||||
&rc_end_usage_arg,
|
||||
&bitrates_arg,
|
||||
&dropframe_thresh_arg,
|
||||
&tune_content_arg,
|
||||
&inter_layer_pred_arg,
|
||||
NULL };
|
||||
|
||||
static const uint32_t default_frames_to_skip = 0;
|
||||
|
@ -145,7 +168,6 @@ static const int32_t default_speed = -1; // -1 means use library default.
|
|||
static const uint32_t default_threads = 0; // zero means use library default.
|
||||
|
||||
typedef struct {
|
||||
const char *input_filename;
|
||||
const char *output_filename;
|
||||
uint32_t frames_to_code;
|
||||
uint32_t frames_to_skip;
|
||||
|
@ -153,12 +175,14 @@ typedef struct {
|
|||
stats_io_t rc_stats;
|
||||
int passes;
|
||||
int pass;
|
||||
int tune_content;
|
||||
int inter_layer_pred;
|
||||
} AppInput;
|
||||
|
||||
static const char *exec_name;
|
||||
|
||||
void usage_exit(void) {
|
||||
fprintf(stderr, "Usage: %s <options> input_filename output_filename\n",
|
||||
fprintf(stderr, "Usage: %s <options> input_filename -o output_filename\n",
|
||||
exec_name);
|
||||
fprintf(stderr, "Options:\n");
|
||||
arg_show_usage(stderr, svc_args);
|
||||
|
@ -217,6 +241,8 @@ static void parse_command_line(int argc, const char **argv_,
|
|||
|
||||
if (arg_match(&arg, &frames_arg, argi)) {
|
||||
app_input->frames_to_code = arg_parse_uint(&arg);
|
||||
} else if (arg_match(&arg, &outputfile, argi)) {
|
||||
app_input->output_filename = arg.val;
|
||||
} else if (arg_match(&arg, &width_arg, argi)) {
|
||||
enc_cfg->g_w = arg_parse_uint(&arg);
|
||||
} else if (arg_match(&arg, &height_arg, argi)) {
|
||||
|
@ -237,6 +263,9 @@ static void parse_command_line(int argc, const char **argv_,
|
|||
#endif
|
||||
} else if (arg_match(&arg, &speed_arg, argi)) {
|
||||
svc_ctx->speed = arg_parse_uint(&arg);
|
||||
if (svc_ctx->speed > 9) {
|
||||
warn("Mapping speed %d to speed 9.\n", svc_ctx->speed);
|
||||
}
|
||||
} else if (arg_match(&arg, &aqmode_arg, argi)) {
|
||||
svc_ctx->aqmode = arg_parse_uint(&arg);
|
||||
} else if (arg_match(&arg, &threads_arg, argi)) {
|
||||
|
@ -251,11 +280,15 @@ static void parse_command_line(int argc, const char **argv_,
|
|||
enc_cfg->kf_min_dist = arg_parse_uint(&arg);
|
||||
enc_cfg->kf_max_dist = enc_cfg->kf_min_dist;
|
||||
} else if (arg_match(&arg, &scale_factors_arg, argi)) {
|
||||
snprintf(string_options, sizeof(string_options), "%s scale-factors=%s",
|
||||
string_options, arg.val);
|
||||
strncat(string_options, " scale-factors=",
|
||||
sizeof(string_options) - strlen(string_options) - 1);
|
||||
strncat(string_options, arg.val,
|
||||
sizeof(string_options) - strlen(string_options) - 1);
|
||||
} else if (arg_match(&arg, &bitrates_arg, argi)) {
|
||||
snprintf(string_options, sizeof(string_options), "%s bitrates=%s",
|
||||
string_options, arg.val);
|
||||
strncat(string_options, " bitrates=",
|
||||
sizeof(string_options) - strlen(string_options) - 1);
|
||||
strncat(string_options, arg.val,
|
||||
sizeof(string_options) - strlen(string_options) - 1);
|
||||
} else if (arg_match(&arg, &passes_arg, argi)) {
|
||||
passes = arg_parse_uint(&arg);
|
||||
if (passes < 1 || passes > 2) {
|
||||
|
@ -269,11 +302,15 @@ static void parse_command_line(int argc, const char **argv_,
|
|||
} else if (arg_match(&arg, &fpf_name_arg, argi)) {
|
||||
fpf_file_name = arg.val;
|
||||
} else if (arg_match(&arg, &min_q_arg, argi)) {
|
||||
snprintf(string_options, sizeof(string_options), "%s min-quantizers=%s",
|
||||
string_options, arg.val);
|
||||
strncat(string_options, " min-quantizers=",
|
||||
sizeof(string_options) - strlen(string_options) - 1);
|
||||
strncat(string_options, arg.val,
|
||||
sizeof(string_options) - strlen(string_options) - 1);
|
||||
} else if (arg_match(&arg, &max_q_arg, argi)) {
|
||||
snprintf(string_options, sizeof(string_options), "%s max-quantizers=%s",
|
||||
string_options, arg.val);
|
||||
strncat(string_options, " max-quantizers=",
|
||||
sizeof(string_options) - strlen(string_options) - 1);
|
||||
strncat(string_options, arg.val,
|
||||
sizeof(string_options) - strlen(string_options) - 1);
|
||||
} else if (arg_match(&arg, &min_bitrate_arg, argi)) {
|
||||
min_bitrate = arg_parse_uint(&arg);
|
||||
} else if (arg_match(&arg, &max_bitrate_arg, argi)) {
|
||||
|
@ -303,6 +340,12 @@ static void parse_command_line(int argc, const char **argv_,
|
|||
break;
|
||||
}
|
||||
#endif // CONFIG_VP9_HIGHBITDEPTH
|
||||
} else if (arg_match(&arg, &dropframe_thresh_arg, argi)) {
|
||||
enc_cfg->rc_dropframe_thresh = arg_parse_uint(&arg);
|
||||
} else if (arg_match(&arg, &tune_content_arg, argi)) {
|
||||
app_input->tune_content = arg_parse_uint(&arg);
|
||||
} else if (arg_match(&arg, &inter_layer_pred_arg, argi)) {
|
||||
app_input->inter_layer_pred = arg_parse_uint(&arg);
|
||||
} else {
|
||||
++argj;
|
||||
}
|
||||
|
@ -358,13 +401,18 @@ static void parse_command_line(int argc, const char **argv_,
|
|||
if (argi[0][0] == '-' && strlen(argi[0]) > 1)
|
||||
die("Error: Unrecognized option %s\n", *argi);
|
||||
|
||||
if (argv[0] == NULL || argv[1] == 0) {
|
||||
if (argv[0] == NULL) {
|
||||
usage_exit();
|
||||
}
|
||||
app_input->input_filename = argv[0];
|
||||
app_input->output_filename = argv[1];
|
||||
app_input->input_ctx.filename = argv[0];
|
||||
free(argv);
|
||||
|
||||
open_input_file(&app_input->input_ctx);
|
||||
if (app_input->input_ctx.file_type == FILE_TYPE_Y4M) {
|
||||
enc_cfg->g_w = app_input->input_ctx.width;
|
||||
enc_cfg->g_h = app_input->input_ctx.height;
|
||||
}
|
||||
|
||||
if (enc_cfg->g_w < 16 || enc_cfg->g_w % 2 || enc_cfg->g_h < 16 ||
|
||||
enc_cfg->g_h % 2)
|
||||
die("Invalid resolution: %d x %d\n", enc_cfg->g_w, enc_cfg->g_h);
|
||||
|
@ -429,7 +477,8 @@ static void set_rate_control_stats(struct RateControlStats *rc,
|
|||
rc->layer_framerate[layer] = framerate / cfg->ts_rate_decimator[tl];
|
||||
if (tl > 0) {
|
||||
rc->layer_pfb[layer] =
|
||||
1000.0 * (cfg->layer_target_bitrate[layer] -
|
||||
1000.0 *
|
||||
(cfg->layer_target_bitrate[layer] -
|
||||
cfg->layer_target_bitrate[layer - 1]) /
|
||||
(rc->layer_framerate[layer] - rc->layer_framerate[layer - 1]);
|
||||
} else {
|
||||
|
@ -502,14 +551,13 @@ static void printout_rate_control_summary(struct RateControlStats *rc,
|
|||
printf("Average, rms-variance, and percent-fluct: %f %f %f \n",
|
||||
rc->avg_st_encoding_bitrate, sqrt(rc->variance_st_encoding_bitrate),
|
||||
perc_fluctuation);
|
||||
if (frame_cnt != tot_num_frames)
|
||||
die("Error: Number of input frames not equal to output encoded frames != "
|
||||
"%d tot_num_frames = %d\n",
|
||||
frame_cnt, tot_num_frames);
|
||||
printf("Num of input, num of encoded (super) frames: %d %d \n", frame_cnt,
|
||||
tot_num_frames);
|
||||
}
|
||||
|
||||
vpx_codec_err_t parse_superframe_index(const uint8_t *data, size_t data_sz,
|
||||
uint64_t sizes[8], int *count) {
|
||||
static vpx_codec_err_t parse_superframe_index(const uint8_t *data,
|
||||
size_t data_sz, uint64_t sizes[8],
|
||||
int *count) {
|
||||
// A chunk ending with a byte matching 0xc0 is an invalid chunk unless
|
||||
// it is a super frame index. If the last byte of real video compression
|
||||
// data is 0xc0 the encoder must add a 0 byte. If we have the marker but
|
||||
|
@ -561,83 +609,356 @@ vpx_codec_err_t parse_superframe_index(const uint8_t *data, size_t data_sz,
|
|||
// bypass/flexible mode. The pattern corresponds to the pattern
|
||||
// VP9E_TEMPORAL_LAYERING_MODE_0101 (temporal_layering_mode == 2) used in
|
||||
// non-flexible mode.
|
||||
void set_frame_flags_bypass_mode(int sl, int tl, int num_spatial_layers,
|
||||
int is_key_frame,
|
||||
static void set_frame_flags_bypass_mode_ex0(
|
||||
int tl, int num_spatial_layers, int is_key_frame,
|
||||
vpx_svc_ref_frame_config_t *ref_frame_config) {
|
||||
int sl;
|
||||
for (sl = 0; sl < num_spatial_layers; ++sl)
|
||||
ref_frame_config->update_buffer_slot[sl] = 0;
|
||||
|
||||
for (sl = 0; sl < num_spatial_layers; ++sl) {
|
||||
if (!tl) {
|
||||
if (!sl) {
|
||||
ref_frame_config->frame_flags[sl] =
|
||||
VP8_EFLAG_NO_REF_GF | VP8_EFLAG_NO_REF_ARF | VP8_EFLAG_NO_UPD_GF |
|
||||
VP8_EFLAG_NO_UPD_ARF;
|
||||
} else {
|
||||
if (is_key_frame) {
|
||||
ref_frame_config->frame_flags[sl] =
|
||||
VP8_EFLAG_NO_REF_LAST | VP8_EFLAG_NO_REF_ARF |
|
||||
VP8_EFLAG_NO_UPD_GF | VP8_EFLAG_NO_UPD_ARF;
|
||||
} else {
|
||||
ref_frame_config->frame_flags[sl] =
|
||||
VP8_EFLAG_NO_REF_ARF | VP8_EFLAG_NO_UPD_GF | VP8_EFLAG_NO_UPD_ARF;
|
||||
}
|
||||
}
|
||||
} else if (tl == 1) {
|
||||
if (!sl) {
|
||||
ref_frame_config->frame_flags[sl] =
|
||||
VP8_EFLAG_NO_REF_GF | VP8_EFLAG_NO_REF_ARF | VP8_EFLAG_NO_UPD_LAST |
|
||||
VP8_EFLAG_NO_UPD_GF;
|
||||
} else {
|
||||
ref_frame_config->frame_flags[sl] =
|
||||
VP8_EFLAG_NO_REF_ARF | VP8_EFLAG_NO_UPD_LAST | VP8_EFLAG_NO_UPD_GF;
|
||||
}
|
||||
}
|
||||
// Set the buffer idx.
|
||||
if (tl == 0) {
|
||||
ref_frame_config->lst_fb_idx[sl] = sl;
|
||||
if (sl)
|
||||
if (sl) {
|
||||
if (is_key_frame) {
|
||||
ref_frame_config->lst_fb_idx[sl] = sl - 1;
|
||||
ref_frame_config->gld_fb_idx[sl] = sl;
|
||||
} else {
|
||||
ref_frame_config->gld_fb_idx[sl] = sl - 1;
|
||||
else
|
||||
}
|
||||
} else {
|
||||
ref_frame_config->gld_fb_idx[sl] = 0;
|
||||
}
|
||||
ref_frame_config->alt_fb_idx[sl] = 0;
|
||||
} else if (tl == 1) {
|
||||
ref_frame_config->lst_fb_idx[sl] = sl;
|
||||
ref_frame_config->gld_fb_idx[sl] = num_spatial_layers + sl - 1;
|
||||
ref_frame_config->alt_fb_idx[sl] = num_spatial_layers + sl;
|
||||
}
|
||||
// Set the reference and update flags.
|
||||
if (!tl) {
|
||||
if (!sl) {
|
||||
// Base spatial and base temporal (sl = 0, tl = 0)
|
||||
ref_frame_config->reference_last[sl] = 1;
|
||||
ref_frame_config->reference_golden[sl] = 0;
|
||||
ref_frame_config->reference_alt_ref[sl] = 0;
|
||||
ref_frame_config->update_buffer_slot[sl] |=
|
||||
1 << ref_frame_config->lst_fb_idx[sl];
|
||||
} else {
|
||||
if (is_key_frame) {
|
||||
ref_frame_config->reference_last[sl] = 1;
|
||||
ref_frame_config->reference_golden[sl] = 0;
|
||||
ref_frame_config->reference_alt_ref[sl] = 0;
|
||||
ref_frame_config->update_buffer_slot[sl] |=
|
||||
1 << ref_frame_config->gld_fb_idx[sl];
|
||||
} else {
|
||||
// Non-zero spatiall layer.
|
||||
ref_frame_config->reference_last[sl] = 1;
|
||||
ref_frame_config->reference_golden[sl] = 1;
|
||||
ref_frame_config->reference_alt_ref[sl] = 1;
|
||||
ref_frame_config->update_buffer_slot[sl] |=
|
||||
1 << ref_frame_config->lst_fb_idx[sl];
|
||||
}
|
||||
}
|
||||
} else if (tl == 1) {
|
||||
if (!sl) {
|
||||
// Base spatial and top temporal (tl = 1)
|
||||
ref_frame_config->reference_last[sl] = 1;
|
||||
ref_frame_config->reference_golden[sl] = 0;
|
||||
ref_frame_config->reference_alt_ref[sl] = 0;
|
||||
ref_frame_config->update_buffer_slot[sl] |=
|
||||
1 << ref_frame_config->alt_fb_idx[sl];
|
||||
} else {
|
||||
// Non-zero spatial.
|
||||
if (sl < num_spatial_layers - 1) {
|
||||
ref_frame_config->reference_last[sl] = 1;
|
||||
ref_frame_config->reference_golden[sl] = 1;
|
||||
ref_frame_config->reference_alt_ref[sl] = 0;
|
||||
ref_frame_config->update_buffer_slot[sl] |=
|
||||
1 << ref_frame_config->alt_fb_idx[sl];
|
||||
} else if (sl == num_spatial_layers - 1) {
|
||||
// Top spatial and top temporal (non-reference -- doesn't update any
|
||||
// reference buffers)
|
||||
ref_frame_config->reference_last[sl] = 1;
|
||||
ref_frame_config->reference_golden[sl] = 1;
|
||||
ref_frame_config->reference_alt_ref[sl] = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Example pattern for 2 spatial layers and 2 temporal layers used in the
|
||||
// bypass/flexible mode, except only 1 spatial layer when temporal_layer_id = 1.
|
||||
static void set_frame_flags_bypass_mode_ex1(
|
||||
int tl, int num_spatial_layers, int is_key_frame,
|
||||
vpx_svc_ref_frame_config_t *ref_frame_config) {
|
||||
int sl;
|
||||
for (sl = 0; sl < num_spatial_layers; ++sl)
|
||||
ref_frame_config->update_buffer_slot[sl] = 0;
|
||||
|
||||
if (tl == 0) {
|
||||
if (is_key_frame) {
|
||||
ref_frame_config->lst_fb_idx[1] = 0;
|
||||
ref_frame_config->gld_fb_idx[1] = 1;
|
||||
} else {
|
||||
ref_frame_config->lst_fb_idx[1] = 1;
|
||||
ref_frame_config->gld_fb_idx[1] = 0;
|
||||
}
|
||||
ref_frame_config->alt_fb_idx[1] = 0;
|
||||
|
||||
ref_frame_config->lst_fb_idx[0] = 0;
|
||||
ref_frame_config->gld_fb_idx[0] = 0;
|
||||
ref_frame_config->alt_fb_idx[0] = 0;
|
||||
}
|
||||
if (tl == 1) {
|
||||
ref_frame_config->lst_fb_idx[0] = 0;
|
||||
ref_frame_config->gld_fb_idx[0] = 1;
|
||||
ref_frame_config->alt_fb_idx[0] = 2;
|
||||
|
||||
ref_frame_config->lst_fb_idx[1] = 1;
|
||||
ref_frame_config->gld_fb_idx[1] = 2;
|
||||
ref_frame_config->alt_fb_idx[1] = 3;
|
||||
}
|
||||
// Set the reference and update flags.
|
||||
if (tl == 0) {
|
||||
// Base spatial and base temporal (sl = 0, tl = 0)
|
||||
ref_frame_config->reference_last[0] = 1;
|
||||
ref_frame_config->reference_golden[0] = 0;
|
||||
ref_frame_config->reference_alt_ref[0] = 0;
|
||||
ref_frame_config->update_buffer_slot[0] |=
|
||||
1 << ref_frame_config->lst_fb_idx[0];
|
||||
|
||||
if (is_key_frame) {
|
||||
ref_frame_config->reference_last[1] = 1;
|
||||
ref_frame_config->reference_golden[1] = 0;
|
||||
ref_frame_config->reference_alt_ref[1] = 0;
|
||||
ref_frame_config->update_buffer_slot[1] |=
|
||||
1 << ref_frame_config->gld_fb_idx[1];
|
||||
} else {
|
||||
// Non-zero spatiall layer.
|
||||
ref_frame_config->reference_last[1] = 1;
|
||||
ref_frame_config->reference_golden[1] = 1;
|
||||
ref_frame_config->reference_alt_ref[1] = 1;
|
||||
ref_frame_config->update_buffer_slot[1] |=
|
||||
1 << ref_frame_config->lst_fb_idx[1];
|
||||
}
|
||||
}
|
||||
if (tl == 1) {
|
||||
// Top spatial and top temporal (non-reference -- doesn't update any
|
||||
// reference buffers)
|
||||
ref_frame_config->reference_last[1] = 1;
|
||||
ref_frame_config->reference_golden[1] = 0;
|
||||
ref_frame_config->reference_alt_ref[1] = 0;
|
||||
}
|
||||
}
|
||||
|
||||
#if CONFIG_VP9_DECODER && !SIMULCAST_MODE
|
||||
static void test_decode(vpx_codec_ctx_t *encoder, vpx_codec_ctx_t *decoder,
|
||||
const int frames_out, int *mismatch_seen) {
|
||||
vpx_image_t enc_img, dec_img;
|
||||
struct vp9_ref_frame ref_enc, ref_dec;
|
||||
if (*mismatch_seen) return;
|
||||
/* Get the internal reference frame */
|
||||
ref_enc.idx = 0;
|
||||
ref_dec.idx = 0;
|
||||
vpx_codec_control(encoder, VP9_GET_REFERENCE, &ref_enc);
|
||||
enc_img = ref_enc.img;
|
||||
vpx_codec_control(decoder, VP9_GET_REFERENCE, &ref_dec);
|
||||
dec_img = ref_dec.img;
|
||||
#if CONFIG_VP9_HIGHBITDEPTH
|
||||
if ((enc_img.fmt & VPX_IMG_FMT_HIGHBITDEPTH) !=
|
||||
(dec_img.fmt & VPX_IMG_FMT_HIGHBITDEPTH)) {
|
||||
if (enc_img.fmt & VPX_IMG_FMT_HIGHBITDEPTH) {
|
||||
vpx_img_alloc(&enc_img, enc_img.fmt - VPX_IMG_FMT_HIGHBITDEPTH,
|
||||
enc_img.d_w, enc_img.d_h, 16);
|
||||
vpx_img_truncate_16_to_8(&enc_img, &ref_enc.img);
|
||||
}
|
||||
if (dec_img.fmt & VPX_IMG_FMT_HIGHBITDEPTH) {
|
||||
vpx_img_alloc(&dec_img, dec_img.fmt - VPX_IMG_FMT_HIGHBITDEPTH,
|
||||
dec_img.d_w, dec_img.d_h, 16);
|
||||
vpx_img_truncate_16_to_8(&dec_img, &ref_dec.img);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
if (!compare_img(&enc_img, &dec_img)) {
|
||||
int y[4], u[4], v[4];
|
||||
#if CONFIG_VP9_HIGHBITDEPTH
|
||||
if (enc_img.fmt & VPX_IMG_FMT_HIGHBITDEPTH) {
|
||||
find_mismatch_high(&enc_img, &dec_img, y, u, v);
|
||||
} else {
|
||||
find_mismatch(&enc_img, &dec_img, y, u, v);
|
||||
}
|
||||
#else
|
||||
find_mismatch(&enc_img, &dec_img, y, u, v);
|
||||
#endif
|
||||
decoder->err = 1;
|
||||
printf(
|
||||
"Encode/decode mismatch on frame %d at"
|
||||
" Y[%d, %d] {%d/%d},"
|
||||
" U[%d, %d] {%d/%d},"
|
||||
" V[%d, %d] {%d/%d}\n",
|
||||
frames_out, y[0], y[1], y[2], y[3], u[0], u[1], u[2], u[3], v[0], v[1],
|
||||
v[2], v[3]);
|
||||
*mismatch_seen = frames_out;
|
||||
}
|
||||
|
||||
vpx_img_free(&enc_img);
|
||||
vpx_img_free(&dec_img);
|
||||
}
|
||||
#endif
|
||||
|
||||
#if OUTPUT_RC_STATS
|
||||
static void svc_output_rc_stats(
|
||||
vpx_codec_ctx_t *codec, vpx_codec_enc_cfg_t *enc_cfg,
|
||||
vpx_svc_layer_id_t *layer_id, const vpx_codec_cx_pkt_t *cx_pkt,
|
||||
struct RateControlStats *rc, VpxVideoWriter **outfile,
|
||||
const uint32_t frame_cnt, const double framerate) {
|
||||
int num_layers_encoded = 0;
|
||||
unsigned int sl, tl;
|
||||
uint64_t sizes[8];
|
||||
uint64_t sizes_parsed[8];
|
||||
int count = 0;
|
||||
double sum_bitrate = 0.0;
|
||||
double sum_bitrate2 = 0.0;
|
||||
vp9_zero(sizes);
|
||||
vp9_zero(sizes_parsed);
|
||||
vpx_codec_control(codec, VP9E_GET_SVC_LAYER_ID, layer_id);
|
||||
parse_superframe_index(cx_pkt->data.frame.buf, cx_pkt->data.frame.sz,
|
||||
sizes_parsed, &count);
|
||||
if (enc_cfg->ss_number_layers == 1) sizes[0] = cx_pkt->data.frame.sz;
|
||||
for (sl = 0; sl < enc_cfg->ss_number_layers; ++sl) {
|
||||
sizes[sl] = 0;
|
||||
if (cx_pkt->data.frame.spatial_layer_encoded[sl]) {
|
||||
sizes[sl] = sizes_parsed[num_layers_encoded];
|
||||
num_layers_encoded++;
|
||||
}
|
||||
}
|
||||
for (sl = 0; sl < enc_cfg->ss_number_layers; ++sl) {
|
||||
unsigned int sl2;
|
||||
uint64_t tot_size = 0;
|
||||
#if SIMULCAST_MODE
|
||||
for (sl2 = 0; sl2 < sl; ++sl2) {
|
||||
if (cx_pkt->data.frame.spatial_layer_encoded[sl2]) tot_size += sizes[sl2];
|
||||
}
|
||||
vpx_video_writer_write_frame(outfile[sl],
|
||||
(uint8_t *)(cx_pkt->data.frame.buf) + tot_size,
|
||||
(size_t)(sizes[sl]), cx_pkt->data.frame.pts);
|
||||
#else
|
||||
for (sl2 = 0; sl2 <= sl; ++sl2) {
|
||||
if (cx_pkt->data.frame.spatial_layer_encoded[sl2]) tot_size += sizes[sl2];
|
||||
}
|
||||
if (tot_size > 0)
|
||||
vpx_video_writer_write_frame(outfile[sl], cx_pkt->data.frame.buf,
|
||||
(size_t)(tot_size), cx_pkt->data.frame.pts);
|
||||
#endif // SIMULCAST_MODE
|
||||
}
|
||||
for (sl = 0; sl < enc_cfg->ss_number_layers; ++sl) {
|
||||
if (cx_pkt->data.frame.spatial_layer_encoded[sl]) {
|
||||
for (tl = layer_id->temporal_layer_id; tl < enc_cfg->ts_number_layers;
|
||||
++tl) {
|
||||
const int layer = sl * enc_cfg->ts_number_layers + tl;
|
||||
++rc->layer_tot_enc_frames[layer];
|
||||
rc->layer_encoding_bitrate[layer] += 8.0 * sizes[sl];
|
||||
// Keep count of rate control stats per layer, for non-key
|
||||
// frames.
|
||||
if (tl == (unsigned int)layer_id->temporal_layer_id &&
|
||||
!(cx_pkt->data.frame.flags & VPX_FRAME_IS_KEY)) {
|
||||
rc->layer_avg_frame_size[layer] += 8.0 * sizes[sl];
|
||||
rc->layer_avg_rate_mismatch[layer] +=
|
||||
fabs(8.0 * sizes[sl] - rc->layer_pfb[layer]) /
|
||||
rc->layer_pfb[layer];
|
||||
++rc->layer_enc_frames[layer];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Update for short-time encoding bitrate states, for moving
|
||||
// window of size rc->window, shifted by rc->window / 2.
|
||||
// Ignore first window segment, due to key frame.
|
||||
if (frame_cnt > (unsigned int)rc->window_size) {
|
||||
for (sl = 0; sl < enc_cfg->ss_number_layers; ++sl) {
|
||||
if (cx_pkt->data.frame.spatial_layer_encoded[sl])
|
||||
sum_bitrate += 0.001 * 8.0 * sizes[sl] * framerate;
|
||||
}
|
||||
if (frame_cnt % rc->window_size == 0) {
|
||||
rc->window_count += 1;
|
||||
rc->avg_st_encoding_bitrate += sum_bitrate / rc->window_size;
|
||||
rc->variance_st_encoding_bitrate +=
|
||||
(sum_bitrate / rc->window_size) * (sum_bitrate / rc->window_size);
|
||||
}
|
||||
}
|
||||
|
||||
// Second shifted window.
|
||||
if (frame_cnt > (unsigned int)(rc->window_size + rc->window_size / 2)) {
|
||||
for (sl = 0; sl < enc_cfg->ss_number_layers; ++sl) {
|
||||
sum_bitrate2 += 0.001 * 8.0 * sizes[sl] * framerate;
|
||||
}
|
||||
|
||||
if (frame_cnt > (unsigned int)(2 * rc->window_size) &&
|
||||
frame_cnt % rc->window_size == 0) {
|
||||
rc->window_count += 1;
|
||||
rc->avg_st_encoding_bitrate += sum_bitrate2 / rc->window_size;
|
||||
rc->variance_st_encoding_bitrate +=
|
||||
(sum_bitrate2 / rc->window_size) * (sum_bitrate2 / rc->window_size);
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
int main(int argc, const char **argv) {
|
||||
AppInput app_input;
|
||||
VpxVideoWriter *writer = NULL;
|
||||
VpxVideoInfo info;
|
||||
vpx_codec_ctx_t codec;
|
||||
vpx_codec_ctx_t encoder;
|
||||
vpx_codec_enc_cfg_t enc_cfg;
|
||||
SvcContext svc_ctx;
|
||||
vpx_svc_frame_drop_t svc_drop_frame;
|
||||
uint32_t i;
|
||||
uint32_t frame_cnt = 0;
|
||||
vpx_image_t raw;
|
||||
vpx_codec_err_t res;
|
||||
int pts = 0; /* PTS starts at 0 */
|
||||
int frame_duration = 1; /* 1 timebase tick per frame */
|
||||
FILE *infile = NULL;
|
||||
int end_of_stream = 0;
|
||||
int frames_received = 0;
|
||||
#if OUTPUT_RC_STATS
|
||||
VpxVideoWriter *outfile[VPX_TS_MAX_LAYERS] = { NULL };
|
||||
VpxVideoWriter *outfile[VPX_SS_MAX_LAYERS] = { NULL };
|
||||
struct RateControlStats rc;
|
||||
vpx_svc_layer_id_t layer_id;
|
||||
vpx_svc_ref_frame_config_t ref_frame_config;
|
||||
unsigned int sl, tl;
|
||||
double sum_bitrate = 0.0;
|
||||
double sum_bitrate2 = 0.0;
|
||||
unsigned int sl;
|
||||
double framerate = 30.0;
|
||||
#endif
|
||||
struct vpx_usec_timer timer;
|
||||
int64_t cx_time = 0;
|
||||
#if CONFIG_INTERNAL_STATS
|
||||
FILE *f = fopen("opsnr.stt", "a");
|
||||
#endif
|
||||
#if CONFIG_VP9_DECODER && !SIMULCAST_MODE
|
||||
int mismatch_seen = 0;
|
||||
vpx_codec_ctx_t decoder;
|
||||
#endif
|
||||
memset(&svc_ctx, 0, sizeof(svc_ctx));
|
||||
svc_ctx.log_print = 1;
|
||||
memset(&app_input, 0, sizeof(AppInput));
|
||||
memset(&info, 0, sizeof(VpxVideoInfo));
|
||||
memset(&layer_id, 0, sizeof(vpx_svc_layer_id_t));
|
||||
memset(&rc, 0, sizeof(struct RateControlStats));
|
||||
exec_name = argv[0];
|
||||
|
||||
/* Setup default input stream settings */
|
||||
app_input.input_ctx.framerate.numerator = 30;
|
||||
app_input.input_ctx.framerate.denominator = 1;
|
||||
app_input.input_ctx.only_i420 = 1;
|
||||
app_input.input_ctx.bit_depth = 0;
|
||||
|
||||
parse_command_line(argc, argv, &app_input, &svc_ctx, &enc_cfg);
|
||||
|
||||
// Y4M reader handles its own allocation.
|
||||
if (app_input.input_ctx.file_type != FILE_TYPE_Y4M) {
|
||||
// Allocate image buffer
|
||||
#if CONFIG_VP9_HIGHBITDEPTH
|
||||
if (!vpx_img_alloc(&raw,
|
||||
|
@ -651,16 +972,23 @@ int main(int argc, const char **argv) {
|
|||
die("Failed to allocate image %dx%d\n", enc_cfg.g_w, enc_cfg.g_h);
|
||||
}
|
||||
#endif // CONFIG_VP9_HIGHBITDEPTH
|
||||
|
||||
if (!(infile = fopen(app_input.input_filename, "rb")))
|
||||
die("Failed to open %s for reading\n", app_input.input_filename);
|
||||
}
|
||||
|
||||
// Initialize codec
|
||||
if (vpx_svc_init(&svc_ctx, &codec, vpx_codec_vp9_cx(), &enc_cfg) !=
|
||||
if (vpx_svc_init(&svc_ctx, &encoder, vpx_codec_vp9_cx(), &enc_cfg) !=
|
||||
VPX_CODEC_OK)
|
||||
die("Failed to initialize encoder\n");
|
||||
#if CONFIG_VP9_DECODER && !SIMULCAST_MODE
|
||||
if (vpx_codec_dec_init(
|
||||
&decoder, get_vpx_decoder_by_name("vp9")->codec_interface(), NULL, 0))
|
||||
die("Failed to initialize decoder\n");
|
||||
#endif
|
||||
|
||||
#if OUTPUT_RC_STATS
|
||||
rc.window_count = 1;
|
||||
rc.window_size = 15; // Silence a static analysis warning.
|
||||
rc.avg_st_encoding_bitrate = 0.0;
|
||||
rc.variance_st_encoding_bitrate = 0.0;
|
||||
if (svc_ctx.output_rc_stat) {
|
||||
set_rate_control_stats(&rc, &enc_cfg);
|
||||
framerate = enc_cfg.g_timebase.den / enc_cfg.g_timebase.num;
|
||||
|
@ -668,6 +996,8 @@ int main(int argc, const char **argv) {
|
|||
#endif
|
||||
|
||||
info.codec_fourcc = VP9_FOURCC;
|
||||
info.frame_width = enc_cfg.g_w;
|
||||
info.frame_height = enc_cfg.g_h;
|
||||
info.time_base.numerator = enc_cfg.g_timebase.num;
|
||||
info.time_base.denominator = enc_cfg.g_timebase.den;
|
||||
|
||||
|
@ -679,43 +1009,65 @@ int main(int argc, const char **argv) {
|
|||
die("Failed to open %s for writing\n", app_input.output_filename);
|
||||
}
|
||||
#if OUTPUT_RC_STATS
|
||||
// For now, just write temporal layer streams.
|
||||
// TODO(marpan): do spatial by re-writing superframe.
|
||||
// Write out spatial layer stream.
|
||||
// TODO(marpan/jianj): allow for writing each spatial and temporal stream.
|
||||
if (svc_ctx.output_rc_stat) {
|
||||
for (tl = 0; tl < enc_cfg.ts_number_layers; ++tl) {
|
||||
for (sl = 0; sl < enc_cfg.ss_number_layers; ++sl) {
|
||||
char file_name[PATH_MAX];
|
||||
|
||||
snprintf(file_name, sizeof(file_name), "%s_t%d.ivf",
|
||||
app_input.output_filename, tl);
|
||||
outfile[tl] = vpx_video_writer_open(file_name, kContainerIVF, &info);
|
||||
if (!outfile[tl]) die("Failed to open %s for writing", file_name);
|
||||
snprintf(file_name, sizeof(file_name), "%s_s%d.ivf",
|
||||
app_input.output_filename, sl);
|
||||
outfile[sl] = vpx_video_writer_open(file_name, kContainerIVF, &info);
|
||||
if (!outfile[sl]) die("Failed to open %s for writing", file_name);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
// skip initial frames
|
||||
for (i = 0; i < app_input.frames_to_skip; ++i) vpx_img_read(&raw, infile);
|
||||
for (i = 0; i < app_input.frames_to_skip; ++i)
|
||||
read_frame(&app_input.input_ctx, &raw);
|
||||
|
||||
if (svc_ctx.speed != -1)
|
||||
vpx_codec_control(&codec, VP8E_SET_CPUUSED, svc_ctx.speed);
|
||||
vpx_codec_control(&encoder, VP8E_SET_CPUUSED, svc_ctx.speed);
|
||||
if (svc_ctx.threads) {
|
||||
vpx_codec_control(&codec, VP9E_SET_TILE_COLUMNS, (svc_ctx.threads >> 1));
|
||||
vpx_codec_control(&encoder, VP9E_SET_TILE_COLUMNS,
|
||||
get_msb(svc_ctx.threads));
|
||||
if (svc_ctx.threads > 1)
|
||||
vpx_codec_control(&codec, VP9E_SET_ROW_MT, 1);
|
||||
vpx_codec_control(&encoder, VP9E_SET_ROW_MT, 1);
|
||||
else
|
||||
vpx_codec_control(&codec, VP9E_SET_ROW_MT, 0);
|
||||
vpx_codec_control(&encoder, VP9E_SET_ROW_MT, 0);
|
||||
}
|
||||
if (svc_ctx.speed >= 5 && svc_ctx.aqmode == 1)
|
||||
vpx_codec_control(&codec, VP9E_SET_AQ_MODE, 3);
|
||||
vpx_codec_control(&encoder, VP9E_SET_AQ_MODE, 3);
|
||||
if (svc_ctx.speed >= 5)
|
||||
vpx_codec_control(&codec, VP8E_SET_STATIC_THRESHOLD, 1);
|
||||
vpx_codec_control(&codec, VP8E_SET_MAX_INTRA_BITRATE_PCT, 900);
|
||||
vpx_codec_control(&encoder, VP8E_SET_STATIC_THRESHOLD, 1);
|
||||
vpx_codec_control(&encoder, VP8E_SET_MAX_INTRA_BITRATE_PCT, 900);
|
||||
|
||||
vpx_codec_control(&encoder, VP9E_SET_SVC_INTER_LAYER_PRED,
|
||||
app_input.inter_layer_pred);
|
||||
|
||||
vpx_codec_control(&encoder, VP9E_SET_NOISE_SENSITIVITY, 0);
|
||||
|
||||
vpx_codec_control(&encoder, VP9E_SET_TUNE_CONTENT, app_input.tune_content);
|
||||
|
||||
svc_drop_frame.framedrop_mode = FULL_SUPERFRAME_DROP;
|
||||
for (sl = 0; sl < (unsigned int)svc_ctx.spatial_layers; ++sl)
|
||||
svc_drop_frame.framedrop_thresh[sl] = enc_cfg.rc_dropframe_thresh;
|
||||
svc_drop_frame.max_consec_drop = INT_MAX;
|
||||
vpx_codec_control(&encoder, VP9E_SET_SVC_FRAME_DROP_LAYER, &svc_drop_frame);
|
||||
|
||||
// Encode frames
|
||||
while (!end_of_stream) {
|
||||
vpx_codec_iter_t iter = NULL;
|
||||
const vpx_codec_cx_pkt_t *cx_pkt;
|
||||
if (frame_cnt >= app_input.frames_to_code || !vpx_img_read(&raw, infile)) {
|
||||
// Example patterns for bypass/flexible mode:
|
||||
// example_pattern = 0: 2 temporal layers, and spatial_layers = 1,2,3. Exact
|
||||
// to fixed SVC patterns. example_pattern = 1: 2 spatial and 2 temporal
|
||||
// layers, with SL0 only has TL0, and SL1 has both TL0 and TL1. This example
|
||||
// uses the extended API.
|
||||
int example_pattern = 0;
|
||||
if (frame_cnt >= app_input.frames_to_code ||
|
||||
!read_frame(&app_input.input_ctx, &raw)) {
|
||||
// We need one extra vpx_svc_encode call at end of stream to flush
|
||||
// encoder and get remaining data
|
||||
end_of_stream = 1;
|
||||
|
@ -723,140 +1075,97 @@ int main(int argc, const char **argv) {
|
|||
|
||||
// For BYPASS/FLEXIBLE mode, set the frame flags (reference and updates)
|
||||
// and the buffer indices for each spatial layer of the current
|
||||
// (super)frame to be encoded. The temporal layer_id for the current frame
|
||||
// also needs to be set.
|
||||
// (super)frame to be encoded. The spatial and temporal layer_id for the
|
||||
// current frame also needs to be set.
|
||||
// TODO(marpan): Should rename the "VP9E_TEMPORAL_LAYERING_MODE_BYPASS"
|
||||
// mode to "VP9E_LAYERING_MODE_BYPASS".
|
||||
if (svc_ctx.temporal_layering_mode == VP9E_TEMPORAL_LAYERING_MODE_BYPASS) {
|
||||
layer_id.spatial_layer_id = 0;
|
||||
// Example for 2 temporal layers.
|
||||
if (frame_cnt % 2 == 0)
|
||||
if (frame_cnt % 2 == 0) {
|
||||
layer_id.temporal_layer_id = 0;
|
||||
else
|
||||
for (i = 0; i < VPX_SS_MAX_LAYERS; i++)
|
||||
layer_id.temporal_layer_id_per_spatial[i] = 0;
|
||||
} else {
|
||||
layer_id.temporal_layer_id = 1;
|
||||
// Note that we only set the temporal layer_id, since we are calling
|
||||
// the encode for the whole superframe. The encoder will internally loop
|
||||
// over all the spatial layers for the current superframe.
|
||||
vpx_codec_control(&codec, VP9E_SET_SVC_LAYER_ID, &layer_id);
|
||||
set_frame_flags_bypass_mode(sl, layer_id.temporal_layer_id,
|
||||
for (i = 0; i < VPX_SS_MAX_LAYERS; i++)
|
||||
layer_id.temporal_layer_id_per_spatial[i] = 1;
|
||||
}
|
||||
if (example_pattern == 1) {
|
||||
// example_pattern 1 is hard-coded for 2 spatial and 2 temporal layers.
|
||||
assert(svc_ctx.spatial_layers == 2);
|
||||
assert(svc_ctx.temporal_layers == 2);
|
||||
if (frame_cnt % 2 == 0) {
|
||||
// Spatial layer 0 and 1 are encoded.
|
||||
layer_id.temporal_layer_id_per_spatial[0] = 0;
|
||||
layer_id.temporal_layer_id_per_spatial[1] = 0;
|
||||
layer_id.spatial_layer_id = 0;
|
||||
} else {
|
||||
// Only spatial layer 1 is encoded here.
|
||||
layer_id.temporal_layer_id_per_spatial[1] = 1;
|
||||
layer_id.spatial_layer_id = 1;
|
||||
}
|
||||
}
|
||||
vpx_codec_control(&encoder, VP9E_SET_SVC_LAYER_ID, &layer_id);
|
||||
// TODO(jianj): Fix the parameter passing for "is_key_frame" in
|
||||
// set_frame_flags_bypass_model() for case of periodic key frames.
|
||||
if (example_pattern == 0) {
|
||||
set_frame_flags_bypass_mode_ex0(layer_id.temporal_layer_id,
|
||||
svc_ctx.spatial_layers, frame_cnt == 0,
|
||||
&ref_frame_config);
|
||||
vpx_codec_control(&codec, VP9E_SET_SVC_REF_FRAME_CONFIG,
|
||||
} else if (example_pattern == 1) {
|
||||
set_frame_flags_bypass_mode_ex1(layer_id.temporal_layer_id,
|
||||
svc_ctx.spatial_layers, frame_cnt == 0,
|
||||
&ref_frame_config);
|
||||
}
|
||||
ref_frame_config.duration[0] = frame_duration * 1;
|
||||
ref_frame_config.duration[1] = frame_duration * 1;
|
||||
|
||||
vpx_codec_control(&encoder, VP9E_SET_SVC_REF_FRAME_CONFIG,
|
||||
&ref_frame_config);
|
||||
// Keep track of input frames, to account for frame drops in rate control
|
||||
// stats/metrics.
|
||||
for (sl = 0; sl < (unsigned int)enc_cfg.ss_number_layers; ++sl) {
|
||||
for (sl = 0; sl < enc_cfg.ss_number_layers; ++sl) {
|
||||
++rc.layer_input_frames[sl * enc_cfg.ts_number_layers +
|
||||
layer_id.temporal_layer_id];
|
||||
}
|
||||
} else {
|
||||
// For the fixed pattern SVC, temporal layer is given by superframe count.
|
||||
unsigned int tl = 0;
|
||||
if (enc_cfg.ts_number_layers == 2)
|
||||
tl = (frame_cnt % 2 != 0);
|
||||
else if (enc_cfg.ts_number_layers == 3) {
|
||||
if (frame_cnt % 2 != 0) tl = 2;
|
||||
if ((frame_cnt > 1) && ((frame_cnt - 2) % 4 == 0)) tl = 1;
|
||||
}
|
||||
for (sl = 0; sl < enc_cfg.ss_number_layers; ++sl)
|
||||
++rc.layer_input_frames[sl * enc_cfg.ts_number_layers + tl];
|
||||
}
|
||||
|
||||
vpx_usec_timer_start(&timer);
|
||||
res = vpx_svc_encode(
|
||||
&svc_ctx, &codec, (end_of_stream ? NULL : &raw), pts, frame_duration,
|
||||
&svc_ctx, &encoder, (end_of_stream ? NULL : &raw), pts, frame_duration,
|
||||
svc_ctx.speed >= 5 ? VPX_DL_REALTIME : VPX_DL_GOOD_QUALITY);
|
||||
vpx_usec_timer_mark(&timer);
|
||||
cx_time += vpx_usec_timer_elapsed(&timer);
|
||||
|
||||
printf("%s", vpx_svc_get_message(&svc_ctx));
|
||||
fflush(stdout);
|
||||
if (res != VPX_CODEC_OK) {
|
||||
die_codec(&codec, "Failed to encode frame");
|
||||
die_codec(&encoder, "Failed to encode frame");
|
||||
}
|
||||
|
||||
while ((cx_pkt = vpx_codec_get_cx_data(&codec, &iter)) != NULL) {
|
||||
while ((cx_pkt = vpx_codec_get_cx_data(&encoder, &iter)) != NULL) {
|
||||
switch (cx_pkt->kind) {
|
||||
case VPX_CODEC_CX_FRAME_PKT: {
|
||||
SvcInternal_t *const si = (SvcInternal_t *)svc_ctx.internal;
|
||||
if (cx_pkt->data.frame.sz > 0) {
|
||||
#if OUTPUT_RC_STATS
|
||||
uint64_t sizes[8];
|
||||
int count = 0;
|
||||
#endif
|
||||
vpx_video_writer_write_frame(writer, cx_pkt->data.frame.buf,
|
||||
cx_pkt->data.frame.sz,
|
||||
cx_pkt->data.frame.pts);
|
||||
#if OUTPUT_RC_STATS
|
||||
// TODO(marpan): Put this (to line728) in separate function.
|
||||
if (svc_ctx.output_rc_stat) {
|
||||
vpx_codec_control(&codec, VP9E_GET_SVC_LAYER_ID, &layer_id);
|
||||
parse_superframe_index(cx_pkt->data.frame.buf,
|
||||
cx_pkt->data.frame.sz, sizes, &count);
|
||||
if (enc_cfg.ss_number_layers == 1)
|
||||
sizes[0] = cx_pkt->data.frame.sz;
|
||||
// Note computing input_layer_frames here won't account for frame
|
||||
// drops in rate control stats.
|
||||
// TODO(marpan): Fix this for non-bypass mode so we can get stats
|
||||
// for dropped frames.
|
||||
if (svc_ctx.temporal_layering_mode !=
|
||||
VP9E_TEMPORAL_LAYERING_MODE_BYPASS) {
|
||||
for (sl = 0; sl < enc_cfg.ss_number_layers; ++sl) {
|
||||
++rc.layer_input_frames[sl * enc_cfg.ts_number_layers +
|
||||
layer_id.temporal_layer_id];
|
||||
}
|
||||
}
|
||||
for (tl = layer_id.temporal_layer_id;
|
||||
tl < enc_cfg.ts_number_layers; ++tl) {
|
||||
vpx_video_writer_write_frame(
|
||||
outfile[tl], cx_pkt->data.frame.buf, cx_pkt->data.frame.sz,
|
||||
cx_pkt->data.frame.pts);
|
||||
}
|
||||
|
||||
for (sl = 0; sl < enc_cfg.ss_number_layers; ++sl) {
|
||||
for (tl = layer_id.temporal_layer_id;
|
||||
tl < enc_cfg.ts_number_layers; ++tl) {
|
||||
const int layer = sl * enc_cfg.ts_number_layers + tl;
|
||||
++rc.layer_tot_enc_frames[layer];
|
||||
rc.layer_encoding_bitrate[layer] += 8.0 * sizes[sl];
|
||||
// Keep count of rate control stats per layer, for non-key
|
||||
// frames.
|
||||
if (tl == (unsigned int)layer_id.temporal_layer_id &&
|
||||
!(cx_pkt->data.frame.flags & VPX_FRAME_IS_KEY)) {
|
||||
rc.layer_avg_frame_size[layer] += 8.0 * sizes[sl];
|
||||
rc.layer_avg_rate_mismatch[layer] +=
|
||||
fabs(8.0 * sizes[sl] - rc.layer_pfb[layer]) /
|
||||
rc.layer_pfb[layer];
|
||||
++rc.layer_enc_frames[layer];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Update for short-time encoding bitrate states, for moving
|
||||
// window of size rc->window, shifted by rc->window / 2.
|
||||
// Ignore first window segment, due to key frame.
|
||||
if (frame_cnt > (unsigned int)rc.window_size) {
|
||||
tl = layer_id.temporal_layer_id;
|
||||
for (sl = 0; sl < enc_cfg.ss_number_layers; ++sl) {
|
||||
sum_bitrate += 0.001 * 8.0 * sizes[sl] * framerate;
|
||||
}
|
||||
if (frame_cnt % rc.window_size == 0) {
|
||||
rc.window_count += 1;
|
||||
rc.avg_st_encoding_bitrate += sum_bitrate / rc.window_size;
|
||||
rc.variance_st_encoding_bitrate +=
|
||||
(sum_bitrate / rc.window_size) *
|
||||
(sum_bitrate / rc.window_size);
|
||||
sum_bitrate = 0.0;
|
||||
}
|
||||
}
|
||||
|
||||
// Second shifted window.
|
||||
if (frame_cnt >
|
||||
(unsigned int)(rc.window_size + rc.window_size / 2)) {
|
||||
tl = layer_id.temporal_layer_id;
|
||||
for (sl = 0; sl < enc_cfg.ss_number_layers; ++sl) {
|
||||
sum_bitrate2 += 0.001 * 8.0 * sizes[sl] * framerate;
|
||||
}
|
||||
|
||||
if (frame_cnt > (unsigned int)(2 * rc.window_size) &&
|
||||
frame_cnt % rc.window_size == 0) {
|
||||
rc.window_count += 1;
|
||||
rc.avg_st_encoding_bitrate += sum_bitrate2 / rc.window_size;
|
||||
rc.variance_st_encoding_bitrate +=
|
||||
(sum_bitrate2 / rc.window_size) *
|
||||
(sum_bitrate2 / rc.window_size);
|
||||
sum_bitrate2 = 0.0;
|
||||
}
|
||||
}
|
||||
svc_output_rc_stats(&encoder, &enc_cfg, &layer_id, cx_pkt, &rc,
|
||||
outfile, frame_cnt, framerate);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
@ -868,6 +1177,11 @@ int main(int argc, const char **argv) {
|
|||
if (enc_cfg.ss_number_layers == 1 && enc_cfg.ts_number_layers == 1)
|
||||
si->bytes_sum[0] += (int)cx_pkt->data.frame.sz;
|
||||
++frames_received;
|
||||
#if CONFIG_VP9_DECODER && !SIMULCAST_MODE
|
||||
if (vpx_codec_decode(&decoder, cx_pkt->data.frame.buf,
|
||||
(unsigned int)cx_pkt->data.frame.sz, NULL, 0))
|
||||
die_codec(&decoder, "Failed to decode frame.");
|
||||
#endif
|
||||
break;
|
||||
}
|
||||
case VPX_CODEC_STATS_PKT: {
|
||||
|
@ -877,6 +1191,19 @@ int main(int argc, const char **argv) {
|
|||
}
|
||||
default: { break; }
|
||||
}
|
||||
|
||||
#if CONFIG_VP9_DECODER && !SIMULCAST_MODE
|
||||
vpx_codec_control(&encoder, VP9E_GET_SVC_LAYER_ID, &layer_id);
|
||||
// Don't look for mismatch on top spatial and top temporal layers as they
|
||||
// are non reference frames.
|
||||
if ((enc_cfg.ss_number_layers > 1 || enc_cfg.ts_number_layers > 1) &&
|
||||
!(layer_id.temporal_layer_id > 0 &&
|
||||
layer_id.temporal_layer_id == (int)enc_cfg.ts_number_layers - 1 &&
|
||||
cx_pkt->data.frame
|
||||
.spatial_layer_encoded[enc_cfg.ss_number_layers - 1])) {
|
||||
test_decode(&encoder, &decoder, frame_cnt, &mismatch_seen);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
if (!end_of_stream) {
|
||||
|
@ -885,41 +1212,45 @@ int main(int argc, const char **argv) {
|
|||
}
|
||||
}
|
||||
|
||||
// Compensate for the extra frame count for the bypass mode.
|
||||
if (svc_ctx.temporal_layering_mode == VP9E_TEMPORAL_LAYERING_MODE_BYPASS) {
|
||||
for (sl = 0; sl < enc_cfg.ss_number_layers; ++sl) {
|
||||
const int layer =
|
||||
sl * enc_cfg.ts_number_layers + layer_id.temporal_layer_id;
|
||||
--rc.layer_input_frames[layer];
|
||||
}
|
||||
}
|
||||
|
||||
printf("Processed %d frames\n", frame_cnt);
|
||||
fclose(infile);
|
||||
|
||||
close_input_file(&app_input.input_ctx);
|
||||
|
||||
#if OUTPUT_RC_STATS
|
||||
if (svc_ctx.output_rc_stat) {
|
||||
printout_rate_control_summary(&rc, &enc_cfg, frame_cnt);
|
||||
printf("\n");
|
||||
}
|
||||
#endif
|
||||
if (vpx_codec_destroy(&codec)) die_codec(&codec, "Failed to destroy codec");
|
||||
if (vpx_codec_destroy(&encoder))
|
||||
die_codec(&encoder, "Failed to destroy codec");
|
||||
if (app_input.passes == 2) stats_close(&app_input.rc_stats, 1);
|
||||
if (writer) {
|
||||
vpx_video_writer_close(writer);
|
||||
}
|
||||
#if OUTPUT_RC_STATS
|
||||
if (svc_ctx.output_rc_stat) {
|
||||
for (tl = 0; tl < enc_cfg.ts_number_layers; ++tl) {
|
||||
vpx_video_writer_close(outfile[tl]);
|
||||
for (sl = 0; sl < enc_cfg.ss_number_layers; ++sl) {
|
||||
vpx_video_writer_close(outfile[sl]);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
#if CONFIG_INTERNAL_STATS
|
||||
if (mismatch_seen) {
|
||||
fprintf(f, "First mismatch occurred in frame %d\n", mismatch_seen);
|
||||
} else {
|
||||
fprintf(f, "No mismatch detected in recon buffers\n");
|
||||
}
|
||||
fclose(f);
|
||||
#endif
|
||||
printf("Frame cnt and encoding time/FPS stats for encoding: %d %f %f \n",
|
||||
frame_cnt, 1000 * (float)cx_time / (double)(frame_cnt * 1000000),
|
||||
1000000 * (double)frame_cnt / (double)cx_time);
|
||||
if (app_input.input_ctx.file_type != FILE_TYPE_Y4M) {
|
||||
vpx_img_free(&raw);
|
||||
}
|
||||
// display average size, psnr
|
||||
printf("%s", vpx_svc_dump_statistics(&svc_ctx));
|
||||
vpx_svc_dump_statistics(&svc_ctx);
|
||||
vpx_svc_release(&svc_ctx);
|
||||
return EXIT_SUCCESS;
|
||||
}
|
||||
|
|
|
@ -68,128 +68,6 @@ void usage_exit() {
|
|||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
static int compare_img(const vpx_image_t *const img1,
|
||||
const vpx_image_t *const img2) {
|
||||
uint32_t l_w = img1->d_w;
|
||||
uint32_t c_w = (img1->d_w + img1->x_chroma_shift) >> img1->x_chroma_shift;
|
||||
const uint32_t c_h =
|
||||
(img1->d_h + img1->y_chroma_shift) >> img1->y_chroma_shift;
|
||||
uint32_t i;
|
||||
int match = 1;
|
||||
|
||||
match &= (img1->fmt == img2->fmt);
|
||||
match &= (img1->d_w == img2->d_w);
|
||||
match &= (img1->d_h == img2->d_h);
|
||||
|
||||
for (i = 0; i < img1->d_h; ++i)
|
||||
match &= (memcmp(img1->planes[VPX_PLANE_Y] + i * img1->stride[VPX_PLANE_Y],
|
||||
img2->planes[VPX_PLANE_Y] + i * img2->stride[VPX_PLANE_Y],
|
||||
l_w) == 0);
|
||||
|
||||
for (i = 0; i < c_h; ++i)
|
||||
match &= (memcmp(img1->planes[VPX_PLANE_U] + i * img1->stride[VPX_PLANE_U],
|
||||
img2->planes[VPX_PLANE_U] + i * img2->stride[VPX_PLANE_U],
|
||||
c_w) == 0);
|
||||
|
||||
for (i = 0; i < c_h; ++i)
|
||||
match &= (memcmp(img1->planes[VPX_PLANE_V] + i * img1->stride[VPX_PLANE_V],
|
||||
img2->planes[VPX_PLANE_V] + i * img2->stride[VPX_PLANE_V],
|
||||
c_w) == 0);
|
||||
|
||||
return match;
|
||||
}
|
||||
|
||||
#define mmin(a, b) ((a) < (b) ? (a) : (b))
|
||||
static void find_mismatch(const vpx_image_t *const img1,
|
||||
const vpx_image_t *const img2, int yloc[4],
|
||||
int uloc[4], int vloc[4]) {
|
||||
const uint32_t bsize = 64;
|
||||
const uint32_t bsizey = bsize >> img1->y_chroma_shift;
|
||||
const uint32_t bsizex = bsize >> img1->x_chroma_shift;
|
||||
const uint32_t c_w =
|
||||
(img1->d_w + img1->x_chroma_shift) >> img1->x_chroma_shift;
|
||||
const uint32_t c_h =
|
||||
(img1->d_h + img1->y_chroma_shift) >> img1->y_chroma_shift;
|
||||
int match = 1;
|
||||
uint32_t i, j;
|
||||
yloc[0] = yloc[1] = yloc[2] = yloc[3] = -1;
|
||||
for (i = 0, match = 1; match && i < img1->d_h; i += bsize) {
|
||||
for (j = 0; match && j < img1->d_w; j += bsize) {
|
||||
int k, l;
|
||||
const int si = mmin(i + bsize, img1->d_h) - i;
|
||||
const int sj = mmin(j + bsize, img1->d_w) - j;
|
||||
for (k = 0; match && k < si; ++k) {
|
||||
for (l = 0; match && l < sj; ++l) {
|
||||
if (*(img1->planes[VPX_PLANE_Y] +
|
||||
(i + k) * img1->stride[VPX_PLANE_Y] + j + l) !=
|
||||
*(img2->planes[VPX_PLANE_Y] +
|
||||
(i + k) * img2->stride[VPX_PLANE_Y] + j + l)) {
|
||||
yloc[0] = i + k;
|
||||
yloc[1] = j + l;
|
||||
yloc[2] = *(img1->planes[VPX_PLANE_Y] +
|
||||
(i + k) * img1->stride[VPX_PLANE_Y] + j + l);
|
||||
yloc[3] = *(img2->planes[VPX_PLANE_Y] +
|
||||
(i + k) * img2->stride[VPX_PLANE_Y] + j + l);
|
||||
match = 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
uloc[0] = uloc[1] = uloc[2] = uloc[3] = -1;
|
||||
for (i = 0, match = 1; match && i < c_h; i += bsizey) {
|
||||
for (j = 0; match && j < c_w; j += bsizex) {
|
||||
int k, l;
|
||||
const int si = mmin(i + bsizey, c_h - i);
|
||||
const int sj = mmin(j + bsizex, c_w - j);
|
||||
for (k = 0; match && k < si; ++k) {
|
||||
for (l = 0; match && l < sj; ++l) {
|
||||
if (*(img1->planes[VPX_PLANE_U] +
|
||||
(i + k) * img1->stride[VPX_PLANE_U] + j + l) !=
|
||||
*(img2->planes[VPX_PLANE_U] +
|
||||
(i + k) * img2->stride[VPX_PLANE_U] + j + l)) {
|
||||
uloc[0] = i + k;
|
||||
uloc[1] = j + l;
|
||||
uloc[2] = *(img1->planes[VPX_PLANE_U] +
|
||||
(i + k) * img1->stride[VPX_PLANE_U] + j + l);
|
||||
uloc[3] = *(img2->planes[VPX_PLANE_U] +
|
||||
(i + k) * img2->stride[VPX_PLANE_U] + j + l);
|
||||
match = 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
vloc[0] = vloc[1] = vloc[2] = vloc[3] = -1;
|
||||
for (i = 0, match = 1; match && i < c_h; i += bsizey) {
|
||||
for (j = 0; match && j < c_w; j += bsizex) {
|
||||
int k, l;
|
||||
const int si = mmin(i + bsizey, c_h - i);
|
||||
const int sj = mmin(j + bsizex, c_w - j);
|
||||
for (k = 0; match && k < si; ++k) {
|
||||
for (l = 0; match && l < sj; ++l) {
|
||||
if (*(img1->planes[VPX_PLANE_V] +
|
||||
(i + k) * img1->stride[VPX_PLANE_V] + j + l) !=
|
||||
*(img2->planes[VPX_PLANE_V] +
|
||||
(i + k) * img2->stride[VPX_PLANE_V] + j + l)) {
|
||||
vloc[0] = i + k;
|
||||
vloc[1] = j + l;
|
||||
vloc[2] = *(img1->planes[VPX_PLANE_V] +
|
||||
(i + k) * img1->stride[VPX_PLANE_V] + j + l);
|
||||
vloc[3] = *(img2->planes[VPX_PLANE_V] +
|
||||
(i + k) * img2->stride[VPX_PLANE_V] + j + l);
|
||||
match = 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void testing_decode(vpx_codec_ctx_t *encoder, vpx_codec_ctx_t *decoder,
|
||||
unsigned int frame_out, int *mismatch_seen) {
|
||||
vpx_image_t enc_img, dec_img;
|
||||
|
|
|
@ -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;
|
||||
}
|
|
@ -19,14 +19,18 @@
|
|||
#include <string.h>
|
||||
|
||||
#include "./vpx_config.h"
|
||||
#include "./y4minput.h"
|
||||
#include "../vpx_ports/vpx_timer.h"
|
||||
#include "vpx/vp8cx.h"
|
||||
#include "vpx/vpx_encoder.h"
|
||||
#include "vpx_ports/bitops.h"
|
||||
|
||||
#include "../tools_common.h"
|
||||
#include "../video_writer.h"
|
||||
|
||||
#define VP8_ROI_MAP 0
|
||||
#define ROI_MAP 0
|
||||
|
||||
#define zero(Dest) memset(&(Dest), 0, sizeof(Dest));
|
||||
|
||||
static const char *exec_name;
|
||||
|
||||
|
@ -89,18 +93,20 @@ struct RateControlMetrics {
|
|||
// in the stream.
|
||||
static void set_rate_control_metrics(struct RateControlMetrics *rc,
|
||||
vpx_codec_enc_cfg_t *cfg) {
|
||||
unsigned int i = 0;
|
||||
int i = 0;
|
||||
// Set the layer (cumulative) framerate and the target layer (non-cumulative)
|
||||
// per-frame-bandwidth, for the rate control encoding stats below.
|
||||
const double framerate = cfg->g_timebase.den / cfg->g_timebase.num;
|
||||
const int ts_number_layers = cfg->ts_number_layers;
|
||||
rc->layer_framerate[0] = framerate / cfg->ts_rate_decimator[0];
|
||||
rc->layer_pfb[0] =
|
||||
1000.0 * rc->layer_target_bitrate[0] / rc->layer_framerate[0];
|
||||
for (i = 0; i < cfg->ts_number_layers; ++i) {
|
||||
for (i = 0; i < ts_number_layers; ++i) {
|
||||
if (i > 0) {
|
||||
rc->layer_framerate[i] = framerate / cfg->ts_rate_decimator[i];
|
||||
rc->layer_pfb[i] = 1000.0 * (rc->layer_target_bitrate[i] -
|
||||
rc->layer_target_bitrate[i - 1]) /
|
||||
rc->layer_pfb[i] =
|
||||
1000.0 *
|
||||
(rc->layer_target_bitrate[i] - rc->layer_target_bitrate[i - 1]) /
|
||||
(rc->layer_framerate[i] - rc->layer_framerate[i - 1]);
|
||||
}
|
||||
rc->layer_input_frames[i] = 0;
|
||||
|
@ -114,6 +120,9 @@ static void set_rate_control_metrics(struct RateControlMetrics *rc,
|
|||
rc->window_size = 15;
|
||||
rc->avg_st_encoding_bitrate = 0.0;
|
||||
rc->variance_st_encoding_bitrate = 0.0;
|
||||
// Target bandwidth for the whole stream.
|
||||
// Set to layer_target_bitrate for highest layer (total bitrate).
|
||||
cfg->rc_target_bitrate = rc->layer_target_bitrate[ts_number_layers - 1];
|
||||
}
|
||||
|
||||
static void printout_rate_control_summary(struct RateControlMetrics *rc,
|
||||
|
@ -164,38 +173,60 @@ static void printout_rate_control_summary(struct RateControlMetrics *rc,
|
|||
die("Error: Number of input frames not equal to output! \n");
|
||||
}
|
||||
|
||||
#if VP8_ROI_MAP
|
||||
static void vp8_set_roi_map(vpx_codec_enc_cfg_t *cfg, vpx_roi_map_t *roi) {
|
||||
#if ROI_MAP
|
||||
static void set_roi_map(const char *enc_name, vpx_codec_enc_cfg_t *cfg,
|
||||
vpx_roi_map_t *roi) {
|
||||
unsigned int i, j;
|
||||
memset(roi, 0, sizeof(*roi));
|
||||
int block_size = 0;
|
||||
uint8_t is_vp8 = strncmp(enc_name, "vp8", 3) == 0 ? 1 : 0;
|
||||
uint8_t is_vp9 = strncmp(enc_name, "vp9", 3) == 0 ? 1 : 0;
|
||||
if (!is_vp8 && !is_vp9) {
|
||||
die("unsupported codec.");
|
||||
}
|
||||
zero(*roi);
|
||||
|
||||
block_size = is_vp9 && !is_vp8 ? 8 : 16;
|
||||
|
||||
// ROI is based on the segments (4 for vp8, 8 for vp9), smallest unit for
|
||||
// segment is 16x16 for vp8, 8x8 for vp9.
|
||||
roi->rows = (cfg->g_h + 15) / 16;
|
||||
roi->cols = (cfg->g_w + 15) / 16;
|
||||
roi->rows = (cfg->g_h + block_size - 1) / block_size;
|
||||
roi->cols = (cfg->g_w + block_size - 1) / block_size;
|
||||
|
||||
// Applies delta QP on the segment blocks, varies from -63 to 63.
|
||||
// Setting to negative means lower QP (better quality).
|
||||
// Below we set delta_q to the extreme (-63) to show strong effect.
|
||||
roi->delta_q[0] = 0;
|
||||
// VP8 uses the first 4 segments. VP9 uses all 8 segments.
|
||||
zero(roi->delta_q);
|
||||
roi->delta_q[1] = -63;
|
||||
roi->delta_q[2] = 0;
|
||||
roi->delta_q[3] = 0;
|
||||
|
||||
// Applies delta loopfilter strength on the segment blocks, varies from -63 to
|
||||
// 63. Setting to positive means stronger loopfilter.
|
||||
roi->delta_lf[0] = 0;
|
||||
roi->delta_lf[1] = 0;
|
||||
roi->delta_lf[2] = 0;
|
||||
roi->delta_lf[3] = 0;
|
||||
// 63. Setting to positive means stronger loopfilter. VP8 uses the first 4
|
||||
// segments. VP9 uses all 8 segments.
|
||||
zero(roi->delta_lf);
|
||||
|
||||
if (is_vp8) {
|
||||
// Applies skip encoding threshold on the segment blocks, varies from 0 to
|
||||
// UINT_MAX. Larger value means more skipping of encoding is possible.
|
||||
// This skip threshold only applies on delta frames.
|
||||
roi->static_threshold[0] = 0;
|
||||
roi->static_threshold[1] = 0;
|
||||
roi->static_threshold[2] = 0;
|
||||
roi->static_threshold[3] = 0;
|
||||
zero(roi->static_threshold);
|
||||
}
|
||||
|
||||
if (is_vp9) {
|
||||
// Apply skip segment. Setting to 1 means this block will be copied from
|
||||
// previous frame.
|
||||
zero(roi->skip);
|
||||
}
|
||||
|
||||
if (is_vp9) {
|
||||
// Apply ref frame segment.
|
||||
// -1 : Do not apply this segment.
|
||||
// 0 : Froce using intra.
|
||||
// 1 : Force using last.
|
||||
// 2 : Force using golden.
|
||||
// 3 : Force using alfref but not used in non-rd pickmode for 0 lag.
|
||||
memset(roi->ref_frame, -1, sizeof(roi->ref_frame));
|
||||
roi->ref_frame[1] = 1;
|
||||
}
|
||||
|
||||
// Use 2 states: 1 is center square, 0 is the rest.
|
||||
roi->roi_map =
|
||||
|
@ -563,12 +594,12 @@ int main(int argc, char **argv) {
|
|||
int layering_mode = 0;
|
||||
int layer_flags[VPX_TS_MAX_PERIODICITY] = { 0 };
|
||||
int flag_periodicity = 1;
|
||||
#if VP8_ROI_MAP
|
||||
#if ROI_MAP
|
||||
vpx_roi_map_t roi;
|
||||
#endif
|
||||
vpx_svc_layer_id_t layer_id = { 0, 0 };
|
||||
vpx_svc_layer_id_t layer_id;
|
||||
const VpxInterface *encoder = NULL;
|
||||
FILE *infile = NULL;
|
||||
struct VpxInputContext input_ctx;
|
||||
struct RateControlMetrics rc;
|
||||
int64_t cx_time = 0;
|
||||
const int min_args_base = 13;
|
||||
|
@ -583,6 +614,15 @@ int main(int argc, char **argv) {
|
|||
double sum_bitrate2 = 0.0;
|
||||
double framerate = 30.0;
|
||||
|
||||
zero(rc.layer_target_bitrate);
|
||||
memset(&layer_id, 0, sizeof(vpx_svc_layer_id_t));
|
||||
memset(&input_ctx, 0, sizeof(input_ctx));
|
||||
/* Setup default input stream settings */
|
||||
input_ctx.framerate.numerator = 30;
|
||||
input_ctx.framerate.denominator = 1;
|
||||
input_ctx.only_i420 = 1;
|
||||
input_ctx.bit_depth = 0;
|
||||
|
||||
exec_name = argv[0];
|
||||
// Check usage and arguments.
|
||||
if (argc < min_args) {
|
||||
|
@ -621,6 +661,9 @@ int main(int argc, char **argv) {
|
|||
die("Invalid number of arguments");
|
||||
}
|
||||
|
||||
input_ctx.filename = argv[1];
|
||||
open_input_file(&input_ctx);
|
||||
|
||||
#if CONFIG_VP9_HIGHBITDEPTH
|
||||
switch (strtol(argv[argc - 1], NULL, 0)) {
|
||||
case 8:
|
||||
|
@ -637,15 +680,23 @@ int main(int argc, char **argv) {
|
|||
break;
|
||||
default: die("Invalid bit depth (8, 10, 12) %s", argv[argc - 1]);
|
||||
}
|
||||
|
||||
// Y4M reader has its own allocation.
|
||||
if (input_ctx.file_type != FILE_TYPE_Y4M) {
|
||||
if (!vpx_img_alloc(
|
||||
&raw, bit_depth == VPX_BITS_8 ? VPX_IMG_FMT_I420 : VPX_IMG_FMT_I42016,
|
||||
&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
|
||||
// Y4M reader has its own allocation.
|
||||
if (input_ctx.file_type != FILE_TYPE_Y4M) {
|
||||
if (!vpx_img_alloc(&raw, VPX_IMG_FMT_I420, width, height, 32)) {
|
||||
die("Failed to allocate image", width, height);
|
||||
}
|
||||
}
|
||||
#endif // CONFIG_VP9_HIGHBITDEPTH
|
||||
|
||||
// Populate encoder configuration.
|
||||
|
@ -675,6 +726,9 @@ int main(int argc, char **argv) {
|
|||
if (speed < 0) {
|
||||
die("Invalid speed setting: must be positive");
|
||||
}
|
||||
if (strncmp(encoder->name, "vp9", 3) == 0 && speed > 9) {
|
||||
warn("Mapping speed %d to speed 9.\n", speed);
|
||||
}
|
||||
|
||||
for (i = min_args_base;
|
||||
(int)i < min_args_base + mode_to_num_layers[layering_mode]; ++i) {
|
||||
|
@ -722,13 +776,15 @@ int main(int argc, char **argv) {
|
|||
|
||||
set_rate_control_metrics(&rc, &cfg);
|
||||
|
||||
// Target bandwidth for the whole stream.
|
||||
// Set to layer_target_bitrate for highest layer (total bitrate).
|
||||
cfg.rc_target_bitrate = rc.layer_target_bitrate[cfg.ts_number_layers - 1];
|
||||
|
||||
// Open input file.
|
||||
if (!(infile = fopen(argv[1], "rb"))) {
|
||||
die("Failed to open %s for reading", argv[1]);
|
||||
if (input_ctx.file_type == FILE_TYPE_Y4M) {
|
||||
if (input_ctx.width != cfg.g_w || input_ctx.height != cfg.g_h) {
|
||||
die("Incorrect width or height: %d x %d", cfg.g_w, cfg.g_h);
|
||||
}
|
||||
if (input_ctx.framerate.numerator != cfg.g_timebase.den ||
|
||||
input_ctx.framerate.denominator != cfg.g_timebase.num) {
|
||||
die("Incorrect framerate: numerator %d denominator %d",
|
||||
cfg.g_timebase.num, cfg.g_timebase.den);
|
||||
}
|
||||
}
|
||||
|
||||
framerate = cfg.g_timebase.den / cfg.g_timebase.num;
|
||||
|
@ -766,8 +822,8 @@ int main(int argc, char **argv) {
|
|||
vpx_codec_control(&codec, VP8E_SET_NOISE_SENSITIVITY, kVp8DenoiserOff);
|
||||
vpx_codec_control(&codec, VP8E_SET_STATIC_THRESHOLD, 1);
|
||||
vpx_codec_control(&codec, VP8E_SET_GF_CBR_BOOST_PCT, 0);
|
||||
#if VP8_ROI_MAP
|
||||
vp8_set_roi_map(&cfg, &roi);
|
||||
#if ROI_MAP
|
||||
set_roi_map(encoder->name, &cfg, &roi);
|
||||
if (vpx_codec_control(&codec, VP8E_SET_ROI_MAP, &roi))
|
||||
die_codec(&codec, "Failed to set ROI map");
|
||||
#endif
|
||||
|
@ -783,7 +839,13 @@ int main(int argc, char **argv) {
|
|||
vpx_codec_control(&codec, VP9E_SET_NOISE_SENSITIVITY, kVp9DenoiserOff);
|
||||
vpx_codec_control(&codec, VP8E_SET_STATIC_THRESHOLD, 1);
|
||||
vpx_codec_control(&codec, VP9E_SET_TUNE_CONTENT, 0);
|
||||
vpx_codec_control(&codec, VP9E_SET_TILE_COLUMNS, (cfg.g_threads >> 1));
|
||||
vpx_codec_control(&codec, VP9E_SET_TILE_COLUMNS, get_msb(cfg.g_threads));
|
||||
#if ROI_MAP
|
||||
set_roi_map(encoder->name, &cfg, &roi);
|
||||
if (vpx_codec_control(&codec, VP9E_SET_ROI_MAP, &roi))
|
||||
die_codec(&codec, "Failed to set ROI map");
|
||||
vpx_codec_control(&codec, VP9E_SET_AQ_MODE, 0);
|
||||
#endif
|
||||
// TODO(marpan/jianj): There is an issue with row-mt for low resolutons at
|
||||
// high speed settings, disable its use for those cases for now.
|
||||
if (cfg.g_threads > 1 && ((cfg.g_w > 320 && cfg.g_h > 240) || speed < 7))
|
||||
|
@ -822,6 +884,7 @@ int main(int argc, char **argv) {
|
|||
layer_id.spatial_layer_id = 0;
|
||||
layer_id.temporal_layer_id =
|
||||
cfg.ts_layer_id[frame_cnt % cfg.ts_periodicity];
|
||||
layer_id.temporal_layer_id_per_spatial[0] = layer_id.temporal_layer_id;
|
||||
if (strncmp(encoder->name, "vp9", 3) == 0) {
|
||||
vpx_codec_control(&codec, VP9E_SET_SVC_LAYER_ID, &layer_id);
|
||||
} else if (strncmp(encoder->name, "vp8", 3) == 0) {
|
||||
|
@ -830,7 +893,7 @@ int main(int argc, char **argv) {
|
|||
}
|
||||
flags = layer_flags[frame_cnt % flag_periodicity];
|
||||
if (layering_mode == 0) flags = 0;
|
||||
frame_avail = vpx_img_read(&raw, infile);
|
||||
frame_avail = read_frame(&input_ctx, &raw);
|
||||
if (frame_avail) ++rc.layer_input_frames[layer_id.temporal_layer_id];
|
||||
vpx_usec_timer_start(&timer);
|
||||
if (vpx_codec_encode(&codec, frame_avail ? &raw : NULL, pts, 1, flags,
|
||||
|
@ -898,7 +961,7 @@ int main(int argc, char **argv) {
|
|||
++frame_cnt;
|
||||
pts += frame_duration;
|
||||
}
|
||||
fclose(infile);
|
||||
close_input_file(&input_ctx);
|
||||
printout_rate_control_summary(&rc, &cfg, frame_cnt);
|
||||
printf("\n");
|
||||
printf("Frame cnt and encoding time/FPS stats for encoding: %d %f %f \n",
|
||||
|
@ -910,6 +973,12 @@ int main(int argc, char **argv) {
|
|||
// Try to rewrite the output file headers with the actual frame count.
|
||||
for (i = 0; i < cfg.ts_number_layers; ++i) vpx_video_writer_close(outfile[i]);
|
||||
|
||||
if (input_ctx.file_type != FILE_TYPE_Y4M) {
|
||||
vpx_img_free(&raw);
|
||||
}
|
||||
|
||||
#if ROI_MAP
|
||||
free(roi.roi_map);
|
||||
#endif
|
||||
return EXIT_SUCCESS;
|
||||
}
|
||||
|
|
|
@ -76,12 +76,12 @@ int ivf_read_frame(FILE *infile, uint8_t **buffer, size_t *bytes_read,
|
|||
size_t frame_size = 0;
|
||||
|
||||
if (fread(raw_header, IVF_FRAME_HDR_SZ, 1, infile) != 1) {
|
||||
if (!feof(infile)) warn("Failed to read frame size\n");
|
||||
if (!feof(infile)) warn("Failed to read frame size");
|
||||
} else {
|
||||
frame_size = mem_get_le32(raw_header);
|
||||
|
||||
if (frame_size > 256 * 1024 * 1024) {
|
||||
warn("Read invalid frame size (%u)\n", (unsigned int)frame_size);
|
||||
warn("Read invalid frame size (%u)", (unsigned int)frame_size);
|
||||
frame_size = 0;
|
||||
}
|
||||
|
||||
|
@ -92,7 +92,7 @@ int ivf_read_frame(FILE *infile, uint8_t **buffer, size_t *bytes_read,
|
|||
*buffer = new_buffer;
|
||||
*buffer_size = 2 * frame_size;
|
||||
} else {
|
||||
warn("Failed to allocate compressed data buffer\n");
|
||||
warn("Failed to allocate compressed data buffer");
|
||||
frame_size = 0;
|
||||
}
|
||||
}
|
||||
|
@ -100,7 +100,7 @@ int ivf_read_frame(FILE *infile, uint8_t **buffer, size_t *bytes_read,
|
|||
|
||||
if (!feof(infile)) {
|
||||
if (fread(*buffer, 1, frame_size, infile) != frame_size) {
|
||||
warn("Failed to read full frame\n");
|
||||
warn("Failed to read full frame");
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
|
|
@ -7,8 +7,8 @@
|
|||
* in the file PATENTS. All contributing project authors may
|
||||
* be found in the AUTHORS file in the root of the source tree.
|
||||
*/
|
||||
#ifndef IVFDEC_H_
|
||||
#define IVFDEC_H_
|
||||
#ifndef VPX_IVFDEC_H_
|
||||
#define VPX_IVFDEC_H_
|
||||
|
||||
#include "./tools_common.h"
|
||||
|
||||
|
@ -25,4 +25,4 @@ int ivf_read_frame(FILE *infile, uint8_t **buffer, size_t *bytes_read,
|
|||
} /* extern "C" */
|
||||
#endif
|
||||
|
||||
#endif // IVFDEC_H_
|
||||
#endif // VPX_IVFDEC_H_
|
||||
|
|
|
@ -7,8 +7,8 @@
|
|||
* in the file PATENTS. All contributing project authors may
|
||||
* be found in the AUTHORS file in the root of the source tree.
|
||||
*/
|
||||
#ifndef IVFENC_H_
|
||||
#define IVFENC_H_
|
||||
#ifndef VPX_IVFENC_H_
|
||||
#define VPX_IVFENC_H_
|
||||
|
||||
#include "./tools_common.h"
|
||||
|
||||
|
@ -30,4 +30,4 @@ void ivf_write_frame_size(FILE *outfile, size_t frame_size);
|
|||
} /* extern "C" */
|
||||
#endif
|
||||
|
||||
#endif // IVFENC_H_
|
||||
#endif // VPX_IVFENC_H_
|
||||
|
|
|
@ -943,18 +943,6 @@ GENERATE_XML = NO
|
|||
|
||||
XML_OUTPUT = xml
|
||||
|
||||
# The XML_SCHEMA tag can be used to specify an XML schema,
|
||||
# which can be used by a validating XML parser to check the
|
||||
# syntax of the XML files.
|
||||
|
||||
XML_SCHEMA =
|
||||
|
||||
# The XML_DTD tag can be used to specify an XML DTD,
|
||||
# which can be used by a validating XML parser to check the
|
||||
# syntax of the XML files.
|
||||
|
||||
XML_DTD =
|
||||
|
||||
# If the XML_PROGRAMLISTING tag is set to YES Doxygen will
|
||||
# dump the program listings (including syntax highlighting
|
||||
# and cross-referencing information) to the XML output. Note that
|
||||
|
|
|
@ -88,7 +88,6 @@ ifeq ($(CONFIG_VP9_ENCODER),yes)
|
|||
CODEC_EXPORTS-yes += $(addprefix $(VP9_PREFIX),$(VP9_CX_EXPORTS))
|
||||
CODEC_SRCS-yes += $(VP9_PREFIX)vp9cx.mk vpx/vp8.h vpx/vp8cx.h
|
||||
INSTALL-LIBS-yes += include/vpx/vp8.h include/vpx/vp8cx.h
|
||||
INSTALL-LIBS-$(CONFIG_SPATIAL_SVC) += include/vpx/svc_context.h
|
||||
INSTALL_MAPS += include/vpx/% $(SRC_PATH_BARE)/$(VP9_PREFIX)/%
|
||||
CODEC_DOC_SRCS += vpx/vp8.h vpx/vp8cx.h
|
||||
CODEC_DOC_SECTIONS += vp9 vp9_encoder
|
||||
|
@ -113,13 +112,6 @@ ifeq ($(CONFIG_DECODERS),yes)
|
|||
CODEC_DOC_SECTIONS += decoder
|
||||
endif
|
||||
|
||||
# Suppress -Wextra warnings in third party code.
|
||||
$(BUILD_PFX)third_party/googletest/%.cc.o: CXXFLAGS += -Wno-missing-field-initializers
|
||||
# Suppress -Wextra warnings in first party code pending investigation.
|
||||
# https://bugs.chromium.org/p/webm/issues/detail?id=1069
|
||||
$(BUILD_PFX)vp8/encoder/onyx_if.c.o: CFLAGS += -Wno-unknown-warning-option -Wno-clobbered
|
||||
$(BUILD_PFX)vp8/decoder/onyxd_if.c.o: CFLAGS += -Wno-unknown-warning-option -Wno-clobbered
|
||||
|
||||
ifeq ($(CONFIG_MSVS),yes)
|
||||
CODEC_LIB=$(if $(CONFIG_STATIC_MSVCRT),vpxmt,vpxmd)
|
||||
GTEST_LIB=$(if $(CONFIG_STATIC_MSVCRT),gtestmt,gtestmd)
|
||||
|
@ -153,9 +145,6 @@ INSTALL-SRCS-$(CONFIG_CODEC_SRCS) += vpx_dsp/x86/bitdepth_conversion_sse2.asm
|
|||
endif
|
||||
CODEC_EXPORTS-yes += vpx/exports_com
|
||||
CODEC_EXPORTS-$(CONFIG_ENCODERS) += vpx/exports_enc
|
||||
ifeq ($(CONFIG_SPATIAL_SVC),yes)
|
||||
CODEC_EXPORTS-$(CONFIG_ENCODERS) += vpx/exports_spatial_svc
|
||||
endif
|
||||
CODEC_EXPORTS-$(CONFIG_DECODERS) += vpx/exports_dec
|
||||
|
||||
INSTALL-LIBS-yes += include/vpx/vpx_codec.h
|
||||
|
@ -206,6 +195,8 @@ vpx.def: $(call enabled,CODEC_EXPORTS)
|
|||
--out=$@ $^
|
||||
CLEAN-OBJS += vpx.def
|
||||
|
||||
vpx.$(VCPROJ_SFX): VCPROJ_SRCS=$(filter-out $(addprefix %, $(ASM_INCLUDES)), $^)
|
||||
|
||||
vpx.$(VCPROJ_SFX): $(CODEC_SRCS) vpx.def
|
||||
@echo " [CREATE] $@"
|
||||
$(qexec)$(GEN_VCPROJ) \
|
||||
|
@ -218,7 +209,15 @@ vpx.$(VCPROJ_SFX): $(CODEC_SRCS) vpx.def
|
|||
--ver=$(CONFIG_VS_VERSION) \
|
||||
--src-path-bare="$(SRC_PATH_BARE)" \
|
||||
--out=$@ $(CFLAGS) \
|
||||
$(filter-out $(addprefix %, $(ASM_INCLUDES)), $^) \
|
||||
$(filter $(SRC_PATH_BARE)/vp8/%.c, $(VCPROJ_SRCS)) \
|
||||
$(filter $(SRC_PATH_BARE)/vp8/%.h, $(VCPROJ_SRCS)) \
|
||||
$(filter $(SRC_PATH_BARE)/vp9/%.c, $(VCPROJ_SRCS)) \
|
||||
$(filter $(SRC_PATH_BARE)/vp9/%.h, $(VCPROJ_SRCS)) \
|
||||
$(filter $(SRC_PATH_BARE)/vpx/%, $(VCPROJ_SRCS)) \
|
||||
$(filter $(SRC_PATH_BARE)/vpx_dsp/%, $(VCPROJ_SRCS)) \
|
||||
$(filter-out $(addprefix $(SRC_PATH_BARE)/, \
|
||||
vp8/%.c vp8/%.h vp9/%.c vp9/%.h vpx/% vpx_dsp/%), \
|
||||
$(VCPROJ_SRCS)) \
|
||||
--src-path-bare="$(SRC_PATH_BARE)" \
|
||||
|
||||
PROJECTS-yes += vpx.$(VCPROJ_SFX)
|
||||
|
@ -233,8 +232,8 @@ OBJS-yes += $(LIBVPX_OBJS)
|
|||
LIBS-$(if yes,$(CONFIG_STATIC)) += $(BUILD_PFX)libvpx.a $(BUILD_PFX)libvpx_g.a
|
||||
$(BUILD_PFX)libvpx_g.a: $(LIBVPX_OBJS)
|
||||
|
||||
SO_VERSION_MAJOR := 5
|
||||
SO_VERSION_MINOR := 0
|
||||
SO_VERSION_MAJOR := 6
|
||||
SO_VERSION_MINOR := 1
|
||||
SO_VERSION_PATCH := 0
|
||||
ifeq ($(filter darwin%,$(TGT_OS)),$(TGT_OS))
|
||||
LIBVPX_SO := libvpx.$(SO_VERSION_MAJOR).dylib
|
||||
|
@ -274,18 +273,6 @@ $(BUILD_PFX)$(LIBVPX_SO): extralibs += -lm
|
|||
$(BUILD_PFX)$(LIBVPX_SO): SONAME = libvpx.so.$(SO_VERSION_MAJOR)
|
||||
$(BUILD_PFX)$(LIBVPX_SO): EXPORTS_FILE = $(EXPORT_FILE)
|
||||
|
||||
libvpx.ver: $(call enabled,CODEC_EXPORTS)
|
||||
@echo " [CREATE] $@"
|
||||
$(qexec)echo "{ global:" > $@
|
||||
$(qexec)for f in $?; do awk '{print $$2";"}' < $$f >>$@; done
|
||||
$(qexec)echo "local: *; };" >> $@
|
||||
CLEAN-OBJS += libvpx.ver
|
||||
|
||||
libvpx.syms: $(call enabled,CODEC_EXPORTS)
|
||||
@echo " [CREATE] $@"
|
||||
$(qexec)awk '{print "_"$$2}' $^ >$@
|
||||
CLEAN-OBJS += libvpx.syms
|
||||
|
||||
libvpx.def: $(call enabled,CODEC_EXPORTS)
|
||||
@echo " [CREATE] $@"
|
||||
$(qexec)echo LIBRARY $(LIBVPX_SO:.dll=) INITINSTANCE TERMINSTANCE > $@
|
||||
|
@ -345,6 +332,18 @@ INSTALL_MAPS += $(LIBSUBDIR)/pkgconfig/%.pc %.pc
|
|||
CLEAN-OBJS += vpx.pc
|
||||
endif
|
||||
|
||||
libvpx.ver: $(call enabled,CODEC_EXPORTS)
|
||||
@echo " [CREATE] $@"
|
||||
$(qexec)echo "{ global:" > $@
|
||||
$(qexec)for f in $?; do awk '{print $$2";"}' < $$f >>$@; done
|
||||
$(qexec)echo "local: *; };" >> $@
|
||||
CLEAN-OBJS += libvpx.ver
|
||||
|
||||
libvpx.syms: $(call enabled,CODEC_EXPORTS)
|
||||
@echo " [CREATE] $@"
|
||||
$(qexec)awk '{print "_"$$2}' $^ >$@
|
||||
CLEAN-OBJS += libvpx.syms
|
||||
|
||||
#
|
||||
# Rule to make assembler configuration file from C configuration file
|
||||
#
|
||||
|
|
|
@ -25,8 +25,10 @@
|
|||
release.
|
||||
- The \ref readme contains instructions on recompiling the sample applications.
|
||||
- Read the \ref usage "usage" for a narrative on codec usage.
|
||||
\if samples
|
||||
- Read the \ref samples "sample code" for examples of how to interact with the
|
||||
codec.
|
||||
\endif
|
||||
- \ref codec reference
|
||||
\if encoder
|
||||
- \ref encoder reference
|
||||
|
|
|
@ -163,7 +163,7 @@ void MD5Final(md5byte digest[16], struct MD5Context *ctx) {
|
|||
*/
|
||||
VPX_NO_UNSIGNED_OVERFLOW_CHECK void MD5Transform(UWORD32 buf[4],
|
||||
UWORD32 const in[16]) {
|
||||
register UWORD32 a, b, c, d;
|
||||
UWORD32 a, b, c, d;
|
||||
|
||||
a = buf[0];
|
||||
b = buf[1];
|
||||
|
|
|
@ -20,8 +20,8 @@
|
|||
* Still in the public domain.
|
||||
*/
|
||||
|
||||
#ifndef MD5_UTILS_H_
|
||||
#define MD5_UTILS_H_
|
||||
#ifndef VPX_MD5_UTILS_H_
|
||||
#define VPX_MD5_UTILS_H_
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
|
@ -46,4 +46,4 @@ void MD5Transform(UWORD32 buf[4], UWORD32 const in[16]);
|
|||
} // extern "C"
|
||||
#endif
|
||||
|
||||
#endif // MD5_UTILS_H_
|
||||
#endif // VPX_MD5_UTILS_H_
|
||||
|
|
|
@ -8,8 +8,8 @@
|
|||
* be found in the AUTHORS file in the root of the source tree.
|
||||
*/
|
||||
|
||||
#ifndef RATE_HIST_H_
|
||||
#define RATE_HIST_H_
|
||||
#ifndef VPX_RATE_HIST_H_
|
||||
#define VPX_RATE_HIST_H_
|
||||
|
||||
#include "vpx/vpx_encoder.h"
|
||||
|
||||
|
@ -37,4 +37,4 @@ void show_rate_histogram(struct rate_hist *hist, const vpx_codec_enc_cfg_t *cfg,
|
|||
} // extern "C"
|
||||
#endif
|
||||
|
||||
#endif // RATE_HIST_H_
|
||||
#endif // VPX_RATE_HIST_H_
|
||||
|
|
|
@ -8,8 +8,8 @@
|
|||
* be found in the AUTHORS file in the root of the source tree.
|
||||
*/
|
||||
|
||||
#ifndef TEST_ACM_RANDOM_H_
|
||||
#define TEST_ACM_RANDOM_H_
|
||||
#ifndef VPX_TEST_ACM_RANDOM_H_
|
||||
#define VPX_TEST_ACM_RANDOM_H_
|
||||
|
||||
#include <assert.h>
|
||||
|
||||
|
@ -34,6 +34,24 @@ class ACMRandom {
|
|||
return (value >> 15) & 0xffff;
|
||||
}
|
||||
|
||||
int32_t Rand20Signed(void) {
|
||||
// Use 20 bits: values between 524287 and -524288.
|
||||
const uint32_t value = random_.Generate(1048576);
|
||||
return static_cast<int32_t>(value) - 524288;
|
||||
}
|
||||
|
||||
int16_t Rand16Signed(void) {
|
||||
// Use 16 bits: values between 32767 and -32768.
|
||||
const uint32_t value = random_.Generate(65536);
|
||||
return static_cast<int16_t>(value) - 32768;
|
||||
}
|
||||
|
||||
int16_t Rand13Signed(void) {
|
||||
// Use 13 bits: values between 4095 and -4096.
|
||||
const uint32_t value = random_.Generate(8192);
|
||||
return static_cast<int16_t>(value) - 4096;
|
||||
}
|
||||
|
||||
int16_t Rand9Signed(void) {
|
||||
// Use 9 bits: values between 255 (0x0FF) and -256 (0x100).
|
||||
const uint32_t value = random_.Generate(512);
|
||||
|
@ -73,4 +91,4 @@ class ACMRandom {
|
|||
|
||||
} // namespace libvpx_test
|
||||
|
||||
#endif // TEST_ACM_RANDOM_H_
|
||||
#endif // VPX_TEST_ACM_RANDOM_H_
|
||||
|
|
|
@ -74,7 +74,7 @@ class ActiveMapRefreshTest
|
|||
::libvpx_test::Encoder *encoder) {
|
||||
::libvpx_test::Y4mVideoSource *y4m_video =
|
||||
static_cast<libvpx_test::Y4mVideoSource *>(video);
|
||||
if (video->frame() == 1) {
|
||||
if (video->frame() == 0) {
|
||||
encoder->Control(VP8E_SET_CPUUSED, cpu_used_);
|
||||
encoder->Control(VP9E_SET_AQ_MODE, kAqModeCyclicRefresh);
|
||||
} else if (video->frame() >= 2 && video->img()) {
|
||||
|
|
|
@ -35,7 +35,7 @@ class ActiveMapTest
|
|||
|
||||
virtual void PreEncodeFrameHook(::libvpx_test::VideoSource *video,
|
||||
::libvpx_test::Encoder *encoder) {
|
||||
if (video->frame() == 1) {
|
||||
if (video->frame() == 0) {
|
||||
encoder->Control(VP8E_SET_CPUUSED, cpu_used_);
|
||||
} else if (video->frame() == 3) {
|
||||
vpx_active_map_t map = vpx_active_map_t();
|
||||
|
|
|
@ -8,8 +8,11 @@
|
|||
* be found in the AUTHORS file in the root of the source tree.
|
||||
*/
|
||||
#include <math.h>
|
||||
#include <tuple>
|
||||
|
||||
#include "test/clear_system_state.h"
|
||||
#include "test/register_state_check.h"
|
||||
#include "test/util.h"
|
||||
#include "third_party/googletest/src/include/gtest/gtest.h"
|
||||
#include "./vpx_dsp_rtcd.h"
|
||||
#include "vpx/vpx_integer.h"
|
||||
|
@ -25,7 +28,10 @@ typedef void (*AddNoiseFunc)(uint8_t *start, const int8_t *noise,
|
|||
int blackclamp, int whiteclamp, int width,
|
||||
int height, int pitch);
|
||||
|
||||
class AddNoiseTest : public ::testing::TestWithParam<AddNoiseFunc> {
|
||||
typedef std::tuple<double, AddNoiseFunc> AddNoiseTestFPParam;
|
||||
|
||||
class AddNoiseTest : public ::testing::Test,
|
||||
public ::testing::WithParamInterface<AddNoiseTestFPParam> {
|
||||
public:
|
||||
virtual void TearDown() { libvpx_test::ClearSystemState(); }
|
||||
virtual ~AddNoiseTest() {}
|
||||
|
@ -44,14 +50,14 @@ TEST_P(AddNoiseTest, CheckNoiseAdded) {
|
|||
const int height = 64;
|
||||
const int image_size = width * height;
|
||||
int8_t noise[kNoiseSize];
|
||||
const int clamp = vpx_setup_noise(4.4, noise, kNoiseSize);
|
||||
const int clamp = vpx_setup_noise(GET_PARAM(0), noise, kNoiseSize);
|
||||
uint8_t *const s =
|
||||
reinterpret_cast<uint8_t *>(vpx_calloc(image_size, sizeof(*s)));
|
||||
ASSERT_TRUE(s != NULL);
|
||||
memset(s, 99, image_size * sizeof(*s));
|
||||
|
||||
ASM_REGISTER_STATE_CHECK(
|
||||
GetParam()(s, noise, clamp, clamp, width, height, width));
|
||||
GET_PARAM(1)(s, noise, clamp, clamp, width, height, width));
|
||||
|
||||
// Check to make sure we don't end up having either the same or no added
|
||||
// noise either vertically or horizontally.
|
||||
|
@ -70,7 +76,7 @@ TEST_P(AddNoiseTest, CheckNoiseAdded) {
|
|||
memset(s, 255, image_size);
|
||||
|
||||
ASM_REGISTER_STATE_CHECK(
|
||||
GetParam()(s, noise, clamp, clamp, width, height, width));
|
||||
GET_PARAM(1)(s, noise, clamp, clamp, width, height, width));
|
||||
|
||||
// Check to make sure don't roll over.
|
||||
for (int i = 0; i < image_size; ++i) {
|
||||
|
@ -81,7 +87,7 @@ TEST_P(AddNoiseTest, CheckNoiseAdded) {
|
|||
memset(s, 0, image_size);
|
||||
|
||||
ASM_REGISTER_STATE_CHECK(
|
||||
GetParam()(s, noise, clamp, clamp, width, height, width));
|
||||
GET_PARAM(1)(s, noise, clamp, clamp, width, height, width));
|
||||
|
||||
// Check to make sure don't roll under.
|
||||
for (int i = 0; i < image_size; ++i) {
|
||||
|
@ -108,7 +114,7 @@ TEST_P(AddNoiseTest, CheckCvsAssembly) {
|
|||
|
||||
srand(0);
|
||||
ASM_REGISTER_STATE_CHECK(
|
||||
GetParam()(s, noise, clamp, clamp, width, height, width));
|
||||
GET_PARAM(1)(s, noise, clamp, clamp, width, height, width));
|
||||
srand(0);
|
||||
ASM_REGISTER_STATE_CHECK(
|
||||
vpx_plane_add_noise_c(d, noise, clamp, clamp, width, height, width));
|
||||
|
@ -121,16 +127,24 @@ TEST_P(AddNoiseTest, CheckCvsAssembly) {
|
|||
vpx_free(s);
|
||||
}
|
||||
|
||||
INSTANTIATE_TEST_CASE_P(C, AddNoiseTest,
|
||||
::testing::Values(vpx_plane_add_noise_c));
|
||||
using std::make_tuple;
|
||||
|
||||
INSTANTIATE_TEST_CASE_P(
|
||||
C, AddNoiseTest,
|
||||
::testing::Values(make_tuple(3.25, vpx_plane_add_noise_c),
|
||||
make_tuple(4.4, vpx_plane_add_noise_c)));
|
||||
|
||||
#if HAVE_SSE2
|
||||
INSTANTIATE_TEST_CASE_P(SSE2, AddNoiseTest,
|
||||
::testing::Values(vpx_plane_add_noise_sse2));
|
||||
INSTANTIATE_TEST_CASE_P(
|
||||
SSE2, AddNoiseTest,
|
||||
::testing::Values(make_tuple(3.25, vpx_plane_add_noise_sse2),
|
||||
make_tuple(4.4, vpx_plane_add_noise_sse2)));
|
||||
#endif
|
||||
|
||||
#if HAVE_MSA
|
||||
INSTANTIATE_TEST_CASE_P(MSA, AddNoiseTest,
|
||||
::testing::Values(vpx_plane_add_noise_msa));
|
||||
INSTANTIATE_TEST_CASE_P(
|
||||
MSA, AddNoiseTest,
|
||||
::testing::Values(make_tuple(3.25, vpx_plane_add_noise_msa),
|
||||
make_tuple(4.4, vpx_plane_add_noise_msa)));
|
||||
#endif
|
||||
} // namespace
|
||||
|
|
|
@ -32,7 +32,7 @@ class AltRefAqSegmentTest
|
|||
|
||||
virtual void PreEncodeFrameHook(::libvpx_test::VideoSource *video,
|
||||
::libvpx_test::Encoder *encoder) {
|
||||
if (video->frame() == 1) {
|
||||
if (video->frame() == 0) {
|
||||
encoder->Control(VP8E_SET_CPUUSED, set_cpu_used_);
|
||||
encoder->Control(VP9E_SET_ALT_REF_AQ, alt_ref_aq_mode_);
|
||||
encoder->Control(VP9E_SET_AQ_MODE, aq_mode_);
|
||||
|
|
|
@ -35,7 +35,7 @@ class AltRefTest : public ::libvpx_test::EncoderTest,
|
|||
|
||||
virtual void PreEncodeFrameHook(libvpx_test::VideoSource *video,
|
||||
libvpx_test::Encoder *encoder) {
|
||||
if (video->frame() == 1) {
|
||||
if (video->frame() == 0) {
|
||||
encoder->Control(VP8E_SET_ENABLEAUTOALTREF, 1);
|
||||
encoder->Control(VP8E_SET_CPUUSED, 3);
|
||||
}
|
||||
|
|
|
@ -3,12 +3,12 @@ Android.mk will build vpx unittests on android.
|
|||
./libvpx/configure --target=armv7-android-gcc --enable-external-build \
|
||||
--enable-postproc --disable-install-srcs --enable-multi-res-encoding \
|
||||
--enable-temporal-denoising --disable-unit-tests --disable-install-docs \
|
||||
--disable-examples --disable-runtime-cpu-detect --sdk-path=$NDK
|
||||
--disable-examples --disable-runtime-cpu-detect
|
||||
|
||||
2) From the parent directory, invoke ndk-build:
|
||||
NDK_PROJECT_PATH=. ndk-build APP_BUILD_SCRIPT=./libvpx/test/android/Android.mk \
|
||||
APP_ABI=armeabi-v7a APP_PLATFORM=android-18 APP_OPTIM=release \
|
||||
APP_STL=gnustl_static
|
||||
APP_STL=c++_static
|
||||
|
||||
Note: Both adb and ndk-build are available prebuilt at:
|
||||
https://chromium.googlesource.com/android_tools
|
||||
|
|
|
@ -31,7 +31,7 @@ class AqSegmentTest
|
|||
|
||||
virtual void PreEncodeFrameHook(::libvpx_test::VideoSource *video,
|
||||
::libvpx_test::Encoder *encoder) {
|
||||
if (video->frame() == 1) {
|
||||
if (video->frame() == 0) {
|
||||
encoder->Control(VP8E_SET_CPUUSED, set_cpu_used_);
|
||||
encoder->Control(VP9E_SET_AQ_MODE, aq_mode_);
|
||||
encoder->Control(VP8E_SET_MAX_INTRA_BITRATE_PCT, 100);
|
||||
|
|
|
@ -11,6 +11,7 @@
|
|||
#include <limits.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <tuple>
|
||||
|
||||
#include "third_party/googletest/src/include/gtest/gtest.h"
|
||||
|
||||
|
@ -22,40 +23,43 @@
|
|||
#include "test/clear_system_state.h"
|
||||
#include "test/register_state_check.h"
|
||||
#include "test/util.h"
|
||||
#include "vpx/vpx_codec.h"
|
||||
#include "vpx_mem/vpx_mem.h"
|
||||
#include "vpx_ports/vpx_timer.h"
|
||||
|
||||
using libvpx_test::ACMRandom;
|
||||
|
||||
namespace {
|
||||
|
||||
template <typename Pixel>
|
||||
class AverageTestBase : public ::testing::Test {
|
||||
public:
|
||||
AverageTestBase(int width, int height) : width_(width), height_(height) {}
|
||||
AverageTestBase(int width, int height)
|
||||
: width_(width), height_(height), source_data_(NULL), source_stride_(0),
|
||||
bit_depth_(8) {}
|
||||
|
||||
static void SetUpTestCase() {
|
||||
source_data_ = reinterpret_cast<uint8_t *>(
|
||||
vpx_memalign(kDataAlignment, kDataBlockSize));
|
||||
}
|
||||
|
||||
static void TearDownTestCase() {
|
||||
virtual void TearDown() {
|
||||
vpx_free(source_data_);
|
||||
source_data_ = NULL;
|
||||
libvpx_test::ClearSystemState();
|
||||
}
|
||||
|
||||
virtual void TearDown() { libvpx_test::ClearSystemState(); }
|
||||
|
||||
protected:
|
||||
// Handle blocks up to 4 blocks 64x64 with stride up to 128
|
||||
static const int kDataAlignment = 16;
|
||||
static const int kDataBlockSize = 64 * 128;
|
||||
|
||||
virtual void SetUp() {
|
||||
source_data_ = reinterpret_cast<Pixel *>(
|
||||
vpx_memalign(kDataAlignment, kDataBlockSize * sizeof(source_data_[0])));
|
||||
ASSERT_TRUE(source_data_ != NULL);
|
||||
source_stride_ = (width_ + 31) & ~31;
|
||||
bit_depth_ = 8;
|
||||
rnd_.Reset(ACMRandom::DeterministicSeed());
|
||||
}
|
||||
|
||||
// Sum Pixels
|
||||
static unsigned int ReferenceAverage8x8(const uint8_t *source, int pitch) {
|
||||
static unsigned int ReferenceAverage8x8(const Pixel *source, int pitch) {
|
||||
unsigned int average = 0;
|
||||
for (int h = 0; h < 8; ++h) {
|
||||
for (int w = 0; w < 8; ++w) average += source[h * pitch + w];
|
||||
|
@ -63,7 +67,7 @@ class AverageTestBase : public ::testing::Test {
|
|||
return ((average + 32) >> 6);
|
||||
}
|
||||
|
||||
static unsigned int ReferenceAverage4x4(const uint8_t *source, int pitch) {
|
||||
static unsigned int ReferenceAverage4x4(const Pixel *source, int pitch) {
|
||||
unsigned int average = 0;
|
||||
for (int h = 0; h < 4; ++h) {
|
||||
for (int w = 0; w < 4; ++w) average += source[h * pitch + w];
|
||||
|
@ -71,7 +75,7 @@ class AverageTestBase : public ::testing::Test {
|
|||
return ((average + 8) >> 4);
|
||||
}
|
||||
|
||||
void FillConstant(uint8_t fill_constant) {
|
||||
void FillConstant(Pixel fill_constant) {
|
||||
for (int i = 0; i < width_ * height_; ++i) {
|
||||
source_data_[i] = fill_constant;
|
||||
}
|
||||
|
@ -79,21 +83,22 @@ class AverageTestBase : public ::testing::Test {
|
|||
|
||||
void FillRandom() {
|
||||
for (int i = 0; i < width_ * height_; ++i) {
|
||||
source_data_[i] = rnd_.Rand8();
|
||||
source_data_[i] = rnd_.Rand16() & ((1 << bit_depth_) - 1);
|
||||
}
|
||||
}
|
||||
|
||||
int width_, height_;
|
||||
static uint8_t *source_data_;
|
||||
Pixel *source_data_;
|
||||
int source_stride_;
|
||||
int bit_depth_;
|
||||
|
||||
ACMRandom rnd_;
|
||||
};
|
||||
typedef unsigned int (*AverageFunction)(const uint8_t *s, int pitch);
|
||||
|
||||
typedef std::tr1::tuple<int, int, int, int, AverageFunction> AvgFunc;
|
||||
typedef std::tuple<int, int, int, int, AverageFunction> AvgFunc;
|
||||
|
||||
class AverageTest : public AverageTestBase,
|
||||
class AverageTest : public AverageTestBase<uint8_t>,
|
||||
public ::testing::WithParamInterface<AvgFunc> {
|
||||
public:
|
||||
AverageTest() : AverageTestBase(GET_PARAM(0), GET_PARAM(1)) {}
|
||||
|
@ -119,12 +124,40 @@ class AverageTest : public AverageTestBase,
|
|||
}
|
||||
};
|
||||
|
||||
#if CONFIG_VP9_HIGHBITDEPTH
|
||||
class AverageTestHBD : public AverageTestBase<uint16_t>,
|
||||
public ::testing::WithParamInterface<AvgFunc> {
|
||||
public:
|
||||
AverageTestHBD() : AverageTestBase(GET_PARAM(0), GET_PARAM(1)) {}
|
||||
|
||||
protected:
|
||||
void CheckAverages() {
|
||||
const int block_size = GET_PARAM(3);
|
||||
unsigned int expected = 0;
|
||||
if (block_size == 8) {
|
||||
expected =
|
||||
ReferenceAverage8x8(source_data_ + GET_PARAM(2), source_stride_);
|
||||
} else if (block_size == 4) {
|
||||
expected =
|
||||
ReferenceAverage4x4(source_data_ + GET_PARAM(2), source_stride_);
|
||||
}
|
||||
|
||||
ASM_REGISTER_STATE_CHECK(GET_PARAM(4)(
|
||||
CONVERT_TO_BYTEPTR(source_data_ + GET_PARAM(2)), source_stride_));
|
||||
unsigned int actual = GET_PARAM(4)(
|
||||
CONVERT_TO_BYTEPTR(source_data_ + GET_PARAM(2)), source_stride_);
|
||||
|
||||
EXPECT_EQ(expected, actual);
|
||||
}
|
||||
};
|
||||
#endif // CONFIG_VP9_HIGHBITDEPTH
|
||||
|
||||
typedef void (*IntProRowFunc)(int16_t hbuf[16], uint8_t const *ref,
|
||||
const int ref_stride, const int height);
|
||||
|
||||
typedef std::tr1::tuple<int, IntProRowFunc, IntProRowFunc> IntProRowParam;
|
||||
typedef std::tuple<int, IntProRowFunc, IntProRowFunc> IntProRowParam;
|
||||
|
||||
class IntProRowTest : public AverageTestBase,
|
||||
class IntProRowTest : public AverageTestBase<uint8_t>,
|
||||
public ::testing::WithParamInterface<IntProRowParam> {
|
||||
public:
|
||||
IntProRowTest()
|
||||
|
@ -135,6 +168,10 @@ class IntProRowTest : public AverageTestBase,
|
|||
|
||||
protected:
|
||||
virtual void SetUp() {
|
||||
source_data_ = reinterpret_cast<uint8_t *>(
|
||||
vpx_memalign(kDataAlignment, kDataBlockSize * sizeof(source_data_[0])));
|
||||
ASSERT_TRUE(source_data_ != NULL);
|
||||
|
||||
hbuf_asm_ = reinterpret_cast<int16_t *>(
|
||||
vpx_memalign(kDataAlignment, sizeof(*hbuf_asm_) * 16));
|
||||
hbuf_c_ = reinterpret_cast<int16_t *>(
|
||||
|
@ -142,6 +179,8 @@ class IntProRowTest : public AverageTestBase,
|
|||
}
|
||||
|
||||
virtual void TearDown() {
|
||||
vpx_free(source_data_);
|
||||
source_data_ = NULL;
|
||||
vpx_free(hbuf_c_);
|
||||
hbuf_c_ = NULL;
|
||||
vpx_free(hbuf_asm_);
|
||||
|
@ -164,9 +203,9 @@ class IntProRowTest : public AverageTestBase,
|
|||
|
||||
typedef int16_t (*IntProColFunc)(uint8_t const *ref, const int width);
|
||||
|
||||
typedef std::tr1::tuple<int, IntProColFunc, IntProColFunc> IntProColParam;
|
||||
typedef std::tuple<int, IntProColFunc, IntProColFunc> IntProColParam;
|
||||
|
||||
class IntProColTest : public AverageTestBase,
|
||||
class IntProColTest : public AverageTestBase<uint8_t>,
|
||||
public ::testing::WithParamInterface<IntProColParam> {
|
||||
public:
|
||||
IntProColTest() : AverageTestBase(GET_PARAM(0), 1), sum_asm_(0), sum_c_(0) {
|
||||
|
@ -189,7 +228,7 @@ class IntProColTest : public AverageTestBase,
|
|||
};
|
||||
|
||||
typedef int (*SatdFunc)(const tran_low_t *coeffs, int length);
|
||||
typedef std::tr1::tuple<int, SatdFunc> SatdTestParam;
|
||||
typedef std::tuple<int, SatdFunc> SatdTestParam;
|
||||
|
||||
class SatdTest : public ::testing::Test,
|
||||
public ::testing::WithParamInterface<SatdTestParam> {
|
||||
|
@ -212,12 +251,7 @@ class SatdTest : public ::testing::Test,
|
|||
for (int i = 0; i < satd_size_; ++i) src_[i] = val;
|
||||
}
|
||||
|
||||
void FillRandom() {
|
||||
for (int i = 0; i < satd_size_; ++i) {
|
||||
const int16_t tmp = rnd_.Rand16();
|
||||
src_[i] = (tran_low_t)tmp;
|
||||
}
|
||||
}
|
||||
virtual void FillRandom() = 0;
|
||||
|
||||
void Check(const int expected) {
|
||||
int total;
|
||||
|
@ -225,17 +259,29 @@ class SatdTest : public ::testing::Test,
|
|||
EXPECT_EQ(expected, total);
|
||||
}
|
||||
|
||||
tran_low_t *GetCoeff() const { return src_; }
|
||||
|
||||
int satd_size_;
|
||||
ACMRandom rnd_;
|
||||
tran_low_t *src_;
|
||||
|
||||
private:
|
||||
tran_low_t *src_;
|
||||
SatdFunc satd_func_;
|
||||
ACMRandom rnd_;
|
||||
};
|
||||
|
||||
class SatdLowbdTest : public SatdTest {
|
||||
protected:
|
||||
virtual void FillRandom() {
|
||||
for (int i = 0; i < satd_size_; ++i) {
|
||||
const int16_t tmp = rnd_.Rand16Signed();
|
||||
src_[i] = (tran_low_t)tmp;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
typedef int64_t (*BlockErrorFunc)(const tran_low_t *coeff,
|
||||
const tran_low_t *dqcoeff, int block_size);
|
||||
typedef std::tr1::tuple<int, BlockErrorFunc> BlockErrorTestFPParam;
|
||||
typedef std::tuple<int, BlockErrorFunc> BlockErrorTestFPParam;
|
||||
|
||||
class BlockErrorTestFP
|
||||
: public ::testing::Test,
|
||||
|
@ -279,6 +325,10 @@ class BlockErrorTestFP
|
|||
EXPECT_EQ(expected, total);
|
||||
}
|
||||
|
||||
tran_low_t *GetCoeff() const { return coeff_; }
|
||||
|
||||
tran_low_t *GetDQCoeff() const { return dqcoeff_; }
|
||||
|
||||
int txfm_size_;
|
||||
|
||||
private:
|
||||
|
@ -288,8 +338,6 @@ class BlockErrorTestFP
|
|||
ACMRandom rnd_;
|
||||
};
|
||||
|
||||
uint8_t *AverageTestBase::source_data_ = NULL;
|
||||
|
||||
TEST_P(AverageTest, MinValue) {
|
||||
FillConstant(0);
|
||||
CheckAverages();
|
||||
|
@ -308,6 +356,27 @@ TEST_P(AverageTest, Random) {
|
|||
CheckAverages();
|
||||
}
|
||||
}
|
||||
#if CONFIG_VP9_HIGHBITDEPTH
|
||||
TEST_P(AverageTestHBD, MinValue) {
|
||||
FillConstant(0);
|
||||
CheckAverages();
|
||||
}
|
||||
|
||||
TEST_P(AverageTestHBD, MaxValue) {
|
||||
FillConstant((1 << VPX_BITS_12) - 1);
|
||||
CheckAverages();
|
||||
}
|
||||
|
||||
TEST_P(AverageTestHBD, Random) {
|
||||
bit_depth_ = VPX_BITS_12;
|
||||
// The reference frame, but not the source frame, may be unaligned for
|
||||
// certain types of searches.
|
||||
for (int i = 0; i < 1000; i++) {
|
||||
FillRandom();
|
||||
CheckAverages();
|
||||
}
|
||||
}
|
||||
#endif // CONFIG_VP9_HIGHBITDEPTH
|
||||
|
||||
TEST_P(IntProRowTest, MinValue) {
|
||||
FillConstant(0);
|
||||
|
@ -339,27 +408,27 @@ TEST_P(IntProColTest, Random) {
|
|||
RunComparison();
|
||||
}
|
||||
|
||||
TEST_P(SatdTest, MinValue) {
|
||||
TEST_P(SatdLowbdTest, MinValue) {
|
||||
const int kMin = -32640;
|
||||
const int expected = -kMin * satd_size_;
|
||||
FillConstant(kMin);
|
||||
Check(expected);
|
||||
}
|
||||
|
||||
TEST_P(SatdTest, MaxValue) {
|
||||
TEST_P(SatdLowbdTest, MaxValue) {
|
||||
const int kMax = 32640;
|
||||
const int expected = kMax * satd_size_;
|
||||
FillConstant(kMax);
|
||||
Check(expected);
|
||||
}
|
||||
|
||||
TEST_P(SatdTest, Random) {
|
||||
TEST_P(SatdLowbdTest, Random) {
|
||||
int expected;
|
||||
switch (satd_size_) {
|
||||
case 16: expected = 205298; break;
|
||||
case 64: expected = 1113950; break;
|
||||
case 256: expected = 4268415; break;
|
||||
case 1024: expected = 16954082; break;
|
||||
case 16: expected = 263252; break;
|
||||
case 64: expected = 1105420; break;
|
||||
case 256: expected = 4252250; break;
|
||||
case 1024: expected = 16876840; break;
|
||||
default:
|
||||
FAIL() << "Invalid satd size (" << satd_size_
|
||||
<< ") valid: 16/64/256/1024";
|
||||
|
@ -368,11 +437,12 @@ TEST_P(SatdTest, Random) {
|
|||
Check(expected);
|
||||
}
|
||||
|
||||
TEST_P(SatdTest, DISABLED_Speed) {
|
||||
TEST_P(SatdLowbdTest, DISABLED_Speed) {
|
||||
const int kCountSpeedTestBlock = 20000;
|
||||
vpx_usec_timer timer;
|
||||
DECLARE_ALIGNED(16, tran_low_t, coeff[1024]);
|
||||
const int blocksize = GET_PARAM(0);
|
||||
FillRandom();
|
||||
tran_low_t *coeff = GetCoeff();
|
||||
|
||||
vpx_usec_timer_start(&timer);
|
||||
for (int i = 0; i < kCountSpeedTestBlock; ++i) {
|
||||
|
@ -383,6 +453,62 @@ TEST_P(SatdTest, DISABLED_Speed) {
|
|||
printf("blocksize: %4d time: %4d us\n", blocksize, elapsed_time);
|
||||
}
|
||||
|
||||
#if CONFIG_VP9_HIGHBITDEPTH
|
||||
class SatdHighbdTest : public SatdTest {
|
||||
protected:
|
||||
virtual void FillRandom() {
|
||||
for (int i = 0; i < satd_size_; ++i) {
|
||||
src_[i] = rnd_.Rand20Signed();
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
TEST_P(SatdHighbdTest, MinValue) {
|
||||
const int kMin = -524280;
|
||||
const int expected = -kMin * satd_size_;
|
||||
FillConstant(kMin);
|
||||
Check(expected);
|
||||
}
|
||||
|
||||
TEST_P(SatdHighbdTest, MaxValue) {
|
||||
const int kMax = 524280;
|
||||
const int expected = kMax * satd_size_;
|
||||
FillConstant(kMax);
|
||||
Check(expected);
|
||||
}
|
||||
|
||||
TEST_P(SatdHighbdTest, Random) {
|
||||
int expected;
|
||||
switch (satd_size_) {
|
||||
case 16: expected = 5249712; break;
|
||||
case 64: expected = 18362120; break;
|
||||
case 256: expected = 66100520; break;
|
||||
case 1024: expected = 266094734; break;
|
||||
default:
|
||||
FAIL() << "Invalid satd size (" << satd_size_
|
||||
<< ") valid: 16/64/256/1024";
|
||||
}
|
||||
FillRandom();
|
||||
Check(expected);
|
||||
}
|
||||
|
||||
TEST_P(SatdHighbdTest, DISABLED_Speed) {
|
||||
const int kCountSpeedTestBlock = 20000;
|
||||
vpx_usec_timer timer;
|
||||
const int blocksize = GET_PARAM(0);
|
||||
FillRandom();
|
||||
tran_low_t *coeff = GetCoeff();
|
||||
|
||||
vpx_usec_timer_start(&timer);
|
||||
for (int i = 0; i < kCountSpeedTestBlock; ++i) {
|
||||
GET_PARAM(1)(coeff, blocksize);
|
||||
}
|
||||
vpx_usec_timer_mark(&timer);
|
||||
const int elapsed_time = static_cast<int>(vpx_usec_timer_elapsed(&timer));
|
||||
printf("blocksize: %4d time: %4d us\n", blocksize, elapsed_time);
|
||||
}
|
||||
#endif // CONFIG_VP9_HIGHBITDEPTH
|
||||
|
||||
TEST_P(BlockErrorTestFP, MinValue) {
|
||||
const int64_t kMin = -32640;
|
||||
const int64_t expected = kMin * kMin * txfm_size_;
|
||||
|
@ -415,9 +541,10 @@ TEST_P(BlockErrorTestFP, Random) {
|
|||
TEST_P(BlockErrorTestFP, DISABLED_Speed) {
|
||||
const int kCountSpeedTestBlock = 20000;
|
||||
vpx_usec_timer timer;
|
||||
DECLARE_ALIGNED(16, tran_low_t, coeff[1024]);
|
||||
DECLARE_ALIGNED(16, tran_low_t, dqcoeff[1024]);
|
||||
const int blocksize = GET_PARAM(0);
|
||||
FillRandom();
|
||||
tran_low_t *coeff = GetCoeff();
|
||||
tran_low_t *dqcoeff = GetDQCoeff();
|
||||
|
||||
vpx_usec_timer_start(&timer);
|
||||
for (int i = 0; i < kCountSpeedTestBlock; ++i) {
|
||||
|
@ -428,14 +555,34 @@ TEST_P(BlockErrorTestFP, DISABLED_Speed) {
|
|||
printf("blocksize: %4d time: %4d us\n", blocksize, elapsed_time);
|
||||
}
|
||||
|
||||
using std::tr1::make_tuple;
|
||||
using std::make_tuple;
|
||||
|
||||
INSTANTIATE_TEST_CASE_P(
|
||||
C, AverageTest,
|
||||
::testing::Values(make_tuple(16, 16, 1, 8, &vpx_avg_8x8_c),
|
||||
make_tuple(16, 16, 1, 4, &vpx_avg_4x4_c)));
|
||||
|
||||
INSTANTIATE_TEST_CASE_P(C, SatdTest,
|
||||
#if CONFIG_VP9_HIGHBITDEPTH
|
||||
INSTANTIATE_TEST_CASE_P(
|
||||
C, AverageTestHBD,
|
||||
::testing::Values(make_tuple(16, 16, 1, 8, &vpx_highbd_avg_8x8_c),
|
||||
make_tuple(16, 16, 1, 4, &vpx_highbd_avg_4x4_c)));
|
||||
|
||||
#if HAVE_SSE2
|
||||
INSTANTIATE_TEST_CASE_P(
|
||||
SSE2, AverageTestHBD,
|
||||
::testing::Values(make_tuple(16, 16, 1, 8, &vpx_highbd_avg_8x8_sse2),
|
||||
make_tuple(16, 16, 1, 4, &vpx_highbd_avg_4x4_sse2)));
|
||||
#endif // HAVE_SSE2
|
||||
|
||||
INSTANTIATE_TEST_CASE_P(C, SatdHighbdTest,
|
||||
::testing::Values(make_tuple(16, &vpx_satd_c),
|
||||
make_tuple(64, &vpx_satd_c),
|
||||
make_tuple(256, &vpx_satd_c),
|
||||
make_tuple(1024, &vpx_satd_c)));
|
||||
#endif // CONFIG_VP9_HIGHBITDEPTH
|
||||
|
||||
INSTANTIATE_TEST_CASE_P(C, SatdLowbdTest,
|
||||
::testing::Values(make_tuple(16, &vpx_satd_c),
|
||||
make_tuple(64, &vpx_satd_c),
|
||||
make_tuple(256, &vpx_satd_c),
|
||||
|
@ -472,7 +619,7 @@ INSTANTIATE_TEST_CASE_P(
|
|||
make_tuple(64, &vpx_int_pro_col_sse2,
|
||||
&vpx_int_pro_col_c)));
|
||||
|
||||
INSTANTIATE_TEST_CASE_P(SSE2, SatdTest,
|
||||
INSTANTIATE_TEST_CASE_P(SSE2, SatdLowbdTest,
|
||||
::testing::Values(make_tuple(16, &vpx_satd_sse2),
|
||||
make_tuple(64, &vpx_satd_sse2),
|
||||
make_tuple(256, &vpx_satd_sse2),
|
||||
|
@ -487,12 +634,21 @@ INSTANTIATE_TEST_CASE_P(
|
|||
#endif // HAVE_SSE2
|
||||
|
||||
#if HAVE_AVX2
|
||||
INSTANTIATE_TEST_CASE_P(AVX2, SatdTest,
|
||||
INSTANTIATE_TEST_CASE_P(AVX2, SatdLowbdTest,
|
||||
::testing::Values(make_tuple(16, &vpx_satd_avx2),
|
||||
make_tuple(64, &vpx_satd_avx2),
|
||||
make_tuple(256, &vpx_satd_avx2),
|
||||
make_tuple(1024, &vpx_satd_avx2)));
|
||||
|
||||
#if CONFIG_VP9_HIGHBITDEPTH
|
||||
INSTANTIATE_TEST_CASE_P(
|
||||
AVX2, SatdHighbdTest,
|
||||
::testing::Values(make_tuple(16, &vpx_highbd_satd_avx2),
|
||||
make_tuple(64, &vpx_highbd_satd_avx2),
|
||||
make_tuple(256, &vpx_highbd_satd_avx2),
|
||||
make_tuple(1024, &vpx_highbd_satd_avx2)));
|
||||
#endif // CONFIG_VP9_HIGHBITDEPTH
|
||||
|
||||
INSTANTIATE_TEST_CASE_P(
|
||||
AVX2, BlockErrorTestFP,
|
||||
::testing::Values(make_tuple(16, &vp9_block_error_fp_avx2),
|
||||
|
@ -525,7 +681,7 @@ INSTANTIATE_TEST_CASE_P(
|
|||
make_tuple(64, &vpx_int_pro_col_neon,
|
||||
&vpx_int_pro_col_c)));
|
||||
|
||||
INSTANTIATE_TEST_CASE_P(NEON, SatdTest,
|
||||
INSTANTIATE_TEST_CASE_P(NEON, SatdLowbdTest,
|
||||
::testing::Values(make_tuple(16, &vpx_satd_neon),
|
||||
make_tuple(64, &vpx_satd_neon),
|
||||
make_tuple(256, &vpx_satd_neon),
|
||||
|
@ -570,7 +726,7 @@ INSTANTIATE_TEST_CASE_P(
|
|||
// TODO(jingning): Remove the highbitdepth flag once the SIMD functions are
|
||||
// in place.
|
||||
#if !CONFIG_VP9_HIGHBITDEPTH
|
||||
INSTANTIATE_TEST_CASE_P(MSA, SatdTest,
|
||||
INSTANTIATE_TEST_CASE_P(MSA, SatdLowbdTest,
|
||||
::testing::Values(make_tuple(16, &vpx_satd_msa),
|
||||
make_tuple(64, &vpx_satd_msa),
|
||||
make_tuple(256, &vpx_satd_msa),
|
||||
|
|
|
@ -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));
|
||||
}
|
|
@ -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_
|
|
@ -11,6 +11,7 @@
|
|||
#include <limits.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <tuple>
|
||||
|
||||
#include "third_party/googletest/src/include/gtest/gtest.h"
|
||||
|
||||
|
@ -25,10 +26,7 @@
|
|||
#include "test/util.h"
|
||||
|
||||
#include "vpx_mem/vpx_mem.h"
|
||||
|
||||
extern "C" double vp9_get_blockiness(const unsigned char *img1, int img1_pitch,
|
||||
const unsigned char *img2, int img2_pitch,
|
||||
int width, int height);
|
||||
#include "vp9/encoder/vp9_blockiness.h"
|
||||
|
||||
using libvpx_test::ACMRandom;
|
||||
|
||||
|
@ -141,7 +139,7 @@ class BlockinessTestBase : public ::testing::Test {
|
|||
};
|
||||
|
||||
#if CONFIG_VP9_ENCODER
|
||||
typedef std::tr1::tuple<int, int> BlockinessParam;
|
||||
typedef std::tuple<int, int> BlockinessParam;
|
||||
class BlockinessVP9Test
|
||||
: public BlockinessTestBase,
|
||||
public ::testing::WithParamInterface<BlockinessParam> {
|
||||
|
@ -208,15 +206,15 @@ TEST_P(BlockinessVP9Test, WorstCaseBlockiness) {
|
|||
}
|
||||
#endif // CONFIG_VP9_ENCODER
|
||||
|
||||
using std::tr1::make_tuple;
|
||||
using std::make_tuple;
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// C functions
|
||||
|
||||
#if CONFIG_VP9_ENCODER
|
||||
const BlockinessParam c_vp9_tests[] = {
|
||||
make_tuple(320, 240), make_tuple(318, 242), make_tuple(318, 238),
|
||||
};
|
||||
const BlockinessParam c_vp9_tests[] = { make_tuple(320, 240),
|
||||
make_tuple(318, 242),
|
||||
make_tuple(318, 238) };
|
||||
INSTANTIATE_TEST_CASE_P(C, BlockinessVP9Test, ::testing::ValuesIn(c_vp9_tests));
|
||||
#endif
|
||||
|
||||
|
|
|
@ -31,7 +31,7 @@ class BordersTest
|
|||
|
||||
virtual void PreEncodeFrameHook(::libvpx_test::VideoSource *video,
|
||||
::libvpx_test::Encoder *encoder) {
|
||||
if (video->frame() == 1) {
|
||||
if (video->frame() == 0) {
|
||||
encoder->Control(VP8E_SET_CPUUSED, 1);
|
||||
encoder->Control(VP8E_SET_ENABLEAUTOALTREF, 1);
|
||||
encoder->Control(VP8E_SET_ARNR_MAXFRAMES, 7);
|
||||
|
|
|
@ -8,8 +8,8 @@
|
|||
* be found in the AUTHORS file in the root of the source tree.
|
||||
*/
|
||||
|
||||
#ifndef TEST_BUFFER_H_
|
||||
#define TEST_BUFFER_H_
|
||||
#ifndef VPX_TEST_BUFFER_H_
|
||||
#define VPX_TEST_BUFFER_H_
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
|
@ -379,4 +379,4 @@ bool Buffer<T>::BufferSizesMatch(const Buffer<T> &a) const {
|
|||
return true;
|
||||
}
|
||||
} // namespace libvpx_test
|
||||
#endif // TEST_BUFFER_H_
|
||||
#endif // VPX_TEST_BUFFER_H_
|
||||
|
|
|
@ -171,9 +171,10 @@ TEST_F(ByteAlignmentTest, SwitchByteAlignment) {
|
|||
TEST_P(ByteAlignmentTest, TestAlignment) {
|
||||
const ByteAlignmentTestParam t = GetParam();
|
||||
SetByteAlignment(t.byte_alignment, t.expected_value);
|
||||
if (t.decode_remaining)
|
||||
if (t.decode_remaining) {
|
||||
ASSERT_EQ(VPX_CODEC_OK, DecodeRemainingFrames(t.byte_alignment));
|
||||
}
|
||||
}
|
||||
|
||||
INSTANTIATE_TEST_CASE_P(Alignments, ByteAlignmentTest,
|
||||
::testing::ValuesIn(kBaTestParams));
|
||||
|
|
|
@ -7,23 +7,17 @@
|
|||
* in the file PATENTS. All contributing project authors may
|
||||
* be found in the AUTHORS file in the root of the source tree.
|
||||
*/
|
||||
#ifndef TEST_CLEAR_SYSTEM_STATE_H_
|
||||
#define TEST_CLEAR_SYSTEM_STATE_H_
|
||||
#ifndef VPX_TEST_CLEAR_SYSTEM_STATE_H_
|
||||
#define VPX_TEST_CLEAR_SYSTEM_STATE_H_
|
||||
|
||||
#include "./vpx_config.h"
|
||||
#if ARCH_X86 || ARCH_X86_64
|
||||
#include "vpx_ports/x86.h"
|
||||
#endif
|
||||
#include "vpx_ports/system_state.h"
|
||||
|
||||
namespace libvpx_test {
|
||||
|
||||
// Reset system to a known state. This function should be used for all non-API
|
||||
// test cases.
|
||||
inline void ClearSystemState() {
|
||||
#if ARCH_X86 || ARCH_X86_64
|
||||
vpx_reset_mmx_state();
|
||||
#endif
|
||||
}
|
||||
inline void ClearSystemState() { vpx_clear_system_state(); }
|
||||
|
||||
} // namespace libvpx_test
|
||||
#endif // TEST_CLEAR_SYSTEM_STATE_H_
|
||||
#endif // VPX_TEST_CLEAR_SYSTEM_STATE_H_
|
||||
|
|
|
@ -7,8 +7,10 @@
|
|||
* in the file PATENTS. All contributing project authors may
|
||||
* be found in the AUTHORS file in the root of the source tree.
|
||||
*/
|
||||
#ifndef TEST_CODEC_FACTORY_H_
|
||||
#define TEST_CODEC_FACTORY_H_
|
||||
#ifndef VPX_TEST_CODEC_FACTORY_H_
|
||||
#define VPX_TEST_CODEC_FACTORY_H_
|
||||
|
||||
#include <tuple>
|
||||
|
||||
#include "./vpx_config.h"
|
||||
#include "vpx/vpx_decoder.h"
|
||||
|
@ -53,23 +55,22 @@ class CodecFactory {
|
|||
template <class T1>
|
||||
class CodecTestWithParam
|
||||
: public ::testing::TestWithParam<
|
||||
std::tr1::tuple<const libvpx_test::CodecFactory *, T1> > {};
|
||||
std::tuple<const libvpx_test::CodecFactory *, T1> > {};
|
||||
|
||||
template <class T1, class T2>
|
||||
class CodecTestWith2Params
|
||||
: public ::testing::TestWithParam<
|
||||
std::tr1::tuple<const libvpx_test::CodecFactory *, T1, T2> > {};
|
||||
std::tuple<const libvpx_test::CodecFactory *, T1, T2> > {};
|
||||
|
||||
template <class T1, class T2, class T3>
|
||||
class CodecTestWith3Params
|
||||
: public ::testing::TestWithParam<
|
||||
std::tr1::tuple<const libvpx_test::CodecFactory *, T1, T2, T3> > {};
|
||||
std::tuple<const libvpx_test::CodecFactory *, T1, T2, T3> > {};
|
||||
|
||||
template <class T1, class T2, class T3, class T4>
|
||||
class CodecTestWith4Params
|
||||
: public ::testing::TestWithParam<
|
||||
std::tr1::tuple<const libvpx_test::CodecFactory *, T1, T2, T3, T4> > {
|
||||
};
|
||||
std::tuple<const libvpx_test::CodecFactory *, T1, T2, T3, T4> > {};
|
||||
|
||||
/*
|
||||
* VP8 Codec Definitions
|
||||
|
@ -264,4 +265,4 @@ const libvpx_test::VP9CodecFactory kVP9;
|
|||
#endif // CONFIG_VP9
|
||||
|
||||
} // namespace libvpx_test
|
||||
#endif // TEST_CODEC_FACTORY_H_
|
||||
#endif // VPX_TEST_CODEC_FACTORY_H_
|
||||
|
|
|
@ -29,6 +29,10 @@ uint8_t avg_with_rounding(uint8_t a, uint8_t b) { return (a + b + 1) >> 1; }
|
|||
|
||||
void reference_pred(const Buffer<uint8_t> &pred, const Buffer<uint8_t> &ref,
|
||||
int width, int height, Buffer<uint8_t> *avg) {
|
||||
ASSERT_TRUE(avg->TopLeftPixel() != NULL);
|
||||
ASSERT_TRUE(pred.TopLeftPixel() != NULL);
|
||||
ASSERT_TRUE(ref.TopLeftPixel() != NULL);
|
||||
|
||||
for (int y = 0; y < height; ++y) {
|
||||
for (int x = 0; x < width; ++x) {
|
||||
avg->TopLeftPixel()[y * avg->stride() + x] =
|
||||
|
|
|
@ -11,6 +11,7 @@
|
|||
#include <limits.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <tuple>
|
||||
|
||||
#include "third_party/googletest/src/include/gtest/gtest.h"
|
||||
|
||||
|
@ -127,7 +128,7 @@ class ConsistencyTestBase : public ::testing::Test {
|
|||
};
|
||||
|
||||
#if CONFIG_VP9_ENCODER
|
||||
typedef std::tr1::tuple<int, int> ConsistencyParam;
|
||||
typedef std::tuple<int, int> ConsistencyParam;
|
||||
class ConsistencyVP9Test
|
||||
: public ConsistencyTestBase,
|
||||
public ::testing::WithParamInterface<ConsistencyParam> {
|
||||
|
@ -198,15 +199,15 @@ TEST_P(ConsistencyVP9Test, ConsistencyIsZero) {
|
|||
}
|
||||
#endif // CONFIG_VP9_ENCODER
|
||||
|
||||
using std::tr1::make_tuple;
|
||||
using std::make_tuple;
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// C functions
|
||||
|
||||
#if CONFIG_VP9_ENCODER
|
||||
const ConsistencyParam c_vp9_tests[] = {
|
||||
make_tuple(320, 240), make_tuple(318, 242), make_tuple(318, 238),
|
||||
};
|
||||
const ConsistencyParam c_vp9_tests[] = { make_tuple(320, 240),
|
||||
make_tuple(318, 242),
|
||||
make_tuple(318, 238) };
|
||||
INSTANTIATE_TEST_CASE_P(C, ConsistencyVP9Test,
|
||||
::testing::ValuesIn(c_vp9_tests));
|
||||
#endif
|
||||
|
|
|
@ -9,6 +9,7 @@
|
|||
*/
|
||||
|
||||
#include <string.h>
|
||||
#include <tuple>
|
||||
|
||||
#include "third_party/googletest/src/include/gtest/gtest.h"
|
||||
|
||||
|
@ -77,7 +78,7 @@ struct ConvolveFunctions {
|
|||
int use_highbd_; // 0 if high bitdepth not used, else the actual bit depth.
|
||||
};
|
||||
|
||||
typedef std::tr1::tuple<int, int, const ConvolveFunctions *> ConvolveParam;
|
||||
typedef std::tuple<int, int, const ConvolveFunctions *> ConvolveParam;
|
||||
|
||||
#define ALL_SIZES(convolve_fn) \
|
||||
make_tuple(4, 4, &convolve_fn), make_tuple(8, 4, &convolve_fn), \
|
||||
|
@ -114,6 +115,7 @@ void filter_block2d_8_c(const uint8_t *src_ptr, const unsigned int src_stride,
|
|||
// and filter_max_width = 16
|
||||
//
|
||||
uint8_t intermediate_buffer[71 * kMaxDimension];
|
||||
vp9_zero(intermediate_buffer);
|
||||
const int intermediate_next_stride =
|
||||
1 - static_cast<int>(intermediate_height * output_width);
|
||||
|
||||
|
@ -213,6 +215,8 @@ void highbd_filter_block2d_8_c(const uint16_t *src_ptr,
|
|||
const int intermediate_next_stride =
|
||||
1 - static_cast<int>(intermediate_height * output_width);
|
||||
|
||||
vp9_zero(intermediate_buffer);
|
||||
|
||||
// Horizontal pass (src -> transposed intermediate).
|
||||
{
|
||||
uint16_t *output_ptr = intermediate_buffer;
|
||||
|
@ -412,8 +416,14 @@ class ConvolveTest : public ::testing::TestWithParam<ConvolveParam> {
|
|||
for (int i = 0; i < kOutputBufferSize; ++i) {
|
||||
if (IsIndexInBorder(i)) {
|
||||
output_[i] = 255;
|
||||
#if CONFIG_VP9_HIGHBITDEPTH
|
||||
output16_[i] = mask_;
|
||||
#endif
|
||||
} else {
|
||||
output_[i] = 0;
|
||||
#if CONFIG_VP9_HIGHBITDEPTH
|
||||
output16_[i] = 0;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -450,7 +460,9 @@ class ConvolveTest : public ::testing::TestWithParam<ConvolveParam> {
|
|||
|
||||
void CheckGuardBlocks() {
|
||||
for (int i = 0; i < kOutputBufferSize; ++i) {
|
||||
if (IsIndexInBorder(i)) EXPECT_EQ(255, output_[i]);
|
||||
if (IsIndexInBorder(i)) {
|
||||
EXPECT_EQ(255, output_[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -672,6 +684,74 @@ TEST_P(ConvolveTest, DISABLED_8Tap_Vert_Speed) {
|
|||
UUT_->use_highbd_ ? UUT_->use_highbd_ : 8, elapsed_time);
|
||||
}
|
||||
|
||||
TEST_P(ConvolveTest, DISABLED_4Tap_Speed) {
|
||||
const uint8_t *const in = input();
|
||||
uint8_t *const out = output();
|
||||
const InterpKernel *const fourtap = vp9_filter_kernels[FOURTAP];
|
||||
const int kNumTests = 5000000;
|
||||
const int width = Width();
|
||||
const int height = Height();
|
||||
vpx_usec_timer timer;
|
||||
|
||||
SetConstantInput(127);
|
||||
|
||||
vpx_usec_timer_start(&timer);
|
||||
for (int n = 0; n < kNumTests; ++n) {
|
||||
UUT_->hv8_[0](in, kInputStride, out, kOutputStride, fourtap, 8, 16, 8, 16,
|
||||
width, height);
|
||||
}
|
||||
vpx_usec_timer_mark(&timer);
|
||||
|
||||
const int elapsed_time = static_cast<int>(vpx_usec_timer_elapsed(&timer));
|
||||
printf("convolve4_%dx%d_%d: %d us\n", width, height,
|
||||
UUT_->use_highbd_ ? UUT_->use_highbd_ : 8, elapsed_time);
|
||||
}
|
||||
|
||||
TEST_P(ConvolveTest, DISABLED_4Tap_Horiz_Speed) {
|
||||
const uint8_t *const in = input();
|
||||
uint8_t *const out = output();
|
||||
const InterpKernel *const fourtap = vp9_filter_kernels[FOURTAP];
|
||||
const int kNumTests = 5000000;
|
||||
const int width = Width();
|
||||
const int height = Height();
|
||||
vpx_usec_timer timer;
|
||||
|
||||
SetConstantInput(127);
|
||||
|
||||
vpx_usec_timer_start(&timer);
|
||||
for (int n = 0; n < kNumTests; ++n) {
|
||||
UUT_->h8_[0](in, kInputStride, out, kOutputStride, fourtap, 8, 16, 8, 16,
|
||||
width, height);
|
||||
}
|
||||
vpx_usec_timer_mark(&timer);
|
||||
|
||||
const int elapsed_time = static_cast<int>(vpx_usec_timer_elapsed(&timer));
|
||||
printf("convolve4_horiz_%dx%d_%d: %d us\n", width, height,
|
||||
UUT_->use_highbd_ ? UUT_->use_highbd_ : 8, elapsed_time);
|
||||
}
|
||||
|
||||
TEST_P(ConvolveTest, DISABLED_4Tap_Vert_Speed) {
|
||||
const uint8_t *const in = input();
|
||||
uint8_t *const out = output();
|
||||
const InterpKernel *const fourtap = vp9_filter_kernels[FOURTAP];
|
||||
const int kNumTests = 5000000;
|
||||
const int width = Width();
|
||||
const int height = Height();
|
||||
vpx_usec_timer timer;
|
||||
|
||||
SetConstantInput(127);
|
||||
|
||||
vpx_usec_timer_start(&timer);
|
||||
for (int n = 0; n < kNumTests; ++n) {
|
||||
UUT_->v8_[0](in, kInputStride, out, kOutputStride, fourtap, 8, 16, 8, 16,
|
||||
width, height);
|
||||
}
|
||||
vpx_usec_timer_mark(&timer);
|
||||
|
||||
const int elapsed_time = static_cast<int>(vpx_usec_timer_elapsed(&timer));
|
||||
printf("convolve4_vert_%dx%d_%d: %d us\n", width, height,
|
||||
UUT_->use_highbd_ ? UUT_->use_highbd_ : 8, elapsed_time);
|
||||
}
|
||||
TEST_P(ConvolveTest, DISABLED_8Tap_Avg_Speed) {
|
||||
const uint8_t *const in = input();
|
||||
uint8_t *const out = output();
|
||||
|
@ -787,7 +867,7 @@ TEST_P(ConvolveTest, Copy2D) {
|
|||
}
|
||||
}
|
||||
|
||||
const int kNumFilterBanks = 4;
|
||||
const int kNumFilterBanks = 5;
|
||||
const int kNumFilters = 16;
|
||||
|
||||
TEST(ConvolveTest, FiltersWontSaturateWhenAddedPairwise) {
|
||||
|
@ -1040,7 +1120,7 @@ TEST_P(ConvolveTest, CheckScalingFiltering) {
|
|||
}
|
||||
#endif
|
||||
|
||||
using std::tr1::make_tuple;
|
||||
using std::make_tuple;
|
||||
|
||||
#if CONFIG_VP9_HIGHBITDEPTH
|
||||
#define WRAP(func, bd) \
|
||||
|
@ -1183,9 +1263,9 @@ const ConvolveFunctions convolve12_c(
|
|||
wrap_convolve8_horiz_c_12, wrap_convolve8_avg_horiz_c_12,
|
||||
wrap_convolve8_vert_c_12, wrap_convolve8_avg_vert_c_12, wrap_convolve8_c_12,
|
||||
wrap_convolve8_avg_c_12, 12);
|
||||
const ConvolveParam kArrayConvolve_c[] = {
|
||||
ALL_SIZES(convolve8_c), ALL_SIZES(convolve10_c), ALL_SIZES(convolve12_c)
|
||||
};
|
||||
const ConvolveParam kArrayConvolve_c[] = { ALL_SIZES(convolve8_c),
|
||||
ALL_SIZES(convolve10_c),
|
||||
ALL_SIZES(convolve12_c) };
|
||||
|
||||
#else
|
||||
const ConvolveFunctions convolve8_c(
|
||||
|
@ -1377,4 +1457,16 @@ const ConvolveParam kArrayConvolve_vsx[] = { ALL_SIZES(convolve8_vsx) };
|
|||
INSTANTIATE_TEST_CASE_P(VSX, ConvolveTest,
|
||||
::testing::ValuesIn(kArrayConvolve_vsx));
|
||||
#endif // HAVE_VSX
|
||||
|
||||
#if HAVE_MMI
|
||||
const ConvolveFunctions convolve8_mmi(
|
||||
vpx_convolve_copy_c, vpx_convolve_avg_mmi, vpx_convolve8_horiz_mmi,
|
||||
vpx_convolve8_avg_horiz_mmi, vpx_convolve8_vert_mmi,
|
||||
vpx_convolve8_avg_vert_mmi, vpx_convolve8_mmi, vpx_convolve8_avg_mmi,
|
||||
vpx_scaled_horiz_c, vpx_scaled_avg_horiz_c, vpx_scaled_vert_c,
|
||||
vpx_scaled_avg_vert_c, vpx_scaled_2d_c, vpx_scaled_avg_2d_c, 0);
|
||||
const ConvolveParam kArrayConvolve_mmi[] = { ALL_SIZES(convolve8_mmi) };
|
||||
INSTANTIATE_TEST_CASE_P(MMI, ConvolveTest,
|
||||
::testing::ValuesIn(kArrayConvolve_mmi));
|
||||
#endif // HAVE_MMI
|
||||
} // namespace
|
||||
|
|
|
@ -44,7 +44,7 @@ class CpuSpeedTest
|
|||
|
||||
virtual void PreEncodeFrameHook(::libvpx_test::VideoSource *video,
|
||||
::libvpx_test::Encoder *encoder) {
|
||||
if (video->frame() == 1) {
|
||||
if (video->frame() == 0) {
|
||||
encoder->Control(VP8E_SET_CPUUSED, set_cpu_used_);
|
||||
encoder->Control(VP9E_SET_TUNE_CONTENT, tune_content_);
|
||||
if (encoding_mode_ != ::libvpx_test::kRealTime) {
|
||||
|
@ -152,5 +152,5 @@ VP9_INSTANTIATE_TEST_CASE(CpuSpeedTest,
|
|||
::testing::Values(::libvpx_test::kTwoPassGood,
|
||||
::libvpx_test::kOnePassGood,
|
||||
::libvpx_test::kRealTime),
|
||||
::testing::Range(0, 9));
|
||||
::testing::Range(0, 10));
|
||||
} // namespace
|
||||
|
|
|
@ -65,7 +65,7 @@ class CQTest : public ::libvpx_test::EncoderTest,
|
|||
|
||||
virtual void PreEncodeFrameHook(libvpx_test::VideoSource *video,
|
||||
libvpx_test::Encoder *encoder) {
|
||||
if (video->frame() == 1) {
|
||||
if (video->frame() == 0) {
|
||||
if (cfg_.rc_end_usage == VPX_CQ) {
|
||||
encoder->Control(VP8E_SET_CQ_LEVEL, cq_level_);
|
||||
}
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -11,6 +11,7 @@
|
|||
#include <math.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <tuple>
|
||||
|
||||
#include "third_party/googletest/src/include/gtest/gtest.h"
|
||||
|
||||
|
@ -229,10 +230,9 @@ typedef void (*FhtFunc)(const int16_t *in, tran_low_t *out, int stride,
|
|||
typedef void (*IhtFunc)(const tran_low_t *in, uint8_t *out, int stride,
|
||||
int tx_type);
|
||||
|
||||
typedef std::tr1::tuple<FdctFunc, IdctFunc, int, vpx_bit_depth_t> Dct16x16Param;
|
||||
typedef std::tr1::tuple<FhtFunc, IhtFunc, int, vpx_bit_depth_t> Ht16x16Param;
|
||||
typedef std::tr1::tuple<IdctFunc, IdctFunc, int, vpx_bit_depth_t>
|
||||
Idct16x16Param;
|
||||
typedef std::tuple<FdctFunc, IdctFunc, int, vpx_bit_depth_t> Dct16x16Param;
|
||||
typedef std::tuple<FhtFunc, IhtFunc, int, vpx_bit_depth_t> Ht16x16Param;
|
||||
typedef std::tuple<IdctFunc, IdctFunc, int, vpx_bit_depth_t> Idct16x16Param;
|
||||
|
||||
void fdct16x16_ref(const int16_t *in, tran_low_t *out, int stride,
|
||||
int /*tx_type*/) {
|
||||
|
@ -744,7 +744,7 @@ TEST_P(InvTrans16x16DCT, CompareReference) {
|
|||
CompareInvReference(ref_txfm_, thresh_);
|
||||
}
|
||||
|
||||
using std::tr1::make_tuple;
|
||||
using std::make_tuple;
|
||||
|
||||
#if CONFIG_VP9_HIGHBITDEPTH
|
||||
INSTANTIATE_TEST_CASE_P(
|
||||
|
|
|
@ -11,6 +11,7 @@
|
|||
#include <math.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <tuple>
|
||||
|
||||
#include "third_party/googletest/src/include/gtest/gtest.h"
|
||||
|
||||
|
@ -18,6 +19,7 @@
|
|||
#include "./vpx_config.h"
|
||||
#include "./vpx_dsp_rtcd.h"
|
||||
#include "test/acm_random.h"
|
||||
#include "test/bench.h"
|
||||
#include "test/clear_system_state.h"
|
||||
#include "test/register_state_check.h"
|
||||
#include "test/util.h"
|
||||
|
@ -66,7 +68,7 @@ void reference_32x32_dct_2d(const int16_t input[kNumCoeffs],
|
|||
typedef void (*FwdTxfmFunc)(const int16_t *in, tran_low_t *out, int stride);
|
||||
typedef void (*InvTxfmFunc)(const tran_low_t *in, uint8_t *out, int stride);
|
||||
|
||||
typedef std::tr1::tuple<FwdTxfmFunc, InvTxfmFunc, int, vpx_bit_depth_t>
|
||||
typedef std::tuple<FwdTxfmFunc, InvTxfmFunc, int, vpx_bit_depth_t>
|
||||
Trans32x32Param;
|
||||
|
||||
#if CONFIG_VP9_HIGHBITDEPTH
|
||||
|
@ -79,7 +81,8 @@ void idct32x32_12(const tran_low_t *in, uint8_t *out, int stride) {
|
|||
}
|
||||
#endif // CONFIG_VP9_HIGHBITDEPTH
|
||||
|
||||
class Trans32x32Test : public ::testing::TestWithParam<Trans32x32Param> {
|
||||
class Trans32x32Test : public AbstractBench,
|
||||
public ::testing::TestWithParam<Trans32x32Param> {
|
||||
public:
|
||||
virtual ~Trans32x32Test() {}
|
||||
virtual void SetUp() {
|
||||
|
@ -99,8 +102,14 @@ class Trans32x32Test : public ::testing::TestWithParam<Trans32x32Param> {
|
|||
int mask_;
|
||||
FwdTxfmFunc fwd_txfm_;
|
||||
InvTxfmFunc inv_txfm_;
|
||||
|
||||
int16_t *bench_in_;
|
||||
tran_low_t *bench_out_;
|
||||
virtual void Run();
|
||||
};
|
||||
|
||||
void Trans32x32Test::Run() { fwd_txfm_(bench_in_, bench_out_, 32); }
|
||||
|
||||
TEST_P(Trans32x32Test, AccuracyCheck) {
|
||||
ACMRandom rnd(ACMRandom::DeterministicSeed());
|
||||
uint32_t max_error = 0;
|
||||
|
@ -237,6 +246,19 @@ TEST_P(Trans32x32Test, MemCheck) {
|
|||
}
|
||||
}
|
||||
|
||||
TEST_P(Trans32x32Test, DISABLED_Speed) {
|
||||
ACMRandom rnd(ACMRandom::DeterministicSeed());
|
||||
|
||||
DECLARE_ALIGNED(16, int16_t, input_extreme_block[kNumCoeffs]);
|
||||
DECLARE_ALIGNED(16, tran_low_t, output_block[kNumCoeffs]);
|
||||
|
||||
bench_in_ = input_extreme_block;
|
||||
bench_out_ = output_block;
|
||||
|
||||
RunNTimes(INT16_MAX);
|
||||
PrintMedian("32x32");
|
||||
}
|
||||
|
||||
TEST_P(Trans32x32Test, InverseAccuracy) {
|
||||
ACMRandom rnd(ACMRandom::DeterministicSeed());
|
||||
const int count_test_block = 1000;
|
||||
|
@ -292,7 +314,7 @@ TEST_P(Trans32x32Test, InverseAccuracy) {
|
|||
}
|
||||
}
|
||||
|
||||
using std::tr1::make_tuple;
|
||||
using std::make_tuple;
|
||||
|
||||
#if CONFIG_VP9_HIGHBITDEPTH
|
||||
INSTANTIATE_TEST_CASE_P(
|
||||
|
@ -371,7 +393,7 @@ INSTANTIATE_TEST_CASE_P(
|
|||
VSX, Trans32x32Test,
|
||||
::testing::Values(make_tuple(&vpx_fdct32x32_c, &vpx_idct32x32_1024_add_vsx,
|
||||
0, VPX_BITS_8),
|
||||
make_tuple(&vpx_fdct32x32_rd_c,
|
||||
make_tuple(&vpx_fdct32x32_rd_vsx,
|
||||
&vpx_idct32x32_1024_add_vsx, 1, VPX_BITS_8)));
|
||||
#endif // HAVE_VSX && !CONFIG_VP9_HIGHBITDEPTH && !CONFIG_EMULATE_HARDWARE
|
||||
} // namespace
|
||||
|
|
|
@ -11,8 +11,8 @@
|
|||
#include <math.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <limits>
|
||||
#include <tuple>
|
||||
|
||||
#include "third_party/googletest/src/include/gtest/gtest.h"
|
||||
|
||||
|
@ -28,8 +28,8 @@
|
|||
|
||||
using libvpx_test::ACMRandom;
|
||||
using libvpx_test::Buffer;
|
||||
using std::tr1::tuple;
|
||||
using std::tr1::make_tuple;
|
||||
using std::make_tuple;
|
||||
using std::tuple;
|
||||
|
||||
namespace {
|
||||
typedef void (*PartialFdctFunc)(const int16_t *in, tran_low_t *out, int stride);
|
||||
|
@ -39,11 +39,15 @@ typedef tuple<PartialFdctFunc, int /* size */, vpx_bit_depth_t>
|
|||
|
||||
tran_low_t partial_fdct_ref(const Buffer<int16_t> &in, int size) {
|
||||
int64_t sum = 0;
|
||||
if (in.TopLeftPixel() != NULL) {
|
||||
for (int y = 0; y < size; ++y) {
|
||||
for (int x = 0; x < size; ++x) {
|
||||
sum += in.TopLeftPixel()[y * in.stride() + x];
|
||||
}
|
||||
}
|
||||
} else {
|
||||
assert(0);
|
||||
}
|
||||
|
||||
switch (size) {
|
||||
case 4: sum *= 2; break;
|
||||
|
@ -77,6 +81,7 @@ class PartialFdctTest : public ::testing::TestWithParam<PartialFdctParam> {
|
|||
Buffer<tran_low_t> output_block = Buffer<tran_low_t>(size_, size_, 0, 16);
|
||||
ASSERT_TRUE(output_block.Init());
|
||||
|
||||
if (output_block.TopLeftPixel() != NULL) {
|
||||
for (int i = 0; i < 100; ++i) {
|
||||
if (i == 0) {
|
||||
input_block.Set(maxvalue);
|
||||
|
@ -93,6 +98,9 @@ class PartialFdctTest : public ::testing::TestWithParam<PartialFdctParam> {
|
|||
EXPECT_EQ(partial_fdct_ref(input_block, size_),
|
||||
output_block.TopLeftPixel()[0]);
|
||||
}
|
||||
} else {
|
||||
assert(0);
|
||||
}
|
||||
}
|
||||
|
||||
PartialFdctFunc fwd_txfm_;
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -138,8 +138,30 @@ TEST(DecodeAPI, Vp9InvalidDecode) {
|
|||
EXPECT_EQ(VPX_CODEC_OK, vpx_codec_destroy(&dec));
|
||||
}
|
||||
|
||||
TEST(DecodeAPI, Vp9PeekSI) {
|
||||
void TestPeekInfo(const uint8_t *const data, uint32_t data_sz,
|
||||
uint32_t peek_size) {
|
||||
const vpx_codec_iface_t *const codec = &vpx_codec_vp9_dx_algo;
|
||||
// Verify behavior of vpx_codec_decode. vpx_codec_decode doesn't even get
|
||||
// to decoder_peek_si_internal on frames of size < 8.
|
||||
if (data_sz >= 8) {
|
||||
vpx_codec_ctx_t dec;
|
||||
EXPECT_EQ(VPX_CODEC_OK, vpx_codec_dec_init(&dec, codec, NULL, 0));
|
||||
EXPECT_EQ((data_sz < peek_size) ? VPX_CODEC_UNSUP_BITSTREAM
|
||||
: VPX_CODEC_CORRUPT_FRAME,
|
||||
vpx_codec_decode(&dec, data, data_sz, NULL, 0));
|
||||
vpx_codec_iter_t iter = NULL;
|
||||
EXPECT_EQ(NULL, vpx_codec_get_frame(&dec, &iter));
|
||||
EXPECT_EQ(VPX_CODEC_OK, vpx_codec_destroy(&dec));
|
||||
}
|
||||
|
||||
// Verify behavior of vpx_codec_peek_stream_info.
|
||||
vpx_codec_stream_info_t si;
|
||||
si.sz = sizeof(si);
|
||||
EXPECT_EQ((data_sz < peek_size) ? VPX_CODEC_UNSUP_BITSTREAM : VPX_CODEC_OK,
|
||||
vpx_codec_peek_stream_info(codec, data, data_sz, &si));
|
||||
}
|
||||
|
||||
TEST(DecodeAPI, Vp9PeekStreamInfo) {
|
||||
// The first 9 bytes are valid and the rest of the bytes are made up. Until
|
||||
// size 10, this should return VPX_CODEC_UNSUP_BITSTREAM and after that it
|
||||
// should return VPX_CODEC_CORRUPT_FRAME.
|
||||
|
@ -150,24 +172,18 @@ TEST(DecodeAPI, Vp9PeekSI) {
|
|||
};
|
||||
|
||||
for (uint32_t data_sz = 1; data_sz <= 32; ++data_sz) {
|
||||
// Verify behavior of vpx_codec_decode. vpx_codec_decode doesn't even get
|
||||
// to decoder_peek_si_internal on frames of size < 8.
|
||||
if (data_sz >= 8) {
|
||||
vpx_codec_ctx_t dec;
|
||||
EXPECT_EQ(VPX_CODEC_OK, vpx_codec_dec_init(&dec, codec, NULL, 0));
|
||||
EXPECT_EQ(
|
||||
(data_sz < 10) ? VPX_CODEC_UNSUP_BITSTREAM : VPX_CODEC_CORRUPT_FRAME,
|
||||
vpx_codec_decode(&dec, data, data_sz, NULL, 0));
|
||||
vpx_codec_iter_t iter = NULL;
|
||||
EXPECT_EQ(NULL, vpx_codec_get_frame(&dec, &iter));
|
||||
EXPECT_EQ(VPX_CODEC_OK, vpx_codec_destroy(&dec));
|
||||
TestPeekInfo(data, data_sz, 10);
|
||||
}
|
||||
}
|
||||
|
||||
// Verify behavior of vpx_codec_peek_stream_info.
|
||||
vpx_codec_stream_info_t si;
|
||||
si.sz = sizeof(si);
|
||||
EXPECT_EQ((data_sz < 10) ? VPX_CODEC_UNSUP_BITSTREAM : VPX_CODEC_OK,
|
||||
vpx_codec_peek_stream_info(codec, data, data_sz, &si));
|
||||
TEST(DecodeAPI, Vp9PeekStreamInfoTruncated) {
|
||||
// This profile 1 header requires 10.25 bytes, ensure
|
||||
// vpx_codec_peek_stream_info doesn't over read.
|
||||
const uint8_t profile1_data[10] = { 0xa4, 0xe9, 0x30, 0x68, 0x53,
|
||||
0xe9, 0x30, 0x68, 0x53, 0x04 };
|
||||
|
||||
for (uint32_t data_sz = 1; data_sz <= 10; ++data_sz) {
|
||||
TestPeekInfo(profile1_data, data_sz, 11);
|
||||
}
|
||||
}
|
||||
#endif // CONFIG_VP9_DECODER
|
||||
|
|
|
@ -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
|
|
@ -9,6 +9,8 @@
|
|||
*/
|
||||
|
||||
#include <string>
|
||||
#include <tuple>
|
||||
|
||||
#include "test/codec_factory.h"
|
||||
#include "test/decode_test_driver.h"
|
||||
#include "test/encode_test_driver.h"
|
||||
|
@ -21,7 +23,7 @@
|
|||
#include "./ivfenc.h"
|
||||
#include "./vpx_version.h"
|
||||
|
||||
using std::tr1::make_tuple;
|
||||
using std::make_tuple;
|
||||
|
||||
namespace {
|
||||
|
||||
|
@ -34,7 +36,7 @@ const char kNewEncodeOutputFile[] = "new_encode.ivf";
|
|||
/*
|
||||
DecodePerfTest takes a tuple of filename + number of threads to decode with
|
||||
*/
|
||||
typedef std::tr1::tuple<const char *, unsigned> DecodePerfParam;
|
||||
typedef std::tuple<const char *, unsigned> DecodePerfParam;
|
||||
|
||||
const DecodePerfParam kVP9DecodePerfVectors[] = {
|
||||
make_tuple("vp90-2-bbb_426x240_tile_1x1_180kbps.webm", 1),
|
||||
|
@ -137,7 +139,7 @@ class VP9NewEncodeDecodePerfTest
|
|||
|
||||
virtual void PreEncodeFrameHook(::libvpx_test::VideoSource *video,
|
||||
::libvpx_test::Encoder *encoder) {
|
||||
if (video->frame() == 1) {
|
||||
if (video->frame() == 0) {
|
||||
encoder->Control(VP8E_SET_CPUUSED, speed_);
|
||||
encoder->Control(VP9E_SET_FRAME_PARALLEL_DECODING, 1);
|
||||
encoder->Control(VP9E_SET_TILE_COLUMNS, 2);
|
||||
|
|
|
@ -8,6 +8,7 @@
|
|||
* be found in the AUTHORS file in the root of the source tree.
|
||||
*/
|
||||
|
||||
#include <memory>
|
||||
#include <string>
|
||||
|
||||
#include "test/codec_factory.h"
|
||||
|
@ -53,7 +54,7 @@ class DecodeSvcTest : public ::libvpx_test::DecoderTest,
|
|||
// number of frames decoded. This results in 1/4x1/4 resolution (320x180).
|
||||
TEST_P(DecodeSvcTest, DecodeSvcTestUpToSpatialLayer0) {
|
||||
const std::string filename = GET_PARAM(1);
|
||||
testing::internal::scoped_ptr<libvpx_test::CompressedVideoSource> video;
|
||||
std::unique_ptr<libvpx_test::CompressedVideoSource> video;
|
||||
video.reset(new libvpx_test::IVFVideoSource(filename));
|
||||
ASSERT_TRUE(video.get() != NULL);
|
||||
video->Init();
|
||||
|
@ -70,7 +71,7 @@ TEST_P(DecodeSvcTest, DecodeSvcTestUpToSpatialLayer0) {
|
|||
// number of frames decoded. This results in 1/2x1/2 resolution (640x360).
|
||||
TEST_P(DecodeSvcTest, DecodeSvcTestUpToSpatialLayer1) {
|
||||
const std::string filename = GET_PARAM(1);
|
||||
testing::internal::scoped_ptr<libvpx_test::CompressedVideoSource> video;
|
||||
std::unique_ptr<libvpx_test::CompressedVideoSource> video;
|
||||
video.reset(new libvpx_test::IVFVideoSource(filename));
|
||||
ASSERT_TRUE(video.get() != NULL);
|
||||
video->Init();
|
||||
|
@ -87,7 +88,7 @@ TEST_P(DecodeSvcTest, DecodeSvcTestUpToSpatialLayer1) {
|
|||
// number of frames decoded. This results in the full resolution (1280x720).
|
||||
TEST_P(DecodeSvcTest, DecodeSvcTestUpToSpatialLayer2) {
|
||||
const std::string filename = GET_PARAM(1);
|
||||
testing::internal::scoped_ptr<libvpx_test::CompressedVideoSource> video;
|
||||
std::unique_ptr<libvpx_test::CompressedVideoSource> video;
|
||||
video.reset(new libvpx_test::IVFVideoSource(filename));
|
||||
ASSERT_TRUE(video.get() != NULL);
|
||||
video->Init();
|
||||
|
@ -105,7 +106,7 @@ TEST_P(DecodeSvcTest, DecodeSvcTestUpToSpatialLayer2) {
|
|||
// the decoding should result in the full resolution (1280x720).
|
||||
TEST_P(DecodeSvcTest, DecodeSvcTestUpToSpatialLayer10) {
|
||||
const std::string filename = GET_PARAM(1);
|
||||
testing::internal::scoped_ptr<libvpx_test::CompressedVideoSource> video;
|
||||
std::unique_ptr<libvpx_test::CompressedVideoSource> video;
|
||||
video.reset(new libvpx_test::IVFVideoSource(filename));
|
||||
ASSERT_TRUE(video.get() != NULL);
|
||||
video->Init();
|
||||
|
|
|
@ -52,9 +52,10 @@ void DecoderTest::HandlePeekResult(Decoder *const decoder,
|
|||
/* Vp8's implementation of PeekStream returns an error if the frame you
|
||||
* pass it is not a keyframe, so we only expect VPX_CODEC_OK on the first
|
||||
* frame, which must be a keyframe. */
|
||||
if (video->frame_number() == 0)
|
||||
if (video->frame_number() == 0) {
|
||||
ASSERT_EQ(VPX_CODEC_OK, res_peek)
|
||||
<< "Peek return failed: " << vpx_codec_err_to_string(res_peek);
|
||||
}
|
||||
} else {
|
||||
/* The Vp9 implementation of PeekStream returns an error only if the
|
||||
* data passed to it isn't a valid Vp9 chunk. */
|
||||
|
@ -97,7 +98,7 @@ void DecoderTest::RunLoop(CompressedVideoSource *video,
|
|||
const vpx_image_t *img = NULL;
|
||||
|
||||
// Get decompressed data
|
||||
while ((img = dec_iter.Next())) {
|
||||
while (!::testing::Test::HasFailure() && (img = dec_iter.Next())) {
|
||||
DecompressedFrameHook(*img, video->frame_number());
|
||||
}
|
||||
}
|
||||
|
|
|
@ -8,8 +8,8 @@
|
|||
* be found in the AUTHORS file in the root of the source tree.
|
||||
*/
|
||||
|
||||
#ifndef TEST_DECODE_TEST_DRIVER_H_
|
||||
#define TEST_DECODE_TEST_DRIVER_H_
|
||||
#ifndef VPX_TEST_DECODE_TEST_DRIVER_H_
|
||||
#define VPX_TEST_DECODE_TEST_DRIVER_H_
|
||||
#include <cstring>
|
||||
#include "third_party/googletest/src/include/gtest/gtest.h"
|
||||
#include "./vpx_config.h"
|
||||
|
@ -159,4 +159,4 @@ class DecoderTest {
|
|||
|
||||
} // namespace libvpx_test
|
||||
|
||||
#endif // TEST_DECODE_TEST_DRIVER_H_
|
||||
#endif // VPX_TEST_DECODE_TEST_DRIVER_H_
|
||||
|
|
|
@ -48,7 +48,7 @@ const EncodePerfTestVideo kVP9EncodePerfTestVectors[] = {
|
|||
EncodePerfTestVideo("niklas_1280_720_30.yuv", 1280, 720, 600, 470),
|
||||
};
|
||||
|
||||
const int kEncodePerfTestSpeeds[] = { 5, 6, 7, 8 };
|
||||
const int kEncodePerfTestSpeeds[] = { 5, 6, 7, 8, 9 };
|
||||
const int kEncodePerfTestThreads[] = { 1, 2, 4 };
|
||||
|
||||
#define NELEMENTS(x) (sizeof((x)) / sizeof((x)[0]))
|
||||
|
|
|
@ -8,6 +8,7 @@
|
|||
* be found in the AUTHORS file in the root of the source tree.
|
||||
*/
|
||||
|
||||
#include <memory>
|
||||
#include <string>
|
||||
|
||||
#include "third_party/googletest/src/include/gtest/gtest.h"
|
||||
|
@ -128,6 +129,8 @@ static bool compare_img(const vpx_image_t *img1, const vpx_image_t *img2) {
|
|||
bool match = (img1->fmt == img2->fmt) && (img1->cs == img2->cs) &&
|
||||
(img1->d_w == img2->d_w) && (img1->d_h == img2->d_h);
|
||||
|
||||
if (!match) return false;
|
||||
|
||||
const unsigned int width_y = img1->d_w;
|
||||
const unsigned int height_y = img1->d_h;
|
||||
unsigned int i;
|
||||
|
@ -177,7 +180,7 @@ void EncoderTest::RunLoop(VideoSource *video) {
|
|||
}
|
||||
|
||||
BeginPassHook(pass);
|
||||
testing::internal::scoped_ptr<Encoder> encoder(
|
||||
std::unique_ptr<Encoder> encoder(
|
||||
codec_->CreateEncoder(cfg_, deadline_, init_flags_, &stats_));
|
||||
ASSERT_TRUE(encoder.get() != NULL);
|
||||
|
||||
|
@ -191,7 +194,7 @@ void EncoderTest::RunLoop(VideoSource *video) {
|
|||
if (init_flags_ & VPX_CODEC_USE_OUTPUT_PARTITION) {
|
||||
dec_init_flags |= VPX_CODEC_USE_INPUT_FRAGMENTS;
|
||||
}
|
||||
testing::internal::scoped_ptr<Decoder> decoder(
|
||||
std::unique_ptr<Decoder> decoder(
|
||||
codec_->CreateDecoder(dec_cfg, dec_init_flags));
|
||||
bool again;
|
||||
for (again = true; again; video->Next()) {
|
||||
|
@ -214,6 +217,7 @@ void EncoderTest::RunLoop(VideoSource *video) {
|
|||
case VPX_CODEC_CX_FRAME_PKT:
|
||||
has_cxdata = true;
|
||||
if (decoder.get() != NULL && DoDecode()) {
|
||||
PreDecodeFrameHook(video, decoder.get());
|
||||
vpx_codec_err_t res_dec = decoder->DecodeFrame(
|
||||
(const uint8_t *)pkt->data.frame.buf, pkt->data.frame.sz);
|
||||
|
||||
|
|
|
@ -7,8 +7,8 @@
|
|||
* in the file PATENTS. All contributing project authors may
|
||||
* be found in the AUTHORS file in the root of the source tree.
|
||||
*/
|
||||
#ifndef TEST_ENCODE_TEST_DRIVER_H_
|
||||
#define TEST_ENCODE_TEST_DRIVER_H_
|
||||
#ifndef VPX_TEST_ENCODE_TEST_DRIVER_H_
|
||||
#define VPX_TEST_ENCODE_TEST_DRIVER_H_
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
@ -128,24 +128,37 @@ class Encoder {
|
|||
ASSERT_EQ(VPX_CODEC_OK, res) << EncoderError();
|
||||
}
|
||||
|
||||
void Control(int ctrl_id, struct vpx_svc_ref_frame_config *arg) {
|
||||
const vpx_codec_err_t res = vpx_codec_control_(&encoder_, ctrl_id, arg);
|
||||
ASSERT_EQ(VPX_CODEC_OK, res) << EncoderError();
|
||||
}
|
||||
|
||||
void Control(int ctrl_id, struct vpx_svc_parameters *arg) {
|
||||
const vpx_codec_err_t res = vpx_codec_control_(&encoder_, ctrl_id, arg);
|
||||
ASSERT_EQ(VPX_CODEC_OK, res) << EncoderError();
|
||||
}
|
||||
|
||||
void Control(int ctrl_id, struct vpx_svc_frame_drop *arg) {
|
||||
const vpx_codec_err_t res = vpx_codec_control_(&encoder_, ctrl_id, arg);
|
||||
ASSERT_EQ(VPX_CODEC_OK, res) << EncoderError();
|
||||
}
|
||||
|
||||
void Control(int ctrl_id, struct vpx_svc_spatial_layer_sync *arg) {
|
||||
const vpx_codec_err_t res = vpx_codec_control_(&encoder_, ctrl_id, arg);
|
||||
ASSERT_EQ(VPX_CODEC_OK, res) << EncoderError();
|
||||
}
|
||||
|
||||
#if CONFIG_VP8_ENCODER || CONFIG_VP9_ENCODER
|
||||
void Control(int ctrl_id, vpx_active_map_t *arg) {
|
||||
const vpx_codec_err_t res = vpx_codec_control_(&encoder_, ctrl_id, arg);
|
||||
ASSERT_EQ(VPX_CODEC_OK, res) << EncoderError();
|
||||
}
|
||||
#endif
|
||||
|
||||
#if CONFIG_VP8_ENCODER
|
||||
void Control(int ctrl_id, vpx_roi_map_t *arg) {
|
||||
const vpx_codec_err_t res = vpx_codec_control_(&encoder_, ctrl_id, arg);
|
||||
ASSERT_EQ(VPX_CODEC_OK, res) << EncoderError();
|
||||
}
|
||||
#endif
|
||||
|
||||
void Config(const vpx_codec_enc_cfg_t *cfg) {
|
||||
const vpx_codec_err_t res = vpx_codec_enc_config_set(&encoder_, cfg);
|
||||
ASSERT_EQ(VPX_CODEC_OK, res) << EncoderError();
|
||||
|
@ -219,6 +232,9 @@ class EncoderTest {
|
|||
virtual void PreEncodeFrameHook(VideoSource * /*video*/,
|
||||
Encoder * /*encoder*/) {}
|
||||
|
||||
virtual void PreDecodeFrameHook(VideoSource * /*video*/,
|
||||
Decoder * /*decoder*/) {}
|
||||
|
||||
virtual void PostEncodeFrameHook(Encoder * /*encoder*/) {}
|
||||
|
||||
// Hook to be called on every compressed data packet.
|
||||
|
@ -273,4 +289,4 @@ class EncoderTest {
|
|||
|
||||
} // namespace libvpx_test
|
||||
|
||||
#endif // TEST_ENCODE_TEST_DRIVER_H_
|
||||
#endif // VPX_TEST_ENCODE_TEST_DRIVER_H_
|
||||
|
|
|
@ -8,6 +8,7 @@
|
|||
* be found in the AUTHORS file in the root of the source tree.
|
||||
*/
|
||||
|
||||
#include <memory>
|
||||
#include <string>
|
||||
|
||||
#include "./vpx_config.h"
|
||||
|
@ -113,9 +114,9 @@ class ExternalFrameBufferList {
|
|||
return 0;
|
||||
}
|
||||
|
||||
// Checks that the ximage data is contained within the external frame buffer
|
||||
// private data passed back in the ximage.
|
||||
void CheckXImageFrameBuffer(const vpx_image_t *img) {
|
||||
// Checks that the vpx_image_t data is contained within the external frame
|
||||
// buffer private data passed back in the vpx_image_t.
|
||||
void CheckImageFrameBuffer(const vpx_image_t *img) {
|
||||
if (img->fb_priv != NULL) {
|
||||
const struct ExternalFrameBuffer *const ext_fb =
|
||||
reinterpret_cast<ExternalFrameBuffer *>(img->fb_priv);
|
||||
|
@ -335,14 +336,13 @@ class ExternalFrameBufferTest : public ::testing::Test {
|
|||
return VPX_CODEC_OK;
|
||||
}
|
||||
|
||||
protected:
|
||||
void CheckDecodedFrames() {
|
||||
libvpx_test::DxDataIterator dec_iter = decoder_->GetDxData();
|
||||
const vpx_image_t *img = NULL;
|
||||
|
||||
// Get decompressed data
|
||||
while ((img = dec_iter.Next()) != NULL) {
|
||||
fb_list_.CheckXImageFrameBuffer(img);
|
||||
fb_list_.CheckImageFrameBuffer(img);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -393,7 +393,7 @@ TEST_P(ExternalFrameBufferMD5Test, ExtFBMD5Match) {
|
|||
#endif
|
||||
|
||||
// Open compressed video file.
|
||||
testing::internal::scoped_ptr<libvpx_test::CompressedVideoSource> video;
|
||||
std::unique_ptr<libvpx_test::CompressedVideoSource> video;
|
||||
if (filename.substr(filename.length() - 3, 3) == "ivf") {
|
||||
video.reset(new libvpx_test::IVFVideoSource(filename));
|
||||
} else {
|
||||
|
|
|
@ -11,6 +11,7 @@
|
|||
#include <math.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <tuple>
|
||||
|
||||
#include "third_party/googletest/src/include/gtest/gtest.h"
|
||||
|
||||
|
@ -43,9 +44,9 @@ typedef void (*FhtFunc)(const int16_t *in, tran_low_t *out, int stride,
|
|||
typedef void (*IhtFunc)(const tran_low_t *in, uint8_t *out, int stride,
|
||||
int tx_type);
|
||||
|
||||
typedef std::tr1::tuple<FdctFunc, IdctFunc, int, vpx_bit_depth_t> Dct8x8Param;
|
||||
typedef std::tr1::tuple<FhtFunc, IhtFunc, int, vpx_bit_depth_t> Ht8x8Param;
|
||||
typedef std::tr1::tuple<IdctFunc, IdctFunc, int, vpx_bit_depth_t> Idct8x8Param;
|
||||
typedef std::tuple<FdctFunc, IdctFunc, int, vpx_bit_depth_t> Dct8x8Param;
|
||||
typedef std::tuple<FhtFunc, IhtFunc, int, vpx_bit_depth_t> Ht8x8Param;
|
||||
typedef std::tuple<IdctFunc, IdctFunc, int, vpx_bit_depth_t> Idct8x8Param;
|
||||
|
||||
void reference_8x8_dct_1d(const double in[8], double out[8]) {
|
||||
const double kInvSqrt2 = 0.707106781186547524400844362104;
|
||||
|
@ -628,7 +629,7 @@ TEST_P(InvTrans8x8DCT, CompareReference) {
|
|||
CompareInvReference(ref_txfm_, thresh_);
|
||||
}
|
||||
|
||||
using std::tr1::make_tuple;
|
||||
using std::make_tuple;
|
||||
|
||||
#if CONFIG_VP9_HIGHBITDEPTH
|
||||
INSTANTIATE_TEST_CASE_P(
|
||||
|
@ -675,6 +676,7 @@ INSTANTIATE_TEST_CASE_P(NEON, FwdTrans8x8DCT,
|
|||
::testing::Values(make_tuple(&vpx_fdct8x8_neon,
|
||||
&vpx_idct8x8_64_add_neon,
|
||||
0, VPX_BITS_8)));
|
||||
|
||||
#if !CONFIG_VP9_HIGHBITDEPTH
|
||||
INSTANTIATE_TEST_CASE_P(
|
||||
NEON, FwdTrans8x8HT,
|
||||
|
|
|
@ -34,7 +34,7 @@ class VP9FrameSizeTestsLarge : public ::libvpx_test::EncoderTest,
|
|||
|
||||
virtual void PreEncodeFrameHook(::libvpx_test::VideoSource *video,
|
||||
::libvpx_test::Encoder *encoder) {
|
||||
if (video->frame() == 1) {
|
||||
if (video->frame() == 0) {
|
||||
encoder->Control(VP8E_SET_CPUUSED, 7);
|
||||
encoder->Control(VP8E_SET_ENABLEAUTOALTREF, 1);
|
||||
encoder->Control(VP8E_SET_ARNR_MAXFRAMES, 7);
|
||||
|
|
|
@ -25,13 +25,13 @@ using ::libvpx_test::ACMRandom;
|
|||
typedef void (*HadamardFunc)(const int16_t *a, ptrdiff_t a_stride,
|
||||
tran_low_t *b);
|
||||
|
||||
void hadamard_loop(const int16_t *a, int a_stride, int16_t *out) {
|
||||
int16_t b[8];
|
||||
void hadamard_loop(const tran_low_t *a, tran_low_t *out) {
|
||||
tran_low_t b[8];
|
||||
for (int i = 0; i < 8; i += 2) {
|
||||
b[i + 0] = a[i * a_stride] + a[(i + 1) * a_stride];
|
||||
b[i + 1] = a[i * a_stride] - a[(i + 1) * a_stride];
|
||||
b[i + 0] = a[i * 8] + a[(i + 1) * 8];
|
||||
b[i + 1] = a[i * 8] - a[(i + 1) * 8];
|
||||
}
|
||||
int16_t c[8];
|
||||
tran_low_t c[8];
|
||||
for (int i = 0; i < 8; i += 4) {
|
||||
c[i + 0] = b[i + 0] + b[i + 2];
|
||||
c[i + 1] = b[i + 1] + b[i + 3];
|
||||
|
@ -49,12 +49,15 @@ void hadamard_loop(const int16_t *a, int a_stride, int16_t *out) {
|
|||
}
|
||||
|
||||
void reference_hadamard8x8(const int16_t *a, int a_stride, tran_low_t *b) {
|
||||
int16_t buf[64];
|
||||
int16_t buf2[64];
|
||||
for (int i = 0; i < 8; ++i) hadamard_loop(a + i, a_stride, buf + i * 8);
|
||||
for (int i = 0; i < 8; ++i) hadamard_loop(buf + i, 8, buf2 + i * 8);
|
||||
|
||||
for (int i = 0; i < 64; ++i) b[i] = (tran_low_t)buf2[i];
|
||||
tran_low_t input[64];
|
||||
tran_low_t buf[64];
|
||||
for (int i = 0; i < 8; ++i) {
|
||||
for (int j = 0; j < 8; ++j) {
|
||||
input[i * 8 + j] = static_cast<tran_low_t>(a[i * a_stride + j]);
|
||||
}
|
||||
}
|
||||
for (int i = 0; i < 8; ++i) hadamard_loop(input + i, buf + i * 8);
|
||||
for (int i = 0; i < 8; ++i) hadamard_loop(buf + i, b + i * 8);
|
||||
}
|
||||
|
||||
void reference_hadamard16x16(const int16_t *a, int a_stride, tran_low_t *b) {
|
||||
|
@ -89,205 +92,229 @@ void reference_hadamard16x16(const int16_t *a, int a_stride, tran_low_t *b) {
|
|||
}
|
||||
}
|
||||
|
||||
class HadamardTestBase : public ::testing::TestWithParam<HadamardFunc> {
|
||||
void reference_hadamard32x32(const int16_t *a, int a_stride, tran_low_t *b) {
|
||||
reference_hadamard16x16(a + 0 + 0 * a_stride, a_stride, b + 0);
|
||||
reference_hadamard16x16(a + 16 + 0 * a_stride, a_stride, b + 256);
|
||||
reference_hadamard16x16(a + 0 + 16 * a_stride, a_stride, b + 512);
|
||||
reference_hadamard16x16(a + 16 + 16 * a_stride, a_stride, b + 768);
|
||||
|
||||
for (int i = 0; i < 256; ++i) {
|
||||
const tran_low_t a0 = b[0];
|
||||
const tran_low_t a1 = b[256];
|
||||
const tran_low_t a2 = b[512];
|
||||
const tran_low_t a3 = b[768];
|
||||
|
||||
const tran_low_t b0 = (a0 + a1) >> 2;
|
||||
const tran_low_t b1 = (a0 - a1) >> 2;
|
||||
const tran_low_t b2 = (a2 + a3) >> 2;
|
||||
const tran_low_t b3 = (a2 - a3) >> 2;
|
||||
|
||||
b[0] = b0 + b2;
|
||||
b[256] = b1 + b3;
|
||||
b[512] = b0 - b2;
|
||||
b[768] = b1 - b3;
|
||||
|
||||
++b;
|
||||
}
|
||||
}
|
||||
|
||||
struct HadamardFuncWithSize {
|
||||
HadamardFuncWithSize(HadamardFunc f, int s) : func(f), block_size(s) {}
|
||||
HadamardFunc func;
|
||||
int block_size;
|
||||
};
|
||||
|
||||
std::ostream &operator<<(std::ostream &os, const HadamardFuncWithSize &hfs) {
|
||||
return os << "block size: " << hfs.block_size;
|
||||
}
|
||||
|
||||
class HadamardTestBase : public ::testing::TestWithParam<HadamardFuncWithSize> {
|
||||
public:
|
||||
virtual void SetUp() {
|
||||
h_func_ = GetParam();
|
||||
h_func_ = GetParam().func;
|
||||
bwh_ = GetParam().block_size;
|
||||
block_size_ = bwh_ * bwh_;
|
||||
rnd_.Reset(ACMRandom::DeterministicSeed());
|
||||
}
|
||||
|
||||
protected:
|
||||
HadamardFunc h_func_;
|
||||
ACMRandom rnd_;
|
||||
};
|
||||
virtual int16_t Rand() = 0;
|
||||
|
||||
void HadamardSpeedTest(const char *name, HadamardFunc const func,
|
||||
const int16_t *input, int stride, tran_low_t *output,
|
||||
int times) {
|
||||
int i;
|
||||
vpx_usec_timer timer;
|
||||
|
||||
vpx_usec_timer_start(&timer);
|
||||
for (i = 0; i < times; ++i) {
|
||||
func(input, stride, output);
|
||||
}
|
||||
vpx_usec_timer_mark(&timer);
|
||||
|
||||
const int elapsed_time = static_cast<int>(vpx_usec_timer_elapsed(&timer));
|
||||
printf("%s[%12d runs]: %d us\n", name, times, elapsed_time);
|
||||
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);
|
||||
}
|
||||
|
||||
class Hadamard8x8Test : public HadamardTestBase {};
|
||||
|
||||
void HadamardSpeedTest8x8(HadamardFunc const func, int times) {
|
||||
DECLARE_ALIGNED(16, int16_t, input[64]);
|
||||
DECLARE_ALIGNED(16, tran_low_t, output[64]);
|
||||
memset(input, 1, sizeof(input));
|
||||
HadamardSpeedTest("Hadamard8x8", func, input, 8, output, times);
|
||||
}
|
||||
|
||||
TEST_P(Hadamard8x8Test, CompareReferenceRandom) {
|
||||
DECLARE_ALIGNED(16, int16_t, a[64]);
|
||||
DECLARE_ALIGNED(16, tran_low_t, b[64]);
|
||||
tran_low_t b_ref[64];
|
||||
for (int i = 0; i < 64; ++i) {
|
||||
a[i] = rnd_.Rand9Signed();
|
||||
}
|
||||
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));
|
||||
|
||||
reference_hadamard8x8(a, 8, b_ref);
|
||||
ASM_REGISTER_STATE_CHECK(h_func_(a, 8, b));
|
||||
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 + 64);
|
||||
std::sort(b_ref, b_ref + 64);
|
||||
std::sort(b, b + block_size_);
|
||||
std::sort(b_ref, b_ref + block_size_);
|
||||
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();
|
||||
}
|
||||
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));
|
||||
|
||||
reference_hadamard8x8(a, i, 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 + 64);
|
||||
std::sort(b_ref, b_ref + 64);
|
||||
std::sort(b, b + block_size_);
|
||||
std::sort(b_ref, b_ref + block_size_);
|
||||
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);
|
||||
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);
|
||||
}
|
||||
|
||||
INSTANTIATE_TEST_CASE_P(C, Hadamard8x8Test,
|
||||
::testing::Values(&vpx_hadamard_8x8_c));
|
||||
protected:
|
||||
int bwh_;
|
||||
int block_size_;
|
||||
HadamardFunc h_func_;
|
||||
ACMRandom rnd_;
|
||||
};
|
||||
|
||||
class HadamardLowbdTest : public HadamardTestBase {
|
||||
protected:
|
||||
virtual int16_t Rand() { return rnd_.Rand9Signed(); }
|
||||
};
|
||||
|
||||
TEST_P(HadamardLowbdTest, CompareReferenceRandom) { CompareReferenceRandom(); }
|
||||
|
||||
TEST_P(HadamardLowbdTest, VaryStride) { VaryStride(); }
|
||||
|
||||
TEST_P(HadamardLowbdTest, DISABLED_Speed) {
|
||||
SpeedTest(10);
|
||||
SpeedTest(10000);
|
||||
SpeedTest(10000000);
|
||||
}
|
||||
|
||||
INSTANTIATE_TEST_CASE_P(
|
||||
C, HadamardLowbdTest,
|
||||
::testing::Values(HadamardFuncWithSize(&vpx_hadamard_8x8_c, 8),
|
||||
HadamardFuncWithSize(&vpx_hadamard_16x16_c, 16),
|
||||
HadamardFuncWithSize(&vpx_hadamard_32x32_c, 32)));
|
||||
|
||||
#if HAVE_SSE2
|
||||
INSTANTIATE_TEST_CASE_P(SSE2, Hadamard8x8Test,
|
||||
::testing::Values(&vpx_hadamard_8x8_sse2));
|
||||
INSTANTIATE_TEST_CASE_P(
|
||||
SSE2, HadamardLowbdTest,
|
||||
::testing::Values(HadamardFuncWithSize(&vpx_hadamard_8x8_sse2, 8),
|
||||
HadamardFuncWithSize(&vpx_hadamard_16x16_sse2, 16),
|
||||
HadamardFuncWithSize(&vpx_hadamard_32x32_sse2, 32)));
|
||||
#endif // HAVE_SSE2
|
||||
|
||||
#if HAVE_AVX2
|
||||
INSTANTIATE_TEST_CASE_P(
|
||||
AVX2, HadamardLowbdTest,
|
||||
::testing::Values(HadamardFuncWithSize(&vpx_hadamard_16x16_avx2, 16),
|
||||
HadamardFuncWithSize(&vpx_hadamard_32x32_avx2, 32)));
|
||||
#endif // HAVE_AVX2
|
||||
|
||||
#if HAVE_SSSE3 && ARCH_X86_64
|
||||
INSTANTIATE_TEST_CASE_P(SSSE3, Hadamard8x8Test,
|
||||
::testing::Values(&vpx_hadamard_8x8_ssse3));
|
||||
INSTANTIATE_TEST_CASE_P(
|
||||
SSSE3, HadamardLowbdTest,
|
||||
::testing::Values(HadamardFuncWithSize(&vpx_hadamard_8x8_ssse3, 8)));
|
||||
#endif // HAVE_SSSE3 && ARCH_X86_64
|
||||
|
||||
#if HAVE_NEON
|
||||
INSTANTIATE_TEST_CASE_P(NEON, Hadamard8x8Test,
|
||||
::testing::Values(&vpx_hadamard_8x8_neon));
|
||||
INSTANTIATE_TEST_CASE_P(
|
||||
NEON, HadamardLowbdTest,
|
||||
::testing::Values(HadamardFuncWithSize(&vpx_hadamard_8x8_neon, 8),
|
||||
HadamardFuncWithSize(&vpx_hadamard_16x16_neon, 16)));
|
||||
#endif // HAVE_NEON
|
||||
|
||||
// TODO(jingning): Remove highbitdepth flag when the SIMD functions are
|
||||
// in place and turn on the unit test.
|
||||
#if !CONFIG_VP9_HIGHBITDEPTH
|
||||
#if HAVE_MSA
|
||||
INSTANTIATE_TEST_CASE_P(MSA, Hadamard8x8Test,
|
||||
::testing::Values(&vpx_hadamard_8x8_msa));
|
||||
INSTANTIATE_TEST_CASE_P(
|
||||
MSA, HadamardLowbdTest,
|
||||
::testing::Values(HadamardFuncWithSize(&vpx_hadamard_8x8_msa, 8),
|
||||
HadamardFuncWithSize(&vpx_hadamard_16x16_msa, 16)));
|
||||
#endif // HAVE_MSA
|
||||
#endif // !CONFIG_VP9_HIGHBITDEPTH
|
||||
|
||||
#if HAVE_VSX
|
||||
INSTANTIATE_TEST_CASE_P(VSX, Hadamard8x8Test,
|
||||
::testing::Values(&vpx_hadamard_8x8_vsx));
|
||||
INSTANTIATE_TEST_CASE_P(
|
||||
VSX, HadamardLowbdTest,
|
||||
::testing::Values(HadamardFuncWithSize(&vpx_hadamard_8x8_vsx, 8),
|
||||
HadamardFuncWithSize(&vpx_hadamard_16x16_vsx, 16)));
|
||||
#endif // HAVE_VSX
|
||||
|
||||
class Hadamard16x16Test : public HadamardTestBase {};
|
||||
#if CONFIG_VP9_HIGHBITDEPTH
|
||||
class HadamardHighbdTest : public HadamardTestBase {
|
||||
protected:
|
||||
virtual int16_t Rand() { return rnd_.Rand13Signed(); }
|
||||
};
|
||||
|
||||
void HadamardSpeedTest16x16(HadamardFunc const func, int times) {
|
||||
DECLARE_ALIGNED(16, int16_t, input[256]);
|
||||
DECLARE_ALIGNED(16, tran_low_t, output[256]);
|
||||
memset(input, 1, sizeof(input));
|
||||
HadamardSpeedTest("Hadamard16x16", func, input, 16, output, times);
|
||||
TEST_P(HadamardHighbdTest, CompareReferenceRandom) { CompareReferenceRandom(); }
|
||||
|
||||
TEST_P(HadamardHighbdTest, VaryStride) { VaryStride(); }
|
||||
|
||||
TEST_P(HadamardHighbdTest, DISABLED_Speed) {
|
||||
SpeedTest(10);
|
||||
SpeedTest(10000);
|
||||
SpeedTest(10000000);
|
||||
}
|
||||
|
||||
TEST_P(Hadamard16x16Test, CompareReferenceRandom) {
|
||||
DECLARE_ALIGNED(16, int16_t, a[16 * 16]);
|
||||
DECLARE_ALIGNED(16, tran_low_t, b[16 * 16]);
|
||||
tran_low_t b_ref[16 * 16];
|
||||
for (int i = 0; i < 16 * 16; ++i) {
|
||||
a[i] = rnd_.Rand9Signed();
|
||||
}
|
||||
memset(b, 0, sizeof(b));
|
||||
memset(b_ref, 0, sizeof(b_ref));
|
||||
|
||||
reference_hadamard16x16(a, 16, b_ref);
|
||||
ASM_REGISTER_STATE_CHECK(h_func_(a, 16, b));
|
||||
|
||||
// The order of the output is not important. Sort before checking.
|
||||
std::sort(b, b + 16 * 16);
|
||||
std::sort(b_ref, b_ref + 16 * 16);
|
||||
EXPECT_EQ(0, memcmp(b, b_ref, sizeof(b)));
|
||||
}
|
||||
|
||||
TEST_P(Hadamard16x16Test, VaryStride) {
|
||||
DECLARE_ALIGNED(16, int16_t, a[16 * 16 * 8]);
|
||||
DECLARE_ALIGNED(16, tran_low_t, b[16 * 16]);
|
||||
tran_low_t b_ref[16 * 16];
|
||||
for (int i = 0; i < 16 * 16 * 8; ++i) {
|
||||
a[i] = rnd_.Rand9Signed();
|
||||
}
|
||||
|
||||
for (int i = 8; i < 64; i += 8) {
|
||||
memset(b, 0, sizeof(b));
|
||||
memset(b_ref, 0, sizeof(b_ref));
|
||||
|
||||
reference_hadamard16x16(a, i, b_ref);
|
||||
ASM_REGISTER_STATE_CHECK(h_func_(a, i, b));
|
||||
|
||||
// The order of the output is not important. Sort before checking.
|
||||
std::sort(b, b + 16 * 16);
|
||||
std::sort(b_ref, b_ref + 16 * 16);
|
||||
EXPECT_EQ(0, memcmp(b, b_ref, sizeof(b)));
|
||||
}
|
||||
}
|
||||
|
||||
TEST_P(Hadamard16x16Test, DISABLED_Speed) {
|
||||
HadamardSpeedTest16x16(h_func_, 10);
|
||||
HadamardSpeedTest16x16(h_func_, 10000);
|
||||
HadamardSpeedTest16x16(h_func_, 10000000);
|
||||
}
|
||||
|
||||
INSTANTIATE_TEST_CASE_P(C, Hadamard16x16Test,
|
||||
::testing::Values(&vpx_hadamard_16x16_c));
|
||||
|
||||
#if HAVE_SSE2
|
||||
INSTANTIATE_TEST_CASE_P(SSE2, Hadamard16x16Test,
|
||||
::testing::Values(&vpx_hadamard_16x16_sse2));
|
||||
#endif // HAVE_SSE2
|
||||
INSTANTIATE_TEST_CASE_P(
|
||||
C, HadamardHighbdTest,
|
||||
::testing::Values(HadamardFuncWithSize(&vpx_highbd_hadamard_8x8_c, 8),
|
||||
HadamardFuncWithSize(&vpx_highbd_hadamard_16x16_c, 16),
|
||||
HadamardFuncWithSize(&vpx_highbd_hadamard_32x32_c, 32)));
|
||||
|
||||
#if HAVE_AVX2
|
||||
INSTANTIATE_TEST_CASE_P(AVX2, Hadamard16x16Test,
|
||||
::testing::Values(&vpx_hadamard_16x16_avx2));
|
||||
INSTANTIATE_TEST_CASE_P(
|
||||
AVX2, HadamardHighbdTest,
|
||||
::testing::Values(HadamardFuncWithSize(&vpx_highbd_hadamard_8x8_avx2, 8),
|
||||
HadamardFuncWithSize(&vpx_highbd_hadamard_16x16_avx2, 16),
|
||||
HadamardFuncWithSize(&vpx_highbd_hadamard_32x32_avx2,
|
||||
32)));
|
||||
#endif // HAVE_AVX2
|
||||
|
||||
#if HAVE_VSX
|
||||
INSTANTIATE_TEST_CASE_P(VSX, Hadamard16x16Test,
|
||||
::testing::Values(&vpx_hadamard_16x16_vsx));
|
||||
#endif // HAVE_VSX
|
||||
|
||||
#if HAVE_NEON
|
||||
INSTANTIATE_TEST_CASE_P(NEON, Hadamard16x16Test,
|
||||
::testing::Values(&vpx_hadamard_16x16_neon));
|
||||
#endif // HAVE_NEON
|
||||
|
||||
#if !CONFIG_VP9_HIGHBITDEPTH
|
||||
#if HAVE_MSA
|
||||
INSTANTIATE_TEST_CASE_P(MSA, Hadamard16x16Test,
|
||||
::testing::Values(&vpx_hadamard_16x16_msa));
|
||||
#endif // HAVE_MSA
|
||||
#endif // !CONFIG_VP9_HIGHBITDEPTH
|
||||
#endif // CONFIG_VP9_HIGHBITDEPTH
|
||||
} // namespace
|
||||
|
|
|
@ -7,8 +7,8 @@
|
|||
* in the file PATENTS. All contributing project authors may
|
||||
* be found in the AUTHORS file in the root of the source tree.
|
||||
*/
|
||||
#ifndef TEST_I420_VIDEO_SOURCE_H_
|
||||
#define TEST_I420_VIDEO_SOURCE_H_
|
||||
#ifndef VPX_TEST_I420_VIDEO_SOURCE_H_
|
||||
#define VPX_TEST_I420_VIDEO_SOURCE_H_
|
||||
#include <cstdio>
|
||||
#include <cstdlib>
|
||||
#include <string>
|
||||
|
@ -30,4 +30,4 @@ class I420VideoSource : public YUVVideoSource {
|
|||
|
||||
} // namespace libvpx_test
|
||||
|
||||
#endif // TEST_I420_VIDEO_SOURCE_H_
|
||||
#endif // VPX_TEST_I420_VIDEO_SOURCE_H_
|
||||
|
|
|
@ -72,6 +72,7 @@ TEST_P(IDCTTest, TestAllZeros) {
|
|||
|
||||
TEST_P(IDCTTest, TestAllOnes) {
|
||||
input->Set(0);
|
||||
ASSERT_TRUE(input->TopLeftPixel() != NULL);
|
||||
// When the first element is '4' it will fill the output buffer with '1'.
|
||||
input->TopLeftPixel()[0] = 4;
|
||||
predict->Set(0);
|
||||
|
@ -89,6 +90,7 @@ TEST_P(IDCTTest, TestAddOne) {
|
|||
// Set the transform output to '1' and make sure it gets added to the
|
||||
// prediction buffer.
|
||||
input->Set(0);
|
||||
ASSERT_TRUE(input->TopLeftPixel() != NULL);
|
||||
input->TopLeftPixel()[0] = 4;
|
||||
output->Set(0);
|
||||
|
||||
|
@ -174,4 +176,4 @@ INSTANTIATE_TEST_CASE_P(MSA, IDCTTest,
|
|||
INSTANTIATE_TEST_CASE_P(MMI, IDCTTest,
|
||||
::testing::Values(vp8_short_idct4x4llm_mmi));
|
||||
#endif // HAVE_MMI
|
||||
}
|
||||
} // namespace
|
||||
|
|
|
@ -10,6 +10,7 @@
|
|||
|
||||
#include <cstdio>
|
||||
#include <cstdlib>
|
||||
#include <memory>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include "third_party/googletest/src/include/gtest/gtest.h"
|
||||
|
@ -89,7 +90,7 @@ class InvalidFileTest : public ::libvpx_test::DecoderTest,
|
|||
const std::string filename = input.filename;
|
||||
|
||||
// Open compressed video file.
|
||||
testing::internal::scoped_ptr<libvpx_test::CompressedVideoSource> video;
|
||||
std::unique_ptr<libvpx_test::CompressedVideoSource> video;
|
||||
if (filename.substr(filename.length() - 3, 3) == "ivf") {
|
||||
video.reset(new libvpx_test::IVFVideoSource(filename));
|
||||
} else if (filename.substr(filename.length() - 4, 4) == "webm") {
|
||||
|
@ -123,6 +124,8 @@ TEST_P(InvalidFileTest, ReturnCode) { RunTest(); }
|
|||
#if CONFIG_VP8_DECODER
|
||||
const DecodeParam kVP8InvalidFileTests[] = {
|
||||
{ 1, "invalid-bug-1443.ivf" },
|
||||
{ 1, "invalid-token-partition.ivf" },
|
||||
{ 1, "invalid-vp80-00-comprehensive-s17661_r01-05_b6-.ivf" },
|
||||
};
|
||||
|
||||
VP8_INSTANTIATE_TEST_CASE(InvalidFileTest,
|
||||
|
@ -202,6 +205,8 @@ const DecodeParam kMultiThreadedVP9InvalidFileTests[] = {
|
|||
{ 2, "invalid-vp90-2-09-aq2.webm.ivf.s3984_r01-05_b6-.v2.ivf" },
|
||||
{ 4, "invalid-vp90-2-09-subpixel-00.ivf.s19552_r01-05_b6-.v2.ivf" },
|
||||
{ 2, "invalid-crbug-629481.webm" },
|
||||
{ 3, "invalid-crbug-1558.ivf" },
|
||||
{ 4, "invalid-crbug-1562.ivf" },
|
||||
};
|
||||
|
||||
INSTANTIATE_TEST_CASE_P(
|
||||
|
|
|
@ -7,8 +7,8 @@
|
|||
* in the file PATENTS. All contributing project authors may
|
||||
* be found in the AUTHORS file in the root of the source tree.
|
||||
*/
|
||||
#ifndef TEST_IVF_VIDEO_SOURCE_H_
|
||||
#define TEST_IVF_VIDEO_SOURCE_H_
|
||||
#ifndef VPX_TEST_IVF_VIDEO_SOURCE_H_
|
||||
#define VPX_TEST_IVF_VIDEO_SOURCE_H_
|
||||
#include <cstdio>
|
||||
#include <cstdlib>
|
||||
#include <new>
|
||||
|
@ -16,7 +16,7 @@
|
|||
#include "test/video_source.h"
|
||||
|
||||
namespace libvpx_test {
|
||||
const unsigned int kCodeBufferSize = 256 * 1024;
|
||||
const unsigned int kCodeBufferSize = 256 * 1024 * 1024;
|
||||
const unsigned int kIvfFileHdrSize = 32;
|
||||
const unsigned int kIvfFrameHdrSize = 12;
|
||||
|
||||
|
@ -103,4 +103,4 @@ class IVFVideoSource : public CompressedVideoSource {
|
|||
|
||||
} // namespace libvpx_test
|
||||
|
||||
#endif // TEST_IVF_VIDEO_SOURCE_H_
|
||||
#endif // VPX_TEST_IVF_VIDEO_SOURCE_H_
|
||||
|
|
|
@ -38,7 +38,7 @@ class KeyframeTest
|
|||
if (kf_do_force_kf_) {
|
||||
frame_flags_ = (video->frame() % 3) ? 0 : VPX_EFLAG_FORCE_KF;
|
||||
}
|
||||
if (set_cpu_used_ && video->frame() == 1) {
|
||||
if (set_cpu_used_ && video->frame() == 0) {
|
||||
encoder->Control(VP8E_SET_CPUUSED, set_cpu_used_);
|
||||
}
|
||||
}
|
||||
|
@ -68,7 +68,9 @@ TEST_P(KeyframeTest, TestRandomVideoSource) {
|
|||
|
||||
// In realtime mode - auto placed keyframes are exceedingly rare, don't
|
||||
// bother with this check if(GetParam() > 0)
|
||||
if (GET_PARAM(1) > 0) EXPECT_GT(kf_count_, 1);
|
||||
if (GET_PARAM(1) > 0) {
|
||||
EXPECT_GT(kf_count_, 1);
|
||||
}
|
||||
}
|
||||
|
||||
TEST_P(KeyframeTest, TestDisableKeyframes) {
|
||||
|
@ -128,8 +130,9 @@ TEST_P(KeyframeTest, TestAutoKeyframe) {
|
|||
|
||||
// In realtime mode - auto placed keyframes are exceedingly rare, don't
|
||||
// bother with this check
|
||||
if (GET_PARAM(1) > 0)
|
||||
if (GET_PARAM(1) > 0) {
|
||||
EXPECT_EQ(2u, kf_pts_list_.size()) << " Not the right number of keyframes ";
|
||||
}
|
||||
|
||||
// Verify that keyframes match the file keyframes in the file.
|
||||
for (std::vector<vpx_codec_pts_t>::const_iterator iter = kf_pts_list_.begin();
|
||||
|
|
|
@ -11,6 +11,7 @@
|
|||
#include <cmath>
|
||||
#include <cstdlib>
|
||||
#include <string>
|
||||
#include <tuple>
|
||||
|
||||
#include "third_party/googletest/src/include/gtest/gtest.h"
|
||||
|
||||
|
@ -56,8 +57,8 @@ typedef void (*dual_loop_op_t)(Pixel *s, int p, const uint8_t *blimit0,
|
|||
const uint8_t *thresh1);
|
||||
#endif // CONFIG_VP9_HIGHBITDEPTH
|
||||
|
||||
typedef std::tr1::tuple<loop_op_t, loop_op_t, int> loop8_param_t;
|
||||
typedef std::tr1::tuple<dual_loop_op_t, dual_loop_op_t, int> dualloop8_param_t;
|
||||
typedef std::tuple<loop_op_t, loop_op_t, int> loop8_param_t;
|
||||
typedef std::tuple<dual_loop_op_t, dual_loop_op_t, int> dualloop8_param_t;
|
||||
|
||||
void InitInput(Pixel *s, Pixel *ref_s, ACMRandom *rnd, const uint8_t limit,
|
||||
const int mask, const int32_t p, const int i) {
|
||||
|
@ -402,7 +403,7 @@ TEST_P(Loop8Test9Param, ValueCheck) {
|
|||
<< "First failed at test case " << first_failure;
|
||||
}
|
||||
|
||||
using std::tr1::make_tuple;
|
||||
using std::make_tuple;
|
||||
|
||||
#if HAVE_SSE2
|
||||
#if CONFIG_VP9_HIGHBITDEPTH
|
||||
|
|
|
@ -8,8 +8,8 @@
|
|||
* be found in the AUTHORS file in the root of the source tree.
|
||||
*/
|
||||
|
||||
#ifndef TEST_MD5_HELPER_H_
|
||||
#define TEST_MD5_HELPER_H_
|
||||
#ifndef VPX_TEST_MD5_HELPER_H_
|
||||
#define VPX_TEST_MD5_HELPER_H_
|
||||
|
||||
#include "./md5_utils.h"
|
||||
#include "vpx/vpx_decoder.h"
|
||||
|
@ -72,4 +72,4 @@ class MD5 {
|
|||
|
||||
} // namespace libvpx_test
|
||||
|
||||
#endif // TEST_MD5_HELPER_H_
|
||||
#endif // VPX_TEST_MD5_HELPER_H_
|
||||
|
|
|
@ -11,8 +11,8 @@
|
|||
#include <math.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <limits>
|
||||
#include <tuple>
|
||||
|
||||
#include "third_party/googletest/src/include/gtest/gtest.h"
|
||||
|
||||
|
@ -51,8 +51,8 @@ void highbd_wrapper(const tran_low_t *in, uint8_t *out, int stride, int bd) {
|
|||
}
|
||||
#endif
|
||||
|
||||
typedef std::tr1::tuple<FwdTxfmFunc, InvTxfmWithBdFunc, InvTxfmWithBdFunc,
|
||||
TX_SIZE, int, int, int>
|
||||
typedef std::tuple<FwdTxfmFunc, InvTxfmWithBdFunc, InvTxfmWithBdFunc, TX_SIZE,
|
||||
int, int, int>
|
||||
PartialInvTxfmParam;
|
||||
const int kMaxNumCoeffs = 1024;
|
||||
const int kCountTestBlock = 1000;
|
||||
|
@ -324,7 +324,7 @@ TEST_P(PartialIDctTest, DISABLED_Speed) {
|
|||
<< "Error: partial inverse transform produces different results";
|
||||
}
|
||||
|
||||
using std::tr1::make_tuple;
|
||||
using std::make_tuple;
|
||||
|
||||
const PartialInvTxfmParam c_partial_idct_tests[] = {
|
||||
#if CONFIG_VP9_HIGHBITDEPTH
|
||||
|
|
|
@ -11,6 +11,7 @@
|
|||
#include "./vpx_config.h"
|
||||
#include "./vpx_dsp_rtcd.h"
|
||||
#include "test/acm_random.h"
|
||||
#include "test/bench.h"
|
||||
#include "test/buffer.h"
|
||||
#include "test/clear_system_state.h"
|
||||
#include "test/register_state_check.h"
|
||||
|
@ -32,7 +33,6 @@ typedef void (*VpxMbPostProcDownFunc)(unsigned char *dst, int pitch, int rows,
|
|||
int cols, int flimit);
|
||||
|
||||
namespace {
|
||||
|
||||
// Compute the filter level used in post proc from the loop filter strength
|
||||
int q2mbl(int x) {
|
||||
if (x < 20) x = 20;
|
||||
|
@ -42,33 +42,52 @@ int q2mbl(int x) {
|
|||
}
|
||||
|
||||
class VpxPostProcDownAndAcrossMbRowTest
|
||||
: public ::testing::TestWithParam<VpxPostProcDownAndAcrossMbRowFunc> {
|
||||
: public AbstractBench,
|
||||
public ::testing::TestWithParam<VpxPostProcDownAndAcrossMbRowFunc> {
|
||||
public:
|
||||
VpxPostProcDownAndAcrossMbRowTest()
|
||||
: mb_post_proc_down_and_across_(GetParam()) {}
|
||||
virtual void TearDown() { libvpx_test::ClearSystemState(); }
|
||||
|
||||
protected:
|
||||
virtual void Run();
|
||||
|
||||
const VpxPostProcDownAndAcrossMbRowFunc mb_post_proc_down_and_across_;
|
||||
// Size of the underlying data block that will be filtered.
|
||||
int block_width_;
|
||||
int block_height_;
|
||||
Buffer<uint8_t> *src_image_;
|
||||
Buffer<uint8_t> *dst_image_;
|
||||
uint8_t *flimits_;
|
||||
};
|
||||
|
||||
void VpxPostProcDownAndAcrossMbRowTest::Run() {
|
||||
mb_post_proc_down_and_across_(
|
||||
src_image_->TopLeftPixel(), dst_image_->TopLeftPixel(),
|
||||
src_image_->stride(), dst_image_->stride(), block_width_, flimits_, 16);
|
||||
}
|
||||
|
||||
// Test routine for the VPx post-processing function
|
||||
// vpx_post_proc_down_and_across_mb_row_c.
|
||||
|
||||
TEST_P(VpxPostProcDownAndAcrossMbRowTest, CheckFilterOutput) {
|
||||
// Size of the underlying data block that will be filtered.
|
||||
const int block_width = 16;
|
||||
const int block_height = 16;
|
||||
block_width_ = 16;
|
||||
block_height_ = 16;
|
||||
|
||||
// 5-tap filter needs 2 padding rows above and below the block in the input.
|
||||
Buffer<uint8_t> src_image = Buffer<uint8_t>(block_width, block_height, 2);
|
||||
Buffer<uint8_t> src_image = Buffer<uint8_t>(block_width_, block_height_, 2);
|
||||
ASSERT_TRUE(src_image.Init());
|
||||
|
||||
// Filter extends output block by 8 samples at left and right edges.
|
||||
// Though the left padding is only 8 bytes, the assembly code tries to
|
||||
// read 16 bytes before the pointer.
|
||||
Buffer<uint8_t> dst_image =
|
||||
Buffer<uint8_t>(block_width, block_height, 8, 16, 8, 8);
|
||||
Buffer<uint8_t>(block_width_, block_height_, 8, 16, 8, 8);
|
||||
ASSERT_TRUE(dst_image.Init());
|
||||
|
||||
uint8_t *const flimits =
|
||||
reinterpret_cast<uint8_t *>(vpx_memalign(16, block_width));
|
||||
(void)memset(flimits, 255, block_width);
|
||||
flimits_ = reinterpret_cast<uint8_t *>(vpx_memalign(16, block_width_));
|
||||
(void)memset(flimits_, 255, block_width_);
|
||||
|
||||
// Initialize pixels in the input:
|
||||
// block pixels to value 1,
|
||||
|
@ -79,37 +98,36 @@ TEST_P(VpxPostProcDownAndAcrossMbRowTest, CheckFilterOutput) {
|
|||
// Initialize pixels in the output to 99.
|
||||
dst_image.Set(99);
|
||||
|
||||
ASM_REGISTER_STATE_CHECK(GetParam()(
|
||||
ASM_REGISTER_STATE_CHECK(mb_post_proc_down_and_across_(
|
||||
src_image.TopLeftPixel(), dst_image.TopLeftPixel(), src_image.stride(),
|
||||
dst_image.stride(), block_width, flimits, 16));
|
||||
dst_image.stride(), block_width_, flimits_, 16));
|
||||
|
||||
static const uint8_t kExpectedOutput[block_height] = {
|
||||
4, 3, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 3, 4
|
||||
};
|
||||
static const uint8_t kExpectedOutput[] = { 4, 3, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 3, 4 };
|
||||
|
||||
uint8_t *pixel_ptr = dst_image.TopLeftPixel();
|
||||
for (int i = 0; i < block_height; ++i) {
|
||||
for (int j = 0; j < block_width; ++j) {
|
||||
for (int i = 0; i < block_height_; ++i) {
|
||||
for (int j = 0; j < block_width_; ++j) {
|
||||
ASSERT_EQ(kExpectedOutput[i], pixel_ptr[j])
|
||||
<< "at (" << i << ", " << j << ")";
|
||||
}
|
||||
pixel_ptr += dst_image.stride();
|
||||
}
|
||||
|
||||
vpx_free(flimits);
|
||||
vpx_free(flimits_);
|
||||
};
|
||||
|
||||
TEST_P(VpxPostProcDownAndAcrossMbRowTest, CheckCvsAssembly) {
|
||||
// Size of the underlying data block that will be filtered.
|
||||
// Y blocks are always a multiple of 16 wide and exactly 16 high. U and V
|
||||
// blocks are always a multiple of 8 wide and exactly 8 high.
|
||||
const int block_width = 136;
|
||||
const int block_height = 16;
|
||||
block_width_ = 136;
|
||||
block_height_ = 16;
|
||||
|
||||
// 5-tap filter needs 2 padding rows above and below the block in the input.
|
||||
// SSE2 reads in blocks of 16. Pad an extra 8 in case the width is not %16.
|
||||
Buffer<uint8_t> src_image =
|
||||
Buffer<uint8_t>(block_width, block_height, 2, 2, 10, 2);
|
||||
Buffer<uint8_t>(block_width_, block_height_, 2, 2, 10, 2);
|
||||
ASSERT_TRUE(src_image.Init());
|
||||
|
||||
// Filter extends output block by 8 samples at left and right edges.
|
||||
|
@ -118,17 +136,17 @@ TEST_P(VpxPostProcDownAndAcrossMbRowTest, CheckCvsAssembly) {
|
|||
// not a problem.
|
||||
// SSE2 reads in blocks of 16. Pad an extra 8 in case the width is not %16.
|
||||
Buffer<uint8_t> dst_image =
|
||||
Buffer<uint8_t>(block_width, block_height, 8, 8, 16, 8);
|
||||
Buffer<uint8_t>(block_width_, block_height_, 8, 8, 16, 8);
|
||||
ASSERT_TRUE(dst_image.Init());
|
||||
Buffer<uint8_t> dst_image_ref = Buffer<uint8_t>(block_width, block_height, 8);
|
||||
Buffer<uint8_t> dst_image_ref =
|
||||
Buffer<uint8_t>(block_width_, block_height_, 8);
|
||||
ASSERT_TRUE(dst_image_ref.Init());
|
||||
|
||||
// Filter values are set in blocks of 16 for Y and 8 for U/V. Each macroblock
|
||||
// can have a different filter. SSE2 assembly reads flimits in blocks of 16 so
|
||||
// it must be padded out.
|
||||
const int flimits_width = block_width % 16 ? block_width + 8 : block_width;
|
||||
uint8_t *const flimits =
|
||||
reinterpret_cast<uint8_t *>(vpx_memalign(16, flimits_width));
|
||||
const int flimits_width = block_width_ % 16 ? block_width_ + 8 : block_width_;
|
||||
flimits_ = reinterpret_cast<uint8_t *>(vpx_memalign(16, flimits_width));
|
||||
|
||||
ACMRandom rnd;
|
||||
rnd.Reset(ACMRandom::DeterministicSeed());
|
||||
|
@ -138,37 +156,78 @@ TEST_P(VpxPostProcDownAndAcrossMbRowTest, CheckCvsAssembly) {
|
|||
src_image.SetPadding(10);
|
||||
src_image.Set(&rnd, &ACMRandom::Rand8);
|
||||
|
||||
for (int blocks = 0; blocks < block_width; blocks += 8) {
|
||||
(void)memset(flimits, 0, sizeof(*flimits) * flimits_width);
|
||||
for (int blocks = 0; blocks < block_width_; blocks += 8) {
|
||||
(void)memset(flimits_, 0, sizeof(*flimits_) * flimits_width);
|
||||
|
||||
for (int f = 0; f < 255; f++) {
|
||||
(void)memset(flimits + blocks, f, sizeof(*flimits) * 8);
|
||||
|
||||
(void)memset(flimits_ + blocks, f, sizeof(*flimits_) * 8);
|
||||
dst_image.Set(0);
|
||||
dst_image_ref.Set(0);
|
||||
|
||||
vpx_post_proc_down_and_across_mb_row_c(
|
||||
src_image.TopLeftPixel(), dst_image_ref.TopLeftPixel(),
|
||||
src_image.stride(), dst_image_ref.stride(), block_width, flimits,
|
||||
block_height);
|
||||
ASM_REGISTER_STATE_CHECK(
|
||||
GetParam()(src_image.TopLeftPixel(), dst_image.TopLeftPixel(),
|
||||
src_image.stride(), dst_image.stride(), block_width,
|
||||
flimits, block_height));
|
||||
src_image.stride(), dst_image_ref.stride(), block_width_, flimits_,
|
||||
block_height_);
|
||||
ASM_REGISTER_STATE_CHECK(mb_post_proc_down_and_across_(
|
||||
src_image.TopLeftPixel(), dst_image.TopLeftPixel(),
|
||||
src_image.stride(), dst_image.stride(), block_width_, flimits_,
|
||||
block_height_));
|
||||
|
||||
ASSERT_TRUE(dst_image.CheckValues(dst_image_ref));
|
||||
}
|
||||
}
|
||||
|
||||
vpx_free(flimits);
|
||||
vpx_free(flimits_);
|
||||
}
|
||||
|
||||
TEST_P(VpxPostProcDownAndAcrossMbRowTest, DISABLED_Speed) {
|
||||
// Size of the underlying data block that will be filtered.
|
||||
block_width_ = 16;
|
||||
block_height_ = 16;
|
||||
|
||||
// 5-tap filter needs 2 padding rows above and below the block in the input.
|
||||
Buffer<uint8_t> src_image = Buffer<uint8_t>(block_width_, block_height_, 2);
|
||||
ASSERT_TRUE(src_image.Init());
|
||||
this->src_image_ = &src_image;
|
||||
|
||||
// Filter extends output block by 8 samples at left and right edges.
|
||||
// Though the left padding is only 8 bytes, the assembly code tries to
|
||||
// read 16 bytes before the pointer.
|
||||
Buffer<uint8_t> dst_image =
|
||||
Buffer<uint8_t>(block_width_, block_height_, 8, 16, 8, 8);
|
||||
ASSERT_TRUE(dst_image.Init());
|
||||
this->dst_image_ = &dst_image;
|
||||
|
||||
flimits_ = reinterpret_cast<uint8_t *>(vpx_memalign(16, block_width_));
|
||||
(void)memset(flimits_, 255, block_width_);
|
||||
|
||||
// Initialize pixels in the input:
|
||||
// block pixels to value 1,
|
||||
// border pixels to value 10.
|
||||
src_image.SetPadding(10);
|
||||
src_image.Set(1);
|
||||
|
||||
// Initialize pixels in the output to 99.
|
||||
dst_image.Set(99);
|
||||
|
||||
RunNTimes(INT16_MAX);
|
||||
PrintMedian("16x16");
|
||||
|
||||
vpx_free(flimits_);
|
||||
};
|
||||
|
||||
class VpxMbPostProcAcrossIpTest
|
||||
: public ::testing::TestWithParam<VpxMbPostProcAcrossIpFunc> {
|
||||
: public AbstractBench,
|
||||
public ::testing::TestWithParam<VpxMbPostProcAcrossIpFunc> {
|
||||
public:
|
||||
VpxMbPostProcAcrossIpTest()
|
||||
: rows_(16), cols_(16), mb_post_proc_across_ip_(GetParam()),
|
||||
src_(Buffer<uint8_t>(rows_, cols_, 8, 8, 17, 8)) {}
|
||||
virtual void TearDown() { libvpx_test::ClearSystemState(); }
|
||||
|
||||
protected:
|
||||
virtual void Run();
|
||||
|
||||
void SetCols(unsigned char *s, int rows, int cols, int src_width) {
|
||||
for (int r = 0; r < rows; r++) {
|
||||
for (int c = 0; c < cols; c++) {
|
||||
|
@ -195,71 +254,67 @@ class VpxMbPostProcAcrossIpTest
|
|||
GetParam()(s, src_width, rows, cols, filter_level));
|
||||
RunComparison(expected_output, s, rows, cols, src_width);
|
||||
}
|
||||
|
||||
const int rows_;
|
||||
const int cols_;
|
||||
const VpxMbPostProcAcrossIpFunc mb_post_proc_across_ip_;
|
||||
Buffer<uint8_t> src_;
|
||||
};
|
||||
|
||||
void VpxMbPostProcAcrossIpTest::Run() {
|
||||
mb_post_proc_across_ip_(src_.TopLeftPixel(), src_.stride(), rows_, cols_,
|
||||
q2mbl(0));
|
||||
}
|
||||
|
||||
TEST_P(VpxMbPostProcAcrossIpTest, CheckLowFilterOutput) {
|
||||
const int rows = 16;
|
||||
const int cols = 16;
|
||||
ASSERT_TRUE(src_.Init());
|
||||
src_.SetPadding(10);
|
||||
SetCols(src_.TopLeftPixel(), rows_, cols_, src_.stride());
|
||||
|
||||
Buffer<uint8_t> src = Buffer<uint8_t>(cols, rows, 8, 8, 17, 8);
|
||||
ASSERT_TRUE(src.Init());
|
||||
src.SetPadding(10);
|
||||
SetCols(src.TopLeftPixel(), rows, cols, src.stride());
|
||||
|
||||
Buffer<uint8_t> expected_output = Buffer<uint8_t>(cols, rows, 0);
|
||||
Buffer<uint8_t> expected_output = Buffer<uint8_t>(cols_, rows_, 0);
|
||||
ASSERT_TRUE(expected_output.Init());
|
||||
SetCols(expected_output.TopLeftPixel(), rows, cols, expected_output.stride());
|
||||
SetCols(expected_output.TopLeftPixel(), rows_, cols_,
|
||||
expected_output.stride());
|
||||
|
||||
RunFilterLevel(src.TopLeftPixel(), rows, cols, src.stride(), q2mbl(0),
|
||||
RunFilterLevel(src_.TopLeftPixel(), rows_, cols_, src_.stride(), q2mbl(0),
|
||||
expected_output.TopLeftPixel());
|
||||
}
|
||||
|
||||
TEST_P(VpxMbPostProcAcrossIpTest, CheckMediumFilterOutput) {
|
||||
const int rows = 16;
|
||||
const int cols = 16;
|
||||
ASSERT_TRUE(src_.Init());
|
||||
src_.SetPadding(10);
|
||||
SetCols(src_.TopLeftPixel(), rows_, cols_, src_.stride());
|
||||
|
||||
Buffer<uint8_t> src = Buffer<uint8_t>(cols, rows, 8, 8, 17, 8);
|
||||
ASSERT_TRUE(src.Init());
|
||||
src.SetPadding(10);
|
||||
SetCols(src.TopLeftPixel(), rows, cols, src.stride());
|
||||
|
||||
static const unsigned char kExpectedOutput[cols] = {
|
||||
static const unsigned char kExpectedOutput[] = {
|
||||
2, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 13
|
||||
};
|
||||
|
||||
RunFilterLevel(src.TopLeftPixel(), rows, cols, src.stride(), q2mbl(70),
|
||||
RunFilterLevel(src_.TopLeftPixel(), rows_, cols_, src_.stride(), q2mbl(70),
|
||||
kExpectedOutput);
|
||||
}
|
||||
|
||||
TEST_P(VpxMbPostProcAcrossIpTest, CheckHighFilterOutput) {
|
||||
const int rows = 16;
|
||||
const int cols = 16;
|
||||
ASSERT_TRUE(src_.Init());
|
||||
src_.SetPadding(10);
|
||||
SetCols(src_.TopLeftPixel(), rows_, cols_, src_.stride());
|
||||
|
||||
Buffer<uint8_t> src = Buffer<uint8_t>(cols, rows, 8, 8, 17, 8);
|
||||
ASSERT_TRUE(src.Init());
|
||||
src.SetPadding(10);
|
||||
SetCols(src.TopLeftPixel(), rows, cols, src.stride());
|
||||
|
||||
static const unsigned char kExpectedOutput[cols] = {
|
||||
static const unsigned char kExpectedOutput[] = {
|
||||
2, 2, 3, 4, 4, 5, 6, 7, 8, 9, 10, 11, 11, 12, 13, 13
|
||||
};
|
||||
|
||||
RunFilterLevel(src.TopLeftPixel(), rows, cols, src.stride(), INT_MAX,
|
||||
RunFilterLevel(src_.TopLeftPixel(), rows_, cols_, src_.stride(), INT_MAX,
|
||||
kExpectedOutput);
|
||||
|
||||
SetCols(src.TopLeftPixel(), rows, cols, src.stride());
|
||||
SetCols(src_.TopLeftPixel(), rows_, cols_, src_.stride());
|
||||
|
||||
RunFilterLevel(src.TopLeftPixel(), rows, cols, src.stride(), q2mbl(100),
|
||||
RunFilterLevel(src_.TopLeftPixel(), rows_, cols_, src_.stride(), q2mbl(100),
|
||||
kExpectedOutput);
|
||||
}
|
||||
|
||||
TEST_P(VpxMbPostProcAcrossIpTest, CheckCvsAssembly) {
|
||||
const int rows = 16;
|
||||
const int cols = 16;
|
||||
|
||||
Buffer<uint8_t> c_mem = Buffer<uint8_t>(cols, rows, 8, 8, 17, 8);
|
||||
Buffer<uint8_t> c_mem = Buffer<uint8_t>(cols_, rows_, 8, 8, 17, 8);
|
||||
ASSERT_TRUE(c_mem.Init());
|
||||
Buffer<uint8_t> asm_mem = Buffer<uint8_t>(cols, rows, 8, 8, 17, 8);
|
||||
Buffer<uint8_t> asm_mem = Buffer<uint8_t>(cols_, rows_, 8, 8, 17, 8);
|
||||
ASSERT_TRUE(asm_mem.Init());
|
||||
|
||||
// When level >= 100, the filter behaves the same as the level = INT_MAX
|
||||
|
@ -267,24 +322,41 @@ TEST_P(VpxMbPostProcAcrossIpTest, CheckCvsAssembly) {
|
|||
for (int level = 0; level < 100; level++) {
|
||||
c_mem.SetPadding(10);
|
||||
asm_mem.SetPadding(10);
|
||||
SetCols(c_mem.TopLeftPixel(), rows, cols, c_mem.stride());
|
||||
SetCols(asm_mem.TopLeftPixel(), rows, cols, asm_mem.stride());
|
||||
SetCols(c_mem.TopLeftPixel(), rows_, cols_, c_mem.stride());
|
||||
SetCols(asm_mem.TopLeftPixel(), rows_, cols_, asm_mem.stride());
|
||||
|
||||
vpx_mbpost_proc_across_ip_c(c_mem.TopLeftPixel(), c_mem.stride(), rows,
|
||||
cols, q2mbl(level));
|
||||
vpx_mbpost_proc_across_ip_c(c_mem.TopLeftPixel(), c_mem.stride(), rows_,
|
||||
cols_, q2mbl(level));
|
||||
ASM_REGISTER_STATE_CHECK(GetParam()(
|
||||
asm_mem.TopLeftPixel(), asm_mem.stride(), rows, cols, q2mbl(level)));
|
||||
asm_mem.TopLeftPixel(), asm_mem.stride(), rows_, cols_, q2mbl(level)));
|
||||
|
||||
ASSERT_TRUE(asm_mem.CheckValues(c_mem));
|
||||
}
|
||||
}
|
||||
|
||||
TEST_P(VpxMbPostProcAcrossIpTest, DISABLED_Speed) {
|
||||
ASSERT_TRUE(src_.Init());
|
||||
src_.SetPadding(10);
|
||||
|
||||
SetCols(src_.TopLeftPixel(), rows_, cols_, src_.stride());
|
||||
|
||||
RunNTimes(100000);
|
||||
PrintMedian("16x16");
|
||||
}
|
||||
|
||||
class VpxMbPostProcDownTest
|
||||
: public ::testing::TestWithParam<VpxMbPostProcDownFunc> {
|
||||
: public AbstractBench,
|
||||
public ::testing::TestWithParam<VpxMbPostProcDownFunc> {
|
||||
public:
|
||||
VpxMbPostProcDownTest()
|
||||
: rows_(16), cols_(16), mb_post_proc_down_(GetParam()),
|
||||
src_c_(Buffer<uint8_t>(rows_, cols_, 8, 8, 8, 17)) {}
|
||||
|
||||
virtual void TearDown() { libvpx_test::ClearSystemState(); }
|
||||
|
||||
protected:
|
||||
virtual void Run();
|
||||
|
||||
void SetRows(unsigned char *src_c, int rows, int cols, int src_width) {
|
||||
for (int r = 0; r < rows; r++) {
|
||||
memset(src_c, r, cols);
|
||||
|
@ -306,22 +378,28 @@ class VpxMbPostProcDownTest
|
|||
void RunFilterLevel(unsigned char *s, int rows, int cols, int src_width,
|
||||
int filter_level, const unsigned char *expected_output) {
|
||||
ASM_REGISTER_STATE_CHECK(
|
||||
GetParam()(s, src_width, rows, cols, filter_level));
|
||||
mb_post_proc_down_(s, src_width, rows, cols, filter_level));
|
||||
RunComparison(expected_output, s, rows, cols, src_width);
|
||||
}
|
||||
|
||||
const int rows_;
|
||||
const int cols_;
|
||||
const VpxMbPostProcDownFunc mb_post_proc_down_;
|
||||
Buffer<uint8_t> src_c_;
|
||||
};
|
||||
|
||||
void VpxMbPostProcDownTest::Run() {
|
||||
mb_post_proc_down_(src_c_.TopLeftPixel(), src_c_.stride(), rows_, cols_,
|
||||
q2mbl(0));
|
||||
}
|
||||
|
||||
TEST_P(VpxMbPostProcDownTest, CheckHighFilterOutput) {
|
||||
const int rows = 16;
|
||||
const int cols = 16;
|
||||
ASSERT_TRUE(src_c_.Init());
|
||||
src_c_.SetPadding(10);
|
||||
|
||||
Buffer<uint8_t> src_c = Buffer<uint8_t>(cols, rows, 8, 8, 8, 17);
|
||||
ASSERT_TRUE(src_c.Init());
|
||||
src_c.SetPadding(10);
|
||||
SetRows(src_c_.TopLeftPixel(), rows_, cols_, src_c_.stride());
|
||||
|
||||
SetRows(src_c.TopLeftPixel(), rows, cols, src_c.stride());
|
||||
|
||||
static const unsigned char kExpectedOutput[rows * cols] = {
|
||||
static const unsigned char kExpectedOutput[] = {
|
||||
2, 2, 1, 1, 2, 2, 2, 2, 2, 2, 1, 1, 2, 2, 2, 2, 2, 2, 2,
|
||||
2, 3, 2, 2, 2, 2, 2, 2, 2, 3, 2, 2, 2, 3, 3, 3, 3, 3, 3,
|
||||
3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 4, 4, 3, 4, 4, 3, 3, 3,
|
||||
|
@ -338,26 +416,22 @@ TEST_P(VpxMbPostProcDownTest, CheckHighFilterOutput) {
|
|||
13, 13, 13, 13, 14, 13, 13, 13, 13
|
||||
};
|
||||
|
||||
RunFilterLevel(src_c.TopLeftPixel(), rows, cols, src_c.stride(), INT_MAX,
|
||||
RunFilterLevel(src_c_.TopLeftPixel(), rows_, cols_, src_c_.stride(), INT_MAX,
|
||||
kExpectedOutput);
|
||||
|
||||
src_c.SetPadding(10);
|
||||
SetRows(src_c.TopLeftPixel(), rows, cols, src_c.stride());
|
||||
RunFilterLevel(src_c.TopLeftPixel(), rows, cols, src_c.stride(), q2mbl(100),
|
||||
kExpectedOutput);
|
||||
src_c_.SetPadding(10);
|
||||
SetRows(src_c_.TopLeftPixel(), rows_, cols_, src_c_.stride());
|
||||
RunFilterLevel(src_c_.TopLeftPixel(), rows_, cols_, src_c_.stride(),
|
||||
q2mbl(100), kExpectedOutput);
|
||||
}
|
||||
|
||||
TEST_P(VpxMbPostProcDownTest, CheckMediumFilterOutput) {
|
||||
const int rows = 16;
|
||||
const int cols = 16;
|
||||
ASSERT_TRUE(src_c_.Init());
|
||||
src_c_.SetPadding(10);
|
||||
|
||||
Buffer<uint8_t> src_c = Buffer<uint8_t>(cols, rows, 8, 8, 8, 17);
|
||||
ASSERT_TRUE(src_c.Init());
|
||||
src_c.SetPadding(10);
|
||||
SetRows(src_c_.TopLeftPixel(), rows_, cols_, src_c_.stride());
|
||||
|
||||
SetRows(src_c.TopLeftPixel(), rows, cols, src_c.stride());
|
||||
|
||||
static const unsigned char kExpectedOutput[rows * cols] = {
|
||||
static const unsigned char kExpectedOutput[] = {
|
||||
2, 2, 1, 1, 2, 2, 2, 2, 2, 2, 1, 1, 2, 2, 2, 2, 2, 2, 2,
|
||||
2, 3, 2, 2, 2, 2, 2, 2, 2, 3, 2, 2, 2, 2, 2, 2, 2, 2, 2,
|
||||
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3, 3,
|
||||
|
@ -374,67 +448,69 @@ TEST_P(VpxMbPostProcDownTest, CheckMediumFilterOutput) {
|
|||
13, 13, 13, 13, 14, 13, 13, 13, 13
|
||||
};
|
||||
|
||||
RunFilterLevel(src_c.TopLeftPixel(), rows, cols, src_c.stride(), q2mbl(70),
|
||||
kExpectedOutput);
|
||||
RunFilterLevel(src_c_.TopLeftPixel(), rows_, cols_, src_c_.stride(),
|
||||
q2mbl(70), kExpectedOutput);
|
||||
}
|
||||
|
||||
TEST_P(VpxMbPostProcDownTest, CheckLowFilterOutput) {
|
||||
const int rows = 16;
|
||||
const int cols = 16;
|
||||
ASSERT_TRUE(src_c_.Init());
|
||||
src_c_.SetPadding(10);
|
||||
|
||||
Buffer<uint8_t> src_c = Buffer<uint8_t>(cols, rows, 8, 8, 8, 17);
|
||||
ASSERT_TRUE(src_c.Init());
|
||||
src_c.SetPadding(10);
|
||||
SetRows(src_c_.TopLeftPixel(), rows_, cols_, src_c_.stride());
|
||||
|
||||
SetRows(src_c.TopLeftPixel(), rows, cols, src_c.stride());
|
||||
|
||||
unsigned char *expected_output = new unsigned char[rows * cols];
|
||||
unsigned char *expected_output = new unsigned char[rows_ * cols_];
|
||||
ASSERT_TRUE(expected_output != NULL);
|
||||
SetRows(expected_output, rows, cols, cols);
|
||||
SetRows(expected_output, rows_, cols_, cols_);
|
||||
|
||||
RunFilterLevel(src_c.TopLeftPixel(), rows, cols, src_c.stride(), q2mbl(0),
|
||||
RunFilterLevel(src_c_.TopLeftPixel(), rows_, cols_, src_c_.stride(), q2mbl(0),
|
||||
expected_output);
|
||||
|
||||
delete[] expected_output;
|
||||
}
|
||||
|
||||
TEST_P(VpxMbPostProcDownTest, CheckCvsAssembly) {
|
||||
const int rows = 16;
|
||||
const int cols = 16;
|
||||
|
||||
ACMRandom rnd;
|
||||
rnd.Reset(ACMRandom::DeterministicSeed());
|
||||
|
||||
Buffer<uint8_t> src_c = Buffer<uint8_t>(cols, rows, 8, 8, 8, 17);
|
||||
ASSERT_TRUE(src_c.Init());
|
||||
Buffer<uint8_t> src_asm = Buffer<uint8_t>(cols, rows, 8, 8, 8, 17);
|
||||
ASSERT_TRUE(src_c_.Init());
|
||||
Buffer<uint8_t> src_asm = Buffer<uint8_t>(cols_, rows_, 8, 8, 8, 17);
|
||||
ASSERT_TRUE(src_asm.Init());
|
||||
|
||||
for (int level = 0; level < 100; level++) {
|
||||
src_c.SetPadding(10);
|
||||
src_c_.SetPadding(10);
|
||||
src_asm.SetPadding(10);
|
||||
src_c.Set(&rnd, &ACMRandom::Rand8);
|
||||
src_asm.CopyFrom(src_c);
|
||||
src_c_.Set(&rnd, &ACMRandom::Rand8);
|
||||
src_asm.CopyFrom(src_c_);
|
||||
|
||||
vpx_mbpost_proc_down_c(src_c.TopLeftPixel(), src_c.stride(), rows, cols,
|
||||
vpx_mbpost_proc_down_c(src_c_.TopLeftPixel(), src_c_.stride(), rows_, cols_,
|
||||
q2mbl(level));
|
||||
ASM_REGISTER_STATE_CHECK(GetParam()(
|
||||
src_asm.TopLeftPixel(), src_asm.stride(), rows, cols, q2mbl(level)));
|
||||
ASSERT_TRUE(src_asm.CheckValues(src_c));
|
||||
ASM_REGISTER_STATE_CHECK(mb_post_proc_down_(
|
||||
src_asm.TopLeftPixel(), src_asm.stride(), rows_, cols_, q2mbl(level)));
|
||||
ASSERT_TRUE(src_asm.CheckValues(src_c_));
|
||||
|
||||
src_c.SetPadding(10);
|
||||
src_c_.SetPadding(10);
|
||||
src_asm.SetPadding(10);
|
||||
src_c.Set(&rnd, &ACMRandom::Rand8Extremes);
|
||||
src_asm.CopyFrom(src_c);
|
||||
src_c_.Set(&rnd, &ACMRandom::Rand8Extremes);
|
||||
src_asm.CopyFrom(src_c_);
|
||||
|
||||
vpx_mbpost_proc_down_c(src_c.TopLeftPixel(), src_c.stride(), rows, cols,
|
||||
vpx_mbpost_proc_down_c(src_c_.TopLeftPixel(), src_c_.stride(), rows_, cols_,
|
||||
q2mbl(level));
|
||||
ASM_REGISTER_STATE_CHECK(GetParam()(
|
||||
src_asm.TopLeftPixel(), src_asm.stride(), rows, cols, q2mbl(level)));
|
||||
ASSERT_TRUE(src_asm.CheckValues(src_c));
|
||||
ASM_REGISTER_STATE_CHECK(mb_post_proc_down_(
|
||||
src_asm.TopLeftPixel(), src_asm.stride(), rows_, cols_, q2mbl(level)));
|
||||
ASSERT_TRUE(src_asm.CheckValues(src_c_));
|
||||
}
|
||||
}
|
||||
|
||||
TEST_P(VpxMbPostProcDownTest, DISABLED_Speed) {
|
||||
ASSERT_TRUE(src_c_.Init());
|
||||
src_c_.SetPadding(10);
|
||||
|
||||
SetRows(src_c_.TopLeftPixel(), rows_, cols_, src_c_.stride());
|
||||
|
||||
RunNTimes(100000);
|
||||
PrintMedian("16x16");
|
||||
}
|
||||
|
||||
INSTANTIATE_TEST_CASE_P(
|
||||
C, VpxPostProcDownAndAcrossMbRowTest,
|
||||
::testing::Values(vpx_post_proc_down_and_across_mb_row_c));
|
||||
|
@ -481,4 +557,16 @@ INSTANTIATE_TEST_CASE_P(MSA, VpxMbPostProcDownTest,
|
|||
::testing::Values(vpx_mbpost_proc_down_msa));
|
||||
#endif // HAVE_MSA
|
||||
|
||||
#if HAVE_VSX
|
||||
INSTANTIATE_TEST_CASE_P(
|
||||
VSX, VpxPostProcDownAndAcrossMbRowTest,
|
||||
::testing::Values(vpx_post_proc_down_and_across_mb_row_vsx));
|
||||
|
||||
INSTANTIATE_TEST_CASE_P(VSX, VpxMbPostProcAcrossIpTest,
|
||||
::testing::Values(vpx_mbpost_proc_across_ip_vsx));
|
||||
|
||||
INSTANTIATE_TEST_CASE_P(VSX, VpxMbPostProcDownTest,
|
||||
::testing::Values(vpx_mbpost_proc_down_vsx));
|
||||
#endif // HAVE_VSX
|
||||
|
||||
} // namespace
|
||||
|
|
|
@ -10,30 +10,34 @@
|
|||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <tuple>
|
||||
|
||||
#include "third_party/googletest/src/include/gtest/gtest.h"
|
||||
|
||||
#include "./vp8_rtcd.h"
|
||||
#include "./vpx_config.h"
|
||||
#include "test/acm_random.h"
|
||||
#include "test/bench.h"
|
||||
#include "test/clear_system_state.h"
|
||||
#include "test/register_state_check.h"
|
||||
#include "test/util.h"
|
||||
#include "vpx/vpx_integer.h"
|
||||
#include "vpx_mem/vpx_mem.h"
|
||||
#include "vpx_ports/msvc.h"
|
||||
|
||||
namespace {
|
||||
|
||||
using libvpx_test::ACMRandom;
|
||||
using std::tr1::make_tuple;
|
||||
using std::make_tuple;
|
||||
|
||||
typedef void (*PredictFunc)(uint8_t *src_ptr, int src_pixels_per_line,
|
||||
int xoffset, int yoffset, uint8_t *dst_ptr,
|
||||
int dst_pitch);
|
||||
|
||||
typedef std::tr1::tuple<int, int, PredictFunc> PredictParam;
|
||||
typedef std::tuple<int, int, PredictFunc> PredictParam;
|
||||
|
||||
class PredictTestBase : public ::testing::TestWithParam<PredictParam> {
|
||||
class PredictTestBase : public AbstractBench,
|
||||
public ::testing::TestWithParam<PredictParam> {
|
||||
public:
|
||||
PredictTestBase()
|
||||
: width_(GET_PARAM(0)), height_(GET_PARAM(1)), predict_(GET_PARAM(2)),
|
||||
|
@ -204,7 +208,20 @@ class PredictTestBase : public ::testing::TestWithParam<PredictParam> {
|
|||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
void Run() {
|
||||
for (int xoffset = 0; xoffset < 8; ++xoffset) {
|
||||
for (int yoffset = 0; yoffset < 8; ++yoffset) {
|
||||
if (xoffset == 0 && yoffset == 0) {
|
||||
continue;
|
||||
}
|
||||
|
||||
predict_(&src_[kSrcStride * 2 + 2], kSrcStride, xoffset, yoffset, dst_,
|
||||
dst_stride_);
|
||||
}
|
||||
}
|
||||
}
|
||||
}; // namespace
|
||||
|
||||
class SixtapPredictTest : public PredictTestBase {};
|
||||
|
||||
|
@ -341,6 +358,14 @@ TEST_P(BilinearPredictTest, TestWithRandomData) {
|
|||
TEST_P(BilinearPredictTest, TestWithUnalignedDst) {
|
||||
TestWithUnalignedDst(vp8_bilinear_predict16x16_c);
|
||||
}
|
||||
TEST_P(BilinearPredictTest, DISABLED_Speed) {
|
||||
const int kCountSpeedTestBlock = 5000000 / (width_ * height_);
|
||||
RunNTimes(kCountSpeedTestBlock);
|
||||
|
||||
char title[16];
|
||||
snprintf(title, sizeof(title), "%dx%d", width_, height_);
|
||||
PrintMedian(title);
|
||||
}
|
||||
|
||||
INSTANTIATE_TEST_CASE_P(
|
||||
C, BilinearPredictTest,
|
||||
|
@ -356,17 +381,13 @@ INSTANTIATE_TEST_CASE_P(
|
|||
make_tuple(8, 4, &vp8_bilinear_predict8x4_neon),
|
||||
make_tuple(4, 4, &vp8_bilinear_predict4x4_neon)));
|
||||
#endif
|
||||
#if HAVE_MMX
|
||||
INSTANTIATE_TEST_CASE_P(
|
||||
MMX, BilinearPredictTest,
|
||||
::testing::Values(make_tuple(8, 4, &vp8_bilinear_predict8x4_mmx),
|
||||
make_tuple(4, 4, &vp8_bilinear_predict4x4_mmx)));
|
||||
#endif
|
||||
#if HAVE_SSE2
|
||||
INSTANTIATE_TEST_CASE_P(
|
||||
SSE2, BilinearPredictTest,
|
||||
::testing::Values(make_tuple(16, 16, &vp8_bilinear_predict16x16_sse2),
|
||||
make_tuple(8, 8, &vp8_bilinear_predict8x8_sse2)));
|
||||
make_tuple(8, 8, &vp8_bilinear_predict8x8_sse2),
|
||||
make_tuple(8, 4, &vp8_bilinear_predict8x4_sse2),
|
||||
make_tuple(4, 4, &vp8_bilinear_predict4x4_sse2)));
|
||||
#endif
|
||||
#if HAVE_SSSE3
|
||||
INSTANTIATE_TEST_CASE_P(
|
||||
|
|
|
@ -9,12 +9,14 @@
|
|||
*/
|
||||
|
||||
#include <string.h>
|
||||
#include <tuple>
|
||||
|
||||
#include "third_party/googletest/src/include/gtest/gtest.h"
|
||||
|
||||
#include "./vpx_config.h"
|
||||
#include "./vp8_rtcd.h"
|
||||
#include "./vpx_config.h"
|
||||
#include "test/acm_random.h"
|
||||
#include "test/bench.h"
|
||||
#include "test/clear_system_state.h"
|
||||
#include "test/register_state_check.h"
|
||||
#include "test/util.h"
|
||||
|
@ -33,10 +35,10 @@ const int kNumBlockEntries = 16;
|
|||
|
||||
typedef void (*VP8Quantize)(BLOCK *b, BLOCKD *d);
|
||||
|
||||
typedef std::tr1::tuple<VP8Quantize, VP8Quantize> VP8QuantizeParam;
|
||||
typedef std::tuple<VP8Quantize, VP8Quantize> VP8QuantizeParam;
|
||||
|
||||
using libvpx_test::ACMRandom;
|
||||
using std::tr1::make_tuple;
|
||||
using std::make_tuple;
|
||||
|
||||
// Create and populate a VP8_COMP instance which has a complete set of
|
||||
// quantization inputs as well as a second MACROBLOCKD for output.
|
||||
|
@ -116,7 +118,8 @@ class QuantizeTestBase {
|
|||
};
|
||||
|
||||
class QuantizeTest : public QuantizeTestBase,
|
||||
public ::testing::TestWithParam<VP8QuantizeParam> {
|
||||
public ::testing::TestWithParam<VP8QuantizeParam>,
|
||||
public AbstractBench {
|
||||
protected:
|
||||
virtual void SetUp() {
|
||||
SetupCompressor();
|
||||
|
@ -124,6 +127,10 @@ class QuantizeTest : public QuantizeTestBase,
|
|||
c_quant_ = GET_PARAM(1);
|
||||
}
|
||||
|
||||
virtual void Run() {
|
||||
asm_quant_(&vp8_comp_->mb.block[0], ¯oblockd_dst_->block[0]);
|
||||
}
|
||||
|
||||
void RunComparison() {
|
||||
for (int i = 0; i < kNumBlocks; ++i) {
|
||||
ASM_REGISTER_STATE_CHECK(
|
||||
|
@ -166,6 +173,13 @@ TEST_P(QuantizeTest, TestMultipleQ) {
|
|||
}
|
||||
}
|
||||
|
||||
TEST_P(QuantizeTest, DISABLED_Speed) {
|
||||
FillCoeffRandom();
|
||||
|
||||
RunNTimes(10000000);
|
||||
PrintMedian("vp8 quantize");
|
||||
}
|
||||
|
||||
#if HAVE_SSE2
|
||||
INSTANTIATE_TEST_CASE_P(
|
||||
SSE2, QuantizeTest,
|
||||
|
|
|
@ -8,8 +8,8 @@
|
|||
* be found in the AUTHORS file in the root of the source tree.
|
||||
*/
|
||||
|
||||
#ifndef TEST_REGISTER_STATE_CHECK_H_
|
||||
#define TEST_REGISTER_STATE_CHECK_H_
|
||||
#ifndef VPX_TEST_REGISTER_STATE_CHECK_H_
|
||||
#define VPX_TEST_REGISTER_STATE_CHECK_H_
|
||||
|
||||
#include "third_party/googletest/src/include/gtest/gtest.h"
|
||||
#include "./vpx_config.h"
|
||||
|
@ -28,7 +28,7 @@
|
|||
// See platform implementations of RegisterStateCheckXXX for details.
|
||||
//
|
||||
|
||||
#if defined(_WIN64)
|
||||
#if defined(_WIN64) && ARCH_X86_64
|
||||
|
||||
#undef NOMINMAX
|
||||
#define NOMINMAX
|
||||
|
@ -138,7 +138,7 @@ class RegisterStateCheck {};
|
|||
|
||||
} // namespace libvpx_test
|
||||
|
||||
#endif // _WIN64
|
||||
#endif // _WIN64 && ARCH_X86_64
|
||||
|
||||
#if ARCH_X86 || ARCH_X86_64
|
||||
#if defined(__GNUC__)
|
||||
|
@ -184,4 +184,4 @@ class RegisterStateCheckMMX {
|
|||
#define API_REGISTER_STATE_CHECK ASM_REGISTER_STATE_CHECK
|
||||
#endif
|
||||
|
||||
#endif // TEST_REGISTER_STATE_CHECK_H_
|
||||
#endif // VPX_TEST_REGISTER_STATE_CHECK_H_
|
||||
|
|
|
@ -277,12 +277,29 @@ class ResizeTest
|
|||
SetMode(GET_PARAM(1));
|
||||
}
|
||||
|
||||
virtual void FramePktHook(const vpx_codec_cx_pkt_t *pkt) {
|
||||
ASSERT_NE(static_cast<int>(pkt->data.frame.width[0]), 0);
|
||||
ASSERT_NE(static_cast<int>(pkt->data.frame.height[0]), 0);
|
||||
encode_frame_width_.push_back(pkt->data.frame.width[0]);
|
||||
encode_frame_height_.push_back(pkt->data.frame.height[0]);
|
||||
}
|
||||
|
||||
unsigned int GetFrameWidth(size_t idx) const {
|
||||
return encode_frame_width_[idx];
|
||||
}
|
||||
|
||||
unsigned int GetFrameHeight(size_t idx) const {
|
||||
return encode_frame_height_[idx];
|
||||
}
|
||||
|
||||
virtual void DecompressedFrameHook(const vpx_image_t &img,
|
||||
vpx_codec_pts_t pts) {
|
||||
frame_info_list_.push_back(FrameInfo(pts, img.d_w, img.d_h));
|
||||
}
|
||||
|
||||
std::vector<FrameInfo> frame_info_list_;
|
||||
std::vector<unsigned int> encode_frame_width_;
|
||||
std::vector<unsigned int> encode_frame_height_;
|
||||
};
|
||||
|
||||
TEST_P(ResizeTest, TestExternalResizeWorks) {
|
||||
|
@ -296,6 +313,9 @@ TEST_P(ResizeTest, TestExternalResizeWorks) {
|
|||
const unsigned int frame = static_cast<unsigned>(info->pts);
|
||||
unsigned int expected_w;
|
||||
unsigned int expected_h;
|
||||
const size_t idx = info - frame_info_list_.begin();
|
||||
ASSERT_EQ(info->w, GetFrameWidth(idx));
|
||||
ASSERT_EQ(info->h, GetFrameHeight(idx));
|
||||
ScaleForFrameNumber(frame, kInitialWidth, kInitialHeight, &expected_w,
|
||||
&expected_h, 0);
|
||||
EXPECT_EQ(expected_w, info->w)
|
||||
|
@ -464,8 +484,23 @@ class ResizeRealtimeTest
|
|||
++mismatch_nframes_;
|
||||
}
|
||||
|
||||
virtual void FramePktHook(const vpx_codec_cx_pkt_t *pkt) {
|
||||
ASSERT_NE(static_cast<int>(pkt->data.frame.width[0]), 0);
|
||||
ASSERT_NE(static_cast<int>(pkt->data.frame.height[0]), 0);
|
||||
encode_frame_width_.push_back(pkt->data.frame.width[0]);
|
||||
encode_frame_height_.push_back(pkt->data.frame.height[0]);
|
||||
}
|
||||
|
||||
unsigned int GetMismatchFrames() { return mismatch_nframes_; }
|
||||
|
||||
unsigned int GetFrameWidth(size_t idx) const {
|
||||
return encode_frame_width_[idx];
|
||||
}
|
||||
|
||||
unsigned int GetFrameHeight(size_t idx) const {
|
||||
return encode_frame_height_[idx];
|
||||
}
|
||||
|
||||
void DefaultConfig() {
|
||||
cfg_.rc_buf_initial_sz = 500;
|
||||
cfg_.rc_buf_optimal_sz = 600;
|
||||
|
@ -493,6 +528,8 @@ class ResizeRealtimeTest
|
|||
bool change_bitrate_;
|
||||
double mismatch_psnr_;
|
||||
int mismatch_nframes_;
|
||||
std::vector<unsigned int> encode_frame_width_;
|
||||
std::vector<unsigned int> encode_frame_height_;
|
||||
};
|
||||
|
||||
TEST_P(ResizeRealtimeTest, TestExternalResizeWorks) {
|
||||
|
@ -582,6 +619,9 @@ TEST_P(ResizeRealtimeTest, TestInternalResizeDownUpChangeBitRate) {
|
|||
int resize_count = 0;
|
||||
for (std::vector<FrameInfo>::const_iterator info = frame_info_list_.begin();
|
||||
info != frame_info_list_.end(); ++info) {
|
||||
const size_t idx = info - frame_info_list_.begin();
|
||||
ASSERT_EQ(info->w, GetFrameWidth(idx));
|
||||
ASSERT_EQ(info->h, GetFrameHeight(idx));
|
||||
if (info->w != last_w || info->h != last_h) {
|
||||
resize_count++;
|
||||
if (resize_count == 1) {
|
||||
|
|
|
@ -10,19 +10,21 @@
|
|||
|
||||
#include <string.h>
|
||||
#include <limits.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#include "third_party/googletest/src/include/gtest/gtest.h"
|
||||
|
||||
#include "./vpx_config.h"
|
||||
#include "./vpx_dsp_rtcd.h"
|
||||
#include "test/acm_random.h"
|
||||
#include "test/bench.h"
|
||||
#include "test/clear_system_state.h"
|
||||
#include "test/register_state_check.h"
|
||||
#include "test/util.h"
|
||||
#include "vpx/vpx_codec.h"
|
||||
#include "vpx_mem/vpx_mem.h"
|
||||
#include "vpx_ports/mem.h"
|
||||
#include "vpx_ports/msvc.h"
|
||||
#include "vpx_ports/vpx_timer.h"
|
||||
|
||||
template <typename Function>
|
||||
struct TestParams {
|
||||
|
@ -84,7 +86,7 @@ class SADTestBase : public ::testing::TestWithParam<ParamType> {
|
|||
#endif // CONFIG_VP9_HIGHBITDEPTH
|
||||
}
|
||||
mask_ = (1 << bit_depth_) - 1;
|
||||
source_stride_ = (params_.width + 31) & ~31;
|
||||
source_stride_ = (params_.width + 63) & ~63;
|
||||
reference_stride_ = params_.width * 2;
|
||||
rnd_.Reset(ACMRandom::DeterministicSeed());
|
||||
}
|
||||
|
@ -108,7 +110,7 @@ class SADTestBase : public ::testing::TestWithParam<ParamType> {
|
|||
|
||||
protected:
|
||||
// Handle blocks up to 4 blocks 64x64 with stride up to 128
|
||||
static const int kDataAlignment = 16;
|
||||
static const int kDataAlignment = 32;
|
||||
static const int kDataBlockSize = 64 * 128;
|
||||
static const int kDataBufferSize = 4 * kDataBlockSize;
|
||||
|
||||
|
@ -264,7 +266,7 @@ class SADx4Test : public SADTestBase<SadMxNx4Param> {
|
|||
}
|
||||
};
|
||||
|
||||
class SADTest : public SADTestBase<SadMxNParam> {
|
||||
class SADTest : public AbstractBench, public SADTestBase<SadMxNParam> {
|
||||
public:
|
||||
SADTest() : SADTestBase(GetParam()) {}
|
||||
|
||||
|
@ -284,6 +286,11 @@ class SADTest : public SADTestBase<SadMxNParam> {
|
|||
|
||||
ASSERT_EQ(reference_sad, exp_sad);
|
||||
}
|
||||
|
||||
void Run() {
|
||||
params_.func(source_data_, source_stride_, reference_data_,
|
||||
reference_stride_);
|
||||
}
|
||||
};
|
||||
|
||||
class SADavgTest : public SADTestBase<SadMxNAvgParam> {
|
||||
|
@ -350,6 +357,17 @@ TEST_P(SADTest, ShortSrc) {
|
|||
source_stride_ = tmp_stride;
|
||||
}
|
||||
|
||||
TEST_P(SADTest, DISABLED_Speed) {
|
||||
const int kCountSpeedTestBlock = 50000000 / (params_.width * params_.height);
|
||||
FillRandom(source_data_, source_stride_);
|
||||
|
||||
RunNTimes(kCountSpeedTestBlock);
|
||||
|
||||
char title[16];
|
||||
snprintf(title, sizeof(title), "%dx%d", params_.width, params_.height);
|
||||
PrintMedian(title);
|
||||
}
|
||||
|
||||
TEST_P(SADavgTest, MaxRef) {
|
||||
FillConstant(source_data_, source_stride_, 0);
|
||||
FillConstant(reference_data_, reference_stride_, mask_);
|
||||
|
@ -463,6 +481,38 @@ TEST_P(SADx4Test, SrcAlignedByWidth) {
|
|||
source_data_ = tmp_source_data;
|
||||
}
|
||||
|
||||
TEST_P(SADx4Test, DISABLED_Speed) {
|
||||
int tmp_stride = reference_stride_;
|
||||
reference_stride_ -= 1;
|
||||
FillRandom(source_data_, source_stride_);
|
||||
FillRandom(GetReference(0), reference_stride_);
|
||||
FillRandom(GetReference(1), reference_stride_);
|
||||
FillRandom(GetReference(2), reference_stride_);
|
||||
FillRandom(GetReference(3), reference_stride_);
|
||||
const int kCountSpeedTestBlock = 500000000 / (params_.width * params_.height);
|
||||
uint32_t reference_sad[4], exp_sad[4];
|
||||
vpx_usec_timer timer;
|
||||
|
||||
memset(reference_sad, 0, sizeof(reference_sad));
|
||||
SADs(exp_sad);
|
||||
vpx_usec_timer_start(&timer);
|
||||
for (int i = 0; i < kCountSpeedTestBlock; ++i) {
|
||||
for (int block = 0; block < 4; ++block) {
|
||||
reference_sad[block] = ReferenceSAD(block);
|
||||
}
|
||||
}
|
||||
vpx_usec_timer_mark(&timer);
|
||||
for (int block = 0; block < 4; ++block) {
|
||||
EXPECT_EQ(reference_sad[block], exp_sad[block]) << "block " << block;
|
||||
}
|
||||
const int elapsed_time =
|
||||
static_cast<int>(vpx_usec_timer_elapsed(&timer) / 1000);
|
||||
printf("sad%dx%dx4 (%2dbit) time: %5d ms\n", params_.width, params_.height,
|
||||
bit_depth_, elapsed_time);
|
||||
|
||||
reference_stride_ = tmp_stride;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// C functions
|
||||
const SadMxNParam c_tests[] = {
|
||||
|
@ -971,6 +1021,9 @@ const SadMxNParam vsx_tests[] = {
|
|||
SadMxNParam(16, 32, &vpx_sad16x32_vsx),
|
||||
SadMxNParam(16, 16, &vpx_sad16x16_vsx),
|
||||
SadMxNParam(16, 8, &vpx_sad16x8_vsx),
|
||||
SadMxNParam(8, 16, &vpx_sad8x16_vsx),
|
||||
SadMxNParam(8, 8, &vpx_sad8x8_vsx),
|
||||
SadMxNParam(8, 4, &vpx_sad8x4_vsx),
|
||||
};
|
||||
INSTANTIATE_TEST_CASE_P(VSX, SADTest, ::testing::ValuesIn(vsx_tests));
|
||||
|
||||
|
|
|
@ -30,7 +30,7 @@ SHA1_FILE="$(dirname $0)/test-data.sha1"
|
|||
# Download a file from the url and check its sha1sum.
|
||||
download_and_check_file() {
|
||||
# Get the file from the file path.
|
||||
local readonly root="${1#${LIBVPX_TEST_DATA_PATH}/}"
|
||||
local root="${1#${LIBVPX_TEST_DATA_PATH}/}"
|
||||
|
||||
# Download the file using curl. Trap to insure non partial file.
|
||||
(trap "rm -f $1" INT TERM \
|
||||
|
@ -72,13 +72,13 @@ stress_verify_environment() {
|
|||
# This function runs tests on libvpx that run multiple encodes and decodes
|
||||
# in parallel in hopes of catching synchronization and/or threading issues.
|
||||
stress() {
|
||||
local readonly decoder="$(vpx_tool_path vpxdec)"
|
||||
local readonly encoder="$(vpx_tool_path vpxenc)"
|
||||
local readonly codec="$1"
|
||||
local readonly webm="$2"
|
||||
local readonly decode_count="$3"
|
||||
local readonly threads="$4"
|
||||
local readonly enc_args="$5"
|
||||
local decoder="$(vpx_tool_path vpxdec)"
|
||||
local encoder="$(vpx_tool_path vpxenc)"
|
||||
local codec="$1"
|
||||
local webm="$2"
|
||||
local decode_count="$3"
|
||||
local threads="$4"
|
||||
local enc_args="$5"
|
||||
local pids=""
|
||||
local rt_max_jobs=${STRESS_RT_MAX_JOBS:-5}
|
||||
local onepass_max_jobs=${STRESS_ONEPASS_MAX_JOBS:-5}
|
||||
|
@ -144,6 +144,19 @@ vp8_stress_test() {
|
|||
fi
|
||||
}
|
||||
|
||||
vp8_stress_test_token_parititions() {
|
||||
local vp8_max_jobs=${STRESS_VP8_DECODE_MAX_JOBS:-40}
|
||||
if [ "$(vp8_decode_available)" = "yes" -a \
|
||||
"$(vp8_encode_available)" = "yes" ]; then
|
||||
for threads in 2 4 8; do
|
||||
for token_partitions in 1 2 3; do
|
||||
stress vp8 "${VP8}" "${vp8_max_jobs}" ${threads} \
|
||||
"--token-parts=$token_partitions"
|
||||
done
|
||||
done
|
||||
fi
|
||||
}
|
||||
|
||||
vp9_stress() {
|
||||
local vp9_max_jobs=${STRESS_VP9_DECODE_MAX_JOBS:-25}
|
||||
|
||||
|
@ -154,16 +167,17 @@ vp9_stress() {
|
|||
}
|
||||
|
||||
vp9_stress_test() {
|
||||
for threads in 4 8 100; do
|
||||
for threads in 4 8 64; do
|
||||
vp9_stress "$threads" "--row-mt=0"
|
||||
done
|
||||
}
|
||||
|
||||
vp9_stress_test_row_mt() {
|
||||
for threads in 4 8 100; do
|
||||
for threads in 4 8 64; do
|
||||
vp9_stress "$threads" "--row-mt=1"
|
||||
done
|
||||
}
|
||||
|
||||
run_tests stress_verify_environment \
|
||||
"vp8_stress_test vp9_stress_test vp9_stress_test_row_mt"
|
||||
"vp8_stress_test vp8_stress_test_token_parititions
|
||||
vp9_stress_test vp9_stress_test_row_mt"
|
||||
|
|
|
@ -11,6 +11,7 @@
|
|||
#include <cmath>
|
||||
#include <cstdlib>
|
||||
#include <string>
|
||||
#include <tuple>
|
||||
|
||||
#include "third_party/googletest/src/include/gtest/gtest.h"
|
||||
|
||||
|
@ -28,7 +29,7 @@ namespace {
|
|||
const int kNumIterations = 10000;
|
||||
|
||||
typedef uint64_t (*SSI16Func)(const int16_t *src, int stride, int size);
|
||||
typedef std::tr1::tuple<SSI16Func, SSI16Func> SumSquaresParam;
|
||||
typedef std::tuple<SSI16Func, SSI16Func> SumSquaresParam;
|
||||
|
||||
class SumSquaresTest : public ::testing::TestWithParam<SumSquaresParam> {
|
||||
public:
|
||||
|
@ -102,7 +103,14 @@ TEST_P(SumSquaresTest, ExtremeValues) {
|
|||
}
|
||||
}
|
||||
|
||||
using std::tr1::make_tuple;
|
||||
using std::make_tuple;
|
||||
|
||||
#if HAVE_NEON
|
||||
INSTANTIATE_TEST_CASE_P(
|
||||
NEON, SumSquaresTest,
|
||||
::testing::Values(make_tuple(&vpx_sum_squares_2d_i16_c,
|
||||
&vpx_sum_squares_2d_i16_neon)));
|
||||
#endif // HAVE_NEON
|
||||
|
||||
#if HAVE_SSE2
|
||||
INSTANTIATE_TEST_CASE_P(
|
||||
|
@ -112,8 +120,9 @@ INSTANTIATE_TEST_CASE_P(
|
|||
#endif // HAVE_SSE2
|
||||
|
||||
#if HAVE_MSA
|
||||
INSTANTIATE_TEST_CASE_P(MSA, SumSquaresTest, ::testing::Values(make_tuple(
|
||||
&vpx_sum_squares_2d_i16_c,
|
||||
INSTANTIATE_TEST_CASE_P(
|
||||
MSA, SumSquaresTest,
|
||||
::testing::Values(make_tuple(&vpx_sum_squares_2d_i16_c,
|
||||
&vpx_sum_squares_2d_i16_msa)));
|
||||
#endif // HAVE_MSA
|
||||
} // namespace
|
||||
|
|
|
@ -8,6 +8,8 @@
|
|||
* be found in the AUTHORS file in the root of the source tree.
|
||||
*/
|
||||
#include <climits>
|
||||
#include <tuple>
|
||||
|
||||
#include "third_party/googletest/src/include/gtest/gtest.h"
|
||||
#include "test/codec_factory.h"
|
||||
#include "test/encode_test_driver.h"
|
||||
|
@ -18,7 +20,7 @@ namespace {
|
|||
|
||||
const int kTestMode = 0;
|
||||
|
||||
typedef std::tr1::tuple<libvpx_test::TestMode, int> SuperframeTestParam;
|
||||
typedef std::tuple<libvpx_test::TestMode, int> SuperframeTestParam;
|
||||
|
||||
class SuperframeTest
|
||||
: public ::libvpx_test::EncoderTest,
|
||||
|
@ -31,7 +33,7 @@ class SuperframeTest
|
|||
virtual void SetUp() {
|
||||
InitializeConfig();
|
||||
const SuperframeTestParam input = GET_PARAM(1);
|
||||
const libvpx_test::TestMode mode = std::tr1::get<kTestMode>(input);
|
||||
const libvpx_test::TestMode mode = std::get<kTestMode>(input);
|
||||
SetMode(mode);
|
||||
sf_count_ = 0;
|
||||
sf_count_max_ = INT_MAX;
|
||||
|
@ -41,7 +43,7 @@ class SuperframeTest
|
|||
|
||||
virtual void PreEncodeFrameHook(libvpx_test::VideoSource *video,
|
||||
libvpx_test::Encoder *encoder) {
|
||||
if (video->frame() == 1) {
|
||||
if (video->frame() == 0) {
|
||||
encoder->Control(VP8E_SET_ENABLEAUTOALTREF, 1);
|
||||
}
|
||||
}
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -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
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 2013 The WebM project authors. All Rights Reserved.
|
||||
* Copyright (c) 2018 The WebM project authors. All Rights Reserved.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license
|
||||
* that can be found in the LICENSE file in the root of the source
|
||||
|
@ -8,782 +8,127 @@
|
|||
* be found in the AUTHORS file in the root of the source tree.
|
||||
*/
|
||||
|
||||
#include <string>
|
||||
#include "third_party/googletest/src/include/gtest/gtest.h"
|
||||
#include "test/codec_factory.h"
|
||||
#include "test/decode_test_driver.h"
|
||||
#include "test/i420_video_source.h"
|
||||
#include "test/svc_test.h"
|
||||
|
||||
#include "vp9/decoder/vp9_decoder.h"
|
||||
|
||||
#include "vpx/svc_context.h"
|
||||
#include "vpx/vp8cx.h"
|
||||
#include "vpx/vpx_encoder.h"
|
||||
|
||||
namespace {
|
||||
|
||||
using libvpx_test::CodecFactory;
|
||||
using libvpx_test::Decoder;
|
||||
using libvpx_test::DxDataIterator;
|
||||
using libvpx_test::VP9CodecFactory;
|
||||
|
||||
class SvcTest : public ::testing::Test {
|
||||
protected:
|
||||
static const uint32_t kWidth = 352;
|
||||
static const uint32_t kHeight = 288;
|
||||
|
||||
SvcTest()
|
||||
: codec_iface_(0), test_file_name_("hantro_collage_w352h288.yuv"),
|
||||
codec_initialized_(false), decoder_(0) {
|
||||
memset(&svc_, 0, sizeof(svc_));
|
||||
memset(&codec_, 0, sizeof(codec_));
|
||||
memset(&codec_enc_, 0, sizeof(codec_enc_));
|
||||
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;
|
||||
}
|
||||
|
||||
virtual ~SvcTest() {}
|
||||
|
||||
virtual void SetUp() {
|
||||
svc_.log_level = SVC_LOG_DEBUG;
|
||||
svc_.log_print = 0;
|
||||
|
||||
codec_iface_ = vpx_codec_vp9_cx();
|
||||
const vpx_codec_err_t res =
|
||||
vpx_codec_enc_config_default(codec_iface_, &codec_enc_, 0);
|
||||
EXPECT_EQ(VPX_CODEC_OK, res);
|
||||
|
||||
codec_enc_.g_w = kWidth;
|
||||
codec_enc_.g_h = kHeight;
|
||||
codec_enc_.g_timebase.num = 1;
|
||||
codec_enc_.g_timebase.den = 60;
|
||||
codec_enc_.kf_min_dist = 100;
|
||||
codec_enc_.kf_max_dist = 100;
|
||||
|
||||
vpx_codec_dec_cfg_t dec_cfg = vpx_codec_dec_cfg_t();
|
||||
VP9CodecFactory codec_factory;
|
||||
decoder_ = codec_factory.CreateDecoder(dec_cfg, 0);
|
||||
|
||||
tile_columns_ = 0;
|
||||
tile_rows_ = 0;
|
||||
void OnePassCbrSvc::PreEncodeFrameHookSetup(::libvpx_test::VideoSource *video,
|
||||
::libvpx_test::Encoder *encoder) {
|
||||
if (video->frame() == 0) {
|
||||
for (int i = 0; i < VPX_MAX_LAYERS; ++i) {
|
||||
svc_params_.max_quantizers[i] = 63;
|
||||
svc_params_.min_quantizers[i] = 0;
|
||||
}
|
||||
svc_params_.speed_per_layer[0] = base_speed_setting_;
|
||||
for (int i = 1; i < VPX_SS_MAX_LAYERS; ++i) {
|
||||
svc_params_.speed_per_layer[i] = speed_setting_;
|
||||
}
|
||||
|
||||
virtual void TearDown() {
|
||||
ReleaseEncoder();
|
||||
delete (decoder_);
|
||||
encoder->Control(VP9E_SET_SVC, 1);
|
||||
encoder->Control(VP9E_SET_SVC_PARAMETERS, &svc_params_);
|
||||
encoder->Control(VP8E_SET_CPUUSED, speed_setting_);
|
||||
encoder->Control(VP9E_SET_AQ_MODE, 3);
|
||||
encoder->Control(VP8E_SET_MAX_INTRA_BITRATE_PCT, 300);
|
||||
encoder->Control(VP9E_SET_TILE_COLUMNS, get_msb(cfg_.g_threads));
|
||||
encoder->Control(VP9E_SET_ROW_MT, 1);
|
||||
encoder->Control(VP8E_SET_STATIC_THRESHOLD, 1);
|
||||
}
|
||||
|
||||
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;
|
||||
superframe_count_++;
|
||||
temporal_layer_id_ = 0;
|
||||
if (number_temporal_layers_ == 2) {
|
||||
temporal_layer_id_ = (superframe_count_ % 2 != 0);
|
||||
} else if (number_temporal_layers_ == 3) {
|
||||
if (superframe_count_ % 2 != 0) temporal_layer_id_ = 2;
|
||||
if (superframe_count_ > 1) {
|
||||
if ((superframe_count_ - 2) % 4 == 0) temporal_layer_id_ = 1;
|
||||
}
|
||||
}
|
||||
|
||||
void ReleaseEncoder() {
|
||||
vpx_svc_release(&svc_);
|
||||
if (codec_initialized_) vpx_codec_destroy(&codec_);
|
||||
codec_initialized_ = false;
|
||||
frame_flags_ = 0;
|
||||
}
|
||||
|
||||
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 OnePassCbrSvc::PostEncodeFrameHook(::libvpx_test::Encoder *encoder) {
|
||||
vpx_svc_layer_id_t layer_id;
|
||||
encoder->Control(VP9E_GET_SVC_LAYER_ID, &layer_id);
|
||||
temporal_layer_id_ = layer_id.temporal_layer_id;
|
||||
for (int sl = 0; sl < number_spatial_layers_; ++sl) {
|
||||
for (int tl = temporal_layer_id_; tl < number_temporal_layers_; ++tl) {
|
||||
const int layer = sl * number_temporal_layers_ + tl;
|
||||
bits_in_buffer_model_[layer] +=
|
||||
static_cast<int64_t>(layer_target_avg_bandwidth_[layer]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Pass1EncodeNFrames(const int n, const int layers,
|
||||
std::string *const stats_buf) {
|
||||
vpx_codec_err_t res;
|
||||
|
||||
ASSERT_GT(n, 0);
|
||||
ASSERT_GT(layers, 0);
|
||||
svc_.spatial_layers = layers;
|
||||
codec_enc_.g_pass = VPX_RC_FIRST_PASS;
|
||||
InitializeEncoder();
|
||||
|
||||
libvpx_test::I420VideoSource video(
|
||||
test_file_name_, codec_enc_.g_w, codec_enc_.g_h,
|
||||
codec_enc_.g_timebase.den, codec_enc_.g_timebase.num, 0, 30);
|
||||
video.Begin();
|
||||
|
||||
for (int i = 0; i < n; ++i) {
|
||||
res = vpx_svc_encode(&svc_, &codec_, video.img(), video.pts(),
|
||||
video.duration(), VPX_DL_GOOD_QUALITY);
|
||||
ASSERT_EQ(VPX_CODEC_OK, res);
|
||||
GetStatsData(stats_buf);
|
||||
video.Next();
|
||||
void OnePassCbrSvc::AssignLayerBitrates() {
|
||||
int sl, spatial_layer_target;
|
||||
int spatial_layers = cfg_.ss_number_layers;
|
||||
int temporal_layers = cfg_.ts_number_layers;
|
||||
float total = 0;
|
||||
float alloc_ratio[VPX_MAX_LAYERS] = { 0 };
|
||||
float framerate = 30.0;
|
||||
for (sl = 0; sl < spatial_layers; ++sl) {
|
||||
if (svc_params_.scaling_factor_den[sl] > 0) {
|
||||
alloc_ratio[sl] =
|
||||
static_cast<float>((svc_params_.scaling_factor_num[sl] * 1.0 /
|
||||
svc_params_.scaling_factor_den[sl]));
|
||||
total += alloc_ratio[sl];
|
||||
}
|
||||
|
||||
// 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);
|
||||
for (sl = 0; sl < spatial_layers; ++sl) {
|
||||
cfg_.ss_target_bitrate[sl] = spatial_layer_target =
|
||||
static_cast<unsigned int>(cfg_.rc_target_bitrate * alloc_ratio[sl] /
|
||||
total);
|
||||
const int index = sl * temporal_layers;
|
||||
if (cfg_.temporal_layering_mode == 3) {
|
||||
cfg_.layer_target_bitrate[index] = spatial_layer_target >> 1;
|
||||
cfg_.layer_target_bitrate[index + 1] =
|
||||
(spatial_layer_target >> 1) + (spatial_layer_target >> 2);
|
||||
cfg_.layer_target_bitrate[index + 2] = spatial_layer_target;
|
||||
} else if (cfg_.temporal_layering_mode == 2) {
|
||||
cfg_.layer_target_bitrate[index] = spatial_layer_target * 2 / 3;
|
||||
cfg_.layer_target_bitrate[index + 1] = spatial_layer_target;
|
||||
} else if (cfg_.temporal_layering_mode <= 1) {
|
||||
cfg_.layer_target_bitrate[index] = spatial_layer_target;
|
||||
}
|
||||
}
|
||||
for (sl = 0; sl < spatial_layers; ++sl) {
|
||||
for (int tl = 0; tl < temporal_layers; ++tl) {
|
||||
const int layer = sl * temporal_layers + tl;
|
||||
float layer_framerate = framerate;
|
||||
if (temporal_layers == 2 && tl == 0) layer_framerate = framerate / 2;
|
||||
if (temporal_layers == 3 && tl == 0) layer_framerate = framerate / 4;
|
||||
if (temporal_layers == 3 && tl == 1) layer_framerate = framerate / 2;
|
||||
layer_target_avg_bandwidth_[layer] = static_cast<int>(
|
||||
cfg_.layer_target_bitrate[layer] * 1000.0 / layer_framerate);
|
||||
bits_in_buffer_model_[layer] =
|
||||
cfg_.layer_target_bitrate[layer] * cfg_.rc_buf_initial_sz;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Pass2EncodeNFrames(std::string *const stats_buf, const int n,
|
||||
const int layers,
|
||||
struct vpx_fixed_buf *const outputs) {
|
||||
vpx_codec_err_t res;
|
||||
size_t frame_received = 0;
|
||||
|
||||
ASSERT_TRUE(outputs != NULL);
|
||||
ASSERT_GT(n, 0);
|
||||
ASSERT_GT(layers, 0);
|
||||
svc_.spatial_layers = layers;
|
||||
codec_enc_.rc_target_bitrate = 500;
|
||||
if (codec_enc_.g_pass == VPX_RC_LAST_PASS) {
|
||||
ASSERT_TRUE(stats_buf != NULL);
|
||||
ASSERT_GT(stats_buf->size(), 0U);
|
||||
codec_enc_.rc_twopass_stats_in.buf = &(*stats_buf)[0];
|
||||
codec_enc_.rc_twopass_stats_in.sz = stats_buf->size();
|
||||
}
|
||||
InitializeEncoder();
|
||||
|
||||
libvpx_test::I420VideoSource video(
|
||||
test_file_name_, codec_enc_.g_w, codec_enc_.g_h,
|
||||
codec_enc_.g_timebase.den, codec_enc_.g_timebase.num, 0, 30);
|
||||
video.Begin();
|
||||
|
||||
for (int i = 0; i < n; ++i) {
|
||||
res = vpx_svc_encode(&svc_, &codec_, video.img(), video.pts(),
|
||||
video.duration(), VPX_DL_GOOD_QUALITY);
|
||||
ASSERT_EQ(VPX_CODEC_OK, res);
|
||||
StoreFrames(n, outputs, &frame_received);
|
||||
video.Next();
|
||||
}
|
||||
|
||||
// Flush encoder.
|
||||
res = vpx_svc_encode(&svc_, &codec_, NULL, 0, video.duration(),
|
||||
VPX_DL_GOOD_QUALITY);
|
||||
EXPECT_EQ(VPX_CODEC_OK, res);
|
||||
StoreFrames(n, outputs, &frame_received);
|
||||
|
||||
EXPECT_EQ(frame_received, static_cast<size_t>(n));
|
||||
|
||||
ReleaseEncoder();
|
||||
}
|
||||
|
||||
void DecodeNFrames(const struct vpx_fixed_buf *const inputs, const int n) {
|
||||
int decoded_frames = 0;
|
||||
int received_frames = 0;
|
||||
|
||||
ASSERT_TRUE(inputs != NULL);
|
||||
ASSERT_GT(n, 0);
|
||||
|
||||
for (int i = 0; i < n; ++i) {
|
||||
ASSERT_TRUE(inputs[i].buf != NULL);
|
||||
ASSERT_GT(inputs[i].sz, 0U);
|
||||
const vpx_codec_err_t res_dec = decoder_->DecodeFrame(
|
||||
static_cast<const uint8_t *>(inputs[i].buf), inputs[i].sz);
|
||||
ASSERT_EQ(VPX_CODEC_OK, res_dec) << decoder_->DecodeError();
|
||||
++decoded_frames;
|
||||
|
||||
DxDataIterator dec_iter = decoder_->GetDxData();
|
||||
while (dec_iter.Next() != NULL) {
|
||||
++received_frames;
|
||||
}
|
||||
}
|
||||
EXPECT_EQ(decoded_frames, n);
|
||||
EXPECT_EQ(received_frames, n);
|
||||
}
|
||||
|
||||
void DropEnhancementLayers(struct vpx_fixed_buf *const inputs,
|
||||
const int num_super_frames,
|
||||
const int remained_spatial_layers) {
|
||||
ASSERT_TRUE(inputs != NULL);
|
||||
ASSERT_GT(num_super_frames, 0);
|
||||
ASSERT_GT(remained_spatial_layers, 0);
|
||||
|
||||
for (int i = 0; i < num_super_frames; ++i) {
|
||||
uint32_t frame_sizes[8] = { 0 };
|
||||
int frame_count = 0;
|
||||
int frames_found = 0;
|
||||
int frame;
|
||||
ASSERT_TRUE(inputs[i].buf != NULL);
|
||||
ASSERT_GT(inputs[i].sz, 0U);
|
||||
|
||||
vpx_codec_err_t res = vp9_parse_superframe_index(
|
||||
static_cast<const uint8_t *>(inputs[i].buf), inputs[i].sz,
|
||||
frame_sizes, &frame_count, NULL, NULL);
|
||||
ASSERT_EQ(VPX_CODEC_OK, res);
|
||||
|
||||
if (frame_count == 0) {
|
||||
// There's no super frame but only a single frame.
|
||||
ASSERT_EQ(1, remained_spatial_layers);
|
||||
} else {
|
||||
// Found a super frame.
|
||||
uint8_t *frame_data = static_cast<uint8_t *>(inputs[i].buf);
|
||||
uint8_t *frame_start = frame_data;
|
||||
for (frame = 0; frame < frame_count; ++frame) {
|
||||
// Looking for a visible frame.
|
||||
if (frame_data[0] & 0x02) {
|
||||
++frames_found;
|
||||
if (frames_found == remained_spatial_layers) break;
|
||||
}
|
||||
frame_data += frame_sizes[frame];
|
||||
}
|
||||
ASSERT_LT(frame, frame_count)
|
||||
<< "Couldn't find a visible frame. "
|
||||
<< "remained_spatial_layers: " << remained_spatial_layers
|
||||
<< " super_frame: " << i;
|
||||
if (frame == frame_count - 1) continue;
|
||||
|
||||
frame_data += frame_sizes[frame];
|
||||
|
||||
// We need to add one more frame for multiple frame contexts.
|
||||
uint8_t marker =
|
||||
static_cast<const uint8_t *>(inputs[i].buf)[inputs[i].sz - 1];
|
||||
const uint32_t mag = ((marker >> 3) & 0x3) + 1;
|
||||
const size_t index_sz = 2 + mag * frame_count;
|
||||
const size_t new_index_sz = 2 + mag * (frame + 1);
|
||||
marker &= 0x0f8;
|
||||
marker |= frame;
|
||||
|
||||
// Copy existing frame sizes.
|
||||
memmove(frame_data + 1, frame_start + inputs[i].sz - index_sz + 1,
|
||||
new_index_sz - 2);
|
||||
// New marker.
|
||||
frame_data[0] = marker;
|
||||
frame_data += (mag * (frame + 1) + 1);
|
||||
|
||||
*frame_data++ = marker;
|
||||
inputs[i].sz = frame_data - frame_start;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void FreeBitstreamBuffers(struct vpx_fixed_buf *const inputs, const int n) {
|
||||
ASSERT_TRUE(inputs != NULL);
|
||||
ASSERT_GT(n, 0);
|
||||
|
||||
for (int i = 0; i < n; ++i) {
|
||||
free(inputs[i].buf);
|
||||
inputs[i].buf = NULL;
|
||||
inputs[i].sz = 0;
|
||||
}
|
||||
}
|
||||
|
||||
SvcContext svc_;
|
||||
vpx_codec_ctx_t codec_;
|
||||
struct vpx_codec_enc_cfg codec_enc_;
|
||||
vpx_codec_iface_t *codec_iface_;
|
||||
std::string test_file_name_;
|
||||
bool codec_initialized_;
|
||||
Decoder *decoder_;
|
||||
int tile_columns_;
|
||||
int tile_rows_;
|
||||
};
|
||||
|
||||
TEST_F(SvcTest, SvcInit) {
|
||||
// test missing parameters
|
||||
vpx_codec_err_t res = vpx_svc_init(NULL, &codec_, codec_iface_, &codec_enc_);
|
||||
EXPECT_EQ(VPX_CODEC_INVALID_PARAM, res);
|
||||
res = vpx_svc_init(&svc_, NULL, codec_iface_, &codec_enc_);
|
||||
EXPECT_EQ(VPX_CODEC_INVALID_PARAM, res);
|
||||
res = vpx_svc_init(&svc_, &codec_, NULL, &codec_enc_);
|
||||
EXPECT_EQ(VPX_CODEC_INVALID_PARAM, res);
|
||||
|
||||
res = vpx_svc_init(&svc_, &codec_, codec_iface_, NULL);
|
||||
EXPECT_EQ(VPX_CODEC_INVALID_PARAM, res);
|
||||
|
||||
svc_.spatial_layers = 6; // too many layers
|
||||
res = vpx_svc_init(&svc_, &codec_, codec_iface_, &codec_enc_);
|
||||
EXPECT_EQ(VPX_CODEC_INVALID_PARAM, res);
|
||||
|
||||
svc_.spatial_layers = 0; // use default layers
|
||||
InitializeEncoder();
|
||||
EXPECT_EQ(VPX_SS_DEFAULT_LAYERS, svc_.spatial_layers);
|
||||
}
|
||||
|
||||
TEST_F(SvcTest, InitTwoLayers) {
|
||||
svc_.spatial_layers = 2;
|
||||
InitializeEncoder();
|
||||
}
|
||||
|
||||
TEST_F(SvcTest, InvalidOptions) {
|
||||
vpx_codec_err_t res = vpx_svc_set_options(&svc_, NULL);
|
||||
EXPECT_EQ(VPX_CODEC_INVALID_PARAM, res);
|
||||
|
||||
res = vpx_svc_set_options(&svc_, "not-an-option=1");
|
||||
EXPECT_EQ(VPX_CODEC_OK, res);
|
||||
res = vpx_svc_init(&svc_, &codec_, vpx_codec_vp9_cx(), &codec_enc_);
|
||||
EXPECT_EQ(VPX_CODEC_INVALID_PARAM, res);
|
||||
}
|
||||
|
||||
TEST_F(SvcTest, SetLayersOption) {
|
||||
vpx_codec_err_t res = vpx_svc_set_options(&svc_, "spatial-layers=3");
|
||||
EXPECT_EQ(VPX_CODEC_OK, res);
|
||||
InitializeEncoder();
|
||||
EXPECT_EQ(3, svc_.spatial_layers);
|
||||
}
|
||||
|
||||
TEST_F(SvcTest, SetMultipleOptions) {
|
||||
vpx_codec_err_t res =
|
||||
vpx_svc_set_options(&svc_, "spatial-layers=2 scale-factors=1/3,2/3");
|
||||
EXPECT_EQ(VPX_CODEC_OK, res);
|
||||
InitializeEncoder();
|
||||
EXPECT_EQ(2, svc_.spatial_layers);
|
||||
}
|
||||
|
||||
TEST_F(SvcTest, SetScaleFactorsOption) {
|
||||
svc_.spatial_layers = 2;
|
||||
vpx_codec_err_t res =
|
||||
vpx_svc_set_options(&svc_, "scale-factors=not-scale-factors");
|
||||
EXPECT_EQ(VPX_CODEC_OK, res);
|
||||
res = vpx_svc_init(&svc_, &codec_, vpx_codec_vp9_cx(), &codec_enc_);
|
||||
EXPECT_EQ(VPX_CODEC_INVALID_PARAM, res);
|
||||
|
||||
res = vpx_svc_set_options(&svc_, "scale-factors=1/3, 3*3");
|
||||
EXPECT_EQ(VPX_CODEC_OK, res);
|
||||
res = vpx_svc_init(&svc_, &codec_, vpx_codec_vp9_cx(), &codec_enc_);
|
||||
EXPECT_EQ(VPX_CODEC_INVALID_PARAM, res);
|
||||
|
||||
res = vpx_svc_set_options(&svc_, "scale-factors=1/3");
|
||||
EXPECT_EQ(VPX_CODEC_OK, res);
|
||||
res = vpx_svc_init(&svc_, &codec_, vpx_codec_vp9_cx(), &codec_enc_);
|
||||
EXPECT_EQ(VPX_CODEC_INVALID_PARAM, res);
|
||||
|
||||
res = vpx_svc_set_options(&svc_, "scale-factors=1/3,2/3");
|
||||
EXPECT_EQ(VPX_CODEC_OK, res);
|
||||
InitializeEncoder();
|
||||
}
|
||||
|
||||
TEST_F(SvcTest, SetQuantizersOption) {
|
||||
svc_.spatial_layers = 2;
|
||||
vpx_codec_err_t res = vpx_svc_set_options(&svc_, "max-quantizers=nothing");
|
||||
EXPECT_EQ(VPX_CODEC_OK, res);
|
||||
res = vpx_svc_init(&svc_, &codec_, vpx_codec_vp9_cx(), &codec_enc_);
|
||||
EXPECT_EQ(VPX_CODEC_INVALID_PARAM, res);
|
||||
|
||||
res = vpx_svc_set_options(&svc_, "min-quantizers=nothing");
|
||||
EXPECT_EQ(VPX_CODEC_OK, res);
|
||||
res = vpx_svc_init(&svc_, &codec_, vpx_codec_vp9_cx(), &codec_enc_);
|
||||
EXPECT_EQ(VPX_CODEC_INVALID_PARAM, res);
|
||||
|
||||
res = vpx_svc_set_options(&svc_, "max-quantizers=40");
|
||||
EXPECT_EQ(VPX_CODEC_OK, res);
|
||||
res = vpx_svc_init(&svc_, &codec_, vpx_codec_vp9_cx(), &codec_enc_);
|
||||
EXPECT_EQ(VPX_CODEC_INVALID_PARAM, res);
|
||||
|
||||
res = vpx_svc_set_options(&svc_, "min-quantizers=40");
|
||||
EXPECT_EQ(VPX_CODEC_OK, res);
|
||||
res = vpx_svc_init(&svc_, &codec_, vpx_codec_vp9_cx(), &codec_enc_);
|
||||
EXPECT_EQ(VPX_CODEC_INVALID_PARAM, res);
|
||||
|
||||
res = vpx_svc_set_options(&svc_, "max-quantizers=30,30 min-quantizers=40,40");
|
||||
EXPECT_EQ(VPX_CODEC_OK, res);
|
||||
res = vpx_svc_init(&svc_, &codec_, vpx_codec_vp9_cx(), &codec_enc_);
|
||||
EXPECT_EQ(VPX_CODEC_INVALID_PARAM, res);
|
||||
|
||||
res = vpx_svc_set_options(&svc_, "max-quantizers=40,40 min-quantizers=30,30");
|
||||
InitializeEncoder();
|
||||
}
|
||||
|
||||
TEST_F(SvcTest, SetAutoAltRefOption) {
|
||||
svc_.spatial_layers = 5;
|
||||
vpx_codec_err_t res = vpx_svc_set_options(&svc_, "auto-alt-refs=none");
|
||||
EXPECT_EQ(VPX_CODEC_OK, res);
|
||||
res = vpx_svc_init(&svc_, &codec_, vpx_codec_vp9_cx(), &codec_enc_);
|
||||
EXPECT_EQ(VPX_CODEC_INVALID_PARAM, res);
|
||||
|
||||
res = vpx_svc_set_options(&svc_, "auto-alt-refs=1,1,1,1,0");
|
||||
EXPECT_EQ(VPX_CODEC_OK, res);
|
||||
res = vpx_svc_init(&svc_, &codec_, vpx_codec_vp9_cx(), &codec_enc_);
|
||||
EXPECT_EQ(VPX_CODEC_INVALID_PARAM, res);
|
||||
|
||||
vpx_svc_set_options(&svc_, "auto-alt-refs=0,1,1,1,0");
|
||||
InitializeEncoder();
|
||||
}
|
||||
|
||||
// Test that decoder can handle an SVC frame as the first frame in a sequence.
|
||||
TEST_F(SvcTest, OnePassEncodeOneFrame) {
|
||||
codec_enc_.g_pass = VPX_RC_ONE_PASS;
|
||||
vpx_fixed_buf output = vpx_fixed_buf();
|
||||
Pass2EncodeNFrames(NULL, 1, 2, &output);
|
||||
DecodeNFrames(&output, 1);
|
||||
FreeBitstreamBuffers(&output, 1);
|
||||
}
|
||||
|
||||
TEST_F(SvcTest, OnePassEncodeThreeFrames) {
|
||||
codec_enc_.g_pass = VPX_RC_ONE_PASS;
|
||||
codec_enc_.g_lag_in_frames = 0;
|
||||
vpx_fixed_buf outputs[3];
|
||||
memset(&outputs[0], 0, sizeof(outputs));
|
||||
Pass2EncodeNFrames(NULL, 3, 2, &outputs[0]);
|
||||
DecodeNFrames(&outputs[0], 3);
|
||||
FreeBitstreamBuffers(&outputs[0], 3);
|
||||
}
|
||||
|
||||
TEST_F(SvcTest, TwoPassEncode10Frames) {
|
||||
// First pass encode
|
||||
std::string stats_buf;
|
||||
Pass1EncodeNFrames(10, 2, &stats_buf);
|
||||
|
||||
// Second pass encode
|
||||
codec_enc_.g_pass = VPX_RC_LAST_PASS;
|
||||
vpx_fixed_buf outputs[10];
|
||||
memset(&outputs[0], 0, sizeof(outputs));
|
||||
Pass2EncodeNFrames(&stats_buf, 10, 2, &outputs[0]);
|
||||
DecodeNFrames(&outputs[0], 10);
|
||||
FreeBitstreamBuffers(&outputs[0], 10);
|
||||
}
|
||||
|
||||
TEST_F(SvcTest, TwoPassEncode20FramesWithAltRef) {
|
||||
// First pass encode
|
||||
std::string stats_buf;
|
||||
Pass1EncodeNFrames(20, 2, &stats_buf);
|
||||
|
||||
// Second pass encode
|
||||
codec_enc_.g_pass = VPX_RC_LAST_PASS;
|
||||
vpx_svc_set_options(&svc_, "auto-alt-refs=1,1");
|
||||
vpx_fixed_buf outputs[20];
|
||||
memset(&outputs[0], 0, sizeof(outputs));
|
||||
Pass2EncodeNFrames(&stats_buf, 20, 2, &outputs[0]);
|
||||
DecodeNFrames(&outputs[0], 20);
|
||||
FreeBitstreamBuffers(&outputs[0], 20);
|
||||
}
|
||||
|
||||
TEST_F(SvcTest, TwoPassEncode2SpatialLayersDecodeBaseLayerOnly) {
|
||||
// First pass encode
|
||||
std::string stats_buf;
|
||||
Pass1EncodeNFrames(10, 2, &stats_buf);
|
||||
|
||||
// Second pass encode
|
||||
codec_enc_.g_pass = VPX_RC_LAST_PASS;
|
||||
vpx_svc_set_options(&svc_, "auto-alt-refs=1,1");
|
||||
vpx_fixed_buf outputs[10];
|
||||
memset(&outputs[0], 0, sizeof(outputs));
|
||||
Pass2EncodeNFrames(&stats_buf, 10, 2, &outputs[0]);
|
||||
DropEnhancementLayers(&outputs[0], 10, 1);
|
||||
DecodeNFrames(&outputs[0], 10);
|
||||
FreeBitstreamBuffers(&outputs[0], 10);
|
||||
}
|
||||
|
||||
TEST_F(SvcTest, TwoPassEncode5SpatialLayersDecode54321Layers) {
|
||||
// First pass encode
|
||||
std::string stats_buf;
|
||||
Pass1EncodeNFrames(10, 5, &stats_buf);
|
||||
|
||||
// Second pass encode
|
||||
codec_enc_.g_pass = VPX_RC_LAST_PASS;
|
||||
vpx_svc_set_options(&svc_, "auto-alt-refs=0,1,1,1,0");
|
||||
vpx_fixed_buf outputs[10];
|
||||
memset(&outputs[0], 0, sizeof(outputs));
|
||||
Pass2EncodeNFrames(&stats_buf, 10, 5, &outputs[0]);
|
||||
|
||||
DecodeNFrames(&outputs[0], 10);
|
||||
DropEnhancementLayers(&outputs[0], 10, 4);
|
||||
DecodeNFrames(&outputs[0], 10);
|
||||
DropEnhancementLayers(&outputs[0], 10, 3);
|
||||
DecodeNFrames(&outputs[0], 10);
|
||||
DropEnhancementLayers(&outputs[0], 10, 2);
|
||||
DecodeNFrames(&outputs[0], 10);
|
||||
DropEnhancementLayers(&outputs[0], 10, 1);
|
||||
DecodeNFrames(&outputs[0], 10);
|
||||
|
||||
FreeBitstreamBuffers(&outputs[0], 10);
|
||||
}
|
||||
|
||||
TEST_F(SvcTest, TwoPassEncode2SNRLayers) {
|
||||
// First pass encode
|
||||
std::string stats_buf;
|
||||
vpx_svc_set_options(&svc_, "scale-factors=1/1,1/1");
|
||||
Pass1EncodeNFrames(20, 2, &stats_buf);
|
||||
|
||||
// Second pass encode
|
||||
codec_enc_.g_pass = VPX_RC_LAST_PASS;
|
||||
vpx_svc_set_options(&svc_, "auto-alt-refs=1,1 scale-factors=1/1,1/1");
|
||||
vpx_fixed_buf outputs[20];
|
||||
memset(&outputs[0], 0, sizeof(outputs));
|
||||
Pass2EncodeNFrames(&stats_buf, 20, 2, &outputs[0]);
|
||||
DecodeNFrames(&outputs[0], 20);
|
||||
FreeBitstreamBuffers(&outputs[0], 20);
|
||||
}
|
||||
|
||||
TEST_F(SvcTest, TwoPassEncode3SNRLayersDecode321Layers) {
|
||||
// First pass encode
|
||||
std::string stats_buf;
|
||||
vpx_svc_set_options(&svc_, "scale-factors=1/1,1/1,1/1");
|
||||
Pass1EncodeNFrames(20, 3, &stats_buf);
|
||||
|
||||
// Second pass encode
|
||||
codec_enc_.g_pass = VPX_RC_LAST_PASS;
|
||||
vpx_svc_set_options(&svc_, "auto-alt-refs=1,1,1 scale-factors=1/1,1/1,1/1");
|
||||
vpx_fixed_buf outputs[20];
|
||||
memset(&outputs[0], 0, sizeof(outputs));
|
||||
Pass2EncodeNFrames(&stats_buf, 20, 3, &outputs[0]);
|
||||
DecodeNFrames(&outputs[0], 20);
|
||||
DropEnhancementLayers(&outputs[0], 20, 2);
|
||||
DecodeNFrames(&outputs[0], 20);
|
||||
DropEnhancementLayers(&outputs[0], 20, 1);
|
||||
DecodeNFrames(&outputs[0], 20);
|
||||
|
||||
FreeBitstreamBuffers(&outputs[0], 20);
|
||||
}
|
||||
|
||||
TEST_F(SvcTest, SetMultipleFrameContextsOption) {
|
||||
svc_.spatial_layers = 5;
|
||||
vpx_codec_err_t res = vpx_svc_set_options(&svc_, "multi-frame-contexts=1");
|
||||
EXPECT_EQ(VPX_CODEC_OK, res);
|
||||
res = vpx_svc_init(&svc_, &codec_, vpx_codec_vp9_cx(), &codec_enc_);
|
||||
EXPECT_EQ(VPX_CODEC_INVALID_PARAM, res);
|
||||
|
||||
svc_.spatial_layers = 2;
|
||||
res = vpx_svc_set_options(&svc_, "multi-frame-contexts=1");
|
||||
InitializeEncoder();
|
||||
}
|
||||
|
||||
TEST_F(SvcTest, TwoPassEncode2SpatialLayersWithMultipleFrameContexts) {
|
||||
// First pass encode
|
||||
std::string stats_buf;
|
||||
Pass1EncodeNFrames(10, 2, &stats_buf);
|
||||
|
||||
// Second pass encode
|
||||
codec_enc_.g_pass = VPX_RC_LAST_PASS;
|
||||
codec_enc_.g_error_resilient = 0;
|
||||
vpx_svc_set_options(&svc_, "auto-alt-refs=1,1 multi-frame-contexts=1");
|
||||
vpx_fixed_buf outputs[10];
|
||||
memset(&outputs[0], 0, sizeof(outputs));
|
||||
Pass2EncodeNFrames(&stats_buf, 10, 2, &outputs[0]);
|
||||
DecodeNFrames(&outputs[0], 10);
|
||||
FreeBitstreamBuffers(&outputs[0], 10);
|
||||
}
|
||||
|
||||
TEST_F(SvcTest,
|
||||
TwoPassEncode2SpatialLayersWithMultipleFrameContextsDecodeBaselayer) {
|
||||
// First pass encode
|
||||
std::string stats_buf;
|
||||
Pass1EncodeNFrames(10, 2, &stats_buf);
|
||||
|
||||
// Second pass encode
|
||||
codec_enc_.g_pass = VPX_RC_LAST_PASS;
|
||||
codec_enc_.g_error_resilient = 0;
|
||||
vpx_svc_set_options(&svc_, "auto-alt-refs=1,1 multi-frame-contexts=1");
|
||||
vpx_fixed_buf outputs[10];
|
||||
memset(&outputs[0], 0, sizeof(outputs));
|
||||
Pass2EncodeNFrames(&stats_buf, 10, 2, &outputs[0]);
|
||||
DropEnhancementLayers(&outputs[0], 10, 1);
|
||||
DecodeNFrames(&outputs[0], 10);
|
||||
FreeBitstreamBuffers(&outputs[0], 10);
|
||||
}
|
||||
|
||||
TEST_F(SvcTest, TwoPassEncode2SNRLayersWithMultipleFrameContexts) {
|
||||
// First pass encode
|
||||
std::string stats_buf;
|
||||
vpx_svc_set_options(&svc_, "scale-factors=1/1,1/1");
|
||||
Pass1EncodeNFrames(10, 2, &stats_buf);
|
||||
|
||||
// Second pass encode
|
||||
codec_enc_.g_pass = VPX_RC_LAST_PASS;
|
||||
codec_enc_.g_error_resilient = 0;
|
||||
vpx_svc_set_options(&svc_,
|
||||
"auto-alt-refs=1,1 scale-factors=1/1,1/1 "
|
||||
"multi-frame-contexts=1");
|
||||
vpx_fixed_buf outputs[10];
|
||||
memset(&outputs[0], 0, sizeof(outputs));
|
||||
Pass2EncodeNFrames(&stats_buf, 10, 2, &outputs[0]);
|
||||
DecodeNFrames(&outputs[0], 10);
|
||||
FreeBitstreamBuffers(&outputs[0], 10);
|
||||
}
|
||||
|
||||
TEST_F(SvcTest,
|
||||
TwoPassEncode3SNRLayersWithMultipleFrameContextsDecode321Layer) {
|
||||
// First pass encode
|
||||
std::string stats_buf;
|
||||
vpx_svc_set_options(&svc_, "scale-factors=1/1,1/1,1/1");
|
||||
Pass1EncodeNFrames(10, 3, &stats_buf);
|
||||
|
||||
// Second pass encode
|
||||
codec_enc_.g_pass = VPX_RC_LAST_PASS;
|
||||
codec_enc_.g_error_resilient = 0;
|
||||
vpx_svc_set_options(&svc_,
|
||||
"auto-alt-refs=1,1,1 scale-factors=1/1,1/1,1/1 "
|
||||
"multi-frame-contexts=1");
|
||||
vpx_fixed_buf outputs[10];
|
||||
memset(&outputs[0], 0, sizeof(outputs));
|
||||
Pass2EncodeNFrames(&stats_buf, 10, 3, &outputs[0]);
|
||||
|
||||
DecodeNFrames(&outputs[0], 10);
|
||||
DropEnhancementLayers(&outputs[0], 10, 2);
|
||||
DecodeNFrames(&outputs[0], 10);
|
||||
DropEnhancementLayers(&outputs[0], 10, 1);
|
||||
DecodeNFrames(&outputs[0], 10);
|
||||
|
||||
FreeBitstreamBuffers(&outputs[0], 10);
|
||||
}
|
||||
|
||||
TEST_F(SvcTest, TwoPassEncode2TemporalLayers) {
|
||||
// First pass encode
|
||||
std::string stats_buf;
|
||||
vpx_svc_set_options(&svc_, "scale-factors=1/1");
|
||||
svc_.temporal_layers = 2;
|
||||
Pass1EncodeNFrames(10, 1, &stats_buf);
|
||||
|
||||
// Second pass encode
|
||||
codec_enc_.g_pass = VPX_RC_LAST_PASS;
|
||||
svc_.temporal_layers = 2;
|
||||
vpx_svc_set_options(&svc_, "auto-alt-refs=1 scale-factors=1/1");
|
||||
vpx_fixed_buf outputs[10];
|
||||
memset(&outputs[0], 0, sizeof(outputs));
|
||||
Pass2EncodeNFrames(&stats_buf, 10, 1, &outputs[0]);
|
||||
DecodeNFrames(&outputs[0], 10);
|
||||
FreeBitstreamBuffers(&outputs[0], 10);
|
||||
}
|
||||
|
||||
TEST_F(SvcTest, TwoPassEncode2TemporalLayersWithMultipleFrameContexts) {
|
||||
// First pass encode
|
||||
std::string stats_buf;
|
||||
vpx_svc_set_options(&svc_, "scale-factors=1/1");
|
||||
svc_.temporal_layers = 2;
|
||||
Pass1EncodeNFrames(10, 1, &stats_buf);
|
||||
|
||||
// Second pass encode
|
||||
codec_enc_.g_pass = VPX_RC_LAST_PASS;
|
||||
svc_.temporal_layers = 2;
|
||||
codec_enc_.g_error_resilient = 0;
|
||||
vpx_svc_set_options(&svc_,
|
||||
"auto-alt-refs=1 scale-factors=1/1 "
|
||||
"multi-frame-contexts=1");
|
||||
vpx_fixed_buf outputs[10];
|
||||
memset(&outputs[0], 0, sizeof(outputs));
|
||||
Pass2EncodeNFrames(&stats_buf, 10, 1, &outputs[0]);
|
||||
DecodeNFrames(&outputs[0], 10);
|
||||
FreeBitstreamBuffers(&outputs[0], 10);
|
||||
}
|
||||
|
||||
TEST_F(SvcTest, TwoPassEncode2TemporalLayersDecodeBaseLayer) {
|
||||
// First pass encode
|
||||
std::string stats_buf;
|
||||
vpx_svc_set_options(&svc_, "scale-factors=1/1");
|
||||
svc_.temporal_layers = 2;
|
||||
Pass1EncodeNFrames(10, 1, &stats_buf);
|
||||
|
||||
// Second pass encode
|
||||
codec_enc_.g_pass = VPX_RC_LAST_PASS;
|
||||
svc_.temporal_layers = 2;
|
||||
vpx_svc_set_options(&svc_, "auto-alt-refs=1 scale-factors=1/1");
|
||||
vpx_fixed_buf outputs[10];
|
||||
memset(&outputs[0], 0, sizeof(outputs));
|
||||
Pass2EncodeNFrames(&stats_buf, 10, 1, &outputs[0]);
|
||||
|
||||
vpx_fixed_buf base_layer[5];
|
||||
for (int i = 0; i < 5; ++i) base_layer[i] = outputs[i * 2];
|
||||
|
||||
DecodeNFrames(&base_layer[0], 5);
|
||||
FreeBitstreamBuffers(&outputs[0], 10);
|
||||
}
|
||||
|
||||
TEST_F(SvcTest,
|
||||
TwoPassEncode2TemporalLayersWithMultipleFrameContextsDecodeBaseLayer) {
|
||||
// First pass encode
|
||||
std::string stats_buf;
|
||||
vpx_svc_set_options(&svc_, "scale-factors=1/1");
|
||||
svc_.temporal_layers = 2;
|
||||
Pass1EncodeNFrames(10, 1, &stats_buf);
|
||||
|
||||
// Second pass encode
|
||||
codec_enc_.g_pass = VPX_RC_LAST_PASS;
|
||||
svc_.temporal_layers = 2;
|
||||
codec_enc_.g_error_resilient = 0;
|
||||
vpx_svc_set_options(&svc_,
|
||||
"auto-alt-refs=1 scale-factors=1/1 "
|
||||
"multi-frame-contexts=1");
|
||||
vpx_fixed_buf outputs[10];
|
||||
memset(&outputs[0], 0, sizeof(outputs));
|
||||
Pass2EncodeNFrames(&stats_buf, 10, 1, &outputs[0]);
|
||||
|
||||
vpx_fixed_buf base_layer[5];
|
||||
for (int i = 0; i < 5; ++i) base_layer[i] = outputs[i * 2];
|
||||
|
||||
DecodeNFrames(&base_layer[0], 5);
|
||||
FreeBitstreamBuffers(&outputs[0], 10);
|
||||
}
|
||||
|
||||
TEST_F(SvcTest, TwoPassEncode2TemporalLayersWithTiles) {
|
||||
// First pass encode
|
||||
std::string stats_buf;
|
||||
vpx_svc_set_options(&svc_, "scale-factors=1/1");
|
||||
svc_.temporal_layers = 2;
|
||||
Pass1EncodeNFrames(10, 1, &stats_buf);
|
||||
|
||||
// Second pass encode
|
||||
codec_enc_.g_pass = VPX_RC_LAST_PASS;
|
||||
svc_.temporal_layers = 2;
|
||||
vpx_svc_set_options(&svc_, "auto-alt-refs=1 scale-factors=1/1");
|
||||
codec_enc_.g_w = 704;
|
||||
codec_enc_.g_h = 144;
|
||||
tile_columns_ = 1;
|
||||
tile_rows_ = 1;
|
||||
vpx_fixed_buf outputs[10];
|
||||
memset(&outputs[0], 0, sizeof(outputs));
|
||||
Pass2EncodeNFrames(&stats_buf, 10, 1, &outputs[0]);
|
||||
DecodeNFrames(&outputs[0], 10);
|
||||
FreeBitstreamBuffers(&outputs[0], 10);
|
||||
}
|
||||
|
||||
TEST_F(SvcTest, TwoPassEncode2TemporalLayersWithMultipleFrameContextsAndTiles) {
|
||||
// First pass encode
|
||||
std::string stats_buf;
|
||||
vpx_svc_set_options(&svc_, "scale-factors=1/1");
|
||||
svc_.temporal_layers = 2;
|
||||
Pass1EncodeNFrames(10, 1, &stats_buf);
|
||||
|
||||
// Second pass encode
|
||||
codec_enc_.g_pass = VPX_RC_LAST_PASS;
|
||||
svc_.temporal_layers = 2;
|
||||
codec_enc_.g_error_resilient = 0;
|
||||
codec_enc_.g_w = 704;
|
||||
codec_enc_.g_h = 144;
|
||||
tile_columns_ = 1;
|
||||
tile_rows_ = 1;
|
||||
vpx_svc_set_options(&svc_,
|
||||
"auto-alt-refs=1 scale-factors=1/1 "
|
||||
"multi-frame-contexts=1");
|
||||
vpx_fixed_buf outputs[10];
|
||||
memset(&outputs[0], 0, sizeof(outputs));
|
||||
Pass2EncodeNFrames(&stats_buf, 10, 1, &outputs[0]);
|
||||
DecodeNFrames(&outputs[0], 10);
|
||||
FreeBitstreamBuffers(&outputs[0], 10);
|
||||
}
|
||||
|
||||
} // namespace
|
||||
} // namespace svc_test
|
||||
|
|
|
@ -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_
|
|
@ -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
|
|
@ -3,14 +3,16 @@ LIBVPX_TEST_SRCS-yes += test-data.mk
|
|||
# Encoder test source
|
||||
LIBVPX_TEST_DATA-$(CONFIG_ENCODERS) += hantro_collage_w352h288.yuv
|
||||
LIBVPX_TEST_DATA-$(CONFIG_ENCODERS) += hantro_odd.yuv
|
||||
LIBVPX_TEST_DATA-$(CONFIG_ENCODERS) += desktop_office1.1280_720-020.yuv
|
||||
LIBVPX_TEST_DATA-$(CONFIG_ENCODERS) += slides_code_term_web_plot.1920_1080.yuv
|
||||
|
||||
LIBVPX_TEST_DATA-$(CONFIG_ENCODERS) += park_joy_90p_10_420.y4m
|
||||
LIBVPX_TEST_DATA-$(CONFIG_ENCODERS) += park_joy_90p_10_422.y4m
|
||||
LIBVPX_TEST_DATA-$(CONFIG_ENCODERS) += park_joy_90p_10_444.y4m
|
||||
LIBVPX_TEST_DATA-$(CONFIG_ENCODERS) += park_joy_90p_10_420_20f.y4m
|
||||
LIBVPX_TEST_DATA-$(CONFIG_ENCODERS) += park_joy_90p_10_422_20f.y4m
|
||||
LIBVPX_TEST_DATA-$(CONFIG_ENCODERS) += park_joy_90p_10_444_20f.y4m
|
||||
LIBVPX_TEST_DATA-$(CONFIG_ENCODERS) += park_joy_90p_10_440.yuv
|
||||
LIBVPX_TEST_DATA-$(CONFIG_ENCODERS) += park_joy_90p_12_420.y4m
|
||||
LIBVPX_TEST_DATA-$(CONFIG_ENCODERS) += park_joy_90p_12_422.y4m
|
||||
LIBVPX_TEST_DATA-$(CONFIG_ENCODERS) += park_joy_90p_12_444.y4m
|
||||
LIBVPX_TEST_DATA-$(CONFIG_ENCODERS) += park_joy_90p_12_420_20f.y4m
|
||||
LIBVPX_TEST_DATA-$(CONFIG_ENCODERS) += park_joy_90p_12_422_20f.y4m
|
||||
LIBVPX_TEST_DATA-$(CONFIG_ENCODERS) += park_joy_90p_12_444_20f.y4m
|
||||
LIBVPX_TEST_DATA-$(CONFIG_ENCODERS) += park_joy_90p_12_440.yuv
|
||||
LIBVPX_TEST_DATA-$(CONFIG_ENCODERS) += park_joy_90p_8_420_a10-1.y4m
|
||||
LIBVPX_TEST_DATA-$(CONFIG_ENCODERS) += park_joy_90p_8_420.y4m
|
||||
|
@ -734,8 +736,12 @@ endif # CONFIG_VP9_HIGHBITDEPTH
|
|||
# Invalid files for testing libvpx error checking.
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP8_DECODER) += invalid-bug-1443.ivf
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP8_DECODER) += invalid-bug-1443.ivf.res
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP8_DECODER) += invalid-token-partition.ivf
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP8_DECODER) += invalid-token-partition.ivf.res
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP8_DECODER) += invalid-vp80-00-comprehensive-018.ivf.2kf_0x6.ivf
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP8_DECODER) += invalid-vp80-00-comprehensive-018.ivf.2kf_0x6.ivf.res
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP8_DECODER) += invalid-vp80-00-comprehensive-s17661_r01-05_b6-.ivf
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP8_DECODER) += invalid-vp80-00-comprehensive-s17661_r01-05_b6-.ivf.res
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += invalid-vp90-01-v3.webm
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += invalid-vp90-01-v3.webm.res
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += invalid-vp90-02-v2.webm
|
||||
|
@ -783,8 +789,13 @@ LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += invalid-vp90-2-07-frame_parallel-2.web
|
|||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += invalid-vp90-2-07-frame_parallel-3.webm
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += invalid-crbug-629481.webm
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += invalid-crbug-629481.webm.res
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += invalid-crbug-1558.ivf
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += invalid-crbug-1558.ivf.res
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += invalid-crbug-1562.ivf
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += invalid-crbug-1562.ivf.res
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += invalid-crbug-667044.webm
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += invalid-crbug-667044.webm.res
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += crbug-1539.rawfile
|
||||
|
||||
ifeq ($(CONFIG_DECODE_PERF_TESTS),yes)
|
||||
# Encode / Decode test
|
||||
|
|
|
@ -17,13 +17,13 @@ df1a1453feb3c00d7d89746c7003b4163523bff3 *invalid-vp90-03-v3.webm
|
|||
d637297561dd904eb2c97a9015deeb31c4a1e8d2 *invalid-vp90-2-08-tile_1x4_frame_parallel_all_key.webm
|
||||
3a204bdbeaa3c6458b77bcebb8366d107267f55d *invalid-vp90-2-08-tile_1x4_frame_parallel_all_key.webm.res
|
||||
9aa21d8b2cb9d39abe8a7bb6032dc66955fb4342 *noisy_clip_640_360.y4m
|
||||
a432f96ff0a787268e2f94a8092ab161a18d1b06 *park_joy_90p_10_420.y4m
|
||||
0b194cc312c3a2e84d156a221b0a5eb615dfddc5 *park_joy_90p_10_422.y4m
|
||||
ff0e0a21dc2adc95b8c1b37902713700655ced17 *park_joy_90p_10_444.y4m
|
||||
0936b837708ae68c034719f8e07596021c2c214f *park_joy_90p_10_420_20f.y4m
|
||||
5727a853c083c1099f837d27967bc1322d50ed4f *park_joy_90p_10_422_20f.y4m
|
||||
e13489470ef8e8b2a871a5640d795a42a39be58d *park_joy_90p_10_444_20f.y4m
|
||||
c934da6fb8cc54ee2a8c17c54cf6076dac37ead0 *park_joy_90p_10_440.yuv
|
||||
614c32ae1eca391e867c70d19974f0d62664dd99 *park_joy_90p_12_420.y4m
|
||||
c92825f1ea25c5c37855083a69faac6ac4641a9e *park_joy_90p_12_422.y4m
|
||||
b592189b885b6cc85db55cc98512a197d73d3b34 *park_joy_90p_12_444.y4m
|
||||
79b0dc1784635a7f291e21c4e8d66a29c496ab99 *park_joy_90p_12_420_20f.y4m
|
||||
9cf22b0f809f7464c8b9058f0cfa9d905921cbd1 *park_joy_90p_12_422_20f.y4m
|
||||
22b2a4abaecc4a9ade6bb503d25fb82367947e85 *park_joy_90p_12_444_20f.y4m
|
||||
82c1bfcca368c2f22bad7d693d690d5499ecdd11 *park_joy_90p_12_440.yuv
|
||||
b9e1e90aece2be6e2c90d89e6ab2372d5f8c792d *park_joy_90p_8_420_a10-1.y4m
|
||||
4e0eb61e76f0684188d9bc9f3ce61f6b6b77bb2c *park_joy_90p_8_420.y4m
|
||||
|
@ -852,5 +852,16 @@ e402cbbf9e550ae017a1e9f1f73931c1d18474e8 *invalid-crbug-667044.webm
|
|||
d3964f9dad9f60363c81b688324d95b4ec7c8038 *invalid-crbug-667044.webm.res
|
||||
fd9df7f3f6992af1d7a9dde975c9a0d6f28c053d *invalid-bug-1443.ivf
|
||||
fd3020fa6e9ca5966206738654c97dec313b0a95 *invalid-bug-1443.ivf.res
|
||||
1a0e405606939f2febab1a21b30c37cb8f2c8cb1 *invalid-token-partition.ivf
|
||||
90a8a95e7024f015b87f5483a65036609b3d1b74 *invalid-token-partition.ivf.res
|
||||
17696cd21e875f1d6e5d418cbf89feab02c8850a *vp90-2-22-svc_1280x720_1.webm
|
||||
e2f9e1e47a791b4e939a9bdc50bf7a25b3761f77 *vp90-2-22-svc_1280x720_1.webm.md5
|
||||
a0fbbbc5dd50fd452096f4455a58c1a8c9f66697 *invalid-vp80-00-comprehensive-s17661_r01-05_b6-.ivf
|
||||
a61774cf03fc584bd9f0904fc145253bb8ea6c4c *invalid-vp80-00-comprehensive-s17661_r01-05_b6-.ivf.res
|
||||
894fae3afee0290546590823974203ab4b8abd95 *crbug-1539.rawfile
|
||||
f1026c03efd5da21b381c8eb21f0d64e6d7e4ba3 *invalid-crbug-1558.ivf
|
||||
eb198c25f861c3fe2cbd310de11eb96843019345 *invalid-crbug-1558.ivf.res
|
||||
c62b005a9fd32c36a1b3f67de6840330f9915e34 *invalid-crbug-1562.ivf
|
||||
f0cd8389948ad16085714d96567612136f6a46c5 *invalid-crbug-1562.ivf.res
|
||||
bac455906360b45338a16dd626ac5f19bc36a307 *desktop_office1.1280_720-020.yuv
|
||||
094be4b80fa30bd227149ea16ab6476d549ea092 *slides_code_term_web_plot.1920_1080.yuv
|
||||
|
|
|
@ -1,4 +1,6 @@
|
|||
LIBVPX_TEST_SRCS-yes += acm_random.h
|
||||
LIBVPX_TEST_SRCS-yes += bench.h
|
||||
LIBVPX_TEST_SRCS-yes += bench.cc
|
||||
LIBVPX_TEST_SRCS-yes += buffer.h
|
||||
LIBVPX_TEST_SRCS-yes += clear_system_state.h
|
||||
LIBVPX_TEST_SRCS-yes += codec_factory.h
|
||||
|
@ -22,7 +24,8 @@ LIBVPX_TEST_SRCS-$(CONFIG_ENCODERS) += ../y4minput.h ../y4minput.c
|
|||
LIBVPX_TEST_SRCS-$(CONFIG_ENCODERS) += altref_test.cc
|
||||
LIBVPX_TEST_SRCS-$(CONFIG_ENCODERS) += aq_segment_test.cc
|
||||
LIBVPX_TEST_SRCS-$(CONFIG_ENCODERS) += alt_ref_aq_segment_test.cc
|
||||
LIBVPX_TEST_SRCS-$(CONFIG_ENCODERS) += datarate_test.cc
|
||||
LIBVPX_TEST_SRCS-$(CONFIG_ENCODERS) += vp8_datarate_test.cc
|
||||
LIBVPX_TEST_SRCS-$(CONFIG_ENCODERS) += vp9_datarate_test.cc
|
||||
LIBVPX_TEST_SRCS-$(CONFIG_ENCODERS) += encode_api_test.cc
|
||||
LIBVPX_TEST_SRCS-$(CONFIG_ENCODERS) += error_resilience_test.cc
|
||||
LIBVPX_TEST_SRCS-$(CONFIG_ENCODERS) += i420_video_source.h
|
||||
|
@ -46,9 +49,15 @@ LIBVPX_TEST_SRCS-$(CONFIG_VP9_ENCODER) += cpu_speed_test.cc
|
|||
LIBVPX_TEST_SRCS-$(CONFIG_VP9_ENCODER) += frame_size_tests.cc
|
||||
LIBVPX_TEST_SRCS-$(CONFIG_VP9_ENCODER) += vp9_lossless_test.cc
|
||||
LIBVPX_TEST_SRCS-$(CONFIG_VP9_ENCODER) += vp9_end_to_end_test.cc
|
||||
LIBVPX_TEST_SRCS-$(CONFIG_VP9_ENCODER) += decode_corrupted.cc
|
||||
LIBVPX_TEST_SRCS-$(CONFIG_VP9_ENCODER) += vp9_ethread_test.cc
|
||||
LIBVPX_TEST_SRCS-$(CONFIG_VP9_ENCODER) += vp9_motion_vector_test.cc
|
||||
LIBVPX_TEST_SRCS-$(CONFIG_VP9_ENCODER) += level_test.cc
|
||||
LIBVPX_TEST_SRCS-$(CONFIG_VP9_ENCODER) += svc_datarate_test.cc
|
||||
LIBVPX_TEST_SRCS-$(CONFIG_VP9_ENCODER) += svc_test.cc
|
||||
LIBVPX_TEST_SRCS-$(CONFIG_VP9_ENCODER) += svc_test.h
|
||||
LIBVPX_TEST_SRCS-$(CONFIG_VP9_ENCODER) += svc_end_to_end_test.cc
|
||||
LIBVPX_TEST_SRCS-$(CONFIG_VP9_ENCODER) += timestamp_test.cc
|
||||
|
||||
LIBVPX_TEST_SRCS-yes += decode_test_driver.cc
|
||||
LIBVPX_TEST_SRCS-yes += decode_test_driver.h
|
||||
|
@ -67,6 +76,7 @@ LIBWEBM_PARSER_SRCS += ../third_party/libwebm/mkvparser/mkvparser.cc
|
|||
LIBWEBM_PARSER_SRCS += ../third_party/libwebm/mkvparser/mkvreader.cc
|
||||
LIBWEBM_PARSER_SRCS += ../third_party/libwebm/mkvparser/mkvparser.h
|
||||
LIBWEBM_PARSER_SRCS += ../third_party/libwebm/mkvparser/mkvreader.h
|
||||
LIBWEBM_PARSER_SRCS += ../third_party/libwebm/common/webmids.h
|
||||
LIBVPX_TEST_SRCS-$(CONFIG_DECODERS) += $(LIBWEBM_PARSER_SRCS)
|
||||
LIBVPX_TEST_SRCS-$(CONFIG_DECODERS) += ../tools_common.h
|
||||
LIBVPX_TEST_SRCS-$(CONFIG_DECODERS) += ../webmdec.cc
|
||||
|
@ -161,7 +171,7 @@ LIBVPX_TEST_SRCS-$(CONFIG_VP9_ENCODER) += hadamard_test.cc
|
|||
LIBVPX_TEST_SRCS-$(CONFIG_VP9_ENCODER) += minmax_test.cc
|
||||
LIBVPX_TEST_SRCS-$(CONFIG_VP9_ENCODER) += vp9_scale_test.cc
|
||||
ifneq ($(CONFIG_REALTIME_ONLY),yes)
|
||||
LIBVPX_TEST_SRCS-$(CONFIG_VP9_ENCODER) += temporal_filter_test.cc
|
||||
LIBVPX_TEST_SRCS-$(CONFIG_VP9_ENCODER) += yuv_temporal_filter_test.cc
|
||||
endif
|
||||
LIBVPX_TEST_SRCS-$(CONFIG_VP9_ENCODER) += variance_test.cc
|
||||
LIBVPX_TEST_SRCS-$(CONFIG_VP9_ENCODER) += vp9_block_error_test.cc
|
||||
|
@ -169,7 +179,6 @@ LIBVPX_TEST_SRCS-$(CONFIG_VP9_ENCODER) += vp9_quantize_test.cc
|
|||
LIBVPX_TEST_SRCS-$(CONFIG_VP9_ENCODER) += vp9_subtract_test.cc
|
||||
|
||||
ifeq ($(CONFIG_VP9_ENCODER),yes)
|
||||
LIBVPX_TEST_SRCS-$(CONFIG_SPATIAL_SVC) += svc_test.cc
|
||||
LIBVPX_TEST_SRCS-$(CONFIG_INTERNAL_STATS) += blockiness_test.cc
|
||||
LIBVPX_TEST_SRCS-$(CONFIG_INTERNAL_STATS) += consistency_test.cc
|
||||
endif
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue