Update upstream source from tag 'upstream/1.10.0'
Update to upstream version '1.10.0'
with Debian dir 5583d8988553e0dc02f5066a827764ba75d48f44
Sebastian Ramacher
2 years ago
11 | 11 | Elliott Karpilovsky <elliottk@google.com> |
12 | 12 | Erik Niemeyer <erik.a.niemeyer@intel.com> <erik.a.niemeyer@gmail.com> |
13 | 13 | Fyodor Kyslov <kyslov@google.com> |
14 | Gregor Jasny <gjasny@gmail.com> | |
15 | Gregor Jasny <gjasny@gmail.com> <gjasny@googlemail.com> | |
14 | 16 | Guillaume Martres <gmartres@google.com> <smarter3@gmail.com> |
15 | 17 | Hangyu Kuang <hkuang@google.com> |
16 | 18 | Hui Su <huisu@google.com> |
36 | 36 | Clement Courbet <courbet@google.com> |
37 | 37 | Daniele Castagna <dcastagna@chromium.org> |
38 | 38 | Daniel Kang <ddkang@google.com> |
39 | Daniel Sommermann <dcsommer@gmail.com> | |
39 | 40 | Dan Zhu <zxdan@google.com> |
40 | 41 | Deb Mukherjee <debargha@google.com> |
41 | 42 | Deepa K G <deepa.kg@ittiam.com> |
72 | 73 | Jacek Caban <cjacek@gmail.com> |
73 | 74 | Jacky Chen <jackychen@google.com> |
74 | 75 | James Berry <jamesberry@google.com> |
76 | James Touton <bekenn@gmail.com> | |
75 | 77 | James Yu <james.yu@linaro.org> |
76 | 78 | James Zern <jzern@google.com> |
77 | 79 | Jan Gerber <j@mailb.org> |
81 | 83 | Jeff Faust <jfaust@google.com> |
82 | 84 | Jeff Muizelaar <jmuizelaar@mozilla.com> |
83 | 85 | Jeff Petkau <jpet@chromium.org> |
86 | Jeremy Leconte <jleconte@google.com> | |
84 | 87 | Jerome Jiang <jianj@google.com> |
85 | 88 | Jia Jia <jia.jia@linaro.org> |
86 | 89 | Jian Zhou <zhoujian@google.com> |
87 | 90 | Jim Bankoski <jimbankoski@google.com> |
91 | jinbo <jinbo-hf@loongson.cn> | |
88 | 92 | Jingning Han <jingning@google.com> |
93 | Joel Fernandes <joelaf@google.com> | |
89 | 94 | Joey Parrish <joeyparrish@google.com> |
90 | 95 | Johann Koenig <johannkoenig@google.com> |
91 | 96 | John Koleszar <jkoleszar@google.com> |
0 | 2021-03-09 v1.10.0 "Ruddy Duck" | |
1 | This maintenance release adds support for darwin20 and new codec controls, as | |
2 | well as numerous bug fixes. | |
3 | ||
4 | - Upgrading: | |
5 | New codec control is added to disable loopfilter for VP9. | |
6 | ||
7 | New encoder control is added to disable feature to increase Q on overshoot | |
8 | detection for CBR. | |
9 | ||
10 | Configure support for darwin20 is added. | |
11 | ||
12 | New codec control is added for VP9 rate control. The control ID of this | |
13 | interface is VP9E_SET_EXTERNAL_RATE_CONTROL. To make VP9 use a customized | |
14 | external rate control model, users will have to implement each callback | |
15 | function in vpx_rc_funcs_t and register them using libvpx API | |
16 | vpx_codec_control_() with the control ID. | |
17 | ||
18 | - Enhancement: | |
19 | Use -std=gnu++11 instead of -std=c++11 for c++ files. | |
20 | ||
21 | - Bug fixes: | |
22 | Override assembler with --as option of configure for MSVS. | |
23 | Fix several compilation issues with gcc 4.8.5. | |
24 | Fix to resetting rate control for temporal layers. | |
25 | Fix to the rate control stats of SVC example encoder when number of spatial | |
26 | layers is 1. | |
27 | Fix to reusing motion vectors from the base spatial layer in SVC. | |
28 | 2 pass related flags removed from SVC example encoder. | |
29 | ||
0 | 30 | 2020-07-29 v1.9.0 "Quacking Duck" |
1 | 31 | This release adds support for NV12, a separate library for rate control, as |
2 | 32 | well as incremental improvements. |
0 | README - 20 July 2020 | |
0 | README - 08 March 2021 | |
1 | 1 | |
2 | 2 | Welcome to the WebM VP8/VP9 Codec SDK! |
3 | 3 | |
9 | 9 | 1. Prerequisites |
10 | 10 | |
11 | 11 | * All x86 targets require the Yasm[1] assembler be installed[2]. |
12 | * All Windows builds require that Cygwin[3] be installed. | |
13 | * Building the documentation requires Doxygen[4]. If you do not | |
12 | * All Windows builds require that Cygwin[3] or MSYS2[4] be installed. | |
13 | * Building the documentation requires Doxygen[5]. If you do not | |
14 | 14 | have this package, the install-docs option will be disabled. |
15 | * Downloading the data for the unit tests requires curl[5] and sha1sum. | |
15 | * Downloading the data for the unit tests requires curl[6] and sha1sum. | |
16 | 16 | sha1sum is provided via the GNU coreutils, installed by default on |
17 | 17 | many *nix platforms, as well as MinGW and Cygwin. If coreutils is not |
18 | 18 | available, a compatible version of sha1sum can be built from |
19 | source[6]. These requirements are optional if not running the unit | |
19 | source[7]. These requirements are optional if not running the unit | |
20 | 20 | tests. |
21 | 21 | |
22 | 22 | [1]: http://www.tortall.net/projects/yasm |
25 | 25 | yasm-<version>-<arch>.exe to yasm.exe and place it in: |
26 | 26 | Program Files (x86)/Microsoft Visual Studio/2017/<level>/Common7/Tools/ |
27 | 27 | [3]: http://www.cygwin.com |
28 | [4]: http://www.doxygen.org | |
29 | [5]: http://curl.haxx.se | |
30 | [6]: http://www.microbrew.org/tools/md5sha1sum/ | |
28 | [4]: http://www.msys2.org/ | |
29 | [5]: http://www.doxygen.org | |
30 | [6]: http://curl.haxx.se | |
31 | [7]: http://www.microbrew.org/tools/md5sha1sum/ | |
31 | 32 | |
32 | 33 | 2. Out-of-tree builds |
33 | 34 | Out of tree builds are a supported method of building the application. For |
61 | 62 | |
62 | 63 | arm64-android-gcc |
63 | 64 | arm64-darwin-gcc |
65 | arm64-darwin20-gcc | |
64 | 66 | arm64-linux-gcc |
65 | 67 | arm64-win64-gcc |
66 | 68 | arm64-win64-vs15 |
112 | 114 | x86_64-darwin17-gcc |
113 | 115 | x86_64-darwin18-gcc |
114 | 116 | x86_64-darwin19-gcc |
117 | x86_64-darwin20-gcc | |
115 | 118 | x86_64-iphonesimulator-gcc |
116 | 119 | x86_64-linux-gcc |
117 | 120 | x86_64-linux-icc |
146 | 146 | $(BUILD_PFX)%_vsx.c.d: CFLAGS += -maltivec -mvsx |
147 | 147 | $(BUILD_PFX)%_vsx.c.o: CFLAGS += -maltivec -mvsx |
148 | 148 | |
149 | # MIPS | |
150 | $(BUILD_PFX)%_msa.c.d: CFLAGS += -mmsa | |
151 | $(BUILD_PFX)%_msa.c.o: CFLAGS += -mmsa | |
152 | ||
149 | 153 | $(BUILD_PFX)%.c.d: %.c |
150 | 154 | $(if $(quiet),@echo " [DEP] $@") |
151 | 155 | $(qexec)mkdir -p $(dir $@) |
261 | 261 | source_path="`pwd`" |
262 | 262 | disable_feature source_path_used |
263 | 263 | fi |
264 | # Makefiles greedily process the '#' character as a comment, even if it is | |
265 | # inside quotes. So, this character must be escaped in all paths in Makefiles. | |
266 | source_path_mk=$(echo $source_path | sed -e 's;\#;\\\#;g') | |
264 | 267 | |
265 | 268 | if test ! -z "$TMPDIR" ; then |
266 | 269 | TMPDIRx="${TMPDIR}" |
480 | 483 | |
481 | 484 | cat >> $1 << EOF |
482 | 485 | # This file automatically generated by configure. Do not edit! |
483 | SRC_PATH="$source_path" | |
484 | SRC_PATH_BARE=$source_path | |
486 | SRC_PATH="$source_path_mk" | |
487 | SRC_PATH_BARE=$source_path_mk | |
485 | 488 | BUILD_PFX=${BUILD_PFX} |
486 | 489 | TOOLCHAIN=${toolchain} |
487 | ASM_CONVERSION=${asm_conversion_cmd:-${source_path}/build/make/ads2gas.pl} | |
490 | ASM_CONVERSION=${asm_conversion_cmd:-${source_path_mk}/build/make/ads2gas.pl} | |
488 | 491 | GEN_VCPROJ=${gen_vcproj_cmd} |
489 | 492 | MSVS_ARCH_DIR=${msvs_arch_dir} |
490 | 493 | |
770 | 773 | tgt_isa=x86_64 |
771 | 774 | tgt_os=`echo $gcctarget | sed 's/.*\(darwin1[0-9]\).*/\1/'` |
772 | 775 | ;; |
776 | *darwin20*) | |
777 | tgt_isa=`uname -m` | |
778 | tgt_os=`echo $gcctarget | sed 's/.*\(darwin2[0-9]\).*/\1/'` | |
779 | ;; | |
773 | 780 | x86_64*mingw32*) |
774 | 781 | tgt_os=win64 |
775 | 782 | ;; |
844 | 851 | # Handle darwin variants. Newer SDKs allow targeting older |
845 | 852 | # platforms, so use the newest one available. |
846 | 853 | case ${toolchain} in |
847 | arm*-darwin*) | |
854 | arm*-darwin-*) | |
848 | 855 | add_cflags "-miphoneos-version-min=${IOS_VERSION_MIN}" |
849 | 856 | iphoneos_sdk_dir="$(show_darwin_sdk_path iphoneos)" |
850 | 857 | if [ -d "${iphoneos_sdk_dir}" ]; then |
852 | 859 | add_ldflags "-isysroot ${iphoneos_sdk_dir}" |
853 | 860 | fi |
854 | 861 | ;; |
855 | x86*-darwin*) | |
862 | *-darwin*) | |
856 | 863 | osx_sdk_dir="$(show_darwin_sdk_path macosx)" |
857 | 864 | if [ -d "${osx_sdk_dir}" ]; then |
858 | 865 | add_cflags "-isysroot ${osx_sdk_dir}" |
909 | 916 | *-darwin19-*) |
910 | 917 | add_cflags "-mmacosx-version-min=10.15" |
911 | 918 | add_ldflags "-mmacosx-version-min=10.15" |
919 | ;; | |
920 | *-darwin20-*) | |
921 | add_cflags "-mmacosx-version-min=10.16 -arch ${toolchain%%-*}" | |
922 | add_ldflags "-mmacosx-version-min=10.16 -arch ${toolchain%%-*}" | |
912 | 923 | ;; |
913 | 924 | *-iphonesimulator-*) |
914 | 925 | add_cflags "-miphoneos-version-min=${IOS_VERSION_MIN}" |
983 | 994 | fi |
984 | 995 | |
985 | 996 | enabled debug && add_asflags -g |
986 | asm_conversion_cmd="${source_path}/build/make/ads2gas.pl" | |
997 | asm_conversion_cmd="${source_path_mk}/build/make/ads2gas.pl" | |
987 | 998 | |
988 | 999 | case ${tgt_os} in |
989 | 1000 | win*) |
1005 | 1016 | # respective SDKs' limitations. Fortunately, these are all 32-bit ABIs |
1006 | 1017 | # and so can be selected as 'win32'. |
1007 | 1018 | if [ ${tgt_os} = "win32" ]; then |
1008 | asm_conversion_cmd="${source_path}/build/make/ads2armasm_ms.pl" | |
1019 | asm_conversion_cmd="${source_path_mk}/build/make/ads2armasm_ms.pl" | |
1009 | 1020 | AS_SFX=.S |
1010 | 1021 | msvs_arch_dir=arm-msvs |
1011 | 1022 | disable_feature multithread |
1083 | 1094 | soft_enable unit_tests |
1084 | 1095 | ;; |
1085 | 1096 | |
1086 | darwin*) | |
1097 | darwin) | |
1087 | 1098 | if ! enabled external_build; then |
1088 | 1099 | XCRUN_FIND="xcrun --sdk iphoneos --find" |
1089 | 1100 | CXX="$(${XCRUN_FIND} clang++)" |
1140 | 1151 | fi |
1141 | 1152 | fi |
1142 | 1153 | |
1143 | asm_conversion_cmd="${source_path}/build/make/ads2gas_apple.pl" | |
1154 | asm_conversion_cmd="${source_path_mk}/build/make/ads2gas_apple.pl" | |
1144 | 1155 | ;; |
1145 | 1156 | |
1146 | 1157 | linux*) |
1194 | 1205 | check_add_asflags -mips64r6 -mabi=64 -mhard-float -mfp64 |
1195 | 1206 | check_add_ldflags -mips64r6 -mabi=64 -mfp64 |
1196 | 1207 | ;; |
1208 | loongson3*) | |
1209 | check_cflags -march=loongson3a && soft_enable mmi \ | |
1210 | || disable_feature mmi | |
1211 | check_cflags -mmsa && soft_enable msa \ | |
1212 | || disable_feature msa | |
1213 | tgt_isa=loongson3a | |
1214 | ;; | |
1197 | 1215 | esac |
1216 | ||
1217 | if enabled mmi || enabled msa; then | |
1218 | soft_enable runtime_cpu_detect | |
1219 | fi | |
1198 | 1220 | |
1199 | 1221 | if enabled msa; then |
1200 | 1222 | # TODO(libyuv:793) |
1201 | 1223 | # The new mips functions in libyuv do not build |
1202 | 1224 | # with the toolchains we currently use for testing. |
1203 | 1225 | soft_disable libyuv |
1204 | ||
1205 | add_cflags -mmsa | |
1206 | add_asflags -mmsa | |
1207 | add_ldflags -mmsa | |
1208 | 1226 | fi |
1209 | fi | |
1210 | ||
1211 | if enabled mmi; then | |
1212 | tgt_isa=loongson3a | |
1213 | check_add_ldflags -march=loongson3a | |
1214 | 1227 | fi |
1215 | 1228 | |
1216 | 1229 | check_add_cflags -march=${tgt_isa} |
1282 | 1295 | enabled optimizations && disabled gprof && check_add_cflags -fomit-frame-pointer |
1283 | 1296 | ;; |
1284 | 1297 | vs*) |
1285 | # When building with Microsoft Visual Studio the assembler is | |
1286 | # invoked directly. Checking at configure time is unnecessary. | |
1287 | # Skip the check by setting AS arbitrarily | |
1288 | AS=msvs | |
1289 | 1298 | msvs_arch_dir=x86-msvs |
1290 | 1299 | case ${tgt_cc##vs} in |
1291 | 1300 | 14) |
156 | 156 | ;; |
157 | 157 | --lib) proj_kind="lib" |
158 | 158 | ;; |
159 | --as=*) as="${optval}" | |
160 | ;; | |
159 | 161 | --src-path-bare=*) |
160 | 162 | src_path_bare=$(fix_path "$optval") |
161 | 163 | src_path_bare=${src_path_bare%/} |
246 | 248 | case "$target" in |
247 | 249 | x86_64*) |
248 | 250 | platforms[0]="x64" |
249 | asm_Debug_cmdline="yasm -Xvc -g cv8 -f win64 ${yasmincs} "%(FullPath)"" | |
250 | asm_Release_cmdline="yasm -Xvc -f win64 ${yasmincs} "%(FullPath)"" | |
251 | asm_Debug_cmdline="${as} -Xvc -gcv8 -f win64 ${yasmincs} "%(FullPath)"" | |
252 | asm_Release_cmdline="${as} -Xvc -f win64 ${yasmincs} "%(FullPath)"" | |
251 | 253 | ;; |
252 | 254 | x86*) |
253 | 255 | platforms[0]="Win32" |
254 | asm_Debug_cmdline="yasm -Xvc -g cv8 -f win32 ${yasmincs} "%(FullPath)"" | |
255 | asm_Release_cmdline="yasm -Xvc -f win32 ${yasmincs} "%(FullPath)"" | |
256 | asm_Debug_cmdline="${as} -Xvc -gcv8 -f win32 ${yasmincs} "%(FullPath)"" | |
257 | asm_Release_cmdline="${as} -Xvc -f win32 ${yasmincs} "%(FullPath)"" | |
256 | 258 | ;; |
257 | 259 | arm64*) |
258 | 260 | platforms[0]="ARM64" |
8 | 8 | ## be found in the AUTHORS file in the root of the source tree. |
9 | 9 | ## |
10 | 10 | |
11 | if [ "$(uname -o 2>/dev/null)" = "Cygwin" ] \ | |
11 | shell_name="$(uname -o 2>/dev/null)" | |
12 | if [[ "$shell_name" = "Cygwin" || "$shell_name" = "Msys" ]] \ | |
12 | 13 | && cygpath --help >/dev/null 2>&1; then |
13 | 14 | FIXPATH='cygpath -m' |
14 | 15 | else |
314 | 314 | |
315 | 315 | sub mips() { |
316 | 316 | determine_indirection("c", @ALL_ARCHS); |
317 | ||
318 | # Assign the helper variable for each enabled extension | |
319 | foreach my $opt (@ALL_ARCHS) { | |
320 | my $opt_uc = uc $opt; | |
321 | eval "\$have_${opt}=\"flags & HAS_${opt_uc}\""; | |
322 | } | |
323 | ||
317 | 324 | common_top; |
318 | 325 | |
319 | 326 | print <<EOF; |
320 | 327 | #include "vpx_config.h" |
321 | 328 | |
322 | 329 | #ifdef RTCD_C |
330 | #include "vpx_ports/mips.h" | |
323 | 331 | static void setup_rtcd_internal(void) |
324 | 332 | { |
333 | int flags = mips_cpu_caps(); | |
334 | ||
335 | (void)flags; | |
336 | ||
325 | 337 | EOF |
326 | 338 | |
327 | 339 | set_function_pointers("c", @ALL_ARCHS); |
409 | 421 | &require(@REQUIRES); |
410 | 422 | x86; |
411 | 423 | } elsif ($opts{arch} eq 'mips32' || $opts{arch} eq 'mips64') { |
424 | my $have_dspr2 = 0; | |
425 | my $have_msa = 0; | |
426 | my $have_mmi = 0; | |
412 | 427 | @ALL_ARCHS = filter("$opts{arch}"); |
413 | 428 | open CONFIG_FILE, $opts{config} or |
414 | 429 | die "Error opening config file '$opts{config}': $!\n"; |
415 | 430 | while (<CONFIG_FILE>) { |
416 | 431 | if (/HAVE_DSPR2=yes/) { |
417 | @ALL_ARCHS = filter("$opts{arch}", qw/dspr2/); | |
418 | last; | |
432 | $have_dspr2 = 1; | |
419 | 433 | } |
420 | 434 | if (/HAVE_MSA=yes/) { |
421 | @ALL_ARCHS = filter("$opts{arch}", qw/msa/); | |
422 | last; | |
435 | $have_msa = 1; | |
423 | 436 | } |
424 | 437 | if (/HAVE_MMI=yes/) { |
425 | @ALL_ARCHS = filter("$opts{arch}", qw/mmi/); | |
426 | last; | |
438 | $have_mmi = 1; | |
427 | 439 | } |
428 | 440 | } |
429 | 441 | close CONFIG_FILE; |
442 | if ($have_dspr2 == 1) { | |
443 | @ALL_ARCHS = filter("$opts{arch}", qw/dspr2/); | |
444 | } elsif ($have_msa == 1 && $have_mmi == 1) { | |
445 | @ALL_ARCHS = filter("$opts{arch}", qw/mmi msa/); | |
446 | } elsif ($have_msa == 1) { | |
447 | @ALL_ARCHS = filter("$opts{arch}", qw/msa/); | |
448 | } elsif ($have_mmi == 1) { | |
449 | @ALL_ARCHS = filter("$opts{arch}", qw/mmi/); | |
450 | } else { | |
451 | unoptimized; | |
452 | } | |
430 | 453 | mips; |
431 | 454 | } elsif ($opts{arch} =~ /armv7\w?/) { |
432 | 455 | @ALL_ARCHS = filter(qw/neon_asm neon/); |
98 | 98 | # alphabetically by architecture, generic-gnu last. |
99 | 99 | all_platforms="${all_platforms} arm64-android-gcc" |
100 | 100 | all_platforms="${all_platforms} arm64-darwin-gcc" |
101 | all_platforms="${all_platforms} arm64-darwin20-gcc" | |
101 | 102 | all_platforms="${all_platforms} arm64-linux-gcc" |
102 | 103 | all_platforms="${all_platforms} arm64-win64-gcc" |
103 | 104 | all_platforms="${all_platforms} arm64-win64-vs15" |
149 | 150 | all_platforms="${all_platforms} x86_64-darwin17-gcc" |
150 | 151 | all_platforms="${all_platforms} x86_64-darwin18-gcc" |
151 | 152 | all_platforms="${all_platforms} x86_64-darwin19-gcc" |
153 | all_platforms="${all_platforms} x86_64-darwin20-gcc" | |
152 | 154 | all_platforms="${all_platforms} x86_64-iphonesimulator-gcc" |
153 | 155 | all_platforms="${all_platforms} x86_64-linux-gcc" |
154 | 156 | all_platforms="${all_platforms} x86_64-linux-icc" |
728 | 730 | soft_enable libyuv |
729 | 731 | ;; |
730 | 732 | *-android-*) |
731 | check_add_cxxflags -std=c++11 && soft_enable webm_io | |
733 | check_add_cxxflags -std=gnu++11 && soft_enable webm_io | |
732 | 734 | soft_enable libyuv |
733 | 735 | # GTestLog must be modified to use Android logging utilities. |
734 | 736 | ;; |
735 | 737 | *-darwin-*) |
736 | check_add_cxxflags -std=c++11 | |
738 | check_add_cxxflags -std=gnu++11 | |
737 | 739 | # iOS/ARM builds do not work with gtest. This does not match |
738 | 740 | # x86 targets. |
739 | 741 | ;; |
740 | 742 | *-iphonesimulator-*) |
741 | check_add_cxxflags -std=c++11 && soft_enable webm_io | |
743 | check_add_cxxflags -std=gnu++11 && soft_enable webm_io | |
742 | 744 | soft_enable libyuv |
743 | 745 | ;; |
744 | 746 | *-win*) |
745 | 747 | # Some mingw toolchains don't have pthread available by default. |
746 | 748 | # Treat these more like visual studio where threading in gtest |
747 | 749 | # would be disabled for the same reason. |
748 | check_add_cxxflags -std=c++11 && soft_enable unit_tests \ | |
750 | check_add_cxxflags -std=gnu++11 && soft_enable unit_tests \ | |
749 | 751 | && soft_enable webm_io |
750 | 752 | check_cxx "$@" <<EOF && soft_enable libyuv |
751 | 753 | int z; |
752 | 754 | EOF |
753 | 755 | ;; |
754 | 756 | *) |
755 | enabled pthread_h && check_add_cxxflags -std=c++11 \ | |
757 | enabled pthread_h && check_add_cxxflags -std=gnu++11 \ | |
756 | 758 | && soft_enable unit_tests |
757 | check_add_cxxflags -std=c++11 && soft_enable webm_io | |
759 | check_add_cxxflags -std=gnu++11 && soft_enable webm_io | |
758 | 760 | check_cxx "$@" <<EOF && soft_enable libyuv |
759 | 761 | int z; |
760 | 762 | EOF |
65 | 65 | ARG_DEF("k", "kf-dist", 1, "number of frames between keyframes"); |
66 | 66 | static const arg_def_t scale_factors_arg = |
67 | 67 | ARG_DEF("r", "scale-factors", 1, "scale factors (lowest to highest layer)"); |
68 | static const arg_def_t passes_arg = | |
69 | ARG_DEF("p", "passes", 1, "Number of passes (1/2)"); | |
70 | static const arg_def_t pass_arg = | |
71 | ARG_DEF(NULL, "pass", 1, "Pass to execute (1/2)"); | |
72 | static const arg_def_t fpf_name_arg = | |
73 | ARG_DEF(NULL, "fpf", 1, "First pass statistics file name"); | |
74 | 68 | static const arg_def_t min_q_arg = |
75 | 69 | ARG_DEF(NULL, "min-q", 1, "Minimum quantizer"); |
76 | 70 | static const arg_def_t max_q_arg = |
124 | 118 | &spatial_layers_arg, |
125 | 119 | &kf_dist_arg, |
126 | 120 | &scale_factors_arg, |
127 | &passes_arg, | |
128 | &pass_arg, | |
129 | &fpf_name_arg, | |
130 | 121 | &min_q_arg, |
131 | 122 | &max_q_arg, |
132 | 123 | &min_bitrate_arg, |
172 | 163 | uint32_t frames_to_skip; |
173 | 164 | struct VpxInputContext input_ctx; |
174 | 165 | stats_io_t rc_stats; |
175 | int passes; | |
176 | int pass; | |
177 | 166 | int tune_content; |
178 | 167 | int inter_layer_pred; |
179 | 168 | } AppInput; |
196 | 185 | char **argi = NULL; |
197 | 186 | char **argj = NULL; |
198 | 187 | vpx_codec_err_t res; |
199 | int passes = 0; | |
200 | int pass = 0; | |
201 | const char *fpf_file_name = NULL; | |
202 | 188 | unsigned int min_bitrate = 0; |
203 | 189 | unsigned int max_bitrate = 0; |
204 | 190 | char string_options[1024] = { 0 }; |
288 | 274 | sizeof(string_options) - strlen(string_options) - 1); |
289 | 275 | strncat(string_options, arg.val, |
290 | 276 | sizeof(string_options) - strlen(string_options) - 1); |
291 | } else if (arg_match(&arg, &passes_arg, argi)) { | |
292 | passes = arg_parse_uint(&arg); | |
293 | if (passes < 1 || passes > 2) { | |
294 | die("Error: Invalid number of passes (%d)\n", passes); | |
295 | } | |
296 | } else if (arg_match(&arg, &pass_arg, argi)) { | |
297 | pass = arg_parse_uint(&arg); | |
298 | if (pass < 1 || pass > 2) { | |
299 | die("Error: Invalid pass selected (%d)\n", pass); | |
300 | } | |
301 | } else if (arg_match(&arg, &fpf_name_arg, argi)) { | |
302 | fpf_file_name = arg.val; | |
303 | 277 | } else if (arg_match(&arg, &min_q_arg, argi)) { |
304 | 278 | strncat(string_options, " min-quantizers=", |
305 | 279 | sizeof(string_options) - strlen(string_options) - 1); |
354 | 328 | if (strlen(string_options) > 0) |
355 | 329 | vpx_svc_set_options(svc_ctx, string_options + 1); |
356 | 330 | |
357 | if (passes == 0 || passes == 1) { | |
358 | if (pass) { | |
359 | fprintf(stderr, "pass is ignored since there's only one pass\n"); | |
360 | } | |
361 | enc_cfg->g_pass = VPX_RC_ONE_PASS; | |
362 | } else { | |
363 | if (pass == 0) { | |
364 | die("pass must be specified when passes is 2\n"); | |
365 | } | |
366 | ||
367 | if (fpf_file_name == NULL) { | |
368 | die("fpf must be specified when passes is 2\n"); | |
369 | } | |
370 | ||
371 | if (pass == 1) { | |
372 | enc_cfg->g_pass = VPX_RC_FIRST_PASS; | |
373 | if (!stats_open_file(&app_input->rc_stats, fpf_file_name, 0)) { | |
374 | fatal("Failed to open statistics store"); | |
375 | } | |
376 | } else { | |
377 | enc_cfg->g_pass = VPX_RC_LAST_PASS; | |
378 | if (!stats_open_file(&app_input->rc_stats, fpf_file_name, 1)) { | |
379 | fatal("Failed to open statistics store"); | |
380 | } | |
381 | enc_cfg->rc_twopass_stats_in = stats_get(&app_input->rc_stats); | |
382 | } | |
383 | app_input->passes = passes; | |
384 | app_input->pass = pass; | |
385 | } | |
331 | enc_cfg->g_pass = VPX_RC_ONE_PASS; | |
386 | 332 | |
387 | 333 | if (enc_cfg->rc_target_bitrate > 0) { |
388 | 334 | if (min_bitrate > 0) { |
827 | 773 | vpx_codec_control(codec, VP9E_GET_SVC_LAYER_ID, layer_id); |
828 | 774 | parse_superframe_index(cx_pkt->data.frame.buf, cx_pkt->data.frame.sz, |
829 | 775 | sizes_parsed, &count); |
830 | if (enc_cfg->ss_number_layers == 1) sizes[0] = cx_pkt->data.frame.sz; | |
831 | for (sl = 0; sl < enc_cfg->ss_number_layers; ++sl) { | |
832 | sizes[sl] = 0; | |
833 | if (cx_pkt->data.frame.spatial_layer_encoded[sl]) { | |
834 | sizes[sl] = sizes_parsed[num_layers_encoded]; | |
835 | num_layers_encoded++; | |
776 | if (enc_cfg->ss_number_layers == 1) { | |
777 | sizes[0] = cx_pkt->data.frame.sz; | |
778 | } else { | |
779 | for (sl = 0; sl < enc_cfg->ss_number_layers; ++sl) { | |
780 | sizes[sl] = 0; | |
781 | if (cx_pkt->data.frame.spatial_layer_encoded[sl]) { | |
782 | sizes[sl] = sizes_parsed[num_layers_encoded]; | |
783 | num_layers_encoded++; | |
784 | } | |
836 | 785 | } |
837 | 786 | } |
838 | 787 | for (sl = 0; sl < enc_cfg->ss_number_layers; ++sl) { |
1000 | 949 | info.time_base.numerator = enc_cfg.g_timebase.num; |
1001 | 950 | info.time_base.denominator = enc_cfg.g_timebase.den; |
1002 | 951 | |
1003 | if (!(app_input.passes == 2 && app_input.pass == 1)) { | |
1004 | // We don't save the bitstream for the 1st pass on two pass rate control | |
1005 | writer = | |
1006 | vpx_video_writer_open(app_input.output_filename, kContainerIVF, &info); | |
1007 | if (!writer) | |
1008 | die("Failed to open %s for writing\n", app_input.output_filename); | |
1009 | } | |
952 | writer = | |
953 | vpx_video_writer_open(app_input.output_filename, kContainerIVF, &info); | |
954 | if (!writer) | |
955 | die("Failed to open %s for writing\n", app_input.output_filename); | |
956 | ||
1010 | 957 | #if OUTPUT_RC_STATS |
1011 | 958 | // Write out spatial layer stream. |
1012 | 959 | // TODO(marpan/jianj): allow for writing each spatial and temporal stream. |
1048 | 995 | vpx_codec_control(&encoder, VP9E_SET_NOISE_SENSITIVITY, 0); |
1049 | 996 | |
1050 | 997 | vpx_codec_control(&encoder, VP9E_SET_TUNE_CONTENT, app_input.tune_content); |
998 | ||
999 | vpx_codec_control(&encoder, VP9E_SET_DISABLE_OVERSHOOT_MAXQ_CBR, 0); | |
1000 | vpx_codec_control(&encoder, VP9E_SET_DISABLE_LOOPFILTER, 0); | |
1051 | 1001 | |
1052 | 1002 | svc_drop_frame.framedrop_mode = FULL_SUPERFRAME_DROP; |
1053 | 1003 | for (sl = 0; sl < (unsigned int)svc_ctx.spatial_layers; ++sl) |
1223 | 1173 | #endif |
1224 | 1174 | if (vpx_codec_destroy(&encoder)) |
1225 | 1175 | die_codec(&encoder, "Failed to destroy codec"); |
1226 | if (app_input.passes == 2) stats_close(&app_input.rc_stats, 1); | |
1227 | 1176 | if (writer) { |
1228 | 1177 | vpx_video_writer_close(writer); |
1229 | 1178 | } |
40 | 40 | $make -j32 |
41 | 41 | |
42 | 42 | * Build vp9 fuzzer |
43 | $ $CXX $CXXFLAGS -std=c++11 -DDECODER=vp9 \ | |
43 | $ $CXX $CXXFLAGS -std=gnu++11 -DDECODER=vp9 \ | |
44 | 44 | -fsanitize=fuzzer -I../libvpx -I. -Wl,--start-group \ |
45 | 45 | ../libvpx/examples/vpx_dec_fuzzer.cc -o ./vpx_dec_fuzzer_vp9 \ |
46 | 46 | ./libvpx.a -Wl,--end-group |
830 | 830 | } else if (strncmp(encoder->name, "vp9", 3) == 0) { |
831 | 831 | vpx_svc_extra_cfg_t svc_params; |
832 | 832 | memset(&svc_params, 0, sizeof(svc_params)); |
833 | vpx_codec_control(&codec, VP9E_SET_DISABLE_OVERSHOOT_MAXQ_CBR, 0); | |
833 | 834 | vpx_codec_control(&codec, VP8E_SET_CPUUSED, speed); |
834 | 835 | vpx_codec_control(&codec, VP9E_SET_AQ_MODE, 3); |
835 | 836 | vpx_codec_control(&codec, VP9E_SET_GF_CBR_BOOST_PCT, 0); |
839 | 840 | vpx_codec_control(&codec, VP8E_SET_STATIC_THRESHOLD, 1); |
840 | 841 | vpx_codec_control(&codec, VP9E_SET_TUNE_CONTENT, 0); |
841 | 842 | vpx_codec_control(&codec, VP9E_SET_TILE_COLUMNS, get_msb(cfg.g_threads)); |
843 | vpx_codec_control(&codec, VP9E_SET_DISABLE_LOOPFILTER, 0); | |
842 | 844 | #if ROI_MAP |
843 | 845 | set_roi_map(encoder->name, &cfg, &roi); |
844 | 846 | if (vpx_codec_control(&codec, VP9E_SET_ROI_MAP, &roi)) |
927 | 929 | // Update for short-time encoding bitrate states, for moving window |
928 | 930 | // of size rc->window, shifted by rc->window / 2. |
929 | 931 | // Ignore first window segment, due to key frame. |
932 | if (rc.window_size == 0) rc.window_size = 15; | |
930 | 933 | if (frame_cnt > rc.window_size) { |
931 | 934 | sum_bitrate += 0.001 * 8.0 * pkt->data.frame.sz * framerate; |
932 | 935 | if (frame_cnt % rc.window_size == 0) { |
375 | 375 | --ver=$$(CONFIG_VS_VERSION)\ |
376 | 376 | --proj-guid=$$($$(@:.$(VCPROJ_SFX)=).GUID)\ |
377 | 377 | --src-path-bare="$(SRC_PATH_BARE)" \ |
378 | --as=$$(AS) \ | |
378 | 379 | $$(if $$(CONFIG_STATIC_MSVCRT),--static-crt) \ |
379 | 380 | --out=$$@ $$(INTERNAL_CFLAGS) $$(CFLAGS) \ |
380 | 381 | $$(INTERNAL_LDFLAGS) $$(LDFLAGS) -l$$(CODEC_LIB) $$^ |
62 | 62 | CODEC_SRCS-yes += $(addprefix $(VP8_PREFIX),$(call enabled,VP8_CX_SRCS)) |
63 | 63 | CODEC_EXPORTS-yes += $(addprefix $(VP8_PREFIX),$(VP8_CX_EXPORTS)) |
64 | 64 | INSTALL-LIBS-yes += include/vpx/vp8.h include/vpx/vp8cx.h |
65 | INSTALL-LIBS-yes += include/vpx/vpx_ext_ratectrl.h | |
65 | 66 | INSTALL_MAPS += include/vpx/% $(SRC_PATH_BARE)/$(VP8_PREFIX)/% |
66 | 67 | CODEC_DOC_SECTIONS += vp8 vp8_encoder |
67 | 68 | endif |
86 | 87 | CODEC_SRCS-yes += $(addprefix $(VP9_PREFIX),$(call enabled,VP9_CX_SRCS)) |
87 | 88 | CODEC_EXPORTS-yes += $(addprefix $(VP9_PREFIX),$(VP9_CX_EXPORTS)) |
88 | 89 | CODEC_SRCS-yes += $(VP9_PREFIX)vp9cx.mk vpx/vp8.h vpx/vp8cx.h |
90 | CODEC_SRCS-yes += vpx/vpx_ext_ratectrl.h | |
89 | 91 | INSTALL-LIBS-yes += include/vpx/vp8.h include/vpx/vp8cx.h |
92 | INSTALL-LIBS-yes += include/vpx/vpx_ext_ratectrl.h | |
90 | 93 | INSTALL_MAPS += include/vpx/% $(SRC_PATH_BARE)/$(VP9_PREFIX)/% |
91 | CODEC_DOC_SRCS += vpx/vp8.h vpx/vp8cx.h | |
94 | CODEC_DOC_SRCS += vpx/vp8.h vpx/vp8cx.h vpx/vpx_ext_ratectrl.h | |
92 | 95 | CODEC_DOC_SECTIONS += vp9 vp9_encoder |
93 | 96 | |
94 | 97 | RC_RTC_SRCS := $(addprefix $(VP9_PREFIX),$(call enabled,VP9_CX_SRCS)) |
95 | 98 | RC_RTC_SRCS += $(VP9_PREFIX)vp9cx.mk vpx/vp8.h vpx/vp8cx.h |
99 | RC_RTC_SRCS += vpx/vpx_ext_ratectrl.h | |
96 | 100 | RC_RTC_SRCS += $(VP9_PREFIX)ratectrl_rtc.cc |
97 | 101 | RC_RTC_SRCS += $(VP9_PREFIX)ratectrl_rtc.h |
98 | 102 | INSTALL-SRCS-$(CONFIG_CODEC_SRCS) += $(VP9_PREFIX)ratectrl_rtc.cc |
227 | 231 | --ver=$(CONFIG_VS_VERSION) \ |
228 | 232 | --src-path-bare="$(SRC_PATH_BARE)" \ |
229 | 233 | --out=$@ $(CFLAGS) \ |
234 | --as=$(AS) \ | |
230 | 235 | $(filter $(SRC_PATH_BARE)/vp8/%.c, $(VCPROJ_SRCS)) \ |
231 | 236 | $(filter $(SRC_PATH_BARE)/vp8/%.h, $(VCPROJ_SRCS)) \ |
232 | 237 | $(filter $(SRC_PATH_BARE)/vp9/%.c, $(VCPROJ_SRCS)) \ |
257 | 262 | --ver=$(CONFIG_VS_VERSION) \ |
258 | 263 | --src-path-bare="$(SRC_PATH_BARE)" \ |
259 | 264 | --out=$@ $(CFLAGS) \ |
265 | --as=$(AS) \ | |
260 | 266 | $(filter $(SRC_PATH_BARE)/vp9/%.c, $(VCPROJ_SRCS)) \ |
261 | 267 | $(filter $(SRC_PATH_BARE)/vp9/%.cc, $(VCPROJ_SRCS)) \ |
262 | 268 | $(filter $(SRC_PATH_BARE)/vp9/%.h, $(VCPROJ_SRCS)) \ |
280 | 286 | LIBS-$(if yes,$(CONFIG_STATIC)) += $(BUILD_PFX)libvpx.a $(BUILD_PFX)libvpx_g.a |
281 | 287 | $(BUILD_PFX)libvpx_g.a: $(LIBVPX_OBJS) |
282 | 288 | |
289 | # Updating version info. | |
290 | # https://www.gnu.org/software/libtool/manual/libtool.html#Updating-version-info | |
291 | # For libtool: c=<current>, a=<age>, r=<revision> | |
292 | # libtool generates .so file as .so.[c-a].a.r, while -version-info c:r:a is | |
293 | # passed to libtool. | |
294 | # | |
295 | # libvpx library file is generated as libvpx.so.<MAJOR>.<MINOR>.<PATCH> | |
296 | # MAJOR = c-a, MINOR = a, PATCH = r | |
297 | # | |
298 | # To determine SO_VERSION_{MAJOR,MINOR,PATCH}, calculate c,a,r with current | |
299 | # SO_VERSION_* then follow the rules in the link to detemine the new version | |
300 | # (c1, a1, r1) and set MAJOR to [c1-a1], MINOR to a1 and PATCH to r1 | |
283 | 301 | SO_VERSION_MAJOR := 6 |
284 | SO_VERSION_MINOR := 3 | |
302 | SO_VERSION_MINOR := 4 | |
285 | 303 | SO_VERSION_PATCH := 0 |
286 | 304 | ifeq ($(filter darwin%,$(TGT_OS)),$(TGT_OS)) |
287 | 305 | LIBVPX_SO := libvpx.$(SO_VERSION_MAJOR).dylib |
415 | 433 | # YASM |
416 | 434 | $(BUILD_PFX)vpx_config.asm: $(BUILD_PFX)vpx_config.h |
417 | 435 | @echo " [CREATE] $@" |
418 | @egrep "#define [A-Z0-9_]+ [01]" $< \ | |
436 | @LC_ALL=C egrep "#define [A-Z0-9_]+ [01]" $< \ | |
419 | 437 | | awk '{print $$2 " equ " $$3}' > $@ |
420 | 438 | else |
421 | 439 | ADS2GAS=$(if $(filter yes,$(CONFIG_GCC)),| $(ASM_CONVERSION)) |
422 | 440 | $(BUILD_PFX)vpx_config.asm: $(BUILD_PFX)vpx_config.h |
423 | 441 | @echo " [CREATE] $@" |
424 | @egrep "#define [A-Z0-9_]+ [01]" $< \ | |
442 | @LC_ALL=C egrep "#define [A-Z0-9_]+ [01]" $< \ | |
425 | 443 | | awk '{print $$2 " EQU " $$3}' $(ADS2GAS) > $@ |
426 | 444 | @echo " END" $(ADS2GAS) >> $@ |
427 | 445 | CLEAN-OBJS += $(BUILD_PFX)vpx_config.asm |
489 | 507 | @echo $(LIBVPX_TEST_SRCS) | xargs -n1 echo | LC_ALL=C sort -u > $@ |
490 | 508 | CLEAN-OBJS += libvpx_test_srcs.txt |
491 | 509 | |
510 | # Attempt to download the file using curl, retrying once if it fails for a | |
511 | # partial file (18). | |
492 | 512 | $(LIBVPX_TEST_DATA): $(SRC_PATH_BARE)/test/test-data.sha1 |
493 | 513 | @echo " [DOWNLOAD] $@" |
494 | # Attempt to download the file using curl, retrying once if it fails for a | |
495 | # partial file (18). | |
496 | 514 | $(qexec)( \ |
497 | 515 | trap 'rm -f $@' INT TERM; \ |
498 | curl="curl --retry 1 -L -o $@ $(call libvpx_test_data_url,$(@F))"; \ | |
499 | $$curl; \ | |
500 | case "$$?" in \ | |
501 | 18) $$curl -C -;; \ | |
516 | curl="curl -S -s --retry 1 -L -o $@ $(call libvpx_test_data_url,$(@F))"; \ | |
517 | $$curl; ret=$$?; \ | |
518 | case "$$ret" in \ | |
519 | 18) $$curl -C - ;; \ | |
520 | *) exit $$ret ;; \ | |
502 | 521 | esac \ |
503 | 522 | ) |
504 | 523 | |
530 | 549 | --proj-guid=EC00E1EC-AF68-4D92-A255-181690D1C9B1 \ |
531 | 550 | --ver=$(CONFIG_VS_VERSION) \ |
532 | 551 | --src-path-bare="$(SRC_PATH_BARE)" \ |
552 | --as=$(AS) \ | |
533 | 553 | -D_VARIADIC_MAX=10 \ |
534 | 554 | --out=gtest.$(VCPROJ_SFX) $(SRC_PATH_BARE)/third_party/googletest/src/src/gtest-all.cc \ |
535 | 555 | -I. -I"$(SRC_PATH_BARE)/third_party/googletest/src/include" -I"$(SRC_PATH_BARE)/third_party/googletest/src" |
546 | 566 | --proj-guid=CD837F5F-52D8-4314-A370-895D614166A7 \ |
547 | 567 | --ver=$(CONFIG_VS_VERSION) \ |
548 | 568 | --src-path-bare="$(SRC_PATH_BARE)" \ |
569 | --as=$(AS) \ | |
549 | 570 | $(if $(CONFIG_STATIC_MSVCRT),--static-crt) \ |
550 | 571 | --out=$@ $(INTERNAL_CFLAGS) $(CFLAGS) \ |
551 | 572 | -I. -I"$(SRC_PATH_BARE)/third_party/googletest/src/include" \ |
568 | 589 | --proj-guid=CD837F5F-52D8-4314-A370-895D614166A7 \ |
569 | 590 | --ver=$(CONFIG_VS_VERSION) \ |
570 | 591 | --src-path-bare="$(SRC_PATH_BARE)" \ |
592 | --as=$(AS) \ | |
571 | 593 | $(if $(CONFIG_STATIC_MSVCRT),--static-crt) \ |
572 | 594 | --out=$@ $(INTERNAL_CFLAGS) $(CFLAGS) \ |
573 | 595 | -I. -I"$(SRC_PATH_BARE)/third_party/googletest/src/include" \ |
586 | 608 | -D_VARIADIC_MAX=10 \ |
587 | 609 | --proj-guid=30458F88-1BC6-4689-B41C-50F3737AAB27 \ |
588 | 610 | --ver=$(CONFIG_VS_VERSION) \ |
611 | --as=$(AS) \ | |
589 | 612 | --src-path-bare="$(SRC_PATH_BARE)" \ |
590 | 613 | $(if $(CONFIG_STATIC_MSVCRT),--static-crt) \ |
591 | 614 | --out=$@ $(INTERNAL_CFLAGS) $(CFLAGS) \ |
79 | 79 | } else if (video->frame() >= 2 && video->img()) { |
80 | 80 | vpx_image_t *current = video->img(); |
81 | 81 | vpx_image_t *previous = y4m_holder_->img(); |
82 | ASSERT_TRUE(previous != NULL); | |
82 | ASSERT_NE(previous, nullptr); | |
83 | 83 | vpx_active_map_t map = vpx_active_map_t(); |
84 | 84 | const int width = static_cast<int>(current->d_w); |
85 | 85 | const int height = static_cast<int>(current->d_h); |
61 | 61 | vpx_active_map_t map = vpx_active_map_t(); |
62 | 62 | map.cols = (kWidth + 15) / 16; |
63 | 63 | map.rows = (kHeight + 15) / 16; |
64 | map.active_map = NULL; | |
64 | map.active_map = nullptr; | |
65 | 65 | encoder->Control(VP8E_SET_ACTIVEMAP, &map); |
66 | 66 | } |
67 | 67 | } |
52 | 52 | const int clamp = vpx_setup_noise(GET_PARAM(0), noise, kNoiseSize); |
53 | 53 | uint8_t *const s = |
54 | 54 | reinterpret_cast<uint8_t *>(vpx_calloc(image_size, sizeof(*s))); |
55 | ASSERT_TRUE(s != NULL); | |
55 | ASSERT_NE(s, nullptr); | |
56 | 56 | memset(s, 99, image_size * sizeof(*s)); |
57 | 57 | |
58 | 58 | ASM_REGISTER_STATE_CHECK( |
105 | 105 | |
106 | 106 | uint8_t *const s = reinterpret_cast<uint8_t *>(vpx_calloc(image_size, 1)); |
107 | 107 | uint8_t *const d = reinterpret_cast<uint8_t *>(vpx_calloc(image_size, 1)); |
108 | ASSERT_TRUE(s != NULL); | |
109 | ASSERT_TRUE(d != NULL); | |
108 | ASSERT_NE(s, nullptr); | |
109 | ASSERT_NE(d, nullptr); | |
110 | 110 | |
111 | 111 | memset(s, 99, image_size); |
112 | 112 | memset(d, 99, image_size); |
15 | 15 | |
16 | 16 | 3) Run get_files.py to download the test files: |
17 | 17 | python get_files.py -i /path/to/test-data.sha1 -o /path/to/put/files \ |
18 | -u http://downloads.webmproject.org/test_data/libvpx | |
18 | -u https://storage.googleapis.com/downloads.webmproject.org/test_data/libvpx | |
19 | 19 | |
20 | 20 | 4) Transfer files to device using adb. Ensure you have proper permissions for |
21 | 21 | the target |
34 | 34 | class AverageTestBase : public ::testing::Test { |
35 | 35 | public: |
36 | 36 | AverageTestBase(int width, int height) |
37 | : width_(width), height_(height), source_data_(NULL), source_stride_(0), | |
38 | bit_depth_(8) {} | |
37 | : width_(width), height_(height), source_data_(nullptr), | |
38 | source_stride_(0), bit_depth_(8) {} | |
39 | 39 | |
40 | 40 | virtual void TearDown() { |
41 | 41 | vpx_free(source_data_); |
42 | source_data_ = NULL; | |
42 | source_data_ = nullptr; | |
43 | 43 | libvpx_test::ClearSystemState(); |
44 | 44 | } |
45 | 45 | |
51 | 51 | virtual void SetUp() { |
52 | 52 | source_data_ = reinterpret_cast<Pixel *>( |
53 | 53 | vpx_memalign(kDataAlignment, kDataBlockSize * sizeof(source_data_[0]))); |
54 | ASSERT_TRUE(source_data_ != NULL); | |
54 | ASSERT_NE(source_data_, nullptr); | |
55 | 55 | source_stride_ = (width_ + 31) & ~31; |
56 | 56 | bit_depth_ = 8; |
57 | 57 | rnd_.Reset(ACMRandom::DeterministicSeed()); |
151 | 151 | }; |
152 | 152 | #endif // CONFIG_VP9_HIGHBITDEPTH |
153 | 153 | |
154 | #if HAVE_NEON || HAVE_SSE2 || HAVE_MSA | |
154 | 155 | typedef void (*IntProRowFunc)(int16_t hbuf[16], uint8_t const *ref, |
155 | 156 | const int ref_stride, const int height); |
156 | 157 | |
160 | 161 | public ::testing::WithParamInterface<IntProRowParam> { |
161 | 162 | public: |
162 | 163 | IntProRowTest() |
163 | : AverageTestBase(16, GET_PARAM(0)), hbuf_asm_(NULL), hbuf_c_(NULL) { | |
164 | : AverageTestBase(16, GET_PARAM(0)), hbuf_asm_(nullptr), | |
165 | hbuf_c_(nullptr) { | |
164 | 166 | asm_func_ = GET_PARAM(1); |
165 | 167 | c_func_ = GET_PARAM(2); |
166 | 168 | } |
169 | 171 | virtual void SetUp() { |
170 | 172 | source_data_ = reinterpret_cast<uint8_t *>( |
171 | 173 | vpx_memalign(kDataAlignment, kDataBlockSize * sizeof(source_data_[0]))); |
172 | ASSERT_TRUE(source_data_ != NULL); | |
174 | ASSERT_NE(source_data_, nullptr); | |
173 | 175 | |
174 | 176 | hbuf_asm_ = reinterpret_cast<int16_t *>( |
175 | 177 | vpx_memalign(kDataAlignment, sizeof(*hbuf_asm_) * 16)); |
179 | 181 | |
180 | 182 | virtual void TearDown() { |
181 | 183 | vpx_free(source_data_); |
182 | source_data_ = NULL; | |
184 | source_data_ = nullptr; | |
183 | 185 | vpx_free(hbuf_c_); |
184 | hbuf_c_ = NULL; | |
186 | hbuf_c_ = nullptr; | |
185 | 187 | vpx_free(hbuf_asm_); |
186 | hbuf_asm_ = NULL; | |
188 | hbuf_asm_ = nullptr; | |
187 | 189 | } |
188 | 190 | |
189 | 191 | void RunComparison() { |
199 | 201 | int16_t *hbuf_asm_; |
200 | 202 | int16_t *hbuf_c_; |
201 | 203 | }; |
204 | GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(IntProRowTest); | |
202 | 205 | |
203 | 206 | typedef int16_t (*IntProColFunc)(uint8_t const *ref, const int width); |
204 | 207 | |
225 | 228 | int16_t sum_asm_; |
226 | 229 | int16_t sum_c_; |
227 | 230 | }; |
231 | GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(IntProColTest); | |
232 | #endif // HAVE_NEON || HAVE_SSE2 || HAVE_MSA | |
228 | 233 | |
229 | 234 | typedef int (*SatdFunc)(const tran_low_t *coeffs, int length); |
230 | 235 | typedef std::tuple<int, SatdFunc> SatdTestParam; |
238 | 243 | rnd_.Reset(ACMRandom::DeterministicSeed()); |
239 | 244 | src_ = reinterpret_cast<tran_low_t *>( |
240 | 245 | vpx_memalign(16, sizeof(*src_) * satd_size_)); |
241 | ASSERT_TRUE(src_ != NULL); | |
246 | ASSERT_NE(src_, nullptr); | |
242 | 247 | } |
243 | 248 | |
244 | 249 | virtual void TearDown() { |
294 | 299 | vpx_memalign(16, sizeof(*coeff_) * txfm_size_)); |
295 | 300 | dqcoeff_ = reinterpret_cast<tran_low_t *>( |
296 | 301 | vpx_memalign(16, sizeof(*dqcoeff_) * txfm_size_)); |
297 | ASSERT_TRUE(coeff_ != NULL); | |
298 | ASSERT_TRUE(dqcoeff_ != NULL); | |
302 | ASSERT_NE(coeff_, nullptr); | |
303 | ASSERT_NE(dqcoeff_, nullptr); | |
299 | 304 | } |
300 | 305 | |
301 | 306 | virtual void TearDown() { |
377 | 382 | } |
378 | 383 | #endif // CONFIG_VP9_HIGHBITDEPTH |
379 | 384 | |
385 | #if HAVE_NEON || HAVE_SSE2 || HAVE_MSA | |
380 | 386 | TEST_P(IntProRowTest, MinValue) { |
381 | 387 | FillConstant(0); |
382 | 388 | RunComparison(); |
406 | 412 | FillRandom(); |
407 | 413 | RunComparison(); |
408 | 414 | } |
415 | #endif | |
409 | 416 | |
410 | 417 | TEST_P(SatdLowbdTest, MinValue) { |
411 | 418 | const int kMin = -32640; |
43 | 43 | |
44 | 44 | static void TearDownTestSuite() { |
45 | 45 | vpx_free(source_data_); |
46 | source_data_ = NULL; | |
46 | source_data_ = nullptr; | |
47 | 47 | vpx_free(reference_data_); |
48 | reference_data_ = NULL; | |
48 | reference_data_ = nullptr; | |
49 | 49 | } |
50 | 50 | |
51 | 51 | virtual void TearDown() { libvpx_test::ClearSystemState(); } |
153 | 153 | }; |
154 | 154 | #endif // CONFIG_VP9_ENCODER |
155 | 155 | |
156 | uint8_t *BlockinessTestBase::source_data_ = NULL; | |
157 | uint8_t *BlockinessTestBase::reference_data_ = NULL; | |
156 | uint8_t *BlockinessTestBase::source_data_ = nullptr; | |
157 | uint8_t *BlockinessTestBase::reference_data_ = nullptr; | |
158 | 158 | |
159 | 159 | #if CONFIG_VP9_ENCODER |
160 | 160 | TEST_P(BlockinessVP9Test, SourceBlockierThanReference) { |
54 | 54 | class ByteAlignmentTest |
55 | 55 | : public ::testing::TestWithParam<ByteAlignmentTestParam> { |
56 | 56 | protected: |
57 | ByteAlignmentTest() : video_(NULL), decoder_(NULL), md5_file_(NULL) {} | |
57 | ByteAlignmentTest() | |
58 | : video_(nullptr), decoder_(nullptr), md5_file_(nullptr) {} | |
58 | 59 | |
59 | 60 | virtual void SetUp() { |
60 | 61 | video_ = new libvpx_test::WebMVideoSource(kVP9TestFile); |
61 | ASSERT_TRUE(video_ != NULL); | |
62 | ASSERT_NE(video_, nullptr); | |
62 | 63 | video_->Init(); |
63 | 64 | video_->Begin(); |
64 | 65 | |
65 | 66 | const vpx_codec_dec_cfg_t cfg = vpx_codec_dec_cfg_t(); |
66 | 67 | decoder_ = new libvpx_test::VP9Decoder(cfg, 0); |
67 | ASSERT_TRUE(decoder_ != NULL); | |
68 | ASSERT_NE(decoder_, nullptr); | |
68 | 69 | |
69 | 70 | OpenMd5File(kVP9Md5File); |
70 | 71 | } |
71 | 72 | |
72 | 73 | virtual void TearDown() { |
73 | if (md5_file_ != NULL) fclose(md5_file_); | |
74 | if (md5_file_ != nullptr) fclose(md5_file_); | |
74 | 75 | |
75 | 76 | delete decoder_; |
76 | 77 | delete video_; |
89 | 90 | } |
90 | 91 | |
91 | 92 | vpx_codec_err_t DecodeRemainingFrames(int byte_alignment_to_check) { |
92 | for (; video_->cxdata() != NULL; video_->Next()) { | |
93 | for (; video_->cxdata() != nullptr; video_->Next()) { | |
93 | 94 | const vpx_codec_err_t res = |
94 | 95 | decoder_->DecodeFrame(video_->cxdata(), video_->frame_size()); |
95 | 96 | if (res != VPX_CODEC_OK) return res; |
112 | 113 | const vpx_image_t *img; |
113 | 114 | |
114 | 115 | // Get decompressed data |
115 | while ((img = dec_iter.Next()) != NULL) { | |
116 | while ((img = dec_iter.Next()) != nullptr) { | |
116 | 117 | if (byte_alignment_to_check == kLegacyByteAlignment) { |
117 | 118 | CheckByteAlignment(img->planes[0], kLegacyYPlaneByteAlignment); |
118 | 119 | } else { |
127 | 128 | // TODO(fgalligan): Move the MD5 testing code into another class. |
128 | 129 | void OpenMd5File(const std::string &md5_file_name_) { |
129 | 130 | md5_file_ = libvpx_test::OpenTestDataFile(md5_file_name_); |
130 | ASSERT_TRUE(md5_file_ != NULL) | |
131 | ASSERT_NE(md5_file_, nullptr) | |
131 | 132 | << "MD5 file open failed. Filename: " << md5_file_name_; |
132 | 133 | } |
133 | 134 | |
134 | 135 | void CheckMd5(const vpx_image_t &img) { |
135 | ASSERT_TRUE(md5_file_ != NULL); | |
136 | ASSERT_NE(md5_file_, nullptr); | |
136 | 137 | char expected_md5[33]; |
137 | 138 | char junk[128]; |
138 | 139 |
28 | 28 | |
29 | 29 | void reference_pred(const Buffer<uint8_t> &pred, const Buffer<uint8_t> &ref, |
30 | 30 | int width, int height, Buffer<uint8_t> *avg) { |
31 | ASSERT_TRUE(avg->TopLeftPixel() != NULL); | |
32 | ASSERT_TRUE(pred.TopLeftPixel() != NULL); | |
33 | ASSERT_TRUE(ref.TopLeftPixel() != NULL); | |
31 | ASSERT_NE(avg->TopLeftPixel(), nullptr); | |
32 | ASSERT_NE(pred.TopLeftPixel(), nullptr); | |
33 | ASSERT_NE(ref.TopLeftPixel(), nullptr); | |
34 | 34 | |
35 | 35 | for (int y = 0; y < height; ++y) { |
36 | 36 | for (int x = 0; x < width; ++x) { |
53 | 53 | static void ClearSsim() { memset(ssim_array_, 0, kDataBufferSize / 16); } |
54 | 54 | static void TearDownTestSuite() { |
55 | 55 | vpx_free(source_data_[0]); |
56 | source_data_[0] = NULL; | |
56 | source_data_[0] = nullptr; | |
57 | 57 | vpx_free(reference_data_[0]); |
58 | reference_data_[0] = NULL; | |
58 | reference_data_[0] = nullptr; | |
59 | 59 | vpx_free(source_data_[1]); |
60 | source_data_[1] = NULL; | |
60 | source_data_[1] = nullptr; | |
61 | 61 | vpx_free(reference_data_[1]); |
62 | reference_data_[1] = NULL; | |
62 | reference_data_[1] = nullptr; | |
63 | 63 | |
64 | 64 | delete[] ssim_array_; |
65 | 65 | } |
144 | 144 | }; |
145 | 145 | #endif // CONFIG_VP9_ENCODER |
146 | 146 | |
147 | uint8_t *ConsistencyTestBase::source_data_[2] = { NULL, NULL }; | |
148 | uint8_t *ConsistencyTestBase::reference_data_[2] = { NULL, NULL }; | |
149 | Ssimv *ConsistencyTestBase::ssim_array_ = NULL; | |
147 | uint8_t *ConsistencyTestBase::source_data_[2] = { nullptr, nullptr }; | |
148 | uint8_t *ConsistencyTestBase::reference_data_[2] = { nullptr, nullptr }; | |
149 | Ssimv *ConsistencyTestBase::ssim_array_ = nullptr; | |
150 | 150 | |
151 | 151 | #if CONFIG_VP9_ENCODER |
152 | 152 | TEST_P(ConsistencyVP9Test, ConsistencyIsZero) { |
364 | 364 | |
365 | 365 | static void TearDownTestSuite() { |
366 | 366 | vpx_free(input_ - 1); |
367 | input_ = NULL; | |
367 | input_ = nullptr; | |
368 | 368 | vpx_free(output_); |
369 | output_ = NULL; | |
369 | output_ = nullptr; | |
370 | 370 | vpx_free(output_ref_); |
371 | output_ref_ = NULL; | |
371 | output_ref_ = nullptr; | |
372 | 372 | #if CONFIG_VP9_HIGHBITDEPTH |
373 | 373 | vpx_free(input16_ - 1); |
374 | input16_ = NULL; | |
374 | input16_ = nullptr; | |
375 | 375 | vpx_free(output16_); |
376 | output16_ = NULL; | |
376 | output16_ = nullptr; | |
377 | 377 | vpx_free(output16_ref_); |
378 | output16_ref_ = NULL; | |
378 | output16_ref_ = nullptr; | |
379 | 379 | #endif |
380 | 380 | } |
381 | 381 | |
540 | 540 | #endif |
541 | 541 | }; |
542 | 542 | |
543 | uint8_t *ConvolveTest::input_ = NULL; | |
544 | uint8_t *ConvolveTest::output_ = NULL; | |
545 | uint8_t *ConvolveTest::output_ref_ = NULL; | |
546 | #if CONFIG_VP9_HIGHBITDEPTH | |
547 | uint16_t *ConvolveTest::input16_ = NULL; | |
548 | uint16_t *ConvolveTest::output16_ = NULL; | |
549 | uint16_t *ConvolveTest::output16_ref_ = NULL; | |
543 | uint8_t *ConvolveTest::input_ = nullptr; | |
544 | uint8_t *ConvolveTest::output_ = nullptr; | |
545 | uint8_t *ConvolveTest::output_ref_ = nullptr; | |
546 | #if CONFIG_VP9_HIGHBITDEPTH | |
547 | uint16_t *ConvolveTest::input16_ = nullptr; | |
548 | uint16_t *ConvolveTest::output16_ = nullptr; | |
549 | uint16_t *ConvolveTest::output16_ref_ = nullptr; | |
550 | 550 | #endif |
551 | 551 | |
552 | 552 | TEST_P(ConvolveTest, GuardBlocks) { CheckGuardBlocks(); } |
561 | 561 | |
562 | 562 | vpx_usec_timer_start(&timer); |
563 | 563 | for (int n = 0; n < kNumTests; ++n) { |
564 | UUT_->copy_[0](in, kInputStride, out, kOutputStride, NULL, 0, 0, 0, 0, | |
564 | UUT_->copy_[0](in, kInputStride, out, kOutputStride, nullptr, 0, 0, 0, 0, | |
565 | 565 | width, height); |
566 | 566 | } |
567 | 567 | vpx_usec_timer_mark(&timer); |
581 | 581 | |
582 | 582 | vpx_usec_timer_start(&timer); |
583 | 583 | for (int n = 0; n < kNumTests; ++n) { |
584 | UUT_->copy_[1](in, kInputStride, out, kOutputStride, NULL, 0, 0, 0, 0, | |
584 | UUT_->copy_[1](in, kInputStride, out, kOutputStride, nullptr, 0, 0, 0, 0, | |
585 | 585 | width, height); |
586 | 586 | } |
587 | 587 | vpx_usec_timer_mark(&timer); |
779 | 779 | uint8_t *const out = output(); |
780 | 780 | |
781 | 781 | ASM_REGISTER_STATE_CHECK(UUT_->copy_[0](in, kInputStride, out, kOutputStride, |
782 | NULL, 0, 0, 0, 0, Width(), Height())); | |
782 | nullptr, 0, 0, 0, 0, Width(), | |
783 | Height())); | |
783 | 784 | |
784 | 785 | CheckGuardBlocks(); |
785 | 786 | |
798 | 799 | CopyOutputToRef(); |
799 | 800 | |
800 | 801 | ASM_REGISTER_STATE_CHECK(UUT_->copy_[1](in, kInputStride, out, kOutputStride, |
801 | NULL, 0, 0, 0, 0, Width(), Height())); | |
802 | nullptr, 0, 0, 0, 0, Width(), | |
803 | Height())); | |
802 | 804 | |
803 | 805 | CheckGuardBlocks(); |
804 | 806 | |
954 | 956 | UUT_->h8_[i](in, kInputStride, out, kOutputStride, filters, |
955 | 957 | filter_x, 16, 0, 16, Width(), Height())); |
956 | 958 | else |
957 | ASM_REGISTER_STATE_CHECK(UUT_->copy_[i](in, kInputStride, out, | |
958 | kOutputStride, NULL, 0, 0, | |
959 | 0, 0, Width(), Height())); | |
959 | ASM_REGISTER_STATE_CHECK( | |
960 | UUT_->copy_[i](in, kInputStride, out, kOutputStride, nullptr, 0, | |
961 | 0, 0, 0, Width(), Height())); | |
960 | 962 | |
961 | 963 | CheckGuardBlocks(); |
962 | 964 | |
1052 | 1054 | UUT_->h8_[0](in, kInputStride, out, kOutputStride, filters, |
1053 | 1055 | filter_x, 16, 0, 16, Width(), Height())); |
1054 | 1056 | else |
1055 | ASM_REGISTER_STATE_CHECK(UUT_->copy_[0](in, kInputStride, out, | |
1056 | kOutputStride, NULL, 0, 0, | |
1057 | 0, 0, Width(), Height())); | |
1057 | ASM_REGISTER_STATE_CHECK( | |
1058 | UUT_->copy_[0](in, kInputStride, out, kOutputStride, nullptr, | |
1059 | 0, 0, 0, 0, Width(), Height())); | |
1058 | 1060 | |
1059 | 1061 | for (int y = 0; y < Height(); ++y) { |
1060 | 1062 | for (int x = 0; x < Width(); ++x) |
713 | 713 | RunQuantCheck(429, 729); |
714 | 714 | } |
715 | 715 | |
716 | #if HAVE_SSE2 && CONFIG_VP9_HIGHBITDEPTH && !CONFIG_EMULATE_HARDWARE | |
716 | 717 | class InvTrans16x16DCT : public Trans16x16TestBase, |
717 | 718 | public ::testing::TestWithParam<Idct16x16Param> { |
718 | 719 | public: |
738 | 739 | IdctFunc inv_txfm_; |
739 | 740 | int thresh_; |
740 | 741 | }; |
742 | GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(InvTrans16x16DCT); | |
741 | 743 | |
742 | 744 | TEST_P(InvTrans16x16DCT, CompareReference) { |
743 | 745 | CompareInvReference(ref_txfm_, thresh_); |
744 | 746 | } |
747 | #endif // HAVE_SSE2 && CONFIG_VP9_HIGHBITDEPTH && !CONFIG_EMULATE_HARDWARE | |
745 | 748 | |
746 | 749 | using std::make_tuple; |
747 | 750 |
38 | 38 | |
39 | 39 | tran_low_t partial_fdct_ref(const Buffer<int16_t> &in, int size) { |
40 | 40 | int64_t sum = 0; |
41 | if (in.TopLeftPixel() != NULL) { | |
41 | if (in.TopLeftPixel() != nullptr) { | |
42 | 42 | for (int y = 0; y < size; ++y) { |
43 | 43 | for (int x = 0; x < size; ++x) { |
44 | 44 | sum += in.TopLeftPixel()[y * in.stride() + x]; |
80 | 80 | Buffer<tran_low_t> output_block = Buffer<tran_low_t>(size_, size_, 0, 16); |
81 | 81 | ASSERT_TRUE(output_block.Init()); |
82 | 82 | |
83 | if (output_block.TopLeftPixel() != NULL) { | |
83 | if (output_block.TopLeftPixel() != nullptr) { | |
84 | 84 | for (int i = 0; i < 100; ++i) { |
85 | 85 | if (i == 0) { |
86 | 86 | input_block.Set(maxvalue); |
159 | 159 | |
160 | 160 | src_ = reinterpret_cast<uint8_t *>( |
161 | 161 | vpx_memalign(16, pixel_size_ * block_size_)); |
162 | ASSERT_TRUE(src_ != NULL); | |
162 | ASSERT_NE(src_, nullptr); | |
163 | 163 | dst_ = reinterpret_cast<uint8_t *>( |
164 | 164 | vpx_memalign(16, pixel_size_ * block_size_)); |
165 | ASSERT_TRUE(dst_ != NULL); | |
165 | ASSERT_NE(dst_, nullptr); | |
166 | 166 | } |
167 | 167 | |
168 | 168 | virtual void TearDown() { |
169 | 169 | vpx_free(src_); |
170 | src_ = NULL; | |
170 | src_ = nullptr; | |
171 | 171 | vpx_free(dst_); |
172 | dst_ = NULL; | |
172 | dst_ = nullptr; | |
173 | 173 | libvpx_test::ClearSystemState(); |
174 | 174 | } |
175 | 175 | |
210 | 210 | Buffer<int16_t> test_input_block = |
211 | 211 | Buffer<int16_t>(size_, size_, 8, size_ == 4 ? 0 : 16); |
212 | 212 | ASSERT_TRUE(test_input_block.Init()); |
213 | ASSERT_TRUE(test_input_block.TopLeftPixel() != NULL); | |
213 | ASSERT_NE(test_input_block.TopLeftPixel(), nullptr); | |
214 | 214 | Buffer<tran_low_t> test_temp_block = |
215 | 215 | Buffer<tran_low_t>(size_, size_, 0, 16); |
216 | 216 | ASSERT_TRUE(test_temp_block.Init()); |
315 | 315 | } else if (i == 1) { |
316 | 316 | input_extreme_block.Set(-max_pixel_value_); |
317 | 317 | } else { |
318 | ASSERT_TRUE(input_extreme_block.TopLeftPixel() != NULL); | |
318 | ASSERT_NE(input_extreme_block.TopLeftPixel(), nullptr); | |
319 | 319 | for (int h = 0; h < size_; ++h) { |
320 | 320 | for (int w = 0; w < size_; ++w) { |
321 | 321 | input_extreme_block |
330 | 330 | |
331 | 331 | // The minimum quant value is 4. |
332 | 332 | EXPECT_TRUE(output_block.CheckValues(output_ref_block)); |
333 | ASSERT_TRUE(output_block.TopLeftPixel() != NULL); | |
333 | ASSERT_NE(output_block.TopLeftPixel(), nullptr); | |
334 | 334 | for (int h = 0; h < size_; ++h) { |
335 | 335 | for (int w = 0; w < size_; ++w) { |
336 | 336 | EXPECT_GE( |
368 | 368 | |
369 | 369 | for (int i = 0; i < count_test_block; ++i) { |
370 | 370 | InitMem(); |
371 | ASSERT_TRUE(in.TopLeftPixel() != NULL); | |
371 | ASSERT_NE(in.TopLeftPixel(), nullptr); | |
372 | 372 | // Initialize a test block with input range [-max_pixel_value_, |
373 | 373 | // max_pixel_value_]. |
374 | 374 | for (int h = 0; h < size_; ++h) { |
86 | 86 | vpx_usec_timer t; |
87 | 87 | vpx_usec_timer_start(&t); |
88 | 88 | |
89 | for (video.Begin(); video.cxdata() != NULL; video.Next()) { | |
89 | for (video.Begin(); video.cxdata() != nullptr; video.Next()) { | |
90 | 90 | decoder.DecodeFrame(video.cxdata(), video.frame_size()); |
91 | 91 | } |
92 | 92 | |
149 | 149 | const std::string data_path = getenv("LIBVPX_TEST_DATA_PATH"); |
150 | 150 | const std::string path_to_source = data_path + "/" + kNewEncodeOutputFile; |
151 | 151 | outfile_ = fopen(path_to_source.c_str(), "wb"); |
152 | ASSERT_TRUE(outfile_ != NULL); | |
152 | ASSERT_NE(outfile_, nullptr); | |
153 | 153 | } |
154 | 154 | |
155 | 155 | virtual void EndPassHook() { |
156 | if (outfile_ != NULL) { | |
156 | if (outfile_ != nullptr) { | |
157 | 157 | if (!fseek(outfile_, 0, SEEK_SET)) { |
158 | 158 | ivf_write_file_header(outfile_, &cfg_, VP9_FOURCC, out_frames_); |
159 | 159 | } |
160 | 160 | fclose(outfile_); |
161 | outfile_ = NULL; | |
161 | outfile_ = nullptr; | |
162 | 162 | } |
163 | 163 | } |
164 | 164 | |
235 | 235 | vpx_usec_timer t; |
236 | 236 | vpx_usec_timer_start(&t); |
237 | 237 | |
238 | for (decode_video.Begin(); decode_video.cxdata() != NULL; | |
238 | for (decode_video.Begin(); decode_video.cxdata() != nullptr; | |
239 | 239 | decode_video.Next()) { |
240 | 240 | decoder.DecodeFrame(decode_video.cxdata(), decode_video.frame_size()); |
241 | 241 | } |
55 | 55 | const std::string filename = GET_PARAM(1); |
56 | 56 | std::unique_ptr<libvpx_test::CompressedVideoSource> video; |
57 | 57 | video.reset(new libvpx_test::IVFVideoSource(filename)); |
58 | ASSERT_TRUE(video.get() != NULL); | |
58 | ASSERT_NE(video.get(), nullptr); | |
59 | 59 | video->Init(); |
60 | 60 | total_frames_ = 0; |
61 | 61 | spatial_layer_ = 0; |
72 | 72 | const std::string filename = GET_PARAM(1); |
73 | 73 | std::unique_ptr<libvpx_test::CompressedVideoSource> video; |
74 | 74 | video.reset(new libvpx_test::IVFVideoSource(filename)); |
75 | ASSERT_TRUE(video.get() != NULL); | |
75 | ASSERT_NE(video.get(), nullptr); | |
76 | 76 | video->Init(); |
77 | 77 | total_frames_ = 0; |
78 | 78 | spatial_layer_ = 1; |
89 | 89 | const std::string filename = GET_PARAM(1); |
90 | 90 | std::unique_ptr<libvpx_test::CompressedVideoSource> video; |
91 | 91 | video.reset(new libvpx_test::IVFVideoSource(filename)); |
92 | ASSERT_TRUE(video.get() != NULL); | |
92 | ASSERT_NE(video.get(), nullptr); | |
93 | 93 | video->Init(); |
94 | 94 | total_frames_ = 0; |
95 | 95 | spatial_layer_ = 2; |
107 | 107 | const std::string filename = GET_PARAM(1); |
108 | 108 | std::unique_ptr<libvpx_test::CompressedVideoSource> video; |
109 | 109 | video.reset(new libvpx_test::IVFVideoSource(filename)); |
110 | ASSERT_TRUE(video.get() != NULL); | |
110 | ASSERT_NE(video.get(), nullptr); | |
111 | 111 | video->Init(); |
112 | 112 | total_frames_ = 0; |
113 | 113 | spatial_layer_ = 10; |
25 | 25 | } |
26 | 26 | |
27 | 27 | vpx_codec_err_t Decoder::DecodeFrame(const uint8_t *cxdata, size_t size) { |
28 | return DecodeFrame(cxdata, size, NULL); | |
28 | return DecodeFrame(cxdata, size, nullptr); | |
29 | 29 | } |
30 | 30 | |
31 | 31 | vpx_codec_err_t Decoder::DecodeFrame(const uint8_t *cxdata, size_t size, |
66 | 66 | void DecoderTest::RunLoop(CompressedVideoSource *video, |
67 | 67 | const vpx_codec_dec_cfg_t &dec_cfg) { |
68 | 68 | Decoder *const decoder = codec_->CreateDecoder(dec_cfg, flags_); |
69 | ASSERT_TRUE(decoder != NULL); | |
69 | ASSERT_NE(decoder, nullptr); | |
70 | 70 | bool end_of_file = false; |
71 | 71 | |
72 | 72 | // Decode frames. |
77 | 77 | vpx_codec_stream_info_t stream_info; |
78 | 78 | stream_info.sz = sizeof(stream_info); |
79 | 79 | |
80 | if (video->cxdata() != NULL) { | |
80 | if (video->cxdata() != nullptr) { | |
81 | 81 | const vpx_codec_err_t res_peek = decoder->PeekStream( |
82 | 82 | video->cxdata(), video->frame_size(), &stream_info); |
83 | 83 | HandlePeekResult(decoder, video, res_peek); |
88 | 88 | if (!HandleDecodeResult(res_dec, *video, decoder)) break; |
89 | 89 | } else { |
90 | 90 | // Signal end of the file to the decoder. |
91 | const vpx_codec_err_t res_dec = decoder->DecodeFrame(NULL, 0); | |
91 | const vpx_codec_err_t res_dec = decoder->DecodeFrame(nullptr, 0); | |
92 | 92 | ASSERT_EQ(VPX_CODEC_OK, res_dec) << decoder->DecodeError(); |
93 | 93 | end_of_file = true; |
94 | 94 | } |
95 | 95 | |
96 | 96 | DxDataIterator dec_iter = decoder->GetDxData(); |
97 | const vpx_image_t *img = NULL; | |
97 | const vpx_image_t *img = nullptr; | |
98 | 98 | |
99 | 99 | // Get decompressed data |
100 | 100 | while (!::testing::Test::HasFailure() && (img = dec_iter.Next())) { |
33 | 33 | |
34 | 34 | EXPECT_EQ(&img, vpx_img_wrap(&img, VPX_IMG_FMT_I420, 1, 1, 1, buf)); |
35 | 35 | |
36 | EXPECT_EQ(VPX_CODEC_INVALID_PARAM, vpx_codec_enc_init(NULL, NULL, NULL, 0)); | |
37 | EXPECT_EQ(VPX_CODEC_INVALID_PARAM, vpx_codec_enc_init(&enc, NULL, NULL, 0)); | |
38 | EXPECT_EQ(VPX_CODEC_INVALID_PARAM, vpx_codec_encode(NULL, NULL, 0, 0, 0, 0)); | |
39 | EXPECT_EQ(VPX_CODEC_INVALID_PARAM, vpx_codec_encode(NULL, &img, 0, 0, 0, 0)); | |
40 | EXPECT_EQ(VPX_CODEC_INVALID_PARAM, vpx_codec_destroy(NULL)); | |
41 | 36 | EXPECT_EQ(VPX_CODEC_INVALID_PARAM, |
42 | vpx_codec_enc_config_default(NULL, NULL, 0)); | |
37 | vpx_codec_enc_init(nullptr, nullptr, nullptr, 0)); | |
43 | 38 | EXPECT_EQ(VPX_CODEC_INVALID_PARAM, |
44 | vpx_codec_enc_config_default(NULL, &cfg, 0)); | |
45 | EXPECT_TRUE(vpx_codec_error(NULL) != NULL); | |
39 | vpx_codec_enc_init(&enc, nullptr, nullptr, 0)); | |
40 | EXPECT_EQ(VPX_CODEC_INVALID_PARAM, | |
41 | vpx_codec_encode(nullptr, nullptr, 0, 0, 0, 0)); | |
42 | EXPECT_EQ(VPX_CODEC_INVALID_PARAM, | |
43 | vpx_codec_encode(nullptr, &img, 0, 0, 0, 0)); | |
44 | EXPECT_EQ(VPX_CODEC_INVALID_PARAM, vpx_codec_destroy(nullptr)); | |
45 | EXPECT_EQ(VPX_CODEC_INVALID_PARAM, | |
46 | vpx_codec_enc_config_default(nullptr, nullptr, 0)); | |
47 | EXPECT_EQ(VPX_CODEC_INVALID_PARAM, | |
48 | vpx_codec_enc_config_default(nullptr, &cfg, 0)); | |
49 | EXPECT_NE(vpx_codec_error(nullptr), nullptr); | |
46 | 50 | |
47 | 51 | for (int i = 0; i < NELEMENTS(kCodecs); ++i) { |
48 | 52 | SCOPED_TRACE(vpx_codec_iface_name(kCodecs[i])); |
49 | 53 | EXPECT_EQ(VPX_CODEC_INVALID_PARAM, |
50 | vpx_codec_enc_init(NULL, kCodecs[i], NULL, 0)); | |
54 | vpx_codec_enc_init(nullptr, kCodecs[i], nullptr, 0)); | |
51 | 55 | EXPECT_EQ(VPX_CODEC_INVALID_PARAM, |
52 | vpx_codec_enc_init(&enc, kCodecs[i], NULL, 0)); | |
56 | vpx_codec_enc_init(&enc, kCodecs[i], nullptr, 0)); | |
53 | 57 | EXPECT_EQ(VPX_CODEC_INVALID_PARAM, |
54 | 58 | vpx_codec_enc_config_default(kCodecs[i], &cfg, 1)); |
55 | 59 | |
56 | 60 | EXPECT_EQ(VPX_CODEC_OK, vpx_codec_enc_config_default(kCodecs[i], &cfg, 0)); |
57 | 61 | EXPECT_EQ(VPX_CODEC_OK, vpx_codec_enc_init(&enc, kCodecs[i], &cfg, 0)); |
58 | EXPECT_EQ(VPX_CODEC_OK, vpx_codec_encode(&enc, NULL, 0, 0, 0, 0)); | |
62 | EXPECT_EQ(VPX_CODEC_OK, vpx_codec_encode(&enc, nullptr, 0, 0, 0, 0)); | |
59 | 63 | |
60 | 64 | EXPECT_EQ(VPX_CODEC_OK, vpx_codec_destroy(&enc)); |
61 | 65 | } |
90 | 90 | |
91 | 91 | void Encoder::Flush() { |
92 | 92 | const vpx_codec_err_t res = |
93 | vpx_codec_encode(&encoder_, NULL, 0, 0, 0, deadline_); | |
93 | vpx_codec_encode(&encoder_, nullptr, 0, 0, 0, deadline_); | |
94 | 94 | if (!encoder_.priv) |
95 | 95 | ASSERT_EQ(VPX_CODEC_ERROR, res) << EncoderError(); |
96 | 96 | else |
181 | 181 | BeginPassHook(pass); |
182 | 182 | std::unique_ptr<Encoder> encoder( |
183 | 183 | codec_->CreateEncoder(cfg_, deadline_, init_flags_, &stats_)); |
184 | ASSERT_TRUE(encoder.get() != NULL); | |
184 | ASSERT_NE(encoder.get(), nullptr); | |
185 | 185 | |
186 | 186 | ASSERT_NO_FATAL_FAILURE(video->Begin()); |
187 | 187 | encoder->InitEncoder(video); |
197 | 197 | codec_->CreateDecoder(dec_cfg, dec_init_flags)); |
198 | 198 | bool again; |
199 | 199 | for (again = true; again; video->Next()) { |
200 | again = (video->img() != NULL); | |
200 | again = (video->img() != nullptr); | |
201 | 201 | |
202 | 202 | PreEncodeFrameHook(video); |
203 | 203 | PreEncodeFrameHook(video, encoder.get()); |
215 | 215 | switch (pkt->kind) { |
216 | 216 | case VPX_CODEC_CX_FRAME_PKT: |
217 | 217 | has_cxdata = true; |
218 | if (decoder.get() != NULL && DoDecode()) { | |
218 | if (decoder != nullptr && DoDecode()) { | |
219 | 219 | PreDecodeFrameHook(video, decoder.get()); |
220 | 220 | vpx_codec_err_t res_dec = decoder->DecodeFrame( |
221 | 221 | (const uint8_t *)pkt->data.frame.buf, pkt->data.frame.sz); |
239 | 239 | |
240 | 240 | // Flush the decoder when there are no more fragments. |
241 | 241 | if ((init_flags_ & VPX_CODEC_USE_OUTPUT_PARTITION) && has_dxdata) { |
242 | const vpx_codec_err_t res_dec = decoder->DecodeFrame(NULL, 0); | |
242 | const vpx_codec_err_t res_dec = decoder->DecodeFrame(nullptr, 0); | |
243 | 243 | if (!HandleDecodeResult(res_dec, *video, decoder.get())) break; |
244 | 244 | } |
245 | 245 |
146 | 146 | const vpx_codec_err_t res = vpx_codec_control_(&encoder_, ctrl_id, arg); |
147 | 147 | ASSERT_EQ(VPX_CODEC_OK, res) << EncoderError(); |
148 | 148 | } |
149 | ||
150 | #if CONFIG_VP9_ENCODER | |
151 | void Control(int ctrl_id, vpx_rc_funcs_t *arg) { | |
152 | const vpx_codec_err_t res = vpx_codec_control_(&encoder_, ctrl_id, arg); | |
153 | ASSERT_EQ(VPX_CODEC_OK, res) << EncoderError(); | |
154 | } | |
155 | #endif // CONFIG_VP9_ENCODER | |
149 | 156 | |
150 | 157 | #if CONFIG_VP8_ENCODER || CONFIG_VP9_ENCODER |
151 | 158 | void Control(int ctrl_id, vpx_active_map_t *arg) { |
35 | 35 | class ExternalFrameBufferList { |
36 | 36 | public: |
37 | 37 | ExternalFrameBufferList() |
38 | : num_buffers_(0), num_used_buffers_(0), ext_fb_list_(NULL) {} | |
38 | : num_buffers_(0), num_used_buffers_(0), ext_fb_list_(nullptr) {} | |
39 | 39 | |
40 | 40 | virtual ~ExternalFrameBufferList() { |
41 | 41 | for (int i = 0; i < num_buffers_; ++i) { |
50 | 50 | |
51 | 51 | num_buffers_ = num_buffers; |
52 | 52 | ext_fb_list_ = new ExternalFrameBuffer[num_buffers_]; |
53 | EXPECT_TRUE(ext_fb_list_ != NULL); | |
53 | EXPECT_NE(ext_fb_list_, nullptr); | |
54 | 54 | memset(ext_fb_list_, 0, sizeof(ext_fb_list_[0]) * num_buffers_); |
55 | 55 | return true; |
56 | 56 | } |
60 | 60 | // frame buffer is in use by libvpx. Finally sets |fb| to point to the |
61 | 61 | // external frame buffer. Returns < 0 on an error. |
62 | 62 | int GetFreeFrameBuffer(size_t min_size, vpx_codec_frame_buffer_t *fb) { |
63 | EXPECT_TRUE(fb != NULL); | |
63 | EXPECT_NE(fb, nullptr); | |
64 | 64 | const int idx = FindFreeBufferIndex(); |
65 | 65 | if (idx == num_buffers_) return -1; |
66 | 66 | |
80 | 80 | // Test function that will not allocate any data for the frame buffer. |
81 | 81 | // Returns < 0 on an error. |
82 | 82 | int GetZeroFrameBuffer(size_t min_size, vpx_codec_frame_buffer_t *fb) { |
83 | EXPECT_TRUE(fb != NULL); | |
83 | EXPECT_NE(fb, nullptr); | |
84 | 84 | const int idx = FindFreeBufferIndex(); |
85 | 85 | if (idx == num_buffers_) return -1; |
86 | 86 | |
87 | 87 | if (ext_fb_list_[idx].size < min_size) { |
88 | 88 | delete[] ext_fb_list_[idx].data; |
89 | ext_fb_list_[idx].data = NULL; | |
89 | ext_fb_list_[idx].data = nullptr; | |
90 | 90 | ext_fb_list_[idx].size = min_size; |
91 | 91 | } |
92 | 92 | |
97 | 97 | // Marks the external frame buffer that |fb| is pointing to as free. |
98 | 98 | // Returns < 0 on an error. |
99 | 99 | int ReturnFrameBuffer(vpx_codec_frame_buffer_t *fb) { |
100 | if (fb == NULL) { | |
101 | EXPECT_TRUE(fb != NULL); | |
100 | if (fb == nullptr) { | |
101 | EXPECT_NE(fb, nullptr); | |
102 | 102 | return -1; |
103 | 103 | } |
104 | 104 | ExternalFrameBuffer *const ext_fb = |
105 | 105 | reinterpret_cast<ExternalFrameBuffer *>(fb->priv); |
106 | if (ext_fb == NULL) { | |
107 | EXPECT_TRUE(ext_fb != NULL); | |
106 | if (ext_fb == nullptr) { | |
107 | EXPECT_NE(ext_fb, nullptr); | |
108 | 108 | return -1; |
109 | 109 | } |
110 | 110 | EXPECT_EQ(1, ext_fb->in_use); |
116 | 116 | // Checks that the vpx_image_t data is contained within the external frame |
117 | 117 | // buffer private data passed back in the vpx_image_t. |
118 | 118 | void CheckImageFrameBuffer(const vpx_image_t *img) { |
119 | if (img->fb_priv != NULL) { | |
119 | if (img->fb_priv != nullptr) { | |
120 | 120 | const struct ExternalFrameBuffer *const ext_fb = |
121 | 121 | reinterpret_cast<ExternalFrameBuffer *>(img->fb_priv); |
122 | 122 | |
142 | 142 | // Sets |fb| to an external frame buffer. idx is the index into the frame |
143 | 143 | // buffer list. |
144 | 144 | void SetFrameBuffer(int idx, vpx_codec_frame_buffer_t *fb) { |
145 | ASSERT_TRUE(fb != NULL); | |
145 | ASSERT_NE(fb, nullptr); | |
146 | 146 | fb->data = ext_fb_list_[idx].data; |
147 | 147 | fb->size = ext_fb_list_[idx].size; |
148 | 148 | ASSERT_EQ(0, ext_fb_list_[idx].in_use); |
207 | 207 | protected: |
208 | 208 | ExternalFrameBufferMD5Test() |
209 | 209 | : DecoderTest(GET_PARAM(::libvpx_test::kCodecFactoryParam)), |
210 | md5_file_(NULL), num_buffers_(0) {} | |
210 | md5_file_(nullptr), num_buffers_(0) {} | |
211 | 211 | |
212 | 212 | virtual ~ExternalFrameBufferMD5Test() { |
213 | if (md5_file_ != NULL) fclose(md5_file_); | |
213 | if (md5_file_ != nullptr) fclose(md5_file_); | |
214 | 214 | } |
215 | 215 | |
216 | 216 | virtual void PreDecodeFrameHook( |
227 | 227 | |
228 | 228 | void OpenMD5File(const std::string &md5_file_name_) { |
229 | 229 | md5_file_ = libvpx_test::OpenTestDataFile(md5_file_name_); |
230 | ASSERT_TRUE(md5_file_ != NULL) | |
230 | ASSERT_NE(md5_file_, nullptr) | |
231 | 231 | << "Md5 file open failed. Filename: " << md5_file_name_; |
232 | 232 | } |
233 | 233 | |
234 | 234 | virtual void DecompressedFrameHook(const vpx_image_t &img, |
235 | 235 | const unsigned int frame_number) { |
236 | ASSERT_TRUE(md5_file_ != NULL); | |
236 | ASSERT_NE(md5_file_, nullptr); | |
237 | 237 | char expected_md5[33]; |
238 | 238 | char junk[128]; |
239 | 239 | |
285 | 285 | // Class for testing passing in external frame buffers to libvpx. |
286 | 286 | class ExternalFrameBufferTest : public ::testing::Test { |
287 | 287 | protected: |
288 | ExternalFrameBufferTest() : video_(NULL), decoder_(NULL), num_buffers_(0) {} | |
288 | ExternalFrameBufferTest() | |
289 | : video_(nullptr), decoder_(nullptr), num_buffers_(0) {} | |
289 | 290 | |
290 | 291 | virtual void SetUp() { |
291 | 292 | video_ = new libvpx_test::WebMVideoSource(kVP9TestFile); |
292 | ASSERT_TRUE(video_ != NULL); | |
293 | ASSERT_NE(video_, nullptr); | |
293 | 294 | video_->Init(); |
294 | 295 | video_->Begin(); |
295 | 296 | |
296 | 297 | vpx_codec_dec_cfg_t cfg = vpx_codec_dec_cfg_t(); |
297 | 298 | decoder_ = new libvpx_test::VP9Decoder(cfg, 0); |
298 | ASSERT_TRUE(decoder_ != NULL); | |
299 | ASSERT_NE(decoder_, nullptr); | |
299 | 300 | } |
300 | 301 | |
301 | 302 | virtual void TearDown() { |
302 | 303 | delete decoder_; |
303 | decoder_ = NULL; | |
304 | decoder_ = nullptr; | |
304 | 305 | delete video_; |
305 | video_ = NULL; | |
306 | video_ = nullptr; | |
306 | 307 | } |
307 | 308 | |
308 | 309 | // Passes the external frame buffer information to libvpx. |
326 | 327 | } |
327 | 328 | |
328 | 329 | vpx_codec_err_t DecodeRemainingFrames() { |
329 | for (; video_->cxdata() != NULL; video_->Next()) { | |
330 | for (; video_->cxdata() != nullptr; video_->Next()) { | |
330 | 331 | const vpx_codec_err_t res = |
331 | 332 | decoder_->DecodeFrame(video_->cxdata(), video_->frame_size()); |
332 | 333 | if (res != VPX_CODEC_OK) return res; |
337 | 338 | |
338 | 339 | void CheckDecodedFrames() { |
339 | 340 | libvpx_test::DxDataIterator dec_iter = decoder_->GetDxData(); |
340 | const vpx_image_t *img = NULL; | |
341 | const vpx_image_t *img = nullptr; | |
341 | 342 | |
342 | 343 | // Get decompressed data |
343 | while ((img = dec_iter.Next()) != NULL) { | |
344 | while ((img = dec_iter.Next()) != nullptr) { | |
344 | 345 | fb_list_.CheckImageFrameBuffer(img); |
345 | 346 | } |
346 | 347 | } |
355 | 356 | protected: |
356 | 357 | virtual void SetUp() { |
357 | 358 | video_ = new libvpx_test::WebMVideoSource(kVP9NonRefTestFile); |
358 | ASSERT_TRUE(video_ != NULL); | |
359 | ASSERT_NE(video_, nullptr); | |
359 | 360 | video_->Init(); |
360 | 361 | video_->Begin(); |
361 | 362 | |
362 | 363 | vpx_codec_dec_cfg_t cfg = vpx_codec_dec_cfg_t(); |
363 | 364 | decoder_ = new libvpx_test::VP9Decoder(cfg, 0); |
364 | ASSERT_TRUE(decoder_ != NULL); | |
365 | ASSERT_NE(decoder_, nullptr); | |
365 | 366 | } |
366 | 367 | |
367 | 368 | virtual void CheckFrameBufferRelease() { |
404 | 405 | return; |
405 | 406 | #endif |
406 | 407 | } |
407 | ASSERT_TRUE(video.get() != NULL); | |
408 | ASSERT_NE(video.get(), nullptr); | |
408 | 409 | video->Init(); |
409 | 410 | |
410 | 411 | // Construct md5 file name. |
481 | 482 | const int num_buffers = VP9_MAXIMUM_REF_BUFFERS + VPX_MAXIMUM_WORK_BUFFERS; |
482 | 483 | ASSERT_EQ( |
483 | 484 | VPX_CODEC_INVALID_PARAM, |
484 | SetFrameBufferFunctions(num_buffers, NULL, release_vp9_frame_buffer)); | |
485 | SetFrameBufferFunctions(num_buffers, nullptr, release_vp9_frame_buffer)); | |
485 | 486 | } |
486 | 487 | |
487 | 488 | TEST_F(ExternalFrameBufferTest, NullReleaseFunction) { |
488 | 489 | const int num_buffers = VP9_MAXIMUM_REF_BUFFERS + VPX_MAXIMUM_WORK_BUFFERS; |
489 | ASSERT_EQ(VPX_CODEC_INVALID_PARAM, | |
490 | SetFrameBufferFunctions(num_buffers, get_vp9_frame_buffer, NULL)); | |
490 | ASSERT_EQ( | |
491 | VPX_CODEC_INVALID_PARAM, | |
492 | SetFrameBufferFunctions(num_buffers, get_vp9_frame_buffer, nullptr)); | |
491 | 493 | } |
492 | 494 | |
493 | 495 | TEST_F(ExternalFrameBufferTest, SetAfterDecode) { |
597 | 597 | |
598 | 598 | TEST_P(FwdTrans8x8HT, ExtremalCheck) { RunExtremalCheck(); } |
599 | 599 | |
600 | #if HAVE_SSE2 && CONFIG_VP9_HIGHBITDEPTH && !CONFIG_EMULATE_HARDWARE | |
600 | 601 | class InvTrans8x8DCT : public FwdTrans8x8TestBase, |
601 | 602 | public ::testing::TestWithParam<Idct8x8Param> { |
602 | 603 | public: |
623 | 624 | IdctFunc inv_txfm_; |
624 | 625 | int thresh_; |
625 | 626 | }; |
627 | GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(InvTrans8x8DCT); | |
626 | 628 | |
627 | 629 | TEST_P(InvTrans8x8DCT, CompareReference) { |
628 | 630 | CompareInvReference(ref_txfm_, thresh_); |
629 | 631 | } |
632 | #endif // HAVE_SSE2 && CONFIG_VP9_HIGHBITDEPTH && !CONFIG_EMULATE_HARDWARE | |
630 | 633 | |
631 | 634 | using std::make_tuple; |
632 | 635 |
68 | 68 | #if CONFIG_VP9_ENCODER |
69 | 69 | return &vpx_codec_vp9_cx_algo; |
70 | 70 | #else |
71 | return NULL; | |
71 | return nullptr; | |
72 | 72 | #endif |
73 | 73 | } |
74 | 74 | }; |
129 | 129 | encoder->InitEncoder(video); |
130 | 130 | ASSERT_FALSE(::testing::Test::HasFatalFailure()); |
131 | 131 | for (bool again = true; again; video->Next()) { |
132 | again = (video->img() != NULL); | |
132 | again = (video->img() != nullptr); | |
133 | 133 | |
134 | 134 | PreEncodeFrameHook(video, encoder.get()); |
135 | 135 | encoder->EncodeFrame(video, frame_flags_, expected_err); |
30 | 30 | UUT = GetParam(); |
31 | 31 | |
32 | 32 | input = new Buffer<int16_t>(4, 4, 0); |
33 | ASSERT_TRUE(input != NULL); | |
33 | ASSERT_NE(input, nullptr); | |
34 | 34 | ASSERT_TRUE(input->Init()); |
35 | 35 | predict = new Buffer<uint8_t>(4, 4, 3); |
36 | ASSERT_TRUE(predict != NULL); | |
36 | ASSERT_NE(predict, nullptr); | |
37 | 37 | ASSERT_TRUE(predict->Init()); |
38 | 38 | output = new Buffer<uint8_t>(4, 4, 3); |
39 | ASSERT_TRUE(output != NULL); | |
39 | ASSERT_NE(output, nullptr); | |
40 | 40 | ASSERT_TRUE(output->Init()); |
41 | 41 | } |
42 | 42 | |
71 | 71 | |
72 | 72 | TEST_P(IDCTTest, TestAllOnes) { |
73 | 73 | input->Set(0); |
74 | ASSERT_TRUE(input->TopLeftPixel() != NULL); | |
74 | ASSERT_NE(input->TopLeftPixel(), nullptr); | |
75 | 75 | // When the first element is '4' it will fill the output buffer with '1'. |
76 | 76 | input->TopLeftPixel()[0] = 4; |
77 | 77 | predict->Set(0); |
89 | 89 | // Set the transform output to '1' and make sure it gets added to the |
90 | 90 | // prediction buffer. |
91 | 91 | input->Set(0); |
92 | ASSERT_TRUE(input->TopLeftPixel() != NULL); | |
92 | ASSERT_NE(input->TopLeftPixel(), nullptr); | |
93 | 93 | input->TopLeftPixel()[0] = 4; |
94 | 94 | output->Set(0); |
95 | 95 |
37 | 37 | class InvalidFileTest : public ::libvpx_test::DecoderTest, |
38 | 38 | public ::libvpx_test::CodecTestWithParam<DecodeParam> { |
39 | 39 | protected: |
40 | InvalidFileTest() : DecoderTest(GET_PARAM(0)), res_file_(NULL) {} | |
40 | InvalidFileTest() : DecoderTest(GET_PARAM(0)), res_file_(nullptr) {} | |
41 | 41 | |
42 | 42 | virtual ~InvalidFileTest() { |
43 | if (res_file_ != NULL) fclose(res_file_); | |
43 | if (res_file_ != nullptr) fclose(res_file_); | |
44 | 44 | } |
45 | 45 | |
46 | 46 | void OpenResFile(const std::string &res_file_name_) { |
47 | 47 | res_file_ = libvpx_test::OpenTestDataFile(res_file_name_); |
48 | ASSERT_TRUE(res_file_ != NULL) | |
48 | ASSERT_NE(res_file_, nullptr) | |
49 | 49 | << "Result file open failed. Filename: " << res_file_name_; |
50 | 50 | } |
51 | 51 | |
53 | 53 | const vpx_codec_err_t res_dec, |
54 | 54 | const libvpx_test::CompressedVideoSource &video, |
55 | 55 | libvpx_test::Decoder *decoder) { |
56 | EXPECT_TRUE(res_file_ != NULL); | |
56 | EXPECT_NE(res_file_, nullptr); | |
57 | 57 | int expected_res_dec; |
58 | 58 | |
59 | 59 | // Read integer result. |
101 | 101 | return; |
102 | 102 | #endif |
103 | 103 | } |
104 | ASSERT_TRUE(video.get() != NULL); | |
104 | ASSERT_NE(video.get(), nullptr); | |
105 | 105 | video->Init(); |
106 | 106 | |
107 | 107 | // Construct result file name. The file holds a list of expected integer |
144 | 144 | loop_op_t loopfilter_op_; |
145 | 145 | loop_op_t ref_loopfilter_op_; |
146 | 146 | }; |
147 | ||
147 | GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(Loop8Test6Param); | |
148 | ||
149 | #if HAVE_NEON || HAVE_SSE2 || \ | |
150 | (HAVE_DSPR2 || HAVE_MSA && !CONFIG_VP9_HIGHBITDEPTH) | |
148 | 151 | class Loop8Test9Param : public ::testing::TestWithParam<dualloop8_param_t> { |
149 | 152 | public: |
150 | 153 | virtual ~Loop8Test9Param() {} |
163 | 166 | dual_loop_op_t loopfilter_op_; |
164 | 167 | dual_loop_op_t ref_loopfilter_op_; |
165 | 168 | }; |
169 | GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(Loop8Test9Param); | |
170 | #endif // HAVE_NEON || HAVE_SSE2 || (HAVE_DSPR2 || HAVE_MSA && | |
171 | // (!CONFIG_VP9_HIGHBITDEPTH)) | |
166 | 172 | |
167 | 173 | TEST_P(Loop8Test6Param, OperationCheck) { |
168 | 174 | ACMRandom rnd(ACMRandom::DeterministicSeed()); |
274 | 280 | << "First failed at test case " << first_failure; |
275 | 281 | } |
276 | 282 | |
283 | #if HAVE_NEON || HAVE_SSE2 || \ | |
284 | (HAVE_DSPR2 || HAVE_MSA && (!CONFIG_VP9_HIGHBITDEPTH)) | |
277 | 285 | TEST_P(Loop8Test9Param, OperationCheck) { |
278 | 286 | ACMRandom rnd(ACMRandom::DeterministicSeed()); |
279 | 287 | const int count_test_block = number_of_iterations; |
401 | 409 | "loopfilter output. " |
402 | 410 | << "First failed at test case " << first_failure; |
403 | 411 | } |
412 | #endif // HAVE_NEON || HAVE_SSE2 || (HAVE_DSPR2 || HAVE_MSA && | |
413 | // (!CONFIG_VP9_HIGHBITDEPTH)) | |
404 | 414 | |
405 | 415 | using std::make_tuple; |
406 | 416 |
128 | 128 | const char *ground_truth_file = |
129 | 129 | "non_greedy_mv_test_files/ground_truth_16x16.txt"; |
130 | 130 | BLOCK_SIZE bsize = BLOCK_32X32; |
131 | MV *search_mf = NULL; | |
132 | MV *smooth_mf = NULL; | |
133 | MV *estimation = NULL; | |
134 | MV *ground_truth = NULL; | |
135 | int(*local_var)[MF_LOCAL_STRUCTURE_SIZE] = NULL; | |
131 | MV *search_mf = nullptr; | |
132 | MV *smooth_mf = nullptr; | |
133 | MV *estimation = nullptr; | |
134 | MV *ground_truth = nullptr; | |
135 | int(*local_var)[MF_LOCAL_STRUCTURE_SIZE] = nullptr; | |
136 | 136 | int rows = 0, cols = 0; |
137 | 137 | |
138 | 138 | int alpha = 100, max_iter = 100; |
168 | 168 | const char *gt_local_var_file = "non_greedy_mv_test_files/localVar_16x16.txt"; |
169 | 169 | const char *search_mf_file = "non_greedy_mv_test_files/exhaust_16x16.txt"; |
170 | 170 | BLOCK_SIZE bsize = BLOCK_16X16; |
171 | int(*gt_local_var)[MF_LOCAL_STRUCTURE_SIZE] = NULL; | |
172 | int(*est_local_var)[MF_LOCAL_STRUCTURE_SIZE] = NULL; | |
171 | int(*gt_local_var)[MF_LOCAL_STRUCTURE_SIZE] = nullptr; | |
172 | int(*est_local_var)[MF_LOCAL_STRUCTURE_SIZE] = nullptr; | |
173 | 173 | YV12_BUFFER_CONFIG ref_frame, cur_frame; |
174 | 174 | int rows, cols; |
175 | 175 | MV *search_mf; |
101 | 101 | |
102 | 102 | virtual void TearDown() { |
103 | 103 | vpx_free(input_block_); |
104 | input_block_ = NULL; | |
104 | input_block_ = nullptr; | |
105 | 105 | vpx_free(output_block_); |
106 | output_block_ = NULL; | |
106 | output_block_ = nullptr; | |
107 | 107 | vpx_free(output_block_ref_); |
108 | output_block_ref_ = NULL; | |
108 | output_block_ref_ = nullptr; | |
109 | 109 | libvpx_test::ClearSystemState(); |
110 | 110 | } |
111 | 111 |
458 | 458 | SetRows(src_c_.TopLeftPixel(), rows_, cols_, src_c_.stride()); |
459 | 459 | |
460 | 460 | unsigned char *expected_output = new unsigned char[rows_ * cols_]; |
461 | ASSERT_TRUE(expected_output != NULL); | |
461 | ASSERT_NE(expected_output, nullptr); | |
462 | 462 | SetRows(expected_output, rows_, cols_, cols_); |
463 | 463 | |
464 | 464 | RunFilterLevel(src_c_.TopLeftPixel(), rows_, cols_, src_c_.stride(), q2mbl(0), |
40 | 40 | public: |
41 | 41 | PredictTestBase() |
42 | 42 | : width_(GET_PARAM(0)), height_(GET_PARAM(1)), predict_(GET_PARAM(2)), |
43 | src_(NULL), padded_dst_(NULL), dst_(NULL), dst_c_(NULL) {} | |
43 | src_(nullptr), padded_dst_(nullptr), dst_(nullptr), dst_c_(nullptr) {} | |
44 | 44 | |
45 | 45 | virtual void SetUp() { |
46 | 46 | src_ = new uint8_t[kSrcSize]; |
47 | ASSERT_TRUE(src_ != NULL); | |
47 | ASSERT_NE(src_, nullptr); | |
48 | 48 | |
49 | 49 | // padded_dst_ provides a buffer of kBorderSize around the destination |
50 | 50 | // memory to facilitate detecting out of bounds writes. |
52 | 52 | padded_dst_size_ = dst_stride_ * (kBorderSize + height_ + kBorderSize); |
53 | 53 | padded_dst_ = |
54 | 54 | reinterpret_cast<uint8_t *>(vpx_memalign(16, padded_dst_size_)); |
55 | ASSERT_TRUE(padded_dst_ != NULL); | |
55 | ASSERT_NE(padded_dst_, nullptr); | |
56 | 56 | dst_ = padded_dst_ + (kBorderSize * dst_stride_) + kBorderSize; |
57 | 57 | |
58 | 58 | dst_c_ = new uint8_t[16 * 16]; |
59 | ASSERT_TRUE(dst_c_ != NULL); | |
59 | ASSERT_NE(dst_c_, nullptr); | |
60 | 60 | |
61 | 61 | memset(src_, 0, kSrcSize); |
62 | 62 | memset(padded_dst_, 128, padded_dst_size_); |
65 | 65 | |
66 | 66 | virtual void TearDown() { |
67 | 67 | delete[] src_; |
68 | src_ = NULL; | |
68 | src_ = nullptr; | |
69 | 69 | vpx_free(padded_dst_); |
70 | padded_dst_ = NULL; | |
71 | dst_ = NULL; | |
70 | padded_dst_ = nullptr; | |
71 | dst_ = nullptr; | |
72 | 72 | delete[] dst_c_; |
73 | dst_c_ = NULL; | |
73 | dst_c_ = nullptr; | |
74 | 74 | libvpx_test::ClearSystemState(); |
75 | 75 | } |
76 | 76 |
45 | 45 | public: |
46 | 46 | virtual ~QuantizeTestBase() { |
47 | 47 | vp8_remove_compressor(&vp8_comp_); |
48 | vp8_comp_ = NULL; | |
48 | vp8_comp_ = nullptr; | |
49 | 49 | vpx_free(macroblockd_dst_); |
50 | macroblockd_dst_ = NULL; | |
50 | macroblockd_dst_ = nullptr; | |
51 | 51 | libvpx_test::ClearSystemState(); |
52 | 52 | } |
53 | 53 | |
145 | 145 | VP8Quantize asm_quant_; |
146 | 146 | VP8Quantize c_quant_; |
147 | 147 | }; |
148 | GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(QuantizeTest); | |
148 | 149 | |
149 | 150 | TEST_P(QuantizeTest, TestZeroInput) { |
150 | 151 | FillCoeffConstant(0); |
78 | 78 | protected: |
79 | 79 | void RunOneLayer() { |
80 | 80 | SetConfigOneLayer(); |
81 | rc_api_->Create(rc_cfg_); | |
81 | rc_api_ = libvpx::VP9RateControlRTC::Create(rc_cfg_); | |
82 | 82 | FrameInfo frame_info; |
83 | 83 | libvpx::VP9FrameParamsQpRTC frame_params; |
84 | 84 | frame_params.frame_type = KEY_FRAME; |
87 | 87 | std::ifstream one_layer_file; |
88 | 88 | one_layer_file.open(libvpx_test::GetDataPath() + |
89 | 89 | "/rc_interface_test_one_layer"); |
90 | ASSERT_EQ(one_layer_file.rdstate() & std::ifstream::failbit, 0); | |
90 | ASSERT_TRUE(one_layer_file.good()); | |
91 | 91 | for (size_t i = 0; i < kNumFrame; i++) { |
92 | 92 | one_layer_file >> frame_info; |
93 | 93 | if (frame_info.frame_id > 0) frame_params.frame_type = INTER_FRAME; |
109 | 109 | |
110 | 110 | void RunSVC() { |
111 | 111 | SetConfigSVC(); |
112 | rc_api_->Create(rc_cfg_); | |
112 | rc_api_ = libvpx::VP9RateControlRTC::Create(rc_cfg_); | |
113 | 113 | FrameInfo frame_info; |
114 | 114 | libvpx::VP9FrameParamsQpRTC frame_params; |
115 | 115 | frame_params.frame_type = KEY_FRAME; |
116 | 116 | std::ifstream svc_file; |
117 | 117 | svc_file.open(std::string(std::getenv("LIBVPX_TEST_DATA_PATH")) + |
118 | 118 | "/rc_interface_test_svc"); |
119 | ASSERT_EQ(svc_file.rdstate() & std::ifstream::failbit, 0); | |
119 | ASSERT_TRUE(svc_file.good()); | |
120 | 120 | for (size_t i = 0; i < kNumFrame * rc_cfg_.ss_number_layers; i++) { |
121 | 121 | svc_file >> frame_info; |
122 | 122 | if (frame_info.frame_id > 0) frame_params.frame_type = INTER_FRAME; |
270 | 270 | protected: |
271 | 271 | virtual void Next() { |
272 | 272 | ++frame_; |
273 | unsigned int width; | |
274 | unsigned int height; | |
273 | unsigned int width = 0; | |
274 | unsigned int height = 0; | |
275 | 275 | ScaleForFrameNumber(frame_, kInitialWidth, kInitialHeight, &width, &height, |
276 | 276 | flag_codec_, smaller_width_larger_size_); |
277 | 277 | SetSize(width, height); |
349 | 349 | protected: |
350 | 350 | #if WRITE_COMPRESSED_STREAM |
351 | 351 | ResizeInternalTest() |
352 | : ResizeTest(), frame0_psnr_(0.0), outfile_(NULL), out_frames_(0) {} | |
352 | : ResizeTest(), frame0_psnr_(0.0), outfile_(nullptr), out_frames_(0) {} | |
353 | 353 | #else |
354 | 354 | ResizeInternalTest() : ResizeTest(), frame0_psnr_(0.0) {} |
355 | 355 | #endif |
368 | 368 | if (!fseek(outfile_, 0, SEEK_SET)) |
369 | 369 | write_ivf_file_header(&cfg_, out_frames_, outfile_); |
370 | 370 | fclose(outfile_); |
371 | outfile_ = NULL; | |
371 | outfile_ = nullptr; | |
372 | 372 | } |
373 | 373 | #endif |
374 | 374 | } |
671 | 671 | ASSERT_EQ(info->h, GetFrameHeight(idx)); |
672 | 672 | if (info->w != last_w || info->h != last_h) { |
673 | 673 | resize_count++; |
674 | if (resize_count == 1) { | |
674 | if (resize_count <= 2) { | |
675 | 675 | // Verify that resize down occurs. |
676 | 676 | ASSERT_LT(info->w, last_w); |
677 | 677 | ASSERT_LT(info->h, last_h); |
678 | } else if (resize_count == 2) { | |
678 | } else if (resize_count > 2) { | |
679 | 679 | // Verify that resize up occurs. |
680 | 680 | ASSERT_GT(info->w, last_w); |
681 | 681 | ASSERT_GT(info->h, last_h); |
686 | 686 | } |
687 | 687 | |
688 | 688 | #if CONFIG_VP9_DECODER |
689 | // Verify that we get 2 resize events in this test. | |
690 | ASSERT_EQ(resize_count, 2) << "Resizing should occur twice."; | |
689 | // Verify that we get 4 resize events in this test. | |
690 | ASSERT_EQ(resize_count, 4) << "Resizing should occur twice."; | |
691 | 691 | EXPECT_EQ(static_cast<unsigned int>(0), GetMismatchFrames()); |
692 | 692 | #else |
693 | 693 | printf("Warning: VP9 decoder unavailable, unable to check resize count!\n"); |
704 | 704 | protected: |
705 | 705 | #if WRITE_COMPRESSED_STREAM |
706 | 706 | ResizeCspTest() |
707 | : ResizeTest(), frame0_psnr_(0.0), outfile_(NULL), out_frames_(0) {} | |
707 | : ResizeTest(), frame0_psnr_(0.0), outfile_(nullptr), out_frames_(0) {} | |
708 | 708 | #else |
709 | 709 | ResizeCspTest() : ResizeTest(), frame0_psnr_(0.0) {} |
710 | 710 | #endif |
723 | 723 | if (!fseek(outfile_, 0, SEEK_SET)) |
724 | 724 | write_ivf_file_header(&cfg_, out_frames_, outfile_); |
725 | 725 | fclose(outfile_); |
726 | outfile_ = NULL; | |
726 | outfile_ = nullptr; | |
727 | 727 | } |
728 | 728 | #endif |
729 | 729 | } |
24 | 24 | #include "vpx_ports/mem.h" |
25 | 25 | #include "vpx_ports/msvc.h" |
26 | 26 | #include "vpx_ports/vpx_timer.h" |
27 | ||
28 | // const[expr] should be sufficient for DECLARE_ALIGNED but early | |
29 | // implementations of c++11 appear to have some issues with it. | |
30 | #define kDataAlignment 32 | |
27 | 31 | |
28 | 32 | template <typename Function> |
29 | 33 | struct TestParams { |
98 | 102 | |
99 | 103 | virtual void TearDown() { |
100 | 104 | vpx_free(source_data8_); |
101 | source_data8_ = NULL; | |
105 | source_data8_ = nullptr; | |
102 | 106 | vpx_free(reference_data8_); |
103 | reference_data8_ = NULL; | |
107 | reference_data8_ = nullptr; | |
104 | 108 | vpx_free(second_pred8_); |
105 | second_pred8_ = NULL; | |
109 | second_pred8_ = nullptr; | |
106 | 110 | vpx_free(source_data16_); |
107 | source_data16_ = NULL; | |
111 | source_data16_ = nullptr; | |
108 | 112 | vpx_free(reference_data16_); |
109 | reference_data16_ = NULL; | |
113 | reference_data16_ = nullptr; | |
110 | 114 | vpx_free(second_pred16_); |
111 | second_pred16_ = NULL; | |
115 | second_pred16_ = nullptr; | |
112 | 116 | |
113 | 117 | libvpx_test::ClearSystemState(); |
114 | 118 | } |
116 | 120 | protected: |
117 | 121 | // Handle blocks up to 4 blocks 64x64 with stride up to 128 |
118 | 122 | // crbug.com/webm/1660 |
119 | // const[expr] should be sufficient for DECLARE_ALIGNED but early | |
120 | // implementations of c++11 appear to have some issues with it. | |
121 | enum { kDataAlignment = 32 }; | |
122 | 123 | static const int kDataBlockSize = 64 * 128; |
123 | 124 | static const int kDataBufferSize = 4 * kDataBlockSize; |
124 | 125 |
9 | 9 | |
10 | 10 | #include <math.h> |
11 | 11 | #include <memory> |
12 | #include <string> | |
12 | 13 | #include <vector> |
13 | 14 | #include "third_party/googletest/src/include/gtest/gtest.h" |
14 | 15 | #include "vp9/simple_encode.h" |
15 | 16 | |
16 | 17 | namespace vp9 { |
17 | 18 | namespace { |
18 | ||
19 | // TODO(angirbid): Find a better way to construct encode info | |
20 | const int w = 352; | |
21 | const int h = 288; | |
22 | const int frame_rate_num = 30; | |
23 | const int frame_rate_den = 1; | |
24 | const int target_bitrate = 1000; | |
25 | const int num_frames = 17; | |
26 | const char infile_path[] = "bus_352x288_420_f20_b8.yuv"; | |
27 | 19 | |
28 | 20 | double GetBitrateInKbps(size_t bit_size, int num_frames, int frame_rate_num, |
29 | 21 | int frame_rate_den) { |
35 | 27 | // For example, if size is 7, return 2. |
36 | 28 | int GetNumUnit4x4(int size) { return (size + 3) >> 2; } |
37 | 29 | |
38 | TEST(SimpleEncode, ComputeFirstPassStats) { | |
39 | SimpleEncode simple_encode(w, h, frame_rate_num, frame_rate_den, | |
40 | target_bitrate, num_frames, infile_path); | |
30 | class SimpleEncodeTest : public ::testing::Test { | |
31 | protected: | |
32 | const int width_ = 352; | |
33 | const int height_ = 288; | |
34 | const int frame_rate_num_ = 30; | |
35 | const int frame_rate_den_ = 1; | |
36 | const int target_bitrate_ = 1000; | |
37 | const int num_frames_ = 17; | |
38 | const std::string in_file_path_str_ = "bus_352x288_420_f20_b8.yuv"; | |
39 | }; | |
40 | ||
41 | TEST_F(SimpleEncodeTest, ComputeFirstPassStats) { | |
42 | SimpleEncode simple_encode(width_, height_, frame_rate_num_, frame_rate_den_, | |
43 | target_bitrate_, num_frames_, | |
44 | in_file_path_str_.c_str()); | |
41 | 45 | simple_encode.ComputeFirstPassStats(); |
42 | 46 | std::vector<std::vector<double>> frame_stats = |
43 | 47 | simple_encode.ObserveFirstPassStats(); |
44 | EXPECT_EQ(frame_stats.size(), static_cast<size_t>(num_frames)); | |
45 | size_t data_num = frame_stats[0].size(); | |
48 | EXPECT_EQ(frame_stats.size(), static_cast<size_t>(num_frames_)); | |
49 | const size_t data_num = frame_stats[0].size(); | |
46 | 50 | // Read ObserveFirstPassStats before changing FIRSTPASS_STATS. |
47 | 51 | EXPECT_EQ(data_num, static_cast<size_t>(25)); |
48 | 52 | for (size_t i = 0; i < frame_stats.size(); ++i) { |
55 | 59 | } |
56 | 60 | } |
57 | 61 | |
58 | TEST(SimpleEncode, GetCodingFrameNum) { | |
59 | SimpleEncode simple_encode(w, h, frame_rate_num, frame_rate_den, | |
60 | target_bitrate, num_frames, infile_path); | |
62 | TEST_F(SimpleEncodeTest, ObserveFirstPassMotionVectors) { | |
63 | SimpleEncode simple_encode(width_, height_, frame_rate_num_, frame_rate_den_, | |
64 | target_bitrate_, num_frames_, | |
65 | in_file_path_str_.c_str()); | |
66 | simple_encode.ComputeFirstPassStats(); | |
67 | std::vector<std::vector<MotionVectorInfo>> fps_motion_vectors = | |
68 | simple_encode.ObserveFirstPassMotionVectors(); | |
69 | EXPECT_EQ(fps_motion_vectors.size(), static_cast<size_t>(num_frames_)); | |
70 | const size_t num_blocks = ((width_ + 15) >> 4) * ((height_ + 15) >> 4); | |
71 | EXPECT_EQ(num_blocks, fps_motion_vectors[0].size()); | |
72 | for (size_t i = 0; i < fps_motion_vectors.size(); ++i) { | |
73 | EXPECT_EQ(num_blocks, fps_motion_vectors[i].size()); | |
74 | for (size_t j = 0; j < num_blocks; ++j) { | |
75 | const int mv_count = fps_motion_vectors[i][j].mv_count; | |
76 | const int ref_count = | |
77 | (fps_motion_vectors[i][j].ref_frame[0] != kRefFrameTypeNone) + | |
78 | (fps_motion_vectors[i][j].ref_frame[1] != kRefFrameTypeNone); | |
79 | EXPECT_EQ(mv_count, ref_count); | |
80 | } | |
81 | } | |
82 | } | |
83 | ||
84 | TEST_F(SimpleEncodeTest, GetCodingFrameNum) { | |
85 | SimpleEncode simple_encode(width_, height_, frame_rate_num_, frame_rate_den_, | |
86 | target_bitrate_, num_frames_, | |
87 | in_file_path_str_.c_str()); | |
88 | simple_encode.ComputeFirstPassStats(); | |
89 | const int num_coding_frames = simple_encode.GetCodingFrameNum(); | |
90 | EXPECT_EQ(num_coding_frames, 19); | |
91 | } | |
92 | ||
93 | TEST_F(SimpleEncodeTest, EncodeFrame) { | |
94 | SimpleEncode simple_encode(width_, height_, frame_rate_num_, frame_rate_den_, | |
95 | target_bitrate_, num_frames_, | |
96 | in_file_path_str_.c_str()); | |
61 | 97 | simple_encode.ComputeFirstPassStats(); |
62 | 98 | int num_coding_frames = simple_encode.GetCodingFrameNum(); |
63 | EXPECT_EQ(num_coding_frames, 19); | |
64 | } | |
65 | ||
66 | TEST(SimpleEncode, EncodeFrame) { | |
67 | SimpleEncode simple_encode(w, h, frame_rate_num, frame_rate_den, | |
68 | target_bitrate, num_frames, infile_path); | |
69 | simple_encode.ComputeFirstPassStats(); | |
70 | int num_coding_frames = simple_encode.GetCodingFrameNum(); | |
71 | EXPECT_GE(num_coding_frames, num_frames); | |
99 | EXPECT_GE(num_coding_frames, num_frames_); | |
72 | 100 | simple_encode.StartEncode(); |
73 | 101 | size_t total_data_bit_size = 0; |
74 | 102 | int coded_show_frame_count = 0; |
75 | 103 | int frame_coding_index = 0; |
76 | while (coded_show_frame_count < num_frames) { | |
104 | while (coded_show_frame_count < num_frames_) { | |
77 | 105 | const GroupOfPicture group_of_picture = |
78 | 106 | simple_encode.ObserveGroupOfPicture(); |
79 | 107 | const std::vector<EncodeFrameInfo> &encode_frame_list = |
98 | 126 | } |
99 | 127 | coded_show_frame_count += group_of_picture.show_frame_count; |
100 | 128 | } |
101 | const double bitrate = GetBitrateInKbps(total_data_bit_size, num_frames, | |
102 | frame_rate_num, frame_rate_den); | |
129 | const double bitrate = GetBitrateInKbps(total_data_bit_size, num_frames_, | |
130 | frame_rate_num_, frame_rate_den_); | |
103 | 131 | const double off_target_threshold = 150; |
104 | EXPECT_LE(fabs(target_bitrate - bitrate), off_target_threshold); | |
105 | simple_encode.EndEncode(); | |
106 | } | |
107 | ||
108 | TEST(SimpleEncode, ObserveKeyFrameMap) { | |
109 | SimpleEncode simple_encode(w, h, frame_rate_num, frame_rate_den, | |
110 | target_bitrate, num_frames, infile_path); | |
132 | EXPECT_LE(fabs(target_bitrate_ - bitrate), off_target_threshold); | |
133 | simple_encode.EndEncode(); | |
134 | } | |
135 | ||
136 | TEST_F(SimpleEncodeTest, ObserveKeyFrameMap) { | |
137 | SimpleEncode simple_encode(width_, height_, frame_rate_num_, frame_rate_den_, | |
138 | target_bitrate_, num_frames_, | |
139 | in_file_path_str_.c_str()); | |
111 | 140 | simple_encode.ComputeFirstPassStats(); |
112 | 141 | std::vector<int> key_frame_map = simple_encode.ObserveKeyFrameMap(); |
113 | EXPECT_EQ(key_frame_map.size(), static_cast<size_t>(num_frames)); | |
142 | EXPECT_EQ(key_frame_map.size(), static_cast<size_t>(num_frames_)); | |
114 | 143 | simple_encode.StartEncode(); |
115 | 144 | int coded_show_frame_count = 0; |
116 | while (coded_show_frame_count < num_frames) { | |
145 | while (coded_show_frame_count < num_frames_) { | |
117 | 146 | const GroupOfPicture group_of_picture = |
118 | 147 | simple_encode.ObserveGroupOfPicture(); |
119 | 148 | const std::vector<EncodeFrameInfo> &encode_frame_list = |
133 | 162 | simple_encode.EndEncode(); |
134 | 163 | } |
135 | 164 | |
136 | TEST(SimpleEncode, EncodeFrameWithQuantizeIndex) { | |
137 | SimpleEncode simple_encode(w, h, frame_rate_num, frame_rate_den, | |
138 | target_bitrate, num_frames, infile_path); | |
139 | simple_encode.ComputeFirstPassStats(); | |
140 | int num_coding_frames = simple_encode.GetCodingFrameNum(); | |
165 | TEST_F(SimpleEncodeTest, EncodeFrameWithTargetFrameBits) { | |
166 | SimpleEncode simple_encode(width_, height_, frame_rate_num_, frame_rate_den_, | |
167 | target_bitrate_, num_frames_, | |
168 | in_file_path_str_.c_str()); | |
169 | simple_encode.ComputeFirstPassStats(); | |
170 | const int num_coding_frames = simple_encode.GetCodingFrameNum(); | |
171 | simple_encode.StartEncode(); | |
172 | for (int i = 0; i < num_coding_frames; ++i) { | |
173 | EncodeFrameInfo encode_frame_info = simple_encode.GetNextEncodeFrameInfo(); | |
174 | int target_frame_bits; | |
175 | switch (encode_frame_info.frame_type) { | |
176 | case kFrameTypeInter: target_frame_bits = 20000; break; | |
177 | case kFrameTypeKey: | |
178 | case kFrameTypeAltRef: | |
179 | case kFrameTypeGolden: target_frame_bits = 100000; break; | |
180 | case kFrameTypeOverlay: target_frame_bits = 2000; break; | |
181 | default: target_frame_bits = 20000; | |
182 | } | |
183 | ||
184 | double percent_diff = 15; | |
185 | if (encode_frame_info.frame_type == kFrameTypeOverlay) { | |
186 | percent_diff = 100; | |
187 | } | |
188 | EncodeFrameResult encode_frame_result; | |
189 | simple_encode.EncodeFrameWithTargetFrameBits( | |
190 | &encode_frame_result, target_frame_bits, percent_diff); | |
191 | const int recode_count = encode_frame_result.recode_count; | |
192 | // TODO(angiebird): Replace 7 by RATE_CTRL_MAX_RECODE_NUM | |
193 | EXPECT_LE(recode_count, 7); | |
194 | EXPECT_GE(recode_count, 1); | |
195 | ||
196 | const double diff = fabs((double)encode_frame_result.coding_data_bit_size - | |
197 | target_frame_bits); | |
198 | EXPECT_LE(diff * 100 / target_frame_bits, percent_diff); | |
199 | } | |
200 | simple_encode.EndEncode(); | |
201 | } | |
202 | ||
203 | TEST_F(SimpleEncodeTest, EncodeFrameWithQuantizeIndex) { | |
204 | SimpleEncode simple_encode(width_, height_, frame_rate_num_, frame_rate_den_, | |
205 | target_bitrate_, num_frames_, | |
206 | in_file_path_str_.c_str()); | |
207 | simple_encode.ComputeFirstPassStats(); | |
208 | const int num_coding_frames = simple_encode.GetCodingFrameNum(); | |
141 | 209 | simple_encode.StartEncode(); |
142 | 210 | for (int i = 0; i < num_coding_frames; ++i) { |
143 | 211 | const int assigned_quantize_index = 100 + i; |
149 | 217 | simple_encode.EndEncode(); |
150 | 218 | } |
151 | 219 | |
152 | TEST(SimpleEncode, EncodeConsistencyTest) { | |
220 | // This test encodes the video using EncodeFrame(), where quantize indexes | |
221 | // are selected by vp9 rate control. | |
222 | // Encode stats and the quantize_indexes are collected. | |
223 | // Then the test encodes the video again using EncodeFrameWithQuantizeIndex() | |
224 | // using the quantize indexes collected from the first run. | |
225 | // Then test whether the encode stats of the two encoding runs match. | |
226 | TEST_F(SimpleEncodeTest, EncodeConsistencyTest) { | |
153 | 227 | std::vector<int> quantize_index_list; |
154 | 228 | std::vector<uint64_t> ref_sse_list; |
155 | 229 | std::vector<double> ref_psnr_list; |
156 | 230 | std::vector<size_t> ref_bit_size_list; |
231 | std::vector<FrameType> ref_frame_type_list; | |
232 | std::vector<int> ref_show_idx_list; | |
157 | 233 | { |
158 | 234 | // The first encode. |
159 | SimpleEncode simple_encode(w, h, frame_rate_num, frame_rate_den, | |
160 | target_bitrate, num_frames, infile_path); | |
235 | SimpleEncode simple_encode(width_, height_, frame_rate_num_, | |
236 | frame_rate_den_, target_bitrate_, num_frames_, | |
237 | in_file_path_str_.c_str()); | |
161 | 238 | simple_encode.ComputeFirstPassStats(); |
162 | 239 | const int num_coding_frames = simple_encode.GetCodingFrameNum(); |
163 | 240 | simple_encode.StartEncode(); |
168 | 245 | ref_sse_list.push_back(encode_frame_result.sse); |
169 | 246 | ref_psnr_list.push_back(encode_frame_result.psnr); |
170 | 247 | ref_bit_size_list.push_back(encode_frame_result.coding_data_bit_size); |
248 | ref_frame_type_list.push_back(encode_frame_result.frame_type); | |
249 | ref_show_idx_list.push_back(encode_frame_result.show_idx); | |
171 | 250 | } |
172 | 251 | simple_encode.EndEncode(); |
173 | 252 | } |
174 | 253 | { |
175 | 254 | // The second encode with quantize index got from the first encode. |
176 | SimpleEncode simple_encode(w, h, frame_rate_num, frame_rate_den, | |
177 | target_bitrate, num_frames, infile_path); | |
255 | SimpleEncode simple_encode(width_, height_, frame_rate_num_, | |
256 | frame_rate_den_, target_bitrate_, num_frames_, | |
257 | in_file_path_str_.c_str()); | |
178 | 258 | simple_encode.ComputeFirstPassStats(); |
179 | 259 | const int num_coding_frames = simple_encode.GetCodingFrameNum(); |
180 | 260 | EXPECT_EQ(static_cast<size_t>(num_coding_frames), |
188 | 268 | EXPECT_EQ(encode_frame_result.sse, ref_sse_list[i]); |
189 | 269 | EXPECT_DOUBLE_EQ(encode_frame_result.psnr, ref_psnr_list[i]); |
190 | 270 | EXPECT_EQ(encode_frame_result.coding_data_bit_size, ref_bit_size_list[i]); |
271 | EXPECT_EQ(encode_frame_result.frame_type, ref_frame_type_list[i]); | |
272 | EXPECT_EQ(encode_frame_result.show_idx, ref_show_idx_list[i]); | |
191 | 273 | } |
192 | 274 | simple_encode.EndEncode(); |
193 | 275 | } |
195 | 277 | |
196 | 278 | // Test the information (partition info and motion vector info) stored in |
197 | 279 | // encoder is the same between two encode runs. |
198 | TEST(SimpleEncode, EncodeConsistencyTest2) { | |
199 | const int num_rows_4x4 = GetNumUnit4x4(w); | |
200 | const int num_cols_4x4 = GetNumUnit4x4(h); | |
280 | TEST_F(SimpleEncodeTest, EncodeConsistencyTest2) { | |
281 | const int num_rows_4x4 = GetNumUnit4x4(width_); | |
282 | const int num_cols_4x4 = GetNumUnit4x4(height_); | |
201 | 283 | const int num_units_4x4 = num_rows_4x4 * num_cols_4x4; |
202 | 284 | // The first encode. |
203 | SimpleEncode simple_encode(w, h, frame_rate_num, frame_rate_den, | |
204 | target_bitrate, num_frames, infile_path); | |
285 | SimpleEncode simple_encode(width_, height_, frame_rate_num_, frame_rate_den_, | |
286 | target_bitrate_, num_frames_, | |
287 | in_file_path_str_.c_str()); | |
205 | 288 | simple_encode.ComputeFirstPassStats(); |
206 | 289 | const int num_coding_frames = simple_encode.GetCodingFrameNum(); |
207 | 290 | std::vector<PartitionInfo> partition_info_list(num_units_4x4 * |
221 | 304 | } |
222 | 305 | simple_encode.EndEncode(); |
223 | 306 | // The second encode. |
224 | SimpleEncode simple_encode_2(w, h, frame_rate_num, frame_rate_den, | |
225 | target_bitrate, num_frames, infile_path); | |
307 | SimpleEncode simple_encode_2(width_, height_, frame_rate_num_, | |
308 | frame_rate_den_, target_bitrate_, num_frames_, | |
309 | in_file_path_str_.c_str()); | |
226 | 310 | simple_encode_2.ComputeFirstPassStats(); |
227 | 311 | const int num_coding_frames_2 = simple_encode_2.GetCodingFrameNum(); |
228 | 312 | simple_encode_2.StartEncode(); |
263 | 347 | } |
264 | 348 | |
265 | 349 | // Test the information stored in encoder is the same between two encode runs. |
266 | TEST(SimpleEncode, EncodeConsistencyTest3) { | |
350 | TEST_F(SimpleEncodeTest, EncodeConsistencyTest3) { | |
267 | 351 | std::vector<int> quantize_index_list; |
268 | const int num_rows_4x4 = GetNumUnit4x4(w); | |
269 | const int num_cols_4x4 = GetNumUnit4x4(h); | |
352 | const int num_rows_4x4 = GetNumUnit4x4(width_); | |
353 | const int num_cols_4x4 = GetNumUnit4x4(height_); | |
270 | 354 | const int num_units_4x4 = num_rows_4x4 * num_cols_4x4; |
271 | 355 | // The first encode. |
272 | SimpleEncode simple_encode(w, h, frame_rate_num, frame_rate_den, | |
273 | target_bitrate, num_frames, infile_path); | |
356 | SimpleEncode simple_encode(width_, height_, frame_rate_num_, frame_rate_den_, | |
357 | target_bitrate_, num_frames_, | |
358 | in_file_path_str_.c_str()); | |
274 | 359 | simple_encode.ComputeFirstPassStats(); |
275 | 360 | const int num_coding_frames = simple_encode.GetCodingFrameNum(); |
276 | 361 | std::vector<PartitionInfo> partition_info_list(num_units_4x4 * |
287 | 372 | } |
288 | 373 | simple_encode.EndEncode(); |
289 | 374 | // The second encode. |
290 | SimpleEncode simple_encode_2(w, h, frame_rate_num, frame_rate_den, | |
291 | target_bitrate, num_frames, infile_path); | |
375 | SimpleEncode simple_encode_2(width_, height_, frame_rate_num_, | |
376 | frame_rate_den_, target_bitrate_, num_frames_, | |
377 | in_file_path_str_.c_str()); | |
292 | 378 | simple_encode_2.ComputeFirstPassStats(); |
293 | 379 | const int num_coding_frames_2 = simple_encode_2.GetCodingFrameNum(); |
294 | 380 | simple_encode_2.StartEncode(); |
318 | 404 | // Get QPs and arf locations from the first encode. |
319 | 405 | // Set external arfs and QPs for the second encode. |
320 | 406 | // Expect to get matched results. |
321 | TEST(SimpleEncode, EncodeConsistencySetExternalGroupOfPicturesMap) { | |
407 | TEST_F(SimpleEncodeTest, EncodeConsistencySetExternalGroupOfPicturesMap) { | |
322 | 408 | std::vector<int> quantize_index_list; |
323 | 409 | std::vector<uint64_t> ref_sse_list; |
324 | 410 | std::vector<double> ref_psnr_list; |
325 | 411 | std::vector<size_t> ref_bit_size_list; |
326 | std::vector<int> gop_map(num_frames, 0); | |
412 | std::vector<int> gop_map(num_frames_, 0); | |
327 | 413 | { |
328 | 414 | // The first encode. |
329 | SimpleEncode simple_encode(w, h, frame_rate_num, frame_rate_den, | |
330 | target_bitrate, num_frames, infile_path); | |
415 | SimpleEncode simple_encode(width_, height_, frame_rate_num_, | |
416 | frame_rate_den_, target_bitrate_, num_frames_, | |
417 | in_file_path_str_.c_str()); | |
331 | 418 | simple_encode.ComputeFirstPassStats(); |
332 | 419 | simple_encode.StartEncode(); |
333 | 420 | |
334 | 421 | int coded_show_frame_count = 0; |
335 | while (coded_show_frame_count < num_frames) { | |
422 | while (coded_show_frame_count < num_frames_) { | |
336 | 423 | const GroupOfPicture group_of_picture = |
337 | 424 | simple_encode.ObserveGroupOfPicture(); |
338 | 425 | gop_map[coded_show_frame_count] |= kGopMapFlagStart; |
357 | 444 | { |
358 | 445 | // The second encode with quantize index got from the first encode. |
359 | 446 | // The external arfs are the same as the first encode. |
360 | SimpleEncode simple_encode(w, h, frame_rate_num, frame_rate_den, | |
361 | target_bitrate, num_frames, infile_path); | |
447 | SimpleEncode simple_encode(width_, height_, frame_rate_num_, | |
448 | frame_rate_den_, target_bitrate_, num_frames_, | |
449 | in_file_path_str_.c_str()); | |
362 | 450 | simple_encode.ComputeFirstPassStats(); |
363 | simple_encode.SetExternalGroupOfPicturesMap(gop_map); | |
451 | simple_encode.SetExternalGroupOfPicturesMap(gop_map.data(), gop_map.size()); | |
364 | 452 | const int num_coding_frames = simple_encode.GetCodingFrameNum(); |
365 | 453 | EXPECT_EQ(static_cast<size_t>(num_coding_frames), |
366 | 454 | quantize_index_list.size()); |
378 | 466 | } |
379 | 467 | } |
380 | 468 | |
381 | TEST(SimpleEncode, SetExternalGroupOfPicturesMap) { | |
382 | SimpleEncode simple_encode(w, h, frame_rate_num, frame_rate_den, | |
383 | target_bitrate, num_frames, infile_path); | |
384 | simple_encode.ComputeFirstPassStats(); | |
385 | ||
386 | std::vector<int> gop_map(num_frames, 0); | |
469 | TEST_F(SimpleEncodeTest, SetExternalGroupOfPicturesMap) { | |
470 | SimpleEncode simple_encode(width_, height_, frame_rate_num_, frame_rate_den_, | |
471 | target_bitrate_, num_frames_, | |
472 | in_file_path_str_.c_str()); | |
473 | simple_encode.ComputeFirstPassStats(); | |
474 | ||
475 | std::vector<int> gop_map(num_frames_, 0); | |
387 | 476 | |
388 | 477 | // Should be the first gop group. |
389 | 478 | gop_map[0] = 0; |
397 | 486 | // Last gop group. |
398 | 487 | gop_map[14] |= kGopMapFlagStart | kGopMapFlagUseAltRef; |
399 | 488 | |
400 | simple_encode.SetExternalGroupOfPicturesMap(gop_map); | |
489 | simple_encode.SetExternalGroupOfPicturesMap(gop_map.data(), gop_map.size()); | |
401 | 490 | |
402 | 491 | std::vector<int> observed_gop_map = |
403 | 492 | simple_encode.ObserveExternalGroupOfPicturesMap(); |
424 | 513 | |
425 | 514 | simple_encode.StartEncode(); |
426 | 515 | int coded_show_frame_count = 0; |
427 | while (coded_show_frame_count < num_frames) { | |
516 | while (coded_show_frame_count < num_frames_) { | |
428 | 517 | const GroupOfPicture group_of_picture = |
429 | 518 | simple_encode.ObserveGroupOfPicture(); |
430 | 519 | const std::vector<EncodeFrameInfo> &encode_frame_list = |
445 | 534 | simple_encode.EndEncode(); |
446 | 535 | } |
447 | 536 | |
448 | TEST(SimpleEncode, GetEncodeFrameInfo) { | |
537 | TEST_F(SimpleEncodeTest, GetEncodeFrameInfo) { | |
449 | 538 | // Makes sure that the encode_frame_info obtained from GetEncodeFrameInfo() |
450 | 539 | // matches the counterpart in encode_frame_result obtained from EncodeFrame() |
451 | SimpleEncode simple_encode(w, h, frame_rate_num, frame_rate_den, | |
452 | target_bitrate, num_frames, infile_path); | |
540 | SimpleEncode simple_encode(width_, height_, frame_rate_num_, frame_rate_den_, | |
541 | target_bitrate_, num_frames_, | |
542 | in_file_path_str_.c_str()); | |
453 | 543 | simple_encode.ComputeFirstPassStats(); |
454 | 544 | const int num_coding_frames = simple_encode.GetCodingFrameNum(); |
455 | 545 | simple_encode.StartEncode(); |
463 | 553 | simple_encode.EndEncode(); |
464 | 554 | } |
465 | 555 | |
466 | TEST(SimpleEncode, GetFramePixelCount) { | |
467 | SimpleEncode simple_encode(w, h, frame_rate_num, frame_rate_den, | |
468 | target_bitrate, num_frames, infile_path); | |
556 | TEST_F(SimpleEncodeTest, GetFramePixelCount) { | |
557 | SimpleEncode simple_encode(width_, height_, frame_rate_num_, frame_rate_den_, | |
558 | target_bitrate_, num_frames_, | |
559 | in_file_path_str_.c_str()); | |
469 | 560 | EXPECT_EQ(simple_encode.GetFramePixelCount(), |
470 | static_cast<uint64_t>(w * h * 3 / 2)); | |
561 | static_cast<uint64_t>(width_ * height_ * 3 / 2)); | |
471 | 562 | } |
472 | 563 | |
473 | 564 | } // namespace |
17 | 17 | YUV="${LIBVPX_TEST_DATA_PATH}/niklas_1280_720_30.yuv" |
18 | 18 | VP8="${LIBVPX_TEST_DATA_PATH}/tos_vp8.webm" |
19 | 19 | VP9="${LIBVPX_TEST_DATA_PATH}/vp90-2-sintel_1920x818_tile_1x4_fpm_2279kbps.webm" |
20 | DATA_URL="http://downloads.webmproject.org/test_data/libvpx/" | |
20 | DATA_URL="https://storage.googleapis.com/downloads.webmproject.org/test_data/libvpx/" | |
21 | 21 | SHA1_FILE="$(dirname $0)/test-data.sha1" |
22 | 22 | |
23 | 23 | # Set sha1sum to proper sha program (sha1sum, shasum, sha1). This code is |
44 | 44 | SSI16Func ref_func_; |
45 | 45 | SSI16Func tst_func_; |
46 | 46 | }; |
47 | GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(SumSquaresTest); | |
47 | 48 | |
48 | 49 | TEST_P(SumSquaresTest, OperationCheck) { |
49 | 50 | ACMRandom rnd(ACMRandom::DeterministicSeed()); |
26 | 26 | public ::libvpx_test::CodecTestWithParam<SuperframeTestParam> { |
27 | 27 | protected: |
28 | 28 | SuperframeTest() |
29 | : EncoderTest(GET_PARAM(0)), modified_buf_(NULL), last_sf_pts_(0) {} | |
29 | : EncoderTest(GET_PARAM(0)), modified_buf_(nullptr), last_sf_pts_(0) {} | |
30 | 30 | virtual ~SuperframeTest() {} |
31 | 31 | |
32 | 32 | virtual void SetUp() { |
83 | 83 | prev_frame_width[i] = 320; |
84 | 84 | prev_frame_height[i] = 240; |
85 | 85 | } |
86 | ksvc_flex_noupd_tlenh_ = false; | |
86 | 87 | } |
87 | 88 | virtual void BeginPassHook(unsigned int /*pass*/) {} |
88 | 89 | |
90 | 91 | // bypass/flexible mode. The pattern corresponds to the pattern |
91 | 92 | // VP9E_TEMPORAL_LAYERING_MODE_0101 (temporal_layering_mode == 2) used in |
92 | 93 | // non-flexible mode, except that we disable inter-layer prediction. |
93 | void set_frame_flags_bypass_mode( | |
94 | int tl, int num_spatial_layers, int is_key_frame, | |
95 | vpx_svc_ref_frame_config_t *ref_frame_config) { | |
94 | void set_frame_flags_bypass_mode(int tl, int num_spatial_layers, | |
95 | int is_key_frame, | |
96 | vpx_svc_ref_frame_config_t *ref_frame_config, | |
97 | int noupdate_tlenh) { | |
96 | 98 | for (int sl = 0; sl < num_spatial_layers; ++sl) |
97 | 99 | ref_frame_config->update_buffer_slot[sl] = 0; |
98 | 100 | |
150 | 152 | ref_frame_config->reference_last[sl] = 1; |
151 | 153 | ref_frame_config->reference_golden[sl] = 0; |
152 | 154 | ref_frame_config->reference_alt_ref[sl] = 0; |
153 | ref_frame_config->update_buffer_slot[sl] |= | |
154 | 1 << ref_frame_config->alt_fb_idx[sl]; | |
155 | // Non reference frame on top temporal top spatial. | |
156 | ref_frame_config->update_buffer_slot[sl] = 0; | |
155 | 157 | } |
158 | // Force no update on all spatial layers for temporal enhancement layer | |
159 | // frames. | |
160 | if (noupdate_tlenh) ref_frame_config->update_buffer_slot[sl] = 0; | |
156 | 161 | } |
157 | 162 | } |
158 | 163 | } |
243 | 248 | } |
244 | 249 | } |
245 | 250 | |
251 | if (ksvc_flex_noupd_tlenh_) { | |
252 | vpx_svc_layer_id_t layer_id; | |
253 | layer_id.spatial_layer_id = 0; | |
254 | layer_id.temporal_layer_id = (video->frame() % 2 != 0); | |
255 | temporal_layer_id_ = layer_id.temporal_layer_id; | |
256 | for (int i = 0; i < number_spatial_layers_; i++) { | |
257 | layer_id.temporal_layer_id_per_spatial[i] = temporal_layer_id_; | |
258 | ref_frame_config.duration[i] = 1; | |
259 | } | |
260 | encoder->Control(VP9E_SET_SVC_LAYER_ID, &layer_id); | |
261 | set_frame_flags_bypass_mode(layer_id.temporal_layer_id, | |
262 | number_spatial_layers_, 0, &ref_frame_config, | |
263 | 1); | |
264 | encoder->Control(VP9E_SET_SVC_REF_FRAME_CONFIG, &ref_frame_config); | |
265 | } | |
266 | ||
246 | 267 | if (update_pattern_ && video->frame() >= 100) { |
247 | 268 | vpx_svc_layer_id_t layer_id; |
248 | 269 | if (video->frame() == 100) { |
253 | 274 | layer_id.spatial_layer_id = 0; |
254 | 275 | layer_id.temporal_layer_id = (video->frame() % 2 != 0); |
255 | 276 | temporal_layer_id_ = layer_id.temporal_layer_id; |
256 | for (int i = 0; i < number_spatial_layers_; i++) | |
277 | for (int i = 0; i < number_spatial_layers_; i++) { | |
257 | 278 | layer_id.temporal_layer_id_per_spatial[i] = temporal_layer_id_; |
279 | ref_frame_config.duration[i] = 1; | |
280 | } | |
258 | 281 | encoder->Control(VP9E_SET_SVC_LAYER_ID, &layer_id); |
259 | 282 | set_frame_flags_bypass_mode(layer_id.temporal_layer_id, |
260 | number_spatial_layers_, 0, &ref_frame_config); | |
283 | number_spatial_layers_, 0, &ref_frame_config, | |
284 | 0); | |
261 | 285 | encoder->Control(VP9E_SET_SVC_REF_FRAME_CONFIG, &ref_frame_config); |
262 | 286 | } |
263 | 287 | |
556 | 580 | } |
557 | 581 | |
558 | 582 | virtual void MismatchHook(const vpx_image_t *img1, const vpx_image_t *img2) { |
559 | double mismatch_psnr = compute_psnr(img1, img2); | |
560 | mismatch_psnr_ += mismatch_psnr; | |
561 | ++mismatch_nframes_; | |
583 | // TODO(marpan): Look into why an assert is triggered in compute_psnr | |
584 | // for mismatch frames for the special test case: ksvc_flex_noupd_tlenh. | |
585 | // Has to do with dropped frames in bypass/flexible svc mode. | |
586 | if (!ksvc_flex_noupd_tlenh_) { | |
587 | double mismatch_psnr = compute_psnr(img1, img2); | |
588 | mismatch_psnr_ += mismatch_psnr; | |
589 | ++mismatch_nframes_; | |
590 | } | |
562 | 591 | } |
563 | 592 | |
564 | 593 | unsigned int GetMismatchFrames() { return mismatch_nframes_; } |
603 | 632 | int num_resize_down_; |
604 | 633 | unsigned int prev_frame_width[VPX_MAX_LAYERS]; |
605 | 634 | unsigned int prev_frame_height[VPX_MAX_LAYERS]; |
635 | bool ksvc_flex_noupd_tlenh_; | |
606 | 636 | |
607 | 637 | private: |
608 | 638 | virtual void SetConfig(const int num_temporal_layer) { |
721 | 751 | cfg_.g_threads = 1; |
722 | 752 | cfg_.rc_dropframe_thresh = 30; |
723 | 753 | cfg_.kf_max_dist = 9999; |
724 | // Change SVC pattern on the fly. | |
725 | update_pattern_ = 1; | |
726 | 754 | ::libvpx_test::I420VideoSource video("niklas_640_480_30.yuv", 640, 480, 30, 1, |
727 | 755 | 0, 400); |
728 | 756 | top_sl_width_ = 640; |
729 | 757 | top_sl_height_ = 480; |
730 | 758 | cfg_.rc_target_bitrate = 800; |
731 | 759 | ResetModel(); |
760 | // Change SVC pattern on the fly. | |
761 | update_pattern_ = 1; | |
732 | 762 | AssignLayerBitrates(); |
733 | 763 | ASSERT_NO_FATAL_FAILURE(RunLoop(&video)); |
734 | 764 | CheckLayerRateTargeting(number_spatial_layers_, number_temporal_layers_, 0.78, |
1105 | 1135 | #endif |
1106 | 1136 | } |
1107 | 1137 | |
1138 | // Check basic rate targeting for 1 pass CBR SVC: 3 spatial layers and | |
1139 | // 2 temporal layers, for KSVC in flexible mode with no update of reference | |
1140 | // frames for all spatial layers on TL > 0 superframes. | |
1141 | // Run HD clip with 4 threads. | |
1142 | TEST_P(DatarateOnePassCbrSvcFrameDropMultiBR, OnePassCbrSvc3SL2TL4ThKSVCFlex) { | |
1143 | SetSvcConfig(3, 2); | |
1144 | cfg_.rc_buf_initial_sz = 500; | |
1145 | cfg_.rc_buf_optimal_sz = 500; | |
1146 | cfg_.rc_buf_sz = 1000; | |
1147 | cfg_.rc_min_quantizer = 0; | |
1148 | cfg_.rc_max_quantizer = 63; | |
1149 | cfg_.g_threads = 4; | |
1150 | cfg_.rc_dropframe_thresh = 30; | |
1151 | cfg_.kf_max_dist = 9999; | |
1152 | ::libvpx_test::Y4mVideoSource video("niklas_1280_720_30.y4m", 0, 60); | |
1153 | top_sl_width_ = 1280; | |
1154 | top_sl_height_ = 720; | |
1155 | layer_framedrop_ = 0; | |
1156 | const int bitrates[3] = { 200, 400, 600 }; | |
1157 | cfg_.rc_target_bitrate = bitrates[GET_PARAM(3)]; | |
1158 | ResetModel(); | |
1159 | layer_framedrop_ = GET_PARAM(2); | |
1160 | AssignLayerBitrates(); | |
1161 | ksvc_flex_noupd_tlenh_ = true; | |
1162 | cfg_.temporal_layering_mode = VP9E_TEMPORAL_LAYERING_MODE_BYPASS; | |
1163 | ASSERT_NO_FATAL_FAILURE(RunLoop(&video)); | |
1164 | CheckLayerRateTargeting(number_spatial_layers_, number_temporal_layers_, 0.58, | |
1165 | 1.2); | |
1166 | } | |
1167 | ||
1108 | 1168 | // Params: speed setting, inter-layer prediction mode. |
1109 | 1169 | class DatarateOnePassCbrSvcInterLayerPredSingleBR |
1110 | 1170 | : public DatarateOnePassCbrSvc, |
120 | 120 | frame_to_start_decode_(0), frame_to_sync_(0), |
121 | 121 | inter_layer_pred_mode_(GET_PARAM(1)), decode_to_layer_before_sync_(-1), |
122 | 122 | decode_to_layer_after_sync_(-1), denoiser_on_(0), |
123 | intra_only_test_(false), mismatch_nframes_(0), num_nonref_frames_(0) { | |
123 | intra_only_test_(false), loopfilter_off_(0), mismatch_nframes_(0), | |
124 | num_nonref_frames_(0) { | |
124 | 125 | SetMode(::libvpx_test::kRealTime); |
125 | 126 | memset(&svc_layer_sync_, 0, sizeof(svc_layer_sync_)); |
126 | 127 | } |
153 | 154 | // So set it here in these tess to avoid encoder-decoder |
154 | 155 | // mismatch check on color space setting. |
155 | 156 | encoder->Control(VP9E_SET_COLOR_SPACE, VPX_CS_BT_601); |
157 | ||
158 | encoder->Control(VP9E_SET_DISABLE_LOOPFILTER, loopfilter_off_); | |
156 | 159 | } |
157 | 160 | if (video->frame() == frame_to_sync_) { |
158 | 161 | encoder->Control(VP9E_SET_SVC_SPATIAL_LAYER_SYNC, &svc_layer_sync_); |
213 | 216 | int decode_to_layer_after_sync_; |
214 | 217 | int denoiser_on_; |
215 | 218 | bool intra_only_test_; |
219 | int loopfilter_off_; | |
216 | 220 | vpx_svc_spatial_layer_sync_t svc_layer_sync_; |
221 | unsigned int mismatch_nframes_; | |
222 | unsigned int num_nonref_frames_; | |
217 | 223 | |
218 | 224 | private: |
219 | 225 | virtual void SetConfig(const int num_temporal_layer) { |
242 | 248 | cfg_.temporal_layering_mode = 1; |
243 | 249 | } |
244 | 250 | } |
245 | ||
246 | unsigned int mismatch_nframes_; | |
247 | unsigned int num_nonref_frames_; | |
248 | 251 | }; |
249 | 252 | |
250 | 253 | // Test for sync layer for 1 pass CBR SVC: 3 spatial layers and |
469 | 472 | #endif |
470 | 473 | } |
471 | 474 | |
475 | // Params: Loopfilter modes. | |
476 | class LoopfilterOnePassCbrSvc : public OnePassCbrSvc, | |
477 | public ::libvpx_test::CodecTestWithParam<int> { | |
478 | public: | |
479 | LoopfilterOnePassCbrSvc() | |
480 | : OnePassCbrSvc(GET_PARAM(0)), loopfilter_off_(GET_PARAM(1)), | |
481 | mismatch_nframes_(0), num_nonref_frames_(0) { | |
482 | SetMode(::libvpx_test::kRealTime); | |
483 | } | |
484 | ||
485 | protected: | |
486 | virtual ~LoopfilterOnePassCbrSvc() {} | |
487 | ||
488 | virtual void SetUp() { | |
489 | InitializeConfig(); | |
490 | speed_setting_ = 7; | |
491 | } | |
492 | ||
493 | virtual void PreEncodeFrameHook(::libvpx_test::VideoSource *video, | |
494 | ::libvpx_test::Encoder *encoder) { | |
495 | PreEncodeFrameHookSetup(video, encoder); | |
496 | if (number_temporal_layers_ > 1 || number_spatial_layers_ > 1) { | |
497 | // Consider 3 cases: | |
498 | if (loopfilter_off_ == 0) { | |
499 | // loopfilter is on for all spatial layers on every superrframe. | |
500 | for (int i = 0; i < VPX_SS_MAX_LAYERS; ++i) { | |
501 | svc_params_.loopfilter_ctrl[i] = 0; | |
502 | } | |
503 | } else if (loopfilter_off_ == 1) { | |
504 | // loopfilter is off for non-reference frames for all spatial layers. | |
505 | for (int i = 0; i < VPX_SS_MAX_LAYERS; ++i) { | |
506 | svc_params_.loopfilter_ctrl[i] = 1; | |
507 | } | |
508 | } else { | |
509 | // loopfilter is off for all SL0 frames, and off only for non-reference | |
510 | // frames for SL > 0. | |
511 | svc_params_.loopfilter_ctrl[0] = 2; | |
512 | for (int i = 1; i < VPX_SS_MAX_LAYERS; ++i) { | |
513 | svc_params_.loopfilter_ctrl[i] = 1; | |
514 | } | |
515 | } | |
516 | encoder->Control(VP9E_SET_SVC_PARAMETERS, &svc_params_); | |
517 | } else if (number_temporal_layers_ == 1 && number_spatial_layers_ == 1) { | |
518 | // For non-SVC mode use the single layer control. | |
519 | encoder->Control(VP9E_SET_DISABLE_LOOPFILTER, loopfilter_off_); | |
520 | } | |
521 | } | |
522 | ||
523 | virtual void FramePktHook(const vpx_codec_cx_pkt_t *pkt) { | |
524 | // Keep track of number of non-reference frames, needed for mismatch check. | |
525 | // Non-reference frames are top spatial and temporal layer frames, | |
526 | // for TL > 0. | |
527 | if (temporal_layer_id_ == number_temporal_layers_ - 1 && | |
528 | temporal_layer_id_ > 0 && | |
529 | pkt->data.frame.spatial_layer_encoded[number_spatial_layers_ - 1]) | |
530 | num_nonref_frames_++; | |
531 | } | |
532 | ||
533 | virtual void MismatchHook(const vpx_image_t * /*img1*/, | |
534 | const vpx_image_t * /*img2*/) { | |
535 | ++mismatch_nframes_; | |
536 | } | |
537 | ||
538 | virtual void SetConfig(const int /*num_temporal_layer*/) {} | |
539 | ||
540 | int GetMismatchFrames() const { return mismatch_nframes_; } | |
541 | int GetNonRefFrames() const { return num_nonref_frames_; } | |
542 | ||
543 | int loopfilter_off_; | |
544 | ||
545 | private: | |
546 | int mismatch_nframes_; | |
547 | int num_nonref_frames_; | |
548 | }; | |
549 | ||
550 | TEST_P(LoopfilterOnePassCbrSvc, OnePassCbrSvc1SL1TLLoopfilterOff) { | |
551 | SetSvcConfig(1, 1); | |
552 | cfg_.rc_buf_initial_sz = 500; | |
553 | cfg_.rc_buf_optimal_sz = 500; | |
554 | cfg_.rc_buf_sz = 1000; | |
555 | cfg_.rc_min_quantizer = 0; | |
556 | cfg_.rc_max_quantizer = 63; | |
557 | cfg_.g_threads = 1; | |
558 | cfg_.rc_dropframe_thresh = 0; | |
559 | cfg_.rc_target_bitrate = 800; | |
560 | cfg_.kf_max_dist = 9999; | |
561 | cfg_.rc_end_usage = VPX_CBR; | |
562 | cfg_.g_lag_in_frames = 0; | |
563 | cfg_.g_error_resilient = 1; | |
564 | cfg_.ts_rate_decimator[0] = 1; | |
565 | cfg_.temporal_layering_mode = 0; | |
566 | ::libvpx_test::I420VideoSource video("niklas_640_480_30.yuv", 640, 480, 30, 1, | |
567 | 0, 400); | |
568 | cfg_.rc_target_bitrate = 600; | |
569 | AssignLayerBitrates(); | |
570 | ASSERT_NO_FATAL_FAILURE(RunLoop(&video)); | |
571 | #if CONFIG_VP9_DECODER | |
572 | if (loopfilter_off_ == 0) | |
573 | EXPECT_EQ(GetNonRefFrames(), GetMismatchFrames()); | |
574 | else | |
575 | EXPECT_EQ(GetMismatchFrames(), 0); | |
576 | #endif | |
577 | } | |
578 | ||
579 | TEST_P(LoopfilterOnePassCbrSvc, OnePassCbrSvc1SL3TLLoopfilterOff) { | |
580 | SetSvcConfig(1, 3); | |
581 | cfg_.rc_buf_initial_sz = 500; | |
582 | cfg_.rc_buf_optimal_sz = 500; | |
583 | cfg_.rc_buf_sz = 1000; | |
584 | cfg_.rc_min_quantizer = 0; | |
585 | cfg_.rc_max_quantizer = 63; | |
586 | cfg_.g_threads = 1; | |
587 | cfg_.rc_dropframe_thresh = 0; | |
588 | cfg_.rc_target_bitrate = 800; | |
589 | cfg_.kf_max_dist = 9999; | |
590 | cfg_.rc_end_usage = VPX_CBR; | |
591 | cfg_.g_lag_in_frames = 0; | |
592 | cfg_.g_error_resilient = 1; | |
593 | cfg_.ts_rate_decimator[0] = 4; | |
594 | cfg_.ts_rate_decimator[1] = 2; | |
595 | cfg_.ts_rate_decimator[2] = 1; | |
596 | cfg_.temporal_layering_mode = 3; | |
597 | ::libvpx_test::I420VideoSource video("niklas_640_480_30.yuv", 640, 480, 30, 1, | |
598 | 0, 400); | |
599 | cfg_.rc_target_bitrate = 600; | |
600 | AssignLayerBitrates(); | |
601 | ASSERT_NO_FATAL_FAILURE(RunLoop(&video)); | |
602 | #if CONFIG_VP9_DECODER | |
603 | if (loopfilter_off_ == 0) | |
604 | EXPECT_EQ(GetNonRefFrames(), GetMismatchFrames()); | |
605 | else | |
606 | EXPECT_EQ(GetMismatchFrames(), 0); | |
607 | #endif | |
608 | } | |
609 | ||
610 | TEST_P(LoopfilterOnePassCbrSvc, OnePassCbrSvc3SL3TLLoopfilterOff) { | |
611 | SetSvcConfig(3, 3); | |
612 | cfg_.rc_buf_initial_sz = 500; | |
613 | cfg_.rc_buf_optimal_sz = 500; | |
614 | cfg_.rc_buf_sz = 1000; | |
615 | cfg_.rc_min_quantizer = 0; | |
616 | cfg_.rc_max_quantizer = 63; | |
617 | cfg_.g_threads = 1; | |
618 | cfg_.rc_dropframe_thresh = 0; | |
619 | cfg_.rc_target_bitrate = 800; | |
620 | cfg_.kf_max_dist = 9999; | |
621 | cfg_.rc_end_usage = VPX_CBR; | |
622 | cfg_.g_lag_in_frames = 0; | |
623 | cfg_.g_error_resilient = 1; | |
624 | cfg_.ts_rate_decimator[0] = 4; | |
625 | cfg_.ts_rate_decimator[1] = 2; | |
626 | cfg_.ts_rate_decimator[2] = 1; | |
627 | cfg_.temporal_layering_mode = 3; | |
628 | ::libvpx_test::I420VideoSource video("niklas_640_480_30.yuv", 640, 480, 30, 1, | |
629 | 0, 400); | |
630 | cfg_.rc_target_bitrate = 600; | |
631 | AssignLayerBitrates(); | |
632 | ASSERT_NO_FATAL_FAILURE(RunLoop(&video)); | |
633 | #if CONFIG_VP9_DECODER | |
634 | if (loopfilter_off_ == 0) | |
635 | EXPECT_EQ(GetNonRefFrames(), GetMismatchFrames()); | |
636 | else | |
637 | EXPECT_EQ(GetMismatchFrames(), 0); | |
638 | #endif | |
639 | } | |
640 | ||
472 | 641 | VP9_INSTANTIATE_TEST_SUITE(SyncFrameOnePassCbrSvc, ::testing::Range(0, 3)); |
642 | ||
643 | VP9_INSTANTIATE_TEST_SUITE(LoopfilterOnePassCbrSvc, ::testing::Range(0, 3)); | |
473 | 644 | |
474 | 645 | INSTANTIATE_TEST_SUITE_P( |
475 | 646 | VP9, ScalePartitionOnePassCbrSvc, |
42 | 42 | svc_params_.max_quantizers[i] = 63; |
43 | 43 | svc_params_.min_quantizers[i] = 0; |
44 | 44 | } |
45 | svc_params_.speed_per_layer[0] = base_speed_setting_; | |
46 | for (int i = 1; i < VPX_SS_MAX_LAYERS; ++i) { | |
47 | svc_params_.speed_per_layer[i] = speed_setting_; | |
45 | if (number_temporal_layers_ > 1 || number_spatial_layers_ > 1) { | |
46 | svc_params_.speed_per_layer[0] = base_speed_setting_; | |
47 | for (int i = 1; i < VPX_SS_MAX_LAYERS; ++i) { | |
48 | svc_params_.speed_per_layer[i] = speed_setting_; | |
49 | } | |
50 | encoder->Control(VP9E_SET_SVC, 1); | |
51 | encoder->Control(VP9E_SET_SVC_PARAMETERS, &svc_params_); | |
48 | 52 | } |
49 | ||
50 | encoder->Control(VP9E_SET_SVC, 1); | |
51 | encoder->Control(VP9E_SET_SVC_PARAMETERS, &svc_params_); | |
52 | 53 | encoder->Control(VP8E_SET_CPUUSED, speed_setting_); |
53 | 54 | encoder->Control(VP9E_SET_AQ_MODE, 3); |
54 | 55 | encoder->Control(VP8E_SET_MAX_INTRA_BITRATE_PCT, 300); |
26 | 26 | LIBVPX_TEST_DATA-$(CONFIG_VP9_ENCODER) += rush_hour_444.y4m |
27 | 27 | LIBVPX_TEST_DATA-$(CONFIG_VP9_ENCODER) += screendata.y4m |
28 | 28 | LIBVPX_TEST_DATA-$(CONFIG_VP9_ENCODER) += niklas_640_480_30.yuv |
29 | LIBVPX_TEST_DATA-$(CONFIG_RATE_CTRL) += bus_352x288_420_f20_b8.yuv | |
29 | LIBVPX_TEST_DATA-$(CONFIG_VP9_ENCODER) += rc_interface_test_one_layer | |
30 | LIBVPX_TEST_DATA-$(CONFIG_VP9_ENCODER) += rc_interface_test_svc | |
31 | LIBVPX_TEST_DATA-$(CONFIG_VP9_ENCODER) += bus_352x288_420_f20_b8.yuv | |
30 | 32 | |
31 | 33 | # Test vectors |
32 | 34 | LIBVPX_TEST_DATA-$(CONFIG_VP8_DECODER) += vp80-00-comprehensive-001.ivf |
868 | 868 | 518a0be998afece76d3df76047d51e256c591ff2 *invalid-bug-148271109.ivf |
869 | 869 | d3964f9dad9f60363c81b688324d95b4ec7c8038 *invalid-bug-148271109.ivf.res |
870 | 870 | ad18ca16f0a249fb3b7c38de0d9b327fed273f96 *hantro_collage_w352h288_nv12.yuv |
871 | 03f827c0e36ff9a6e23c5cc11936924e4f1827ab *rc_interface_test_one_layer | |
872 | 99e4f4c2961d46dc286db230090a39d78460b25d *rc_interface_test_svc |
57 | 57 | LIBVPX_TEST_SRCS-$(CONFIG_VP9_ENCODER) += svc_test.h |
58 | 58 | LIBVPX_TEST_SRCS-$(CONFIG_VP9_ENCODER) += svc_end_to_end_test.cc |
59 | 59 | LIBVPX_TEST_SRCS-$(CONFIG_VP9_ENCODER) += timestamp_test.cc |
60 | LIBVPX_TEST_SRCS-$(CONFIG_VP9_ENCODER) += vp9_ext_ratectrl_test.cc | |
60 | 61 | |
61 | 62 | LIBVPX_TEST_SRCS-yes += decode_test_driver.cc |
62 | 63 | LIBVPX_TEST_SRCS-yes += decode_test_driver.h |
120 | 121 | LIBVPX_TEST_SRCS-yes += vp8_boolcoder_test.cc |
121 | 122 | LIBVPX_TEST_SRCS-yes += vp8_fragments_test.cc |
122 | 123 | endif |
123 | ||
124 | 124 | LIBVPX_TEST_SRCS-$(CONFIG_POSTPROC) += add_noise_test.cc |
125 | 125 | LIBVPX_TEST_SRCS-$(CONFIG_POSTPROC) += pp_filter_test.cc |
126 | 126 | LIBVPX_TEST_SRCS-$(CONFIG_VP8_DECODER) += vp8_decrypt_test.cc |
127 | ifneq (, $(filter yes, $(HAVE_SSE2) $(HAVE_SSSE3) $(HAVE_SSE4_1) $(HAVE_NEON) \ | |
128 | $(HAVE_MSA) $(HAVE_MMI))) | |
127 | 129 | LIBVPX_TEST_SRCS-$(CONFIG_VP8_ENCODER) += quantize_test.cc |
130 | endif | |
128 | 131 | LIBVPX_TEST_SRCS-$(CONFIG_VP8_ENCODER) += set_roi.cc |
129 | 132 | LIBVPX_TEST_SRCS-$(CONFIG_VP8_ENCODER) += variance_test.cc |
130 | 133 | LIBVPX_TEST_SRCS-$(CONFIG_VP8_ENCODER) += vp8_fdct4x4_test.cc |
173 | 176 | LIBVPX_TEST_SRCS-$(CONFIG_VP9_ENCODER) += yuv_temporal_filter_test.cc |
174 | 177 | endif |
175 | 178 | LIBVPX_TEST_SRCS-$(CONFIG_VP9_ENCODER) += variance_test.cc |
179 | ifneq (, $(filter yes, $(HAVE_SSE2) $(HAVE_AVX2))) | |
176 | 180 | LIBVPX_TEST_SRCS-$(CONFIG_VP9_ENCODER) += vp9_block_error_test.cc |
181 | endif | |
177 | 182 | LIBVPX_TEST_SRCS-$(CONFIG_VP9_ENCODER) += vp9_quantize_test.cc |
178 | 183 | LIBVPX_TEST_SRCS-$(CONFIG_VP9_ENCODER) += vp9_subtract_test.cc |
179 | 184 | |
187 | 192 | endif |
188 | 193 | |
189 | 194 | ifeq ($(CONFIG_VP9_ENCODER)$(CONFIG_VP9_TEMPORAL_DENOISING),yesyes) |
195 | ifneq (, $(filter yes, $(HAVE_SSE2) $(HAVE_AVX2))) | |
190 | 196 | LIBVPX_TEST_SRCS-yes += vp9_denoiser_test.cc |
197 | endif | |
191 | 198 | endif |
192 | 199 | LIBVPX_TEST_SRCS-$(CONFIG_VP9_ENCODER) += vp9_arf_freq_test.cc |
193 | 200 | |
200 | 207 | ## Multi-codec / unconditional whitebox tests. |
201 | 208 | |
202 | 209 | LIBVPX_TEST_SRCS-$(CONFIG_ENCODERS) += sad_test.cc |
210 | ifneq (, $(filter yes, $(HAVE_NEON) $(HAVE_SSE2) $(HAVE_MSA))) | |
203 | 211 | LIBVPX_TEST_SRCS-$(CONFIG_ENCODERS) += sum_squares_test.cc |
212 | endif | |
204 | 213 | |
205 | 214 | TEST_INTRA_PRED_SPEED_SRCS-yes := test_intra_pred_speed.cc |
206 | 215 | TEST_INTRA_PRED_SPEED_SRCS-yes += ../md5_utils.h ../md5_utils.c |
84 | 84 | intra_pred_test_mem.Init(block_size, 8); |
85 | 85 | |
86 | 86 | for (int k = 0; k < kNumVp9IntraPredFuncs; ++k) { |
87 | if (pred_funcs[k] == NULL) continue; | |
87 | if (pred_funcs[k] == nullptr) continue; | |
88 | 88 | memcpy(intra_pred_test_mem.src, intra_pred_test_mem.ref_src, |
89 | 89 | sizeof(intra_pred_test_mem.src)); |
90 | 90 | vpx_usec_timer timer; |
205 | 205 | INTRA_PRED_TEST(SSE2, TestIntraPred4, vpx_dc_predictor_4x4_sse2, |
206 | 206 | vpx_dc_left_predictor_4x4_sse2, vpx_dc_top_predictor_4x4_sse2, |
207 | 207 | vpx_dc_128_predictor_4x4_sse2, vpx_v_predictor_4x4_sse2, |
208 | vpx_h_predictor_4x4_sse2, vpx_d45_predictor_4x4_sse2, NULL, | |
209 | NULL, NULL, vpx_d207_predictor_4x4_sse2, NULL, | |
208 | vpx_h_predictor_4x4_sse2, vpx_d45_predictor_4x4_sse2, nullptr, | |
209 | nullptr, nullptr, vpx_d207_predictor_4x4_sse2, nullptr, | |
210 | 210 | vpx_tm_predictor_4x4_sse2) |
211 | 211 | |
212 | 212 | INTRA_PRED_TEST(SSE2, TestIntraPred8, vpx_dc_predictor_8x8_sse2, |
213 | 213 | vpx_dc_left_predictor_8x8_sse2, vpx_dc_top_predictor_8x8_sse2, |
214 | 214 | vpx_dc_128_predictor_8x8_sse2, vpx_v_predictor_8x8_sse2, |
215 | vpx_h_predictor_8x8_sse2, vpx_d45_predictor_8x8_sse2, NULL, | |
216 | NULL, NULL, NULL, NULL, vpx_tm_predictor_8x8_sse2) | |
215 | vpx_h_predictor_8x8_sse2, vpx_d45_predictor_8x8_sse2, nullptr, | |
216 | nullptr, nullptr, nullptr, nullptr, vpx_tm_predictor_8x8_sse2) | |
217 | 217 | |
218 | 218 | INTRA_PRED_TEST(SSE2, TestIntraPred16, vpx_dc_predictor_16x16_sse2, |
219 | 219 | vpx_dc_left_predictor_16x16_sse2, |
220 | 220 | vpx_dc_top_predictor_16x16_sse2, |
221 | 221 | vpx_dc_128_predictor_16x16_sse2, vpx_v_predictor_16x16_sse2, |
222 | vpx_h_predictor_16x16_sse2, NULL, NULL, NULL, NULL, NULL, NULL, | |
223 | vpx_tm_predictor_16x16_sse2) | |
222 | vpx_h_predictor_16x16_sse2, nullptr, nullptr, nullptr, nullptr, | |
223 | nullptr, nullptr, vpx_tm_predictor_16x16_sse2) | |
224 | 224 | |
225 | 225 | INTRA_PRED_TEST(SSE2, TestIntraPred32, vpx_dc_predictor_32x32_sse2, |
226 | 226 | vpx_dc_left_predictor_32x32_sse2, |
227 | 227 | vpx_dc_top_predictor_32x32_sse2, |
228 | 228 | vpx_dc_128_predictor_32x32_sse2, vpx_v_predictor_32x32_sse2, |
229 | vpx_h_predictor_32x32_sse2, NULL, NULL, NULL, NULL, NULL, NULL, | |
230 | vpx_tm_predictor_32x32_sse2) | |
229 | vpx_h_predictor_32x32_sse2, nullptr, nullptr, nullptr, nullptr, | |
230 | nullptr, nullptr, vpx_tm_predictor_32x32_sse2) | |
231 | 231 | #endif // HAVE_SSE2 |
232 | 232 | |
233 | 233 | #if HAVE_SSSE3 |
234 | INTRA_PRED_TEST(SSSE3, TestIntraPred4, NULL, NULL, NULL, NULL, NULL, NULL, NULL, | |
235 | NULL, NULL, vpx_d153_predictor_4x4_ssse3, NULL, | |
236 | vpx_d63_predictor_4x4_ssse3, NULL) | |
237 | INTRA_PRED_TEST(SSSE3, TestIntraPred8, NULL, NULL, NULL, NULL, NULL, NULL, NULL, | |
238 | NULL, NULL, vpx_d153_predictor_8x8_ssse3, | |
239 | vpx_d207_predictor_8x8_ssse3, vpx_d63_predictor_8x8_ssse3, NULL) | |
240 | INTRA_PRED_TEST(SSSE3, TestIntraPred16, NULL, NULL, NULL, NULL, NULL, NULL, | |
241 | vpx_d45_predictor_16x16_ssse3, NULL, NULL, | |
242 | vpx_d153_predictor_16x16_ssse3, vpx_d207_predictor_16x16_ssse3, | |
243 | vpx_d63_predictor_16x16_ssse3, NULL) | |
244 | INTRA_PRED_TEST(SSSE3, TestIntraPred32, NULL, NULL, NULL, NULL, NULL, NULL, | |
245 | vpx_d45_predictor_32x32_ssse3, NULL, NULL, | |
246 | vpx_d153_predictor_32x32_ssse3, vpx_d207_predictor_32x32_ssse3, | |
247 | vpx_d63_predictor_32x32_ssse3, NULL) | |
234 | INTRA_PRED_TEST(SSSE3, TestIntraPred4, nullptr, nullptr, nullptr, nullptr, | |
235 | nullptr, nullptr, nullptr, nullptr, nullptr, | |
236 | vpx_d153_predictor_4x4_ssse3, nullptr, | |
237 | vpx_d63_predictor_4x4_ssse3, nullptr) | |
238 | INTRA_PRED_TEST(SSSE3, TestIntraPred8, nullptr, nullptr, nullptr, nullptr, | |
239 | nullptr, nullptr, nullptr, nullptr, nullptr, | |
240 | vpx_d153_predictor_8x8_ssse3, vpx_d207_predictor_8x8_ssse3, | |
241 | vpx_d63_predictor_8x8_ssse3, nullptr) | |
242 | INTRA_PRED_TEST(SSSE3, TestIntraPred16, nullptr, nullptr, nullptr, nullptr, | |
243 | nullptr, nullptr, vpx_d45_predictor_16x16_ssse3, nullptr, | |
244 | nullptr, vpx_d153_predictor_16x16_ssse3, | |
245 | vpx_d207_predictor_16x16_ssse3, vpx_d63_predictor_16x16_ssse3, | |
246 | nullptr) | |
247 | INTRA_PRED_TEST(SSSE3, TestIntraPred32, nullptr, nullptr, nullptr, nullptr, | |
248 | nullptr, nullptr, vpx_d45_predictor_32x32_ssse3, nullptr, | |
249 | nullptr, vpx_d153_predictor_32x32_ssse3, | |
250 | vpx_d207_predictor_32x32_ssse3, vpx_d63_predictor_32x32_ssse3, | |
251 | nullptr) | |
248 | 252 | #endif // HAVE_SSSE3 |
249 | 253 | |
250 | 254 | #if HAVE_DSPR2 |
251 | INTRA_PRED_TEST(DSPR2, TestIntraPred4, vpx_dc_predictor_4x4_dspr2, NULL, NULL, | |
252 | NULL, NULL, vpx_h_predictor_4x4_dspr2, NULL, NULL, NULL, NULL, | |
253 | NULL, NULL, vpx_tm_predictor_4x4_dspr2) | |
254 | INTRA_PRED_TEST(DSPR2, TestIntraPred8, vpx_dc_predictor_8x8_dspr2, NULL, NULL, | |
255 | NULL, NULL, vpx_h_predictor_8x8_dspr2, NULL, NULL, NULL, NULL, | |
256 | NULL, NULL, vpx_tm_predictor_8x8_c) | |
257 | INTRA_PRED_TEST(DSPR2, TestIntraPred16, vpx_dc_predictor_16x16_dspr2, NULL, | |
258 | NULL, NULL, NULL, vpx_h_predictor_16x16_dspr2, NULL, NULL, NULL, | |
259 | NULL, NULL, NULL, NULL) | |
255 | INTRA_PRED_TEST(DSPR2, TestIntraPred4, vpx_dc_predictor_4x4_dspr2, nullptr, | |
256 | nullptr, nullptr, nullptr, vpx_h_predictor_4x4_dspr2, nullptr, | |
257 | nullptr, nullptr, nullptr, nullptr, nullptr, | |
258 | vpx_tm_predictor_4x4_dspr2) | |
259 | INTRA_PRED_TEST(DSPR2, TestIntraPred8, vpx_dc_predictor_8x8_dspr2, nullptr, | |
260 | nullptr, nullptr, nullptr, vpx_h_predictor_8x8_dspr2, nullptr, | |
261 | nullptr, nullptr, nullptr, nullptr, nullptr, | |
262 | vpx_tm_predictor_8x8_c) | |
263 | INTRA_PRED_TEST(DSPR2, TestIntraPred16, vpx_dc_predictor_16x16_dspr2, nullptr, | |
264 | nullptr, nullptr, nullptr, vpx_h_predictor_16x16_dspr2, nullptr, | |
265 | nullptr, nullptr, nullptr, nullptr, nullptr, nullptr) | |
260 | 266 | #endif // HAVE_DSPR2 |
261 | 267 | |
262 | 268 | #if HAVE_NEON |
264 | 270 | vpx_dc_left_predictor_4x4_neon, vpx_dc_top_predictor_4x4_neon, |
265 | 271 | vpx_dc_128_predictor_4x4_neon, vpx_v_predictor_4x4_neon, |
266 | 272 | vpx_h_predictor_4x4_neon, vpx_d45_predictor_4x4_neon, |
267 | vpx_d135_predictor_4x4_neon, NULL, NULL, NULL, NULL, | |
273 | vpx_d135_predictor_4x4_neon, nullptr, nullptr, nullptr, nullptr, | |
268 | 274 | vpx_tm_predictor_4x4_neon) |
269 | 275 | INTRA_PRED_TEST(NEON, TestIntraPred8, vpx_dc_predictor_8x8_neon, |
270 | 276 | vpx_dc_left_predictor_8x8_neon, vpx_dc_top_predictor_8x8_neon, |
271 | 277 | vpx_dc_128_predictor_8x8_neon, vpx_v_predictor_8x8_neon, |
272 | 278 | vpx_h_predictor_8x8_neon, vpx_d45_predictor_8x8_neon, |
273 | vpx_d135_predictor_8x8_neon, NULL, NULL, NULL, NULL, | |
279 | vpx_d135_predictor_8x8_neon, nullptr, nullptr, nullptr, nullptr, | |
274 | 280 | vpx_tm_predictor_8x8_neon) |
275 | 281 | INTRA_PRED_TEST(NEON, TestIntraPred16, vpx_dc_predictor_16x16_neon, |
276 | 282 | vpx_dc_left_predictor_16x16_neon, |
277 | 283 | vpx_dc_top_predictor_16x16_neon, |
278 | 284 | vpx_dc_128_predictor_16x16_neon, vpx_v_predictor_16x16_neon, |
279 | 285 | vpx_h_predictor_16x16_neon, vpx_d45_predictor_16x16_neon, |
280 | vpx_d135_predictor_16x16_neon, NULL, NULL, NULL, NULL, | |
281 | vpx_tm_predictor_16x16_neon) | |
286 | vpx_d135_predictor_16x16_neon, nullptr, nullptr, nullptr, | |
287 | nullptr, vpx_tm_predictor_16x16_neon) | |
282 | 288 | INTRA_PRED_TEST(NEON, TestIntraPred32, vpx_dc_predictor_32x32_neon, |
283 | 289 | vpx_dc_left_predictor_32x32_neon, |
284 | 290 | vpx_dc_top_predictor_32x32_neon, |
285 | 291 | vpx_dc_128_predictor_32x32_neon, vpx_v_predictor_32x32_neon, |
286 | 292 | vpx_h_predictor_32x32_neon, vpx_d45_predictor_32x32_neon, |
287 | vpx_d135_predictor_32x32_neon, NULL, NULL, NULL, NULL, | |
288 | vpx_tm_predictor_32x32_neon) | |
293 | vpx_d135_predictor_32x32_neon, nullptr, nullptr, nullptr, | |
294 | nullptr, vpx_tm_predictor_32x32_neon) | |
289 | 295 | #endif // HAVE_NEON |
290 | 296 | |
291 | 297 | #if HAVE_MSA |
292 | 298 | INTRA_PRED_TEST(MSA, TestIntraPred4, vpx_dc_predictor_4x4_msa, |
293 | 299 | vpx_dc_left_predictor_4x4_msa, vpx_dc_top_predictor_4x4_msa, |
294 | 300 | vpx_dc_128_predictor_4x4_msa, vpx_v_predictor_4x4_msa, |
295 | vpx_h_predictor_4x4_msa, NULL, NULL, NULL, NULL, NULL, NULL, | |
296 | vpx_tm_predictor_4x4_msa) | |
301 | vpx_h_predictor_4x4_msa, nullptr, nullptr, nullptr, nullptr, | |
302 | nullptr, nullptr, vpx_tm_predictor_4x4_msa) | |
297 | 303 | INTRA_PRED_TEST(MSA, TestIntraPred8, vpx_dc_predictor_8x8_msa, |
298 | 304 | vpx_dc_left_predictor_8x8_msa, vpx_dc_top_predictor_8x8_msa, |
299 | 305 | vpx_dc_128_predictor_8x8_msa, vpx_v_predictor_8x8_msa, |
300 | vpx_h_predictor_8x8_msa, NULL, NULL, NULL, NULL, NULL, NULL, | |
301 | vpx_tm_predictor_8x8_msa) | |
306 | vpx_h_predictor_8x8_msa, nullptr, nullptr, nullptr, nullptr, | |
307 | nullptr, nullptr, vpx_tm_predictor_8x8_msa) | |
302 | 308 | INTRA_PRED_TEST(MSA, TestIntraPred16, vpx_dc_predictor_16x16_msa, |
303 | 309 | vpx_dc_left_predictor_16x16_msa, vpx_dc_top_predictor_16x16_msa, |
304 | 310 | vpx_dc_128_predictor_16x16_msa, vpx_v_predictor_16x16_msa, |
305 | vpx_h_predictor_16x16_msa, NULL, NULL, NULL, NULL, NULL, NULL, | |
306 | vpx_tm_predictor_16x16_msa) | |
311 | vpx_h_predictor_16x16_msa, nullptr, nullptr, nullptr, nullptr, | |
312 | nullptr, nullptr, vpx_tm_predictor_16x16_msa) | |
307 | 313 | INTRA_PRED_TEST(MSA, TestIntraPred32, vpx_dc_predictor_32x32_msa, |
308 | 314 | vpx_dc_left_predictor_32x32_msa, vpx_dc_top_predictor_32x32_msa, |
309 | 315 | vpx_dc_128_predictor_32x32_msa, vpx_v_predictor_32x32_msa, |
310 | vpx_h_predictor_32x32_msa, NULL, NULL, NULL, NULL, NULL, NULL, | |
311 | vpx_tm_predictor_32x32_msa) | |
316 | vpx_h_predictor_32x32_msa, nullptr, nullptr, nullptr, nullptr, | |
317 | nullptr, nullptr, vpx_tm_predictor_32x32_msa) | |
312 | 318 | #endif // HAVE_MSA |
313 | 319 | |
314 | 320 | #if HAVE_VSX |
315 | 321 | // TODO(crbug.com/webm/1522): Fix test failures. |
316 | 322 | #if 0 |
317 | INTRA_PRED_TEST(VSX, TestIntraPred4, NULL, NULL, NULL, NULL, NULL, | |
318 | vpx_h_predictor_4x4_vsx, NULL, NULL, NULL, NULL, NULL, NULL, | |
319 | vpx_tm_predictor_4x4_vsx) | |
320 | ||
321 | INTRA_PRED_TEST(VSX, TestIntraPred8, vpx_dc_predictor_8x8_vsx, NULL, NULL, NULL, | |
322 | NULL, vpx_h_predictor_8x8_vsx, vpx_d45_predictor_8x8_vsx, NULL, | |
323 | NULL, NULL, NULL, vpx_d63_predictor_8x8_vsx, | |
324 | vpx_tm_predictor_8x8_vsx) | |
323 | INTRA_PRED_TEST(VSX, TestIntraPred4, nullptr, nullptr, nullptr, nullptr, | |
324 | nullptr, vpx_h_predictor_4x4_vsx, nullptr, nullptr, nullptr, | |
325 | nullptr, nullptr, nullptr, vpx_tm_predictor_4x4_vsx) | |
326 | ||
327 | INTRA_PRED_TEST(VSX, TestIntraPred8, vpx_dc_predictor_8x8_vsx, nullptr, nullptr, | |
328 | nullptr, nullptr, vpx_h_predictor_8x8_vsx, | |
329 | vpx_d45_predictor_8x8_vsx, nullptr, nullptr, nullptr, nullptr, | |
330 | vpx_d63_predictor_8x8_vsx, vpx_tm_predictor_8x8_vsx) | |
325 | 331 | #endif |
326 | 332 | |
327 | 333 | INTRA_PRED_TEST(VSX, TestIntraPred16, vpx_dc_predictor_16x16_vsx, |
328 | 334 | vpx_dc_left_predictor_16x16_vsx, vpx_dc_top_predictor_16x16_vsx, |
329 | 335 | vpx_dc_128_predictor_16x16_vsx, vpx_v_predictor_16x16_vsx, |
330 | vpx_h_predictor_16x16_vsx, vpx_d45_predictor_16x16_vsx, NULL, | |
331 | NULL, NULL, NULL, vpx_d63_predictor_16x16_vsx, | |
336 | vpx_h_predictor_16x16_vsx, vpx_d45_predictor_16x16_vsx, nullptr, | |
337 | nullptr, nullptr, nullptr, vpx_d63_predictor_16x16_vsx, | |
332 | 338 | vpx_tm_predictor_16x16_vsx) |
333 | 339 | |
334 | 340 | INTRA_PRED_TEST(VSX, TestIntraPred32, vpx_dc_predictor_32x32_vsx, |
335 | 341 | vpx_dc_left_predictor_32x32_vsx, vpx_dc_top_predictor_32x32_vsx, |
336 | 342 | vpx_dc_128_predictor_32x32_vsx, vpx_v_predictor_32x32_vsx, |
337 | vpx_h_predictor_32x32_vsx, vpx_d45_predictor_32x32_vsx, NULL, | |
338 | NULL, NULL, NULL, vpx_d63_predictor_32x32_vsx, | |
343 | vpx_h_predictor_32x32_vsx, vpx_d45_predictor_32x32_vsx, nullptr, | |
344 | nullptr, nullptr, nullptr, vpx_d63_predictor_32x32_vsx, | |
339 | 345 | vpx_tm_predictor_32x32_vsx) |
340 | 346 | #endif // HAVE_VSX |
341 | 347 | |
360 | 366 | intra_pred_test_mem.Init(block_size, 12); |
361 | 367 | |
362 | 368 | for (int k = 0; k < kNumVp9IntraPredFuncs; ++k) { |
363 | if (pred_funcs[k] == NULL) continue; | |
369 | if (pred_funcs[k] == nullptr) continue; | |
364 | 370 | memcpy(intra_pred_test_mem.src, intra_pred_test_mem.ref_src, |
365 | 371 | sizeof(intra_pred_test_mem.src)); |
366 | 372 | vpx_usec_timer timer; |
486 | 492 | SSE2, TestHighbdIntraPred4, vpx_highbd_dc_predictor_4x4_sse2, |
487 | 493 | vpx_highbd_dc_left_predictor_4x4_sse2, vpx_highbd_dc_top_predictor_4x4_sse2, |
488 | 494 | vpx_highbd_dc_128_predictor_4x4_sse2, vpx_highbd_v_predictor_4x4_sse2, |
489 | vpx_highbd_h_predictor_4x4_sse2, NULL, vpx_highbd_d135_predictor_4x4_sse2, | |
490 | vpx_highbd_d117_predictor_4x4_sse2, vpx_highbd_d153_predictor_4x4_sse2, | |
491 | vpx_highbd_d207_predictor_4x4_sse2, vpx_highbd_d63_predictor_4x4_sse2, | |
492 | vpx_highbd_tm_predictor_4x4_c) | |
493 | ||
494 | HIGHBD_INTRA_PRED_TEST(SSE2, TestHighbdIntraPred8, | |
495 | vpx_highbd_dc_predictor_8x8_sse2, | |
496 | vpx_highbd_dc_left_predictor_8x8_sse2, | |
497 | vpx_highbd_dc_top_predictor_8x8_sse2, | |
498 | vpx_highbd_dc_128_predictor_8x8_sse2, | |
499 | vpx_highbd_v_predictor_8x8_sse2, | |
500 | vpx_highbd_h_predictor_8x8_sse2, NULL, NULL, NULL, NULL, | |
501 | NULL, NULL, vpx_highbd_tm_predictor_8x8_sse2) | |
495 | vpx_highbd_h_predictor_4x4_sse2, nullptr, | |
496 | vpx_highbd_d135_predictor_4x4_sse2, vpx_highbd_d117_predictor_4x4_sse2, | |
497 | vpx_highbd_d153_predictor_4x4_sse2, vpx_highbd_d207_predictor_4x4_sse2, | |
498 | vpx_highbd_d63_predictor_4x4_sse2, vpx_highbd_tm_predictor_4x4_c) | |
499 | ||
500 | HIGHBD_INTRA_PRED_TEST( | |
501 | SSE2, TestHighbdIntraPred8, vpx_highbd_dc_predictor_8x8_sse2, | |
502 | vpx_highbd_dc_left_predictor_8x8_sse2, vpx_highbd_dc_top_predictor_8x8_sse2, | |
503 | vpx_highbd_dc_128_predictor_8x8_sse2, vpx_highbd_v_predictor_8x8_sse2, | |
504 | vpx_highbd_h_predictor_8x8_sse2, nullptr, nullptr, nullptr, nullptr, | |
505 | nullptr, nullptr, vpx_highbd_tm_predictor_8x8_sse2) | |
502 | 506 | |
503 | 507 | HIGHBD_INTRA_PRED_TEST(SSE2, TestHighbdIntraPred16, |
504 | 508 | vpx_highbd_dc_predictor_16x16_sse2, |
506 | 510 | vpx_highbd_dc_top_predictor_16x16_sse2, |
507 | 511 | vpx_highbd_dc_128_predictor_16x16_sse2, |
508 | 512 | vpx_highbd_v_predictor_16x16_sse2, |
509 | vpx_highbd_h_predictor_16x16_sse2, NULL, NULL, NULL, | |
510 | NULL, NULL, NULL, vpx_highbd_tm_predictor_16x16_sse2) | |
513 | vpx_highbd_h_predictor_16x16_sse2, nullptr, nullptr, | |
514 | nullptr, nullptr, nullptr, nullptr, | |
515 | vpx_highbd_tm_predictor_16x16_sse2) | |
511 | 516 | |
512 | 517 | HIGHBD_INTRA_PRED_TEST(SSE2, TestHighbdIntraPred32, |
513 | 518 | vpx_highbd_dc_predictor_32x32_sse2, |
515 | 520 | vpx_highbd_dc_top_predictor_32x32_sse2, |
516 | 521 | vpx_highbd_dc_128_predictor_32x32_sse2, |
517 | 522 | vpx_highbd_v_predictor_32x32_sse2, |
518 | vpx_highbd_h_predictor_32x32_sse2, NULL, NULL, NULL, | |
519 | NULL, NULL, NULL, vpx_highbd_tm_predictor_32x32_sse2) | |
523 | vpx_highbd_h_predictor_32x32_sse2, nullptr, nullptr, | |
524 | nullptr, nullptr, nullptr, nullptr, | |
525 | vpx_highbd_tm_predictor_32x32_sse2) | |
520 | 526 | #endif // HAVE_SSE2 |
521 | 527 | |
522 | 528 | #if HAVE_SSSE3 |
523 | HIGHBD_INTRA_PRED_TEST(SSSE3, TestHighbdIntraPred4, NULL, NULL, NULL, NULL, | |
524 | NULL, NULL, vpx_highbd_d45_predictor_4x4_ssse3, NULL, | |
525 | NULL, NULL, NULL, NULL, NULL) | |
526 | HIGHBD_INTRA_PRED_TEST(SSSE3, TestHighbdIntraPred8, NULL, NULL, NULL, NULL, | |
527 | NULL, NULL, vpx_highbd_d45_predictor_8x8_ssse3, | |
529 | HIGHBD_INTRA_PRED_TEST(SSSE3, TestHighbdIntraPred4, nullptr, nullptr, nullptr, | |
530 | nullptr, nullptr, nullptr, | |
531 | vpx_highbd_d45_predictor_4x4_ssse3, nullptr, nullptr, | |
532 | nullptr, nullptr, nullptr, nullptr) | |
533 | HIGHBD_INTRA_PRED_TEST(SSSE3, TestHighbdIntraPred8, nullptr, nullptr, nullptr, | |
534 | nullptr, nullptr, nullptr, | |
535 | vpx_highbd_d45_predictor_8x8_ssse3, | |
528 | 536 | vpx_highbd_d135_predictor_8x8_ssse3, |
529 | 537 | vpx_highbd_d117_predictor_8x8_ssse3, |
530 | 538 | vpx_highbd_d153_predictor_8x8_ssse3, |
531 | 539 | vpx_highbd_d207_predictor_8x8_ssse3, |
532 | vpx_highbd_d63_predictor_8x8_ssse3, NULL) | |
533 | HIGHBD_INTRA_PRED_TEST(SSSE3, TestHighbdIntraPred16, NULL, NULL, NULL, NULL, | |
534 | NULL, NULL, vpx_highbd_d45_predictor_16x16_ssse3, | |
540 | vpx_highbd_d63_predictor_8x8_ssse3, nullptr) | |
541 | HIGHBD_INTRA_PRED_TEST(SSSE3, TestHighbdIntraPred16, nullptr, nullptr, nullptr, | |
542 | nullptr, nullptr, nullptr, | |
543 | vpx_highbd_d45_predictor_16x16_ssse3, | |
535 | 544 | vpx_highbd_d135_predictor_16x16_ssse3, |
536 | 545 | vpx_highbd_d117_predictor_16x16_ssse3, |
537 | 546 | vpx_highbd_d153_predictor_16x16_ssse3, |
538 | 547 | vpx_highbd_d207_predictor_16x16_ssse3, |
539 | vpx_highbd_d63_predictor_16x16_ssse3, NULL) | |
540 | HIGHBD_INTRA_PRED_TEST(SSSE3, TestHighbdIntraPred32, NULL, NULL, NULL, NULL, | |
541 | NULL, NULL, vpx_highbd_d45_predictor_32x32_ssse3, | |
548 | vpx_highbd_d63_predictor_16x16_ssse3, nullptr) | |
549 | HIGHBD_INTRA_PRED_TEST(SSSE3, TestHighbdIntraPred32, nullptr, nullptr, nullptr, | |
550 | nullptr, nullptr, nullptr, | |
551 | vpx_highbd_d45_predictor_32x32_ssse3, | |
542 | 552 | vpx_highbd_d135_predictor_32x32_ssse3, |
543 | 553 | vpx_highbd_d117_predictor_32x32_ssse3, |
544 | 554 | vpx_highbd_d153_predictor_32x32_ssse3, |
545 | 555 | vpx_highbd_d207_predictor_32x32_ssse3, |
546 | vpx_highbd_d63_predictor_32x32_ssse3, NULL) | |
556 | vpx_highbd_d63_predictor_32x32_ssse3, nullptr) | |
547 | 557 | #endif // HAVE_SSSE3 |
548 | 558 | |
549 | 559 | #if HAVE_NEON |
552 | 562 | vpx_highbd_dc_left_predictor_4x4_neon, vpx_highbd_dc_top_predictor_4x4_neon, |
553 | 563 | vpx_highbd_dc_128_predictor_4x4_neon, vpx_highbd_v_predictor_4x4_neon, |
554 | 564 | vpx_highbd_h_predictor_4x4_neon, vpx_highbd_d45_predictor_4x4_neon, |
555 | vpx_highbd_d135_predictor_4x4_neon, NULL, NULL, NULL, NULL, | |
565 | vpx_highbd_d135_predictor_4x4_neon, nullptr, nullptr, nullptr, nullptr, | |
556 | 566 | vpx_highbd_tm_predictor_4x4_neon) |
557 | 567 | HIGHBD_INTRA_PRED_TEST( |
558 | 568 | NEON, TestHighbdIntraPred8, vpx_highbd_dc_predictor_8x8_neon, |
559 | 569 | vpx_highbd_dc_left_predictor_8x8_neon, vpx_highbd_dc_top_predictor_8x8_neon, |
560 | 570 | vpx_highbd_dc_128_predictor_8x8_neon, vpx_highbd_v_predictor_8x8_neon, |
561 | 571 | vpx_highbd_h_predictor_8x8_neon, vpx_highbd_d45_predictor_8x8_neon, |
562 | vpx_highbd_d135_predictor_8x8_neon, NULL, NULL, NULL, NULL, | |
572 | vpx_highbd_d135_predictor_8x8_neon, nullptr, nullptr, nullptr, nullptr, | |
563 | 573 | vpx_highbd_tm_predictor_8x8_neon) |
564 | 574 | HIGHBD_INTRA_PRED_TEST(NEON, TestHighbdIntraPred16, |
565 | 575 | vpx_highbd_dc_predictor_16x16_neon, |
569 | 579 | vpx_highbd_v_predictor_16x16_neon, |
570 | 580 | vpx_highbd_h_predictor_16x16_neon, |
571 | 581 | vpx_highbd_d45_predictor_16x16_neon, |
572 | vpx_highbd_d135_predictor_16x16_neon, NULL, NULL, NULL, | |
573 | NULL, vpx_highbd_tm_predictor_16x16_neon) | |
582 | vpx_highbd_d135_predictor_16x16_neon, nullptr, nullptr, | |
583 | nullptr, nullptr, vpx_highbd_tm_predictor_16x16_neon) | |
574 | 584 | HIGHBD_INTRA_PRED_TEST(NEON, TestHighbdIntraPred32, |
575 | 585 | vpx_highbd_dc_predictor_32x32_neon, |
576 | 586 | vpx_highbd_dc_left_predictor_32x32_neon, |
579 | 589 | vpx_highbd_v_predictor_32x32_neon, |
580 | 590 | vpx_highbd_h_predictor_32x32_neon, |
581 | 591 | vpx_highbd_d45_predictor_32x32_neon, |
582 | vpx_highbd_d135_predictor_32x32_neon, NULL, NULL, NULL, | |
583 | NULL, vpx_highbd_tm_predictor_32x32_neon) | |
592 | vpx_highbd_d135_predictor_32x32_neon, nullptr, nullptr, | |
593 | nullptr, nullptr, vpx_highbd_tm_predictor_32x32_neon) | |
584 | 594 | #endif // HAVE_NEON |
585 | 595 | |
586 | 596 | #endif // CONFIG_VP9_HIGHBITDEPTH |
39 | 39 | class TestVectorTest : public ::libvpx_test::DecoderTest, |
40 | 40 | public ::libvpx_test::CodecTestWithParam<DecodeParam> { |
41 | 41 | protected: |
42 | TestVectorTest() : DecoderTest(GET_PARAM(0)), md5_file_(NULL) { | |
42 | TestVectorTest() : DecoderTest(GET_PARAM(0)), md5_file_(nullptr) { | |
43 | 43 | #if CONFIG_VP9_DECODER |
44 | 44 | resize_clips_.insert(::libvpx_test::kVP9TestVectorsResize, |
45 | 45 | ::libvpx_test::kVP9TestVectorsResize + |
53 | 53 | |
54 | 54 | void OpenMD5File(const std::string &md5_file_name_) { |
55 | 55 | md5_file_ = libvpx_test::OpenTestDataFile(md5_file_name_); |
56 | ASSERT_TRUE(md5_file_ != NULL) | |
56 | ASSERT_NE(md5_file_, nullptr) | |
57 | 57 | << "Md5 file open failed. Filename: " << md5_file_name_; |
58 | 58 | } |
59 | 59 | |
78 | 78 | |
79 | 79 | virtual void DecompressedFrameHook(const vpx_image_t &img, |
80 | 80 | const unsigned int frame_number) { |
81 | ASSERT_TRUE(md5_file_ != NULL); | |
81 | ASSERT_NE(md5_file_, nullptr); | |
82 | 82 | char expected_md5[33]; |
83 | 83 | char junk[128]; |
84 | 84 | |
136 | 136 | return; |
137 | 137 | #endif |
138 | 138 | } |
139 | ASSERT_TRUE(video.get() != NULL); | |
139 | ASSERT_NE(video.get(), nullptr); | |
140 | 140 | video->Init(); |
141 | 141 | |
142 | 142 | // Construct md5 file name. |
56 | 56 | void *user_priv = reinterpret_cast<void *>(&frame_num); |
57 | 57 | const vpx_codec_err_t res = |
58 | 58 | decoder.DecodeFrame(video.cxdata(), video.frame_size(), |
59 | (frame_num == 0) ? NULL : user_priv); | |
59 | (frame_num == 0) ? nullptr : user_priv); | |
60 | 60 | if (res != VPX_CODEC_OK) { |
61 | 61 | EXPECT_EQ(VPX_CODEC_OK, res) << decoder.DecodeError(); |
62 | 62 | break; |
63 | 63 | } |
64 | 64 | libvpx_test::DxDataIterator dec_iter = decoder.GetDxData(); |
65 | const vpx_image_t *img = NULL; | |
65 | const vpx_image_t *img = nullptr; | |
66 | 66 | |
67 | 67 | // Get decompressed data. |
68 | 68 | while ((img = dec_iter.Next())) { |
69 | 69 | if (frame_num == 0) { |
70 | CheckUserPrivateData(img->user_priv, NULL); | |
70 | CheckUserPrivateData(img->user_priv, nullptr); | |
71 | 71 | } else { |
72 | 72 | CheckUserPrivateData(img->user_priv, &frame_num); |
73 | 73 | |
77 | 77 | ref.idx = rnd.Rand8() % 3; |
78 | 78 | decoder.Control(VP9_GET_REFERENCE, &ref); |
79 | 79 | |
80 | CheckUserPrivateData(ref.img.user_priv, NULL); | |
80 | CheckUserPrivateData(ref.img.user_priv, nullptr); | |
81 | 81 | } |
82 | 82 | md5.Add(img); |
83 | 83 | } |
252 | 252 | |
253 | 253 | template <typename Func> |
254 | 254 | struct TestParams { |
255 | TestParams(int log2w = 0, int log2h = 0, Func function = NULL, | |
255 | TestParams(int log2w = 0, int log2h = 0, Func function = nullptr, | |
256 | 256 | int bit_depth_value = 0) |
257 | 257 | : log2width(log2w), log2height(log2h), func(function) { |
258 | 258 | use_high_bit_depth = (bit_depth_value > 0); |
296 | 296 | use_high_bit_depth() ? sizeof(uint16_t) : sizeof(uint8_t); |
297 | 297 | src_ = reinterpret_cast<uint8_t *>(vpx_memalign(16, block_size() * unit)); |
298 | 298 | ref_ = new uint8_t[block_size() * unit]; |
299 | ASSERT_TRUE(src_ != NULL); | |
300 | ASSERT_TRUE(ref_ != NULL); | |
299 | ASSERT_NE(src_, nullptr); | |
300 | ASSERT_NE(ref_, nullptr); | |
301 | 301 | #if CONFIG_VP9_HIGHBITDEPTH |
302 | 302 | if (use_high_bit_depth()) { |
303 | 303 | // TODO(skal): remove! |
318 | 318 | |
319 | 319 | vpx_free(src_); |
320 | 320 | delete[] ref_; |
321 | src_ = NULL; | |
322 | ref_ = NULL; | |
321 | src_ = nullptr; | |
322 | ref_ = nullptr; | |
323 | 323 | libvpx_test::ClearSystemState(); |
324 | 324 | } |
325 | 325 | |
572 | 572 | (block_size() + width() + height() + 1) * sizeof(uint16_t)))); |
573 | 573 | #endif // CONFIG_VP9_HIGHBITDEPTH |
574 | 574 | } |
575 | ASSERT_TRUE(src_ != NULL); | |
576 | ASSERT_TRUE(sec_ != NULL); | |
577 | ASSERT_TRUE(ref_ != NULL); | |
575 | ASSERT_NE(src_, nullptr); | |
576 | ASSERT_NE(sec_, nullptr); | |
577 | ASSERT_NE(ref_, nullptr); | |
578 | 578 | } |
579 | 579 | |
580 | 580 | virtual void TearDown() { |
806 | 806 | SubpelAvgVarianceParams(2, 2, &vpx_sub_pixel_avg_variance4x4_c, 0))); |
807 | 807 | |
808 | 808 | #if CONFIG_VP9_HIGHBITDEPTH |
809 | typedef MainTestClass<vpx_variance_fn_t> VpxHBDMseTest; | |
810 | 809 | typedef MainTestClass<vpx_variance_fn_t> VpxHBDVarianceTest; |
811 | 810 | typedef SubpelVarianceTest<vpx_subpixvariance_fn_t> VpxHBDSubpelVarianceTest; |
812 | 811 | typedef SubpelVarianceTest<vpx_subp_avg_variance_fn_t> |
813 | 812 | VpxHBDSubpelAvgVarianceTest; |
814 | 813 | |
815 | TEST_P(VpxHBDMseTest, RefMse) { RefTestMse(); } | |
816 | TEST_P(VpxHBDMseTest, MaxMse) { MaxTestMse(); } | |
817 | 814 | TEST_P(VpxHBDVarianceTest, Zero) { ZeroTest(); } |
818 | 815 | TEST_P(VpxHBDVarianceTest, Ref) { RefTest(); } |
819 | 816 | TEST_P(VpxHBDVarianceTest, RefStride) { RefStrideTest(); } |
824 | 821 | TEST_P(VpxHBDSubpelAvgVarianceTest, Ref) { RefTest(); } |
825 | 822 | |
826 | 823 | /* TODO(debargha): This test does not support the highbd version |
824 | typedef MainTestClass<vpx_variance_fn_t> VpxHBDMseTest; | |
825 | TEST_P(VpxHBDMseTest, RefMse) { RefTestMse(); } | |
826 | TEST_P(VpxHBDMseTest, MaxMse) { MaxTestMse(); } | |
827 | 827 | INSTANTIATE_TEST_SUITE_P( |
828 | 828 | C, VpxHBDMseTest, |
829 | 829 | ::testing::Values(MseParams(4, 4, &vpx_highbd_12_mse16x16_c), |
839 | 839 | MseParams(4, 4, &vpx_highbd_8_mse8x16_c), |
840 | 840 | MseParams(4, 4, &vpx_highbd_8_mse8x8_c))); |
841 | 841 | */ |
842 | GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(VpxHBDMseTest); | |
842 | 843 | |
843 | 844 | INSTANTIATE_TEST_SUITE_P( |
844 | 845 | C, VpxHBDVarianceTest, |
39 | 39 | int increase_denoising_; |
40 | 40 | }; |
41 | 41 | |
42 | // TODO(https://crbug.com/webm/1718): This test fails with gcc 8-10. | |
43 | #if defined(__GNUC__) && __GNUC__ >= 8 | |
44 | TEST_P(VP8DenoiserTest, DISABLED_BitexactCheck) { | |
45 | #else | |
42 | 46 | TEST_P(VP8DenoiserTest, BitexactCheck) { |
47 | #endif | |
43 | 48 | ACMRandom rnd(ACMRandom::DeterministicSeed()); |
44 | 49 | const int count_test_block = 4000; |
45 | 50 | const int stride = 16; |
86 | 91 | // Check bitexactness. |
87 | 92 | for (int h = 0; h < 16; ++h) { |
88 | 93 | for (int w = 0; w < 16; ++w) { |
89 | EXPECT_EQ(avg_block_c[h * stride + w], avg_block_sse2[h * stride + w]); | |
94 | ASSERT_EQ(avg_block_c[h * stride + w], avg_block_sse2[h * stride + w]); | |
90 | 95 | } |
91 | 96 | } |
92 | 97 | |
102 | 107 | // Check bitexactness. |
103 | 108 | for (int h = 0; h < 16; ++h) { |
104 | 109 | for (int w = 0; w < 16; ++w) { |
105 | EXPECT_EQ(avg_block_c[h * stride + w], avg_block_sse2[h * stride + w]); | |
110 | ASSERT_EQ(avg_block_c[h * stride + w], avg_block_sse2[h * stride + w]); | |
106 | 111 | } |
107 | 112 | } |
108 | 113 | } |
66 | 66 | HBDBlockErrorFunc error_block_op_; |
67 | 67 | HBDBlockErrorFunc ref_error_block_op_; |
68 | 68 | }; |
69 | GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(BlockErrorTest); | |
69 | 70 | |
70 | 71 | TEST_P(BlockErrorTest, OperationCheck) { |
71 | 72 | ACMRandom rnd(ACMRandom::DeterministicSeed()); |
73 | 73 | GTEST_ASSERT_EQ(bw_buffer[0] & 0x80, 0); |
74 | 74 | |
75 | 75 | vpx_reader br; |
76 | vpx_reader_init(&br, bw_buffer, kBufferSize, NULL, NULL); | |
76 | vpx_reader_init(&br, bw_buffer, kBufferSize, nullptr, nullptr); | |
77 | 77 | bit_rnd.Reset(random_seed); |
78 | 78 | for (int i = 0; i < kBitsToTest; ++i) { |
79 | 79 | if (bit_method == 2) { |
700 | 700 | // Use 2 states: 1 is center square, 0 is the rest. |
701 | 701 | roi_.roi_map = reinterpret_cast<uint8_t *>( |
702 | 702 | calloc(roi_.rows * roi_.cols, sizeof(*roi_.roi_map))); |
703 | ASSERT_TRUE(roi_.roi_map != NULL); | |
703 | ASSERT_NE(roi_.roi_map, nullptr); | |
704 | 704 | |
705 | 705 | for (unsigned int i = 0; i < roi_.rows; ++i) { |
706 | 706 | for (unsigned int j = 0; j < roi_.cols; ++j) { |
50 | 50 | protected: |
51 | 51 | BLOCK_SIZE bs_; |
52 | 52 | }; |
53 | GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(VP9DenoiserTest); | |
53 | 54 | |
54 | 55 | TEST_P(VP9DenoiserTest, BitexactCheck) { |
55 | 56 | ACMRandom rnd(ACMRandom::DeterministicSeed()); |
141 | 141 | |
142 | 142 | std::unique_ptr<libvpx_test::VideoSource> video( |
143 | 143 | new libvpx_test::Y4mVideoSource(test_video_.name, 0, test_video_.frames)); |
144 | ASSERT_TRUE(video.get() != NULL); | |
144 | ASSERT_NE(video.get(), nullptr); | |
145 | 145 | |
146 | 146 | ASSERT_NO_FATAL_FAILURE(RunLoop(video.get())); |
147 | 147 | } |
256 | 256 | video.reset(new libvpx_test::YUVVideoSource(test_video_param_.filename, |
257 | 257 | test_video_param_.fmt, 352, 288, |
258 | 258 | 30, 1, 0, 100)); |
259 | ASSERT_TRUE(video.get() != NULL); | |
259 | ASSERT_NE(video.get(), nullptr); | |
260 | 260 | |
261 | 261 | ASSERT_NO_FATAL_FAILURE(RunLoop(video.get())); |
262 | 262 | } |
279 | 279 | test_video_param_.filename, test_video_param_.fmt, kWidth, kHeight, |
280 | 280 | kFramerate, 1, 0, kFrames)); |
281 | 281 | } |
282 | ASSERT_TRUE(video.get() != NULL); | |
282 | ASSERT_NE(video.get(), nullptr); | |
283 | 283 | |
284 | 284 | ASSERT_NO_FATAL_FAILURE(RunLoop(video.get())); |
285 | 285 | const double psnr = GetAveragePsnr(); |
306 | 306 | test_video_param_.filename, test_video_param_.fmt, kWidth, kHeight, |
307 | 307 | kFramerate, 1, 0, kFrames)); |
308 | 308 | } |
309 | ASSERT_TRUE(video.get() != NULL); | |
309 | ASSERT_NE(video.get(), nullptr); | |
310 | 310 | |
311 | 311 | ASSERT_NO_FATAL_FAILURE(RunLoop(video.get())); |
312 | 312 | const double psnr = GetAveragePsnr(); |
341 | 341 | VP9_INSTANTIATE_TEST_SUITE(EndToEndNV12, |
342 | 342 | ::testing::Values(::libvpx_test::kRealTime), |
343 | 343 | ::testing::ValuesIn(kTestVectorsNv12), |
344 | ::testing::ValuesIn({ 6, 7, 8 })); | |
344 | ::testing::Values(6, 7, 8)); | |
345 | 345 | |
346 | 346 | VP9_INSTANTIATE_TEST_SUITE(EndToEndTestAdaptiveRDThresh, |
347 | 347 | ::testing::Values(5, 6, 7), ::testing::Values(8, 9)); |
40 | 40 | |
41 | 41 | row_mt_mode_ = 1; |
42 | 42 | first_pass_only_ = true; |
43 | firstpass_stats_.buf = NULL; | |
43 | firstpass_stats_.buf = nullptr; | |
44 | 44 | firstpass_stats_.sz = 0; |
45 | 45 | } |
46 | 46 | virtual ~VPxFirstPassEncoderThreadTest() { free(firstpass_stats_.buf); } |
0 | /* | |
1 | * Copyright (c) 2020 The WebM project authors. All Rights Reserved. | |
2 | * | |
3 | * Use of this source code is governed by a BSD-style license | |
4 | * that can be found in the LICENSE file in the root of the source | |
5 | * tree. An additional intellectual property rights grant can be found | |
6 | * in the file PATENTS. All contributing project authors may | |
7 | * be found in the AUTHORS file in the root of the source tree. | |
8 | */ | |
9 | ||
10 | #include <new> | |
11 | ||
12 | #include "test/codec_factory.h" | |
13 | #include "test/encode_test_driver.h" | |
14 | #include "test/util.h" | |
15 | #include "test/yuv_video_source.h" | |
16 | #include "third_party/googletest/src/include/gtest/gtest.h" | |
17 | #include "vpx/vpx_ext_ratectrl.h" | |
18 | ||
19 | namespace { | |
20 | ||
21 | constexpr int kModelMagicNumber = 51396; | |
22 | constexpr unsigned int PrivMagicNumber = 5566; | |
23 | constexpr int kFrameNum = 5; | |
24 | constexpr int kLosslessCodingIndex = 2; | |
25 | ||
26 | struct ToyRateCtrl { | |
27 | int magic_number; | |
28 | int coding_index; | |
29 | }; | |
30 | ||
31 | vpx_rc_status_t rc_create_model(void *priv, | |
32 | const vpx_rc_config_t *ratectrl_config, | |
33 | vpx_rc_model_t *rate_ctrl_model_pt) { | |
34 | ToyRateCtrl *toy_rate_ctrl = new (std::nothrow) ToyRateCtrl; | |
35 | EXPECT_NE(toy_rate_ctrl, nullptr); | |
36 | toy_rate_ctrl->magic_number = kModelMagicNumber; | |
37 | toy_rate_ctrl->coding_index = -1; | |
38 | *rate_ctrl_model_pt = toy_rate_ctrl; | |
39 | EXPECT_EQ(priv, reinterpret_cast<void *>(PrivMagicNumber)); | |
40 | EXPECT_EQ(ratectrl_config->frame_width, 352); | |
41 | EXPECT_EQ(ratectrl_config->frame_height, 288); | |
42 | EXPECT_EQ(ratectrl_config->show_frame_count, kFrameNum); | |
43 | EXPECT_EQ(ratectrl_config->target_bitrate_kbps, 24000); | |
44 | EXPECT_EQ(ratectrl_config->frame_rate_num, 30); | |
45 | EXPECT_EQ(ratectrl_config->frame_rate_den, 1); | |
46 | return VPX_RC_OK; | |
47 | } | |
48 | ||
49 | vpx_rc_status_t rc_send_firstpass_stats( | |
50 | vpx_rc_model_t rate_ctrl_model, | |
51 | const vpx_rc_firstpass_stats_t *first_pass_stats) { | |
52 | const ToyRateCtrl *toy_rate_ctrl = | |
53 | static_cast<ToyRateCtrl *>(rate_ctrl_model); | |
54 | EXPECT_EQ(toy_rate_ctrl->magic_number, kModelMagicNumber); | |
55 | EXPECT_EQ(first_pass_stats->num_frames, kFrameNum); | |
56 | for (int i = 0; i < first_pass_stats->num_frames; ++i) { | |
57 | EXPECT_DOUBLE_EQ(first_pass_stats->frame_stats[i].frame, i); | |
58 | } | |
59 | return VPX_RC_OK; | |
60 | } | |
61 | ||
62 | vpx_rc_status_t rc_get_encodeframe_decision( | |
63 | vpx_rc_model_t rate_ctrl_model, | |
64 | const vpx_rc_encodeframe_info_t *encode_frame_info, | |
65 | vpx_rc_encodeframe_decision_t *frame_decision) { | |
66 | ToyRateCtrl *toy_rate_ctrl = static_cast<ToyRateCtrl *>(rate_ctrl_model); | |
67 | toy_rate_ctrl->coding_index += 1; | |
68 | ||
69 | EXPECT_EQ(toy_rate_ctrl->magic_number, kModelMagicNumber); | |
70 | ||
71 | EXPECT_LT(encode_frame_info->show_index, kFrameNum); | |
72 | EXPECT_EQ(encode_frame_info->coding_index, toy_rate_ctrl->coding_index); | |
73 | ||
74 | if (encode_frame_info->coding_index == 0) { | |
75 | EXPECT_EQ(encode_frame_info->show_index, 0); | |
76 | EXPECT_EQ(encode_frame_info->gop_index, 0); | |
77 | EXPECT_EQ(encode_frame_info->frame_type, 0 /*kFrameTypeKey*/); | |
78 | EXPECT_EQ(encode_frame_info->ref_frame_valid_list[0], | |
79 | 0); // kRefFrameTypeLast | |
80 | EXPECT_EQ(encode_frame_info->ref_frame_valid_list[1], | |
81 | 0); // kRefFrameTypePast | |
82 | EXPECT_EQ(encode_frame_info->ref_frame_valid_list[2], | |
83 | 0); // kRefFrameTypeFuture | |
84 | } | |
85 | ||
86 | if (encode_frame_info->coding_index == 1) { | |
87 | EXPECT_EQ(encode_frame_info->show_index, 4); | |
88 | EXPECT_EQ(encode_frame_info->gop_index, 1); | |
89 | EXPECT_EQ(encode_frame_info->frame_type, 2 /*kFrameTypeAltRef*/); | |
90 | EXPECT_EQ(encode_frame_info->ref_frame_valid_list[0], | |
91 | 1); // kRefFrameTypeLast | |
92 | EXPECT_EQ(encode_frame_info->ref_frame_valid_list[1], | |
93 | 0); // kRefFrameTypePast | |
94 | EXPECT_EQ(encode_frame_info->ref_frame_valid_list[2], | |
95 | 0); // kRefFrameTypeFuture | |
96 | EXPECT_EQ(encode_frame_info->ref_frame_coding_indexes[0], | |
97 | 0); // kRefFrameTypeLast | |
98 | } | |
99 | ||
100 | if (encode_frame_info->coding_index >= 2 && | |
101 | encode_frame_info->coding_index < 5) { | |
102 | // In the first group of pictures, coding_index and gop_index are equal. | |
103 | EXPECT_EQ(encode_frame_info->gop_index, encode_frame_info->coding_index); | |
104 | EXPECT_EQ(encode_frame_info->frame_type, 1 /*kFrameTypeInter*/); | |
105 | } | |
106 | ||
107 | if (encode_frame_info->coding_index == 5) { | |
108 | EXPECT_EQ(encode_frame_info->show_index, 4); | |
109 | EXPECT_EQ(encode_frame_info->gop_index, 0); | |
110 | EXPECT_EQ(encode_frame_info->frame_type, 3 /*kFrameTypeOverlay*/); | |
111 | EXPECT_EQ(encode_frame_info->ref_frame_valid_list[0], | |
112 | 1); // kRefFrameTypeLast | |
113 | EXPECT_EQ(encode_frame_info->ref_frame_valid_list[1], | |
114 | 1); // kRefFrameTypePast | |
115 | EXPECT_EQ(encode_frame_info->ref_frame_valid_list[2], | |
116 | 1); // kRefFrameTypeFuture | |
117 | EXPECT_EQ(encode_frame_info->ref_frame_coding_indexes[0], | |
118 | 4); // kRefFrameTypeLast | |
119 | EXPECT_EQ(encode_frame_info->ref_frame_coding_indexes[1], | |
120 | 0); // kRefFrameTypePast | |
121 | EXPECT_EQ(encode_frame_info->ref_frame_coding_indexes[2], | |
122 | 1); // kRefFrameTypeFuture | |
123 | } | |
124 | if (encode_frame_info->coding_index == kLosslessCodingIndex) { | |
125 | // We should get sse == 0 at rc_update_encodeframe_result() | |
126 | frame_decision->q_index = 0; | |
127 | } else { | |
128 | frame_decision->q_index = 100; | |
129 | } | |
130 | frame_decision->max_frame_size = 0; | |
131 | return VPX_RC_OK; | |
132 | } | |
133 | ||
134 | vpx_rc_status_t rc_update_encodeframe_result( | |
135 | vpx_rc_model_t rate_ctrl_model, | |
136 | const vpx_rc_encodeframe_result_t *encode_frame_result) { | |
137 | const ToyRateCtrl *toy_rate_ctrl = | |
138 | static_cast<ToyRateCtrl *>(rate_ctrl_model); | |
139 | EXPECT_EQ(toy_rate_ctrl->magic_number, kModelMagicNumber); | |
140 | ||
141 | const int64_t ref_pixel_count = 352 * 288 * 3 / 2; | |
142 | EXPECT_EQ(encode_frame_result->pixel_count, ref_pixel_count); | |
143 | if (toy_rate_ctrl->coding_index == kLosslessCodingIndex) { | |
144 | EXPECT_EQ(encode_frame_result->sse, 0); | |
145 | } | |
146 | if (toy_rate_ctrl->coding_index == kLosslessCodingIndex) { | |
147 | EXPECT_EQ(encode_frame_result->actual_encoding_qindex, 0); | |
148 | } else { | |
149 | EXPECT_EQ(encode_frame_result->actual_encoding_qindex, 100); | |
150 | } | |
151 | return VPX_RC_OK; | |
152 | } | |
153 | ||
154 | vpx_rc_status_t rc_delete_model(vpx_rc_model_t rate_ctrl_model) { | |
155 | ToyRateCtrl *toy_rate_ctrl = static_cast<ToyRateCtrl *>(rate_ctrl_model); | |
156 | EXPECT_EQ(toy_rate_ctrl->magic_number, kModelMagicNumber); | |
157 | delete toy_rate_ctrl; | |
158 | return VPX_RC_OK; | |
159 | } | |
160 | ||
161 | class ExtRateCtrlTest : public ::libvpx_test::EncoderTest, | |
162 | public ::testing::Test { | |
163 | protected: | |
164 | ExtRateCtrlTest() : EncoderTest(&::libvpx_test::kVP9) {} | |
165 | ||
166 | ~ExtRateCtrlTest() override = default; | |
167 | ||
168 | void SetUp() override { | |
169 | InitializeConfig(); | |
170 | SetMode(::libvpx_test::kTwoPassGood); | |
171 | } | |
172 | ||
173 | void PreEncodeFrameHook(::libvpx_test::VideoSource *video, | |
174 | ::libvpx_test::Encoder *encoder) override { | |
175 | if (video->frame() == 0) { | |
176 | vpx_rc_funcs_t rc_funcs; | |
177 | rc_funcs.create_model = rc_create_model; | |
178 | rc_funcs.send_firstpass_stats = rc_send_firstpass_stats; | |
179 | rc_funcs.get_encodeframe_decision = rc_get_encodeframe_decision; | |
180 | rc_funcs.update_encodeframe_result = rc_update_encodeframe_result; | |
181 | rc_funcs.delete_model = rc_delete_model; | |
182 | rc_funcs.priv = reinterpret_cast<void *>(PrivMagicNumber); | |
183 | encoder->Control(VP9E_SET_EXTERNAL_RATE_CONTROL, &rc_funcs); | |
184 | } | |
185 | } | |
186 | }; | |
187 | ||
188 | TEST_F(ExtRateCtrlTest, EncodeTest) { | |
189 | cfg_.rc_target_bitrate = 24000; | |
190 | ||
191 | std::unique_ptr<libvpx_test::VideoSource> video; | |
192 | video.reset(new (std::nothrow) libvpx_test::YUVVideoSource( | |
193 | "bus_352x288_420_f20_b8.yuv", VPX_IMG_FMT_I420, 352, 288, 30, 1, 0, | |
194 | kFrameNum)); | |
195 | ||
196 | ASSERT_NE(video.get(), nullptr); | |
197 | ASSERT_NO_FATAL_FAILURE(RunLoop(video.get())); | |
198 | } | |
199 | ||
200 | } // namespace |
31 | 31 | const uint8_t *above, const uint8_t *left); |
32 | 32 | |
33 | 33 | struct IntraPredParam { |
34 | IntraPredParam(IntraPredFunc pred = NULL, IntraPredFunc ref = NULL, | |
34 | IntraPredParam(IntraPredFunc pred = nullptr, IntraPredFunc ref = nullptr, | |
35 | 35 | int block_size_value = 0, int bit_depth_value = 0) |
36 | 36 | : pred_fn(pred), ref_fn(ref), block_size(block_size_value), |
37 | 37 | bit_depth(bit_depth_value) {} |
445 | 445 | const uint16_t *above, const uint16_t *left, |
446 | 446 | int bps); |
447 | 447 | struct HighbdIntraPredParam { |
448 | HighbdIntraPredParam(HighbdIntraPred pred = NULL, HighbdIntraPred ref = NULL, | |
449 | int block_size_value = 0, int bit_depth_value = 0) | |
448 | HighbdIntraPredParam(HighbdIntraPred pred = nullptr, | |
449 | HighbdIntraPred ref = nullptr, int block_size_value = 0, | |
450 | int bit_depth_value = 0) | |
450 | 451 | : pred_fn(pred), ref_fn(ref), block_size(block_size_value), |
451 | 452 | bit_depth(bit_depth_value) {} |
452 | 453 | |
456 | 457 | int bit_depth; |
457 | 458 | }; |
458 | 459 | |
460 | #if HAVE_SSSE3 || HAVE_NEON || HAVE_SSE2 | |
459 | 461 | template <> |
460 | 462 | void IntraPredTest<uint16_t, HighbdIntraPredParam>::Predict() { |
461 | 463 | const int bit_depth = params_.bit_depth; |
465 | 467 | } |
466 | 468 | |
467 | 469 | typedef IntraPredTest<uint16_t, HighbdIntraPredParam> VP9HighbdIntraPredTest; |
470 | GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(VP9HighbdIntraPredTest); | |
468 | 471 | |
469 | 472 | TEST_P(VP9HighbdIntraPredTest, HighbdIntraPredTests) { |
470 | 473 | // max block size is 32 |
474 | 477 | DECLARE_ALIGNED(16, uint16_t, ref_dst[3 * 32 * 32]); |
475 | 478 | RunTest(left_col, above_data, dst, ref_dst); |
476 | 479 | } |
480 | #endif | |
477 | 481 | |
478 | 482 | #if HAVE_SSSE3 |
479 | 483 | INSTANTIATE_TEST_SUITE_P( |
87 | 87 | "niklas_640_480_30.yuv", VPX_IMG_FMT_I420, 3840, 2160, // 2048, 1080, |
88 | 88 | 30, 1, 0, 5)); |
89 | 89 | |
90 | ASSERT_TRUE(video.get() != NULL); | |
90 | ASSERT_NE(video.get(), nullptr); | |
91 | 91 | ASSERT_NO_FATAL_FAILURE(RunLoop(video.get())); |
92 | 92 | } |
93 | 93 |
109 | 109 | vpx_free(quant_ptr_); |
110 | 110 | vpx_free(quant_shift_ptr_); |
111 | 111 | vpx_free(dequant_ptr_); |
112 | zbin_ptr_ = NULL; | |
113 | round_fp_ptr_ = NULL; | |
114 | quant_fp_ptr_ = NULL; | |
115 | round_ptr_ = NULL; | |
116 | quant_ptr_ = NULL; | |
117 | quant_shift_ptr_ = NULL; | |
118 | dequant_ptr_ = NULL; | |
112 | zbin_ptr_ = nullptr; | |
113 | round_fp_ptr_ = nullptr; | |
114 | quant_fp_ptr_ = nullptr; | |
115 | round_ptr_ = nullptr; | |
116 | quant_ptr_ = nullptr; | |
117 | quant_shift_ptr_ = nullptr; | |
118 | dequant_ptr_ = nullptr; | |
119 | 119 | libvpx_test::ClearSystemState(); |
120 | 120 | } |
121 | 121 |
23 | 23 | // Class for testing shutting off the loop filter. |
24 | 24 | class SkipLoopFilterTest { |
25 | 25 | public: |
26 | SkipLoopFilterTest() : video_(NULL), decoder_(NULL), md5_file_(NULL) {} | |
26 | SkipLoopFilterTest() | |
27 | : video_(nullptr), decoder_(nullptr), md5_file_(nullptr) {} | |
27 | 28 | |
28 | 29 | ~SkipLoopFilterTest() { |
29 | if (md5_file_ != NULL) fclose(md5_file_); | |
30 | if (md5_file_ != nullptr) fclose(md5_file_); | |
30 | 31 | delete decoder_; |
31 | 32 | delete video_; |
32 | 33 | } |
36 | 37 | expected_md5_[0] = '\0'; |
37 | 38 | junk_[0] = '\0'; |
38 | 39 | video_ = new libvpx_test::WebMVideoSource(kVp9TestFile); |
39 | if (video_ == NULL) { | |
40 | EXPECT_TRUE(video_ != NULL); | |
40 | if (video_ == nullptr) { | |
41 | EXPECT_NE(video_, nullptr); | |
41 | 42 | return false; |
42 | 43 | } |
43 | 44 | video_->Init(); |
46 | 47 | vpx_codec_dec_cfg_t cfg = vpx_codec_dec_cfg_t(); |
47 | 48 | if (num_threads > 0) cfg.threads = num_threads; |
48 | 49 | decoder_ = new libvpx_test::VP9Decoder(cfg, 0); |
49 | if (decoder_ == NULL) { | |
50 | EXPECT_TRUE(decoder_ != NULL); | |
50 | if (decoder_ == nullptr) { | |
51 | EXPECT_NE(decoder_, nullptr); | |
51 | 52 | return false; |
52 | 53 | } |
53 | 54 | |
72 | 73 | } |
73 | 74 | |
74 | 75 | vpx_codec_err_t DecodeRemainingFrames() { |
75 | for (; video_->cxdata() != NULL; video_->Next()) { | |
76 | for (; video_->cxdata() != nullptr; video_->Next()) { | |
76 | 77 | const vpx_codec_err_t res = |
77 | 78 | decoder_->DecodeFrame(video_->cxdata(), video_->frame_size()); |
78 | 79 | if (res != VPX_CODEC_OK) return res; |
92 | 93 | // TODO(fgalligan): Move the MD5 testing code into another class. |
93 | 94 | void OpenMd5File(const std::string &md5_file_name) { |
94 | 95 | md5_file_ = libvpx_test::OpenTestDataFile(md5_file_name); |
95 | ASSERT_TRUE(md5_file_ != NULL) | |
96 | ASSERT_NE(md5_file_, nullptr) | |
96 | 97 | << "MD5 file open failed. Filename: " << md5_file_name; |
97 | 98 | } |
98 | 99 | |
99 | 100 | // Reads the next line of the MD5 file. |
100 | 101 | void ReadMd5() { |
101 | ASSERT_TRUE(md5_file_ != NULL); | |
102 | ASSERT_NE(md5_file_, nullptr); | |
102 | 103 | const int res = fscanf(md5_file_, "%s %s", expected_md5_, junk_); |
103 | 104 | ASSERT_NE(EOF, res) << "Read md5 data failed"; |
104 | 105 | expected_md5_[32] = '\0'; |
127 | 127 | } |
128 | 128 | |
129 | 129 | TEST(VPxWorkerThreadTest, TestInterfaceAPI) { |
130 | EXPECT_EQ(0, vpx_set_worker_interface(NULL)); | |
131 | EXPECT_TRUE(vpx_get_worker_interface() != NULL); | |
130 | EXPECT_EQ(0, vpx_set_worker_interface(nullptr)); | |
131 | EXPECT_NE(vpx_get_worker_interface(), nullptr); | |
132 | 132 | for (int i = 0; i < 6; ++i) { |
133 | 133 | VPxWorkerInterface winterface = *vpx_get_worker_interface(); |
134 | 134 | switch (i) { |
135 | 135 | default: |
136 | case 0: winterface.init = NULL; break; | |
137 | case 1: winterface.reset = NULL; break; | |
138 | case 2: winterface.sync = NULL; break; | |
139 | case 3: winterface.launch = NULL; break; | |
140 | case 4: winterface.execute = NULL; break; | |
141 | case 5: winterface.end = NULL; break; | |
136 | case 0: winterface.init = nullptr; break; | |
137 | case 1: winterface.reset = nullptr; break; | |
138 | case 2: winterface.sync = nullptr; break; | |
139 | case 3: winterface.launch = nullptr; break; | |
140 | case 4: winterface.execute = nullptr; break; | |
141 | case 5: winterface.end = nullptr; break; | |
142 | 142 | } |
143 | 143 | EXPECT_EQ(0, vpx_set_worker_interface(&winterface)); |
144 | 144 | } |
171 | 171 | } |
172 | 172 | |
173 | 173 | libvpx_test::DxDataIterator dec_iter = decoder.GetDxData(); |
174 | const vpx_image_t *img = NULL; | |
174 | const vpx_image_t *img = nullptr; | |
175 | 175 | |
176 | 176 | // Get decompressed data |
177 | 177 | while ((img = dec_iter.Next())) { |
182 | 182 | } |
183 | 183 | |
184 | 184 | void DecodeFiles(const FileList files[]) { |
185 | for (const FileList *iter = files; iter->name != NULL; ++iter) { | |
185 | for (const FileList *iter = files; iter->name != nullptr; ++iter) { | |
186 | 186 | SCOPED_TRACE(iter->name); |
187 | 187 | for (int t = 1; t <= 8; ++t) { |
188 | 188 | EXPECT_EQ(iter->expected_md5, DecodeFile(iter->name, t)) |
244 | 244 | "368ebc6ebf3a5e478d85b2c3149b2848" }, |
245 | 245 | { "vp90-2-08-tile_1x8_frame_parallel.webm", |
246 | 246 | "17e439da2388aff3a0f69cb22579c6c1" }, |
247 | { NULL, NULL } }; | |
247 | { nullptr, nullptr } }; | |
248 | 248 | |
249 | 249 | DecodeFiles(files); |
250 | 250 | } |
295 | 295 | "ae96f21f21b6370cc0125621b441fc52" }, |
296 | 296 | { "vp90-2-14-resize-fp-tiles-8-4.webm", |
297 | 297 | "3eb4f24f10640d42218f7fd7b9fd30d4" }, |
298 | { NULL, NULL } | |
298 | { nullptr, nullptr } | |
299 | 299 | }; |
300 | 300 | |
301 | 301 | DecodeFiles(files); |
308 | 308 | { "vp90-2-08-tile_1x8.webm", "0941902a52e9092cb010905eab16364c" }, |
309 | 309 | { "vp90-2-08-tile-4x1.webm", "06505aade6647c583c8e00a2f582266f" }, |
310 | 310 | { "vp90-2-08-tile-4x4.webm", "85c2299892460d76e2c600502d52bfe2" }, |
311 | { NULL, NULL } | |
311 | { nullptr, nullptr } | |
312 | 312 | }; |
313 | 313 | |
314 | 314 | DecodeFiles(files); |
89 | 89 | |
90 | 90 | // Checks y4m header information |
91 | 91 | void HeaderChecks(unsigned int bit_depth, vpx_img_fmt_t fmt) { |
92 | ASSERT_TRUE(input_file_ != NULL); | |
92 | ASSERT_NE(input_file_, nullptr); | |
93 | 93 | ASSERT_EQ(y4m_.pic_w, (int)kWidth); |
94 | 94 | ASSERT_EQ(y4m_.pic_h, (int)kHeight); |
95 | 95 | ASSERT_EQ(img()->d_w, kWidth); |
115 | 115 | |
116 | 116 | // Checks MD5 of the raw frame data |
117 | 117 | void Md5Check(const string &expected_md5) { |
118 | ASSERT_TRUE(input_file_ != NULL); | |
118 | ASSERT_NE(input_file_, nullptr); | |
119 | 119 | libvpx_test::MD5 md5; |
120 | 120 | for (unsigned int i = start_; i < limit_; i++) { |
121 | 121 | md5.Add(img()); |
137 | 137 | |
138 | 138 | class Y4mVideoWriteTest : public Y4mVideoSourceTest { |
139 | 139 | protected: |
140 | Y4mVideoWriteTest() : tmpfile_(NULL) {} | |
140 | Y4mVideoWriteTest() : tmpfile_(nullptr) {} | |
141 | 141 | |
142 | 142 | virtual ~Y4mVideoWriteTest() { |
143 | 143 | delete tmpfile_; |
144 | input_file_ = NULL; | |
144 | input_file_ = nullptr; | |
145 | 145 | } |
146 | 146 | |
147 | 147 | void ReplaceInputFile(FILE *input_file) { |
154 | 154 | |
155 | 155 | // Writes out a y4m file and then reads it back |
156 | 156 | void WriteY4mAndReadBack() { |
157 | ASSERT_TRUE(input_file_ != NULL); | |
157 | ASSERT_NE(input_file_, nullptr); | |
158 | 158 | char buf[Y4M_BUFFER_SIZE] = { 0 }; |
159 | 159 | const struct VpxRational framerate = { y4m_.fps_n, y4m_.fps_d }; |
160 | 160 | tmpfile_ = new libvpx_test::TempOutFile; |
161 | ASSERT_TRUE(tmpfile_->file() != NULL); | |
161 | ASSERT_NE(tmpfile_->file(), nullptr); | |
162 | 162 | y4m_write_file_header(buf, sizeof(buf), kWidth, kHeight, &framerate, |
163 | 163 | y4m_.vpx_fmt, y4m_.bit_depth); |
164 | 164 | fputs(buf, tmpfile_->file()); |
187 | 187 | |
188 | 188 | INSTANTIATE_TEST_SUITE_P(C, Y4mVideoWriteTest, |
189 | 189 | ::testing::ValuesIn(kY4mTestVectors)); |
190 | ||
191 | static const char kY4MRegularHeader[] = | |
192 | "YUV4MPEG2 W4 H4 F30:1 Ip A0:0 C420jpeg XYSCSS=420JPEG\n" | |
193 | "FRAME\n" | |
194 | "012345678912345601230123"; | |
195 | ||
196 | TEST(Y4MHeaderTest, RegularHeader) { | |
197 | libvpx_test::TempOutFile f; | |
198 | fwrite(kY4MRegularHeader, 1, sizeof(kY4MRegularHeader), f.file()); | |
199 | fflush(f.file()); | |
200 | EXPECT_EQ(0, fseek(f.file(), 0, 0)); | |
201 | ||
202 | y4m_input y4m; | |
203 | EXPECT_EQ(y4m_input_open(&y4m, f.file(), /*skip_buffer=*/NULL, | |
204 | /*num_skip=*/0, /*only_420=*/0), | |
205 | 0); | |
206 | EXPECT_EQ(y4m.pic_w, 4); | |
207 | EXPECT_EQ(y4m.pic_h, 4); | |
208 | EXPECT_EQ(y4m.fps_n, 30); | |
209 | EXPECT_EQ(y4m.fps_d, 1); | |
210 | EXPECT_EQ(y4m.interlace, 'p'); | |
211 | EXPECT_EQ(strcmp("420jpeg", y4m.chroma_type), 0); | |
212 | y4m_input_close(&y4m); | |
213 | } | |
214 | ||
215 | // Testing that headers over 100 characters can be parsed. | |
216 | static const char kY4MLongHeader[] = | |
217 | "YUV4MPEG2 W4 H4 F30:1 Ip A0:0 C420jpeg XYSCSS=420JPEG " | |
218 | "XCOLORRANGE=LIMITED XSOME_UNKNOWN_METADATA XOTHER_UNKNOWN_METADATA\n" | |
219 | "FRAME\n" | |
220 | "012345678912345601230123"; | |
221 | ||
222 | TEST(Y4MHeaderTest, LongHeader) { | |
223 | libvpx_test::TempOutFile f; | |
224 | fwrite(kY4MLongHeader, 1, sizeof(kY4MLongHeader), f.file()); | |
225 | fflush(f.file()); | |
226 | EXPECT_EQ(fseek(f.file(), 0, 0), 0); | |
227 | ||
228 | y4m_input y4m; | |
229 | EXPECT_EQ(y4m_input_open(&y4m, f.file(), /*skip_buffer=*/NULL, | |
230 | /*num_skip=*/0, /*only_420=*/0), | |
231 | 0); | |
232 | EXPECT_EQ(y4m.pic_w, 4); | |
233 | EXPECT_EQ(y4m.pic_h, 4); | |
234 | EXPECT_EQ(y4m.fps_n, 30); | |
235 | EXPECT_EQ(y4m.fps_d, 1); | |
236 | EXPECT_EQ(y4m.interlace, 'p'); | |
237 | EXPECT_EQ(strcmp("420jpeg", y4m.chroma_type), 0); | |
238 | y4m_input_close(&y4m); | |
239 | } | |
240 | ||
190 | 241 | } // namespace |
0 | 0 | URL: https://github.com/google/googletest.git |
1 | Version: release-1.10.0 | |
1 | Version: release-1.10.0-224-g23b2a3b1 | |
2 | 2 | License: BSD |
3 | 3 | License File: LICENSE |
4 | 4 | |
12 | 12 | |
13 | 13 | Local Modifications: |
14 | 14 | - Remove everything but: |
15 | googletest-release-1.10.0/googletest/ | |
16 | CHANGES | |
15 | googletest/ | |
17 | 16 | CONTRIBUTORS |
18 | 17 | include |
19 | 18 | LICENSE |
20 | 19 | README.md |
21 | 20 | src |
21 | - Enable kErrorOnUninstantiatedParameterizedTest and | |
22 | kErrorOnUninstantiatedTypeParameterizedTest in gtest.cc |
0 | Changes for 1.7.0: | |
1 | ||
2 | * New feature: death tests are supported on OpenBSD and in iOS | |
3 | simulator now. | |
4 | * New feature: Google Test now implements a protocol to allow | |
5 | a test runner to detect that a test program has exited | |
6 | prematurely and report it as a failure (before it would be | |
7 | falsely reported as a success if the exit code is 0). | |
8 | * New feature: Test::RecordProperty() can now be used outside of the | |
9 | lifespan of a test method, in which case it will be attributed to | |
10 | the current test case or the test program in the XML report. | |
11 | * New feature (potentially breaking): --gtest_list_tests now prints | |
12 | the type parameters and value parameters for each test. | |
13 | * Improvement: char pointers and char arrays are now escaped properly | |
14 | in failure messages. | |
15 | * Improvement: failure summary in XML reports now includes file and | |
16 | line information. | |
17 | * Improvement: the <testsuites> XML element now has a timestamp attribute. | |
18 | * Improvement: When --gtest_filter is specified, XML report now doesn't | |
19 | contain information about tests that are filtered out. | |
20 | * Fixed the bug where long --gtest_filter flag values are truncated in | |
21 | death tests. | |
22 | * Potentially breaking change: RUN_ALL_TESTS() is now implemented as a | |
23 | function instead of a macro in order to work better with Clang. | |
24 | * Compatibility fixes with C++ 11 and various platforms. | |
25 | * Bug/warning fixes. | |
26 | ||
27 | Changes for 1.6.0: | |
28 | ||
29 | * New feature: ADD_FAILURE_AT() for reporting a test failure at the | |
30 | given source location -- useful for writing testing utilities. | |
31 | * New feature: the universal value printer is moved from Google Mock | |
32 | to Google Test. | |
33 | * New feature: type parameters and value parameters are reported in | |
34 | the XML report now. | |
35 | * A gtest_disable_pthreads CMake option. | |
36 | * Colored output works in GNU Screen sessions now. | |
37 | * Parameters of value-parameterized tests are now printed in the | |
38 | textual output. | |
39 | * Failures from ad hoc test assertions run before RUN_ALL_TESTS() are | |
40 | now correctly reported. | |
41 | * Arguments of ASSERT_XY and EXPECT_XY no longer need to support << to | |
42 | ostream. | |
43 | * More complete handling of exceptions. | |
44 | * GTEST_ASSERT_XY can be used instead of ASSERT_XY in case the latter | |
45 | name is already used by another library. | |
46 | * --gtest_catch_exceptions is now true by default, allowing a test | |
47 | program to continue after an exception is thrown. | |
48 | * Value-parameterized test fixtures can now derive from Test and | |
49 | WithParamInterface<T> separately, easing conversion of legacy tests. | |
50 | * Death test messages are clearly marked to make them more | |
51 | distinguishable from other messages. | |
52 | * Compatibility fixes for Android, Google Native Client, MinGW, HP UX, | |
53 | PowerPC, Lucid autotools, libCStd, Sun C++, Borland C++ Builder (Code Gear), | |
54 | IBM XL C++ (Visual Age C++), and C++0x. | |
55 | * Bug fixes and implementation clean-ups. | |
56 | * Potentially incompatible changes: disables the harmful 'make install' | |
57 | command in autotools. | |
58 | ||
59 | Changes for 1.5.0: | |
60 | ||
61 | * New feature: assertions can be safely called in multiple threads | |
62 | where the pthreads library is available. | |
63 | * New feature: predicates used inside EXPECT_TRUE() and friends | |
64 | can now generate custom failure messages. | |
65 | * New feature: Google Test can now be compiled as a DLL. | |
66 | * New feature: fused source files are included. | |
67 | * New feature: prints help when encountering unrecognized Google Test flags. | |
68 | * Experimental feature: CMake build script (requires CMake 2.6.4+). | |
69 | * Experimental feature: the Pump script for meta programming. | |
70 | * double values streamed to an assertion are printed with enough precision | |
71 | to differentiate any two different values. | |
72 | * Google Test now works on Solaris and AIX. | |
73 | * Build and test script improvements. | |
74 | * Bug fixes and implementation clean-ups. | |
75 | ||
76 | Potentially breaking changes: | |
77 | ||
78 | * Stopped supporting VC++ 7.1 with exceptions disabled. | |
79 | * Dropped support for 'make install'. | |
80 | ||
81 | Changes for 1.4.0: | |
82 | ||
83 | * New feature: the event listener API | |
84 | * New feature: test shuffling | |
85 | * New feature: the XML report format is closer to junitreport and can | |
86 | be parsed by Hudson now. | |
87 | * New feature: when a test runs under Visual Studio, its failures are | |
88 | integrated in the IDE. | |
89 | * New feature: /MD(d) versions of VC++ projects. | |
90 | * New feature: elapsed time for the tests is printed by default. | |
91 | * New feature: comes with a TR1 tuple implementation such that Boost | |
92 | is no longer needed for Combine(). | |
93 | * New feature: EXPECT_DEATH_IF_SUPPORTED macro and friends. | |
94 | * New feature: the Xcode project can now produce static gtest | |
95 | libraries in addition to a framework. | |
96 | * Compatibility fixes for Solaris, Cygwin, minGW, Windows Mobile, | |
97 | Symbian, gcc, and C++Builder. | |
98 | * Bug fixes and implementation clean-ups. | |
99 | ||
100 | Changes for 1.3.0: | |
101 | ||
102 | * New feature: death tests on Windows, Cygwin, and Mac. | |
103 | * New feature: ability to use Google Test assertions in other testing | |
104 | frameworks. | |
105 | * New feature: ability to run disabled test via | |
106 | --gtest_also_run_disabled_tests. | |
107 | * New feature: the --help flag for printing the usage. | |
108 | * New feature: access to Google Test flag values in user code. | |
109 | * New feature: a script that packs Google Test into one .h and one | |
110 | .cc file for easy deployment. | |
111 | * New feature: support for distributing test functions to multiple | |
112 | machines (requires support from the test runner). | |
113 | * Bug fixes and implementation clean-ups. | |
114 | ||
115 | Changes for 1.2.1: | |
116 | ||
117 | * Compatibility fixes for Linux IA-64 and IBM z/OS. | |
118 | * Added support for using Boost and other TR1 implementations. | |
119 | * Changes to the build scripts to support upcoming release of Google C++ | |
120 | Mocking Framework. | |
121 | * Added Makefile to the distribution package. | |
122 | * Improved build instructions in README. | |
123 | ||
124 | Changes for 1.2.0: | |
125 | ||
126 | * New feature: value-parameterized tests. | |
127 | * New feature: the ASSERT/EXPECT_(NON)FATAL_FAILURE(_ON_ALL_THREADS) | |
128 | macros. | |
129 | * Changed the XML report format to match JUnit/Ant's. | |
130 | * Added tests to the Xcode project. | |
131 | * Added scons/SConscript for building with SCons. | |
132 | * Added src/gtest-all.cc for building Google Test from a single file. | |
133 | * Fixed compatibility with Solaris and z/OS. | |
134 | * Enabled running Python tests on systems with python 2.3 installed, | |
135 | e.g. Mac OS X 10.4. | |
136 | * Bug fixes. | |
137 | ||
138 | Changes for 1.1.0: | |
139 | ||
140 | * New feature: type-parameterized tests. | |
141 | * New feature: exception assertions. | |
142 | * New feature: printing elapsed time of tests. | |
143 | * Improved the robustness of death tests. | |
144 | * Added an Xcode project and samples. | |
145 | * Adjusted the output format on Windows to be understandable by Visual Studio. | |
146 | * Minor bug fixes. | |
147 | ||
148 | Changes for 1.0.1: | |
149 | ||
150 | * Added project files for Visual Studio 7.1. | |
151 | * Fixed issues with compiling on Mac OS X. | |
152 | * Fixed issues with compiling on Cygwin. | |
153 | ||
154 | Changes for 1.0.0: | |
155 | ||
156 | * Initial Open Source release of Google Test |
16 | 16 | Keir Mierle <mierle@gmail.com> |
17 | 17 | Keith Ray <keith.ray@gmail.com> |
18 | 18 | Kenton Varda <kenton@google.com> |
19 | Krystian Kuzniarek <krystian.kuzniarek@gmail.com> | |
19 | 20 | Manuel Klimek <klimek@google.com> |
20 | 21 | Markus Heule <markus.heule@gmail.com> |
21 | 22 | Mika Raento <mikie@iki.fi> |
7 | 7 | |
8 | 8 | ### Build with CMake |
9 | 9 | |
10 | Google Test comes with a CMake build script ( | |
11 | [CMakeLists.txt](https://github.com/google/googletest/blob/master/CMakeLists.txt)) | |
10 | Google Test comes with a CMake build script | |
11 | ([CMakeLists.txt](https://github.com/google/googletest/blob/master/CMakeLists.txt)) | |
12 | 12 | that can be used on a wide range of platforms ("C" stands for cross-platform.). |
13 | 13 | If you don't have CMake installed already, you can download it for free from |
14 | 14 | <http://www.cmake.org/>. |
383 | 383 | Matcher(const char* s); // NOLINT |
384 | 384 | }; |
385 | 385 | |
386 | #if GTEST_HAS_ABSL | |
386 | #if GTEST_INTERNAL_HAS_STRING_VIEW | |
387 | 387 | // The following two specializations allow the user to write str |
388 | 388 | // instead of Eq(str) and "foo" instead of Eq("foo") when a absl::string_view |
389 | 389 | // matcher is expected. |
390 | 390 | template <> |
391 | class GTEST_API_ Matcher<const absl::string_view&> | |
392 | : public internal::MatcherBase<const absl::string_view&> { | |
391 | class GTEST_API_ Matcher<const internal::StringView&> | |
392 | : public internal::MatcherBase<const internal::StringView&> { | |
393 | 393 | public: |
394 | 394 | Matcher() {} |
395 | 395 | |
396 | explicit Matcher(const MatcherInterface<const absl::string_view&>* impl) | |
397 | : internal::MatcherBase<const absl::string_view&>(impl) {} | |
396 | explicit Matcher(const MatcherInterface<const internal::StringView&>* impl) | |
397 | : internal::MatcherBase<const internal::StringView&>(impl) {} | |
398 | 398 | |
399 | 399 | // Allows the user to write str instead of Eq(str) sometimes, where |
400 | 400 | // str is a std::string object. |
403 | 403 | // Allows the user to write "foo" instead of Eq("foo") sometimes. |
404 | 404 | Matcher(const char* s); // NOLINT |
405 | 405 | |
406 | // Allows the user to pass absl::string_views directly. | |
407 | Matcher(absl::string_view s); // NOLINT | |
406 | // Allows the user to pass absl::string_views or std::string_views directly. | |
407 | Matcher(internal::StringView s); // NOLINT | |
408 | 408 | }; |
409 | 409 | |
410 | 410 | template <> |
411 | class GTEST_API_ Matcher<absl::string_view> | |
412 | : public internal::MatcherBase<absl::string_view> { | |
411 | class GTEST_API_ Matcher<internal::StringView> | |
412 | : public internal::MatcherBase<internal::StringView> { | |
413 | 413 | public: |
414 | 414 | Matcher() {} |
415 | 415 | |
416 | explicit Matcher(const MatcherInterface<const absl::string_view&>* impl) | |
417 | : internal::MatcherBase<absl::string_view>(impl) {} | |
418 | explicit Matcher(const MatcherInterface<absl::string_view>* impl) | |
419 | : internal::MatcherBase<absl::string_view>(impl) {} | |
416 | explicit Matcher(const MatcherInterface<const internal::StringView&>* impl) | |
417 | : internal::MatcherBase<internal::StringView>(impl) {} | |
418 | explicit Matcher(const MatcherInterface<internal::StringView>* impl) | |
419 | : internal::MatcherBase<internal::StringView>(impl) {} | |
420 | 420 | |
421 | 421 | // Allows the user to write str instead of Eq(str) sometimes, where |
422 | 422 | // str is a std::string object. |
425 | 425 | // Allows the user to write "foo" instead of Eq("foo") sometimes. |
426 | 426 | Matcher(const char* s); // NOLINT |
427 | 427 | |
428 | // Allows the user to pass absl::string_views directly. | |
429 | Matcher(absl::string_view s); // NOLINT | |
430 | }; | |
431 | #endif // GTEST_HAS_ABSL | |
428 | // Allows the user to pass absl::string_views or std::string_views directly. | |
429 | Matcher(internal::StringView s); // NOLINT | |
430 | }; | |
431 | #endif // GTEST_INTERNAL_HAS_STRING_VIEW | |
432 | 432 | |
433 | 433 | // Prints a matcher in a human-readable format. |
434 | 434 | template <typename T> |
473 | 473 | public: |
474 | 474 | explicit MonomorphicImpl(const Impl& impl) : impl_(impl) {} |
475 | 475 | |
476 | virtual void DescribeTo(::std::ostream* os) const { impl_.DescribeTo(os); } | |
477 | ||
478 | virtual void DescribeNegationTo(::std::ostream* os) const { | |
476 | void DescribeTo(::std::ostream* os) const override { impl_.DescribeTo(os); } | |
477 | ||
478 | void DescribeNegationTo(::std::ostream* os) const override { | |
479 | 479 | impl_.DescribeNegationTo(os); |
480 | 480 | } |
481 | 481 | |
482 | virtual bool MatchAndExplain(T x, MatchResultListener* listener) const { | |
482 | bool MatchAndExplain(T x, MatchResultListener* listener) const override { | |
483 | 483 | return impl_.MatchAndExplain(x, listener); |
484 | 484 | } |
485 | 485 | |
619 | 619 | MatchesRegexMatcher(const RE* regex, bool full_match) |
620 | 620 | : regex_(regex), full_match_(full_match) {} |
621 | 621 | |
622 | #if GTEST_HAS_ABSL | |
623 | bool MatchAndExplain(const absl::string_view& s, | |
622 | #if GTEST_INTERNAL_HAS_STRING_VIEW | |
623 | bool MatchAndExplain(const internal::StringView& s, | |
624 | 624 | MatchResultListener* listener) const { |
625 | 625 | return MatchAndExplain(std::string(s), listener); |
626 | 626 | } |
627 | #endif // GTEST_HAS_ABSL | |
627 | #endif // GTEST_INTERNAL_HAS_STRING_VIEW | |
628 | 628 | |
629 | 629 | // Accepts pointer types, particularly: |
630 | 630 | // const char* |
48 | 48 | |
49 | 49 | #include <limits> |
50 | 50 | #include <memory> |
51 | #include <sstream> | |
51 | 52 | |
52 | 53 | #include "gtest/internal/gtest-port.h" |
53 | 54 |
415 | 415 | : public test_suite_name { \ |
416 | 416 | public: \ |
417 | 417 | GTEST_TEST_CLASS_NAME_(test_suite_name, test_name)() {} \ |
418 | virtual void TestBody(); \ | |
418 | void TestBody() override; \ | |
419 | 419 | \ |
420 | 420 | private: \ |
421 | 421 | static int AddToRegistry() { \ |
422 | 422 | ::testing::UnitTest::GetInstance() \ |
423 | 423 | ->parameterized_test_registry() \ |
424 | 424 | .GetTestSuitePatternHolder<test_suite_name>( \ |
425 | #test_suite_name, \ | |
425 | GTEST_STRINGIFY_(test_suite_name), \ | |
426 | 426 | ::testing::internal::CodeLocation(__FILE__, __LINE__)) \ |
427 | 427 | ->AddTestPattern( \ |
428 | 428 | GTEST_STRINGIFY_(test_suite_name), GTEST_STRINGIFY_(test_name), \ |
482 | 482 | ::testing::UnitTest::GetInstance() \ |
483 | 483 | ->parameterized_test_registry() \ |
484 | 484 | .GetTestSuitePatternHolder<test_suite_name>( \ |
485 | #test_suite_name, \ | |
485 | GTEST_STRINGIFY_(test_suite_name), \ | |
486 | 486 | ::testing::internal::CodeLocation(__FILE__, __LINE__)) \ |
487 | 487 | ->AddTestSuiteInstantiation( \ |
488 | #prefix, >est_##prefix##test_suite_name##_EvalGenerator_, \ | |
488 | GTEST_STRINGIFY_(prefix), \ | |
489 | >est_##prefix##test_suite_name##_EvalGenerator_, \ | |
489 | 490 | >est_##prefix##test_suite_name##_EvalGenerateName_, \ |
490 | 491 | __FILE__, __LINE__) |
492 | ||
493 | ||
494 | // Allow Marking a Parameterized test class as not needing to be instantiated. | |
495 | #define GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(T) \ | |
496 | namespace gtest_do_not_use_outside_namespace_scope {} \ | |
497 | static const ::testing::internal::MarkAsIgnored gtest_allow_ignore_##T( \ | |
498 | GTEST_STRINGIFY_(T)) | |
491 | 499 | |
492 | 500 | // Legacy API is deprecated but still available |
493 | 501 | #ifndef GTEST_REMOVE_LEGACY_TEST_CASEAPI_ |
134 | 134 | kProtobuf, // a protobuf type |
135 | 135 | kConvertibleToInteger, // a type implicitly convertible to BiggestInt |
136 | 136 | // (e.g. a named or unnamed enum type) |
137 | #if GTEST_HAS_ABSL | |
137 | #if GTEST_INTERNAL_HAS_STRING_VIEW | |
138 | 138 | kConvertibleToStringView, // a type implicitly convertible to |
139 | // absl::string_view | |
139 | // absl::string_view or std::string_view | |
140 | 140 | #endif |
141 | 141 | kOtherType // anything else |
142 | 142 | }; |
190 | 190 | } |
191 | 191 | }; |
192 | 192 | |
193 | #if GTEST_HAS_ABSL | |
193 | #if GTEST_INTERNAL_HAS_STRING_VIEW | |
194 | 194 | template <typename T> |
195 | 195 | class TypeWithoutFormatter<T, kConvertibleToStringView> { |
196 | 196 | public: |
197 | 197 | // Since T has neither operator<< nor PrintTo() but can be implicitly |
198 | // converted to absl::string_view, we print it as a absl::string_view. | |
198 | // converted to absl::string_view, we print it as a absl::string_view | |
199 | // (or std::string_view). | |
199 | 200 | // |
200 | 201 | // Note: the implementation is further below, as it depends on |
201 | 202 | // internal::PrintTo symbol which is defined later in the file. |
236 | 237 | const T&, internal::BiggestInt>::value |
237 | 238 | ? kConvertibleToInteger |
238 | 239 | : |
239 | #if GTEST_HAS_ABSL | |
240 | #if GTEST_INTERNAL_HAS_STRING_VIEW | |
240 | 241 | std::is_convertible< |
241 | const T&, absl::string_view>::value | |
242 | const T&, internal::StringView>::value | |
242 | 243 | ? kConvertibleToStringView |
243 | 244 | : |
244 | 245 | #endif |
265 | 266 | // 7.3.4-1 [namespace.udir]. This allows us to fall back onto |
266 | 267 | // testing::internal2::operator<< in case T doesn't come with a << |
267 | 268 | // operator. |
268 | // | |
269 | // We cannot write 'using ::testing::internal2::operator<<;', which | |
270 | // gcc 3.3 fails to compile due to a compiler bug. | |
271 | using namespace ::testing::internal2; // NOLINT | |
269 | ||
270 | using ::testing::internal2::operator<<; | |
272 | 271 | |
273 | 272 | // Assuming T is defined in namespace foo, in the next statement, |
274 | 273 | // the compiler will consider all of: |
602 | 601 | } |
603 | 602 | #endif // GTEST_HAS_STD_WSTRING |
604 | 603 | |
605 | #if GTEST_HAS_ABSL | |
606 | // Overload for absl::string_view. | |
607 | inline void PrintTo(absl::string_view sp, ::std::ostream* os) { | |
604 | #if GTEST_INTERNAL_HAS_STRING_VIEW | |
605 | // Overload for internal::StringView. | |
606 | inline void PrintTo(internal::StringView sp, ::std::ostream* os) { | |
608 | 607 | PrintTo(::std::string(sp), os); |
609 | 608 | } |
610 | #endif // GTEST_HAS_ABSL | |
609 | #endif // GTEST_INTERNAL_HAS_STRING_VIEW | |
611 | 610 | |
612 | 611 | inline void PrintTo(std::nullptr_t, ::std::ostream* os) { *os << "(nullptr)"; } |
613 | 612 | |
900 | 899 | |
901 | 900 | } // namespace internal |
902 | 901 | |
903 | #if GTEST_HAS_ABSL | |
902 | #if GTEST_INTERNAL_HAS_STRING_VIEW | |
904 | 903 | namespace internal2 { |
905 | 904 | template <typename T> |
906 | 905 | void TypeWithoutFormatter<T, kConvertibleToStringView>::PrintValue( |
907 | 906 | const T& value, ::std::ostream* os) { |
908 | internal::PrintTo(absl::string_view(value), os); | |
907 | internal::PrintTo(internal::StringView(value), os); | |
909 | 908 | } |
910 | 909 | } // namespace internal2 |
911 | 910 | #endif |
26 | 26 | // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
27 | 27 | // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
28 | 28 | |
29 | ||
30 | 29 | // GOOGLETEST_CM0001 DO NOT DELETE |
31 | 30 | |
32 | 31 | #ifndef GTEST_INCLUDE_GTEST_GTEST_TYPED_TEST_H_ |
169 | 168 | |
170 | 169 | #endif // 0 |
171 | 170 | |
171 | #include "gtest/internal/gtest-internal.h" | |
172 | 172 | #include "gtest/internal/gtest-port.h" |
173 | 173 | #include "gtest/internal/gtest-type-util.h" |
174 | 174 | |
187 | 187 | #define GTEST_NAME_GENERATOR_(TestSuiteName) \ |
188 | 188 | gtest_type_params_##TestSuiteName##_NameGenerator |
189 | 189 | |
190 | #define TYPED_TEST_SUITE(CaseName, Types, ...) \ | |
191 | typedef ::testing::internal::TypeList<Types>::type GTEST_TYPE_PARAMS_( \ | |
192 | CaseName); \ | |
193 | typedef ::testing::internal::NameGeneratorSelector<__VA_ARGS__>::type \ | |
190 | #define TYPED_TEST_SUITE(CaseName, Types, ...) \ | |
191 | typedef ::testing::internal::GenerateTypeList<Types>::type \ | |
192 | GTEST_TYPE_PARAMS_(CaseName); \ | |
193 | typedef ::testing::internal::NameGeneratorSelector<__VA_ARGS__>::type \ | |
194 | 194 | GTEST_NAME_GENERATOR_(CaseName) |
195 | 195 | |
196 | # define TYPED_TEST(CaseName, TestName) \ | |
196 | #define TYPED_TEST(CaseName, TestName) \ | |
197 | static_assert(sizeof(GTEST_STRINGIFY_(TestName)) > 1, \ | |
198 | "test-name must not be empty"); \ | |
197 | 199 | template <typename gtest_TypeParam_> \ |
198 | 200 | class GTEST_TEST_CLASS_NAME_(CaseName, TestName) \ |
199 | 201 | : public CaseName<gtest_TypeParam_> { \ |
200 | 202 | private: \ |
201 | 203 | typedef CaseName<gtest_TypeParam_> TestFixture; \ |
202 | 204 | typedef gtest_TypeParam_ TypeParam; \ |
203 | virtual void TestBody(); \ | |
205 | void TestBody() override; \ | |
204 | 206 | }; \ |
205 | 207 | static bool gtest_##CaseName##_##TestName##_registered_ \ |
206 | GTEST_ATTRIBUTE_UNUSED_ = \ | |
207 | ::testing::internal::TypeParameterizedTest< \ | |
208 | GTEST_ATTRIBUTE_UNUSED_ = ::testing::internal::TypeParameterizedTest< \ | |
208 | 209 | CaseName, \ |
209 | 210 | ::testing::internal::TemplateSel<GTEST_TEST_CLASS_NAME_(CaseName, \ |
210 | 211 | TestName)>, \ |
212 | 213 | CaseName)>::Register("", \ |
213 | 214 | ::testing::internal::CodeLocation( \ |
214 | 215 | __FILE__, __LINE__), \ |
215 | #CaseName, #TestName, 0, \ | |
216 | GTEST_STRINGIFY_(CaseName), \ | |
217 | GTEST_STRINGIFY_(TestName), 0, \ | |
216 | 218 | ::testing::internal::GenerateNames< \ |
217 | 219 | GTEST_NAME_GENERATOR_(CaseName), \ |
218 | 220 | GTEST_TYPE_PARAMS_(CaseName)>()); \ |
275 | 277 | private: \ |
276 | 278 | typedef SuiteName<gtest_TypeParam_> TestFixture; \ |
277 | 279 | typedef gtest_TypeParam_ TypeParam; \ |
278 | virtual void TestBody(); \ | |
280 | void TestBody() override; \ | |
279 | 281 | }; \ |
280 | 282 | static bool gtest_##TestName##_defined_ GTEST_ATTRIBUTE_UNUSED_ = \ |
281 | 283 | GTEST_TYPED_TEST_SUITE_P_STATE_(SuiteName).AddTestName( \ |
282 | __FILE__, __LINE__, #SuiteName, #TestName); \ | |
284 | __FILE__, __LINE__, GTEST_STRINGIFY_(SuiteName), \ | |
285 | GTEST_STRINGIFY_(TestName)); \ | |
283 | 286 | } \ |
284 | 287 | template <typename gtest_TypeParam_> \ |
285 | 288 | void GTEST_SUITE_NAMESPACE_( \ |
286 | 289 | SuiteName)::TestName<gtest_TypeParam_>::TestBody() |
287 | 290 | |
288 | #define REGISTER_TYPED_TEST_SUITE_P(SuiteName, ...) \ | |
289 | namespace GTEST_SUITE_NAMESPACE_(SuiteName) { \ | |
290 | typedef ::testing::internal::Templates<__VA_ARGS__>::type gtest_AllTests_; \ | |
291 | } \ | |
292 | static const char* const GTEST_REGISTERED_TEST_NAMES_( \ | |
293 | SuiteName) GTEST_ATTRIBUTE_UNUSED_ = \ | |
294 | GTEST_TYPED_TEST_SUITE_P_STATE_(SuiteName).VerifyRegisteredTestNames( \ | |
295 | __FILE__, __LINE__, #__VA_ARGS__) | |
291 | // Note: this won't work correctly if the trailing arguments are macros. | |
292 | #define REGISTER_TYPED_TEST_SUITE_P(SuiteName, ...) \ | |
293 | namespace GTEST_SUITE_NAMESPACE_(SuiteName) { \ | |
294 | typedef ::testing::internal::Templates<__VA_ARGS__> gtest_AllTests_; \ | |
295 | } \ | |
296 | static const char* const GTEST_REGISTERED_TEST_NAMES_( \ | |
297 | SuiteName) GTEST_ATTRIBUTE_UNUSED_ = \ | |
298 | GTEST_TYPED_TEST_SUITE_P_STATE_(SuiteName).VerifyRegisteredTestNames( \ | |
299 | GTEST_STRINGIFY_(SuiteName), __FILE__, __LINE__, #__VA_ARGS__) | |
296 | 300 | |
297 | 301 | // Legacy API is deprecated but still available |
298 | 302 | #ifndef GTEST_REMOVE_LEGACY_TEST_CASEAPI_ |
303 | 307 | #endif // GTEST_REMOVE_LEGACY_TEST_CASEAPI_ |
304 | 308 | |
305 | 309 | #define INSTANTIATE_TYPED_TEST_SUITE_P(Prefix, SuiteName, Types, ...) \ |
310 | static_assert(sizeof(GTEST_STRINGIFY_(Prefix)) > 1, \ | |
311 | "test-suit-prefix must not be empty"); \ | |
306 | 312 | static bool gtest_##Prefix##_##SuiteName GTEST_ATTRIBUTE_UNUSED_ = \ |
307 | 313 | ::testing::internal::TypeParameterizedTestSuite< \ |
308 | 314 | SuiteName, GTEST_SUITE_NAMESPACE_(SuiteName)::gtest_AllTests_, \ |
309 | ::testing::internal::TypeList<Types>::type>:: \ | |
310 | Register(#Prefix, \ | |
315 | ::testing::internal::GenerateTypeList<Types>::type>:: \ | |
316 | Register(GTEST_STRINGIFY_(Prefix), \ | |
311 | 317 | ::testing::internal::CodeLocation(__FILE__, __LINE__), \ |
312 | >EST_TYPED_TEST_SUITE_P_STATE_(SuiteName), #SuiteName, \ | |
318 | >EST_TYPED_TEST_SUITE_P_STATE_(SuiteName), \ | |
319 | GTEST_STRINGIFY_(SuiteName), \ | |
313 | 320 | GTEST_REGISTERED_TEST_NAMES_(SuiteName), \ |
314 | 321 | ::testing::internal::GenerateNames< \ |
315 | 322 | ::testing::internal::NameGeneratorSelector< \ |
316 | 323 | __VA_ARGS__>::type, \ |
317 | ::testing::internal::TypeList<Types>::type>()) | |
324 | ::testing::internal::GenerateTypeList<Types>::type>()) | |
318 | 325 | |
319 | 326 | // Legacy API is deprecated but still available |
320 | 327 | #ifndef GTEST_REMOVE_LEGACY_TEST_CASEAPI_ |
176 | 176 | class UnitTestImpl* GetUnitTestImpl(); |
177 | 177 | void ReportFailureInUnknownLocation(TestPartResult::Type result_type, |
178 | 178 | const std::string& message); |
179 | std::set<std::string>* GetIgnoredParameterizedTestSuites(); | |
179 | 180 | |
180 | 181 | } // namespace internal |
181 | 182 | |
277 | 278 | // Used in EXPECT_TRUE/FALSE(assertion_result). |
278 | 279 | AssertionResult(const AssertionResult& other); |
279 | 280 | |
280 | #if defined(_MSC_VER) && _MSC_VER < 1910 | |
281 | // C4800 is a level 3 warning in Visual Studio 2015 and earlier. | |
282 | // This warning is not emitted in Visual Studio 2017. | |
283 | // This warning is off by default starting in Visual Studio 2019 but can be | |
284 | // enabled with command-line options. | |
285 | #if defined(_MSC_VER) && (_MSC_VER < 1910 || _MSC_VER >= 1920) | |
281 | 286 | GTEST_DISABLE_MSC_WARNINGS_PUSH_(4800 /* forcing value to bool */) |
282 | 287 | #endif |
283 | 288 | |
297 | 302 | = nullptr) |
298 | 303 | : success_(success) {} |
299 | 304 | |
300 | #if defined(_MSC_VER) && _MSC_VER < 1910 | |
305 | #if defined(_MSC_VER) && (_MSC_VER < 1910 || _MSC_VER >= 1920) | |
301 | 306 | GTEST_DISABLE_MSC_WARNINGS_POP_() |
302 | 307 | #endif |
303 | 308 | |
411 | 416 | // test in test case Foo. Hence a sub-class can define its own |
412 | 417 | // SetUpTestSuite() method to shadow the one defined in the super |
413 | 418 | // class. |
414 | // Failures that happen during SetUpTestSuite are logged but otherwise | |
415 | // ignored. | |
416 | 419 | static void SetUpTestSuite() {} |
417 | 420 | |
418 | 421 | // Tears down the stuff shared by all tests in this test suite. |
421 | 424 | // test in test case Foo. Hence a sub-class can define its own |
422 | 425 | // TearDownTestSuite() method to shadow the one defined in the super |
423 | 426 | // class. |
424 | // Failures that happen during TearDownTestSuite are logged but otherwise | |
425 | // ignored. | |
426 | 427 | static void TearDownTestSuite() {} |
427 | 428 | |
428 | 429 | // Legacy API is deprecated but still available |
888 | 889 | bool Passed() const { return !Failed(); } |
889 | 890 | |
890 | 891 | // Returns true if and only if the test suite failed. |
891 | bool Failed() const { return failed_test_count() > 0; } | |
892 | bool Failed() const { | |
893 | return failed_test_count() > 0 || ad_hoc_test_result().Failed(); | |
894 | } | |
892 | 895 | |
893 | 896 | // Returns the elapsed time, in milliseconds. |
894 | 897 | TimeInMillis elapsed_time() const { return elapsed_time_; } |
1419 | 1422 | friend class internal::StreamingListenerTest; |
1420 | 1423 | friend class internal::UnitTestRecordPropertyTestHelper; |
1421 | 1424 | friend Environment* AddGlobalTestEnvironment(Environment* env); |
1425 | friend std::set<std::string>* internal::GetIgnoredParameterizedTestSuites(); | |
1422 | 1426 | friend internal::UnitTestImpl* internal::GetUnitTestImpl(); |
1423 | 1427 | friend void internal::ReportFailureInUnknownLocation( |
1424 | 1428 | TestPartResult::Type result_type, |
1888 | 1892 | // Skips test in runtime. |
1889 | 1893 | // Skipping test aborts current function. |
1890 | 1894 | // Skipped tests are neither successful nor failed. |
1891 | #define GTEST_SKIP() GTEST_SKIP_("Skipped") | |
1895 | #define GTEST_SKIP() GTEST_SKIP_("") | |
1892 | 1896 | |
1893 | 1897 | // ADD_FAILURE unconditionally adds a failure to the current test. |
1894 | 1898 | // SUCCEED generates a success - it doesn't automatically make the |
2297 | 2301 | // to cause a compiler error. |
2298 | 2302 | template <typename T1, typename T2> |
2299 | 2303 | constexpr bool StaticAssertTypeEq() noexcept { |
2300 | static_assert(std::is_same<T1, T2>::value, | |
2301 | "type1 and type2 are not the same type"); | |
2304 | static_assert(std::is_same<T1, T2>::value, "T1 and T2 are not the same type"); | |
2302 | 2305 | return true; |
2303 | 2306 | } |
2304 | 2307 | |
2364 | 2367 | // } |
2365 | 2368 | // |
2366 | 2369 | // GOOGLETEST_CM0011 DO NOT DELETE |
2370 | #if !GTEST_DONT_DEFINE_TEST | |
2367 | 2371 | #define TEST_F(test_fixture, test_name)\ |
2368 | 2372 | GTEST_TEST_(test_fixture, test_name, test_fixture, \ |
2369 | 2373 | ::testing::internal::GetTypeId<test_fixture>()) |
2374 | #endif // !GTEST_DONT_DEFINE_TEST | |
2370 | 2375 | |
2371 | 2376 | // Returns a path to temporary directory. |
2372 | 2377 | // Tries to determine an appropriate directory for the platform. |
52 | 52 | #include <ctype.h> |
53 | 53 | #include <float.h> |
54 | 54 | #include <string.h> |
55 | #include <cstdint> | |
55 | 56 | #include <iomanip> |
56 | 57 | #include <limits> |
57 | 58 | #include <map> |
77 | 78 | #define GTEST_CONCAT_TOKEN_IMPL_(foo, bar) foo ## bar |
78 | 79 | |
79 | 80 | // Stringifies its argument. |
80 | #define GTEST_STRINGIFY_(name) #name | |
81 | // Work around a bug in visual studio which doesn't accept code like this: | |
82 | // | |
83 | // #define GTEST_STRINGIFY_(name) #name | |
84 | // #define MACRO(a, b, c) ... GTEST_STRINGIFY_(a) ... | |
85 | // MACRO(, x, y) | |
86 | // | |
87 | // Complaining about the argument to GTEST_STRINGIFY_ being empty. | |
88 | // This is allowed by the spec. | |
89 | #define GTEST_STRINGIFY_HELPER_(name, ...) #name | |
90 | #define GTEST_STRINGIFY_(...) GTEST_STRINGIFY_HELPER_(__VA_ARGS__, ) | |
81 | 91 | |
82 | 92 | namespace proto2 { class Message; } |
83 | 93 | |
606 | 616 | // Verifies that registered_tests match the test names in |
607 | 617 | // defined_test_names_; returns registered_tests if successful, or |
608 | 618 | // aborts the program otherwise. |
609 | const char* VerifyRegisteredTestNames( | |
610 | const char* file, int line, const char* registered_tests); | |
619 | const char* VerifyRegisteredTestNames(const char* test_suite_name, | |
620 | const char* file, int line, | |
621 | const char* registered_tests); | |
611 | 622 | |
612 | 623 | private: |
613 | 624 | typedef ::std::map<std::string, CodeLocation> RegisteredTestsMap; |
661 | 672 | }; |
662 | 673 | |
663 | 674 | template <typename NameGenerator> |
664 | void GenerateNamesRecursively(Types0, std::vector<std::string>*, int) {} | |
675 | void GenerateNamesRecursively(internal::None, std::vector<std::string>*, int) {} | |
665 | 676 | |
666 | 677 | template <typename NameGenerator, typename Types> |
667 | 678 | void GenerateNamesRecursively(Types, std::vector<std::string>* result, int i) { |
728 | 739 | |
729 | 740 | // The base case for the compile time recursion. |
730 | 741 | template <GTEST_TEMPLATE_ Fixture, class TestSel> |
731 | class TypeParameterizedTest<Fixture, TestSel, Types0> { | |
742 | class TypeParameterizedTest<Fixture, TestSel, internal::None> { | |
732 | 743 | public: |
733 | 744 | static bool Register(const char* /*prefix*/, const CodeLocation&, |
734 | 745 | const char* /*case_name*/, const char* /*test_names*/, |
738 | 749 | return true; |
739 | 750 | } |
740 | 751 | }; |
752 | ||
753 | GTEST_API_ void RegisterTypeParameterizedTestSuite(const char* test_suite_name, | |
754 | CodeLocation code_location); | |
755 | GTEST_API_ void RegisterTypeParameterizedTestSuiteInstantiation( | |
756 | const char* case_name); | |
741 | 757 | |
742 | 758 | // TypeParameterizedTestSuite<Fixture, Tests, Types>::Register() |
743 | 759 | // registers *all combinations* of 'Tests' and 'Types' with Google |
751 | 767 | const char* test_names, |
752 | 768 | const std::vector<std::string>& type_names = |
753 | 769 | GenerateNames<DefaultNameGenerator, Types>()) { |
770 | RegisterTypeParameterizedTestSuiteInstantiation(case_name); | |
754 | 771 | std::string test_name = StripTrailingSpaces( |
755 | 772 | GetPrefixUntilComma(test_names)); |
756 | 773 | if (!state->TestExists(test_name)) { |
780 | 797 | |
781 | 798 | // The base case for the compile time recursion. |
782 | 799 | template <GTEST_TEMPLATE_ Fixture, typename Types> |
783 | class TypeParameterizedTestSuite<Fixture, Templates0, Types> { | |
800 | class TypeParameterizedTestSuite<Fixture, internal::None, Types> { | |
784 | 801 | public: |
785 | 802 | static bool Register(const char* /*prefix*/, const CodeLocation&, |
786 | 803 | const TypedTestSuitePState* /*state*/, |
824 | 841 | const char* value; |
825 | 842 | }; |
826 | 843 | |
844 | // Helper for declaring std::string within 'if' statement | |
845 | // in pre C++17 build environment. | |
846 | struct TrueWithString { | |
847 | TrueWithString() = default; | |
848 | explicit TrueWithString(const char* str) : value(str) {} | |
849 | explicit TrueWithString(const std::string& str) : value(str) {} | |
850 | explicit operator bool() const { return true; } | |
851 | std::string value; | |
852 | }; | |
853 | ||
827 | 854 | // A simple Linear Congruential Generator for generating random |
828 | 855 | // numbers with a uniform distribution. Unlike rand() and srand(), it |
829 | 856 | // doesn't use global state (and therefore can't interfere with user |
831 | 858 | // but it's good enough for our purposes. |
832 | 859 | class GTEST_API_ Random { |
833 | 860 | public: |
834 | static const UInt32 kMaxRange = 1u << 31; | |
835 | ||
836 | explicit Random(UInt32 seed) : state_(seed) {} | |
837 | ||
838 | void Reseed(UInt32 seed) { state_ = seed; } | |
861 | static const uint32_t kMaxRange = 1u << 31; | |
862 | ||
863 | explicit Random(uint32_t seed) : state_(seed) {} | |
864 | ||
865 | void Reseed(uint32_t seed) { state_ = seed; } | |
839 | 866 | |
840 | 867 | // Generates a random number from [0, range). Crashes if 'range' is |
841 | 868 | // 0 or greater than kMaxRange. |
842 | UInt32 Generate(UInt32 range); | |
869 | uint32_t Generate(uint32_t range); | |
843 | 870 | |
844 | 871 | private: |
845 | UInt32 state_; | |
872 | uint32_t state_; | |
846 | 873 | GTEST_DISALLOW_COPY_AND_ASSIGN_(Random); |
847 | 874 | }; |
848 | 875 | |
854 | 881 | // true if and only if T is type proto2::Message or a subclass of it. |
855 | 882 | template <typename T> |
856 | 883 | struct IsAProtocolMessage |
857 | : public bool_constant< | |
858 | std::is_convertible<const T*, const ::proto2::Message*>::value> {}; | |
884 | : public std::is_convertible<const T*, const ::proto2::Message*> {}; | |
859 | 885 | |
860 | 886 | // When the compiler sees expression IsContainerTest<C>(0), if C is an |
861 | 887 | // STL-style container class, the first overload of IsContainerTest |
1123 | 1149 | template <> |
1124 | 1150 | struct MakeIndexSequence<0> : IndexSequence<> {}; |
1125 | 1151 | |
1126 | // FIXME: This implementation of ElemFromList is O(1) in instantiation depth, | |
1127 | // but it is O(N^2) in total instantiations. Not sure if this is the best | |
1128 | // tradeoff, as it will make it somewhat slow to compile. | |
1129 | template <typename T, size_t, size_t> | |
1130 | struct ElemFromListImpl {}; | |
1131 | ||
1132 | template <typename T, size_t I> | |
1133 | struct ElemFromListImpl<T, I, I> { | |
1134 | using type = T; | |
1135 | }; | |
1136 | ||
1137 | // Get the Nth element from T... | |
1138 | // It uses O(1) instantiation depth. | |
1139 | template <size_t N, typename I, typename... T> | |
1140 | struct ElemFromList; | |
1141 | ||
1142 | template <size_t N, size_t... I, typename... T> | |
1143 | struct ElemFromList<N, IndexSequence<I...>, T...> | |
1144 | : ElemFromListImpl<T, N, I>... {}; | |
1152 | template <size_t> | |
1153 | struct Ignore { | |
1154 | Ignore(...); // NOLINT | |
1155 | }; | |
1156 | ||
1157 | template <typename> | |
1158 | struct ElemFromListImpl; | |
1159 | template <size_t... I> | |
1160 | struct ElemFromListImpl<IndexSequence<I...>> { | |
1161 | // We make Ignore a template to solve a problem with MSVC. | |
1162 | // A non-template Ignore would work fine with `decltype(Ignore(I))...`, but | |
1163 | // MSVC doesn't understand how to deal with that pack expansion. | |
1164 | // Use `0 * I` to have a single instantiation of Ignore. | |
1165 | template <typename R> | |
1166 | static R Apply(Ignore<0 * I>..., R (*)(), ...); | |
1167 | }; | |
1168 | ||
1169 | template <size_t N, typename... T> | |
1170 | struct ElemFromList { | |
1171 | using type = | |
1172 | decltype(ElemFromListImpl<typename MakeIndexSequence<N>::type>::Apply( | |
1173 | static_cast<T (*)()>(nullptr)...)); | |
1174 | }; | |
1145 | 1175 | |
1146 | 1176 | template <typename... T> |
1147 | 1177 | class FlatTuple; |
1151 | 1181 | |
1152 | 1182 | template <typename... T, size_t I> |
1153 | 1183 | struct FlatTupleElemBase<FlatTuple<T...>, I> { |
1154 | using value_type = | |
1155 | typename ElemFromList<I, typename MakeIndexSequence<sizeof...(T)>::type, | |
1156 | T...>::type; | |
1184 | using value_type = typename ElemFromList<I, T...>::type; | |
1157 | 1185 | FlatTupleElemBase() = default; |
1158 | 1186 | explicit FlatTupleElemBase(value_type t) : value(std::move(t)) {} |
1159 | 1187 | value_type value; |
1173 | 1201 | |
1174 | 1202 | // Analog to std::tuple but with different tradeoffs. |
1175 | 1203 | // This class minimizes the template instantiation depth, thus allowing more |
1176 | // elements that std::tuple would. std::tuple has been seen to require an | |
1204 | // elements than std::tuple would. std::tuple has been seen to require an | |
1177 | 1205 | // instantiation depth of more than 10x the number of elements in some |
1178 | 1206 | // implementations. |
1179 | 1207 | // FlatTuple and ElemFromList are not recursive and have a fixed depth |
1184 | 1212 | class FlatTuple |
1185 | 1213 | : private FlatTupleBase<FlatTuple<T...>, |
1186 | 1214 | typename MakeIndexSequence<sizeof...(T)>::type> { |
1187 | using Indices = typename FlatTuple::FlatTupleBase::Indices; | |
1215 | using Indices = typename FlatTupleBase< | |
1216 | FlatTuple<T...>, typename MakeIndexSequence<sizeof...(T)>::type>::Indices; | |
1188 | 1217 | |
1189 | 1218 | public: |
1190 | 1219 | FlatTuple() = default; |
1191 | 1220 | explicit FlatTuple(T... t) : FlatTuple::FlatTupleBase(std::move(t)...) {} |
1192 | 1221 | |
1193 | 1222 | template <size_t I> |
1194 | const typename ElemFromList<I, Indices, T...>::type& Get() const { | |
1223 | const typename ElemFromList<I, T...>::type& Get() const { | |
1195 | 1224 | return static_cast<const FlatTupleElemBase<FlatTuple, I>*>(this)->value; |
1196 | 1225 | } |
1197 | 1226 | |
1198 | 1227 | template <size_t I> |
1199 | typename ElemFromList<I, Indices, T...>::type& Get() { | |
1228 | typename ElemFromList<I, T...>::type& Get() { | |
1200 | 1229 | return static_cast<FlatTupleElemBase<FlatTuple, I>*>(this)->value; |
1201 | 1230 | } |
1202 | 1231 | }; |
1282 | 1311 | GTEST_CONCAT_TOKEN_(gtest_label_testthrow_, __LINE__): \ |
1283 | 1312 | fail(gtest_msg.value) |
1284 | 1313 | |
1314 | #if GTEST_HAS_EXCEPTIONS | |
1315 | ||
1316 | #define GTEST_TEST_NO_THROW_CATCH_STD_EXCEPTION_() \ | |
1317 | catch (std::exception const& e) { \ | |
1318 | gtest_msg.value = ( \ | |
1319 | "it throws std::exception-derived exception with description: \"" \ | |
1320 | ); \ | |
1321 | gtest_msg.value += e.what(); \ | |
1322 | gtest_msg.value += "\"."; \ | |
1323 | goto GTEST_CONCAT_TOKEN_(gtest_label_testnothrow_, __LINE__); \ | |
1324 | } | |
1325 | ||
1326 | #else // GTEST_HAS_EXCEPTIONS | |
1327 | ||
1328 | #define GTEST_TEST_NO_THROW_CATCH_STD_EXCEPTION_() | |
1329 | ||
1330 | #endif // GTEST_HAS_EXCEPTIONS | |
1331 | ||
1285 | 1332 | #define GTEST_TEST_NO_THROW_(statement, fail) \ |
1286 | 1333 | GTEST_AMBIGUOUS_ELSE_BLOCKER_ \ |
1287 | if (::testing::internal::AlwaysTrue()) { \ | |
1334 | if (::testing::internal::TrueWithString gtest_msg{}) { \ | |
1288 | 1335 | try { \ |
1289 | 1336 | GTEST_SUPPRESS_UNREACHABLE_CODE_WARNING_BELOW_(statement); \ |
1290 | 1337 | } \ |
1338 | GTEST_TEST_NO_THROW_CATCH_STD_EXCEPTION_() \ | |
1291 | 1339 | catch (...) { \ |
1340 | gtest_msg.value = "it throws."; \ | |
1292 | 1341 | goto GTEST_CONCAT_TOKEN_(gtest_label_testnothrow_, __LINE__); \ |
1293 | 1342 | } \ |
1294 | 1343 | } else \ |
1295 | 1344 | GTEST_CONCAT_TOKEN_(gtest_label_testnothrow_, __LINE__): \ |
1296 | fail("Expected: " #statement " doesn't throw an exception.\n" \ | |
1297 | " Actual: it throws.") | |
1345 | fail(("Expected: " #statement " doesn't throw an exception.\n" \ | |
1346 | " Actual: " + gtest_msg.value).c_str()) | |
1298 | 1347 | |
1299 | 1348 | #define GTEST_TEST_ANY_THROW_(statement, fail) \ |
1300 | 1349 | GTEST_AMBIGUOUS_ELSE_BLOCKER_ \ |
1355 | 1404 | : public parent_class { \ |
1356 | 1405 | public: \ |
1357 | 1406 | GTEST_TEST_CLASS_NAME_(test_suite_name, test_name)() {} \ |
1407 | ~GTEST_TEST_CLASS_NAME_(test_suite_name, test_name)() override = default; \ | |
1408 | GTEST_DISALLOW_COPY_AND_ASSIGN_(GTEST_TEST_CLASS_NAME_(test_suite_name, \ | |
1409 | test_name)); \ | |
1410 | GTEST_DISALLOW_MOVE_AND_ASSIGN_(GTEST_TEST_CLASS_NAME_(test_suite_name, \ | |
1411 | test_name)); \ | |
1358 | 1412 | \ |
1359 | 1413 | private: \ |
1360 | virtual void TestBody(); \ | |
1414 | void TestBody() override; \ | |
1361 | 1415 | static ::testing::TestInfo* const test_info_ GTEST_ATTRIBUTE_UNUSED_; \ |
1362 | GTEST_DISALLOW_COPY_AND_ASSIGN_(GTEST_TEST_CLASS_NAME_(test_suite_name, \ | |
1363 | test_name)); \ | |
1364 | 1416 | }; \ |
1365 | 1417 | \ |
1366 | 1418 | ::testing::TestInfo* const GTEST_TEST_CLASS_NAME_(test_suite_name, \ |
41 | 41 | #include <memory> |
42 | 42 | #include <set> |
43 | 43 | #include <tuple> |
44 | #include <type_traits> | |
44 | 45 | #include <utility> |
45 | 46 | #include <vector> |
46 | 47 | |
47 | 48 | #include "gtest/internal/gtest-internal.h" |
48 | 49 | #include "gtest/internal/gtest-port.h" |
49 | 50 | #include "gtest/gtest-printers.h" |
51 | #include "gtest/gtest-test-part.h" | |
50 | 52 | |
51 | 53 | namespace testing { |
52 | 54 | // Input to a parameterized test name generator, describing a test parameter. |
473 | 475 | |
474 | 476 | // INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE. |
475 | 477 | // |
478 | // Report a the name of a test_suit as safe to ignore | |
479 | // as the side effect of construction of this type. | |
480 | struct MarkAsIgnored { | |
481 | explicit MarkAsIgnored(const char* test_suite); | |
482 | }; | |
483 | ||
484 | GTEST_API_ void InsertSyntheticTestCase(const std::string& name, | |
485 | CodeLocation location, bool has_test_p); | |
486 | ||
487 | // INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE. | |
488 | // | |
476 | 489 | // ParameterizedTestSuiteInfo accumulates tests obtained from TEST_P |
477 | 490 | // macro invocations for a particular test suite and generators |
478 | 491 | // obtained from INSTANTIATE_TEST_SUITE_P macro invocations for that |
521 | 534 | return 0; // Return value used only to run this method in namespace scope. |
522 | 535 | } |
523 | 536 | // UnitTest class invokes this method to register tests in this test suite |
524 | // test suites right before running tests in RUN_ALL_TESTS macro. | |
537 | // right before running tests in RUN_ALL_TESTS macro. | |
525 | 538 | // This method should not be called more than once on any single |
526 | 539 | // instance of a ParameterizedTestSuiteInfoBase derived class. |
527 | 540 | // UnitTest has a guard to prevent from calling this method more than once. |
528 | 541 | void RegisterTests() override { |
542 | bool generated_instantiations = false; | |
543 | ||
529 | 544 | for (typename TestInfoContainer::iterator test_it = tests_.begin(); |
530 | 545 | test_it != tests_.end(); ++test_it) { |
531 | 546 | std::shared_ptr<TestInfo> test_info = *test_it; |
548 | 563 | for (typename ParamGenerator<ParamType>::iterator param_it = |
549 | 564 | generator.begin(); |
550 | 565 | param_it != generator.end(); ++param_it, ++i) { |
566 | generated_instantiations = true; | |
567 | ||
551 | 568 | Message test_name_stream; |
552 | 569 | |
553 | 570 | std::string param_name = name_func( |
579 | 596 | } // for param_it |
580 | 597 | } // for gen_it |
581 | 598 | } // for test_it |
599 | ||
600 | if (!generated_instantiations) { | |
601 | // There are no generaotrs, or they all generate nothing ... | |
602 | InsertSyntheticTestCase(GetTestSuiteName(), code_location_, | |
603 | !tests_.empty()); | |
604 | } | |
582 | 605 | } // RegisterTests |
583 | 606 | |
584 | 607 | private: |
716 | 739 | GTEST_DISALLOW_COPY_AND_ASSIGN_(ParameterizedTestSuiteRegistry); |
717 | 740 | }; |
718 | 741 | |
742 | // Keep track of what type-parameterized test suite are defined and | |
743 | // where as well as which are intatiated. This allows susequently | |
744 | // identifying suits that are defined but never used. | |
745 | class TypeParameterizedTestSuiteRegistry { | |
746 | public: | |
747 | // Add a suite definition | |
748 | void RegisterTestSuite(const char* test_suite_name, | |
749 | CodeLocation code_location); | |
750 | ||
751 | // Add an instantiation of a suit. | |
752 | void RegisterInstantiation(const char* test_suite_name); | |
753 | ||
754 | // For each suit repored as defined but not reported as instantiation, | |
755 | // emit a test that reports that fact (configurably, as an error). | |
756 | void CheckForInstantiations(); | |
757 | ||
758 | private: | |
759 | struct TypeParameterizedTestSuiteInfo { | |
760 | explicit TypeParameterizedTestSuiteInfo(CodeLocation c) | |
761 | : code_location(c), instantiated(false) {} | |
762 | ||
763 | CodeLocation code_location; | |
764 | bool instantiated; | |
765 | }; | |
766 | ||
767 | std::map<std::string, TypeParameterizedTestSuiteInfo> suites_; | |
768 | }; | |
769 | ||
719 | 770 | } // namespace internal |
720 | 771 | |
721 | 772 | // Forward declarations of ValuesIn(), which is implemented in |
101 | 101 | # define GTEST_OS_QNX 1 |
102 | 102 | #elif defined(__HAIKU__) |
103 | 103 | #define GTEST_OS_HAIKU 1 |
104 | #elif defined ESP8266 | |
105 | #define GTEST_OS_ESP8266 1 | |
106 | #elif defined ESP32 | |
107 | #define GTEST_OS_ESP32 1 | |
104 | 108 | #endif // __CYGWIN__ |
105 | 109 | |
106 | 110 | #endif // GTEST_INCLUDE_GTEST_INTERNAL_GTEST_PORT_ARCH_H_ |
189 | 189 | // GTEST_AMBIGUOUS_ELSE_BLOCKER_ - for disabling a gcc warning. |
190 | 190 | // GTEST_ATTRIBUTE_UNUSED_ - declares that a class' instances or a |
191 | 191 | // variable don't have to be used. |
192 | // GTEST_DISALLOW_ASSIGN_ - disables operator=. | |
192 | // GTEST_DISALLOW_ASSIGN_ - disables copy operator=. | |
193 | 193 | // GTEST_DISALLOW_COPY_AND_ASSIGN_ - disables copy ctor and operator=. |
194 | // GTEST_DISALLOW_MOVE_ASSIGN_ - disables move operator=. | |
195 | // GTEST_DISALLOW_MOVE_AND_ASSIGN_ - disables move ctor and operator=. | |
194 | 196 | // GTEST_MUST_USE_RESULT_ - declares that a function's result must be used. |
195 | 197 | // GTEST_INTENTIONAL_CONST_COND_PUSH_ - start code section where MSVC C4127 is |
196 | 198 | // suppressed (constant conditional). |
197 | 199 | // GTEST_INTENTIONAL_CONST_COND_POP_ - finish code section where MSVC C4127 |
198 | 200 | // is suppressed. |
201 | // GTEST_INTERNAL_HAS_STRING_VIEW - for enabling Matcher<std::string_view> or | |
202 | // Matcher<absl::string_view> | |
203 | // specializations. | |
199 | 204 | // |
200 | 205 | // Synchronization: |
201 | 206 | // Mutex, MutexLock, ThreadLocal, GetThreadCount() |
222 | 227 | // |
223 | 228 | // Integer types: |
224 | 229 | // TypeWithSize - maps an integer to a int type. |
225 | // Int32, UInt32, Int64, UInt64, TimeInMillis | |
226 | // - integers of known sizes. | |
230 | // TimeInMillis - integers of known sizes. | |
227 | 231 | // BiggestInt - the biggest signed integer type. |
228 | 232 | // |
229 | 233 | // Command-line utilities: |
234 | 238 | // Environment variable utilities: |
235 | 239 | // GetEnv() - gets the value of an environment variable. |
236 | 240 | // BoolFromGTestEnv() - parses a bool environment variable. |
237 | // Int32FromGTestEnv() - parses an Int32 environment variable. | |
241 | // Int32FromGTestEnv() - parses an int32_t environment variable. | |
238 | 242 | // StringFromGTestEnv() - parses a string environment variable. |
239 | 243 | // |
240 | 244 | // Deprecation warnings: |
247 | 251 | #include <stdio.h> |
248 | 252 | #include <stdlib.h> |
249 | 253 | #include <string.h> |
250 | #include <memory> | |
254 | #include <cstdint> | |
255 | #include <limits> | |
251 | 256 | #include <type_traits> |
252 | 257 | |
253 | 258 | #ifndef _WIN32_WCE |
260 | 265 | # include <TargetConditionals.h> |
261 | 266 | #endif |
262 | 267 | |
263 | #include <algorithm> // NOLINT | |
264 | #include <iostream> // NOLINT | |
265 | #include <sstream> // NOLINT | |
266 | #include <string> // NOLINT | |
268 | #include <iostream> // NOLINT | |
269 | #include <memory> | |
270 | #include <string> // NOLINT | |
267 | 271 | #include <tuple> |
268 | #include <utility> | |
269 | 272 | #include <vector> // NOLINT |
270 | 273 | |
274 | #include "gtest/internal/custom/gtest-port.h" | |
271 | 275 | #include "gtest/internal/gtest-port-arch.h" |
272 | #include "gtest/internal/custom/gtest-port.h" | |
273 | 276 | |
274 | 277 | #if !defined(GTEST_DEV_EMAIL_) |
275 | 278 | # define GTEST_DEV_EMAIL_ "googletestframework@@googlegroups.com" |
440 | 443 | # endif // defined(_MSC_VER) || defined(__BORLANDC__) |
441 | 444 | #endif // GTEST_HAS_EXCEPTIONS |
442 | 445 | |
443 | #if !defined(GTEST_HAS_STD_STRING) | |
444 | // Even though we don't use this macro any longer, we keep it in case | |
445 | // some clients still depend on it. | |
446 | # define GTEST_HAS_STD_STRING 1 | |
447 | #elif !GTEST_HAS_STD_STRING | |
448 | // The user told us that ::std::string isn't available. | |
449 | # error "::std::string isn't available." | |
450 | #endif // !defined(GTEST_HAS_STD_STRING) | |
451 | ||
452 | 446 | #ifndef GTEST_HAS_STD_WSTRING |
453 | 447 | // The user didn't tell us whether ::std::wstring is available, so we need |
454 | 448 | // to figure it out. |
457 | 451 | // no support for it at least as recent as Froyo (2.2). |
458 | 452 | #define GTEST_HAS_STD_WSTRING \ |
459 | 453 | (!(GTEST_OS_LINUX_ANDROID || GTEST_OS_CYGWIN || GTEST_OS_SOLARIS || \ |
460 | GTEST_OS_HAIKU)) | |
454 | GTEST_OS_HAIKU || GTEST_OS_ESP32 || GTEST_OS_ESP8266)) | |
461 | 455 | |
462 | 456 | #endif // GTEST_HAS_STD_WSTRING |
463 | 457 | |
581 | 575 | #ifndef GTEST_HAS_STREAM_REDIRECTION |
582 | 576 | // By default, we assume that stream redirection is supported on all |
583 | 577 | // platforms except known mobile ones. |
584 | # if GTEST_OS_WINDOWS_MOBILE || GTEST_OS_WINDOWS_PHONE || GTEST_OS_WINDOWS_RT | |
578 | #if GTEST_OS_WINDOWS_MOBILE || GTEST_OS_WINDOWS_PHONE || \ | |
579 | GTEST_OS_WINDOWS_RT || GTEST_OS_ESP8266 | |
585 | 580 | # define GTEST_HAS_STREAM_REDIRECTION 0 |
586 | 581 | # else |
587 | 582 | # define GTEST_HAS_STREAM_REDIRECTION 1 |
675 | 670 | #endif |
676 | 671 | |
677 | 672 | |
678 | // A macro to disallow operator= | |
673 | // A macro to disallow copy operator= | |
679 | 674 | // This should be used in the private: declarations for a class. |
680 | 675 | #define GTEST_DISALLOW_ASSIGN_(type) \ |
681 | void operator=(type const &) = delete | |
676 | type& operator=(type const &) = delete | |
682 | 677 | |
683 | 678 | // A macro to disallow copy constructor and operator= |
684 | 679 | // This should be used in the private: declarations for a class. |
685 | 680 | #define GTEST_DISALLOW_COPY_AND_ASSIGN_(type) \ |
686 | 681 | type(type const &) = delete; \ |
687 | 682 | GTEST_DISALLOW_ASSIGN_(type) |
683 | ||
684 | // A macro to disallow move operator= | |
685 | // This should be used in the private: declarations for a class. | |
686 | #define GTEST_DISALLOW_MOVE_ASSIGN_(type) \ | |
687 | type& operator=(type &&) noexcept = delete | |
688 | ||
689 | // A macro to disallow move constructor and operator= | |
690 | // This should be used in the private: declarations for a class. | |
691 | #define GTEST_DISALLOW_MOVE_AND_ASSIGN_(type) \ | |
692 | type(type &&) noexcept = delete; \ | |
693 | GTEST_DISALLOW_MOVE_ASSIGN_(type) | |
688 | 694 | |
689 | 695 | // Tell the compiler to warn about unused return values for functions declared |
690 | 696 | // with this macro. The macro should be used on function declarations |
854 | 860 | // The second argument to the macro must be a valid C++ identifier. If the |
855 | 861 | // expression is false, compiler will issue an error containing this identifier. |
856 | 862 | #define GTEST_COMPILE_ASSERT_(expr, msg) static_assert(expr, #msg) |
857 | ||
858 | // Evaluates to the number of elements in 'array'. | |
859 | #define GTEST_ARRAY_SIZE_(array) (sizeof(array) / sizeof(array[0])) | |
860 | 863 | |
861 | 864 | // A helper for suppressing warnings on constant condition. It just |
862 | 865 | // returns 'condition'. |
1598 | 1601 | class DefaultValueHolderFactory : public ValueHolderFactory { |
1599 | 1602 | public: |
1600 | 1603 | DefaultValueHolderFactory() {} |
1601 | virtual ValueHolder* MakeNewHolder() const { return new ValueHolder(); } | |
1604 | ValueHolder* MakeNewHolder() const override { return new ValueHolder(); } | |
1602 | 1605 | |
1603 | 1606 | private: |
1604 | 1607 | GTEST_DISALLOW_COPY_AND_ASSIGN_(DefaultValueHolderFactory); |
1607 | 1610 | class InstanceValueHolderFactory : public ValueHolderFactory { |
1608 | 1611 | public: |
1609 | 1612 | explicit InstanceValueHolderFactory(const T& value) : value_(value) {} |
1610 | virtual ValueHolder* MakeNewHolder() const { | |
1613 | ValueHolder* MakeNewHolder() const override { | |
1611 | 1614 | return new ValueHolder(value_); |
1612 | 1615 | } |
1613 | 1616 | |
1807 | 1810 | class DefaultValueHolderFactory : public ValueHolderFactory { |
1808 | 1811 | public: |
1809 | 1812 | DefaultValueHolderFactory() {} |
1810 | virtual ValueHolder* MakeNewHolder() const { return new ValueHolder(); } | |
1813 | ValueHolder* MakeNewHolder() const override { return new ValueHolder(); } | |
1811 | 1814 | |
1812 | 1815 | private: |
1813 | 1816 | GTEST_DISALLOW_COPY_AND_ASSIGN_(DefaultValueHolderFactory); |
1816 | 1819 | class InstanceValueHolderFactory : public ValueHolderFactory { |
1817 | 1820 | public: |
1818 | 1821 | explicit InstanceValueHolderFactory(const T& value) : value_(value) {} |
1819 | virtual ValueHolder* MakeNewHolder() const { | |
1822 | ValueHolder* MakeNewHolder() const override { | |
1820 | 1823 | return new ValueHolder(value_); |
1821 | 1824 | } |
1822 | 1825 | |
1886 | 1889 | // we cannot detect it. |
1887 | 1890 | GTEST_API_ size_t GetThreadCount(); |
1888 | 1891 | |
1889 | template <bool B> | |
1890 | using bool_constant = std::integral_constant<bool, B>; | |
1891 | ||
1892 | 1892 | #if GTEST_OS_WINDOWS |
1893 | 1893 | # define GTEST_PATH_SEP_ "\\" |
1894 | 1894 | # define GTEST_HAS_ALT_PATH_SEP_ 1 |
1895 | // The biggest signed integer type the compiler supports. | |
1896 | typedef __int64 BiggestInt; | |
1897 | 1895 | #else |
1898 | 1896 | # define GTEST_PATH_SEP_ "/" |
1899 | 1897 | # define GTEST_HAS_ALT_PATH_SEP_ 0 |
1900 | typedef long long BiggestInt; // NOLINT | |
1901 | 1898 | #endif // GTEST_OS_WINDOWS |
1902 | 1899 | |
1903 | 1900 | // Utilities for char. |
1992 | 1989 | } |
1993 | 1990 | # endif // GTEST_OS_WINDOWS_MOBILE |
1994 | 1991 | |
1992 | #elif GTEST_OS_ESP8266 | |
1993 | typedef struct stat StatStruct; | |
1994 | ||
1995 | inline int FileNo(FILE* file) { return fileno(file); } | |
1996 | inline int IsATTY(int fd) { return isatty(fd); } | |
1997 | inline int Stat(const char* path, StatStruct* buf) { | |
1998 | // stat function not implemented on ESP8266 | |
1999 | return 0; | |
2000 | } | |
2001 | inline int StrCaseCmp(const char* s1, const char* s2) { | |
2002 | return strcasecmp(s1, s2); | |
2003 | } | |
2004 | inline char* StrDup(const char* src) { return strdup(src); } | |
2005 | inline int RmDir(const char* dir) { return rmdir(dir); } | |
2006 | inline bool IsDir(const StatStruct& st) { return S_ISDIR(st.st_mode); } | |
2007 | ||
1995 | 2008 | #else |
1996 | 2009 | |
1997 | 2010 | typedef struct stat StatStruct; |
2012 | 2025 | |
2013 | 2026 | GTEST_DISABLE_MSC_DEPRECATED_PUSH_() |
2014 | 2027 | |
2015 | inline const char* StrNCpy(char* dest, const char* src, size_t n) { | |
2016 | return strncpy(dest, src, n); | |
2017 | } | |
2018 | ||
2019 | 2028 | // ChDir(), FReopen(), FDOpen(), Read(), Write(), Close(), and |
2020 | 2029 | // StrError() aren't needed on Windows CE at this time and thus not |
2021 | 2030 | // defined there. |
2044 | 2053 | inline const char* StrError(int errnum) { return strerror(errnum); } |
2045 | 2054 | #endif |
2046 | 2055 | inline const char* GetEnv(const char* name) { |
2047 | #if GTEST_OS_WINDOWS_MOBILE || GTEST_OS_WINDOWS_PHONE || GTEST_OS_WINDOWS_RT | |
2048 | // We are on Windows CE, which has no environment variables. | |
2056 | #if GTEST_OS_WINDOWS_MOBILE || GTEST_OS_WINDOWS_PHONE || \ | |
2057 | GTEST_OS_WINDOWS_RT || GTEST_OS_ESP8266 | |
2058 | // We are on an embedded platform, which has no environment variables. | |
2049 | 2059 | static_cast<void>(name); // To prevent 'unused argument' warning. |
2050 | 2060 | return nullptr; |
2051 | 2061 | #elif defined(__BORLANDC__) || defined(__SunOS_5_8) || defined(__SunOS_5_9) |
2087 | 2097 | # define GTEST_SNPRINTF_ snprintf |
2088 | 2098 | #endif |
2089 | 2099 | |
2090 | // The maximum number a BiggestInt can represent. This definition | |
2091 | // works no matter BiggestInt is represented in one's complement or | |
2092 | // two's complement. | |
2093 | // | |
2094 | // We cannot rely on numeric_limits in STL, as __int64 and long long | |
2095 | // are not part of standard C++ and numeric_limits doesn't need to be | |
2096 | // defined for them. | |
2097 | const BiggestInt kMaxBiggestInt = | |
2098 | ~(static_cast<BiggestInt>(1) << (8*sizeof(BiggestInt) - 1)); | |
2100 | // The biggest signed integer type the compiler supports. | |
2101 | // | |
2102 | // long long is guaranteed to be at least 64-bits in C++11. | |
2103 | using BiggestInt = long long; // NOLINT | |
2104 | ||
2105 | // The maximum number a BiggestInt can represent. | |
2106 | constexpr BiggestInt kMaxBiggestInt = (std::numeric_limits<BiggestInt>::max)(); | |
2099 | 2107 | |
2100 | 2108 | // This template class serves as a compile-time function from size to |
2101 | 2109 | // type. It maps a size in bytes to a primitive type with that |
2120 | 2128 | public: |
2121 | 2129 | // This prevents the user from using TypeWithSize<N> with incorrect |
2122 | 2130 | // values of N. |
2123 | typedef void UInt; | |
2131 | using UInt = void; | |
2124 | 2132 | }; |
2125 | 2133 | |
2126 | 2134 | // The specialization for size 4. |
2127 | 2135 | template <> |
2128 | 2136 | class TypeWithSize<4> { |
2129 | 2137 | public: |
2130 | // unsigned int has size 4 in both gcc and MSVC. | |
2131 | // | |
2132 | // As base/basictypes.h doesn't compile on Windows, we cannot use | |
2133 | // uint32, uint64, and etc here. | |
2134 | typedef int Int; | |
2135 | typedef unsigned int UInt; | |
2138 | using Int = std::int32_t; | |
2139 | using UInt = std::uint32_t; | |
2136 | 2140 | }; |
2137 | 2141 | |
2138 | 2142 | // The specialization for size 8. |
2139 | 2143 | template <> |
2140 | 2144 | class TypeWithSize<8> { |
2141 | 2145 | public: |
2142 | #if GTEST_OS_WINDOWS | |
2143 | typedef __int64 Int; | |
2144 | typedef unsigned __int64 UInt; | |
2145 | #else | |
2146 | typedef long long Int; // NOLINT | |
2147 | typedef unsigned long long UInt; // NOLINT | |
2148 | #endif // GTEST_OS_WINDOWS | |
2146 | using Int = std::int64_t; | |
2147 | using UInt = std::uint64_t; | |
2149 | 2148 | }; |
2150 | 2149 | |
2151 | 2150 | // Integer types of known sizes. |
2152 | typedef TypeWithSize<4>::Int Int32; | |
2153 | typedef TypeWithSize<4>::UInt UInt32; | |
2154 | typedef TypeWithSize<8>::Int Int64; | |
2155 | typedef TypeWithSize<8>::UInt UInt64; | |
2156 | typedef TypeWithSize<8>::Int TimeInMillis; // Represents time in milliseconds. | |
2151 | using TimeInMillis = int64_t; // Represents time in milliseconds. | |
2157 | 2152 | |
2158 | 2153 | // Utilities for command line flags and environment variables. |
2159 | 2154 | |
2172 | 2167 | // Macros for declaring flags. |
2173 | 2168 | # define GTEST_DECLARE_bool_(name) GTEST_API_ extern bool GTEST_FLAG(name) |
2174 | 2169 | # define GTEST_DECLARE_int32_(name) \ |
2175 | GTEST_API_ extern ::testing::internal::Int32 GTEST_FLAG(name) | |
2170 | GTEST_API_ extern std::int32_t GTEST_FLAG(name) | |
2176 | 2171 | # define GTEST_DECLARE_string_(name) \ |
2177 | 2172 | GTEST_API_ extern ::std::string GTEST_FLAG(name) |
2178 | 2173 | |
2180 | 2175 | # define GTEST_DEFINE_bool_(name, default_val, doc) \ |
2181 | 2176 | GTEST_API_ bool GTEST_FLAG(name) = (default_val) |
2182 | 2177 | # define GTEST_DEFINE_int32_(name, default_val, doc) \ |
2183 | GTEST_API_ ::testing::internal::Int32 GTEST_FLAG(name) = (default_val) | |
2178 | GTEST_API_ std::int32_t GTEST_FLAG(name) = (default_val) | |
2184 | 2179 | # define GTEST_DEFINE_string_(name, default_val, doc) \ |
2185 | 2180 | GTEST_API_ ::std::string GTEST_FLAG(name) = (default_val) |
2186 | 2181 | |
2195 | 2190 | // Parses 'str' for a 32-bit signed integer. If successful, writes the result |
2196 | 2191 | // to *value and returns true; otherwise leaves *value unchanged and returns |
2197 | 2192 | // false. |
2198 | bool ParseInt32(const Message& src_text, const char* str, Int32* value); | |
2199 | ||
2200 | // Parses a bool/Int32/string from the environment variable | |
2193 | bool ParseInt32(const Message& src_text, const char* str, int32_t* value); | |
2194 | ||
2195 | // Parses a bool/int32_t/string from the environment variable | |
2201 | 2196 | // corresponding to the given Google Test flag. |
2202 | 2197 | bool BoolFromGTestEnv(const char* flag, bool default_val); |
2203 | GTEST_API_ Int32 Int32FromGTestEnv(const char* flag, Int32 default_val); | |
2198 | GTEST_API_ int32_t Int32FromGTestEnv(const char* flag, int32_t default_val); | |
2204 | 2199 | std::string OutputFlagAlsoCheckEnvVar(); |
2205 | 2200 | const char* StringFromGTestEnv(const char* flag, const char* default_val); |
2206 | 2201 | |
2227 | 2222 | |
2228 | 2223 | #endif // !defined(GTEST_INTERNAL_DEPRECATED) |
2229 | 2224 | |
2225 | #if GTEST_HAS_ABSL | |
2226 | // Always use absl::string_view for Matcher<> specializations if googletest | |
2227 | // is built with absl support. | |
2228 | # define GTEST_INTERNAL_HAS_STRING_VIEW 1 | |
2229 | #include "absl/strings/string_view.h" | |
2230 | namespace testing { | |
2231 | namespace internal { | |
2232 | using StringView = ::absl::string_view; | |
2233 | } // namespace internal | |
2234 | } // namespace testing | |
2235 | #else | |
2236 | # ifdef __has_include | |
2237 | # if __has_include(<string_view>) && __cplusplus >= 201703L | |
2238 | // Otherwise for C++17 and higher use std::string_view for Matcher<> | |
2239 | // specializations. | |
2240 | # define GTEST_INTERNAL_HAS_STRING_VIEW 1 | |
2241 | #include <string_view> | |
2242 | namespace testing { | |
2243 | namespace internal { | |
2244 | using StringView = ::std::string_view; | |
2245 | } // namespace internal | |
2246 | } // namespace testing | |
2247 | // The case where absl is configured NOT to alias std::string_view is not | |
2248 | // supported. | |
2249 | # endif // __has_include(<string_view>) && __cplusplus >= 201703L | |
2250 | # endif // __has_include | |
2251 | #endif // GTEST_HAS_ABSL | |
2252 | ||
2230 | 2253 | #endif // GTEST_INCLUDE_GTEST_INTERNAL_GTEST_PORT_H_ |
46 | 46 | #endif |
47 | 47 | |
48 | 48 | #include <string.h> |
49 | #include <cstdint> | |
49 | 50 | #include <string> |
50 | 51 | |
51 | 52 | #include "gtest/internal/gtest-port.h" |
151 | 152 | static std::string FormatHexInt(int value); |
152 | 153 | |
153 | 154 | // Formats an int value as "%X". |
154 | static std::string FormatHexUInt32(UInt32 value); | |
155 | static std::string FormatHexUInt32(uint32_t value); | |
155 | 156 | |
156 | 157 | // Formats a byte as "%02X". |
157 | 158 | static std::string FormatByte(unsigned char value); |
0 | // This file was GENERATED by command: | |
1 | // pump.py gtest-type-util.h.pump | |
2 | // DO NOT EDIT BY HAND!!! | |
3 | ||
4 | 0 | // Copyright 2008 Google Inc. |
5 | 1 | // All Rights Reserved. |
6 | 2 | // |
31 | 27 | // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
32 | 28 | |
33 | 29 | // Type utilities needed for implementing typed and type-parameterized |
34 | // tests. This file is generated by a SCRIPT. DO NOT EDIT BY HAND! | |
35 | // | |
36 | // Currently we support at most 50 types in a list, and at most 50 | |
37 | // type-parameterized tests in one type-parameterized test suite. | |
38 | // Please contact googletestframework@googlegroups.com if you need | |
39 | // more. | |
30 | // tests. | |
40 | 31 | |
41 | 32 | // GOOGLETEST_CM0001 DO NOT DELETE |
42 | 33 | |
104 | 95 | |
105 | 96 | #if GTEST_HAS_TYPED_TEST || GTEST_HAS_TYPED_TEST_P |
106 | 97 | |
107 | // A unique type used as the default value for the arguments of class | |
108 | // template Types. This allows us to simulate variadic templates | |
109 | // (e.g. Types<int>, Type<int, double>, and etc), which C++ doesn't | |
110 | // support directly. | |
98 | // A unique type indicating an empty node | |
111 | 99 | struct None {}; |
112 | ||
113 | // The following family of struct and struct templates are used to | |
114 | // represent type lists. In particular, TypesN<T1, T2, ..., TN> | |
115 | // represents a type list with N types (T1, T2, ..., and TN) in it. | |
116 | // Except for Types0, every struct in the family has two member types: | |
117 | // Head for the first type in the list, and Tail for the rest of the | |
118 | // list. | |
119 | ||
120 | // The empty type list. | |
121 | struct Types0 {}; | |
122 | ||
123 | // Type lists of length 1, 2, 3, and so on. | |
124 | ||
125 | template <typename T1> | |
126 | struct Types1 { | |
127 | typedef T1 Head; | |
128 | typedef Types0 Tail; | |
129 | }; | |
130 | template <typename T1, typename T2> | |
131 | struct Types2 { | |
132 | typedef T1 Head; | |
133 | typedef Types1<T2> Tail; | |
134 | }; | |
135 | ||
136 | template <typename T1, typename T2, typename T3> | |
137 | struct Types3 { | |
138 | typedef T1 Head; | |
139 | typedef Types2<T2, T3> Tail; | |
140 | }; | |
141 | ||
142 | template <typename T1, typename T2, typename T3, typename T4> | |
143 | struct Types4 { | |
144 | typedef T1 Head; | |
145 | typedef Types3<T2, T3, T4> Tail; | |
146 | }; | |
147 | ||
148 | template <typename T1, typename T2, typename T3, typename T4, typename T5> | |
149 | struct Types5 { | |
150 | typedef T1 Head; | |
151 | typedef Types4<T2, T3, T4, T5> Tail; | |
152 | }; | |
153 | ||
154 | template <typename T1, typename T2, typename T3, typename T4, typename T5, | |
155 | typename T6> | |
156 | struct Types6 { | |
157 | typedef T1 Head; | |
158 | typedef Types5<T2, T3, T4, T5, T6> Tail; | |
159 | }; | |
160 | ||
161 | template <typename T1, typename T2, typename T3, typename T4, typename T5, | |
162 | typename T6, typename T7> | |
163 | struct Types7 { | |
164 | typedef T1 Head; | |
165 | typedef Types6<T2, T3, T4, T5, T6, T7> Tail; | |
166 | }; | |
167 | ||
168 | template <typename T1, typename T2, typename T3, typename T4, typename T5, | |
169 | typename T6, typename T7, typename T8> | |
170 | struct Types8 { | |
171 | typedef T1 Head; | |
172 | typedef Types7<T2, T3, T4, T5, T6, T7, T8> Tail; | |
173 | }; | |
174 | ||
175 | template <typename T1, typename T2, typename T3, typename T4, typename T5, | |
176 | typename T6, typename T7, typename T8, typename T9> | |
177 | struct Types9 { | |
178 | typedef T1 Head; | |
179 | typedef Types8<T2, T3, T4, T5, T6, T7, T8, T9> Tail; | |
180 | }; | |
181 | ||
182 | template <typename T1, typename T2, typename T3, typename T4, typename T5, | |
183 | typename T6, typename T7, typename T8, typename T9, typename T10> | |
184 | struct Types10 { | |
185 | typedef T1 Head; | |
186 | typedef Types9<T2, T3, T4, T5, T6, T7, T8, T9, T10> Tail; | |
187 | }; | |
188 | ||
189 | template <typename T1, typename T2, typename T3, typename T4, typename T5, | |
190 | typename T6, typename T7, typename T8, typename T9, typename T10, | |
191 | typename T11> | |
192 | struct Types11 { | |
193 | typedef T1 Head; | |
194 | typedef Types10<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11> Tail; | |
195 | }; | |
196 | ||
197 | template <typename T1, typename T2, typename T3, typename T4, typename T5, | |
198 | typename T6, typename T7, typename T8, typename T9, typename T10, | |
199 | typename T11, typename T12> | |
200 | struct Types12 { | |
201 | typedef T1 Head; | |
202 | typedef Types11<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12> Tail; | |
203 | }; | |
204 | ||
205 | template <typename T1, typename T2, typename T3, typename T4, typename T5, | |
206 | typename T6, typename T7, typename T8, typename T9, typename T10, | |
207 | typename T11, typename T12, typename T13> | |
208 | struct Types13 { | |
209 | typedef T1 Head; | |
210 | typedef Types12<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13> Tail; | |
211 | }; | |
212 | ||
213 | template <typename T1, typename T2, typename T3, typename T4, typename T5, | |
214 | typename T6, typename T7, typename T8, typename T9, typename T10, | |
215 | typename T11, typename T12, typename T13, typename T14> | |
216 | struct Types14 { | |
217 | typedef T1 Head; | |
218 | typedef Types13<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14> Tail; | |
219 | }; | |
220 | ||
221 | template <typename T1, typename T2, typename T3, typename T4, typename T5, | |
222 | typename T6, typename T7, typename T8, typename T9, typename T10, | |
223 | typename T11, typename T12, typename T13, typename T14, typename T15> | |
224 | struct Types15 { | |
225 | typedef T1 Head; | |
226 | typedef Types14<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, | |
227 | T15> Tail; | |
228 | }; | |
229 | ||
230 | template <typename T1, typename T2, typename T3, typename T4, typename T5, | |
231 | typename T6, typename T7, typename T8, typename T9, typename T10, | |
232 | typename T11, typename T12, typename T13, typename T14, typename T15, | |
233 | typename T16> | |
234 | struct Types16 { | |
235 | typedef T1 Head; | |
236 | typedef Types15<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, | |
237 | T16> Tail; | |
238 | }; | |
239 | ||
240 | template <typename T1, typename T2, typename T3, typename T4, typename T5, | |
241 | typename T6, typename T7, typename T8, typename T9, typename T10, | |
242 | typename T11, typename T12, typename T13, typename T14, typename T15, | |
243 | typename T16, typename T17> | |
244 | struct Types17 { | |
245 | typedef T1 Head; | |
246 | typedef Types16<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, | |
247 | T16, T17> Tail; | |
248 | }; | |
249 | ||
250 | template <typename T1, typename T2, typename T3, typename T4, typename T5, | |
251 | typename T6, typename T7, typename T8, typename T9, typename T10, | |
252 | typename T11, typename T12, typename T13, typename T14, typename T15, | |
253 | typename T16, typename T17, typename T18> | |
254 | struct Types18 { | |
255 | typedef T1 Head; | |
256 | typedef Types17<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, | |
257 | T16, T17, T18> Tail; | |
258 | }; | |
259 | ||
260 | template <typename T1, typename T2, typename T3, typename T4, typename T5, | |
261 | typename T6, typename T7, typename T8, typename T9, typename T10, | |
262 | typename T11, typename T12, typename T13, typename T14, typename T15, | |
263 | typename T16, typename T17, typename T18, typename T19> | |
264 | struct Types19 { | |
265 | typedef T1 Head; | |
266 | typedef Types18<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, | |
267 | T16, T17, T18, T19> Tail; | |
268 | }; | |
269 | ||
270 | template <typename T1, typename T2, typename T3, typename T4, typename T5, | |
271 | typename T6, typename T7, typename T8, typename T9, typename T10, | |
272 | typename T11, typename T12, typename T13, typename T14, typename T15, | |
273 | typename T16, typename T17, typename T18, typename T19, typename T20> | |
274 | struct Types20 { | |
275 | typedef T1 Head; | |
276 | typedef Types19<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, | |
277 | T16, T17, T18, T19, T20> Tail; | |
278 | }; | |
279 | ||
280 | template <typename T1, typename T2, typename T3, typename T4, typename T5, | |
281 | typename T6, typename T7, typename T8, typename T9, typename T10, | |
282 | typename T11, typename T12, typename T13, typename T14, typename T15, | |
283 | typename T16, typename T17, typename T18, typename T19, typename T20, | |
284 | typename T21> | |
285 | struct Types21 { | |
286 | typedef T1 Head; | |
287 | typedef Types20<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, | |
288 | T16, T17, T18, T19, T20, T21> Tail; | |
289 | }; | |
290 | ||
291 | template <typename T1, typename T2, typename T3, typename T4, typename T5, | |
292 | typename T6, typename T7, typename T8, typename T9, typename T10, | |
293 | typename T11, typename T12, typename T13, typename T14, typename T15, | |
294 | typename T16, typename T17, typename T18, typename T19, typename T20, | |
295 | typename T21, typename T22> | |
296 | struct Types22 { | |
297 | typedef T1 Head; | |
298 | typedef Types21<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, | |
299 | T16, T17, T18, T19, T20, T21, T22> Tail; | |
300 | }; | |
301 | ||
302 | template <typename T1, typename T2, typename T3, typename T4, typename T5, | |
303 | typename T6, typename T7, typename T8, typename T9, typename T10, | |
304 | typename T11, typename T12, typename T13, typename T14, typename T15, | |
305 | typename T16, typename T17, typename T18, typename T19, typename T20, | |
306 | typename T21, typename T22, typename T23> | |
307 | struct Types23 { | |
308 | typedef T1 Head; | |
309 | typedef Types22<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, | |
310 | T16, T17, T18, T19, T20, T21, T22, T23> Tail; | |
311 | }; | |
312 | ||
313 | template <typename T1, typename T2, typename T3, typename T4, typename T5, | |
314 | typename T6, typename T7, typename T8, typename T9, typename T10, | |
315 | typename T11, typename T12, typename T13, typename T14, typename T15, | |
316 | typename T16, typename T17, typename T18, typename T19, typename T20, | |
317 | typename T21, typename T22, typename T23, typename T24> | |
318 | struct Types24 { | |
319 | typedef T1 Head; | |
320 | typedef Types23<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, | |
321 | T16, T17, T18, T19, T20, T21, T22, T23, T24> Tail; | |
322 | }; | |
323 | ||
324 | template <typename T1, typename T2, typename T3, typename T4, typename T5, | |
325 | typename T6, typename T7, typename T8, typename T9, typename T10, | |
326 | typename T11, typename T12, typename T13, typename T14, typename T15, | |
327 | typename T16, typename T17, typename T18, typename T19, typename T20, | |
328 | typename T21, typename T22, typename T23, typename T24, typename T25> | |
329 | struct Types25 { | |
330 | typedef T1 Head; | |
331 | typedef Types24<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, | |
332 | T16, T17, T18, T19, T20, T21, T22, T23, T24, T25> Tail; | |
333 | }; | |
334 | ||
335 | template <typename T1, typename T2, typename T3, typename T4, typename T5, | |
336 | typename T6, typename T7, typename T8, typename T9, typename T10, | |
337 | typename T11, typename T12, typename T13, typename T14, typename T15, | |
338 | typename T16, typename T17, typename T18, typename T19, typename T20, | |
339 | typename T21, typename T22, typename T23, typename T24, typename T25, | |
340 | typename T26> | |
341 | struct Types26 { | |
342 | typedef T1 Head; | |
343 | typedef Types25<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, | |
344 | T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26> Tail; | |
345 | }; | |
346 | ||
347 | template <typename T1, typename T2, typename T3, typename T4, typename T5, | |
348 | typename T6, typename T7, typename T8, typename T9, typename T10, | |
349 | typename T11, typename T12, typename T13, typename T14, typename T15, | |
350 | typename T16, typename T17, typename T18, typename T19, typename T20, | |
351 | typename T21, typename T22, typename T23, typename T24, typename T25, | |
352 | typename T26, typename T27> | |
353 | struct Types27 { | |
354 | typedef T1 Head; | |
355 | typedef Types26<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, | |
356 | T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27> Tail; | |
357 | }; | |
358 | ||
359 | template <typename T1, typename T2, typename T3, typename T4, typename T5, | |
360 | typename T6, typename T7, typename T8, typename T9, typename T10, | |
361 | typename T11, typename T12, typename T13, typename T14, typename T15, | |
362 | typename T16, typename T17, typename T18, typename T19, typename T20, | |
363 | typename T21, typename T22, typename T23, typename T24, typename T25, | |
364 | typename T26, typename T27, typename T28> | |
365 | struct Types28 { | |
366 | typedef T1 Head; | |
367 | typedef Types27<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, | |
368 | T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28> Tail; | |
369 | }; | |
370 | ||
371 | template <typename T1, typename T2, typename T3, typename T4, typename T5, | |
372 | typename T6, typename T7, typename T8, typename T9, typename T10, | |
373 | typename T11, typename T12, typename T13, typename T14, typename T15, | |
374 | typename T16, typename T17, typename T18, typename T19, typename T20, | |
375 | typename T21, typename T22, typename T23, typename T24, typename T25, | |
376 | typename T26, typename T27, typename T28, typename T29> | |
377 | struct Types29 { | |
378 | typedef T1 Head; | |
379 | typedef Types28<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, | |
380 | T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, | |
381 | T29> Tail; | |
382 | }; | |
383 | ||
384 | template <typename T1, typename T2, typename T3, typename T4, typename T5, | |
385 | typename T6, typename T7, typename T8, typename T9, typename T10, | |
386 | typename T11, typename T12, typename T13, typename T14, typename T15, | |
387 | typename T16, typename T17, typename T18, typename T19, typename T20, | |
388 | typename T21, typename T22, typename T23, typename T24, typename T25, | |
389 | typename T26, typename T27, typename T28, typename T29, typename T30> | |
390 | struct Types30 { | |
391 | typedef T1 Head; | |
392 | typedef Types29<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, | |
393 | T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29, | |
394 | T30> Tail; | |
395 | }; | |
396 | ||
397 | template <typename T1, typename T2, typename T3, typename T4, typename T5, | |
398 | typename T6, typename T7, typename T8, typename T9, typename T10, | |
399 | typename T11, typename T12, typename T13, typename T14, typename T15, | |
400 | typename T16, typename T17, typename T18, typename T19, typename T20, | |
401 | typename T21, typename T22, typename T23, typename T24, typename T25, | |
402 | typename T26, typename T27, typename T28, typename T29, typename T30, | |
403 | typename T31> | |
404 | struct Types31 { | |
405 | typedef T1 Head; | |
406 | typedef Types30<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, | |
407 | T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29, | |
408 | T30, T31> Tail; | |
409 | }; | |
410 | ||
411 | template <typename T1, typename T2, typename T3, typename T4, typename T5, | |
412 | typename T6, typename T7, typename T8, typename T9, typename T10, | |
413 | typename T11, typename T12, typename T13, typename T14, typename T15, | |
414 | typename T16, typename T17, typename T18, typename T19, typename T20, | |
415 | typename T21, typename T22, typename T23, typename T24, typename T25, | |
416 | typename T26, typename T27, typename T28, typename T29, typename T30, | |
417 | typename T31, typename T32> | |
418 | struct Types32 { | |
419 | typedef T1 Head; | |
420 | typedef Types31<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, | |
421 | T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29, | |
422 | T30, T31, T32> Tail; | |
423 | }; | |
424 | ||
425 | template <typename T1, typename T2, typename T3, typename T4, typename T5, | |
426 | typename T6, typename T7, typename T8, typename T9, typename T10, | |
427 | typename T11, typename T12, typename T13, typename T14, typename T15, | |
428 | typename T16, typename T17, typename T18, typename T19, typename T20, | |
429 | typename T21, typename T22, typename T23, typename T24, typename T25, | |
430 | typename T26, typename T27, typename T28, typename T29, typename T30, | |
431 | typename T31, typename T32, typename T33> | |
432 | struct Types33 { | |
433 | typedef T1 Head; | |
434 | typedef Types32<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, | |
435 | T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29, | |
436 | T30, T31, T32, T33> Tail; | |
437 | }; | |
438 | ||
439 | template <typename T1, typename T2, typename T3, typename T4, typename T5, | |
440 | typename T6, typename T7, typename T8, typename T9, typename T10, | |
441 | typename T11, typename T12, typename T13, typename T14, typename T15, | |
442 | typename T16, typename T17, typename T18, typename T19, typename T20, | |
443 | typename T21, typename T22, typename T23, typename T24, typename T25, | |
444 | typename T26, typename T27, typename T28, typename T29, typename T30, | |
445 | typename T31, typename T32, typename T33, typename T34> | |
446 | struct Types34 { | |
447 | typedef T1 Head; | |
448 | typedef Types33<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, | |
449 | T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29, | |
450 | T30, T31, T32, T33, T34> Tail; | |
451 | }; | |
452 | ||
453 | template <typename T1, typename T2, typename T3, typename T4, typename T5, | |
454 | typename T6, typename T7, typename T8, typename T9, typename T10, | |
455 | typename T11, typename T12, typename T13, typename T14, typename T15, | |
456 | typename T16, typename T17, typename T18, typename T19, typename T20, | |
457 | typename T21, typename T22, typename T23, typename T24, typename T25, | |
458 | typename T26, typename T27, typename T28, typename T29, typename T30, | |
459 | typename T31, typename T32, typename T33, typename T34, typename T35> | |
460 | struct Types35 { | |
461 | typedef T1 Head; | |
462 | typedef Types34<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, | |
463 | T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29, | |
464 | T30, T31, T32, T33, T34, T35> Tail; | |
465 | }; | |
466 | ||
467 | template <typename T1, typename T2, typename T3, typename T4, typename T5, | |
468 | typename T6, typename T7, typename T8, typename T9, typename T10, | |
469 | typename T11, typename T12, typename T13, typename T14, typename T15, | |
470 | typename T16, typename T17, typename T18, typename T19, typename T20, | |
471 | typename T21, typename T22, typename T23, typename T24, typename T25, | |
472 | typename T26, typename T27, typename T28, typename T29, typename T30, | |
473 | typename T31, typename T32, typename T33, typename T34, typename T35, | |
474 | typename T36> | |
475 | struct Types36 { | |
476 | typedef T1 Head; | |
477 | typedef Types35<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, | |
478 | T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29, | |
479 | T30, T31, T32, T33, T34, T35, T36> Tail; | |
480 | }; | |
481 | ||
482 | template <typename T1, typename T2, typename T3, typename T4, typename T5, | |
483 | typename T6, typename T7, typename T8, typename T9, typename T10, | |
484 | typename T11, typename T12, typename T13, typename T14, typename T15, | |
485 | typename T16, typename T17, typename T18, typename T19, typename T20, | |
486 | typename T21, typename T22, typename T23, typename T24, typename T25, | |
487 | typename T26, typename T27, typename T28, typename T29, typename T30, | |
488 | typename T31, typename T32, typename T33, typename T34, typename T35, | |
489 | typename T36, typename T37> | |
490 | struct Types37 { | |
491 | typedef T1 Head; | |
492 | typedef Types36<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, | |
493 | T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29, | |
494 | T30, T31, T32, T33, T34, T35, T36, T37> Tail; | |
495 | }; | |
496 | ||
497 | template <typename T1, typename T2, typename T3, typename T4, typename T5, | |
498 | typename T6, typename T7, typename T8, typename T9, typename T10, | |
499 | typename T11, typename T12, typename T13, typename T14, typename T15, | |
500 | typename T16, typename T17, typename T18, typename T19, typename T20, | |
501 | typename T21, typename T22, typename T23, typename T24, typename T25, | |
502 | typename T26, typename T27, typename T28, typename T29, typename T30, | |
503 | typename T31, typename T32, typename T33, typename T34, typename T35, | |
504 | typename T36, typename T37, typename T38> | |
505 | struct Types38 { | |
506 | typedef T1 Head; | |
507 | typedef Types37<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, | |
508 | T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29, | |
509 | T30, T31, T32, T33, T34, T35, T36, T37, T38> Tail; | |
510 | }; | |
511 | ||
512 | template <typename T1, typename T2, typename T3, typename T4, typename T5, | |
513 | typename T6, typename T7, typename T8, typename T9, typename T10, | |
514 | typename T11, typename T12, typename T13, typename T14, typename T15, | |
515 | typename T16, typename T17, typename T18, typename T19, typename T20, | |
516 | typename T21, typename T22, typename T23, typename T24, typename T25, | |
517 | typename T26, typename T27, typename T28, typename T29, typename T30, | |
518 | typename T31, typename T32, typename T33, typename T34, typename T35, | |
519 | typename T36, typename T37, typename T38, typename T39> | |
520 | struct Types39 { | |
521 | typedef T1 Head; | |
522 | typedef Types38<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, | |
523 | T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29, | |
524 | T30, T31, T32, T33, T34, T35, T36, T37, T38, T39> Tail; | |
525 | }; | |
526 | ||
527 | template <typename T1, typename T2, typename T3, typename T4, typename T5, | |
528 | typename T6, typename T7, typename T8, typename T9, typename T10, | |
529 | typename T11, typename T12, typename T13, typename T14, typename T15, | |
530 | typename T16, typename T17, typename T18, typename T19, typename T20, | |
531 | typename T21, typename T22, typename T23, typename T24, typename T25, | |
532 | typename T26, typename T27, typename T28, typename T29, typename T30, | |
533 | typename T31, typename T32, typename T33, typename T34, typename T35, | |
534 | typename T36, typename T37, typename T38, typename T39, typename T40> | |
535 | struct Types40 { | |
536 | typedef T1 Head; | |
537 | typedef Types39<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, | |
538 | T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29, | |
539 | T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40> Tail; | |
540 | }; | |
541 | ||
542 | template <typename T1, typename T2, typename T3, typename T4, typename T5, | |
543 | typename T6, typename T7, typename T8, typename T9, typename T10, | |
544 | typename T11, typename T12, typename T13, typename T14, typename T15, | |
545 | typename T16, typename T17, typename T18, typename T19, typename T20, | |
546 | typename T21, typename T22, typename T23, typename T24, typename T25, | |
547 | typename T26, typename T27, typename T28, typename T29, typename T30, | |
548 | typename T31, typename T32, typename T33, typename T34, typename T35, | |
549 | typename T36, typename T37, typename T38, typename T39, typename T40, | |
550 | typename T41> | |
551 | struct Types41 { | |
552 | typedef T1 Head; | |
553 | typedef Types40<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, | |
554 | T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29, | |
555 | T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, T41> Tail; | |
556 | }; | |
557 | ||
558 | template <typename T1, typename T2, typename T3, typename T4, typename T5, | |
559 | typename T6, typename T7, typename T8, typename T9, typename T10, | |
560 | typename T11, typename T12, typename T13, typename T14, typename T15, | |
561 | typename T16, typename T17, typename T18, typename T19, typename T20, | |
562 | typename T21, typename T22, typename T23, typename T24, typename T25, | |
563 | typename T26, typename T27, typename T28, typename T29, typename T30, | |
564 | typename T31, typename T32, typename T33, typename T34, typename T35, | |
565 | typename T36, typename T37, typename T38, typename T39, typename T40, | |
566 | typename T41, typename T42> | |
567 | struct Types42 { | |
568 | typedef T1 Head; | |
569 | typedef Types41<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, | |
570 | T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29, | |
571 | T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, T41, T42> Tail; | |
572 | }; | |
573 | ||
574 | template <typename T1, typename T2, typename T3, typename T4, typename T5, | |
575 | typename T6, typename T7, typename T8, typename T9, typename T10, | |
576 | typename T11, typename T12, typename T13, typename T14, typename T15, | |
577 | typename T16, typename T17, typename T18, typename T19, typename T20, | |
578 | typename T21, typename T22, typename T23, typename T24, typename T25, | |
579 | typename T26, typename T27, typename T28, typename T29, typename T30, | |
580 | typename T31, typename T32, typename T33, typename T34, typename T35, | |
581 | typename T36, typename T37, typename T38, typename T39, typename T40, | |
582 | typename T41, typename T42, typename T43> | |
583 | struct Types43 { | |
584 | typedef T1 Head; | |
585 | typedef Types42<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, | |
586 | T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29, | |
587 | T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, T41, T42, | |
588 | T43> Tail; | |
589 | }; | |
590 | ||
591 | template <typename T1, typename T2, typename T3, typename T4, typename T5, | |
592 | typename T6, typename T7, typename T8, typename T9, typename T10, | |
593 | typename T11, typename T12, typename T13, typename T14, typename T15, | |
594 | typename T16, typename T17, typename T18, typename T19, typename T20, | |
595 | typename T21, typename T22, typename T23, typename T24, typename T25, | |
596 | typename T26, typename T27, typename T28, typename T29, typename T30, | |
597 | typename T31, typename T32, typename T33, typename T34, typename T35, | |
598 | typename T36, typename T37, typename T38, typename T39, typename T40, | |
599 | typename T41, typename T42, typename T43, typename T44> | |
600 | struct Types44 { | |
601 | typedef T1 Head; | |
602 | typedef Types43<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, | |
603 | T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29, | |
604 | T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, T41, T42, T43, | |
605 | T44> Tail; | |
606 | }; | |
607 | ||
608 | template <typename T1, typename T2, typename T3, typename T4, typename T5, | |
609 | typename T6, typename T7, typename T8, typename T9, typename T10, | |
610 | typename T11, typename T12, typename T13, typename T14, typename T15, | |
611 | typename T16, typename T17, typename T18, typename T19, typename T20, | |
612 | typename T21, typename T22, typename T23, typename T24, typename T25, | |
613 | typename T26, typename T27, typename T28, typename T29, typename T30, | |
614 | typename T31, typename T32, typename T33, typename T34, typename T35, | |
615 | typename T36, typename T37, typename T38, typename T39, typename T40, | |
616 | typename T41, typename T42, typename T43, typename T44, typename T45> | |
617 | struct Types45 { | |
618 | typedef T1 Head; | |
619 | typedef Types44<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, | |
620 | T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29, | |
621 | T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, T41, T42, T43, | |
622 | T44, T45> Tail; | |
623 | }; | |
624 | ||
625 | template <typename T1, typename T2, typename T3, typename T4, typename T5, | |
626 | typename T6, typename T7, typename T8, typename T9, typename T10, | |
627 | typename T11, typename T12, typename T13, typename T14, typename T15, | |
628 | typename T16, typename T17, typename T18, typename T19, typename T20, | |
629 | typename T21, typename T22, typename T23, typename T24, typename T25, | |
630 | typename T26, typename T27, typename T28, typename T29, typename T30, | |
631 | typename T31, typename T32, typename T33, typename T34, typename T35, | |
632 | typename T36, typename T37, typename T38, typename T39, typename T40, | |
633 | typename T41, typename T42, typename T43, typename T44, typename T45, | |
634 | typename T46> | |
635 | struct Types46 { | |
636 | typedef T1 Head; | |
637 | typedef Types45<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, | |
638 | T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29, | |
639 | T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, T41, T42, T43, | |
640 | T44, T45, T46> Tail; | |
641 | }; | |
642 | ||
643 | template <typename T1, typename T2, typename T3, typename T4, typename T5, | |
644 | typename T6, typename T7, typename T8, typename T9, typename T10, | |
645 | typename T11, typename T12, typename T13, typename T14, typename T15, | |
646 | typename T16, typename T17, typename T18, typename T19, typename T20, | |
647 | typename T21, typename T22, typename T23, typename T24, typename T25, | |
648 | typename T26, typename T27, typename T28, typename T29, typename T30, | |
649 | typename T31, typename T32, typename T33, typename T34, typename T35, | |
650 | typename T36, typename T37, typename T38, typename T39, typename T40, | |
651 | typename T41, typename T42, typename T43, typename T44, typename T45, | |
652 | typename T46, typename T47> | |
653 | struct Types47 { | |
654 | typedef T1 Head; | |
655 | typedef Types46<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, | |
656 | T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29, | |
657 | T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, T41, T42, T43, | |
658 | T44, T45, T46, T47> Tail; | |
659 | }; | |
660 | ||
661 | template <typename T1, typename T2, typename T3, typename T4, typename T5, | |
662 | typename T6, typename T7, typename T8, typename T9, typename T10, | |
663 | typename T11, typename T12, typename T13, typename T14, typename T15, | |
664 | typename T16, typename T17, typename T18, typename T19, typename T20, | |
665 | typename T21, typename T22, typename T23, typename T24, typename T25, | |
666 | typename T26, typename T27, typename T28, typename T29, typename T30, | |
667 | typename T31, typename T32, typename T33, typename T34, typename T35, | |
668 | typename T36, typename T37, typename T38, typename T39, typename T40, | |
669 | typename T41, typename T42, typename T43, typename T44, typename T45, | |
670 | typename T46, typename T47, typename T48> | |
671 | struct Types48 { | |
672 | typedef T1 Head; | |
673 | typedef Types47<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, | |
674 | T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29, | |
675 | T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, T41, T42, T43, | |
676 | T44, T45, T46, T47, T48> Tail; | |
677 | }; | |
678 | ||
679 | template <typename T1, typename T2, typename T3, typename T4, typename T5, | |
680 | typename T6, typename T7, typename T8, typename T9, typename T10, | |
681 | typename T11, typename T12, typename T13, typename T14, typename T15, | |
682 | typename T16, typename T17, typename T18, typename T19, typename T20, | |
683 | typename T21, typename T22, typename T23, typename T24, typename T25, | |
684 | typename T26, typename T27, typename T28, typename T29, typename T30, | |
685 | typename T31, typename T32, typename T33, typename T34, typename T35, | |
686 | typename T36, typename T37, typename T38, typename T39, typename T40, | |
687 | typename T41, typename T42, typename T43, typename T44, typename T45, | |
688 | typename T46, typename T47, typename T48, typename T49> | |
689 | struct Types49 { | |
690 | typedef T1 Head; | |
691 | typedef Types48<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, | |
692 | T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29, | |
693 | T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, T41, T42, T43, | |
694 | T44, T45, T46, T47, T48, T49> Tail; | |
695 | }; | |
696 | ||
697 | template <typename T1, typename T2, typename T3, typename T4, typename T5, | |
698 | typename T6, typename T7, typename T8, typename T9, typename T10, | |
699 | typename T11, typename T12, typename T13, typename T14, typename T15, | |
700 | typename T16, typename T17, typename T18, typename T19, typename T20, | |
701 | typename T21, typename T22, typename T23, typename T24, typename T25, | |
702 | typename T26, typename T27, typename T28, typename T29, typename T30, | |
703 | typename T31, typename T32, typename T33, typename T34, typename T35, | |
704 | typename T36, typename T37, typename T38, typename T39, typename T40, | |
705 | typename T41, typename T42, typename T43, typename T44, typename T45, | |
706 | typename T46, typename T47, typename T48, typename T49, typename T50> | |
707 | struct Types50 { | |
708 | typedef T1 Head; | |
709 | typedef Types49<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, | |
710 | T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29, | |
711 | T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, T41, T42, T43, | |
712 | T44, T45, T46, T47, T48, T49, T50> Tail; | |
713 | }; | |
714 | ||
715 | ||
716 | } // namespace internal | |
717 | ||
718 | // We don't want to require the users to write TypesN<...> directly, | |
719 | // as that would require them to count the length. Types<...> is much | |
720 | // easier to write, but generates horrible messages when there is a | |
721 | // compiler error, as gcc insists on printing out each template | |
722 | // argument, even if it has the default value (this means Types<int> | |
723 | // will appear as Types<int, None, None, ..., None> in the compiler | |
724 | // errors). | |
725 | // | |
726 | // Our solution is to combine the best part of the two approaches: a | |
727 | // user would write Types<T1, ..., TN>, and Google Test will translate | |
728 | // that to TypesN<T1, ..., TN> internally to make error messages | |
729 | // readable. The translation is done by the 'type' member of the | |
730 | // Types template. | |
731 | template <typename T1 = internal::None, typename T2 = internal::None, | |
732 | typename T3 = internal::None, typename T4 = internal::None, | |
733 | typename T5 = internal::None, typename T6 = internal::None, | |
734 | typename T7 = internal::None, typename T8 = internal::None, | |
735 | typename T9 = internal::None, typename T10 = internal::None, | |
736 | typename T11 = internal::None, typename T12 = internal::None, | |
737 | typename T13 = internal::None, typename T14 = internal::None, | |
738 | typename T15 = internal::None, typename T16 = internal::None, | |
739 | typename T17 = internal::None, typename T18 = internal::None, | |
740 | typename T19 = internal::None, typename T20 = internal::None, | |
741 | typename T21 = internal::None, typename T22 = internal::None, | |
742 | typename T23 = internal::None, typename T24 = internal::None, | |
743 | typename T25 = internal::None, typename T26 = internal::None, | |
744 | typename T27 = internal::None, typename T28 = internal::None, | |
745 | typename T29 = internal::None, typename T30 = internal::None, | |
746 | typename T31 = internal::None, typename T32 = internal::None, | |
747 | typename T33 = internal::None, typename T34 = internal::None, | |
748 | typename T35 = internal::None, typename T36 = internal::None, | |
749 | typename T37 = internal::None, typename T38 = internal::None, | |
750 | typename T39 = internal::None, typename T40 = internal::None, | |
751 | typename T41 = internal::None, typename T42 = internal::None, | |
752 | typename T43 = internal::None, typename T44 = internal::None, | |
753 | typename T45 = internal::None, typename T46 = internal::None, | |
754 | typename T47 = internal::None, typename T48 = internal::None, | |
755 | typename T49 = internal::None, typename T50 = internal::None> | |
756 | struct Types { | |
757 | typedef internal::Types50<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, | |
758 | T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, | |
759 | T27, T28, T29, T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, | |
760 | T41, T42, T43, T44, T45, T46, T47, T48, T49, T50> type; | |
761 | }; | |
762 | ||
763 | template <> | |
764 | struct Types<internal::None, internal::None, internal::None, internal::None, | |
765 | internal::None, internal::None, internal::None, internal::None, | |
766 | internal::None, internal::None, internal::None, internal::None, | |
767 | internal::None, internal::None, internal::None, internal::None, | |
768 | internal::None, internal::None, internal::None, internal::None, | |
769 | internal::None, internal::None, internal::None, internal::None, | |
770 | internal::None, internal::None, internal::None, internal::None, | |
771 | internal::None, internal::None, internal::None, internal::None, | |
772 | internal::None, internal::None, internal::None, internal::None, | |
773 | internal::None, internal::None, internal::None, internal::None, | |
774 | internal::None, internal::None, internal::None, internal::None, | |
775 | internal::None, internal::None, internal::None, internal::None, | |
776 | internal::None, internal::None> { | |
777 | typedef internal::Types0 type; | |
778 | }; | |
779 | template <typename T1> | |
780 | struct Types<T1, internal::None, internal::None, internal::None, | |
781 | internal::None, internal::None, internal::None, internal::None, | |
782 | internal::None, internal::None, internal::None, internal::None, | |
783 | internal::None, internal::None, internal::None, internal::None, | |
784 | internal::None, internal::None, internal::None, internal::None, | |
785 | internal::None, internal::None, internal::None, internal::None, | |
786 | internal::None, internal::None, internal::None, internal::None, | |
787 | internal::None, internal::None, internal::None, internal::None, | |
788 | internal::None, internal::None, internal::None, internal::None, | |
789 | internal::None, internal::None, internal::None, internal::None, | |
790 | internal::None, internal::None, internal::None, internal::None, | |
791 | internal::None, internal::None, internal::None, internal::None, | |
792 | internal::None, internal::None> { | |
793 | typedef internal::Types1<T1> type; | |
794 | }; | |
795 | template <typename T1, typename T2> | |
796 | struct Types<T1, T2, internal::None, internal::None, internal::None, | |
797 | internal::None, internal::None, internal::None, internal::None, | |
798 | internal::None, internal::None, internal::None, internal::None, | |
799 | internal::None, internal::None, internal::None, internal::None, | |
800 | internal::None, internal::None, internal::None, internal::None, | |
801 | internal::None, internal::None, internal::None, internal::None, | |
802 | internal::None, internal::None, internal::None, internal::None, | |
803 | internal::None, internal::None, internal::None, internal::None, | |
804 | internal::None, internal::None, internal::None, internal::None, | |
805 | internal::None, internal::None, internal::None, internal::None, | |
806 | internal::None, internal::None, internal::None, internal::None, | |
807 | internal::None, internal::None, internal::None, internal::None, | |
808 | internal::None> { | |
809 | typedef internal::Types2<T1, T2> type; | |
810 | }; | |
811 | template <typename T1, typename T2, typename T3> | |
812 | struct Types<T1, T2, T3, internal::None, internal::None, internal::None, | |
813 | internal::None, internal::None, internal::None, internal::None, | |
814 | internal::None, internal::None, internal::None, internal::None, | |
815 | internal::None, internal::None, internal::None, internal::None, | |
816 | internal::None, internal::None, internal::None, internal::None, | |
817 | internal::None, internal::None, internal::None, internal::None, | |
818 | internal::None, internal::None, internal::None, internal::None, | |
819 | internal::None, internal::None, internal::None, internal::None, | |
820 | internal::None, internal::None, internal::None, internal::None, | |
821 | internal::None, internal::None, internal::None, internal::None, | |
822 | internal::None, internal::None, internal::None, internal::None, | |
823 | internal::None, internal::None, internal::None, internal::None> { | |
824 | typedef internal::Types3<T1, T2, T3> type; | |
825 | }; | |
826 | template <typename T1, typename T2, typename T3, typename T4> | |
827 | struct Types<T1, T2, T3, T4, internal::None, internal::None, internal::None, | |
828 | internal::None, internal::None, internal::None, internal::None, | |
829 | internal::None, internal::None, internal::None, internal::None, | |
830 | internal::None, internal::None, internal::None, internal::None, | |
831 | internal::None, internal::None, internal::None, internal::None, | |
832 | internal::None, internal::None, internal::None, internal::None, | |
833 | internal::None, internal::None, internal::None, internal::None, | |
834 | internal::None, internal::None, internal::None, internal::None, | |
835 | internal::None, internal::None, internal::None, internal::None, | |
836 | internal::None, internal::None, internal::None, internal::None, | |
837 | internal::None, internal::None, internal::None, internal::None, | |
838 | internal::None, internal::None, internal::None> { | |
839 | typedef internal::Types4<T1, T2, T3, T4> type; | |
840 | }; | |
841 | template <typename T1, typename T2, typename T3, typename T4, typename T5> | |
842 | struct Types<T1, T2, T3, T4, T5, internal::None, internal::None, | |
843 | internal::None, internal::None, internal::None, internal::None, | |
844 | internal::None, internal::None, internal::None, internal::None, | |
845 | internal::None, internal::None, internal::None, internal::None, | |
846 | internal::None, internal::None, internal::None, internal::None, | |
847 | internal::None, internal::None, internal::None, internal::None, | |
848 | internal::None, internal::None, internal::None, internal::None, | |
849 | internal::None, internal::None, internal::None, internal::None, | |
850 | internal::None, internal::None, internal::None, internal::None, | |
851 | internal::None, internal::None, internal::None, internal::None, | |
852 | internal::None, internal::None, internal::None, internal::None, | |
853 | internal::None, internal::None, internal::None> { | |
854 | typedef internal::Types5<T1, T2, T3, T4, T5> type; | |
855 | }; | |
856 | template <typename T1, typename T2, typename T3, typename T4, typename T5, | |
857 | typename T6> | |
858 | struct Types<T1, T2, T3, T4, T5, T6, internal::None, internal::None, | |
859 | internal::None, internal::None, internal::None, internal::None, | |
860 | internal::None, internal::None, internal::None, internal::None, | |
861 | internal::None, internal::None, internal::None, internal::None, | |
862 | internal::None, internal::None, internal::None, internal::None, | |
863 | internal::None, internal::None, internal::None, internal::None, | |
864 | internal::None, internal::None, internal::None, internal::None, | |
865 | internal::None, internal::None, internal::None, internal::None, | |
866 | internal::None, internal::None, internal::None, internal::None, | |
867 | internal::None, internal::None, internal::None, internal::None, | |
868 | internal::None, internal::None, internal::None, internal::None, | |
869 | internal::None, internal::None> { | |
870 | typedef internal::Types6<T1, T2, T3, T4, T5, T6> type; | |
871 | }; | |
872 | template <typename T1, typename T2, typename T3, typename T4, typename T5, | |
873 | typename T6, typename T7> | |
874 | struct Types<T1, T2, T3, T4, T5, T6, T7, internal::None, internal::None, | |
875 | internal::None, internal::None, internal::None, internal::None, | |
876 | internal::None, internal::None, internal::None, internal::None, | |
877 | internal::None, internal::None, internal::None, internal::None, | |
878 | internal::None, internal::None, internal::None, internal::None, | |
879 | internal::None, internal::None, internal::None, internal::None, | |
880 | internal::None, internal::None, internal::None, internal::None, | |
881 | internal::None, internal::None, internal::None, internal::None, | |
882 | internal::None, internal::None, internal::None, internal::None, | |
883 | internal::None, internal::None, internal::None, internal::None, | |
884 | internal::None, internal::None, internal::None, internal::None, | |
885 | internal::None> { | |
886 | typedef internal::Types7<T1, T2, T3, T4, T5, T6, T7> type; | |
887 | }; | |
888 | template <typename T1, typename T2, typename T3, typename T4, typename T5, | |
889 | typename T6, typename T7, typename T8> | |
890 | struct Types<T1, T2, T3, T4, T5, T6, T7, T8, internal::None, internal::None, | |
891 | internal::None, internal::None, internal::None, internal::None, | |
892 | internal::None, internal::None, internal::None, internal::None, | |
893 | internal::None, internal::None, internal::None, internal::None, | |
894 | internal::None, internal::None, internal::None, internal::None, | |
895 | internal::None, internal::None, internal::None, internal::None, | |
896 | internal::None, internal::None, internal::None, internal::None, | |
897 | internal::None, internal::None, internal::None, internal::None, | |
898 | internal::None, internal::None, internal::None, internal::None, | |
899 | internal::None, internal::None, internal::None, internal::None, | |
900 | internal::None, internal::None, internal::None, internal::None> { | |
901 | typedef internal::Types8<T1, T2, T3, T4, T5, T6, T7, T8> type; | |
902 | }; | |
903 | template <typename T1, typename T2, typename T3, typename T4, typename T5, | |
904 | typename T6, typename T7, typename T8, typename T9> | |
905 | struct Types<T1, T2, T3, T4, T5, T6, T7, T8, T9, internal::None, | |
906 | internal::None, internal::None, internal::None, internal::None, | |
907 | internal::None, internal::None, internal::None, internal::None, | |
908 | internal::None, internal::None, internal::None, internal::None, | |
909 | internal::None, internal::None, internal::None, internal::None, | |
910 | internal::None, internal::None, internal::None, internal::None, | |
911 | internal::None, internal::None, internal::None, internal::None, | |
912 | internal::None, internal::None, internal::None, internal::None, | |
913 | internal::None, internal::None, internal::None, internal::None, | |
914 | internal::None, internal::None, internal::None, internal::None, | |
915 | internal::None, internal::None, internal::None, internal::None> { | |
916 | typedef internal::Types9<T1, T2, T3, T4, T5, T6, T7, T8, T9> type; | |
917 | }; | |
918 | template <typename T1, typename T2, typename T3, typename T4, typename T5, | |
919 | typename T6, typename T7, typename T8, typename T9, typename T10> | |
920 | struct Types<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, internal::None, | |
921 | internal::None, internal::None, internal::None, internal::None, | |
922 | internal::None, internal::None, internal::None, internal::None, | |
923 | internal::None, internal::None, internal::None, internal::None, | |
924 | internal::None, internal::None, internal::None, internal::None, | |
925 | internal::None, internal::None, internal::None, internal::None, | |
926 | internal::None, internal::None, internal::None, internal::None, | |
927 | internal::None, internal::None, internal::None, internal::None, | |
928 | internal::None, internal::None, internal::None, internal::None, | |
929 | internal::None, internal::None, internal::None, internal::None, | |
930 | internal::None, internal::None, internal::None> { | |
931 | typedef internal::Types10<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10> type; | |
932 | }; | |
933 | template <typename T1, typename T2, typename T3, typename T4, typename T5, | |
934 | typename T6, typename T7, typename T8, typename T9, typename T10, | |
935 | typename T11> | |
936 | struct Types<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, internal::None, | |
937 | internal::None, internal::None, internal::None, internal::None, | |
938 | internal::None, internal::None, internal::None, internal::None, | |
939 | internal::None, internal::None, internal::None, internal::None, | |
940 | internal::None, internal::None, internal::None, internal::None, | |
941 | internal::None, internal::None, internal::None, internal::None, | |
942 | internal::None, internal::None, internal::None, internal::None, | |
943 | internal::None, internal::None, internal::None, internal::None, | |
944 | internal::None, internal::None, internal::None, internal::None, | |
945 | internal::None, internal::None, internal::None, internal::None, | |
946 | internal::None, internal::None> { | |
947 | typedef internal::Types11<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11> type; | |
948 | }; | |
949 | template <typename T1, typename T2, typename T3, typename T4, typename T5, | |
950 | typename T6, typename T7, typename T8, typename T9, typename T10, | |
951 | typename T11, typename T12> | |
952 | struct Types<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, internal::None, | |
953 | internal::None, internal::None, internal::None, internal::None, | |
954 | internal::None, internal::None, internal::None, internal::None, | |
955 | internal::None, internal::None, internal::None, internal::None, | |
956 | internal::None, internal::None, internal::None, internal::None, | |
957 | internal::None, internal::None, internal::None, internal::None, | |
958 | internal::None, internal::None, internal::None, internal::None, | |
959 | internal::None, internal::None, internal::None, internal::None, | |
960 | internal::None, internal::None, internal::None, internal::None, | |
961 | internal::None, internal::None, internal::None, internal::None, | |
962 | internal::None> { | |
963 | typedef internal::Types12<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, | |
964 | T12> type; | |
965 | }; | |
966 | template <typename T1, typename T2, typename T3, typename T4, typename T5, | |
967 | typename T6, typename T7, typename T8, typename T9, typename T10, | |
968 | typename T11, typename T12, typename T13> | |
969 | struct Types<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, | |
970 | internal::None, internal::None, internal::None, internal::None, | |
971 | internal::None, internal::None, internal::None, internal::None, | |
972 | internal::None, internal::None, internal::None, internal::None, | |
973 | internal::None, internal::None, internal::None, internal::None, | |
974 | internal::None, internal::None, internal::None, internal::None, | |
975 | internal::None, internal::None, internal::None, internal::None, | |
976 | internal::None, internal::None, internal::None, internal::None, | |
977 | internal::None, internal::None, internal::None, internal::None, | |
978 | internal::None, internal::None, internal::None, internal::None, | |
979 | internal::None> { | |
980 | typedef internal::Types13<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, | |
981 | T13> type; | |
982 | }; | |
983 | template <typename T1, typename T2, typename T3, typename T4, typename T5, | |
984 | typename T6, typename T7, typename T8, typename T9, typename T10, | |
985 | typename T11, typename T12, typename T13, typename T14> | |
986 | struct Types<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, | |
987 | internal::None, internal::None, internal::None, internal::None, | |
988 | internal::None, internal::None, internal::None, internal::None, | |
989 | internal::None, internal::None, internal::None, internal::None, | |
990 | internal::None, internal::None, internal::None, internal::None, | |
991 | internal::None, internal::None, internal::None, internal::None, | |
992 | internal::None, internal::None, internal::None, internal::None, | |
993 | internal::None, internal::None, internal::None, internal::None, | |
994 | internal::None, internal::None, internal::None, internal::None, | |
995 | internal::None, internal::None, internal::None, internal::None> { | |
996 | typedef internal::Types14<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, | |
997 | T13, T14> type; | |
998 | }; | |
999 | template <typename T1, typename T2, typename T3, typename T4, typename T5, | |
1000 | typename T6, typename T7, typename T8, typename T9, typename T10, | |
1001 | typename T11, typename T12, typename T13, typename T14, typename T15> | |
1002 | struct Types<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, | |
1003 | internal::None, internal::None, internal::None, internal::None, | |
1004 | internal::None, internal::None, internal::None, internal::None, | |
1005 | internal::None, internal::None, internal::None, internal::None, | |
1006 | internal::None, internal::None, internal::None, internal::None, | |
1007 | internal::None, internal::None, internal::None, internal::None, | |
1008 | internal::None, internal::None, internal::None, internal::None, | |
1009 | internal::None, internal::None, internal::None, internal::None, | |
1010 | internal::None, internal::None, internal::None, internal::None, | |
1011 | internal::None, internal::None, internal::None> { | |
1012 | typedef internal::Types15<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, | |
1013 | T13, T14, T15> type; | |
1014 | }; | |
1015 | template <typename T1, typename T2, typename T3, typename T4, typename T5, | |
1016 | typename T6, typename T7, typename T8, typename T9, typename T10, | |
1017 | typename T11, typename T12, typename T13, typename T14, typename T15, | |
1018 | typename T16> | |
1019 | struct Types<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, | |
1020 | T16, internal::None, internal::None, internal::None, internal::None, | |
1021 | internal::None, internal::None, internal::None, internal::None, | |
1022 | internal::None, internal::None, internal::None, internal::None, | |
1023 | internal::None, internal::None, internal::None, internal::None, | |
1024 | internal::None, internal::None, internal::None, internal::None, | |
1025 | internal::None, internal::None, internal::None, internal::None, | |
1026 | internal::None, internal::None, internal::None, internal::None, | |
1027 | internal::None, internal::None, internal::None, internal::None, | |
1028 | internal::None, internal::None> { | |
1029 | typedef internal::Types16<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, | |
1030 | T13, T14, T15, T16> type; | |
1031 | }; | |
1032 | template <typename T1, typename T2, typename T3, typename T4, typename T5, | |
1033 | typename T6, typename T7, typename T8, typename T9, typename T10, | |
1034 | typename T11, typename T12, typename T13, typename T14, typename T15, | |
1035 | typename T16, typename T17> | |
1036 | struct Types<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, | |
1037 | T16, T17, internal::None, internal::None, internal::None, internal::None, | |
1038 | internal::None, internal::None, internal::None, internal::None, | |
1039 | internal::None, internal::None, internal::None, internal::None, | |
1040 | internal::None, internal::None, internal::None, internal::None, | |
1041 | internal::None, internal::None, internal::None, internal::None, | |
1042 | internal::None, internal::None, internal::None, internal::None, | |
1043 | internal::None, internal::None, internal::None, internal::None, | |
1044 | internal::None, internal::None, internal::None, internal::None, | |
1045 | internal::None> { | |
1046 | typedef internal::Types17<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, | |
1047 | T13, T14, T15, T16, T17> type; | |
1048 | }; | |
1049 | template <typename T1, typename T2, typename T3, typename T4, typename T5, | |
1050 | typename T6, typename T7, typename T8, typename T9, typename T10, | |
1051 | typename T11, typename T12, typename T13, typename T14, typename T15, | |
1052 | typename T16, typename T17, typename T18> | |
1053 | struct Types<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, | |
1054 | T16, T17, T18, internal::None, internal::None, internal::None, | |
1055 | internal::None, internal::None, internal::None, internal::None, | |
1056 | internal::None, internal::None, internal::None, internal::None, | |
1057 | internal::None, internal::None, internal::None, internal::None, | |
1058 | internal::None, internal::None, internal::None, internal::None, | |
1059 | internal::None, internal::None, internal::None, internal::None, | |
1060 | internal::None, internal::None, internal::None, internal::None, | |
1061 | internal::None, internal::None, internal::None, internal::None, | |
1062 | internal::None> { | |
1063 | typedef internal::Types18<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, | |
1064 | T13, T14, T15, T16, T17, T18> type; | |
1065 | }; | |
1066 | template <typename T1, typename T2, typename T3, typename T4, typename T5, | |
1067 | typename T6, typename T7, typename T8, typename T9, typename T10, | |
1068 | typename T11, typename T12, typename T13, typename T14, typename T15, | |
1069 | typename T16, typename T17, typename T18, typename T19> | |
1070 | struct Types<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, | |
1071 | T16, T17, T18, T19, internal::None, internal::None, internal::None, | |
1072 | internal::None, internal::None, internal::None, internal::None, | |
1073 | internal::None, internal::None, internal::None, internal::None, | |
1074 | internal::None, internal::None, internal::None, internal::None, | |
1075 | internal::None, internal::None, internal::None, internal::None, | |
1076 | internal::None, internal::None, internal::None, internal::None, | |
1077 | internal::None, internal::None, internal::None, internal::None, | |
1078 | internal::None, internal::None, internal::None, internal::None> { | |
1079 | typedef internal::Types19<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, | |
1080 | T13, T14, T15, T16, T17, T18, T19> type; | |
1081 | }; | |
1082 | template <typename T1, typename T2, typename T3, typename T4, typename T5, | |
1083 | typename T6, typename T7, typename T8, typename T9, typename T10, | |
1084 | typename T11, typename T12, typename T13, typename T14, typename T15, | |
1085 | typename T16, typename T17, typename T18, typename T19, typename T20> | |
1086 | struct Types<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, | |
1087 | T16, T17, T18, T19, T20, internal::None, internal::None, internal::None, | |
1088 | internal::None, internal::None, internal::None, internal::None, | |
1089 | internal::None, internal::None, internal::None, internal::None, | |
1090 | internal::None, internal::None, internal::None, internal::None, | |
1091 | internal::None, internal::None, internal::None, internal::None, | |
1092 | internal::None, internal::None, internal::None, internal::None, | |
1093 | internal::None, internal::None, internal::None, internal::None, | |
1094 | internal::None, internal::None, internal::None> { | |
1095 | typedef internal::Types20<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, | |
1096 | T13, T14, T15, T16, T17, T18, T19, T20> type; | |
1097 | }; | |
1098 | template <typename T1, typename T2, typename T3, typename T4, typename T5, | |
1099 | typename T6, typename T7, typename T8, typename T9, typename T10, | |
1100 | typename T11, typename T12, typename T13, typename T14, typename T15, | |
1101 | typename T16, typename T17, typename T18, typename T19, typename T20, | |
1102 | typename T21> | |
1103 | struct Types<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, | |
1104 | T16, T17, T18, T19, T20, T21, internal::None, internal::None, | |
1105 | internal::None, internal::None, internal::None, internal::None, | |
1106 | internal::None, internal::None, internal::None, internal::None, | |
1107 | internal::None, internal::None, internal::None, internal::None, | |
1108 | internal::None, internal::None, internal::None, internal::None, | |
1109 | internal::None, internal::None, internal::None, internal::None, | |
1110 | internal::None, internal::None, internal::None, internal::None, | |
1111 | internal::None, internal::None, internal::None> { | |
1112 | typedef internal::Types21<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, | |
1113 | T13, T14, T15, T16, T17, T18, T19, T20, T21> type; | |
1114 | }; | |
1115 | template <typename T1, typename T2, typename T3, typename T4, typename T5, | |
1116 | typename T6, typename T7, typename T8, typename T9, typename T10, | |
1117 | typename T11, typename T12, typename T13, typename T14, typename T15, | |
1118 | typename T16, typename T17, typename T18, typename T19, typename T20, | |
1119 | typename T21, typename T22> | |
1120 | struct Types<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, | |
1121 | T16, T17, T18, T19, T20, T21, T22, internal::None, internal::None, | |
1122 | internal::None, internal::None, internal::None, internal::None, | |
1123 | internal::None, internal::None, internal::None, internal::None, | |
1124 | internal::None, internal::None, internal::None, internal::None, | |
1125 | internal::None, internal::None, internal::None, internal::None, | |
1126 | internal::None, internal::None, internal::None, internal::None, | |
1127 | internal::None, internal::None, internal::None, internal::None, | |
1128 | internal::None, internal::None> { | |
1129 | typedef internal::Types22<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, | |
1130 | T13, T14, T15, T16, T17, T18, T19, T20, T21, T22> type; | |
1131 | }; | |
1132 | template <typename T1, typename T2, typename T3, typename T4, typename T5, | |
1133 | typename T6, typename T7, typename T8, typename T9, typename T10, | |
1134 | typename T11, typename T12, typename T13, typename T14, typename T15, | |
1135 | typename T16, typename T17, typename T18, typename T19, typename T20, | |
1136 | typename T21, typename T22, typename T23> | |
1137 | struct Types<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, | |
1138 | T16, T17, T18, T19, T20, T21, T22, T23, internal::None, internal::None, | |
1139 | internal::None, internal::None, internal::None, internal::None, | |
1140 | internal::None, internal::None, internal::None, internal::None, | |
1141 | internal::None, internal::None, internal::None, internal::None, | |
1142 | internal::None, internal::None, internal::None, internal::None, | |
1143 | internal::None, internal::None, internal::None, internal::None, | |
1144 | internal::None, internal::None, internal::None, internal::None, | |
1145 | internal::None> { | |
1146 | typedef internal::Types23<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, | |
1147 | T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23> type; | |
1148 | }; | |
1149 | template <typename T1, typename T2, typename T3, typename T4, typename T5, | |
1150 | typename T6, typename T7, typename T8, typename T9, typename T10, | |
1151 | typename T11, typename T12, typename T13, typename T14, typename T15, | |
1152 | typename T16, typename T17, typename T18, typename T19, typename T20, | |
1153 | typename T21, typename T22, typename T23, typename T24> | |
1154 | struct Types<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, | |
1155 | T16, T17, T18, T19, T20, T21, T22, T23, T24, internal::None, | |
1156 | internal::None, internal::None, internal::None, internal::None, | |
1157 | internal::None, internal::None, internal::None, internal::None, | |
1158 | internal::None, internal::None, internal::None, internal::None, | |
1159 | internal::None, internal::None, internal::None, internal::None, | |
1160 | internal::None, internal::None, internal::None, internal::None, | |
1161 | internal::None, internal::None, internal::None, internal::None, | |
1162 | internal::None> { | |
1163 | typedef internal::Types24<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, | |
1164 | T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24> type; | |
1165 | }; | |
1166 | template <typename T1, typename T2, typename T3, typename T4, typename T5, | |
1167 | typename T6, typename T7, typename T8, typename T9, typename T10, | |
1168 | typename T11, typename T12, typename T13, typename T14, typename T15, | |
1169 | typename T16, typename T17, typename T18, typename T19, typename T20, | |
1170 | typename T21, typename T22, typename T23, typename T24, typename T25> | |
1171 | struct Types<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, | |
1172 | T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, internal::None, | |
1173 | internal::None, internal::None, internal::None, internal::None, | |
1174 | internal::None, internal::None, internal::None, internal::None, | |
1175 | internal::None, internal::None, internal::None, internal::None, | |
1176 | internal::None, internal::None, internal::None, internal::None, | |
1177 | internal::None, internal::None, internal::None, internal::None, | |
1178 | internal::None, internal::None, internal::None, internal::None> { | |
1179 | typedef internal::Types25<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, | |
1180 | T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25> type; | |
1181 | }; | |
1182 | template <typename T1, typename T2, typename T3, typename T4, typename T5, | |
1183 | typename T6, typename T7, typename T8, typename T9, typename T10, | |
1184 | typename T11, typename T12, typename T13, typename T14, typename T15, | |
1185 | typename T16, typename T17, typename T18, typename T19, typename T20, | |
1186 | typename T21, typename T22, typename T23, typename T24, typename T25, | |
1187 | typename T26> | |
1188 | struct Types<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, | |
1189 | T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, internal::None, | |
1190 | internal::None, internal::None, internal::None, internal::None, | |
1191 | internal::None, internal::None, internal::None, internal::None, | |
1192 | internal::None, internal::None, internal::None, internal::None, | |
1193 | internal::None, internal::None, internal::None, internal::None, | |
1194 | internal::None, internal::None, internal::None, internal::None, | |
1195 | internal::None, internal::None, internal::None> { | |
1196 | typedef internal::Types26<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, | |
1197 | T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, | |
1198 | T26> type; | |
1199 | }; | |
1200 | template <typename T1, typename T2, typename T3, typename T4, typename T5, | |
1201 | typename T6, typename T7, typename T8, typename T9, typename T10, | |
1202 | typename T11, typename T12, typename T13, typename T14, typename T15, | |
1203 | typename T16, typename T17, typename T18, typename T19, typename T20, | |
1204 | typename T21, typename T22, typename T23, typename T24, typename T25, | |
1205 | typename T26, typename T27> | |
1206 | struct Types<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, | |
1207 | T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, internal::None, | |
1208 | internal::None, internal::None, internal::None, internal::None, | |
1209 | internal::None, internal::None, internal::None, internal::None, | |
1210 | internal::None, internal::None, internal::None, internal::None, | |
1211 | internal::None, internal::None, internal::None, internal::None, | |
1212 | internal::None, internal::None, internal::None, internal::None, | |
1213 | internal::None, internal::None> { | |
1214 | typedef internal::Types27<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, | |
1215 | T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, | |
1216 | T27> type; | |
1217 | }; | |
1218 | template <typename T1, typename T2, typename T3, typename T4, typename T5, | |
1219 | typename T6, typename T7, typename T8, typename T9, typename T10, | |
1220 | typename T11, typename T12, typename T13, typename T14, typename T15, | |
1221 | typename T16, typename T17, typename T18, typename T19, typename T20, | |
1222 | typename T21, typename T22, typename T23, typename T24, typename T25, | |
1223 | typename T26, typename T27, typename T28> | |
1224 | struct Types<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, | |
1225 | T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, | |
1226 | internal::None, internal::None, internal::None, internal::None, | |
1227 | internal::None, internal::None, internal::None, internal::None, | |
1228 | internal::None, internal::None, internal::None, internal::None, | |
1229 | internal::None, internal::None, internal::None, internal::None, | |
1230 | internal::None, internal::None, internal::None, internal::None, | |
1231 | internal::None, internal::None> { | |
1232 | typedef internal::Types28<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, | |
1233 | T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, | |
1234 | T27, T28> type; | |
1235 | }; | |
1236 | template <typename T1, typename T2, typename T3, typename T4, typename T5, | |
1237 | typename T6, typename T7, typename T8, typename T9, typename T10, | |
1238 | typename T11, typename T12, typename T13, typename T14, typename T15, | |
1239 | typename T16, typename T17, typename T18, typename T19, typename T20, | |
1240 | typename T21, typename T22, typename T23, typename T24, typename T25, | |
1241 | typename T26, typename T27, typename T28, typename T29> | |
1242 | struct Types<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, | |
1243 | T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29, | |
1244 | internal::None, internal::None, internal::None, internal::None, | |
1245 | internal::None, internal::None, internal::None, internal::None, | |
1246 | internal::None, internal::None, internal::None, internal::None, | |
1247 | internal::None, internal::None, internal::None, internal::None, | |
1248 | internal::None, internal::None, internal::None, internal::None, | |
1249 | internal::None> { | |
1250 | typedef internal::Types29<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, | |
1251 | T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, | |
1252 | T27, T28, T29> type; | |
1253 | }; | |
1254 | template <typename T1, typename T2, typename T3, typename T4, typename T5, | |
1255 | typename T6, typename T7, typename T8, typename T9, typename T10, | |
1256 | typename T11, typename T12, typename T13, typename T14, typename T15, | |
1257 | typename T16, typename T17, typename T18, typename T19, typename T20, | |
1258 | typename T21, typename T22, typename T23, typename T24, typename T25, | |
1259 | typename T26, typename T27, typename T28, typename T29, typename T30> | |
1260 | struct Types<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, | |
1261 | T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29, T30, | |
1262 | internal::None, internal::None, internal::None, internal::None, | |
1263 | internal::None, internal::None, internal::None, internal::None, | |
1264 | internal::None, internal::None, internal::None, internal::None, | |
1265 | internal::None, internal::None, internal::None, internal::None, | |
1266 | internal::None, internal::None, internal::None, internal::None> { | |
1267 | typedef internal::Types30<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, | |
1268 | T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, | |
1269 | T27, T28, T29, T30> type; | |
1270 | }; | |
1271 | template <typename T1, typename T2, typename T3, typename T4, typename T5, | |
1272 | typename T6, typename T7, typename T8, typename T9, typename T10, | |
1273 | typename T11, typename T12, typename T13, typename T14, typename T15, | |
1274 | typename T16, typename T17, typename T18, typename T19, typename T20, | |
1275 | typename T21, typename T22, typename T23, typename T24, typename T25, | |
1276 | typename T26, typename T27, typename T28, typename T29, typename T30, | |
1277 | typename T31> | |
1278 | struct Types<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, | |
1279 | T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29, T30, | |
1280 | T31, internal::None, internal::None, internal::None, internal::None, | |
1281 | internal::None, internal::None, internal::None, internal::None, | |
1282 | internal::None, internal::None, internal::None, internal::None, | |
1283 | internal::None, internal::None, internal::None, internal::None, | |
1284 | internal::None, internal::None, internal::None> { | |
1285 | typedef internal::Types31<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, | |
1286 | T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, | |
1287 | T27, T28, T29, T30, T31> type; | |
1288 | }; | |
1289 | template <typename T1, typename T2, typename T3, typename T4, typename T5, | |
1290 | typename T6, typename T7, typename T8, typename T9, typename T10, | |
1291 | typename T11, typename T12, typename T13, typename T14, typename T15, | |
1292 | typename T16, typename T17, typename T18, typename T19, typename T20, | |
1293 | typename T21, typename T22, typename T23, typename T24, typename T25, | |
1294 | typename T26, typename T27, typename T28, typename T29, typename T30, | |
1295 | typename T31, typename T32> | |
1296 | struct Types<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, | |
1297 | T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29, T30, | |
1298 | T31, T32, internal::None, internal::None, internal::None, internal::None, | |
1299 | internal::None, internal::None, internal::None, internal::None, | |
1300 | internal::None, internal::None, internal::None, internal::None, | |
1301 | internal::None, internal::None, internal::None, internal::None, | |
1302 | internal::None, internal::None> { | |
1303 | typedef internal::Types32<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, | |
1304 | T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, | |
1305 | T27, T28, T29, T30, T31, T32> type; | |
1306 | }; | |
1307 | template <typename T1, typename T2, typename T3, typename T4, typename T5, | |
1308 | typename T6, typename T7, typename T8, typename T9, typename T10, | |
1309 | typename T11, typename T12, typename T13, typename T14, typename T15, | |
1310 | typename T16, typename T17, typename T18, typename T19, typename T20, | |
1311 | typename T21, typename T22, typename T23, typename T24, typename T25, | |
1312 | typename T26, typename T27, typename T28, typename T29, typename T30, | |
1313 | typename T31, typename T32, typename T33> | |
1314 | struct Types<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, | |
1315 | T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29, T30, | |
1316 | T31, T32, T33, internal::None, internal::None, internal::None, | |
1317 | internal::None, internal::None, internal::None, internal::None, | |
1318 | internal::None, internal::None, internal::None, internal::None, | |
1319 | internal::None, internal::None, internal::None, internal::None, | |
1320 | internal::None, internal::None> { | |
1321 | typedef internal::Types33<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, | |
1322 | T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, | |
1323 | T27, T28, T29, T30, T31, T32, T33> type; | |
1324 | }; | |
1325 | template <typename T1, typename T2, typename T3, typename T4, typename T5, | |
1326 | typename T6, typename T7, typename T8, typename T9, typename T10, | |
1327 | typename T11, typename T12, typename T13, typename T14, typename T15, | |
1328 | typename T16, typename T17, typename T18, typename T19, typename T20, | |
1329 | typename T21, typename T22, typename T23, typename T24, typename T25, | |
1330 | typename T26, typename T27, typename T28, typename T29, typename T30, | |
1331 | typename T31, typename T32, typename T33, typename T34> | |
1332 | struct Types<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, | |
1333 | T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29, T30, | |
1334 | T31, T32, T33, T34, internal::None, internal::None, internal::None, | |
1335 | internal::None, internal::None, internal::None, internal::None, | |
1336 | internal::None, internal::None, internal::None, internal::None, | |
1337 | internal::None, internal::None, internal::None, internal::None, | |
1338 | internal::None> { | |
1339 | typedef internal::Types34<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, | |
1340 | T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, | |
1341 | T27, T28, T29, T30, T31, T32, T33, T34> type; | |
1342 | }; | |
1343 | template <typename T1, typename T2, typename T3, typename T4, typename T5, | |
1344 | typename T6, typename T7, typename T8, typename T9, typename T10, | |
1345 | typename T11, typename T12, typename T13, typename T14, typename T15, | |
1346 | typename T16, typename T17, typename T18, typename T19, typename T20, | |
1347 | typename T21, typename T22, typename T23, typename T24, typename T25, | |
1348 | typename T26, typename T27, typename T28, typename T29, typename T30, | |
1349 | typename T31, typename T32, typename T33, typename T34, typename T35> | |
1350 | struct Types<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, | |
1351 | T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29, T30, | |
1352 | T31, T32, T33, T34, T35, internal::None, internal::None, internal::None, | |
1353 | internal::None, internal::None, internal::None, internal::None, | |
1354 | internal::None, internal::None, internal::None, internal::None, | |
1355 | internal::None, internal::None, internal::None, internal::None> { | |
1356 | typedef internal::Types35<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, | |
1357 | T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, | |
1358 | T27, T28, T29, T30, T31, T32, T33, T34, T35> type; | |
1359 | }; | |
1360 | template <typename T1, typename T2, typename T3, typename T4, typename T5, | |
1361 | typename T6, typename T7, typename T8, typename T9, typename T10, | |
1362 | typename T11, typename T12, typename T13, typename T14, typename T15, | |
1363 | typename T16, typename T17, typename T18, typename T19, typename T20, | |
1364 | typename T21, typename T22, typename T23, typename T24, typename T25, | |
1365 | typename T26, typename T27, typename T28, typename T29, typename T30, | |
1366 | typename T31, typename T32, typename T33, typename T34, typename T35, | |
1367 | typename T36> | |
1368 | struct Types<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, | |
1369 | T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29, T30, | |
1370 | T31, T32, T33, T34, T35, T36, internal::None, internal::None, | |
1371 | internal::None, internal::None, internal::None, internal::None, | |
1372 | internal::None, internal::None, internal::None, internal::None, | |
1373 | internal::None, internal::None, internal::None, internal::None> { | |
1374 | typedef internal::Types36<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, | |
1375 | T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, | |
1376 | T27, T28, T29, T30, T31, T32, T33, T34, T35, T36> type; | |
1377 | }; | |
1378 | template <typename T1, typename T2, typename T3, typename T4, typename T5, | |
1379 | typename T6, typename T7, typename T8, typename T9, typename T10, | |
1380 | typename T11, typename T12, typename T13, typename T14, typename T15, | |
1381 | typename T16, typename T17, typename T18, typename T19, typename T20, | |
1382 | typename T21, typename T22, typename T23, typename T24, typename T25, | |
1383 | typename T26, typename T27, typename T28, typename T29, typename T30, | |
1384 | typename T31, typename T32, typename T33, typename T34, typename T35, | |
1385 | typename T36, typename T37> | |
1386 | struct Types<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, | |
1387 | T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29, T30, | |
1388 | T31, T32, T33, T34, T35, T36, T37, internal::None, internal::None, | |
1389 | internal::None, internal::None, internal::None, internal::None, | |
1390 | internal::None, internal::None, internal::None, internal::None, | |
1391 | internal::None, internal::None, internal::None> { | |
1392 | typedef internal::Types37<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, | |
1393 | T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, | |
1394 | T27, T28, T29, T30, T31, T32, T33, T34, T35, T36, T37> type; | |
1395 | }; | |
1396 | template <typename T1, typename T2, typename T3, typename T4, typename T5, | |
1397 | typename T6, typename T7, typename T8, typename T9, typename T10, | |
1398 | typename T11, typename T12, typename T13, typename T14, typename T15, | |
1399 | typename T16, typename T17, typename T18, typename T19, typename T20, | |
1400 | typename T21, typename T22, typename T23, typename T24, typename T25, | |
1401 | typename T26, typename T27, typename T28, typename T29, typename T30, | |
1402 | typename T31, typename T32, typename T33, typename T34, typename T35, | |
1403 | typename T36, typename T37, typename T38> | |
1404 | struct Types<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, | |
1405 | T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29, T30, | |
1406 | T31, T32, T33, T34, T35, T36, T37, T38, internal::None, internal::None, | |
1407 | internal::None, internal::None, internal::None, internal::None, | |
1408 | internal::None, internal::None, internal::None, internal::None, | |
1409 | internal::None, internal::None> { | |
1410 | typedef internal::Types38<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, | |
1411 | T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, | |
1412 | T27, T28, T29, T30, T31, T32, T33, T34, T35, T36, T37, T38> type; | |
1413 | }; | |
1414 | template <typename T1, typename T2, typename T3, typename T4, typename T5, | |
1415 | typename T6, typename T7, typename T8, typename T9, typename T10, | |
1416 | typename T11, typename T12, typename T13, typename T14, typename T15, | |
1417 | typename T16, typename T17, typename T18, typename T19, typename T20, | |
1418 | typename T21, typename T22, typename T23, typename T24, typename T25, | |
1419 | typename T26, typename T27, typename T28, typename T29, typename T30, | |
1420 | typename T31, typename T32, typename T33, typename T34, typename T35, | |
1421 | typename T36, typename T37, typename T38, typename T39> | |
1422 | struct Types<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, | |
1423 | T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29, T30, | |
1424 | T31, T32, T33, T34, T35, T36, T37, T38, T39, internal::None, | |
1425 | internal::None, internal::None, internal::None, internal::None, | |
1426 | internal::None, internal::None, internal::None, internal::None, | |
1427 | internal::None, internal::None> { | |
1428 | typedef internal::Types39<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, | |
1429 | T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, | |
1430 | T27, T28, T29, T30, T31, T32, T33, T34, T35, T36, T37, T38, T39> type; | |
1431 | }; | |
1432 | template <typename T1, typename T2, typename T3, typename T4, typename T5, | |
1433 | typename T6, typename T7, typename T8, typename T9, typename T10, | |
1434 | typename T11, typename T12, typename T13, typename T14, typename T15, | |
1435 | typename T16, typename T17, typename T18, typename T19, typename T20, | |
1436 | typename T21, typename T22, typename T23, typename T24, typename T25, | |
1437 | typename T26, typename T27, typename T28, typename T29, typename T30, | |
1438 | typename T31, typename T32, typename T33, typename T34, typename T35, | |
1439 | typename T36, typename T37, typename T38, typename T39, typename T40> | |
1440 | struct Types<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, | |
1441 | T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29, T30, | |
1442 | T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, internal::None, | |
1443 | internal::None, internal::None, internal::None, internal::None, | |
1444 | internal::None, internal::None, internal::None, internal::None, | |
1445 | internal::None> { | |
1446 | typedef internal::Types40<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, | |
1447 | T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, | |
1448 | T27, T28, T29, T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, | |
1449 | T40> type; | |
1450 | }; | |
1451 | template <typename T1, typename T2, typename T3, typename T4, typename T5, | |
1452 | typename T6, typename T7, typename T8, typename T9, typename T10, | |
1453 | typename T11, typename T12, typename T13, typename T14, typename T15, | |
1454 | typename T16, typename T17, typename T18, typename T19, typename T20, | |
1455 | typename T21, typename T22, typename T23, typename T24, typename T25, | |
1456 | typename T26, typename T27, typename T28, typename T29, typename T30, | |
1457 | typename T31, typename T32, typename T33, typename T34, typename T35, | |
1458 | typename T36, typename T37, typename T38, typename T39, typename T40, | |
1459 | typename T41> | |
1460 | struct Types<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, | |
1461 | T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29, T30, | |
1462 | T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, T41, internal::None, | |
1463 | internal::None, internal::None, internal::None, internal::None, | |
1464 | internal::None, internal::None, internal::None, internal::None> { | |
1465 | typedef internal::Types41<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, | |
1466 | T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, | |
1467 | T27, T28, T29, T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, | |
1468 | T41> type; | |
1469 | }; | |
1470 | template <typename T1, typename T2, typename T3, typename T4, typename T5, | |
1471 | typename T6, typename T7, typename T8, typename T9, typename T10, | |
1472 | typename T11, typename T12, typename T13, typename T14, typename T15, | |
1473 | typename T16, typename T17, typename T18, typename T19, typename T20, | |
1474 | typename T21, typename T22, typename T23, typename T24, typename T25, | |
1475 | typename T26, typename T27, typename T28, typename T29, typename T30, | |
1476 | typename T31, typename T32, typename T33, typename T34, typename T35, | |
1477 | typename T36, typename T37, typename T38, typename T39, typename T40, | |
1478 | typename T41, typename T42> | |
1479 | struct Types<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, | |
1480 | T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29, T30, | |
1481 | T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, T41, T42, internal::None, | |
1482 | internal::None, internal::None, internal::None, internal::None, | |
1483 | internal::None, internal::None, internal::None> { | |
1484 | typedef internal::Types42<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, | |
1485 | T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, | |
1486 | T27, T28, T29, T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, | |
1487 | T41, T42> type; | |
1488 | }; | |
1489 | template <typename T1, typename T2, typename T3, typename T4, typename T5, | |
1490 | typename T6, typename T7, typename T8, typename T9, typename T10, | |
1491 | typename T11, typename T12, typename T13, typename T14, typename T15, | |
1492 | typename T16, typename T17, typename T18, typename T19, typename T20, | |
1493 | typename T21, typename T22, typename T23, typename T24, typename T25, | |
1494 | typename T26, typename T27, typename T28, typename T29, typename T30, | |
1495 | typename T31, typename T32, typename T33, typename T34, typename T35, | |
1496 | typename T36, typename T37, typename T38, typename T39, typename T40, | |
1497 | typename T41, typename T42, typename T43> | |
1498 | struct Types<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, | |
1499 | T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29, T30, | |
1500 | T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, T41, T42, T43, | |
1501 | internal::None, internal::None, internal::None, internal::None, | |
1502 | internal::None, internal::None, internal::None> { | |
1503 | typedef internal::Types43<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, | |
1504 | T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, | |
1505 | T27, T28, T29, T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, | |
1506 | T41, T42, T43> type; | |
1507 | }; | |
1508 | template <typename T1, typename T2, typename T3, typename T4, typename T5, | |
1509 | typename T6, typename T7, typename T8, typename T9, typename T10, | |
1510 | typename T11, typename T12, typename T13, typename T14, typename T15, | |
1511 | typename T16, typename T17, typename T18, typename T19, typename T20, | |
1512 | typename T21, typename T22, typename T23, typename T24, typename T25, | |
1513 | typename T26, typename T27, typename T28, typename T29, typename T30, | |
1514 | typename T31, typename T32, typename T33, typename T34, typename T35, | |
1515 | typename T36, typename T37, typename T38, typename T39, typename T40, | |
1516 | typename T41, typename T42, typename T43, typename T44> | |
1517 | struct Types<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, | |
1518 | T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29, T30, | |
1519 | T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, T41, T42, T43, T44, | |
1520 | internal::None, internal::None, internal::None, internal::None, | |
1521 | internal::None, internal::None> { | |
1522 | typedef internal::Types44<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, | |
1523 | T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, | |
1524 | T27, T28, T29, T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, | |
1525 | T41, T42, T43, T44> type; | |
1526 | }; | |
1527 | template <typename T1, typename T2, typename T3, typename T4, typename T5, | |
1528 | typename T6, typename T7, typename T8, typename T9, typename T10, | |
1529 | typename T11, typename T12, typename T13, typename T14, typename T15, | |
1530 | typename T16, typename T17, typename T18, typename T19, typename T20, | |
1531 | typename T21, typename T22, typename T23, typename T24, typename T25, | |
1532 | typename T26, typename T27, typename T28, typename T29, typename T30, | |
1533 | typename T31, typename T32, typename T33, typename T34, typename T35, | |
1534 | typename T36, typename T37, typename T38, typename T39, typename T40, | |
1535 | typename T41, typename T42, typename T43, typename T44, typename T45> | |
1536 | struct Types<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, | |
1537 | T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29, T30, | |
1538 | T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, T41, T42, T43, T44, T45, | |
1539 | internal::None, internal::None, internal::None, internal::None, | |
1540 | internal::None> { | |
1541 | typedef internal::Types45<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, | |
1542 | T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, | |
1543 | T27, T28, T29, T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, | |
1544 | T41, T42, T43, T44, T45> type; | |
1545 | }; | |
1546 | template <typename T1, typename T2, typename T3, typename T4, typename T5, | |
1547 | typename T6, typename T7, typename T8, typename T9, typename T10, | |
1548 | typename T11, typename T12, typename T13, typename T14, typename T15, | |
1549 | typename T16, typename T17, typename T18, typename T19, typename T20, | |
1550 | typename T21, typename T22, typename T23, typename T24, typename T25, | |
1551 | typename T26, typename T27, typename T28, typename T29, typename T30, | |
1552 | typename T31, typename T32, typename T33, typename T34, typename T35, | |
1553 | typename T36, typename T37, typename T38, typename T39, typename T40, | |
1554 | typename T41, typename T42, typename T43, typename T44, typename T45, | |
1555 | typename T46> | |
1556 | struct Types<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, | |
1557 | T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29, T30, | |
1558 | T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, T41, T42, T43, T44, T45, | |
1559 | T46, internal::None, internal::None, internal::None, internal::None> { | |
1560 | typedef internal::Types46<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, | |
1561 | T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, | |
1562 | T27, T28, T29, T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, | |
1563 | T41, T42, T43, T44, T45, T46> type; | |
1564 | }; | |
1565 | template <typename T1, typename T2, typename T3, typename T4, typename T5, | |
1566 | typename T6, typename T7, typename T8, typename T9, typename T10, | |
1567 | typename T11, typename T12, typename T13, typename T14, typename T15, | |
1568 | typename T16, typename T17, typename T18, typename T19, typename T20, | |
1569 | typename T21, typename T22, typename T23, typename T24, typename T25, | |
1570 | typename T26, typename T27, typename T28, typename T29, typename T30, | |
1571 | typename T31, typename T32, typename T33, typename T34, typename T35, | |
1572 | typename T36, typename T37, typename T38, typename T39, typename T40, | |
1573 | typename T41, typename T42, typename T43, typename T44, typename T45, | |
1574 | typename T46, typename T47> | |
1575 | struct Types<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, | |
1576 | T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29, T30, | |
1577 | T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, T41, T42, T43, T44, T45, | |
1578 | T46, T47, internal::None, internal::None, internal::None> { | |
1579 | typedef internal::Types47<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, | |
1580 | T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, | |
1581 | T27, T28, T29, T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, | |
1582 | T41, T42, T43, T44, T45, T46, T47> type; | |
1583 | }; | |
1584 | template <typename T1, typename T2, typename T3, typename T4, typename T5, | |
1585 | typename T6, typename T7, typename T8, typename T9, typename T10, | |
1586 | typename T11, typename T12, typename T13, typename T14, typename T15, | |
1587 | typename T16, typename T17, typename T18, typename T19, typename T20, | |
1588 | typename T21, typename T22, typename T23, typename T24, typename T25, | |
1589 | typename T26, typename T27, typename T28, typename T29, typename T30, | |
1590 | typename T31, typename T32, typename T33, typename T34, typename T35, | |
1591 | typename T36, typename T37, typename T38, typename T39, typename T40, | |
1592 | typename T41, typename T42, typename T43, typename T44, typename T45, | |
1593 | typename T46, typename T47, typename T48> | |
1594 | struct Types<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, | |
1595 | T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29, T30, | |
1596 | T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, T41, T42, T43, T44, T45, | |
1597 | T46, T47, T48, internal::None, internal::None> { | |
1598 | typedef internal::Types48<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, | |
1599 | T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, | |
1600 | T27, T28, T29, T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, | |
1601 | T41, T42, T43, T44, T45, T46, T47, T48> type; | |
1602 | }; | |
1603 | template <typename T1, typename T2, typename T3, typename T4, typename T5, | |
1604 | typename T6, typename T7, typename T8, typename T9, typename T10, | |
1605 | typename T11, typename T12, typename T13, typename T14, typename T15, | |
1606 | typename T16, typename T17, typename T18, typename T19, typename T20, | |
1607 | typename T21, typename T22, typename T23, typename T24, typename T25, | |
1608 | typename T26, typename T27, typename T28, typename T29, typename T30, | |
1609 | typename T31, typename T32, typename T33, typename T34, typename T35, | |
1610 | typename T36, typename T37, typename T38, typename T39, typename T40, | |
1611 | typename T41, typename T42, typename T43, typename T44, typename T45, | |
1612 | typename T46, typename T47, typename T48, typename T49> | |
1613 | struct Types<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, | |
1614 | T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29, T30, | |
1615 | T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, T41, T42, T43, T44, T45, | |
1616 | T46, T47, T48, T49, internal::None> { | |
1617 | typedef internal::Types49<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, | |
1618 | T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, | |
1619 | T27, T28, T29, T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, | |
1620 | T41, T42, T43, T44, T45, T46, T47, T48, T49> type; | |
1621 | }; | |
1622 | ||
1623 | namespace internal { | |
1624 | 100 | |
1625 | 101 | # define GTEST_TEMPLATE_ template <typename T> class |
1626 | 102 | |
1643 | 119 | # define GTEST_BIND_(TmplSel, T) \ |
1644 | 120 | TmplSel::template Bind<T>::type |
1645 | 121 | |
1646 | // A unique struct template used as the default value for the | |
1647 | // arguments of class template Templates. This allows us to simulate | |
1648 | // variadic templates (e.g. Templates<int>, Templates<int, double>, | |
1649 | // and etc), which C++ doesn't support directly. | |
1650 | template <typename T> | |
1651 | struct NoneT {}; | |
1652 | ||
1653 | // The following family of struct and struct templates are used to | |
1654 | // represent template lists. In particular, TemplatesN<T1, T2, ..., | |
1655 | // TN> represents a list of N templates (T1, T2, ..., and TN). Except | |
1656 | // for Templates0, every struct in the family has two member types: | |
1657 | // Head for the selector of the first template in the list, and Tail | |
1658 | // for the rest of the list. | |
1659 | ||
1660 | // The empty template list. | |
1661 | struct Templates0 {}; | |
1662 | ||
1663 | // Template lists of length 1, 2, 3, and so on. | |
1664 | ||
1665 | template <GTEST_TEMPLATE_ T1> | |
1666 | struct Templates1 { | |
1667 | typedef TemplateSel<T1> Head; | |
1668 | typedef Templates0 Tail; | |
1669 | }; | |
1670 | template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2> | |
1671 | struct Templates2 { | |
1672 | typedef TemplateSel<T1> Head; | |
1673 | typedef Templates1<T2> Tail; | |
122 | template <GTEST_TEMPLATE_ Head_, GTEST_TEMPLATE_... Tail_> | |
123 | struct Templates { | |
124 | using Head = TemplateSel<Head_>; | |
125 | using Tail = Templates<Tail_...>; | |
1674 | 126 | }; |
1675 | 127 | |
1676 | template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3> | |
1677 | struct Templates3 { | |
1678 | typedef TemplateSel<T1> Head; | |
1679 | typedef Templates2<T2, T3> Tail; | |
128 | template <GTEST_TEMPLATE_ Head_> | |
129 | struct Templates<Head_> { | |
130 | using Head = TemplateSel<Head_>; | |
131 | using Tail = None; | |
1680 | 132 | }; |
1681 | 133 | |
1682 | template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3, | |
1683 | GTEST_TEMPLATE_ T4> | |
1684 | struct Templates4 { | |
1685 | typedef TemplateSel<T1> Head; | |
1686 | typedef Templates3<T2, T3, T4> Tail; | |
134 | // Tuple-like type lists | |
135 | template <typename Head_, typename... Tail_> | |
136 | struct Types { | |
137 | using Head = Head_; | |
138 | using Tail = Types<Tail_...>; | |
1687 | 139 | }; |
1688 | 140 | |
1689 | template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3, | |
1690 | GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5> | |
1691 | struct Templates5 { | |
1692 | typedef TemplateSel<T1> Head; | |
1693 | typedef Templates4<T2, T3, T4, T5> Tail; | |
141 | template <typename Head_> | |
142 | struct Types<Head_> { | |
143 | using Head = Head_; | |
144 | using Tail = None; | |
1694 | 145 | }; |
1695 | 146 | |
1696 | template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3, | |
1697 | GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6> | |
1698 | struct Templates6 { | |
1699 | typedef TemplateSel<T1> Head; | |
1700 | typedef Templates5<T2, T3, T4, T5, T6> Tail; | |
147 | // Helper metafunctions to tell apart a single type from types | |
148 | // generated by ::testing::Types | |
149 | template <typename... Ts> | |
150 | struct ProxyTypeList { | |
151 | using type = Types<Ts...>; | |
1701 | 152 | }; |
1702 | 153 | |
1703 | template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3, | |
1704 | GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6, | |
1705 | GTEST_TEMPLATE_ T7> | |
1706 | struct Templates7 { | |
1707 | typedef TemplateSel<T1> Head; | |
1708 | typedef Templates6<T2, T3, T4, T5, T6, T7> Tail; | |
1709 | }; | |
154 | template <typename> | |
155 | struct is_proxy_type_list : std::false_type {}; | |
1710 | 156 | |
1711 | template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3, | |
1712 | GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6, | |
1713 | GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8> | |
1714 | struct Templates8 { | |
1715 | typedef TemplateSel<T1> Head; | |
1716 | typedef Templates7<T2, T3, T4, T5, T6, T7, T8> Tail; | |
1717 | }; | |
157 | template <typename... Ts> | |
158 | struct is_proxy_type_list<ProxyTypeList<Ts...>> : std::true_type {}; | |
1718 | 159 | |
1719 | template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3, | |
1720 | GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6, | |
1721 | GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9> | |
1722 | struct Templates9 { | |
1723 | typedef TemplateSel<T1> Head; | |
1724 | typedef Templates8<T2, T3, T4, T5, T6, T7, T8, T9> Tail; | |
1725 | }; | |
160 | // Generator which conditionally creates type lists. | |
161 | // It recognizes if a requested type list should be created | |
162 | // and prevents creating a new type list nested within another one. | |
163 | template <typename T> | |
164 | struct GenerateTypeList { | |
165 | private: | |
166 | using proxy = typename std::conditional<is_proxy_type_list<T>::value, T, | |
167 | ProxyTypeList<T>>::type; | |
1726 | 168 | |
1727 | template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3, | |
1728 | GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6, | |
1729 | GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9, | |
1730 | GTEST_TEMPLATE_ T10> | |
1731 | struct Templates10 { | |
1732 | typedef TemplateSel<T1> Head; | |
1733 | typedef Templates9<T2, T3, T4, T5, T6, T7, T8, T9, T10> Tail; | |
1734 | }; | |
1735 | ||
1736 | template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3, | |
1737 | GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6, | |
1738 | GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9, | |
1739 | GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11> | |
1740 | struct Templates11 { | |
1741 | typedef TemplateSel<T1> Head; | |
1742 | typedef Templates10<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11> Tail; | |
1743 | }; | |
1744 | ||
1745 | template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3, | |
1746 | GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6, | |
1747 | GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9, | |
1748 | GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12> | |
1749 | struct Templates12 { | |
1750 | typedef TemplateSel<T1> Head; | |
1751 | typedef Templates11<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12> Tail; | |
1752 | }; | |
1753 | ||
1754 | template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3, | |
1755 | GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6, | |
1756 | GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9, | |
1757 | GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12, | |
1758 | GTEST_TEMPLATE_ T13> | |
1759 | struct Templates13 { | |
1760 | typedef TemplateSel<T1> Head; | |
1761 | typedef Templates12<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13> Tail; | |
1762 | }; | |
1763 | ||
1764 | template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3, | |
1765 | GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6, | |
1766 | GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9, | |
1767 | GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12, | |
1768 | GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14> | |
1769 | struct Templates14 { | |
1770 | typedef TemplateSel<T1> Head; | |
1771 | typedef Templates13<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, | |
1772 | T14> Tail; | |
1773 | }; | |
1774 | ||
1775 | template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3, | |
1776 | GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6, | |
1777 | GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9, | |
1778 | GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12, | |
1779 | GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15> | |
1780 | struct Templates15 { | |
1781 | typedef TemplateSel<T1> Head; | |
1782 | typedef Templates14<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, | |
1783 | T15> Tail; | |
1784 | }; | |
1785 | ||
1786 | template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3, | |
1787 | GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6, | |
1788 | GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9, | |
1789 | GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12, | |
1790 | GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15, | |
1791 | GTEST_TEMPLATE_ T16> | |
1792 | struct Templates16 { | |
1793 | typedef TemplateSel<T1> Head; | |
1794 | typedef Templates15<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, | |
1795 | T15, T16> Tail; | |
1796 | }; | |
1797 | ||
1798 | template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3, | |
1799 | GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6, | |
1800 | GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9, | |
1801 | GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12, | |
1802 | GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15, | |
1803 | GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17> | |
1804 | struct Templates17 { | |
1805 | typedef TemplateSel<T1> Head; | |
1806 | typedef Templates16<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, | |
1807 | T15, T16, T17> Tail; | |
1808 | }; | |
1809 | ||
1810 | template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3, | |
1811 | GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6, | |
1812 | GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9, | |
1813 | GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12, | |
1814 | GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15, | |
1815 | GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18> | |
1816 | struct Templates18 { | |
1817 | typedef TemplateSel<T1> Head; | |
1818 | typedef Templates17<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, | |
1819 | T15, T16, T17, T18> Tail; | |
1820 | }; | |
1821 | ||
1822 | template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3, | |
1823 | GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6, | |
1824 | GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9, | |
1825 | GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12, | |
1826 | GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15, | |
1827 | GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18, | |
1828 | GTEST_TEMPLATE_ T19> | |
1829 | struct Templates19 { | |
1830 | typedef TemplateSel<T1> Head; | |
1831 | typedef Templates18<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, | |
1832 | T15, T16, T17, T18, T19> Tail; | |
1833 | }; | |
1834 | ||
1835 | template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3, | |
1836 | GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6, | |
1837 | GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9, | |
1838 | GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12, | |
1839 | GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15, | |
1840 | GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18, | |
1841 | GTEST_TEMPLATE_ T19, GTEST_TEMPLATE_ T20> | |
1842 | struct Templates20 { | |
1843 | typedef TemplateSel<T1> Head; | |
1844 | typedef Templates19<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, | |
1845 | T15, T16, T17, T18, T19, T20> Tail; | |
1846 | }; | |
1847 | ||
1848 | template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3, | |
1849 | GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6, | |
1850 | GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9, | |
1851 | GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12, | |
1852 | GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15, | |
1853 | GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18, | |
1854 | GTEST_TEMPLATE_ T19, GTEST_TEMPLATE_ T20, GTEST_TEMPLATE_ T21> | |
1855 | struct Templates21 { | |
1856 | typedef TemplateSel<T1> Head; | |
1857 | typedef Templates20<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, | |
1858 | T15, T16, T17, T18, T19, T20, T21> Tail; | |
1859 | }; | |
1860 | ||
1861 | template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3, | |
1862 | GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6, | |
1863 | GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9, | |
1864 | GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12, | |
1865 | GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15, | |
1866 | GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18, | |
1867 | GTEST_TEMPLATE_ T19, GTEST_TEMPLATE_ T20, GTEST_TEMPLATE_ T21, | |
1868 | GTEST_TEMPLATE_ T22> | |
1869 | struct Templates22 { | |
1870 | typedef TemplateSel<T1> Head; | |
1871 | typedef Templates21<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, | |
1872 | T15, T16, T17, T18, T19, T20, T21, T22> Tail; | |
1873 | }; | |
1874 | ||
1875 | template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3, | |
1876 | GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6, | |
1877 | GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9, | |
1878 | GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12, | |
1879 | GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15, | |
1880 | GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18, | |
1881 | GTEST_TEMPLATE_ T19, GTEST_TEMPLATE_ T20, GTEST_TEMPLATE_ T21, | |
1882 | GTEST_TEMPLATE_ T22, GTEST_TEMPLATE_ T23> | |
1883 | struct Templates23 { | |
1884 | typedef TemplateSel<T1> Head; | |
1885 | typedef Templates22<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, | |
1886 | T15, T16, T17, T18, T19, T20, T21, T22, T23> Tail; | |
1887 | }; | |
1888 | ||
1889 | template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3, | |
1890 | GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6, | |
1891 | GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9, | |
1892 | GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12, | |
1893 | GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15, | |
1894 | GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18, | |
1895 | GTEST_TEMPLATE_ T19, GTEST_TEMPLATE_ T20, GTEST_TEMPLATE_ T21, | |
1896 | GTEST_TEMPLATE_ T22, GTEST_TEMPLATE_ T23, GTEST_TEMPLATE_ T24> | |
1897 | struct Templates24 { | |
1898 | typedef TemplateSel<T1> Head; | |
1899 | typedef Templates23<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, | |
1900 | T15, T16, T17, T18, T19, T20, T21, T22, T23, T24> Tail; | |
1901 | }; | |
1902 | ||
1903 | template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3, | |
1904 | GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6, | |
1905 | GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9, | |
1906 | GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12, | |
1907 | GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15, | |
1908 | GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18, | |
1909 | GTEST_TEMPLATE_ T19, GTEST_TEMPLATE_ T20, GTEST_TEMPLATE_ T21, | |
1910 | GTEST_TEMPLATE_ T22, GTEST_TEMPLATE_ T23, GTEST_TEMPLATE_ T24, | |
1911 | GTEST_TEMPLATE_ T25> | |
1912 | struct Templates25 { | |
1913 | typedef TemplateSel<T1> Head; | |
1914 | typedef Templates24<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, | |
1915 | T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25> Tail; | |
1916 | }; | |
1917 | ||
1918 | template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3, | |
1919 | GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6, | |
1920 | GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9, | |
1921 | GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12, | |
1922 | GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15, | |
1923 | GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18, | |
1924 | GTEST_TEMPLATE_ T19, GTEST_TEMPLATE_ T20, GTEST_TEMPLATE_ T21, | |
1925 | GTEST_TEMPLATE_ T22, GTEST_TEMPLATE_ T23, GTEST_TEMPLATE_ T24, | |
1926 | GTEST_TEMPLATE_ T25, GTEST_TEMPLATE_ T26> | |
1927 | struct Templates26 { | |
1928 | typedef TemplateSel<T1> Head; | |
1929 | typedef Templates25<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, | |
1930 | T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26> Tail; | |
1931 | }; | |
1932 | ||
1933 | template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3, | |
1934 | GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6, | |
1935 | GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9, | |
1936 | GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12, | |
1937 | GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15, | |
1938 | GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18, | |
1939 | GTEST_TEMPLATE_ T19, GTEST_TEMPLATE_ T20, GTEST_TEMPLATE_ T21, | |
1940 | GTEST_TEMPLATE_ T22, GTEST_TEMPLATE_ T23, GTEST_TEMPLATE_ T24, | |
1941 | GTEST_TEMPLATE_ T25, GTEST_TEMPLATE_ T26, GTEST_TEMPLATE_ T27> | |
1942 | struct Templates27 { | |
1943 | typedef TemplateSel<T1> Head; | |
1944 | typedef Templates26<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, | |
1945 | T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27> Tail; | |
1946 | }; | |
1947 | ||
1948 | template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3, | |
1949 | GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6, | |
1950 | GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9, | |
1951 | GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12, | |
1952 | GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15, | |
1953 | GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18, | |
1954 | GTEST_TEMPLATE_ T19, GTEST_TEMPLATE_ T20, GTEST_TEMPLATE_ T21, | |
1955 | GTEST_TEMPLATE_ T22, GTEST_TEMPLATE_ T23, GTEST_TEMPLATE_ T24, | |
1956 | GTEST_TEMPLATE_ T25, GTEST_TEMPLATE_ T26, GTEST_TEMPLATE_ T27, | |
1957 | GTEST_TEMPLATE_ T28> | |
1958 | struct Templates28 { | |
1959 | typedef TemplateSel<T1> Head; | |
1960 | typedef Templates27<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, | |
1961 | T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, | |
1962 | T28> Tail; | |
1963 | }; | |
1964 | ||
1965 | template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3, | |
1966 | GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6, | |
1967 | GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9, | |
1968 | GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12, | |
1969 | GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15, | |
1970 | GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18, | |
1971 | GTEST_TEMPLATE_ T19, GTEST_TEMPLATE_ T20, GTEST_TEMPLATE_ T21, | |
1972 | GTEST_TEMPLATE_ T22, GTEST_TEMPLATE_ T23, GTEST_TEMPLATE_ T24, | |
1973 | GTEST_TEMPLATE_ T25, GTEST_TEMPLATE_ T26, GTEST_TEMPLATE_ T27, | |
1974 | GTEST_TEMPLATE_ T28, GTEST_TEMPLATE_ T29> | |
1975 | struct Templates29 { | |
1976 | typedef TemplateSel<T1> Head; | |
1977 | typedef Templates28<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, | |
1978 | T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, | |
1979 | T29> Tail; | |
1980 | }; | |
1981 | ||
1982 | template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3, | |
1983 | GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6, | |
1984 | GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9, | |
1985 | GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12, | |
1986 | GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15, | |
1987 | GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18, | |
1988 | GTEST_TEMPLATE_ T19, GTEST_TEMPLATE_ T20, GTEST_TEMPLATE_ T21, | |
1989 | GTEST_TEMPLATE_ T22, GTEST_TEMPLATE_ T23, GTEST_TEMPLATE_ T24, | |
1990 | GTEST_TEMPLATE_ T25, GTEST_TEMPLATE_ T26, GTEST_TEMPLATE_ T27, | |
1991 | GTEST_TEMPLATE_ T28, GTEST_TEMPLATE_ T29, GTEST_TEMPLATE_ T30> | |
1992 | struct Templates30 { | |
1993 | typedef TemplateSel<T1> Head; | |
1994 | typedef Templates29<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, | |
1995 | T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, | |
1996 | T29, T30> Tail; | |
1997 | }; | |
1998 | ||
1999 | template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3, | |
2000 | GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6, | |
2001 | GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9, | |
2002 | GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12, | |
2003 | GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15, | |
2004 | GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18, | |
2005 | GTEST_TEMPLATE_ T19, GTEST_TEMPLATE_ T20, GTEST_TEMPLATE_ T21, | |
2006 | GTEST_TEMPLATE_ T22, GTEST_TEMPLATE_ T23, GTEST_TEMPLATE_ T24, | |
2007 | GTEST_TEMPLATE_ T25, GTEST_TEMPLATE_ T26, GTEST_TEMPLATE_ T27, | |
2008 | GTEST_TEMPLATE_ T28, GTEST_TEMPLATE_ T29, GTEST_TEMPLATE_ T30, | |
2009 | GTEST_TEMPLATE_ T31> | |
2010 | struct Templates31 { | |
2011 | typedef TemplateSel<T1> Head; | |
2012 | typedef Templates30<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, | |
2013 | T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, | |
2014 | T29, T30, T31> Tail; | |
2015 | }; | |
2016 | ||
2017 | template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3, | |
2018 | GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6, | |
2019 | GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9, | |
2020 | GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12, | |
2021 | GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15, | |
2022 | GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18, | |
2023 | GTEST_TEMPLATE_ T19, GTEST_TEMPLATE_ T20, GTEST_TEMPLATE_ T21, | |
2024 | GTEST_TEMPLATE_ T22, GTEST_TEMPLATE_ T23, GTEST_TEMPLATE_ T24, | |
2025 | GTEST_TEMPLATE_ T25, GTEST_TEMPLATE_ T26, GTEST_TEMPLATE_ T27, | |
2026 | GTEST_TEMPLATE_ T28, GTEST_TEMPLATE_ T29, GTEST_TEMPLATE_ T30, | |
2027 | GTEST_TEMPLATE_ T31, GTEST_TEMPLATE_ T32> | |
2028 | struct Templates32 { | |
2029 | typedef TemplateSel<T1> Head; | |
2030 | typedef Templates31<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, | |
2031 | T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, | |
2032 | T29, T30, T31, T32> Tail; | |
2033 | }; | |
2034 | ||
2035 | template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3, | |
2036 | GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6, | |
2037 | GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9, | |
2038 | GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12, | |
2039 | GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15, | |
2040 | GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18, | |
2041 | GTEST_TEMPLATE_ T19, GTEST_TEMPLATE_ T20, GTEST_TEMPLATE_ T21, | |
2042 | GTEST_TEMPLATE_ T22, GTEST_TEMPLATE_ T23, GTEST_TEMPLATE_ T24, | |
2043 | GTEST_TEMPLATE_ T25, GTEST_TEMPLATE_ T26, GTEST_TEMPLATE_ T27, | |
2044 | GTEST_TEMPLATE_ T28, GTEST_TEMPLATE_ T29, GTEST_TEMPLATE_ T30, | |
2045 | GTEST_TEMPLATE_ T31, GTEST_TEMPLATE_ T32, GTEST_TEMPLATE_ T33> | |
2046 | struct Templates33 { | |
2047 | typedef TemplateSel<T1> Head; | |
2048 | typedef Templates32<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, | |
2049 | T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, | |
2050 | T29, T30, T31, T32, T33> Tail; | |
2051 | }; | |
2052 | ||
2053 | template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3, | |
2054 | GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6, | |
2055 | GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9, | |
2056 | GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12, | |
2057 | GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15, | |
2058 | GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18, | |
2059 | GTEST_TEMPLATE_ T19, GTEST_TEMPLATE_ T20, GTEST_TEMPLATE_ T21, | |
2060 | GTEST_TEMPLATE_ T22, GTEST_TEMPLATE_ T23, GTEST_TEMPLATE_ T24, | |
2061 | GTEST_TEMPLATE_ T25, GTEST_TEMPLATE_ T26, GTEST_TEMPLATE_ T27, | |
2062 | GTEST_TEMPLATE_ T28, GTEST_TEMPLATE_ T29, GTEST_TEMPLATE_ T30, | |
2063 | GTEST_TEMPLATE_ T31, GTEST_TEMPLATE_ T32, GTEST_TEMPLATE_ T33, | |
2064 | GTEST_TEMPLATE_ T34> | |
2065 | struct Templates34 { | |
2066 | typedef TemplateSel<T1> Head; | |
2067 | typedef Templates33<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, | |
2068 | T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, | |
2069 | T29, T30, T31, T32, T33, T34> Tail; | |
2070 | }; | |
2071 | ||
2072 | template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3, | |
2073 | GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6, | |
2074 | GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9, | |
2075 | GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12, | |
2076 | GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15, | |
2077 | GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18, | |
2078 | GTEST_TEMPLATE_ T19, GTEST_TEMPLATE_ T20, GTEST_TEMPLATE_ T21, | |
2079 | GTEST_TEMPLATE_ T22, GTEST_TEMPLATE_ T23, GTEST_TEMPLATE_ T24, | |
2080 | GTEST_TEMPLATE_ T25, GTEST_TEMPLATE_ T26, GTEST_TEMPLATE_ T27, | |
2081 | GTEST_TEMPLATE_ T28, GTEST_TEMPLATE_ T29, GTEST_TEMPLATE_ T30, | |
2082 | GTEST_TEMPLATE_ T31, GTEST_TEMPLATE_ T32, GTEST_TEMPLATE_ T33, | |
2083 | GTEST_TEMPLATE_ T34, GTEST_TEMPLATE_ T35> | |
2084 | struct Templates35 { | |
2085 | typedef TemplateSel<T1> Head; | |
2086 | typedef Templates34<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, | |
2087 | T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, | |
2088 | T29, T30, T31, T32, T33, T34, T35> Tail; | |
2089 | }; | |
2090 | ||
2091 | template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3, | |
2092 | GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6, | |
2093 | GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9, | |
2094 | GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12, | |
2095 | GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15, | |
2096 | GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18, | |
2097 | GTEST_TEMPLATE_ T19, GTEST_TEMPLATE_ T20, GTEST_TEMPLATE_ T21, | |
2098 | GTEST_TEMPLATE_ T22, GTEST_TEMPLATE_ T23, GTEST_TEMPLATE_ T24, | |
2099 | GTEST_TEMPLATE_ T25, GTEST_TEMPLATE_ T26, GTEST_TEMPLATE_ T27, | |
2100 | GTEST_TEMPLATE_ T28, GTEST_TEMPLATE_ T29, GTEST_TEMPLATE_ T30, | |
2101 | GTEST_TEMPLATE_ T31, GTEST_TEMPLATE_ T32, GTEST_TEMPLATE_ T33, | |
2102 | GTEST_TEMPLATE_ T34, GTEST_TEMPLATE_ T35, GTEST_TEMPLATE_ T36> | |
2103 | struct Templates36 { | |
2104 | typedef TemplateSel<T1> Head; | |
2105 | typedef Templates35<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, | |
2106 | T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, | |
2107 | T29, T30, T31, T32, T33, T34, T35, T36> Tail; | |
2108 | }; | |
2109 | ||
2110 | template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3, | |
2111 | GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6, | |
2112 | GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9, | |
2113 | GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12, | |
2114 | GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15, | |
2115 | GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18, | |
2116 | GTEST_TEMPLATE_ T19, GTEST_TEMPLATE_ T20, GTEST_TEMPLATE_ T21, | |
2117 | GTEST_TEMPLATE_ T22, GTEST_TEMPLATE_ T23, GTEST_TEMPLATE_ T24, | |
2118 | GTEST_TEMPLATE_ T25, GTEST_TEMPLATE_ T26, GTEST_TEMPLATE_ T27, | |
2119 | GTEST_TEMPLATE_ T28, GTEST_TEMPLATE_ T29, GTEST_TEMPLATE_ T30, | |
2120 | GTEST_TEMPLATE_ T31, GTEST_TEMPLATE_ T32, GTEST_TEMPLATE_ T33, | |
2121 | GTEST_TEMPLATE_ T34, GTEST_TEMPLATE_ T35, GTEST_TEMPLATE_ T36, | |
2122 | GTEST_TEMPLATE_ T37> | |
2123 | struct Templates37 { | |
2124 | typedef TemplateSel<T1> Head; | |
2125 | typedef Templates36<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, | |
2126 | T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, | |
2127 | T29, T30, T31, T32, T33, T34, T35, T36, T37> Tail; | |
2128 | }; | |
2129 | ||
2130 | template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3, | |
2131 | GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6, | |
2132 | GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9, | |
2133 | GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12, | |
2134 | GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15, | |
2135 | GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18, | |
2136 | GTEST_TEMPLATE_ T19, GTEST_TEMPLATE_ T20, GTEST_TEMPLATE_ T21, | |
2137 | GTEST_TEMPLATE_ T22, GTEST_TEMPLATE_ T23, GTEST_TEMPLATE_ T24, | |
2138 | GTEST_TEMPLATE_ T25, GTEST_TEMPLATE_ T26, GTEST_TEMPLATE_ T27, | |
2139 | GTEST_TEMPLATE_ T28, GTEST_TEMPLATE_ T29, GTEST_TEMPLATE_ T30, | |
2140 | GTEST_TEMPLATE_ T31, GTEST_TEMPLATE_ T32, GTEST_TEMPLATE_ T33, | |
2141 | GTEST_TEMPLATE_ T34, GTEST_TEMPLATE_ T35, GTEST_TEMPLATE_ T36, | |
2142 | GTEST_TEMPLATE_ T37, GTEST_TEMPLATE_ T38> | |
2143 | struct Templates38 { | |
2144 | typedef TemplateSel<T1> Head; | |
2145 | typedef Templates37<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, | |
2146 | T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, | |
2147 | T29, T30, T31, T32, T33, T34, T35, T36, T37, T38> Tail; | |
2148 | }; | |
2149 | ||
2150 | template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3, | |
2151 | GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6, | |
2152 | GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9, | |
2153 | GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12, | |
2154 | GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15, | |
2155 | GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18, | |
2156 | GTEST_TEMPLATE_ T19, GTEST_TEMPLATE_ T20, GTEST_TEMPLATE_ T21, | |
2157 | GTEST_TEMPLATE_ T22, GTEST_TEMPLATE_ T23, GTEST_TEMPLATE_ T24, | |
2158 | GTEST_TEMPLATE_ T25, GTEST_TEMPLATE_ T26, GTEST_TEMPLATE_ T27, | |
2159 | GTEST_TEMPLATE_ T28, GTEST_TEMPLATE_ T29, GTEST_TEMPLATE_ T30, | |
2160 | GTEST_TEMPLATE_ T31, GTEST_TEMPLATE_ T32, GTEST_TEMPLATE_ T33, | |
2161 | GTEST_TEMPLATE_ T34, GTEST_TEMPLATE_ T35, GTEST_TEMPLATE_ T36, | |
2162 | GTEST_TEMPLATE_ T37, GTEST_TEMPLATE_ T38, GTEST_TEMPLATE_ T39> | |
2163 | struct Templates39 { | |
2164 | typedef TemplateSel<T1> Head; | |
2165 | typedef Templates38<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, | |
2166 | T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, | |
2167 | T29, T30, T31, T32, T33, T34, T35, T36, T37, T38, T39> Tail; | |
2168 | }; | |
2169 | ||
2170 | template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3, | |
2171 | GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6, | |
2172 | GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9, | |
2173 | GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12, | |
2174 | GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15, | |
2175 | GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18, | |
2176 | GTEST_TEMPLATE_ T19, GTEST_TEMPLATE_ T20, GTEST_TEMPLATE_ T21, | |
2177 | GTEST_TEMPLATE_ T22, GTEST_TEMPLATE_ T23, GTEST_TEMPLATE_ T24, | |
2178 | GTEST_TEMPLATE_ T25, GTEST_TEMPLATE_ T26, GTEST_TEMPLATE_ T27, | |
2179 | GTEST_TEMPLATE_ T28, GTEST_TEMPLATE_ T29, GTEST_TEMPLATE_ T30, | |
2180 | GTEST_TEMPLATE_ T31, GTEST_TEMPLATE_ T32, GTEST_TEMPLATE_ T33, | |
2181 | GTEST_TEMPLATE_ T34, GTEST_TEMPLATE_ T35, GTEST_TEMPLATE_ T36, | |
2182 | GTEST_TEMPLATE_ T37, GTEST_TEMPLATE_ T38, GTEST_TEMPLATE_ T39, | |
2183 | GTEST_TEMPLATE_ T40> | |
2184 | struct Templates40 { | |
2185 | typedef TemplateSel<T1> Head; | |
2186 | typedef Templates39<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, | |
2187 | T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, | |
2188 | T29, T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40> Tail; | |
2189 | }; | |
2190 | ||
2191 | template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3, | |
2192 | GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6, | |
2193 | GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9, | |
2194 | GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12, | |
2195 | GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15, | |
2196 | GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18, | |
2197 | GTEST_TEMPLATE_ T19, GTEST_TEMPLATE_ T20, GTEST_TEMPLATE_ T21, | |
2198 | GTEST_TEMPLATE_ T22, GTEST_TEMPLATE_ T23, GTEST_TEMPLATE_ T24, | |
2199 | GTEST_TEMPLATE_ T25, GTEST_TEMPLATE_ T26, GTEST_TEMPLATE_ T27, | |
2200 | GTEST_TEMPLATE_ T28, GTEST_TEMPLATE_ T29, GTEST_TEMPLATE_ T30, | |
2201 | GTEST_TEMPLATE_ T31, GTEST_TEMPLATE_ T32, GTEST_TEMPLATE_ T33, | |
2202 | GTEST_TEMPLATE_ T34, GTEST_TEMPLATE_ T35, GTEST_TEMPLATE_ T36, | |
2203 | GTEST_TEMPLATE_ T37, GTEST_TEMPLATE_ T38, GTEST_TEMPLATE_ T39, | |
2204 | GTEST_TEMPLATE_ T40, GTEST_TEMPLATE_ T41> | |
2205 | struct Templates41 { | |
2206 | typedef TemplateSel<T1> Head; | |
2207 | typedef Templates40<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, | |
2208 | T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, | |
2209 | T29, T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, T41> Tail; | |
2210 | }; | |
2211 | ||
2212 | template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3, | |
2213 | GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6, | |
2214 | GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9, | |
2215 | GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12, | |
2216 | GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15, | |
2217 | GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18, | |
2218 | GTEST_TEMPLATE_ T19, GTEST_TEMPLATE_ T20, GTEST_TEMPLATE_ T21, | |
2219 | GTEST_TEMPLATE_ T22, GTEST_TEMPLATE_ T23, GTEST_TEMPLATE_ T24, | |
2220 | GTEST_TEMPLATE_ T25, GTEST_TEMPLATE_ T26, GTEST_TEMPLATE_ T27, | |
2221 | GTEST_TEMPLATE_ T28, GTEST_TEMPLATE_ T29, GTEST_TEMPLATE_ T30, | |
2222 | GTEST_TEMPLATE_ T31, GTEST_TEMPLATE_ T32, GTEST_TEMPLATE_ T33, | |
2223 | GTEST_TEMPLATE_ T34, GTEST_TEMPLATE_ T35, GTEST_TEMPLATE_ T36, | |
2224 | GTEST_TEMPLATE_ T37, GTEST_TEMPLATE_ T38, GTEST_TEMPLATE_ T39, | |
2225 | GTEST_TEMPLATE_ T40, GTEST_TEMPLATE_ T41, GTEST_TEMPLATE_ T42> | |
2226 | struct Templates42 { | |
2227 | typedef TemplateSel<T1> Head; | |
2228 | typedef Templates41<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, | |
2229 | T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, | |
2230 | T29, T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, T41, | |
2231 | T42> Tail; | |
2232 | }; | |
2233 | ||
2234 | template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3, | |
2235 | GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6, | |
2236 | GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9, | |
2237 | GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12, | |
2238 | GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15, | |
2239 | GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18, | |
2240 | GTEST_TEMPLATE_ T19, GTEST_TEMPLATE_ T20, GTEST_TEMPLATE_ T21, | |
2241 | GTEST_TEMPLATE_ T22, GTEST_TEMPLATE_ T23, GTEST_TEMPLATE_ T24, | |
2242 | GTEST_TEMPLATE_ T25, GTEST_TEMPLATE_ T26, GTEST_TEMPLATE_ T27, | |
2243 | GTEST_TEMPLATE_ T28, GTEST_TEMPLATE_ T29, GTEST_TEMPLATE_ T30, | |
2244 | GTEST_TEMPLATE_ T31, GTEST_TEMPLATE_ T32, GTEST_TEMPLATE_ T33, | |
2245 | GTEST_TEMPLATE_ T34, GTEST_TEMPLATE_ T35, GTEST_TEMPLATE_ T36, | |
2246 | GTEST_TEMPLATE_ T37, GTEST_TEMPLATE_ T38, GTEST_TEMPLATE_ T39, | |
2247 | GTEST_TEMPLATE_ T40, GTEST_TEMPLATE_ T41, GTEST_TEMPLATE_ T42, | |
2248 | GTEST_TEMPLATE_ T43> | |
2249 | struct Templates43 { | |
2250 | typedef TemplateSel<T1> Head; | |
2251 | typedef Templates42<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, | |
2252 | T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, | |
2253 | T29, T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, T41, T42, | |
2254 | T43> Tail; | |
2255 | }; | |
2256 | ||
2257 | template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3, | |
2258 | GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6, | |
2259 | GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9, | |
2260 | GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12, | |
2261 | GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15, | |
2262 | GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18, | |
2263 | GTEST_TEMPLATE_ T19, GTEST_TEMPLATE_ T20, GTEST_TEMPLATE_ T21, | |
2264 | GTEST_TEMPLATE_ T22, GTEST_TEMPLATE_ T23, GTEST_TEMPLATE_ T24, | |
2265 | GTEST_TEMPLATE_ T25, GTEST_TEMPLATE_ T26, GTEST_TEMPLATE_ T27, | |
2266 | GTEST_TEMPLATE_ T28, GTEST_TEMPLATE_ T29, GTEST_TEMPLATE_ T30, | |
2267 | GTEST_TEMPLATE_ T31, GTEST_TEMPLATE_ T32, GTEST_TEMPLATE_ T33, | |
2268 | GTEST_TEMPLATE_ T34, GTEST_TEMPLATE_ T35, GTEST_TEMPLATE_ T36, | |
2269 | GTEST_TEMPLATE_ T37, GTEST_TEMPLATE_ T38, GTEST_TEMPLATE_ T39, | |
2270 | GTEST_TEMPLATE_ T40, GTEST_TEMPLATE_ T41, GTEST_TEMPLATE_ T42, | |
2271 | GTEST_TEMPLATE_ T43, GTEST_TEMPLATE_ T44> | |
2272 | struct Templates44 { | |
2273 | typedef TemplateSel<T1> Head; | |
2274 | typedef Templates43<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, | |
2275 | T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, | |
2276 | T29, T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, T41, T42, | |
2277 | T43, T44> Tail; | |
2278 | }; | |
2279 | ||
2280 | template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3, | |
2281 | GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6, | |
2282 | GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9, | |
2283 | GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12, | |
2284 | GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15, | |
2285 | GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18, | |
2286 | GTEST_TEMPLATE_ T19, GTEST_TEMPLATE_ T20, GTEST_TEMPLATE_ T21, | |
2287 | GTEST_TEMPLATE_ T22, GTEST_TEMPLATE_ T23, GTEST_TEMPLATE_ T24, | |
2288 | GTEST_TEMPLATE_ T25, GTEST_TEMPLATE_ T26, GTEST_TEMPLATE_ T27, | |
2289 | GTEST_TEMPLATE_ T28, GTEST_TEMPLATE_ T29, GTEST_TEMPLATE_ T30, | |
2290 | GTEST_TEMPLATE_ T31, GTEST_TEMPLATE_ T32, GTEST_TEMPLATE_ T33, | |
2291 | GTEST_TEMPLATE_ T34, GTEST_TEMPLATE_ T35, GTEST_TEMPLATE_ T36, | |
2292 | GTEST_TEMPLATE_ T37, GTEST_TEMPLATE_ T38, GTEST_TEMPLATE_ T39, | |
2293 | GTEST_TEMPLATE_ T40, GTEST_TEMPLATE_ T41, GTEST_TEMPLATE_ T42, | |
2294 | GTEST_TEMPLATE_ T43, GTEST_TEMPLATE_ T44, GTEST_TEMPLATE_ T45> | |
2295 | struct Templates45 { | |
2296 | typedef TemplateSel<T1> Head; | |
2297 | typedef Templates44<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, | |
2298 | T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, | |
2299 | T29, T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, T41, T42, | |
2300 | T43, T44, T45> Tail; | |
2301 | }; | |
2302 | ||
2303 | template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3, | |
2304 | GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6, | |
2305 | GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9, | |
2306 | GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12, | |
2307 | GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15, | |
2308 | GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18, | |
2309 | GTEST_TEMPLATE_ T19, GTEST_TEMPLATE_ T20, GTEST_TEMPLATE_ T21, | |
2310 | GTEST_TEMPLATE_ T22, GTEST_TEMPLATE_ T23, GTEST_TEMPLATE_ T24, | |
2311 | GTEST_TEMPLATE_ T25, GTEST_TEMPLATE_ T26, GTEST_TEMPLATE_ T27, | |
2312 | GTEST_TEMPLATE_ T28, GTEST_TEMPLATE_ T29, GTEST_TEMPLATE_ T30, | |
2313 | GTEST_TEMPLATE_ T31, GTEST_TEMPLATE_ T32, GTEST_TEMPLATE_ T33, | |
2314 | GTEST_TEMPLATE_ T34, GTEST_TEMPLATE_ T35, GTEST_TEMPLATE_ T36, | |
2315 | GTEST_TEMPLATE_ T37, GTEST_TEMPLATE_ T38, GTEST_TEMPLATE_ T39, | |
2316 | GTEST_TEMPLATE_ T40, GTEST_TEMPLATE_ T41, GTEST_TEMPLATE_ T42, | |
2317 | GTEST_TEMPLATE_ T43, GTEST_TEMPLATE_ T44, GTEST_TEMPLATE_ T45, | |
2318 | GTEST_TEMPLATE_ T46> | |
2319 | struct Templates46 { | |
2320 | typedef TemplateSel<T1> Head; | |
2321 | typedef Templates45<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, | |
2322 | T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, | |
2323 | T29, T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, T41, T42, | |
2324 | T43, T44, T45, T46> Tail; | |
2325 | }; | |
2326 | ||
2327 | template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3, | |
2328 | GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6, | |
2329 | GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9, | |
2330 | GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12, | |
2331 | GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15, | |
2332 | GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18, | |
2333 | GTEST_TEMPLATE_ T19, GTEST_TEMPLATE_ T20, GTEST_TEMPLATE_ T21, | |
2334 | GTEST_TEMPLATE_ T22, GTEST_TEMPLATE_ T23, GTEST_TEMPLATE_ T24, | |
2335 | GTEST_TEMPLATE_ T25, GTEST_TEMPLATE_ T26, GTEST_TEMPLATE_ T27, | |
2336 | GTEST_TEMPLATE_ T28, GTEST_TEMPLATE_ T29, GTEST_TEMPLATE_ T30, | |
2337 | GTEST_TEMPLATE_ T31, GTEST_TEMPLATE_ T32, GTEST_TEMPLATE_ T33, | |
2338 | GTEST_TEMPLATE_ T34, GTEST_TEMPLATE_ T35, GTEST_TEMPLATE_ T36, | |
2339 | GTEST_TEMPLATE_ T37, GTEST_TEMPLATE_ T38, GTEST_TEMPLATE_ T39, | |
2340 | GTEST_TEMPLATE_ T40, GTEST_TEMPLATE_ T41, GTEST_TEMPLATE_ T42, | |
2341 | GTEST_TEMPLATE_ T43, GTEST_TEMPLATE_ T44, GTEST_TEMPLATE_ T45, | |
2342 | GTEST_TEMPLATE_ T46, GTEST_TEMPLATE_ T47> | |
2343 | struct Templates47 { | |
2344 | typedef TemplateSel<T1> Head; | |
2345 | typedef Templates46<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, | |
2346 | T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, | |
2347 | T29, T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, T41, T42, | |
2348 | T43, T44, T45, T46, T47> Tail; | |
2349 | }; | |
2350 | ||
2351 | template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3, | |
2352 | GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6, | |
2353 | GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9, | |
2354 | GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12, | |
2355 | GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15, | |
2356 | GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18, | |
2357 | GTEST_TEMPLATE_ T19, GTEST_TEMPLATE_ T20, GTEST_TEMPLATE_ T21, | |
2358 | GTEST_TEMPLATE_ T22, GTEST_TEMPLATE_ T23, GTEST_TEMPLATE_ T24, | |
2359 | GTEST_TEMPLATE_ T25, GTEST_TEMPLATE_ T26, GTEST_TEMPLATE_ T27, | |
2360 | GTEST_TEMPLATE_ T28, GTEST_TEMPLATE_ T29, GTEST_TEMPLATE_ T30, | |
2361 | GTEST_TEMPLATE_ T31, GTEST_TEMPLATE_ T32, GTEST_TEMPLATE_ T33, | |
2362 | GTEST_TEMPLATE_ T34, GTEST_TEMPLATE_ T35, GTEST_TEMPLATE_ T36, | |
2363 | GTEST_TEMPLATE_ T37, GTEST_TEMPLATE_ T38, GTEST_TEMPLATE_ T39, | |
2364 | GTEST_TEMPLATE_ T40, GTEST_TEMPLATE_ T41, GTEST_TEMPLATE_ T42, | |
2365 | GTEST_TEMPLATE_ T43, GTEST_TEMPLATE_ T44, GTEST_TEMPLATE_ T45, | |
2366 | GTEST_TEMPLATE_ T46, GTEST_TEMPLATE_ T47, GTEST_TEMPLATE_ T48> | |
2367 | struct Templates48 { | |
2368 | typedef TemplateSel<T1> Head; | |
2369 | typedef Templates47<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, | |
2370 | T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, | |
2371 | T29, T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, T41, T42, | |
2372 | T43, T44, T45, T46, T47, T48> Tail; | |
2373 | }; | |
2374 | ||
2375 | template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3, | |
2376 | GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6, | |
2377 | GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9, | |
2378 | GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12, | |
2379 | GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15, | |
2380 | GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18, | |
2381 | GTEST_TEMPLATE_ T19, GTEST_TEMPLATE_ T20, GTEST_TEMPLATE_ T21, | |
2382 | GTEST_TEMPLATE_ T22, GTEST_TEMPLATE_ T23, GTEST_TEMPLATE_ T24, | |
2383 | GTEST_TEMPLATE_ T25, GTEST_TEMPLATE_ T26, GTEST_TEMPLATE_ T27, | |
2384 | GTEST_TEMPLATE_ T28, GTEST_TEMPLATE_ T29, GTEST_TEMPLATE_ T30, | |
2385 | GTEST_TEMPLATE_ T31, GTEST_TEMPLATE_ T32, GTEST_TEMPLATE_ T33, | |
2386 | GTEST_TEMPLATE_ T34, GTEST_TEMPLATE_ T35, GTEST_TEMPLATE_ T36, | |
2387 | GTEST_TEMPLATE_ T37, GTEST_TEMPLATE_ T38, GTEST_TEMPLATE_ T39, | |
2388 | GTEST_TEMPLATE_ T40, GTEST_TEMPLATE_ T41, GTEST_TEMPLATE_ T42, | |
2389 | GTEST_TEMPLATE_ T43, GTEST_TEMPLATE_ T44, GTEST_TEMPLATE_ T45, | |
2390 | GTEST_TEMPLATE_ T46, GTEST_TEMPLATE_ T47, GTEST_TEMPLATE_ T48, | |
2391 | GTEST_TEMPLATE_ T49> | |
2392 | struct Templates49 { | |
2393 | typedef TemplateSel<T1> Head; | |
2394 | typedef Templates48<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, | |
2395 | T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, | |
2396 | T29, T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, T41, T42, | |
2397 | T43, T44, T45, T46, T47, T48, T49> Tail; | |
2398 | }; | |
2399 | ||
2400 | template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3, | |
2401 | GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6, | |
2402 | GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9, | |
2403 | GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12, | |
2404 | GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15, | |
2405 | GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18, | |
2406 | GTEST_TEMPLATE_ T19, GTEST_TEMPLATE_ T20, GTEST_TEMPLATE_ T21, | |
2407 | GTEST_TEMPLATE_ T22, GTEST_TEMPLATE_ T23, GTEST_TEMPLATE_ T24, | |
2408 | GTEST_TEMPLATE_ T25, GTEST_TEMPLATE_ T26, GTEST_TEMPLATE_ T27, | |
2409 | GTEST_TEMPLATE_ T28, GTEST_TEMPLATE_ T29, GTEST_TEMPLATE_ T30, | |
2410 | GTEST_TEMPLATE_ T31, GTEST_TEMPLATE_ T32, GTEST_TEMPLATE_ T33, | |
2411 | GTEST_TEMPLATE_ T34, GTEST_TEMPLATE_ T35, GTEST_TEMPLATE_ T36, | |
2412 | GTEST_TEMPLATE_ T37, GTEST_TEMPLATE_ T38, GTEST_TEMPLATE_ T39, | |
2413 | GTEST_TEMPLATE_ T40, GTEST_TEMPLATE_ T41, GTEST_TEMPLATE_ T42, | |
2414 | GTEST_TEMPLATE_ T43, GTEST_TEMPLATE_ T44, GTEST_TEMPLATE_ T45, | |
2415 | GTEST_TEMPLATE_ T46, GTEST_TEMPLATE_ T47, GTEST_TEMPLATE_ T48, | |
2416 | GTEST_TEMPLATE_ T49, GTEST_TEMPLATE_ T50> | |
2417 | struct Templates50 { | |
2418 | typedef TemplateSel<T1> Head; | |
2419 | typedef Templates49<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, | |
2420 | T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, | |
2421 | T29, T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, T41, T42, | |
2422 | T43, T44, T45, T46, T47, T48, T49, T50> Tail; | |
2423 | }; | |
2424 | ||
2425 | ||
2426 | // We don't want to require the users to write TemplatesN<...> directly, | |
2427 | // as that would require them to count the length. Templates<...> is much | |
2428 | // easier to write, but generates horrible messages when there is a | |
2429 | // compiler error, as gcc insists on printing out each template | |
2430 | // argument, even if it has the default value (this means Templates<list> | |
2431 | // will appear as Templates<list, NoneT, NoneT, ..., NoneT> in the compiler | |
2432 | // errors). | |
2433 | // | |
2434 | // Our solution is to combine the best part of the two approaches: a | |
2435 | // user would write Templates<T1, ..., TN>, and Google Test will translate | |
2436 | // that to TemplatesN<T1, ..., TN> internally to make error messages | |
2437 | // readable. The translation is done by the 'type' member of the | |
2438 | // Templates template. | |
2439 | template <GTEST_TEMPLATE_ T1 = NoneT, GTEST_TEMPLATE_ T2 = NoneT, | |
2440 | GTEST_TEMPLATE_ T3 = NoneT, GTEST_TEMPLATE_ T4 = NoneT, | |
2441 | GTEST_TEMPLATE_ T5 = NoneT, GTEST_TEMPLATE_ T6 = NoneT, | |
2442 | GTEST_TEMPLATE_ T7 = NoneT, GTEST_TEMPLATE_ T8 = NoneT, | |
2443 | GTEST_TEMPLATE_ T9 = NoneT, GTEST_TEMPLATE_ T10 = NoneT, | |
2444 | GTEST_TEMPLATE_ T11 = NoneT, GTEST_TEMPLATE_ T12 = NoneT, | |
2445 | GTEST_TEMPLATE_ T13 = NoneT, GTEST_TEMPLATE_ T14 = NoneT, | |
2446 | GTEST_TEMPLATE_ T15 = NoneT, GTEST_TEMPLATE_ T16 = NoneT, | |
2447 | GTEST_TEMPLATE_ T17 = NoneT, GTEST_TEMPLATE_ T18 = NoneT, | |
2448 | GTEST_TEMPLATE_ T19 = NoneT, GTEST_TEMPLATE_ T20 = NoneT, | |
2449 | GTEST_TEMPLATE_ T21 = NoneT, GTEST_TEMPLATE_ T22 = NoneT, | |
2450 | GTEST_TEMPLATE_ T23 = NoneT, GTEST_TEMPLATE_ T24 = NoneT, | |
2451 | GTEST_TEMPLATE_ T25 = NoneT, GTEST_TEMPLATE_ T26 = NoneT, | |
2452 | GTEST_TEMPLATE_ T27 = NoneT, GTEST_TEMPLATE_ T28 = NoneT, | |
2453 | GTEST_TEMPLATE_ T29 = NoneT, GTEST_TEMPLATE_ T30 = NoneT, | |
2454 | GTEST_TEMPLATE_ T31 = NoneT, GTEST_TEMPLATE_ T32 = NoneT, | |
2455 | GTEST_TEMPLATE_ T33 = NoneT, GTEST_TEMPLATE_ T34 = NoneT, | |
2456 | GTEST_TEMPLATE_ T35 = NoneT, GTEST_TEMPLATE_ T36 = NoneT, | |
2457 | GTEST_TEMPLATE_ T37 = NoneT, GTEST_TEMPLATE_ T38 = NoneT, | |
2458 | GTEST_TEMPLATE_ T39 = NoneT, GTEST_TEMPLATE_ T40 = NoneT, | |
2459 | GTEST_TEMPLATE_ T41 = NoneT, GTEST_TEMPLATE_ T42 = NoneT, | |
2460 | GTEST_TEMPLATE_ T43 = NoneT, GTEST_TEMPLATE_ T44 = NoneT, | |
2461 | GTEST_TEMPLATE_ T45 = NoneT, GTEST_TEMPLATE_ T46 = NoneT, | |
2462 | GTEST_TEMPLATE_ T47 = NoneT, GTEST_TEMPLATE_ T48 = NoneT, | |
2463 | GTEST_TEMPLATE_ T49 = NoneT, GTEST_TEMPLATE_ T50 = NoneT> | |
2464 | struct Templates { | |
2465 | typedef Templates50<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, | |
2466 | T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, | |
2467 | T28, T29, T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, T41, | |
2468 | T42, T43, T44, T45, T46, T47, T48, T49, T50> type; | |
2469 | }; | |
2470 | ||
2471 | template <> | |
2472 | struct Templates<NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, | |
2473 | NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, | |
2474 | NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, | |
2475 | NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, | |
2476 | NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, | |
2477 | NoneT> { | |
2478 | typedef Templates0 type; | |
2479 | }; | |
2480 | template <GTEST_TEMPLATE_ T1> | |
2481 | struct Templates<T1, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, | |
2482 | NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, | |
2483 | NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, | |
2484 | NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, | |
2485 | NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, | |
2486 | NoneT> { | |
2487 | typedef Templates1<T1> type; | |
2488 | }; | |
2489 | template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2> | |
2490 | struct Templates<T1, T2, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, | |
2491 | NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, | |
2492 | NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, | |
2493 | NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, | |
2494 | NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, | |
2495 | NoneT> { | |
2496 | typedef Templates2<T1, T2> type; | |
2497 | }; | |
2498 | template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3> | |
2499 | struct Templates<T1, T2, T3, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, | |
2500 | NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, | |
2501 | NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, | |
2502 | NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, | |
2503 | NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT> { | |
2504 | typedef Templates3<T1, T2, T3> type; | |
2505 | }; | |
2506 | template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3, | |
2507 | GTEST_TEMPLATE_ T4> | |
2508 | struct Templates<T1, T2, T3, T4, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, | |
2509 | NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, | |
2510 | NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, | |
2511 | NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, | |
2512 | NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT> { | |
2513 | typedef Templates4<T1, T2, T3, T4> type; | |
2514 | }; | |
2515 | template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3, | |
2516 | GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5> | |
2517 | struct Templates<T1, T2, T3, T4, T5, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, | |
2518 | NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, | |
2519 | NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, | |
2520 | NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, | |
2521 | NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT> { | |
2522 | typedef Templates5<T1, T2, T3, T4, T5> type; | |
2523 | }; | |
2524 | template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3, | |
2525 | GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6> | |
2526 | struct Templates<T1, T2, T3, T4, T5, T6, NoneT, NoneT, NoneT, NoneT, NoneT, | |
2527 | NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, | |
2528 | NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, | |
2529 | NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, | |
2530 | NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT> { | |
2531 | typedef Templates6<T1, T2, T3, T4, T5, T6> type; | |
2532 | }; | |
2533 | template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3, | |
2534 | GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6, | |
2535 | GTEST_TEMPLATE_ T7> | |
2536 | struct Templates<T1, T2, T3, T4, T5, T6, T7, NoneT, NoneT, NoneT, NoneT, NoneT, | |
2537 | NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, | |
2538 | NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, | |
2539 | NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, | |
2540 | NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT> { | |
2541 | typedef Templates7<T1, T2, T3, T4, T5, T6, T7> type; | |
2542 | }; | |
2543 | template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3, | |
2544 | GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6, | |
2545 | GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8> | |
2546 | struct Templates<T1, T2, T3, T4, T5, T6, T7, T8, NoneT, NoneT, NoneT, NoneT, | |
2547 | NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, | |
2548 | NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, | |
2549 | NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, | |
2550 | NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT> { | |
2551 | typedef Templates8<T1, T2, T3, T4, T5, T6, T7, T8> type; | |
2552 | }; | |
2553 | template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3, | |
2554 | GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6, | |
2555 | GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9> | |
2556 | struct Templates<T1, T2, T3, T4, T5, T6, T7, T8, T9, NoneT, NoneT, NoneT, | |
2557 | NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, | |
2558 | NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, | |
2559 | NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, | |
2560 | NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT> { | |
2561 | typedef Templates9<T1, T2, T3, T4, T5, T6, T7, T8, T9> type; | |
2562 | }; | |
2563 | template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3, | |
2564 | GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6, | |
2565 | GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9, | |
2566 | GTEST_TEMPLATE_ T10> | |
2567 | struct Templates<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, NoneT, NoneT, NoneT, | |
2568 | NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, | |
2569 | NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, | |
2570 | NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, | |
2571 | NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT> { | |
2572 | typedef Templates10<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10> type; | |
2573 | }; | |
2574 | template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3, | |
2575 | GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6, | |
2576 | GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9, | |
2577 | GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11> | |
2578 | struct Templates<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, NoneT, NoneT, | |
2579 | NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, | |
2580 | NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, | |
2581 | NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, | |
2582 | NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT> { | |
2583 | typedef Templates11<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11> type; | |
2584 | }; | |
2585 | template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3, | |
2586 | GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6, | |
2587 | GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9, | |
2588 | GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12> | |
2589 | struct Templates<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, NoneT, | |
2590 | NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, | |
2591 | NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, | |
2592 | NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, | |
2593 | NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT> { | |
2594 | typedef Templates12<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12> type; | |
2595 | }; | |
2596 | template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3, | |
2597 | GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6, | |
2598 | GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9, | |
2599 | GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12, | |
2600 | GTEST_TEMPLATE_ T13> | |
2601 | struct Templates<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, NoneT, | |
2602 | NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, | |
2603 | NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, | |
2604 | NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, | |
2605 | NoneT, NoneT, NoneT, NoneT, NoneT, NoneT> { | |
2606 | typedef Templates13<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, | |
2607 | T13> type; | |
2608 | }; | |
2609 | template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3, | |
2610 | GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6, | |
2611 | GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9, | |
2612 | GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12, | |
2613 | GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14> | |
2614 | struct Templates<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, | |
2615 | NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, | |
2616 | NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, | |
2617 | NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, | |
2618 | NoneT, NoneT, NoneT, NoneT, NoneT, NoneT> { | |
2619 | typedef Templates14<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, | |
2620 | T14> type; | |
2621 | }; | |
2622 | template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3, | |
2623 | GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6, | |
2624 | GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9, | |
2625 | GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12, | |
2626 | GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15> | |
2627 | struct Templates<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, | |
2628 | T15, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, | |
2629 | NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, | |
2630 | NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, | |
2631 | NoneT, NoneT, NoneT, NoneT, NoneT> { | |
2632 | typedef Templates15<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, | |
2633 | T14, T15> type; | |
2634 | }; | |
2635 | template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3, | |
2636 | GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6, | |
2637 | GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9, | |
2638 | GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12, | |
2639 | GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15, | |
2640 | GTEST_TEMPLATE_ T16> | |
2641 | struct Templates<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, | |
2642 | T15, T16, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, | |
2643 | NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, | |
2644 | NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, | |
2645 | NoneT, NoneT, NoneT, NoneT, NoneT> { | |
2646 | typedef Templates16<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, | |
2647 | T14, T15, T16> type; | |
2648 | }; | |
2649 | template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3, | |
2650 | GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6, | |
2651 | GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9, | |
2652 | GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12, | |
2653 | GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15, | |
2654 | GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17> | |
2655 | struct Templates<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, | |
2656 | T15, T16, T17, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, | |
2657 | NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, | |
2658 | NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, | |
2659 | NoneT, NoneT, NoneT, NoneT, NoneT> { | |
2660 | typedef Templates17<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, | |
2661 | T14, T15, T16, T17> type; | |
2662 | }; | |
2663 | template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3, | |
2664 | GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6, | |
2665 | GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9, | |
2666 | GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12, | |
2667 | GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15, | |
2668 | GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18> | |
2669 | struct Templates<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, | |
2670 | T15, T16, T17, T18, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, | |
2671 | NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, | |
2672 | NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, | |
2673 | NoneT, NoneT, NoneT, NoneT> { | |
2674 | typedef Templates18<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, | |
2675 | T14, T15, T16, T17, T18> type; | |
2676 | }; | |
2677 | template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3, | |
2678 | GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6, | |
2679 | GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9, | |
2680 | GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12, | |
2681 | GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15, | |
2682 | GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18, | |
2683 | GTEST_TEMPLATE_ T19> | |
2684 | struct Templates<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, | |
2685 | T15, T16, T17, T18, T19, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, | |
2686 | NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, | |
2687 | NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, | |
2688 | NoneT, NoneT, NoneT, NoneT> { | |
2689 | typedef Templates19<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, | |
2690 | T14, T15, T16, T17, T18, T19> type; | |
2691 | }; | |
2692 | template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3, | |
2693 | GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6, | |
2694 | GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9, | |
2695 | GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12, | |
2696 | GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15, | |
2697 | GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18, | |
2698 | GTEST_TEMPLATE_ T19, GTEST_TEMPLATE_ T20> | |
2699 | struct Templates<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, | |
2700 | T15, T16, T17, T18, T19, T20, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, | |
2701 | NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, | |
2702 | NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, | |
2703 | NoneT, NoneT, NoneT, NoneT> { | |
2704 | typedef Templates20<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, | |
2705 | T14, T15, T16, T17, T18, T19, T20> type; | |
2706 | }; | |
2707 | template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3, | |
2708 | GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6, | |
2709 | GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9, | |
2710 | GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12, | |
2711 | GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15, | |
2712 | GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18, | |
2713 | GTEST_TEMPLATE_ T19, GTEST_TEMPLATE_ T20, GTEST_TEMPLATE_ T21> | |
2714 | struct Templates<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, | |
2715 | T15, T16, T17, T18, T19, T20, T21, NoneT, NoneT, NoneT, NoneT, NoneT, | |
2716 | NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, | |
2717 | NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, | |
2718 | NoneT, NoneT, NoneT, NoneT> { | |
2719 | typedef Templates21<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, | |
2720 | T14, T15, T16, T17, T18, T19, T20, T21> type; | |
2721 | }; | |
2722 | template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3, | |
2723 | GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6, | |
2724 | GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9, | |
2725 | GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12, | |
2726 | GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15, | |
2727 | GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18, | |
2728 | GTEST_TEMPLATE_ T19, GTEST_TEMPLATE_ T20, GTEST_TEMPLATE_ T21, | |
2729 | GTEST_TEMPLATE_ T22> | |
2730 | struct Templates<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, | |
2731 | T15, T16, T17, T18, T19, T20, T21, T22, NoneT, NoneT, NoneT, NoneT, NoneT, | |
2732 | NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, | |
2733 | NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, | |
2734 | NoneT, NoneT, NoneT> { | |
2735 | typedef Templates22<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, | |
2736 | T14, T15, T16, T17, T18, T19, T20, T21, T22> type; | |
2737 | }; | |
2738 | template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3, | |
2739 | GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6, | |
2740 | GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9, | |
2741 | GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12, | |
2742 | GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15, | |
2743 | GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18, | |
2744 | GTEST_TEMPLATE_ T19, GTEST_TEMPLATE_ T20, GTEST_TEMPLATE_ T21, | |
2745 | GTEST_TEMPLATE_ T22, GTEST_TEMPLATE_ T23> | |
2746 | struct Templates<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, | |
2747 | T15, T16, T17, T18, T19, T20, T21, T22, T23, NoneT, NoneT, NoneT, NoneT, | |
2748 | NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, | |
2749 | NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, | |
2750 | NoneT, NoneT, NoneT> { | |
2751 | typedef Templates23<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, | |
2752 | T14, T15, T16, T17, T18, T19, T20, T21, T22, T23> type; | |
2753 | }; | |
2754 | template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3, | |
2755 | GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6, | |
2756 | GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9, | |
2757 | GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12, | |
2758 | GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15, | |
2759 | GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18, | |
2760 | GTEST_TEMPLATE_ T19, GTEST_TEMPLATE_ T20, GTEST_TEMPLATE_ T21, | |
2761 | GTEST_TEMPLATE_ T22, GTEST_TEMPLATE_ T23, GTEST_TEMPLATE_ T24> | |
2762 | struct Templates<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, | |
2763 | T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, NoneT, NoneT, NoneT, | |
2764 | NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, | |
2765 | NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, | |
2766 | NoneT, NoneT, NoneT> { | |
2767 | typedef Templates24<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, | |
2768 | T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24> type; | |
2769 | }; | |
2770 | template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3, | |
2771 | GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6, | |
2772 | GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9, | |
2773 | GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12, | |
2774 | GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15, | |
2775 | GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18, | |
2776 | GTEST_TEMPLATE_ T19, GTEST_TEMPLATE_ T20, GTEST_TEMPLATE_ T21, | |
2777 | GTEST_TEMPLATE_ T22, GTEST_TEMPLATE_ T23, GTEST_TEMPLATE_ T24, | |
2778 | GTEST_TEMPLATE_ T25> | |
2779 | struct Templates<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, | |
2780 | T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, NoneT, NoneT, NoneT, | |
2781 | NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, | |
2782 | NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, | |
2783 | NoneT, NoneT> { | |
2784 | typedef Templates25<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, | |
2785 | T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25> type; | |
2786 | }; | |
2787 | template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3, | |
2788 | GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6, | |
2789 | GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9, | |
2790 | GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12, | |
2791 | GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15, | |
2792 | GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18, | |
2793 | GTEST_TEMPLATE_ T19, GTEST_TEMPLATE_ T20, GTEST_TEMPLATE_ T21, | |
2794 | GTEST_TEMPLATE_ T22, GTEST_TEMPLATE_ T23, GTEST_TEMPLATE_ T24, | |
2795 | GTEST_TEMPLATE_ T25, GTEST_TEMPLATE_ T26> | |
2796 | struct Templates<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, | |
2797 | T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, NoneT, NoneT, | |
2798 | NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, | |
2799 | NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, | |
2800 | NoneT, NoneT> { | |
2801 | typedef Templates26<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, | |
2802 | T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26> type; | |
2803 | }; | |
2804 | template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3, | |
2805 | GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6, | |
2806 | GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9, | |
2807 | GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12, | |
2808 | GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15, | |
2809 | GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18, | |
2810 | GTEST_TEMPLATE_ T19, GTEST_TEMPLATE_ T20, GTEST_TEMPLATE_ T21, | |
2811 | GTEST_TEMPLATE_ T22, GTEST_TEMPLATE_ T23, GTEST_TEMPLATE_ T24, | |
2812 | GTEST_TEMPLATE_ T25, GTEST_TEMPLATE_ T26, GTEST_TEMPLATE_ T27> | |
2813 | struct Templates<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, | |
2814 | T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, NoneT, | |
2815 | NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, | |
2816 | NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, | |
2817 | NoneT, NoneT> { | |
2818 | typedef Templates27<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, | |
2819 | T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, | |
2820 | T27> type; | |
2821 | }; | |
2822 | template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3, | |
2823 | GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6, | |
2824 | GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9, | |
2825 | GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12, | |
2826 | GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15, | |
2827 | GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18, | |
2828 | GTEST_TEMPLATE_ T19, GTEST_TEMPLATE_ T20, GTEST_TEMPLATE_ T21, | |
2829 | GTEST_TEMPLATE_ T22, GTEST_TEMPLATE_ T23, GTEST_TEMPLATE_ T24, | |
2830 | GTEST_TEMPLATE_ T25, GTEST_TEMPLATE_ T26, GTEST_TEMPLATE_ T27, | |
2831 | GTEST_TEMPLATE_ T28> | |
2832 | struct Templates<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, | |
2833 | T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, | |
2834 | NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, | |
2835 | NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, | |
2836 | NoneT, NoneT> { | |
2837 | typedef Templates28<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, | |
2838 | T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, | |
2839 | T28> type; | |
2840 | }; | |
2841 | template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3, | |
2842 | GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6, | |
2843 | GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9, | |
2844 | GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12, | |
2845 | GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15, | |
2846 | GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18, | |
2847 | GTEST_TEMPLATE_ T19, GTEST_TEMPLATE_ T20, GTEST_TEMPLATE_ T21, | |
2848 | GTEST_TEMPLATE_ T22, GTEST_TEMPLATE_ T23, GTEST_TEMPLATE_ T24, | |
2849 | GTEST_TEMPLATE_ T25, GTEST_TEMPLATE_ T26, GTEST_TEMPLATE_ T27, | |
2850 | GTEST_TEMPLATE_ T28, GTEST_TEMPLATE_ T29> | |
2851 | struct Templates<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, | |
2852 | T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29, | |
2853 | NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, | |
2854 | NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, | |
2855 | NoneT> { | |
2856 | typedef Templates29<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, | |
2857 | T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, | |
2858 | T28, T29> type; | |
2859 | }; | |
2860 | template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3, | |
2861 | GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6, | |
2862 | GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9, | |
2863 | GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12, | |
2864 | GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15, | |
2865 | GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18, | |
2866 | GTEST_TEMPLATE_ T19, GTEST_TEMPLATE_ T20, GTEST_TEMPLATE_ T21, | |
2867 | GTEST_TEMPLATE_ T22, GTEST_TEMPLATE_ T23, GTEST_TEMPLATE_ T24, | |
2868 | GTEST_TEMPLATE_ T25, GTEST_TEMPLATE_ T26, GTEST_TEMPLATE_ T27, | |
2869 | GTEST_TEMPLATE_ T28, GTEST_TEMPLATE_ T29, GTEST_TEMPLATE_ T30> | |
2870 | struct Templates<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, | |
2871 | T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29, | |
2872 | T30, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, | |
2873 | NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT> { | |
2874 | typedef Templates30<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, | |
2875 | T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, | |
2876 | T28, T29, T30> type; | |
2877 | }; | |
2878 | template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3, | |
2879 | GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6, | |
2880 | GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9, | |
2881 | GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12, | |
2882 | GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15, | |
2883 | GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18, | |
2884 | GTEST_TEMPLATE_ T19, GTEST_TEMPLATE_ T20, GTEST_TEMPLATE_ T21, | |
2885 | GTEST_TEMPLATE_ T22, GTEST_TEMPLATE_ T23, GTEST_TEMPLATE_ T24, | |
2886 | GTEST_TEMPLATE_ T25, GTEST_TEMPLATE_ T26, GTEST_TEMPLATE_ T27, | |
2887 | GTEST_TEMPLATE_ T28, GTEST_TEMPLATE_ T29, GTEST_TEMPLATE_ T30, | |
2888 | GTEST_TEMPLATE_ T31> | |
2889 | struct Templates<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, | |
2890 | T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29, | |
2891 | T30, T31, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, | |
2892 | NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT> { | |
2893 | typedef Templates31<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, | |
2894 | T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, | |
2895 | T28, T29, T30, T31> type; | |
2896 | }; | |
2897 | template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3, | |
2898 | GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6, | |
2899 | GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9, | |
2900 | GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12, | |
2901 | GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15, | |
2902 | GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18, | |
2903 | GTEST_TEMPLATE_ T19, GTEST_TEMPLATE_ T20, GTEST_TEMPLATE_ T21, | |
2904 | GTEST_TEMPLATE_ T22, GTEST_TEMPLATE_ T23, GTEST_TEMPLATE_ T24, | |
2905 | GTEST_TEMPLATE_ T25, GTEST_TEMPLATE_ T26, GTEST_TEMPLATE_ T27, | |
2906 | GTEST_TEMPLATE_ T28, GTEST_TEMPLATE_ T29, GTEST_TEMPLATE_ T30, | |
2907 | GTEST_TEMPLATE_ T31, GTEST_TEMPLATE_ T32> | |
2908 | struct Templates<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, | |
2909 | T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29, | |
2910 | T30, T31, T32, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, | |
2911 | NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT> { | |
2912 | typedef Templates32<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, | |
2913 | T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, | |
2914 | T28, T29, T30, T31, T32> type; | |
2915 | }; | |
2916 | template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3, | |
2917 | GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6, | |
2918 | GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9, | |
2919 | GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12, | |
2920 | GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15, | |
2921 | GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18, | |
2922 | GTEST_TEMPLATE_ T19, GTEST_TEMPLATE_ T20, GTEST_TEMPLATE_ T21, | |
2923 | GTEST_TEMPLATE_ T22, GTEST_TEMPLATE_ T23, GTEST_TEMPLATE_ T24, | |
2924 | GTEST_TEMPLATE_ T25, GTEST_TEMPLATE_ T26, GTEST_TEMPLATE_ T27, | |
2925 | GTEST_TEMPLATE_ T28, GTEST_TEMPLATE_ T29, GTEST_TEMPLATE_ T30, | |
2926 | GTEST_TEMPLATE_ T31, GTEST_TEMPLATE_ T32, GTEST_TEMPLATE_ T33> | |
2927 | struct Templates<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, | |
2928 | T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29, | |
2929 | T30, T31, T32, T33, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, | |
2930 | NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT> { | |
2931 | typedef Templates33<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, | |
2932 | T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, | |
2933 | T28, T29, T30, T31, T32, T33> type; | |
2934 | }; | |
2935 | template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3, | |
2936 | GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6, | |
2937 | GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9, | |
2938 | GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12, | |
2939 | GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15, | |
2940 | GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18, | |
2941 | GTEST_TEMPLATE_ T19, GTEST_TEMPLATE_ T20, GTEST_TEMPLATE_ T21, | |
2942 | GTEST_TEMPLATE_ T22, GTEST_TEMPLATE_ T23, GTEST_TEMPLATE_ T24, | |
2943 | GTEST_TEMPLATE_ T25, GTEST_TEMPLATE_ T26, GTEST_TEMPLATE_ T27, | |
2944 | GTEST_TEMPLATE_ T28, GTEST_TEMPLATE_ T29, GTEST_TEMPLATE_ T30, | |
2945 | GTEST_TEMPLATE_ T31, GTEST_TEMPLATE_ T32, GTEST_TEMPLATE_ T33, | |
2946 | GTEST_TEMPLATE_ T34> | |
2947 | struct Templates<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, | |
2948 | T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29, | |
2949 | T30, T31, T32, T33, T34, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, | |
2950 | NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT> { | |
2951 | typedef Templates34<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, | |
2952 | T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, | |
2953 | T28, T29, T30, T31, T32, T33, T34> type; | |
2954 | }; | |
2955 | template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3, | |
2956 | GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6, | |
2957 | GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9, | |
2958 | GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12, | |
2959 | GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15, | |
2960 | GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18, | |
2961 | GTEST_TEMPLATE_ T19, GTEST_TEMPLATE_ T20, GTEST_TEMPLATE_ T21, | |
2962 | GTEST_TEMPLATE_ T22, GTEST_TEMPLATE_ T23, GTEST_TEMPLATE_ T24, | |
2963 | GTEST_TEMPLATE_ T25, GTEST_TEMPLATE_ T26, GTEST_TEMPLATE_ T27, | |
2964 | GTEST_TEMPLATE_ T28, GTEST_TEMPLATE_ T29, GTEST_TEMPLATE_ T30, | |
2965 | GTEST_TEMPLATE_ T31, GTEST_TEMPLATE_ T32, GTEST_TEMPLATE_ T33, | |
2966 | GTEST_TEMPLATE_ T34, GTEST_TEMPLATE_ T35> | |
2967 | struct Templates<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, | |
2968 | T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29, | |
2969 | T30, T31, T32, T33, T34, T35, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, | |
2970 | NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT> { | |
2971 | typedef Templates35<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, | |
2972 | T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, | |
2973 | T28, T29, T30, T31, T32, T33, T34, T35> type; | |
2974 | }; | |
2975 | template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3, | |
2976 | GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6, | |
2977 | GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9, | |
2978 | GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12, | |
2979 | GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15, | |
2980 | GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18, | |
2981 | GTEST_TEMPLATE_ T19, GTEST_TEMPLATE_ T20, GTEST_TEMPLATE_ T21, | |
2982 | GTEST_TEMPLATE_ T22, GTEST_TEMPLATE_ T23, GTEST_TEMPLATE_ T24, | |
2983 | GTEST_TEMPLATE_ T25, GTEST_TEMPLATE_ T26, GTEST_TEMPLATE_ T27, | |
2984 | GTEST_TEMPLATE_ T28, GTEST_TEMPLATE_ T29, GTEST_TEMPLATE_ T30, | |
2985 | GTEST_TEMPLATE_ T31, GTEST_TEMPLATE_ T32, GTEST_TEMPLATE_ T33, | |
2986 | GTEST_TEMPLATE_ T34, GTEST_TEMPLATE_ T35, GTEST_TEMPLATE_ T36> | |
2987 | struct Templates<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, | |
2988 | T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29, | |
2989 | T30, T31, T32, T33, T34, T35, T36, NoneT, NoneT, NoneT, NoneT, NoneT, | |
2990 | NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT> { | |
2991 | typedef Templates36<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, | |
2992 | T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, | |
2993 | T28, T29, T30, T31, T32, T33, T34, T35, T36> type; | |
2994 | }; | |
2995 | template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3, | |
2996 | GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6, | |
2997 | GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9, | |
2998 | GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12, | |
2999 | GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15, | |
3000 | GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18, | |
3001 | GTEST_TEMPLATE_ T19, GTEST_TEMPLATE_ T20, GTEST_TEMPLATE_ T21, | |
3002 | GTEST_TEMPLATE_ T22, GTEST_TEMPLATE_ T23, GTEST_TEMPLATE_ T24, | |
3003 | GTEST_TEMPLATE_ T25, GTEST_TEMPLATE_ T26, GTEST_TEMPLATE_ T27, | |
3004 | GTEST_TEMPLATE_ T28, GTEST_TEMPLATE_ T29, GTEST_TEMPLATE_ T30, | |
3005 | GTEST_TEMPLATE_ T31, GTEST_TEMPLATE_ T32, GTEST_TEMPLATE_ T33, | |
3006 | GTEST_TEMPLATE_ T34, GTEST_TEMPLATE_ T35, GTEST_TEMPLATE_ T36, | |
3007 | GTEST_TEMPLATE_ T37> | |
3008 | struct Templates<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, | |
3009 | T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29, | |
3010 | T30, T31, T32, T33, T34, T35, T36, T37, NoneT, NoneT, NoneT, NoneT, NoneT, | |
3011 | NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT> { | |
3012 | typedef Templates37<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, | |
3013 | T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, | |
3014 | T28, T29, T30, T31, T32, T33, T34, T35, T36, T37> type; | |
3015 | }; | |
3016 | template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3, | |
3017 | GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6, | |
3018 | GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9, | |
3019 | GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12, | |
3020 | GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15, | |
3021 | GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18, | |
3022 | GTEST_TEMPLATE_ T19, GTEST_TEMPLATE_ T20, GTEST_TEMPLATE_ T21, | |
3023 | GTEST_TEMPLATE_ T22, GTEST_TEMPLATE_ T23, GTEST_TEMPLATE_ T24, | |
3024 | GTEST_TEMPLATE_ T25, GTEST_TEMPLATE_ T26, GTEST_TEMPLATE_ T27, | |
3025 | GTEST_TEMPLATE_ T28, GTEST_TEMPLATE_ T29, GTEST_TEMPLATE_ T30, | |
3026 | GTEST_TEMPLATE_ T31, GTEST_TEMPLATE_ T32, GTEST_TEMPLATE_ T33, | |
3027 | GTEST_TEMPLATE_ T34, GTEST_TEMPLATE_ T35, GTEST_TEMPLATE_ T36, | |
3028 | GTEST_TEMPLATE_ T37, GTEST_TEMPLATE_ T38> | |
3029 | struct Templates<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, | |
3030 | T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29, | |
3031 | T30, T31, T32, T33, T34, T35, T36, T37, T38, NoneT, NoneT, NoneT, NoneT, | |
3032 | NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT> { | |
3033 | typedef Templates38<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, | |
3034 | T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, | |
3035 | T28, T29, T30, T31, T32, T33, T34, T35, T36, T37, T38> type; | |
3036 | }; | |
3037 | template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3, | |
3038 | GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6, | |
3039 | GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9, | |
3040 | GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12, | |
3041 | GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15, | |
3042 | GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18, | |
3043 | GTEST_TEMPLATE_ T19, GTEST_TEMPLATE_ T20, GTEST_TEMPLATE_ T21, | |
3044 | GTEST_TEMPLATE_ T22, GTEST_TEMPLATE_ T23, GTEST_TEMPLATE_ T24, | |
3045 | GTEST_TEMPLATE_ T25, GTEST_TEMPLATE_ T26, GTEST_TEMPLATE_ T27, | |
3046 | GTEST_TEMPLATE_ T28, GTEST_TEMPLATE_ T29, GTEST_TEMPLATE_ T30, | |
3047 | GTEST_TEMPLATE_ T31, GTEST_TEMPLATE_ T32, GTEST_TEMPLATE_ T33, | |
3048 | GTEST_TEMPLATE_ T34, GTEST_TEMPLATE_ T35, GTEST_TEMPLATE_ T36, | |
3049 | GTEST_TEMPLATE_ T37, GTEST_TEMPLATE_ T38, GTEST_TEMPLATE_ T39> | |
3050 | struct Templates<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, | |
3051 | T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29, | |
3052 | T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, NoneT, NoneT, NoneT, | |
3053 | NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT> { | |
3054 | typedef Templates39<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, | |
3055 | T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, | |
3056 | T28, T29, T30, T31, T32, T33, T34, T35, T36, T37, T38, T39> type; | |
3057 | }; | |
3058 | template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3, | |
3059 | GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6, | |
3060 | GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9, | |
3061 | GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12, | |
3062 | GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15, | |
3063 | GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18, | |
3064 | GTEST_TEMPLATE_ T19, GTEST_TEMPLATE_ T20, GTEST_TEMPLATE_ T21, | |
3065 | GTEST_TEMPLATE_ T22, GTEST_TEMPLATE_ T23, GTEST_TEMPLATE_ T24, | |
3066 | GTEST_TEMPLATE_ T25, GTEST_TEMPLATE_ T26, GTEST_TEMPLATE_ T27, | |
3067 | GTEST_TEMPLATE_ T28, GTEST_TEMPLATE_ T29, GTEST_TEMPLATE_ T30, | |
3068 | GTEST_TEMPLATE_ T31, GTEST_TEMPLATE_ T32, GTEST_TEMPLATE_ T33, | |
3069 | GTEST_TEMPLATE_ T34, GTEST_TEMPLATE_ T35, GTEST_TEMPLATE_ T36, | |
3070 | GTEST_TEMPLATE_ T37, GTEST_TEMPLATE_ T38, GTEST_TEMPLATE_ T39, | |
3071 | GTEST_TEMPLATE_ T40> | |
3072 | struct Templates<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, | |
3073 | T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29, | |
3074 | T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, NoneT, NoneT, NoneT, | |
3075 | NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT> { | |
3076 | typedef Templates40<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, | |
3077 | T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, | |
3078 | T28, T29, T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40> type; | |
3079 | }; | |
3080 | template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3, | |
3081 | GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6, | |
3082 | GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9, | |
3083 | GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12, | |
3084 | GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15, | |
3085 | GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18, | |
3086 | GTEST_TEMPLATE_ T19, GTEST_TEMPLATE_ T20, GTEST_TEMPLATE_ T21, | |
3087 | GTEST_TEMPLATE_ T22, GTEST_TEMPLATE_ T23, GTEST_TEMPLATE_ T24, | |
3088 | GTEST_TEMPLATE_ T25, GTEST_TEMPLATE_ T26, GTEST_TEMPLATE_ T27, | |
3089 | GTEST_TEMPLATE_ T28, GTEST_TEMPLATE_ T29, GTEST_TEMPLATE_ T30, | |
3090 | GTEST_TEMPLATE_ T31, GTEST_TEMPLATE_ T32, GTEST_TEMPLATE_ T33, | |
3091 | GTEST_TEMPLATE_ T34, GTEST_TEMPLATE_ T35, GTEST_TEMPLATE_ T36, | |
3092 | GTEST_TEMPLATE_ T37, GTEST_TEMPLATE_ T38, GTEST_TEMPLATE_ T39, | |
3093 | GTEST_TEMPLATE_ T40, GTEST_TEMPLATE_ T41> | |
3094 | struct Templates<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, | |
3095 | T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29, | |
3096 | T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, T41, NoneT, NoneT, | |
3097 | NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT> { | |
3098 | typedef Templates41<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, | |
3099 | T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, | |
3100 | T28, T29, T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, | |
3101 | T41> type; | |
3102 | }; | |
3103 | template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3, | |
3104 | GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6, | |
3105 | GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9, | |
3106 | GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12, | |
3107 | GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15, | |
3108 | GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18, | |
3109 | GTEST_TEMPLATE_ T19, GTEST_TEMPLATE_ T20, GTEST_TEMPLATE_ T21, | |
3110 | GTEST_TEMPLATE_ T22, GTEST_TEMPLATE_ T23, GTEST_TEMPLATE_ T24, | |
3111 | GTEST_TEMPLATE_ T25, GTEST_TEMPLATE_ T26, GTEST_TEMPLATE_ T27, | |
3112 | GTEST_TEMPLATE_ T28, GTEST_TEMPLATE_ T29, GTEST_TEMPLATE_ T30, | |
3113 | GTEST_TEMPLATE_ T31, GTEST_TEMPLATE_ T32, GTEST_TEMPLATE_ T33, | |
3114 | GTEST_TEMPLATE_ T34, GTEST_TEMPLATE_ T35, GTEST_TEMPLATE_ T36, | |
3115 | GTEST_TEMPLATE_ T37, GTEST_TEMPLATE_ T38, GTEST_TEMPLATE_ T39, | |
3116 | GTEST_TEMPLATE_ T40, GTEST_TEMPLATE_ T41, GTEST_TEMPLATE_ T42> | |
3117 | struct Templates<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, | |
3118 | T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29, | |
3119 | T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, T41, T42, NoneT, | |
3120 | NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT> { | |
3121 | typedef Templates42<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, | |
3122 | T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, | |
3123 | T28, T29, T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, T41, | |
3124 | T42> type; | |
3125 | }; | |
3126 | template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3, | |
3127 | GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6, | |
3128 | GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9, | |
3129 | GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12, | |
3130 | GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15, | |
3131 | GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18, | |
3132 | GTEST_TEMPLATE_ T19, GTEST_TEMPLATE_ T20, GTEST_TEMPLATE_ T21, | |
3133 | GTEST_TEMPLATE_ T22, GTEST_TEMPLATE_ T23, GTEST_TEMPLATE_ T24, | |
3134 | GTEST_TEMPLATE_ T25, GTEST_TEMPLATE_ T26, GTEST_TEMPLATE_ T27, | |
3135 | GTEST_TEMPLATE_ T28, GTEST_TEMPLATE_ T29, GTEST_TEMPLATE_ T30, | |
3136 | GTEST_TEMPLATE_ T31, GTEST_TEMPLATE_ T32, GTEST_TEMPLATE_ T33, | |
3137 | GTEST_TEMPLATE_ T34, GTEST_TEMPLATE_ T35, GTEST_TEMPLATE_ T36, | |
3138 | GTEST_TEMPLATE_ T37, GTEST_TEMPLATE_ T38, GTEST_TEMPLATE_ T39, | |
3139 | GTEST_TEMPLATE_ T40, GTEST_TEMPLATE_ T41, GTEST_TEMPLATE_ T42, | |
3140 | GTEST_TEMPLATE_ T43> | |
3141 | struct Templates<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, | |
3142 | T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29, | |
3143 | T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, T41, T42, T43, | |
3144 | NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT> { | |
3145 | typedef Templates43<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, | |
3146 | T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, | |
3147 | T28, T29, T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, T41, | |
3148 | T42, T43> type; | |
3149 | }; | |
3150 | template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3, | |
3151 | GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6, | |
3152 | GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9, | |
3153 | GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12, | |
3154 | GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15, | |
3155 | GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18, | |
3156 | GTEST_TEMPLATE_ T19, GTEST_TEMPLATE_ T20, GTEST_TEMPLATE_ T21, | |
3157 | GTEST_TEMPLATE_ T22, GTEST_TEMPLATE_ T23, GTEST_TEMPLATE_ T24, | |
3158 | GTEST_TEMPLATE_ T25, GTEST_TEMPLATE_ T26, GTEST_TEMPLATE_ T27, | |
3159 | GTEST_TEMPLATE_ T28, GTEST_TEMPLATE_ T29, GTEST_TEMPLATE_ T30, | |
3160 | GTEST_TEMPLATE_ T31, GTEST_TEMPLATE_ T32, GTEST_TEMPLATE_ T33, | |
3161 | GTEST_TEMPLATE_ T34, GTEST_TEMPLATE_ T35, GTEST_TEMPLATE_ T36, | |
3162 | GTEST_TEMPLATE_ T37, GTEST_TEMPLATE_ T38, GTEST_TEMPLATE_ T39, | |
3163 | GTEST_TEMPLATE_ T40, GTEST_TEMPLATE_ T41, GTEST_TEMPLATE_ T42, | |
3164 | GTEST_TEMPLATE_ T43, GTEST_TEMPLATE_ T44> | |
3165 | struct Templates<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, | |
3166 | T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29, | |
3167 | T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, T41, T42, T43, T44, | |
3168 | NoneT, NoneT, NoneT, NoneT, NoneT, NoneT> { | |
3169 | typedef Templates44<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, | |
3170 | T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, | |
3171 | T28, T29, T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, T41, | |
3172 | T42, T43, T44> type; | |
3173 | }; | |
3174 | template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3, | |
3175 | GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6, | |
3176 | GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9, | |
3177 | GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12, | |
3178 | GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15, | |
3179 | GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18, | |
3180 | GTEST_TEMPLATE_ T19, GTEST_TEMPLATE_ T20, GTEST_TEMPLATE_ T21, | |
3181 | GTEST_TEMPLATE_ T22, GTEST_TEMPLATE_ T23, GTEST_TEMPLATE_ T24, | |
3182 | GTEST_TEMPLATE_ T25, GTEST_TEMPLATE_ T26, GTEST_TEMPLATE_ T27, | |
3183 | GTEST_TEMPLATE_ T28, GTEST_TEMPLATE_ T29, GTEST_TEMPLATE_ T30, | |
3184 | GTEST_TEMPLATE_ T31, GTEST_TEMPLATE_ T32, GTEST_TEMPLATE_ T33, | |
3185 | GTEST_TEMPLATE_ T34, GTEST_TEMPLATE_ T35, GTEST_TEMPLATE_ T36, | |
3186 | GTEST_TEMPLATE_ T37, GTEST_TEMPLATE_ T38, GTEST_TEMPLATE_ T39, | |
3187 | GTEST_TEMPLATE_ T40, GTEST_TEMPLATE_ T41, GTEST_TEMPLATE_ T42, | |
3188 | GTEST_TEMPLATE_ T43, GTEST_TEMPLATE_ T44, GTEST_TEMPLATE_ T45> | |
3189 | struct Templates<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, | |
3190 | T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29, | |
3191 | T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, T41, T42, T43, T44, | |
3192 | T45, NoneT, NoneT, NoneT, NoneT, NoneT> { | |
3193 | typedef Templates45<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, | |
3194 | T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, | |
3195 | T28, T29, T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, T41, | |
3196 | T42, T43, T44, T45> type; | |
3197 | }; | |
3198 | template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3, | |
3199 | GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6, | |
3200 | GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9, | |
3201 | GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12, | |
3202 | GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15, | |
3203 | GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18, | |
3204 | GTEST_TEMPLATE_ T19, GTEST_TEMPLATE_ T20, GTEST_TEMPLATE_ T21, | |
3205 | GTEST_TEMPLATE_ T22, GTEST_TEMPLATE_ T23, GTEST_TEMPLATE_ T24, | |
3206 | GTEST_TEMPLATE_ T25, GTEST_TEMPLATE_ T26, GTEST_TEMPLATE_ T27, | |
3207 | GTEST_TEMPLATE_ T28, GTEST_TEMPLATE_ T29, GTEST_TEMPLATE_ T30, | |
3208 | GTEST_TEMPLATE_ T31, GTEST_TEMPLATE_ T32, GTEST_TEMPLATE_ T33, | |
3209 | GTEST_TEMPLATE_ T34, GTEST_TEMPLATE_ T35, GTEST_TEMPLATE_ T36, | |
3210 | GTEST_TEMPLATE_ T37, GTEST_TEMPLATE_ T38, GTEST_TEMPLATE_ T39, | |
3211 | GTEST_TEMPLATE_ T40, GTEST_TEMPLATE_ T41, GTEST_TEMPLATE_ T42, | |
3212 | GTEST_TEMPLATE_ T43, GTEST_TEMPLATE_ T44, GTEST_TEMPLATE_ T45, | |
3213 | GTEST_TEMPLATE_ T46> | |
3214 | struct Templates<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, | |
3215 | T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29, | |
3216 | T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, T41, T42, T43, T44, | |
3217 | T45, T46, NoneT, NoneT, NoneT, NoneT> { | |
3218 | typedef Templates46<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, | |
3219 | T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, | |
3220 | T28, T29, T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, T41, | |
3221 | T42, T43, T44, T45, T46> type; | |
3222 | }; | |
3223 | template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3, | |
3224 | GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6, | |
3225 | GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9, | |
3226 | GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12, | |
3227 | GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15, | |
3228 | GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18, | |
3229 | GTEST_TEMPLATE_ T19, GTEST_TEMPLATE_ T20, GTEST_TEMPLATE_ T21, | |
3230 | GTEST_TEMPLATE_ T22, GTEST_TEMPLATE_ T23, GTEST_TEMPLATE_ T24, | |
3231 | GTEST_TEMPLATE_ T25, GTEST_TEMPLATE_ T26, GTEST_TEMPLATE_ T27, | |
3232 | GTEST_TEMPLATE_ T28, GTEST_TEMPLATE_ T29, GTEST_TEMPLATE_ T30, | |
3233 | GTEST_TEMPLATE_ T31, GTEST_TEMPLATE_ T32, GTEST_TEMPLATE_ T33, | |
3234 | GTEST_TEMPLATE_ T34, GTEST_TEMPLATE_ T35, GTEST_TEMPLATE_ T36, | |
3235 | GTEST_TEMPLATE_ T37, GTEST_TEMPLATE_ T38, GTEST_TEMPLATE_ T39, | |
3236 | GTEST_TEMPLATE_ T40, GTEST_TEMPLATE_ T41, GTEST_TEMPLATE_ T42, | |
3237 | GTEST_TEMPLATE_ T43, GTEST_TEMPLATE_ T44, GTEST_TEMPLATE_ T45, | |
3238 | GTEST_TEMPLATE_ T46, GTEST_TEMPLATE_ T47> | |
3239 | struct Templates<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, | |
3240 | T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29, | |
3241 | T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, T41, T42, T43, T44, | |
3242 | T45, T46, T47, NoneT, NoneT, NoneT> { | |
3243 | typedef Templates47<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, | |
3244 | T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, | |
3245 | T28, T29, T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, T41, | |
3246 | T42, T43, T44, T45, T46, T47> type; | |
3247 | }; | |
3248 | template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3, | |
3249 | GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6, | |
3250 | GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9, | |
3251 | GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12, | |
3252 | GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15, | |
3253 | GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18, | |
3254 | GTEST_TEMPLATE_ T19, GTEST_TEMPLATE_ T20, GTEST_TEMPLATE_ T21, | |
3255 | GTEST_TEMPLATE_ T22, GTEST_TEMPLATE_ T23, GTEST_TEMPLATE_ T24, | |
3256 | GTEST_TEMPLATE_ T25, GTEST_TEMPLATE_ T26, GTEST_TEMPLATE_ T27, | |
3257 | GTEST_TEMPLATE_ T28, GTEST_TEMPLATE_ T29, GTEST_TEMPLATE_ T30, | |
3258 | GTEST_TEMPLATE_ T31, GTEST_TEMPLATE_ T32, GTEST_TEMPLATE_ T33, | |
3259 | GTEST_TEMPLATE_ T34, GTEST_TEMPLATE_ T35, GTEST_TEMPLATE_ T36, | |
3260 | GTEST_TEMPLATE_ T37, GTEST_TEMPLATE_ T38, GTEST_TEMPLATE_ T39, | |
3261 | GTEST_TEMPLATE_ T40, GTEST_TEMPLATE_ T41, GTEST_TEMPLATE_ T42, | |
3262 | GTEST_TEMPLATE_ T43, GTEST_TEMPLATE_ T44, GTEST_TEMPLATE_ T45, | |
3263 | GTEST_TEMPLATE_ T46, GTEST_TEMPLATE_ T47, GTEST_TEMPLATE_ T48> | |
3264 | struct Templates<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, | |
3265 | T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29, | |
3266 | T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, T41, T42, T43, T44, | |
3267 | T45, T46, T47, T48, NoneT, NoneT> { | |
3268 | typedef Templates48<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, | |
3269 | T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, | |
3270 | T28, T29, T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, T41, | |
3271 | T42, T43, T44, T45, T46, T47, T48> type; | |
3272 | }; | |
3273 | template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3, | |
3274 | GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6, | |
3275 | GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9, | |
3276 | GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12, | |
3277 | GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15, | |
3278 | GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18, | |
3279 | GTEST_TEMPLATE_ T19, GTEST_TEMPLATE_ T20, GTEST_TEMPLATE_ T21, | |
3280 | GTEST_TEMPLATE_ T22, GTEST_TEMPLATE_ T23, GTEST_TEMPLATE_ T24, | |
3281 | GTEST_TEMPLATE_ T25, GTEST_TEMPLATE_ T26, GTEST_TEMPLATE_ T27, | |
3282 | GTEST_TEMPLATE_ T28, GTEST_TEMPLATE_ T29, GTEST_TEMPLATE_ T30, | |
3283 | GTEST_TEMPLATE_ T31, GTEST_TEMPLATE_ T32, GTEST_TEMPLATE_ T33, | |
3284 | GTEST_TEMPLATE_ T34, GTEST_TEMPLATE_ T35, GTEST_TEMPLATE_ T36, | |
3285 | GTEST_TEMPLATE_ T37, GTEST_TEMPLATE_ T38, GTEST_TEMPLATE_ T39, | |
3286 | GTEST_TEMPLATE_ T40, GTEST_TEMPLATE_ T41, GTEST_TEMPLATE_ T42, | |
3287 | GTEST_TEMPLATE_ T43, GTEST_TEMPLATE_ T44, GTEST_TEMPLATE_ T45, | |
3288 | GTEST_TEMPLATE_ T46, GTEST_TEMPLATE_ T47, GTEST_TEMPLATE_ T48, | |
3289 | GTEST_TEMPLATE_ T49> | |
3290 | struct Templates<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, | |
3291 | T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29, | |
3292 | T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, T41, T42, T43, T44, | |
3293 | T45, T46, T47, T48, T49, NoneT> { | |
3294 | typedef Templates49<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, | |
3295 | T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, | |
3296 | T28, T29, T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, T41, | |
3297 | T42, T43, T44, T45, T46, T47, T48, T49> type; | |
3298 | }; | |
3299 | ||
3300 | // The TypeList template makes it possible to use either a single type | |
3301 | // or a Types<...> list in TYPED_TEST_SUITE() and | |
3302 | // INSTANTIATE_TYPED_TEST_SUITE_P(). | |
3303 | ||
3304 | template <typename T> | |
3305 | struct TypeList { | |
3306 | typedef Types1<T> type; | |
3307 | }; | |
3308 | ||
3309 | template <typename T1, typename T2, typename T3, typename T4, typename T5, | |
3310 | typename T6, typename T7, typename T8, typename T9, typename T10, | |
3311 | typename T11, typename T12, typename T13, typename T14, typename T15, | |
3312 | typename T16, typename T17, typename T18, typename T19, typename T20, | |
3313 | typename T21, typename T22, typename T23, typename T24, typename T25, | |
3314 | typename T26, typename T27, typename T28, typename T29, typename T30, | |
3315 | typename T31, typename T32, typename T33, typename T34, typename T35, | |
3316 | typename T36, typename T37, typename T38, typename T39, typename T40, | |
3317 | typename T41, typename T42, typename T43, typename T44, typename T45, | |
3318 | typename T46, typename T47, typename T48, typename T49, typename T50> | |
3319 | struct TypeList<Types<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, | |
3320 | T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, | |
3321 | T29, T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, T41, T42, T43, | |
3322 | T44, T45, T46, T47, T48, T49, T50> > { | |
3323 | typedef typename Types<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, | |
3324 | T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, | |
3325 | T27, T28, T29, T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, | |
3326 | T41, T42, T43, T44, T45, T46, T47, T48, T49, T50>::type type; | |
169 | public: | |
170 | using type = typename proxy::type; | |
3327 | 171 | }; |
3328 | 172 | |
3329 | 173 | #endif // GTEST_HAS_TYPED_TEST || GTEST_HAS_TYPED_TEST_P |
3330 | 174 | |
3331 | 175 | } // namespace internal |
176 | ||
177 | template <typename... Ts> | |
178 | using Types = internal::ProxyTypeList<Ts...>; | |
179 | ||
3332 | 180 | } // namespace testing |
3333 | 181 | |
3334 | 182 | #endif // GTEST_INCLUDE_GTEST_INTERNAL_GTEST_TYPE_UTIL_H_ |
0 | $$ -*- mode: c++; -*- | |
1 | $var n = 50 $$ Maximum length of type lists we want to support. | |
2 | // Copyright 2008 Google Inc. | |
3 | // All Rights Reserved. | |
4 | // | |
5 | // Redistribution and use in source and binary forms, with or without | |
6 | // modification, are permitted provided that the following conditions are | |
7 | // met: | |
8 | // | |
9 | // * Redistributions of source code must retain the above copyright | |
10 | // notice, this list of conditions and the following disclaimer. | |
11 | // * Redistributions in binary form must reproduce the above | |
12 | // copyright notice, this list of conditions and the following disclaimer | |
13 | // in the documentation and/or other materials provided with the | |
14 | // distribution. | |
15 | // * Neither the name of Google Inc. nor the names of its | |
16 | // contributors may be used to endorse or promote products derived from | |
17 | // this software without specific prior written permission. | |
18 | // | |
19 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS | |
20 | // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT | |
21 | // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR | |
22 | // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT | |
23 | // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, | |
24 | // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT | |
25 | // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, | |
26 | // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY | |
27 | // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | |
28 | // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE | |
29 | // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | |
30 | ||
31 | ||
32 | // Type utilities needed for implementing typed and type-parameterized | |
33 | // tests. This file is generated by a SCRIPT. DO NOT EDIT BY HAND! | |
34 | // | |
35 | // Currently we support at most $n types in a list, and at most $n | |
36 | // type-parameterized tests in one type-parameterized test suite. | |
37 | // Please contact googletestframework@googlegroups.com if you need | |
38 | // more. | |
39 | ||
40 | // GOOGLETEST_CM0001 DO NOT DELETE | |
41 | ||
42 | #ifndef GTEST_INCLUDE_GTEST_INTERNAL_GTEST_TYPE_UTIL_H_ | |
43 | #define GTEST_INCLUDE_GTEST_INTERNAL_GTEST_TYPE_UTIL_H_ | |
44 | ||
45 | #include "gtest/internal/gtest-port.h" | |
46 | ||
47 | // #ifdef __GNUC__ is too general here. It is possible to use gcc without using | |
48 | // libstdc++ (which is where cxxabi.h comes from). | |
49 | # if GTEST_HAS_CXXABI_H_ | |
50 | # include <cxxabi.h> | |
51 | # elif defined(__HP_aCC) | |
52 | # include <acxx_demangle.h> | |
53 | # endif // GTEST_HASH_CXXABI_H_ | |
54 | ||
55 | namespace testing { | |
56 | namespace internal { | |
57 | ||
58 | // Canonicalizes a given name with respect to the Standard C++ Library. | |
59 | // This handles removing the inline namespace within `std` that is | |
60 | // used by various standard libraries (e.g., `std::__1`). Names outside | |
61 | // of namespace std are returned unmodified. | |
62 | inline std::string CanonicalizeForStdLibVersioning(std::string s) { | |
63 | static const char prefix[] = "std::__"; | |
64 | if (s.compare(0, strlen(prefix), prefix) == 0) { | |
65 | std::string::size_type end = s.find("::", strlen(prefix)); | |
66 | if (end != s.npos) { | |
67 | // Erase everything between the initial `std` and the second `::`. | |
68 | s.erase(strlen("std"), end - strlen("std")); | |
69 | } | |
70 | } | |
71 | return s; | |
72 | } | |
73 | ||
74 | // GetTypeName<T>() returns a human-readable name of type T. | |
75 | // NB: This function is also used in Google Mock, so don't move it inside of | |
76 | // the typed-test-only section below. | |
77 | template <typename T> | |
78 | std::string GetTypeName() { | |
79 | # if GTEST_HAS_RTTI | |
80 | ||
81 | const char* const name = typeid(T).name(); | |
82 | # if GTEST_HAS_CXXABI_H_ || defined(__HP_aCC) | |
83 | int status = 0; | |
84 | // gcc's implementation of typeid(T).name() mangles the type name, | |
85 | // so we have to demangle it. | |
86 | # if GTEST_HAS_CXXABI_H_ | |
87 | using abi::__cxa_demangle; | |
88 | # endif // GTEST_HAS_CXXABI_H_ | |
89 | char* const readable_name = __cxa_demangle(name, nullptr, nullptr, &status); | |
90 | const std::string name_str(status == 0 ? readable_name : name); | |
91 | free(readable_name); | |
92 | return CanonicalizeForStdLibVersioning(name_str); | |
93 | # else | |
94 | return name; | |
95 | # endif // GTEST_HAS_CXXABI_H_ || __HP_aCC | |
96 | ||
97 | # else | |
98 | ||
99 | return "<type>"; | |
100 | ||
101 | # endif // GTEST_HAS_RTTI | |
102 | } | |
103 | ||
104 | #if GTEST_HAS_TYPED_TEST || GTEST_HAS_TYPED_TEST_P | |
105 | ||
106 | // A unique type used as the default value for the arguments of class | |
107 | // template Types. This allows us to simulate variadic templates | |
108 | // (e.g. Types<int>, Type<int, double>, and etc), which C++ doesn't | |
109 | // support directly. | |
110 | struct None {}; | |
111 | ||
112 | // The following family of struct and struct templates are used to | |
113 | // represent type lists. In particular, TypesN<T1, T2, ..., TN> | |
114 | // represents a type list with N types (T1, T2, ..., and TN) in it. | |
115 | // Except for Types0, every struct in the family has two member types: | |
116 | // Head for the first type in the list, and Tail for the rest of the | |
117 | // list. | |
118 | ||
119 | // The empty type list. | |
120 | struct Types0 {}; | |
121 | ||
122 | // Type lists of length 1, 2, 3, and so on. | |
123 | ||
124 | template <typename T1> | |
125 | struct Types1 { | |
126 | typedef T1 Head; | |
127 | typedef Types0 Tail; | |
128 | }; | |
129 | ||
130 | $range i 2..n | |
131 | ||
132 | $for i [[ | |
133 | $range j 1..i | |
134 | $range k 2..i | |
135 | template <$for j, [[typename T$j]]> | |
136 | struct Types$i { | |
137 | typedef T1 Head; | |
138 | typedef Types$(i-1)<$for k, [[T$k]]> Tail; | |
139 | }; | |
140 | ||
141 | ||
142 | ]] | |
143 | ||
144 | } // namespace internal | |
145 | ||
146 | // We don't want to require the users to write TypesN<...> directly, | |
147 | // as that would require them to count the length. Types<...> is much | |
148 | // easier to write, but generates horrible messages when there is a | |
149 | // compiler error, as gcc insists on printing out each template | |
150 | // argument, even if it has the default value (this means Types<int> | |
151 | // will appear as Types<int, None, None, ..., None> in the compiler | |
152 | // errors). | |
153 | // | |
154 | // Our solution is to combine the best part of the two approaches: a | |
155 | // user would write Types<T1, ..., TN>, and Google Test will translate | |
156 | // that to TypesN<T1, ..., TN> internally to make error messages | |
157 | // readable. The translation is done by the 'type' member of the | |
158 | // Types template. | |
159 | ||
160 | $range i 1..n | |
161 | template <$for i, [[typename T$i = internal::None]]> | |
162 | struct Types { | |
163 | typedef internal::Types$n<$for i, [[T$i]]> type; | |
164 | }; | |
165 | ||
166 | template <> | |
167 | struct Types<$for i, [[internal::None]]> { | |
168 | typedef internal::Types0 type; | |
169 | }; | |
170 | ||
171 | $range i 1..n-1 | |
172 | $for i [[ | |
173 | $range j 1..i | |
174 | $range k i+1..n | |
175 | template <$for j, [[typename T$j]]> | |
176 | struct Types<$for j, [[T$j]]$for k[[, internal::None]]> { | |
177 | typedef internal::Types$i<$for j, [[T$j]]> type; | |
178 | }; | |
179 | ||
180 | ]] | |
181 | ||
182 | namespace internal { | |
183 | ||
184 | # define GTEST_TEMPLATE_ template <typename T> class | |
185 | ||
186 | // The template "selector" struct TemplateSel<Tmpl> is used to | |
187 | // represent Tmpl, which must be a class template with one type | |
188 | // parameter, as a type. TemplateSel<Tmpl>::Bind<T>::type is defined | |
189 | // as the type Tmpl<T>. This allows us to actually instantiate the | |
190 | // template "selected" by TemplateSel<Tmpl>. | |
191 | // | |
192 | // This trick is necessary for simulating typedef for class templates, | |
193 | // which C++ doesn't support directly. | |
194 | template <GTEST_TEMPLATE_ Tmpl> | |
195 | struct TemplateSel { | |
196 | template <typename T> | |
197 | struct Bind { | |
198 | typedef Tmpl<T> type; | |
199 | }; | |
200 | }; | |
201 | ||
202 | # define GTEST_BIND_(TmplSel, T) \ | |
203 | TmplSel::template Bind<T>::type | |
204 | ||
205 | // A unique struct template used as the default value for the | |
206 | // arguments of class template Templates. This allows us to simulate | |
207 | // variadic templates (e.g. Templates<int>, Templates<int, double>, | |
208 | // and etc), which C++ doesn't support directly. | |
209 | template <typename T> | |
210 | struct NoneT {}; | |
211 | ||
212 | // The following family of struct and struct templates are used to | |
213 | // represent template lists. In particular, TemplatesN<T1, T2, ..., | |
214 | // TN> represents a list of N templates (T1, T2, ..., and TN). Except | |
215 | // for Templates0, every struct in the family has two member types: | |
216 | // Head for the selector of the first template in the list, and Tail | |
217 | // for the rest of the list. | |
218 | ||
219 | // The empty template list. | |
220 | struct Templates0 {}; | |
221 | ||
222 | // Template lists of length 1, 2, 3, and so on. | |
223 | ||
224 | template <GTEST_TEMPLATE_ T1> | |
225 | struct Templates1 { | |
226 | typedef TemplateSel<T1> Head; | |
227 | typedef Templates0 Tail; | |
228 | }; | |
229 | ||
230 | $range i 2..n | |
231 | ||
232 | $for i [[ | |
233 | $range j 1..i | |
234 | $range k 2..i | |
235 | template <$for j, [[GTEST_TEMPLATE_ T$j]]> | |
236 | struct Templates$i { | |
237 | typedef TemplateSel<T1> Head; | |
238 | typedef Templates$(i-1)<$for k, [[T$k]]> Tail; | |
239 | }; | |
240 | ||
241 | ||
242 | ]] | |
243 | ||
244 | // We don't want to require the users to write TemplatesN<...> directly, | |
245 | // as that would require them to count the length. Templates<...> is much | |
246 | // easier to write, but generates horrible messages when there is a | |
247 | // compiler error, as gcc insists on printing out each template | |
248 | // argument, even if it has the default value (this means Templates<list> | |
249 | // will appear as Templates<list, NoneT, NoneT, ..., NoneT> in the compiler | |
250 | // errors). | |
251 | // | |
252 | // Our solution is to combine the best part of the two approaches: a | |
253 | // user would write Templates<T1, ..., TN>, and Google Test will translate | |
254 | // that to TemplatesN<T1, ..., TN> internally to make error messages | |
255 | // readable. The translation is done by the 'type' member of the | |
256 | // Templates template. | |
257 | ||
258 | $range i 1..n | |
259 | template <$for i, [[GTEST_TEMPLATE_ T$i = NoneT]]> | |
260 | struct Templates { | |
261 | typedef Templates$n<$for i, [[T$i]]> type; | |
262 | }; | |
263 | ||
264 | template <> | |
265 | struct Templates<$for i, [[NoneT]]> { | |
266 | typedef Templates0 type; | |
267 | }; | |
268 | ||
269 | $range i 1..n-1 | |
270 | $for i [[ | |
271 | $range j 1..i | |
272 | $range k i+1..n | |
273 | template <$for j, [[GTEST_TEMPLATE_ T$j]]> | |
274 | struct Templates<$for j, [[T$j]]$for k[[, NoneT]]> { | |
275 | typedef Templates$i<$for j, [[T$j]]> type; | |
276 | }; | |
277 | ||
278 | ]] | |
279 | ||
280 | // The TypeList template makes it possible to use either a single type | |
281 | // or a Types<...> list in TYPED_TEST_SUITE() and | |
282 | // INSTANTIATE_TYPED_TEST_SUITE_P(). | |
283 | ||
284 | template <typename T> | |
285 | struct TypeList { | |
286 | typedef Types1<T> type; | |
287 | }; | |
288 | ||
289 | ||
290 | $range i 1..n | |
291 | template <$for i, [[typename T$i]]> | |
292 | struct TypeList<Types<$for i, [[T$i]]> > { | |
293 | typedef typename Types<$for i, [[T$i]]>::type type; | |
294 | }; | |
295 | ||
296 | #endif // GTEST_HAS_TYPED_TEST || GTEST_HAS_TYPED_TEST_P | |
297 | ||
298 | } // namespace internal | |
299 | } // namespace testing | |
300 | ||
301 | #endif // GTEST_INCLUDE_GTEST_INTERNAL_GTEST_TYPE_UTIL_H_ |
1363 | 1363 | |
1364 | 1364 | if (!use_fork) { |
1365 | 1365 | static const bool stack_grows_down = StackGrowsDown(); |
1366 | const auto stack_size = static_cast<size_t>(getpagesize()); | |
1366 | const auto stack_size = static_cast<size_t>(getpagesize() * 2); | |
1367 | 1367 | // MMAP_ANONYMOUS is not defined on Mac, so we use MAP_ANON instead. |
1368 | 1368 | void* const stack = mmap(nullptr, stack_size, PROT_READ | PROT_WRITE, |
1369 | 1369 | MAP_ANON | MAP_PRIVATE, -1, 0); |
92 | 92 | // Returns the current working directory, or "" if unsuccessful. |
93 | 93 | FilePath FilePath::GetCurrentDir() { |
94 | 94 | #if GTEST_OS_WINDOWS_MOBILE || GTEST_OS_WINDOWS_PHONE || \ |
95 | GTEST_OS_WINDOWS_RT || ARDUINO || defined(ESP_PLATFORM) | |
95 | GTEST_OS_WINDOWS_RT || GTEST_OS_ESP8266 || GTEST_OS_ESP32 | |
96 | 96 | // These platforms do not have a current directory, so we just return |
97 | 97 | // something reasonable. |
98 | 98 | return FilePath(kCurrentDirectoryString); |
322 | 322 | delete [] unicode; |
323 | 323 | #elif GTEST_OS_WINDOWS |
324 | 324 | int result = _mkdir(pathname_.c_str()); |
325 | #elif GTEST_OS_ESP8266 | |
326 | // do nothing | |
327 | int result = 0; | |
325 | 328 | #else |
326 | 329 | int result = mkdir(pathname_.c_str(), 0777); |
327 | 330 | #endif // GTEST_OS_WINDOWS_MOBILE |
41 | 41 | #include <string.h> // For memmove. |
42 | 42 | |
43 | 43 | #include <algorithm> |
44 | #include <cstdint> | |
44 | 45 | #include <memory> |
45 | 46 | #include <string> |
46 | 47 | #include <vector> |
122 | 123 | // On success, stores the value of the flag in *value, and returns |
123 | 124 | // true. On failure, returns false without changing *value. |
124 | 125 | GTEST_API_ bool ParseInt32Flag( |
125 | const char* str, const char* flag, Int32* value); | |
126 | const char* str, const char* flag, int32_t* value); | |
126 | 127 | |
127 | 128 | // Returns a random seed in range [1, kMaxRandomSeed] based on the |
128 | 129 | // given --gtest_random_seed flag value. |
129 | inline int GetRandomSeedFromFlag(Int32 random_seed_flag) { | |
130 | inline int GetRandomSeedFromFlag(int32_t random_seed_flag) { | |
130 | 131 | const unsigned int raw_seed = (random_seed_flag == 0) ? |
131 | 132 | static_cast<unsigned int>(GetTimeInMillis()) : |
132 | 133 | static_cast<unsigned int>(random_seed_flag); |
212 | 213 | std::string output_; |
213 | 214 | bool print_time_; |
214 | 215 | bool print_utf8_; |
215 | internal::Int32 random_seed_; | |
216 | internal::Int32 repeat_; | |
216 | int32_t random_seed_; | |
217 | int32_t repeat_; | |
217 | 218 | bool shuffle_; |
218 | internal::Int32 stack_trace_depth_; | |
219 | int32_t stack_trace_depth_; | |
219 | 220 | std::string stream_result_to_; |
220 | 221 | bool throw_on_failure_; |
221 | 222 | } GTEST_ATTRIBUTE_UNUSED_; |
226 | 227 | // If the code_point is not a valid Unicode code point |
227 | 228 | // (i.e. outside of Unicode range U+0 to U+10FFFF) it will be converted |
228 | 229 | // to "(Invalid Unicode 0xXXXXXXXX)". |
229 | GTEST_API_ std::string CodePointToUtf8(UInt32 code_point); | |
230 | GTEST_API_ std::string CodePointToUtf8(uint32_t code_point); | |
230 | 231 | |
231 | 232 | // Converts a wide string to a narrow string in UTF-8 encoding. |
232 | 233 | // The wide string is assumed to have the following encoding: |
259 | 260 | const char* shard_index_str, |
260 | 261 | bool in_subprocess_for_death_test); |
261 | 262 | |
262 | // Parses the environment variable var as an Int32. If it is unset, | |
263 | // returns default_val. If it is not an Int32, prints an error and | |
263 | // Parses the environment variable var as a 32-bit integer. If it is unset, | |
264 | // returns default_val. If it is not a 32-bit integer, prints an error and | |
264 | 265 | // and aborts. |
265 | GTEST_API_ Int32 Int32FromEnvOrDie(const char* env_var, Int32 default_val); | |
266 | GTEST_API_ int32_t Int32FromEnvOrDie(const char* env_var, int32_t default_val); | |
266 | 267 | |
267 | 268 | // Given the total number of shards, the shard index, and the test id, |
268 | 269 | // returns true if and only if the test should be run on this shard. The test id |
322 | 323 | const int last_in_range = begin + range_width - 1; |
323 | 324 | const int selected = |
324 | 325 | begin + |
325 | static_cast<int>(random->Generate(static_cast<UInt32>(range_width))); | |
326 | static_cast<int>(random->Generate(static_cast<uint32_t>(range_width))); | |
326 | 327 | std::swap((*v)[static_cast<size_t>(selected)], |
327 | 328 | (*v)[static_cast<size_t>(last_in_range)]); |
328 | 329 | } |
696 | 697 | return parameterized_test_registry_; |
697 | 698 | } |
698 | 699 | |
700 | std::set<std::string>* ignored_parameterized_test_suites() { | |
701 | return &ignored_parameterized_test_suites_; | |
702 | } | |
703 | ||
704 | // Returns TypeParameterizedTestSuiteRegistry object used to keep track of | |
705 | // type-parameterized tests and instantiations of them. | |
706 | internal::TypeParameterizedTestSuiteRegistry& | |
707 | type_parameterized_test_registry() { | |
708 | return type_parameterized_test_registry_; | |
709 | } | |
710 | ||
699 | 711 | // Sets the TestSuite object for the test that's currently running. |
700 | 712 | void set_current_test_suite(TestSuite* a_current_test_suite) { |
701 | 713 | current_test_suite_ = a_current_test_suite; |
872 | 884 | // ParameterizedTestRegistry object used to register value-parameterized |
873 | 885 | // tests. |
874 | 886 | internal::ParameterizedTestSuiteRegistry parameterized_test_registry_; |
887 | internal::TypeParameterizedTestSuiteRegistry | |
888 | type_parameterized_test_registry_; | |
889 | ||
890 | // The set holding the name of parameterized | |
891 | // test suites that may go uninstantiated. | |
892 | std::set<std::string> ignored_parameterized_test_suites_; | |
875 | 893 | |
876 | 894 | // Indicates whether RegisterParameterizedTests() has been called already. |
877 | 895 | bool parameterized_tests_registered_; |
998 | 1016 | char* end; |
999 | 1017 | // BiggestConvertible is the largest integer type that system-provided |
1000 | 1018 | // string-to-number conversion routines can return. |
1001 | ||
1002 | # if GTEST_OS_WINDOWS && !defined(__GNUC__) | |
1003 | ||
1004 | // MSVC and C++ Builder define __int64 instead of the standard long long. | |
1005 | typedef unsigned __int64 BiggestConvertible; | |
1006 | const BiggestConvertible parsed = _strtoui64(str.c_str(), &end, 10); | |
1007 | ||
1008 | # else | |
1009 | ||
1010 | typedef unsigned long long BiggestConvertible; // NOLINT | |
1011 | const BiggestConvertible parsed = strtoull(str.c_str(), &end, 10); | |
1012 | ||
1013 | # endif // GTEST_OS_WINDOWS && !defined(__GNUC__) | |
1014 | ||
1019 | using BiggestConvertible = unsigned long long; // NOLINT | |
1020 | ||
1021 | const BiggestConvertible parsed = strtoull(str.c_str(), &end, 10); // NOLINT | |
1015 | 1022 | const bool parse_success = *end == '\0' && errno == 0; |
1016 | 1023 | |
1017 | 1024 | GTEST_CHECK_(sizeof(Integer) <= sizeof(parsed)); |
57 | 57 | // s. |
58 | 58 | Matcher<std::string>::Matcher(const char* s) { *this = Eq(std::string(s)); } |
59 | 59 | |
60 | #if GTEST_HAS_ABSL | |
61 | // Constructs a matcher that matches a const absl::string_view& whose value is | |
60 | #if GTEST_INTERNAL_HAS_STRING_VIEW | |
61 | // Constructs a matcher that matches a const StringView& whose value is | |
62 | 62 | // equal to s. |
63 | Matcher<const absl::string_view&>::Matcher(const std::string& s) { | |
63 | Matcher<const internal::StringView&>::Matcher(const std::string& s) { | |
64 | 64 | *this = Eq(s); |
65 | 65 | } |
66 | 66 | |
67 | // Constructs a matcher that matches a const absl::string_view& whose value is | |
67 | // Constructs a matcher that matches a const StringView& whose value is | |
68 | 68 | // equal to s. |
69 | Matcher<const absl::string_view&>::Matcher(const char* s) { | |
69 | Matcher<const internal::StringView&>::Matcher(const char* s) { | |
70 | 70 | *this = Eq(std::string(s)); |
71 | 71 | } |
72 | 72 | |
73 | // Constructs a matcher that matches a const absl::string_view& whose value is | |
73 | // Constructs a matcher that matches a const StringView& whose value is | |
74 | 74 | // equal to s. |
75 | Matcher<const absl::string_view&>::Matcher(absl::string_view s) { | |
75 | Matcher<const internal::StringView&>::Matcher(internal::StringView s) { | |
76 | 76 | *this = Eq(std::string(s)); |
77 | 77 | } |
78 | 78 | |
79 | // Constructs a matcher that matches a absl::string_view whose value is equal to | |
79 | // Constructs a matcher that matches a StringView whose value is equal to | |
80 | 80 | // s. |
81 | Matcher<absl::string_view>::Matcher(const std::string& s) { *this = Eq(s); } | |
81 | Matcher<internal::StringView>::Matcher(const std::string& s) { *this = Eq(s); } | |
82 | 82 | |
83 | // Constructs a matcher that matches a absl::string_view whose value is equal to | |
83 | // Constructs a matcher that matches a StringView whose value is equal to | |
84 | 84 | // s. |
85 | Matcher<absl::string_view>::Matcher(const char* s) { | |
85 | Matcher<internal::StringView>::Matcher(const char* s) { | |
86 | 86 | *this = Eq(std::string(s)); |
87 | 87 | } |
88 | 88 | |
89 | // Constructs a matcher that matches a absl::string_view whose value is equal to | |
89 | // Constructs a matcher that matches a StringView whose value is equal to | |
90 | 90 | // s. |
91 | Matcher<absl::string_view>::Matcher(absl::string_view s) { | |
91 | Matcher<internal::StringView>::Matcher(internal::StringView s) { | |
92 | 92 | *this = Eq(std::string(s)); |
93 | 93 | } |
94 | #endif // GTEST_HAS_ABSL | |
94 | #endif // GTEST_INTERNAL_HAS_STRING_VIEW | |
95 | 95 | |
96 | 96 | } // namespace testing |
33 | 33 | #include <stdio.h> |
34 | 34 | #include <stdlib.h> |
35 | 35 | #include <string.h> |
36 | #include <cstdint> | |
36 | 37 | #include <fstream> |
37 | 38 | #include <memory> |
38 | 39 | |
535 | 536 | // Returns a value that can be used to identify the thread from other threads. |
536 | 537 | static ThreadLocalValueHolderBase* GetValueOnCurrentThread( |
537 | 538 | const ThreadLocalBase* thread_local_instance) { |
539 | #ifdef _MSC_VER | |
540 | MemoryIsNotDeallocated memory_is_not_deallocated; | |
541 | #endif // _MSC_VER | |
538 | 542 | DWORD current_thread = ::GetCurrentThreadId(); |
539 | 543 | MutexLock lock(&mutex_); |
540 | 544 | ThreadIdToThreadLocals* const thread_to_thread_locals = |
1285 | 1289 | // Parses 'str' for a 32-bit signed integer. If successful, writes |
1286 | 1290 | // the result to *value and returns true; otherwise leaves *value |
1287 | 1291 | // unchanged and returns false. |
1288 | bool ParseInt32(const Message& src_text, const char* str, Int32* value) { | |
1292 | bool ParseInt32(const Message& src_text, const char* str, int32_t* value) { | |
1289 | 1293 | // Parses the environment variable as a decimal integer. |
1290 | 1294 | char* end = nullptr; |
1291 | 1295 | const long long_value = strtol(str, &end, 10); // NOLINT |
1302 | 1306 | return false; |
1303 | 1307 | } |
1304 | 1308 | |
1305 | // Is the parsed value in the range of an Int32? | |
1306 | const Int32 result = static_cast<Int32>(long_value); | |
1309 | // Is the parsed value in the range of an int32_t? | |
1310 | const auto result = static_cast<int32_t>(long_value); | |
1307 | 1311 | if (long_value == LONG_MAX || long_value == LONG_MIN || |
1308 | 1312 | // The parsed value overflows as a long. (strtol() returns |
1309 | 1313 | // LONG_MAX or LONG_MIN when the input overflows.) |
1310 | 1314 | result != long_value |
1311 | // The parsed value overflows as an Int32. | |
1315 | // The parsed value overflows as an int32_t. | |
1312 | 1316 | ) { |
1313 | 1317 | Message msg; |
1314 | 1318 | msg << "WARNING: " << src_text |
1341 | 1345 | // Reads and returns a 32-bit integer stored in the environment |
1342 | 1346 | // variable corresponding to the given flag; if it isn't set or |
1343 | 1347 | // doesn't represent a valid 32-bit integer, returns default_value. |
1344 | Int32 Int32FromGTestEnv(const char* flag, Int32 default_value) { | |
1348 | int32_t Int32FromGTestEnv(const char* flag, int32_t default_value) { | |
1345 | 1349 | #if defined(GTEST_GET_INT32_FROM_ENV_) |
1346 | 1350 | return GTEST_GET_INT32_FROM_ENV_(flag, default_value); |
1347 | 1351 | #else |
1352 | 1356 | return default_value; |
1353 | 1357 | } |
1354 | 1358 | |
1355 | Int32 result = default_value; | |
1359 | int32_t result = default_value; | |
1356 | 1360 | if (!ParseInt32(Message() << "Environment variable " << env_var, |
1357 | 1361 | string_value, &result)) { |
1358 | 1362 | printf("The default value %s is used.\n", |
30 | 30 | // The Google C++ Testing and Mocking Framework (Google Test) |
31 | 31 | |
32 | 32 | #include "gtest/gtest-test-part.h" |
33 | ||
34 | #include "gtest/internal/gtest-port.h" | |
33 | 35 | #include "src/gtest-internal-inl.h" |
34 | 36 | |
35 | 37 | namespace testing { |
45 | 47 | |
46 | 48 | // Prints a TestPartResult object. |
47 | 49 | std::ostream& operator<<(std::ostream& os, const TestPartResult& result) { |
48 | return os << result.file_name() << ":" << result.line_number() << ": " | |
50 | return os << internal::FormatFileLocation(result.file_name(), | |
51 | result.line_number()) | |
52 | << " " | |
49 | 53 | << (result.type() == TestPartResult::kSuccess |
50 | 54 | ? "Success" |
51 | 55 | : result.type() == TestPartResult::kSkip |
57 | 57 | // registered_tests_; returns registered_tests if successful, or |
58 | 58 | // aborts the program otherwise. |
59 | 59 | const char* TypedTestSuitePState::VerifyRegisteredTestNames( |
60 | const char* file, int line, const char* registered_tests) { | |
60 | const char* test_suite_name, const char* file, int line, | |
61 | const char* registered_tests) { | |
62 | RegisterTypeParameterizedTestSuite(test_suite_name, CodeLocation(file, line)); | |
63 | ||
61 | 64 | typedef RegisteredTestsMap::const_iterator RegisteredTestIter; |
62 | 65 | registered_ = true; |
63 | 66 |
43 | 43 | #include <wctype.h> |
44 | 44 | |
45 | 45 | #include <algorithm> |
46 | #include <cstdint> | |
46 | 47 | #include <iomanip> |
47 | 48 | #include <limits> |
48 | 49 | #include <list> |
82 | 83 | # include <windows.h> // NOLINT |
83 | 84 | # undef min |
84 | 85 | |
86 | #ifdef _MSC_VER | |
85 | 87 | # include <crtdbg.h> // NOLINT |
86 | 88 | # include <debugapi.h> // NOLINT |
89 | #endif | |
90 | ||
87 | 91 | # include <io.h> // NOLINT |
88 | 92 | # include <sys/timeb.h> // NOLINT |
89 | 93 | # include <sys/types.h> // NOLINT |
329 | 333 | // Generates a random number from [0, range), using a Linear |
330 | 334 | // Congruential Generator (LCG). Crashes if 'range' is 0 or greater |
331 | 335 | // than kMaxRange. |
332 | UInt32 Random::Generate(UInt32 range) { | |
336 | uint32_t Random::Generate(uint32_t range) { | |
333 | 337 | // These constants are the same as are used in glibc's rand(3). |
334 | 338 | // Use wider types than necessary to prevent unsigned overflow diagnostics. |
335 | state_ = static_cast<UInt32>(1103515245ULL*state_ + 12345U) % kMaxRange; | |
339 | state_ = static_cast<uint32_t>(1103515245ULL*state_ + 12345U) % kMaxRange; | |
336 | 340 | |
337 | 341 | GTEST_CHECK_(range > 0) |
338 | 342 | << "Cannot generate a number in the range [0, 0)."; |
400 | 404 | ->CurrentOsStackTraceExceptTop(1) |
401 | 405 | // Skips the stack frame for this function itself. |
402 | 406 | ); // NOLINT |
407 | } | |
408 | ||
409 | namespace { | |
410 | ||
411 | // When TEST_P is found without a matching INSTANTIATE_TEST_SUITE_P | |
412 | // to creates test cases for it, a syntetic test case is | |
413 | // inserted to report ether an error or a log message. | |
414 | // | |
415 | // This configuration bit will likely be removed at some point. | |
416 | constexpr bool kErrorOnUninstantiatedParameterizedTest = true; | |
417 | constexpr bool kErrorOnUninstantiatedTypeParameterizedTest = true; | |
418 | ||
419 | // A test that fails at a given file/line location with a given message. | |
420 | class FailureTest : public Test { | |
421 | public: | |
422 | explicit FailureTest(const CodeLocation& loc, std::string error_message, | |
423 | bool as_error) | |
424 | : loc_(loc), | |
425 | error_message_(std::move(error_message)), | |
426 | as_error_(as_error) {} | |
427 | ||
428 | void TestBody() override { | |
429 | if (as_error_) { | |
430 | AssertHelper(TestPartResult::kNonFatalFailure, loc_.file.c_str(), | |
431 | loc_.line, "") = Message() << error_message_; | |
432 | } else { | |
433 | std::cout << error_message_ << std::endl; | |
434 | } | |
435 | } | |
436 | ||
437 | private: | |
438 | const CodeLocation loc_; | |
439 | const std::string error_message_; | |
440 | const bool as_error_; | |
441 | }; | |
442 | ||
443 | ||
444 | } // namespace | |
445 | ||
446 | std::set<std::string>* GetIgnoredParameterizedTestSuites() { | |
447 | return UnitTest::GetInstance()->impl()->ignored_parameterized_test_suites(); | |
448 | } | |
449 | ||
450 | // Add a given test_suit to the list of them allow to go un-instantiated. | |
451 | MarkAsIgnored::MarkAsIgnored(const char* test_suite) { | |
452 | GetIgnoredParameterizedTestSuites()->insert(test_suite); | |
453 | } | |
454 | ||
455 | // If this parameterized test suite has no instantiations (and that | |
456 | // has not been marked as okay), emit a test case reporting that. | |
457 | void InsertSyntheticTestCase(const std::string& name, CodeLocation location, | |
458 | bool has_test_p) { | |
459 | const auto& ignored = *GetIgnoredParameterizedTestSuites(); | |
460 | if (ignored.find(name) != ignored.end()) return; | |
461 | ||
462 | const char kMissingInstantiation[] = // | |
463 | " is defined via TEST_P, but never instantiated. None of the test cases " | |
464 | "will run. Either no INSTANTIATE_TEST_SUITE_P is provided or the only " | |
465 | "ones provided expand to nothing." | |
466 | "\n\n" | |
467 | "Ideally, TEST_P definitions should only ever be included as part of " | |
468 | "binaries that intend to use them. (As opposed to, for example, being " | |
469 | "placed in a library that may be linked in to get other utilities.)"; | |
470 | ||
471 | const char kMissingTestCase[] = // | |
472 | " is instantiated via INSTANTIATE_TEST_SUITE_P, but no tests are " | |
473 | "defined via TEST_P . No test cases will run." | |
474 | "\n\n" | |
475 | "Ideally, INSTANTIATE_TEST_SUITE_P should only ever be invoked from " | |
476 | "code that always depend on code that provides TEST_P. Failing to do " | |
477 | "so is often an indication of dead code, e.g. the last TEST_P was " | |
478 | "removed but the rest got left behind."; | |
479 | ||
480 | std::string message = | |
481 | "Paramaterized test suite " + name + | |
482 | (has_test_p ? kMissingInstantiation : kMissingTestCase) + | |
483 | "\n\n" | |
484 | "To suppress this error for this test suite, insert the following line " | |
485 | "(in a non-header) in the namespace it is defined in:" | |
486 | "\n\n" | |
487 | "GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(" + name + ");"; | |
488 | ||
489 | std::string full_name = "UninstantiatedParamaterizedTestSuite<" + name + ">"; | |
490 | RegisterTest( // | |
491 | "GoogleTestVerification", full_name.c_str(), | |
492 | nullptr, // No type parameter. | |
493 | nullptr, // No value parameter. | |
494 | location.file.c_str(), location.line, [message, location] { | |
495 | return new FailureTest(location, message, | |
496 | kErrorOnUninstantiatedParameterizedTest); | |
497 | }); | |
498 | } | |
499 | ||
500 | void RegisterTypeParameterizedTestSuite(const char* test_suite_name, | |
501 | CodeLocation code_location) { | |
502 | GetUnitTestImpl()->type_parameterized_test_registry().RegisterTestSuite( | |
503 | test_suite_name, code_location); | |
504 | } | |
505 | ||
506 | void RegisterTypeParameterizedTestSuiteInstantiation(const char* case_name) { | |
507 | GetUnitTestImpl() | |
508 | ->type_parameterized_test_registry() | |
509 | .RegisterInstantiation(case_name); | |
510 | } | |
511 | ||
512 | void TypeParameterizedTestSuiteRegistry::RegisterTestSuite( | |
513 | const char* test_suite_name, CodeLocation code_location) { | |
514 | suites_.emplace(std::string(test_suite_name), | |
515 | TypeParameterizedTestSuiteInfo(code_location)); | |
516 | } | |
517 | ||
518 | void TypeParameterizedTestSuiteRegistry::RegisterInstantiation( | |
519 | const char* test_suite_name) { | |
520 | auto it = suites_.find(std::string(test_suite_name)); | |
521 | if (it != suites_.end()) { | |
522 | it->second.instantiated = true; | |
523 | } else { | |
524 | GTEST_LOG_(ERROR) << "Unknown type parameterized test suit '" | |
525 | << test_suite_name << "'"; | |
526 | } | |
527 | } | |
528 | ||
529 | void TypeParameterizedTestSuiteRegistry::CheckForInstantiations() { | |
530 | const auto& ignored = *GetIgnoredParameterizedTestSuites(); | |
531 | for (const auto& testcase : suites_) { | |
532 | if (testcase.second.instantiated) continue; | |
533 | if (ignored.find(testcase.first) != ignored.end()) continue; | |
534 | ||
535 | std::string message = | |
536 | "Type paramaterized test suite " + testcase.first + | |
537 | " is defined via REGISTER_TYPED_TEST_SUITE_P, but never instantiated " | |
538 | "via INSTANTIATE_TYPED_TEST_SUITE_P. None of the test cases will run." | |
539 | "\n\n" | |
540 | "Ideally, TYPED_TEST_P definitions should only ever be included as " | |
541 | "part of binaries that intend to use them. (As opposed to, for " | |
542 | "example, being placed in a library that may be linked in to get other " | |
543 | "utilities.)" | |
544 | "\n\n" | |
545 | "To suppress this error for this test suite, insert the following line " | |
546 | "(in a non-header) in the namespace it is definedin in:" | |
547 | "\n\n" | |
548 | "GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(" + | |
549 | testcase.first + ");"; | |
550 | ||
551 | std::string full_name = | |
552 | "UninstantiatedTypeParamaterizedTestSuite<" + testcase.first + ">"; | |
553 | RegisterTest( // | |
554 | "GoogleTestVerification", full_name.c_str(), | |
555 | nullptr, // No type parameter. | |
556 | nullptr, // No value parameter. | |
557 | testcase.second.code_location.file.c_str(), | |
558 | testcase.second.code_location.line, [message, testcase] { | |
559 | return new FailureTest(testcase.second.code_location, message, | |
560 | kErrorOnUninstantiatedTypeParameterizedTest); | |
561 | }); | |
562 | } | |
403 | 563 | } |
404 | 564 | |
405 | 565 | // A copy of all command line arguments. Set by InitGoogleTest(). |
1734 | 1894 | // 17 - 21 bits 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx |
1735 | 1895 | |
1736 | 1896 | // The maximum code-point a one-byte UTF-8 sequence can represent. |
1737 | const UInt32 kMaxCodePoint1 = (static_cast<UInt32>(1) << 7) - 1; | |
1897 | constexpr uint32_t kMaxCodePoint1 = (static_cast<uint32_t>(1) << 7) - 1; | |
1738 | 1898 | |
1739 | 1899 | // The maximum code-point a two-byte UTF-8 sequence can represent. |
1740 | const UInt32 kMaxCodePoint2 = (static_cast<UInt32>(1) << (5 + 6)) - 1; | |
1900 | constexpr uint32_t kMaxCodePoint2 = (static_cast<uint32_t>(1) << (5 + 6)) - 1; | |
1741 | 1901 | |
1742 | 1902 | // The maximum code-point a three-byte UTF-8 sequence can represent. |
1743 | const UInt32 kMaxCodePoint3 = (static_cast<UInt32>(1) << (4 + 2*6)) - 1; | |
1903 | constexpr uint32_t kMaxCodePoint3 = (static_cast<uint32_t>(1) << (4 + 2*6)) - 1; | |
1744 | 1904 | |
1745 | 1905 | // The maximum code-point a four-byte UTF-8 sequence can represent. |
1746 | const UInt32 kMaxCodePoint4 = (static_cast<UInt32>(1) << (3 + 3*6)) - 1; | |
1906 | constexpr uint32_t kMaxCodePoint4 = (static_cast<uint32_t>(1) << (3 + 3*6)) - 1; | |
1747 | 1907 | |
1748 | 1908 | // Chops off the n lowest bits from a bit pattern. Returns the n |
1749 | 1909 | // lowest bits. As a side effect, the original bit pattern will be |
1750 | 1910 | // shifted to the right by n bits. |
1751 | inline UInt32 ChopLowBits(UInt32* bits, int n) { | |
1752 | const UInt32 low_bits = *bits & ((static_cast<UInt32>(1) << n) - 1); | |
1911 | inline uint32_t ChopLowBits(uint32_t* bits, int n) { | |
1912 | const uint32_t low_bits = *bits & ((static_cast<uint32_t>(1) << n) - 1); | |
1753 | 1913 | *bits >>= n; |
1754 | 1914 | return low_bits; |
1755 | 1915 | } |
1756 | 1916 | |
1757 | 1917 | // Converts a Unicode code point to a narrow string in UTF-8 encoding. |
1758 | // code_point parameter is of type UInt32 because wchar_t may not be | |
1918 | // code_point parameter is of type uint32_t because wchar_t may not be | |
1759 | 1919 | // wide enough to contain a code point. |
1760 | 1920 | // If the code_point is not a valid Unicode code point |
1761 | 1921 | // (i.e. outside of Unicode range U+0 to U+10FFFF) it will be converted |
1762 | 1922 | // to "(Invalid Unicode 0xXXXXXXXX)". |
1763 | std::string CodePointToUtf8(UInt32 code_point) { | |
1923 | std::string CodePointToUtf8(uint32_t code_point) { | |
1764 | 1924 | if (code_point > kMaxCodePoint4) { |
1765 | 1925 | return "(Invalid Unicode 0x" + String::FormatHexUInt32(code_point) + ")"; |
1766 | 1926 | } |
1801 | 1961 | } |
1802 | 1962 | |
1803 | 1963 | // Creates a Unicode code point from UTF16 surrogate pair. |
1804 | inline UInt32 CreateCodePointFromUtf16SurrogatePair(wchar_t first, | |
1805 | wchar_t second) { | |
1806 | const auto first_u = static_cast<UInt32>(first); | |
1807 | const auto second_u = static_cast<UInt32>(second); | |
1808 | const UInt32 mask = (1 << 10) - 1; | |
1964 | inline uint32_t CreateCodePointFromUtf16SurrogatePair(wchar_t first, | |
1965 | wchar_t second) { | |
1966 | const auto first_u = static_cast<uint32_t>(first); | |
1967 | const auto second_u = static_cast<uint32_t>(second); | |
1968 | const uint32_t mask = (1 << 10) - 1; | |
1809 | 1969 | return (sizeof(wchar_t) == 2) |
1810 | 1970 | ? (((first_u & mask) << 10) | (second_u & mask)) + 0x10000 |
1811 | 1971 | : |
1833 | 1993 | |
1834 | 1994 | ::std::stringstream stream; |
1835 | 1995 | for (int i = 0; i < num_chars; ++i) { |
1836 | UInt32 unicode_code_point; | |
1996 | uint32_t unicode_code_point; | |
1837 | 1997 | |
1838 | 1998 | if (str[i] == L'\0') { |
1839 | 1999 | break; |
1842 | 2002 | str[i + 1]); |
1843 | 2003 | i++; |
1844 | 2004 | } else { |
1845 | unicode_code_point = static_cast<UInt32>(str[i]); | |
2005 | unicode_code_point = static_cast<uint32_t>(str[i]); | |
1846 | 2006 | } |
1847 | 2007 | |
1848 | 2008 | stream << CodePointToUtf8(unicode_code_point); |
1968 | 2128 | } |
1969 | 2129 | |
1970 | 2130 | // Formats an int value as "%X". |
1971 | std::string String::FormatHexUInt32(UInt32 value) { | |
2131 | std::string String::FormatHexUInt32(uint32_t value) { | |
1972 | 2132 | std::stringstream ss; |
1973 | 2133 | ss << std::hex << std::uppercase << value; |
1974 | 2134 | return ss.str(); |
1976 | 2136 | |
1977 | 2137 | // Formats an int value as "%X". |
1978 | 2138 | std::string String::FormatHexInt(int value) { |
1979 | return FormatHexUInt32(static_cast<UInt32>(value)); | |
2139 | return FormatHexUInt32(static_cast<uint32_t>(value)); | |
1980 | 2140 | } |
1981 | 2141 | |
1982 | 2142 | // Formats a byte as "%02X". |
2645 | 2805 | void UnitTestImpl::RegisterParameterizedTests() { |
2646 | 2806 | if (!parameterized_tests_registered_) { |
2647 | 2807 | parameterized_test_registry_.RegisterTests(); |
2808 | type_parameterized_test_registry_.CheckForInstantiations(); | |
2648 | 2809 | parameterized_tests_registered_ = true; |
2649 | 2810 | } |
2650 | 2811 | } |
3133 | 3294 | |
3134 | 3295 | private: |
3135 | 3296 | static void PrintFailedTests(const UnitTest& unit_test); |
3297 | static void PrintFailedTestSuites(const UnitTest& unit_test); | |
3136 | 3298 | static void PrintSkippedTests(const UnitTest& unit_test); |
3137 | 3299 | }; |
3138 | 3300 | |
3152 | 3314 | } |
3153 | 3315 | |
3154 | 3316 | if (internal::ShouldShard(kTestTotalShards, kTestShardIndex, false)) { |
3155 | const Int32 shard_index = Int32FromEnvOrDie(kTestShardIndex, -1); | |
3317 | const int32_t shard_index = Int32FromEnvOrDie(kTestShardIndex, -1); | |
3156 | 3318 | ColoredPrintf(COLOR_YELLOW, |
3157 | 3319 | "Note: This is test shard %d of %s.\n", |
3158 | 3320 | static_cast<int>(shard_index) + 1, |
3219 | 3381 | void PrettyUnitTestResultPrinter::OnTestPartResult( |
3220 | 3382 | const TestPartResult& result) { |
3221 | 3383 | switch (result.type()) { |
3222 | // If the test part succeeded, or was skipped, | |
3223 | // we don't need to do anything. | |
3224 | case TestPartResult::kSkip: | |
3384 | // If the test part succeeded, we don't need to do anything. | |
3225 | 3385 | case TestPartResult::kSuccess: |
3226 | 3386 | return; |
3227 | 3387 | default: |
3287 | 3447 | // Internal helper for printing the list of failed tests. |
3288 | 3448 | void PrettyUnitTestResultPrinter::PrintFailedTests(const UnitTest& unit_test) { |
3289 | 3449 | const int failed_test_count = unit_test.failed_test_count(); |
3290 | if (failed_test_count == 0) { | |
3291 | return; | |
3292 | } | |
3450 | ColoredPrintf(COLOR_RED, "[ FAILED ] "); | |
3451 | printf("%s, listed below:\n", FormatTestCount(failed_test_count).c_str()); | |
3293 | 3452 | |
3294 | 3453 | for (int i = 0; i < unit_test.total_test_suite_count(); ++i) { |
3295 | 3454 | const TestSuite& test_suite = *unit_test.GetTestSuite(i); |
3307 | 3466 | printf("\n"); |
3308 | 3467 | } |
3309 | 3468 | } |
3469 | printf("\n%2d FAILED %s\n", failed_test_count, | |
3470 | failed_test_count == 1 ? "TEST" : "TESTS"); | |
3471 | } | |
3472 | ||
3473 | // Internal helper for printing the list of test suite failures not covered by | |
3474 | // PrintFailedTests. | |
3475 | void PrettyUnitTestResultPrinter::PrintFailedTestSuites( | |
3476 | const UnitTest& unit_test) { | |
3477 | int suite_failure_count = 0; | |
3478 | for (int i = 0; i < unit_test.total_test_suite_count(); ++i) { | |
3479 | const TestSuite& test_suite = *unit_test.GetTestSuite(i); | |
3480 | if (!test_suite.should_run()) { | |
3481 | continue; | |
3482 | } | |
3483 | if (test_suite.ad_hoc_test_result().Failed()) { | |
3484 | ColoredPrintf(COLOR_RED, "[ FAILED ] "); | |
3485 | printf("%s: SetUpTestSuite or TearDownTestSuite\n", test_suite.name()); | |
3486 | ++suite_failure_count; | |
3487 | } | |
3488 | } | |
3489 | if (suite_failure_count > 0) { | |
3490 | printf("\n%2d FAILED TEST %s\n", suite_failure_count, | |
3491 | suite_failure_count == 1 ? "SUITE" : "SUITES"); | |
3492 | } | |
3310 | 3493 | } |
3311 | 3494 | |
3312 | 3495 | // Internal helper for printing the list of skipped tests. |
3354 | 3537 | PrintSkippedTests(unit_test); |
3355 | 3538 | } |
3356 | 3539 | |
3357 | int num_failures = unit_test.failed_test_count(); | |
3358 | 3540 | if (!unit_test.Passed()) { |
3359 | const int failed_test_count = unit_test.failed_test_count(); | |
3360 | ColoredPrintf(COLOR_RED, "[ FAILED ] "); | |
3361 | printf("%s, listed below:\n", FormatTestCount(failed_test_count).c_str()); | |
3362 | 3541 | PrintFailedTests(unit_test); |
3363 | printf("\n%2d FAILED %s\n", num_failures, | |
3364 | num_failures == 1 ? "TEST" : "TESTS"); | |
3542 | PrintFailedTestSuites(unit_test); | |
3365 | 3543 | } |
3366 | 3544 | |
3367 | 3545 | int num_disabled = unit_test.reportable_disabled_test_count(); |
3368 | 3546 | if (num_disabled && !GTEST_FLAG(also_run_disabled_tests)) { |
3369 | if (!num_failures) { | |
3547 | if (unit_test.Passed()) { | |
3370 | 3548 | printf("\n"); // Add a spacer if no FAILURE banner is displayed. |
3371 | 3549 | } |
3372 | 3550 | ColoredPrintf(COLOR_YELLOW, |
4507 | 4685 | } |
4508 | 4686 | |
4509 | 4687 | ~ScopedPrematureExitFile() { |
4688 | #if !defined GTEST_OS_ESP8266 | |
4510 | 4689 | if (!premature_exit_filepath_.empty()) { |
4511 | 4690 | int retval = remove(premature_exit_filepath_.c_str()); |
4512 | 4691 | if (retval) { |
4515 | 4694 | << retval; |
4516 | 4695 | } |
4517 | 4696 | } |
4697 | #endif | |
4518 | 4698 | } |
4519 | 4699 | |
4520 | 4700 | private: |
4907 | 5087 | _set_abort_behavior( |
4908 | 5088 | 0x0, // Clear the following flags: |
4909 | 5089 | _WRITE_ABORT_MSG | _CALL_REPORTFAULT); // pop-up window, core dump. |
4910 | # endif | |
4911 | 5090 | |
4912 | 5091 | // In debug mode, the Windows CRT can crash with an assertion over invalid |
4913 | 5092 | // input (e.g. passing an invalid file descriptor). The default handling |
4918 | 5097 | _CRTDBG_MODE_FILE | _CRTDBG_MODE_DEBUG); |
4919 | 5098 | (void)_CrtSetReportFile(_CRT_ASSERT, _CRTDBG_FILE_STDERR); |
4920 | 5099 | } |
5100 | # endif | |
4921 | 5101 | } |
4922 | 5102 | #endif // GTEST_OS_WINDOWS |
4923 | 5103 | |
5298 | 5478 | |
5299 | 5479 | // Shuffles test suites and tests if requested. |
5300 | 5480 | if (has_tests_to_run && GTEST_FLAG(shuffle)) { |
5301 | random()->Reseed(static_cast<UInt32>(random_seed_)); | |
5481 | random()->Reseed(static_cast<uint32_t>(random_seed_)); | |
5302 | 5482 | // This should be done before calling OnTestIterationStart(), |
5303 | 5483 | // such that a test event listener can see the actual test order |
5304 | 5484 | // in the event. |
5421 | 5601 | return false; |
5422 | 5602 | } |
5423 | 5603 | |
5424 | const Int32 total_shards = Int32FromEnvOrDie(total_shards_env, -1); | |
5425 | const Int32 shard_index = Int32FromEnvOrDie(shard_index_env, -1); | |
5604 | const int32_t total_shards = Int32FromEnvOrDie(total_shards_env, -1); | |
5605 | const int32_t shard_index = Int32FromEnvOrDie(shard_index_env, -1); | |
5426 | 5606 | |
5427 | 5607 | if (total_shards == -1 && shard_index == -1) { |
5428 | 5608 | return false; |
5459 | 5639 | // Parses the environment variable var as an Int32. If it is unset, |
5460 | 5640 | // returns default_val. If it is not an Int32, prints an error |
5461 | 5641 | // and aborts. |
5462 | Int32 Int32FromEnvOrDie(const char* var, Int32 default_val) { | |
5642 | int32_t Int32FromEnvOrDie(const char* var, int32_t default_val) { | |
5463 | 5643 | const char* str_val = posix::GetEnv(var); |
5464 | 5644 | if (str_val == nullptr) { |
5465 | 5645 | return default_val; |
5466 | 5646 | } |
5467 | 5647 | |
5468 | Int32 result; | |
5648 | int32_t result; | |
5469 | 5649 | if (!ParseInt32(Message() << "The value of environment variable " << var, |
5470 | 5650 | str_val, &result)) { |
5471 | 5651 | exit(EXIT_FAILURE); |
5489 | 5669 | // https://github.com/google/googletest/blob/master/googletest/docs/advanced.md |
5490 | 5670 | // . Returns the number of tests that should run. |
5491 | 5671 | int UnitTestImpl::FilterTests(ReactionToSharding shard_tests) { |
5492 | const Int32 total_shards = shard_tests == HONOR_SHARDING_PROTOCOL ? | |
5672 | const int32_t total_shards = shard_tests == HONOR_SHARDING_PROTOCOL ? | |
5493 | 5673 | Int32FromEnvOrDie(kTestTotalShards, -1) : -1; |
5494 | const Int32 shard_index = shard_tests == HONOR_SHARDING_PROTOCOL ? | |
5674 | const int32_t shard_index = shard_tests == HONOR_SHARDING_PROTOCOL ? | |
5495 | 5675 | Int32FromEnvOrDie(kTestShardIndex, -1) : -1; |
5496 | 5676 | |
5497 | 5677 | // num_runnable_tests are the number of tests that will |
5780 | 5960 | return true; |
5781 | 5961 | } |
5782 | 5962 | |
5783 | // Parses a string for an Int32 flag, in the form of | |
5784 | // "--flag=value". | |
5963 | // Parses a string for an int32_t flag, in the form of "--flag=value". | |
5785 | 5964 | // |
5786 | 5965 | // On success, stores the value of the flag in *value, and returns |
5787 | 5966 | // true. On failure, returns false without changing *value. |
5788 | bool ParseInt32Flag(const char* str, const char* flag, Int32* value) { | |
5967 | bool ParseInt32Flag(const char* str, const char* flag, int32_t* value) { | |
5789 | 5968 | // Gets the value of the flag as a string. |
5790 | 5969 | const char* const value_str = ParseFlagValue(str, flag, false); |
5791 | 5970 | |
5797 | 5976 | value_str, value); |
5798 | 5977 | } |
5799 | 5978 | |
5800 | // Parses a string for a string flag, in the form of | |
5801 | // "--flag=value". | |
5979 | // Parses a string for a string flag, in the form of "--flag=value". | |
5802 | 5980 | // |
5803 | 5981 | // On success, stores the value of the flag in *value, and returns |
5804 | 5982 | // true. On failure, returns false without changing *value. |
6148 | 6326 | else |
6149 | 6327 | return std::string(temp_dir) + "\\"; |
6150 | 6328 | #elif GTEST_OS_LINUX_ANDROID |
6151 | return "/sdcard/"; | |
6329 | const char* temp_dir = internal::posix::GetEnv("TEST_TMPDIR"); | |
6330 | if (temp_dir == nullptr || temp_dir[0] == '\0') | |
6331 | return "/data/local/tmp/"; | |
6332 | else | |
6333 | return temp_dir; | |
6152 | 6334 | #else |
6153 | 6335 | return "/tmp/"; |
6154 | 6336 | #endif // GTEST_OS_WINDOWS_MOBILE |
29 | 29 | #include <cstdio> |
30 | 30 | #include "gtest/gtest.h" |
31 | 31 | |
32 | #ifdef ARDUINO | |
32 | #if GTEST_OS_ESP8266 || GTEST_OS_ESP32 | |
33 | #if GTEST_OS_ESP8266 | |
34 | extern "C" { | |
35 | #endif | |
33 | 36 | void setup() { |
34 | 37 | testing::InitGoogleTest(); |
35 | 38 | } |
36 | 39 | |
37 | 40 | void loop() { RUN_ALL_TESTS(); } |
41 | ||
42 | #if GTEST_OS_ESP8266 | |
43 | } | |
44 | #endif | |
38 | 45 | |
39 | 46 | #else |
40 | 47 |
2 | 2 | include $(CLEAR_VARS) |
3 | 3 | LOCAL_MODULE:= libwebm |
4 | 4 | LOCAL_CPPFLAGS:=-D__STDC_CONSTANT_MACROS -D__STDC_FORMAT_MACROS |
5 | LOCAL_CPPFLAGS+=-D__STDC_LIMIT_MACROS -std=c++11 | |
5 | LOCAL_CPPFLAGS+=-D__STDC_LIMIT_MACROS -std=gnu++11 | |
6 | 6 | LOCAL_C_INCLUDES:= $(LOCAL_PATH) |
7 | 7 | LOCAL_EXPORT_C_INCLUDES:= $(LOCAL_PATH) |
8 | 8 |
105 | 105 | for filename, affected_lines in file_affected_line_map.iteritems(): |
106 | 106 | if filename.split(".")[-1] not in ("c", "h", "cc"): |
107 | 107 | continue |
108 | if filename.startswith("third_party"): | |
109 | continue | |
108 | 110 | |
109 | 111 | if args: |
110 | 112 | # File contents come from git |
78 | 78 | --ver=$$(CONFIG_VS_VERSION)\ |
79 | 79 | --proj-guid=$$($$(@:.$(VCPROJ_SFX)=).GUID)\ |
80 | 80 | --src-path-bare="$(SRC_PATH_BARE)" \ |
81 | --as=$$(AS) \ | |
81 | 82 | $$(if $$(CONFIG_STATIC_MSVCRT),--static-crt) \ |
82 | 83 | --out=$$@ $$(INTERNAL_CFLAGS) $$(CFLAGS) \ |
83 | 84 | $$(INTERNAL_LDFLAGS) $$(LDFLAGS) $$^ |
15 | 15 | #include "vpx_ports/x86.h" |
16 | 16 | #elif VPX_ARCH_PPC |
17 | 17 | #include "vpx_ports/ppc.h" |
18 | #elif VPX_ARCH_MIPS | |
19 | #include "vpx_ports/mips.h" | |
18 | 20 | #endif |
19 | 21 | #include "vp8/common/onyxc_int.h" |
20 | 22 | #include "vp8/common/systemdependent.h" |
95 | 97 | ctx->cpu_caps = x86_simd_caps(); |
96 | 98 | #elif VPX_ARCH_PPC |
97 | 99 | ctx->cpu_caps = ppc_simd_caps(); |
100 | #elif VPX_ARCH_MIPS | |
101 | ctx->cpu_caps = mips_cpu_caps(); | |
98 | 102 | #else |
99 | 103 | // generic-gnu targets. |
100 | 104 | ctx->cpu_caps = 0; |
99 | 99 | vp8_short_idct4x4llm_mmi(input, dest, stride, dest, stride); |
100 | 100 | |
101 | 101 | __asm__ volatile( |
102 | "xor %[ftmp0], %[ftmp0], %[ftmp0] \n\t" | |
102 | "pxor %[ftmp0], %[ftmp0], %[ftmp0] \n\t" | |
103 | 103 | "gssdlc1 %[ftmp0], 0x07(%[input]) \n\t" |
104 | 104 | "gssdrc1 %[ftmp0], 0x00(%[input]) \n\t" |
105 | 105 | "sdl $0, 0x0f(%[input]) \n\t" |
12 | 12 | #include "vpx_ports/asmdefs_mmi.h" |
13 | 13 | |
14 | 14 | #define TRANSPOSE_4H \ |
15 | "xor %[ftmp0], %[ftmp0], %[ftmp0] \n\t" \ | |
15 | "pxor %[ftmp0], %[ftmp0], %[ftmp0] \n\t" \ | |
16 | 16 | MMI_LI(%[tmp0], 0x93) \ |
17 | 17 | "mtc1 %[tmp0], %[ftmp10] \n\t" \ |
18 | 18 | "punpcklhw %[ftmp5], %[ftmp1], %[ftmp0] \n\t" \ |
19 | 19 | "punpcklhw %[ftmp9], %[ftmp2], %[ftmp0] \n\t" \ |
20 | 20 | "pshufh %[ftmp9], %[ftmp9], %[ftmp10] \n\t" \ |
21 | "or %[ftmp5], %[ftmp5], %[ftmp9] \n\t" \ | |
21 | "por %[ftmp5], %[ftmp5], %[ftmp9] \n\t" \ | |
22 | 22 | "punpckhhw %[ftmp6], %[ftmp1], %[ftmp0] \n\t" \ |
23 | 23 | "punpckhhw %[ftmp9], %[ftmp2], %[ftmp0] \n\t" \ |
24 | 24 | "pshufh %[ftmp9], %[ftmp9], %[ftmp10] \n\t" \ |
25 | "or %[ftmp6], %[ftmp6], %[ftmp9] \n\t" \ | |
25 | "por %[ftmp6], %[ftmp6], %[ftmp9] \n\t" \ | |
26 | 26 | "punpcklhw %[ftmp7], %[ftmp3], %[ftmp0] \n\t" \ |
27 | 27 | "punpcklhw %[ftmp9], %[ftmp4], %[ftmp0] \n\t" \ |
28 | 28 | "pshufh %[ftmp9], %[ftmp9], %[ftmp10] \n\t" \ |
29 | "or %[ftmp7], %[ftmp7], %[ftmp9] \n\t" \ | |
29 | "por %[ftmp7], %[ftmp7], %[ftmp9] \n\t" \ | |
30 | 30 | "punpckhhw %[ftmp8], %[ftmp3], %[ftmp0] \n\t" \ |
31 | 31 | "punpckhhw %[ftmp9], %[ftmp4], %[ftmp0] \n\t" \ |
32 | 32 | "pshufh %[ftmp9], %[ftmp9], %[ftmp10] \n\t" \ |
33 | "or %[ftmp8], %[ftmp8], %[ftmp9] \n\t" \ | |
33 | "por %[ftmp8], %[ftmp8], %[ftmp9] \n\t" \ | |
34 | 34 | "punpcklwd %[ftmp1], %[ftmp5], %[ftmp7] \n\t" \ |
35 | 35 | "punpckhwd %[ftmp2], %[ftmp5], %[ftmp7] \n\t" \ |
36 | 36 | "punpcklwd %[ftmp3], %[ftmp6], %[ftmp8] \n\t" \ |
40 | 40 | int pred_stride, unsigned char *dst_ptr, |
41 | 41 | int dst_stride) { |
42 | 42 | double ftmp[12]; |
43 | uint32_t tmp[0]; | |
44 | DECLARE_ALIGNED(8, const uint64_t, ff_ph_04) = { 0x0004000400040004ULL }; | |
45 | DECLARE_ALIGNED(8, const uint64_t, ff_ph_4e7b) = { 0x4e7b4e7b4e7b4e7bULL }; | |
46 | DECLARE_ALIGNED(8, const uint64_t, ff_ph_22a3) = { 0x22a322a322a322a3ULL }; | |
43 | uint64_t tmp[1]; | |
44 | double ff_ph_04, ff_ph_4e7b, ff_ph_22a3; | |
47 | 45 | |
48 | 46 | __asm__ volatile ( |
47 | "dli %[tmp0], 0x0004000400040004 \n\t" | |
48 | "dmtc1 %[tmp0], %[ff_ph_04] \n\t" | |
49 | "dli %[tmp0], 0x4e7b4e7b4e7b4e7b \n\t" | |
50 | "dmtc1 %[tmp0], %[ff_ph_4e7b] \n\t" | |
51 | "dli %[tmp0], 0x22a322a322a322a3 \n\t" | |
52 | "dmtc1 %[tmp0], %[ff_ph_22a3] \n\t" | |
49 | 53 | MMI_LI(%[tmp0], 0x02) |
50 | "mtc1 %[tmp0], %[ftmp11] \n\t" | |
51 | "xor %[ftmp0], %[ftmp0], %[ftmp0] \n\t" | |
54 | "dmtc1 %[tmp0], %[ftmp11] \n\t" | |
55 | "pxor %[ftmp0], %[ftmp0], %[ftmp0] \n\t" | |
52 | 56 | |
53 | 57 | "gsldlc1 %[ftmp1], 0x07(%[ip]) \n\t" |
54 | 58 | "gsldrc1 %[ftmp1], 0x00(%[ip]) \n\t" |
185 | 189 | [ftmp6]"=&f"(ftmp[6]), [ftmp7]"=&f"(ftmp[7]), [ftmp8]"=&f"(ftmp[8]), |
186 | 190 | [ftmp9]"=&f"(ftmp[9]), [ftmp10]"=&f"(ftmp[10]), |
187 | 191 | [ftmp11]"=&f"(ftmp[11]), [tmp0]"=&r"(tmp[0]), |
188 | [pred_ptr]"+&r"(pred_ptr), [dst_ptr]"+&r"(dst_ptr) | |
189 | : [ip]"r"(input), [ff_ph_22a3]"f"(ff_ph_22a3), | |
190 | [ff_ph_4e7b]"f"(ff_ph_4e7b), [ff_ph_04]"f"(ff_ph_04), | |
192 | [pred_ptr]"+&r"(pred_ptr), [dst_ptr]"+&r"(dst_ptr), | |
193 | [ff_ph_4e7b]"=&f"(ff_ph_4e7b), [ff_ph_04]"=&f"(ff_ph_04), | |
194 | [ff_ph_22a3]"=&f"(ff_ph_22a3) | |
195 | : [ip]"r"(input), | |
191 | 196 | [pred_stride]"r"((mips_reg)pred_stride), |
192 | 197 | [dst_stride]"r"((mips_reg)dst_stride) |
193 | 198 | : "memory" |
197 | 202 | void vp8_dc_only_idct_add_mmi(int16_t input_dc, unsigned char *pred_ptr, |
198 | 203 | int pred_stride, unsigned char *dst_ptr, |
199 | 204 | int dst_stride) { |
200 | int a1 = ((input_dc + 4) >> 3); | |
201 | double ftmp[5]; | |
205 | int a0 = ((input_dc + 4) >> 3); | |
206 | double a1, ftmp[5]; | |
202 | 207 | int low32; |
203 | 208 | |
204 | 209 | __asm__ volatile ( |
205 | "xor %[ftmp0], %[ftmp0], %[ftmp0] \n\t" | |
210 | "pxor %[ftmp0], %[ftmp0], %[ftmp0] \n\t" | |
211 | "dmtc1 %[a0], %[a1] \n\t" | |
206 | 212 | "pshufh %[a1], %[a1], %[ftmp0] \n\t" |
207 | 213 | "ulw %[low32], 0x00(%[pred_ptr]) \n\t" |
208 | 214 | "mtc1 %[low32], %[ftmp1] \n\t" |
243 | 249 | "gsswrc1 %[ftmp1], 0x00(%[dst_ptr]) \n\t" |
244 | 250 | : [ftmp0]"=&f"(ftmp[0]), [ftmp1]"=&f"(ftmp[1]), [ftmp2]"=&f"(ftmp[2]), |
245 | 251 | [ftmp3]"=&f"(ftmp[3]), [ftmp4]"=&f"(ftmp[4]), [low32]"=&r"(low32), |
246 | [dst_ptr]"+&r"(dst_ptr), [pred_ptr]"+&r"(pred_ptr) | |
252 | [dst_ptr]"+&r"(dst_ptr), [pred_ptr]"+&r"(pred_ptr), [a1]"=&f"(a1) | |
247 | 253 | : [dst_stride]"r"((mips_reg)dst_stride), |
248 | [pred_stride]"r"((mips_reg)pred_stride), [a1]"f"(a1) | |
254 | [pred_stride]"r"((mips_reg)pred_stride), [a0]"r"(a0) | |
249 | 255 | : "memory" |
250 | 256 | ); |
251 | 257 | } |
253 | 259 | void vp8_short_inv_walsh4x4_mmi(int16_t *input, int16_t *mb_dqcoeff) { |
254 | 260 | int i; |
255 | 261 | int16_t output[16]; |
256 | double ftmp[12]; | |
257 | uint32_t tmp[1]; | |
258 | DECLARE_ALIGNED(8, const uint64_t, ff_ph_03) = { 0x0003000300030003ULL }; | |
262 | double ff_ph_03, ftmp[12]; | |
263 | uint64_t tmp[1]; | |
259 | 264 | |
260 | 265 | __asm__ volatile ( |
266 | "dli %[tmp0], 0x0003000300030003 \n\t" | |
267 | "dmtc1 %[tmp0], %[ff_ph_03] \n\t" | |
261 | 268 | MMI_LI(%[tmp0], 0x03) |
262 | "xor %[ftmp0], %[ftmp0], %[ftmp0] \n\t" | |
263 | "mtc1 %[tmp0], %[ftmp11] \n\t" | |
269 | "pxor %[ftmp0], %[ftmp0], %[ftmp0] \n\t" | |
270 | "dmtc1 %[tmp0], %[ftmp11] \n\t" | |
264 | 271 | "gsldlc1 %[ftmp1], 0x07(%[ip]) \n\t" |
265 | 272 | "gsldrc1 %[ftmp1], 0x00(%[ip]) \n\t" |
266 | 273 | "gsldlc1 %[ftmp2], 0x0f(%[ip]) \n\t" |
316 | 323 | [ftmp3]"=&f"(ftmp[3]), [ftmp4]"=&f"(ftmp[4]), [ftmp5]"=&f"(ftmp[5]), |
317 | 324 | [ftmp6]"=&f"(ftmp[6]), [ftmp7]"=&f"(ftmp[7]), [ftmp8]"=&f"(ftmp[8]), |
318 | 325 | [ftmp9]"=&f"(ftmp[9]), [ftmp10]"=&f"(ftmp[10]), |
319 | [ftmp11]"=&f"(ftmp[11]), [tmp0]"=&r"(tmp[0]) | |
320 | : [ip]"r"(input), [op]"r"(output), [ff_ph_03]"f"(ff_ph_03) | |
326 | [ftmp11]"=&f"(ftmp[11]), [tmp0]"=&r"(tmp[0]), [ff_ph_03]"=&f"(ff_ph_03) | |
327 | : [ip]"r"(input), [op]"r"(output) | |
321 | 328 | : "memory" |
322 | 329 | ); |
323 | 330 |
12 | 12 | #include "vp8/common/onyxc_int.h" |
13 | 13 | #include "vpx_ports/asmdefs_mmi.h" |
14 | 14 | |
15 | DECLARE_ALIGNED(8, static const uint64_t, ff_ph_01) = { 0x0001000100010001ULL }; | |
16 | DECLARE_ALIGNED(8, static const uint64_t, | |
17 | ff_ph_003f) = { 0x003f003f003f003fULL }; | |
18 | DECLARE_ALIGNED(8, static const uint64_t, | |
19 | ff_ph_0900) = { 0x0900090009000900ULL }; | |
20 | DECLARE_ALIGNED(8, static const uint64_t, | |
21 | ff_ph_1200) = { 0x1200120012001200ULL }; | |
22 | DECLARE_ALIGNED(8, static const uint64_t, | |
23 | ff_ph_1b00) = { 0x1b001b001b001b00ULL }; | |
24 | DECLARE_ALIGNED(8, static const uint64_t, ff_pb_fe) = { 0xfefefefefefefefeULL }; | |
25 | DECLARE_ALIGNED(8, static const uint64_t, ff_pb_80) = { 0x8080808080808080ULL }; | |
26 | DECLARE_ALIGNED(8, static const uint64_t, ff_pb_04) = { 0x0404040404040404ULL }; | |
27 | DECLARE_ALIGNED(8, static const uint64_t, ff_pb_03) = { 0x0303030303030303ULL }; | |
28 | DECLARE_ALIGNED(8, static const uint64_t, ff_pb_01) = { 0x0101010101010101ULL }; | |
29 | ||
30 | 15 | void vp8_loop_filter_horizontal_edge_mmi( |
31 | 16 | unsigned char *src_ptr, int src_pixel_step, const unsigned char *blimit, |
32 | 17 | const unsigned char *limit, const unsigned char *thresh, int count) { |
33 | uint32_t tmp[1]; | |
18 | uint64_t tmp[1]; | |
34 | 19 | mips_reg addr[2]; |
35 | 20 | double ftmp[12]; |
21 | double ff_ph_01, ff_pb_fe, ff_pb_80, ff_pb_04, ff_pb_03; | |
22 | /* clang-format off */ | |
36 | 23 | __asm__ volatile ( |
24 | "dli %[tmp0], 0x0001000100010001 \n\t" | |
25 | "dmtc1 %[tmp0], %[ff_ph_01] \n\t" | |
26 | "dli %[tmp0], 0xfefefefefefefefe \n\t" | |
27 | "dmtc1 %[tmp0], %[ff_pb_fe] \n\t" | |
28 | "dli %[tmp0], 0x8080808080808080 \n\t" | |
29 | "dmtc1 %[tmp0], %[ff_pb_80] \n\t" | |
30 | "dli %[tmp0], 0x0404040404040404 \n\t" | |
31 | "dmtc1 %[tmp0], %[ff_pb_04] \n\t" | |
32 | "dli %[tmp0], 0x0303030303030303 \n\t" | |
33 | "dmtc1 %[tmp0], %[ff_pb_03] \n\t" | |
37 | 34 | "1: \n\t" |
38 | 35 | "gsldlc1 %[ftmp10], 0x07(%[limit]) \n\t" |
39 | 36 | "gsldrc1 %[ftmp10], 0x00(%[limit]) \n\t" |
55 | 52 | "gsldrc1 %[ftmp4], 0x00(%[addr1]) \n\t" |
56 | 53 | "pasubub %[ftmp1], %[ftmp3], %[ftmp4] \n\t" |
57 | 54 | "psubusb %[ftmp1], %[ftmp1], %[ftmp10] \n\t" |
58 | "or %[ftmp0], %[ftmp0], %[ftmp1] \n\t" | |
55 | "por %[ftmp0], %[ftmp0], %[ftmp1] \n\t" | |
59 | 56 | |
60 | 57 | MMI_SUBU(%[addr1], %[src_ptr], %[src_pixel_step]) |
61 | 58 | "gsldlc1 %[ftmp5], 0x07(%[addr1]) \n\t" |
62 | 59 | "gsldrc1 %[ftmp5], 0x00(%[addr1]) \n\t" |
63 | 60 | "pasubub %[ftmp9], %[ftmp4], %[ftmp5] \n\t" |
64 | 61 | "psubusb %[ftmp1], %[ftmp9], %[ftmp10] \n\t" |
65 | "or %[ftmp0], %[ftmp0], %[ftmp1] \n\t" | |
62 | "por %[ftmp0], %[ftmp0], %[ftmp1] \n\t" | |
66 | 63 | |
67 | 64 | "gsldlc1 %[ftmp6], 0x07(%[src_ptr]) \n\t" |
68 | 65 | "gsldrc1 %[ftmp6], 0x00(%[src_ptr]) \n\t" |
71 | 68 | "gsldrc1 %[ftmp7], 0x00(%[addr0]) \n\t" |
72 | 69 | "pasubub %[ftmp11], %[ftmp7], %[ftmp6] \n\t" |
73 | 70 | "psubusb %[ftmp1], %[ftmp11], %[ftmp10] \n\t" |
74 | "or %[ftmp0], %[ftmp0], %[ftmp1] \n\t" | |
71 | "por %[ftmp0], %[ftmp0], %[ftmp1] \n\t" | |
75 | 72 | |
76 | 73 | MMI_ADDU(%[addr1], %[src_ptr], %[src_pixel_step_x2]) |
77 | 74 | "gsldlc1 %[ftmp8], 0x07(%[addr1]) \n\t" |
78 | 75 | "gsldrc1 %[ftmp8], 0x00(%[addr1]) \n\t" |
79 | 76 | "pasubub %[ftmp1], %[ftmp8], %[ftmp7] \n\t" |
80 | 77 | "psubusb %[ftmp1], %[ftmp1], %[ftmp10] \n\t" |
81 | "or %[ftmp0], %[ftmp0], %[ftmp1] \n\t" | |
78 | "por %[ftmp0], %[ftmp0], %[ftmp1] \n\t" | |
82 | 79 | |
83 | 80 | MMI_ADDU(%[addr1], %[addr0], %[src_pixel_step_x2]) |
84 | 81 | "gsldlc1 %[ftmp2], 0x07(%[addr1]) \n\t" |
85 | 82 | "gsldrc1 %[ftmp2], 0x00(%[addr1]) \n\t" |
86 | 83 | "pasubub %[ftmp1], %[ftmp2], %[ftmp8] \n\t" |
87 | 84 | "psubusb %[ftmp1], %[ftmp1], %[ftmp10] \n\t" |
88 | "or %[ftmp0], %[ftmp0], %[ftmp1] \n\t" | |
85 | "por %[ftmp0], %[ftmp0], %[ftmp1] \n\t" | |
89 | 86 | |
90 | 87 | "pasubub %[ftmp1], %[ftmp5], %[ftmp6] \n\t" |
91 | 88 | "paddusb %[ftmp1], %[ftmp1], %[ftmp1] \n\t" |
92 | 89 | "pasubub %[ftmp2], %[ftmp4], %[ftmp7] \n\t" |
93 | "and %[ftmp2], %[ftmp2], %[ff_pb_fe] \n\t" | |
94 | "li %[tmp0], 0x01 \n\t" | |
95 | "mtc1 %[tmp0], %[ftmp10] \n\t" | |
90 | "pand %[ftmp2], %[ftmp2], %[ff_pb_fe] \n\t" | |
91 | "dli %[tmp0], 0x01 \n\t" | |
92 | "dmtc1 %[tmp0], %[ftmp10] \n\t" | |
96 | 93 | "psrlh %[ftmp2], %[ftmp2], %[ftmp10] \n\t" |
97 | 94 | "paddusb %[ftmp1], %[ftmp1], %[ftmp2] \n\t" |
98 | 95 | "gsldlc1 %[ftmp10], 0x07(%[blimit]) \n\t" |
99 | 96 | "gsldrc1 %[ftmp10], 0x00(%[blimit]) \n\t" |
100 | 97 | "psubusb %[ftmp1], %[ftmp1], %[ftmp10] \n\t" |
101 | "or %[ftmp0], %[ftmp0], %[ftmp1] \n\t" | |
102 | "xor %[ftmp10], %[ftmp10], %[ftmp10] \n\t" | |
98 | "por %[ftmp0], %[ftmp0], %[ftmp1] \n\t" | |
99 | "pxor %[ftmp10], %[ftmp10], %[ftmp10] \n\t" | |
103 | 100 | "pcmpeqb %[ftmp0], %[ftmp0], %[ftmp10] \n\t" |
104 | 101 | |
105 | 102 | "gsldlc1 %[ftmp10], 0x07(%[thresh]) \n\t" |
107 | 104 | "psubusb %[ftmp1], %[ftmp9], %[ftmp10] \n\t" |
108 | 105 | "psubusb %[ftmp2], %[ftmp11], %[ftmp10] \n\t" |
109 | 106 | "paddb %[ftmp1], %[ftmp1], %[ftmp2] \n\t" |
110 | "xor %[ftmp2], %[ftmp2], %[ftmp2] \n\t" | |
107 | "pxor %[ftmp2], %[ftmp2], %[ftmp2] \n\t" | |
111 | 108 | "pcmpeqb %[ftmp1], %[ftmp1], %[ftmp2] \n\t" |
112 | 109 | "pcmpeqb %[ftmp2], %[ftmp2], %[ftmp2] \n\t" |
113 | "xor %[ftmp1], %[ftmp1], %[ftmp2] \n\t" | |
114 | ||
115 | "xor %[ftmp4], %[ftmp4], %[ff_pb_80] \n\t" | |
116 | "xor %[ftmp5], %[ftmp5], %[ff_pb_80] \n\t" | |
117 | "xor %[ftmp6], %[ftmp6], %[ff_pb_80] \n\t" | |
118 | "xor %[ftmp7], %[ftmp7], %[ff_pb_80] \n\t" | |
110 | "pxor %[ftmp1], %[ftmp1], %[ftmp2] \n\t" | |
111 | ||
112 | "pxor %[ftmp4], %[ftmp4], %[ff_pb_80] \n\t" | |
113 | "pxor %[ftmp5], %[ftmp5], %[ff_pb_80] \n\t" | |
114 | "pxor %[ftmp6], %[ftmp6], %[ff_pb_80] \n\t" | |
115 | "pxor %[ftmp7], %[ftmp7], %[ff_pb_80] \n\t" | |
119 | 116 | |
120 | 117 | "psubsb %[ftmp2], %[ftmp4], %[ftmp7] \n\t" |
121 | "and %[ftmp2], %[ftmp2], %[ftmp1] \n\t" | |
118 | "pand %[ftmp2], %[ftmp2], %[ftmp1] \n\t" | |
122 | 119 | "psubsb %[ftmp3], %[ftmp6], %[ftmp5] \n\t" |
123 | 120 | "paddsb %[ftmp2], %[ftmp2], %[ftmp3] \n\t" |
124 | 121 | "paddsb %[ftmp2], %[ftmp2], %[ftmp3] \n\t" |
125 | 122 | "paddsb %[ftmp2], %[ftmp2], %[ftmp3] \n\t" |
126 | "and %[ftmp2], %[ftmp2], %[ftmp0] \n\t" | |
123 | "pand %[ftmp2], %[ftmp2], %[ftmp0] \n\t" | |
127 | 124 | |
128 | 125 | "paddsb %[ftmp8], %[ftmp2], %[ff_pb_03] \n\t" |
129 | 126 | "paddsb %[ftmp9], %[ftmp2], %[ff_pb_04] \n\t" |
130 | 127 | |
131 | "xor %[ftmp0], %[ftmp0], %[ftmp0] \n\t" | |
132 | "xor %[ftmp11], %[ftmp11], %[ftmp11] \n\t" | |
128 | "pxor %[ftmp0], %[ftmp0], %[ftmp0] \n\t" | |
129 | "pxor %[ftmp11], %[ftmp11], %[ftmp11] \n\t" | |
133 | 130 | "punpcklbh %[ftmp0], %[ftmp0], %[ftmp8] \n\t" |
134 | 131 | "punpckhbh %[ftmp11], %[ftmp11], %[ftmp8] \n\t" |
135 | 132 | |
136 | "li %[tmp0], 0x0b \n\t" | |
137 | "mtc1 %[tmp0], %[ftmp10] \n\t" | |
133 | "dli %[tmp0], 0x0b \n\t" | |
134 | "dmtc1 %[tmp0], %[ftmp10] \n\t" | |
138 | 135 | "psrah %[ftmp0], %[ftmp0], %[ftmp10] \n\t" |
139 | 136 | "psrah %[ftmp11], %[ftmp11], %[ftmp10] \n\t" |
140 | 137 | "packsshb %[ftmp8], %[ftmp0], %[ftmp11] \n\t" |
141 | "xor %[ftmp0], %[ftmp0], %[ftmp0] \n\t" | |
138 | "pxor %[ftmp0], %[ftmp0], %[ftmp0] \n\t" | |
142 | 139 | "punpcklbh %[ftmp0], %[ftmp0], %[ftmp9] \n\t" |
143 | 140 | "psrah %[ftmp0], %[ftmp0], %[ftmp10] \n\t" |
144 | "xor %[ftmp11], %[ftmp11], %[ftmp11] \n\t" | |
141 | "pxor %[ftmp11], %[ftmp11], %[ftmp11] \n\t" | |
145 | 142 | "punpckhbh %[ftmp9], %[ftmp11], %[ftmp9] \n\t" |
146 | 143 | "psrah %[ftmp9], %[ftmp9], %[ftmp10] \n\t" |
147 | 144 | "paddsh %[ftmp11], %[ftmp0], %[ff_ph_01] \n\t" |
148 | 145 | "packsshb %[ftmp0], %[ftmp0], %[ftmp9] \n\t" |
149 | 146 | "paddsh %[ftmp9], %[ftmp9], %[ff_ph_01] \n\t" |
150 | 147 | |
151 | "li %[tmp0], 0x01 \n\t" | |
152 | "mtc1 %[tmp0], %[ftmp10] \n\t" | |
148 | "dli %[tmp0], 0x01 \n\t" | |
149 | "dmtc1 %[tmp0], %[ftmp10] \n\t" | |
153 | 150 | "psrah %[ftmp11], %[ftmp11], %[ftmp10] \n\t" |
154 | 151 | "psrah %[ftmp9], %[ftmp9], %[ftmp10] \n\t" |
155 | 152 | "packsshb %[ftmp11], %[ftmp11], %[ftmp9] \n\t" |
156 | 153 | "pandn %[ftmp1], %[ftmp1], %[ftmp11] \n\t" |
157 | 154 | "paddsb %[ftmp5], %[ftmp5], %[ftmp8] \n\t" |
158 | "xor %[ftmp5], %[ftmp5], %[ff_pb_80] \n\t" | |
155 | "pxor %[ftmp5], %[ftmp5], %[ff_pb_80] \n\t" | |
159 | 156 | |
160 | 157 | MMI_SUBU(%[addr1], %[src_ptr], %[src_pixel_step]) |
161 | 158 | "gssdlc1 %[ftmp5], 0x07(%[addr1]) \n\t" |
162 | 159 | "gssdrc1 %[ftmp5], 0x00(%[addr1]) \n\t" |
163 | 160 | MMI_SUBU(%[addr1], %[src_ptr], %[src_pixel_step_x2]) |
164 | 161 | "paddsb %[ftmp4], %[ftmp4], %[ftmp1] \n\t" |
165 | "xor %[ftmp4], %[ftmp4], %[ff_pb_80] \n\t" | |
162 | "pxor %[ftmp4], %[ftmp4], %[ff_pb_80] \n\t" | |
166 | 163 | "gssdlc1 %[ftmp4], 0x07(%[addr1]) \n\t" |
167 | 164 | "gssdrc1 %[ftmp4], 0x00(%[addr1]) \n\t" |
168 | 165 | |
169 | 166 | "psubsb %[ftmp6], %[ftmp6], %[ftmp0] \n\t" |
170 | "xor %[ftmp6], %[ftmp6], %[ff_pb_80] \n\t" | |
167 | "pxor %[ftmp6], %[ftmp6], %[ff_pb_80] \n\t" | |
171 | 168 | "gssdlc1 %[ftmp6], 0x07(%[src_ptr]) \n\t" |
172 | 169 | "gssdrc1 %[ftmp6], 0x00(%[src_ptr]) \n\t" |
173 | 170 | |
174 | 171 | "psubsb %[ftmp7], %[ftmp7], %[ftmp1] \n\t" |
175 | "xor %[ftmp7], %[ftmp7], %[ff_pb_80] \n\t" | |
172 | "pxor %[ftmp7], %[ftmp7], %[ff_pb_80] \n\t" | |
176 | 173 | "gssdlc1 %[ftmp7], 0x07(%[addr0]) \n\t" |
177 | 174 | "gssdrc1 %[ftmp7], 0x00(%[addr0]) \n\t" |
178 | 175 | |
187 | 184 | [ftmp10]"=&f"(ftmp[10]), [ftmp11]"=&f"(ftmp[11]), |
188 | 185 | [tmp0]"=&r"(tmp[0]), |
189 | 186 | [addr0]"=&r"(addr[0]), [addr1]"=&r"(addr[1]), |
190 | [src_ptr]"+&r"(src_ptr), [count]"+&r"(count) | |
187 | [src_ptr]"+&r"(src_ptr), [count]"+&r"(count), | |
188 | [ff_ph_01]"=&f"(ff_ph_01), [ff_pb_fe]"=&f"(ff_pb_fe), | |
189 | [ff_pb_80]"=&f"(ff_pb_80), [ff_pb_04]"=&f"(ff_pb_04), | |
190 | [ff_pb_03]"=&f"(ff_pb_03) | |
191 | 191 | : [limit]"r"(limit), [blimit]"r"(blimit), |
192 | 192 | [thresh]"r"(thresh), |
193 | 193 | [src_pixel_step]"r"((mips_reg)src_pixel_step), |
194 | 194 | [src_pixel_step_x2]"r"((mips_reg)(src_pixel_step<<1)), |
195 | [src_pixel_step_x4]"r"((mips_reg)(src_pixel_step<<2)), | |
196 | [ff_ph_01]"f"(ff_ph_01), [ff_pb_fe]"f"(ff_pb_fe), | |
197 | [ff_pb_80]"f"(ff_pb_80), [ff_pb_04]"f"(ff_pb_04), | |
198 | [ff_pb_03]"f"(ff_pb_03) | |
195 | [src_pixel_step_x4]"r"((mips_reg)(src_pixel_step<<2)) | |
199 | 196 | : "memory" |
200 | 197 | ); |
198 | /* clang-format on */ | |
201 | 199 | } |
202 | 200 | |
203 | 201 | void vp8_loop_filter_vertical_edge_mmi(unsigned char *src_ptr, |
205 | 203 | const unsigned char *blimit, |
206 | 204 | const unsigned char *limit, |
207 | 205 | const unsigned char *thresh, int count) { |
208 | uint32_t tmp[1]; | |
206 | uint64_t tmp[1]; | |
209 | 207 | mips_reg addr[2]; |
210 | 208 | double ftmp[13]; |
211 | ||
209 | double ff_pb_fe, ff_ph_01, ff_pb_03, ff_pb_04, ff_pb_80; | |
210 | ||
211 | /* clang-format off */ | |
212 | 212 | __asm__ volatile ( |
213 | "dli %[tmp0], 0xfefefefefefefefe \n\t" | |
214 | "dmtc1 %[tmp0], %[ff_pb_fe] \n\t" | |
215 | "dli %[tmp0], 0x0001000100010001 \n\t" | |
216 | "dmtc1 %[tmp0], %[ff_ph_01] \n\t" | |
217 | "dli %[tmp0], 0x0303030303030303 \n\t" | |
218 | "dmtc1 %[tmp0], %[ff_pb_03] \n\t" | |
219 | "dli %[tmp0], 0x0404040404040404 \n\t" | |
220 | "dmtc1 %[tmp0], %[ff_pb_04] \n\t" | |
221 | "dli %[tmp0], 0x8080808080808080 \n\t" | |
222 | "dmtc1 %[tmp0], %[ff_pb_80] \n\t" | |
213 | 223 | MMI_SLL(%[tmp0], %[src_pixel_step], 0x02) |
214 | 224 | MMI_ADDU(%[src_ptr], %[src_ptr], %[tmp0]) |
215 | 225 | MMI_SUBU(%[src_ptr], %[src_ptr], 0x04) |
287 | 297 | /* abs (q2-q1) */ |
288 | 298 | "pasubub %[ftmp7], %[ftmp11], %[ftmp10] \n\t" |
289 | 299 | "psubusb %[ftmp7], %[ftmp7], %[ftmp8] \n\t" |
290 | "or %[ftmp0], %[ftmp0], %[ftmp7] \n\t" | |
300 | "por %[ftmp0], %[ftmp0], %[ftmp7] \n\t" | |
291 | 301 | /* ftmp3: abs(q1-q0) */ |
292 | 302 | "pasubub %[ftmp3], %[ftmp10], %[ftmp9] \n\t" |
293 | 303 | "psubusb %[ftmp7], %[ftmp3], %[ftmp8] \n\t" |
294 | "or %[ftmp0], %[ftmp0], %[ftmp7] \n\t" | |
304 | "por %[ftmp0], %[ftmp0], %[ftmp7] \n\t" | |
295 | 305 | /* ftmp4: abs(p1-p0) */ |
296 | 306 | "pasubub %[ftmp4], %[ftmp5], %[ftmp6] \n\t" |
297 | 307 | "psubusb %[ftmp7], %[ftmp4], %[ftmp8] \n\t" |
298 | "or %[ftmp0], %[ftmp0], %[ftmp7] \n\t" | |
308 | "por %[ftmp0], %[ftmp0], %[ftmp7] \n\t" | |
299 | 309 | /* abs (p2-p1) */ |
300 | 310 | "pasubub %[ftmp7], %[ftmp2], %[ftmp5] \n\t" |
301 | 311 | "psubusb %[ftmp7], %[ftmp7], %[ftmp8] \n\t" |
302 | "or %[ftmp0], %[ftmp0], %[ftmp7] \n\t" | |
312 | "por %[ftmp0], %[ftmp0], %[ftmp7] \n\t" | |
303 | 313 | /* abs (p3-p2) */ |
304 | 314 | "pasubub %[ftmp7], %[ftmp1], %[ftmp2] \n\t" |
305 | 315 | "psubusb %[ftmp7], %[ftmp7], %[ftmp8] \n\t" |
306 | "or %[ftmp0], %[ftmp0], %[ftmp7] \n\t" | |
316 | "por %[ftmp0], %[ftmp0], %[ftmp7] \n\t" | |
307 | 317 | |
308 | 318 | "gsldlc1 %[ftmp8], 0x07(%[blimit]) \n\t" |
309 | 319 | "gsldrc1 %[ftmp8], 0x00(%[blimit]) \n\t" |
313 | 323 | "paddusb %[ftmp11], %[ftmp11], %[ftmp11] \n\t" |
314 | 324 | /* abs (p1-q1) */ |
315 | 325 | "pasubub %[ftmp12], %[ftmp10], %[ftmp5] \n\t" |
316 | "and %[ftmp12], %[ftmp12], %[ff_pb_fe] \n\t" | |
317 | "li %[tmp0], 0x01 \n\t" | |
318 | "mtc1 %[tmp0], %[ftmp1] \n\t" | |
326 | "pand %[ftmp12], %[ftmp12], %[ff_pb_fe] \n\t" | |
327 | "dli %[tmp0], 0x01 \n\t" | |
328 | "dmtc1 %[tmp0], %[ftmp1] \n\t" | |
319 | 329 | "psrlh %[ftmp12], %[ftmp12], %[ftmp1] \n\t" |
320 | 330 | "paddusb %[ftmp1], %[ftmp11], %[ftmp12] \n\t" |
321 | 331 | "psubusb %[ftmp1], %[ftmp1], %[ftmp8] \n\t" |
322 | "or %[ftmp0], %[ftmp0], %[ftmp1] \n\t" | |
323 | "xor %[ftmp1], %[ftmp1], %[ftmp1] \n\t" | |
332 | "por %[ftmp0], %[ftmp0], %[ftmp1] \n\t" | |
333 | "pxor %[ftmp1], %[ftmp1], %[ftmp1] \n\t" | |
324 | 334 | /* ftmp0:mask */ |
325 | 335 | "pcmpeqb %[ftmp0], %[ftmp0], %[ftmp1] \n\t" |
326 | 336 | |
330 | 340 | /* ftmp3: abs(q1-q0) ftmp4: abs(p1-p0) */ |
331 | 341 | "psubusb %[ftmp4], %[ftmp4], %[ftmp8] \n\t" |
332 | 342 | "psubusb %[ftmp3], %[ftmp3], %[ftmp8] \n\t" |
333 | "or %[ftmp2], %[ftmp4], %[ftmp3] \n\t" | |
343 | "por %[ftmp2], %[ftmp4], %[ftmp3] \n\t" | |
334 | 344 | "pcmpeqb %[ftmp2], %[ftmp2], %[ftmp1] \n\t" |
335 | 345 | "pcmpeqb %[ftmp1], %[ftmp1], %[ftmp1] \n\t" |
336 | 346 | /* ftmp1:hev */ |
337 | "xor %[ftmp1], %[ftmp2], %[ftmp1] \n\t" | |
338 | ||
339 | "xor %[ftmp10], %[ftmp10], %[ff_pb_80] \n\t" | |
340 | "xor %[ftmp9], %[ftmp9], %[ff_pb_80] \n\t" | |
341 | "xor %[ftmp6], %[ftmp6], %[ff_pb_80] \n\t" | |
342 | "xor %[ftmp5], %[ftmp5], %[ff_pb_80] \n\t" | |
347 | "pxor %[ftmp1], %[ftmp2], %[ftmp1] \n\t" | |
348 | ||
349 | "pxor %[ftmp10], %[ftmp10], %[ff_pb_80] \n\t" | |
350 | "pxor %[ftmp9], %[ftmp9], %[ff_pb_80] \n\t" | |
351 | "pxor %[ftmp6], %[ftmp6], %[ff_pb_80] \n\t" | |
352 | "pxor %[ftmp5], %[ftmp5], %[ff_pb_80] \n\t" | |
343 | 353 | |
344 | 354 | "psubsb %[ftmp2], %[ftmp5], %[ftmp10] \n\t" |
345 | "and %[ftmp2], %[ftmp2], %[ftmp1] \n\t" | |
355 | "pand %[ftmp2], %[ftmp2], %[ftmp1] \n\t" | |
346 | 356 | "psubsb %[ftmp3], %[ftmp9], %[ftmp6] \n\t" |
347 | 357 | "paddsb %[ftmp2], %[ftmp2], %[ftmp3] \n\t" |
348 | 358 | "paddsb %[ftmp2], %[ftmp2], %[ftmp3] \n\t" |
349 | 359 | "paddsb %[ftmp2], %[ftmp2], %[ftmp3] \n\t" |
350 | 360 | /* ftmp2:filter_value */ |
351 | "and %[ftmp2], %[ftmp2], %[ftmp0] \n\t" | |
361 | "pand %[ftmp2], %[ftmp2], %[ftmp0] \n\t" | |
352 | 362 | |
353 | 363 | "paddsb %[ftmp11], %[ftmp2], %[ff_pb_04] \n\t" |
354 | 364 | "paddsb %[ftmp12], %[ftmp2], %[ff_pb_03] \n\t" |
355 | 365 | |
356 | "li %[tmp0], 0x0b \n\t" | |
357 | "mtc1 %[tmp0], %[ftmp7] \n\t" | |
358 | "xor %[ftmp0], %[ftmp0], %[ftmp0] \n\t" | |
359 | "xor %[ftmp8], %[ftmp8], %[ftmp8] \n\t" | |
366 | "dli %[tmp0], 0x0b \n\t" | |
367 | "dmtc1 %[tmp0], %[ftmp7] \n\t" | |
368 | "pxor %[ftmp0], %[ftmp0], %[ftmp0] \n\t" | |
369 | "pxor %[ftmp8], %[ftmp8], %[ftmp8] \n\t" | |
360 | 370 | "punpcklbh %[ftmp0], %[ftmp0], %[ftmp12] \n\t" |
361 | 371 | "punpckhbh %[ftmp8], %[ftmp8], %[ftmp12] \n\t" |
362 | 372 | "psrah %[ftmp0], %[ftmp0], %[ftmp7] \n\t" |
363 | 373 | "psrah %[ftmp8], %[ftmp8], %[ftmp7] \n\t" |
364 | 374 | "packsshb %[ftmp12], %[ftmp0], %[ftmp8] \n\t" |
365 | 375 | |
366 | "xor %[ftmp0], %[ftmp0], %[ftmp0] \n\t" | |
367 | "xor %[ftmp8], %[ftmp8], %[ftmp8] \n\t" | |
376 | "pxor %[ftmp0], %[ftmp0], %[ftmp0] \n\t" | |
377 | "pxor %[ftmp8], %[ftmp8], %[ftmp8] \n\t" | |
368 | 378 | "punpcklbh %[ftmp0], %[ftmp0], %[ftmp11] \n\t" |
369 | 379 | "punpckhbh %[ftmp8], %[ftmp8], %[ftmp11] \n\t" |
370 | 380 | "psrah %[ftmp0], %[ftmp0], %[ftmp7] \n\t" |
372 | 382 | "packsshb %[ftmp11], %[ftmp0], %[ftmp8] \n\t" |
373 | 383 | |
374 | 384 | "psubsb %[ftmp9], %[ftmp9], %[ftmp11] \n\t" |
375 | "xor %[ftmp9], %[ftmp9], %[ff_pb_80] \n\t" | |
385 | "pxor %[ftmp9], %[ftmp9], %[ff_pb_80] \n\t" | |
376 | 386 | "paddsb %[ftmp6], %[ftmp6], %[ftmp12] \n\t" |
377 | "xor %[ftmp6], %[ftmp6], %[ff_pb_80] \n\t" | |
387 | "pxor %[ftmp6], %[ftmp6], %[ff_pb_80] \n\t" | |
378 | 388 | "paddsh %[ftmp0], %[ftmp0], %[ff_ph_01] \n\t" |
379 | 389 | "paddsh %[ftmp8], %[ftmp8], %[ff_ph_01] \n\t" |
380 | 390 | |
381 | "li %[tmp0], 0x01 \n\t" | |
382 | "mtc1 %[tmp0], %[ftmp7] \n\t" | |
391 | "dli %[tmp0], 0x01 \n\t" | |
392 | "dmtc1 %[tmp0], %[ftmp7] \n\t" | |
383 | 393 | "psrah %[ftmp0], %[ftmp0], %[ftmp7] \n\t" |
384 | 394 | "psrah %[ftmp8], %[ftmp8], %[ftmp7] \n\t" |
385 | 395 | "packsshb %[ftmp2], %[ftmp0], %[ftmp8] \n\t" |
386 | 396 | "pandn %[ftmp2], %[ftmp1], %[ftmp2] \n\t" |
387 | 397 | "psubsb %[ftmp10], %[ftmp10], %[ftmp2] \n\t" |
388 | "xor %[ftmp10], %[ftmp10], %[ff_pb_80] \n\t" | |
398 | "pxor %[ftmp10], %[ftmp10], %[ff_pb_80] \n\t" | |
389 | 399 | "paddsb %[ftmp5], %[ftmp5], %[ftmp2] \n\t" |
390 | "xor %[ftmp5], %[ftmp5], %[ff_pb_80] \n\t" | |
400 | "pxor %[ftmp5], %[ftmp5], %[ff_pb_80] \n\t" | |
391 | 401 | |
392 | 402 | /* ftmp5: *op1 ; ftmp6: *op0 */ |
393 | 403 | "punpcklbh %[ftmp2], %[ftmp5], %[ftmp6] \n\t" |
407 | 417 | |
408 | 418 | "li %[tmp0], 0x20 \n\t" |
409 | 419 | "mtc1 %[tmp0], %[ftmp9] \n\t" |
410 | "dsrl %[ftmp2], %[ftmp2], %[ftmp9] \n\t" | |
420 | "ssrld %[ftmp2], %[ftmp2], %[ftmp9] \n\t" | |
411 | 421 | MMI_SLL(%[tmp0], %[src_pixel_step], 0x02) |
412 | 422 | MMI_SUBU(%[addr1], %[addr0], %[tmp0]) |
413 | 423 | "gsswlc1 %[ftmp2], 0x05(%[addr1]) \n\t" |
418 | 428 | "gsswlc1 %[ftmp6], 0x05(%[addr1]) \n\t" |
419 | 429 | "gsswrc1 %[ftmp6], 0x02(%[addr1]) \n\t" |
420 | 430 | |
421 | "dsrl %[ftmp6], %[ftmp6], %[ftmp9] \n\t" | |
431 | "ssrld %[ftmp6], %[ftmp6], %[ftmp9] \n\t" | |
422 | 432 | MMI_SUBU(%[addr1], %[src_ptr], %[src_pixel_step]) |
423 | 433 | "gsswlc1 %[ftmp6], 0x05(%[addr1]) \n\t" |
424 | 434 | "gsswrc1 %[ftmp6], 0x02(%[addr1]) \n\t" |
425 | 435 | "gsswlc1 %[ftmp1], 0x05(%[src_ptr]) \n\t" |
426 | 436 | "gsswrc1 %[ftmp1], 0x02(%[src_ptr]) \n\t" |
427 | 437 | |
428 | "dsrl %[ftmp1], %[ftmp1], %[ftmp9] \n\t" | |
438 | "ssrld %[ftmp1], %[ftmp1], %[ftmp9] \n\t" | |
429 | 439 | "gsswlc1 %[ftmp1], 0x05(%[addr0]) \n\t" |
430 | 440 | "gsswrc1 %[ftmp1], 0x02(%[addr0]) \n\t" |
431 | 441 | MMI_ADDU(%[addr1], %[addr0], %[src_pixel_step]) |
432 | 442 | "gsswlc1 %[ftmp5], 0x05(%[addr1]) \n\t" |
433 | 443 | "gsswrc1 %[ftmp5], 0x02(%[addr1]) \n\t" |
434 | 444 | |
435 | "dsrl %[ftmp5], %[ftmp5], %[ftmp9] \n\t" | |
445 | "ssrld %[ftmp5], %[ftmp5], %[ftmp9] \n\t" | |
436 | 446 | MMI_ADDU(%[addr1], %[addr0], %[tmp0]) |
437 | 447 | "gsswlc1 %[ftmp5], 0x05(%[addr1]) \n\t" |
438 | 448 | "gsswrc1 %[ftmp5], 0x02(%[addr1]) \n\t" |
449 | 459 | [ftmp10]"=&f"(ftmp[10]), [ftmp11]"=&f"(ftmp[11]), |
450 | 460 | [ftmp12]"=&f"(ftmp[12]), [tmp0]"=&r"(tmp[0]), |
451 | 461 | [addr0]"=&r"(addr[0]), [addr1]"=&r"(addr[1]), |
452 | [src_ptr]"+&r"(src_ptr), [count]"+&r"(count) | |
462 | [src_ptr]"+&r"(src_ptr), [count]"+&r"(count), | |
463 | [ff_ph_01]"=&f"(ff_ph_01), [ff_pb_03]"=&f"(ff_pb_03), | |
464 | [ff_pb_04]"=&f"(ff_pb_04), [ff_pb_80]"=&f"(ff_pb_80), | |
465 | [ff_pb_fe]"=&f"(ff_pb_fe) | |
453 | 466 | : [limit]"r"(limit), [blimit]"r"(blimit), |
454 | 467 | [thresh]"r"(thresh), |
455 | [src_pixel_step]"r"((mips_reg)src_pixel_step), | |
456 | [ff_ph_01]"f"(ff_ph_01), [ff_pb_03]"f"(ff_pb_03), | |
457 | [ff_pb_04]"f"(ff_pb_04), [ff_pb_80]"f"(ff_pb_80), | |
458 | [ff_pb_fe]"f"(ff_pb_fe) | |
468 | [src_pixel_step]"r"((mips_reg)src_pixel_step) | |
459 | 469 | : "memory" |
460 | 470 | ); |
471 | /* clang-format on */ | |
461 | 472 | } |
462 | 473 | |
463 | 474 | /* clang-format off */ |
483 | 494 | void vp8_mbloop_filter_horizontal_edge_mmi( |
484 | 495 | unsigned char *src_ptr, int src_pixel_step, const unsigned char *blimit, |
485 | 496 | const unsigned char *limit, const unsigned char *thresh, int count) { |
486 | uint32_t tmp[1]; | |
497 | uint64_t tmp[1]; | |
487 | 498 | double ftmp[13]; |
488 | ||
499 | double ff_pb_fe, ff_pb_80, ff_pb_04, ff_pb_03, ff_ph_003f, ff_ph_0900, | |
500 | ff_ph_1200, ff_ph_1b00; | |
501 | ||
502 | /* clang-format off */ | |
489 | 503 | __asm__ volatile ( |
504 | "dli %[tmp0], 0xfefefefefefefefe \n\t" | |
505 | "dmtc1 %[tmp0], %[ff_pb_fe] \n\t" | |
506 | "dli %[tmp0], 0x8080808080808080 \n\t" | |
507 | "dmtc1 %[tmp0], %[ff_pb_80] \n\t" | |
508 | "dli %[tmp0], 0x0404040404040404 \n\t" | |
509 | "dmtc1 %[tmp0], %[ff_pb_04] \n\t" | |
510 | "dli %[tmp0], 0x0303030303030303 \n\t" | |
511 | "dmtc1 %[tmp0], %[ff_pb_03] \n\t" | |
512 | "dli %[tmp0], 0x003f003f003f003f \n\t" | |
513 | "dmtc1 %[tmp0], %[ff_ph_003f] \n\t" | |
514 | "dli %[tmp0], 0x0900090009000900 \n\t" | |
515 | "dmtc1 %[tmp0], %[ff_ph_0900] \n\t" | |
516 | "dli %[tmp0], 0x1200120012001200 \n\t" | |
517 | "dmtc1 %[tmp0], %[ff_ph_1200] \n\t" | |
518 | "dli %[tmp0], 0x1b001b001b001b00 \n\t" | |
519 | "dmtc1 %[tmp0], %[ff_ph_1b00] \n\t" | |
490 | 520 | MMI_SLL(%[tmp0], %[src_pixel_step], 0x02) |
491 | 521 | MMI_SUBU(%[src_ptr], %[src_ptr], %[tmp0]) |
492 | 522 | "1: \n\t" |
531 | 561 | "psubusb %[ftmp0], %[ftmp0], %[ftmp9] \n\t" |
532 | 562 | "pasubub %[ftmp1], %[ftmp3], %[ftmp4] \n\t" |
533 | 563 | "psubusb %[ftmp1], %[ftmp1], %[ftmp9] \n\t" |
534 | "or %[ftmp0], %[ftmp0], %[ftmp1] \n\t" | |
564 | "por %[ftmp0], %[ftmp0], %[ftmp1] \n\t" | |
535 | 565 | "pasubub %[ftmp10], %[ftmp4], %[ftmp5] \n\t" |
536 | 566 | "psubusb %[ftmp1], %[ftmp10], %[ftmp9] \n\t" |
537 | "or %[ftmp0], %[ftmp0], %[ftmp1] \n\t" | |
567 | "por %[ftmp0], %[ftmp0], %[ftmp1] \n\t" | |
538 | 568 | "pasubub %[ftmp11], %[ftmp7], %[ftmp6] \n\t" |
539 | 569 | "psubusb %[ftmp1], %[ftmp11], %[ftmp9] \n\t" |
540 | "or %[ftmp0], %[ftmp0], %[ftmp1] \n\t" | |
570 | "por %[ftmp0], %[ftmp0], %[ftmp1] \n\t" | |
541 | 571 | "pasubub %[ftmp1], %[ftmp8], %[ftmp7] \n\t" |
542 | 572 | "psubusb %[ftmp1], %[ftmp1], %[ftmp9] \n\t" |
543 | "or %[ftmp0], %[ftmp0], %[ftmp1] \n\t" | |
573 | "por %[ftmp0], %[ftmp0], %[ftmp1] \n\t" | |
544 | 574 | "pasubub %[ftmp1], %[ftmp2], %[ftmp8] \n\t" |
545 | 575 | "psubusb %[ftmp1], %[ftmp1], %[ftmp9] \n\t" |
546 | "or %[ftmp0], %[ftmp0], %[ftmp1] \n\t" | |
576 | "por %[ftmp0], %[ftmp0], %[ftmp1] \n\t" | |
547 | 577 | |
548 | 578 | "pasubub %[ftmp1], %[ftmp5], %[ftmp6] \n\t" |
549 | 579 | "paddusb %[ftmp1], %[ftmp1], %[ftmp1] \n\t" |
550 | 580 | "pasubub %[ftmp2], %[ftmp4], %[ftmp7] \n\t" |
551 | "and %[ftmp2], %[ftmp2], %[ff_pb_fe] \n\t" | |
552 | "li %[tmp0], 0x01 \n\t" | |
553 | "mtc1 %[tmp0], %[ftmp9] \n\t" | |
581 | "pand %[ftmp2], %[ftmp2], %[ff_pb_fe] \n\t" | |
582 | "dli %[tmp0], 0x01 \n\t" | |
583 | "dmtc1 %[tmp0], %[ftmp9] \n\t" | |
554 | 584 | "psrlh %[ftmp2], %[ftmp2], %[ftmp9] \n\t" |
555 | 585 | "paddusb %[ftmp1], %[ftmp1], %[ftmp2] \n\t" |
556 | 586 | "psubusb %[ftmp1], %[ftmp1], %[ftmp12] \n\t" |
557 | "or %[ftmp0], %[ftmp0], %[ftmp1] \n\t" | |
558 | "xor %[ftmp9], %[ftmp9], %[ftmp9] \n\t" | |
587 | "por %[ftmp0], %[ftmp0], %[ftmp1] \n\t" | |
588 | "pxor %[ftmp9], %[ftmp9], %[ftmp9] \n\t" | |
559 | 589 | /* ftmp0: mask */ |
560 | 590 | "pcmpeqb %[ftmp0], %[ftmp0], %[ftmp9] \n\t" |
561 | 591 | |
564 | 594 | "psubusb %[ftmp1], %[ftmp10], %[ftmp9] \n\t" |
565 | 595 | "psubusb %[ftmp2], %[ftmp11], %[ftmp9] \n\t" |
566 | 596 | "paddb %[ftmp1], %[ftmp1], %[ftmp2] \n\t" |
567 | "xor %[ftmp2], %[ftmp2], %[ftmp2] \n\t" | |
597 | "pxor %[ftmp2], %[ftmp2], %[ftmp2] \n\t" | |
568 | 598 | "pcmpeqb %[ftmp1], %[ftmp1], %[ftmp2] \n\t" |
569 | 599 | "pcmpeqb %[ftmp2], %[ftmp2], %[ftmp2] \n\t" |
570 | 600 | /* ftmp1: hev */ |
571 | "xor %[ftmp1], %[ftmp1], %[ftmp2] \n\t" | |
572 | ||
573 | "xor %[ftmp4], %[ftmp4], %[ff_pb_80] \n\t" | |
574 | "xor %[ftmp5], %[ftmp5], %[ff_pb_80] \n\t" | |
575 | "xor %[ftmp6], %[ftmp6], %[ff_pb_80] \n\t" | |
576 | "xor %[ftmp7], %[ftmp7], %[ff_pb_80] \n\t" | |
601 | "pxor %[ftmp1], %[ftmp1], %[ftmp2] \n\t" | |
602 | ||
603 | "pxor %[ftmp4], %[ftmp4], %[ff_pb_80] \n\t" | |
604 | "pxor %[ftmp5], %[ftmp5], %[ff_pb_80] \n\t" | |
605 | "pxor %[ftmp6], %[ftmp6], %[ff_pb_80] \n\t" | |
606 | "pxor %[ftmp7], %[ftmp7], %[ff_pb_80] \n\t" | |
577 | 607 | "psubsb %[ftmp2], %[ftmp4], %[ftmp7] \n\t" |
578 | 608 | "psubsb %[ftmp9], %[ftmp6], %[ftmp5] \n\t" |
579 | 609 | "paddsb %[ftmp2], %[ftmp2], %[ftmp9] \n\t" |
580 | 610 | "paddsb %[ftmp2], %[ftmp2], %[ftmp9] \n\t" |
581 | 611 | "paddsb %[ftmp2], %[ftmp2], %[ftmp9] \n\t" |
582 | "and %[ftmp2], %[ftmp2], %[ftmp0] \n\t" | |
612 | "pand %[ftmp2], %[ftmp2], %[ftmp0] \n\t" | |
583 | 613 | "pandn %[ftmp12], %[ftmp1], %[ftmp2] \n\t" |
584 | "and %[ftmp2], %[ftmp2], %[ftmp1] \n\t" | |
585 | ||
586 | "li %[tmp0], 0x0b \n\t" | |
587 | "mtc1 %[tmp0], %[ftmp9] \n\t" | |
614 | "pand %[ftmp2], %[ftmp2], %[ftmp1] \n\t" | |
615 | ||
616 | "dli %[tmp0], 0x0b \n\t" | |
617 | "dmtc1 %[tmp0], %[ftmp9] \n\t" | |
588 | 618 | "paddsb %[ftmp0], %[ftmp2], %[ff_pb_03] \n\t" |
589 | 619 | VP8_MBLOOP_HPSRAB |
590 | 620 | "paddsb %[ftmp5], %[ftmp5], %[ftmp0] \n\t" |
592 | 622 | VP8_MBLOOP_HPSRAB |
593 | 623 | "psubsb %[ftmp6], %[ftmp6], %[ftmp0] \n\t" |
594 | 624 | |
595 | "li %[tmp0], 0x07 \n\t" | |
596 | "mtc1 %[tmp0], %[ftmp9] \n\t" | |
597 | "xor %[ftmp0], %[ftmp0], %[ftmp0] \n\t" | |
625 | "dli %[tmp0], 0x07 \n\t" | |
626 | "dmtc1 %[tmp0], %[ftmp9] \n\t" | |
627 | "pxor %[ftmp0], %[ftmp0], %[ftmp0] \n\t" | |
598 | 628 | |
599 | 629 | VP8_MBLOOP_HPSRAB_ADD(%[ff_ph_1b00]) |
600 | 630 | "psubsb %[ftmp6], %[ftmp6], %[ftmp1] \n\t" |
601 | 631 | "paddsb %[ftmp5], %[ftmp5], %[ftmp1] \n\t" |
602 | "xor %[ftmp6], %[ftmp6], %[ff_pb_80] \n\t" | |
603 | "xor %[ftmp5], %[ftmp5], %[ff_pb_80] \n\t" | |
632 | "pxor %[ftmp6], %[ftmp6], %[ff_pb_80] \n\t" | |
633 | "pxor %[ftmp5], %[ftmp5], %[ff_pb_80] \n\t" | |
604 | 634 | MMI_SLL(%[tmp0], %[src_pixel_step], 0x02) |
605 | 635 | MMI_SUBU(%[src_ptr], %[src_ptr], %[tmp0]) |
606 | 636 | "gssdlc1 %[ftmp5], 0x07(%[src_ptr]) \n\t" |
612 | 642 | VP8_MBLOOP_HPSRAB_ADD(%[ff_ph_1200]) |
613 | 643 | "paddsb %[ftmp4], %[ftmp4], %[ftmp1] \n\t" |
614 | 644 | "psubsb %[ftmp7], %[ftmp7], %[ftmp1] \n\t" |
615 | "xor %[ftmp4], %[ftmp4], %[ff_pb_80] \n\t" | |
616 | "xor %[ftmp7], %[ftmp7], %[ff_pb_80] \n\t" | |
645 | "pxor %[ftmp4], %[ftmp4], %[ff_pb_80] \n\t" | |
646 | "pxor %[ftmp7], %[ftmp7], %[ff_pb_80] \n\t" | |
617 | 647 | MMI_ADDU(%[src_ptr], %[src_ptr], %[src_pixel_step]) |
618 | 648 | "gssdlc1 %[ftmp7], 0x07(%[src_ptr]) \n\t" |
619 | 649 | "gssdrc1 %[ftmp7], 0x00(%[src_ptr]) \n\t" |
623 | 653 | "gssdrc1 %[ftmp4], 0x00(%[src_ptr]) \n\t" |
624 | 654 | |
625 | 655 | VP8_MBLOOP_HPSRAB_ADD(%[ff_ph_0900]) |
626 | "xor %[ftmp3], %[ftmp3], %[ff_pb_80] \n\t" | |
627 | "xor %[ftmp8], %[ftmp8], %[ff_pb_80] \n\t" | |
656 | "pxor %[ftmp3], %[ftmp3], %[ff_pb_80] \n\t" | |
657 | "pxor %[ftmp8], %[ftmp8], %[ff_pb_80] \n\t" | |
628 | 658 | "paddsb %[ftmp3], %[ftmp3], %[ftmp1] \n\t" |
629 | 659 | "psubsb %[ftmp8], %[ftmp8], %[ftmp1] \n\t" |
630 | "xor %[ftmp3], %[ftmp3], %[ff_pb_80] \n\t" | |
631 | "xor %[ftmp8], %[ftmp8], %[ff_pb_80] \n\t" | |
660 | "pxor %[ftmp3], %[ftmp3], %[ff_pb_80] \n\t" | |
661 | "pxor %[ftmp8], %[ftmp8], %[ff_pb_80] \n\t" | |
632 | 662 | MMI_ADDU(%[src_ptr], %[src_ptr], %[tmp0]) |
633 | 663 | "gssdlc1 %[ftmp8], 0x07(%[src_ptr]) \n\t" |
634 | 664 | "gssdrc1 %[ftmp8], 0x00(%[src_ptr]) \n\t" |
648 | 678 | [ftmp8]"=&f"(ftmp[8]), [ftmp9]"=&f"(ftmp[9]), |
649 | 679 | [ftmp10]"=&f"(ftmp[10]), [ftmp11]"=&f"(ftmp[11]), |
650 | 680 | [ftmp12]"=&f"(ftmp[12]), [tmp0]"=&r"(tmp[0]), |
651 | [src_ptr]"+&r"(src_ptr), [count]"+&r"(count) | |
681 | [src_ptr]"+&r"(src_ptr), [count]"+&r"(count), | |
682 | [ff_pb_fe]"=&f"(ff_pb_fe), [ff_pb_80]"=&f"(ff_pb_80), | |
683 | [ff_pb_04]"=&f"(ff_pb_04), [ff_pb_03]"=&f"(ff_pb_03), | |
684 | [ff_ph_0900]"=&f"(ff_ph_0900), [ff_ph_1b00]"=&f"(ff_ph_1b00), | |
685 | [ff_ph_1200]"=&f"(ff_ph_1200), [ff_ph_003f]"=&f"(ff_ph_003f) | |
652 | 686 | : [limit]"r"(limit), [blimit]"r"(blimit), |
653 | 687 | [thresh]"r"(thresh), |
654 | [src_pixel_step]"r"((mips_reg)src_pixel_step), | |
655 | [ff_pb_fe]"f"(ff_pb_fe), [ff_pb_80]"f"(ff_pb_80), | |
656 | [ff_pb_04]"f"(ff_pb_04), [ff_pb_03]"f"(ff_pb_03), | |
657 | [ff_ph_0900]"f"(ff_ph_0900), [ff_ph_1b00]"f"(ff_ph_1b00), | |
658 | [ff_ph_1200]"f"(ff_ph_1200), [ff_ph_003f]"f"(ff_ph_003f) | |
688 | [src_pixel_step]"r"((mips_reg)src_pixel_step) | |
659 | 689 | : "memory" |
660 | 690 | ); |
691 | /* clang-format on */ | |
661 | 692 | } |
662 | 693 | |
694 | /* clang-format off */ | |
663 | 695 | #define VP8_MBLOOP_VPSRAB_ADDH \ |
664 | "xor %[ftmp7], %[ftmp7], %[ftmp7] \n\t" \ | |
665 | "xor %[ftmp8], %[ftmp8], %[ftmp8] \n\t" \ | |
696 | "pxor %[ftmp7], %[ftmp7], %[ftmp7] \n\t" \ | |
697 | "pxor %[ftmp8], %[ftmp8], %[ftmp8] \n\t" \ | |
666 | 698 | "punpcklbh %[ftmp7], %[ftmp7], %[ftmp0] \n\t" \ |
667 | 699 | "punpckhbh %[ftmp8], %[ftmp8], %[ftmp0] \n\t" |
668 | 700 | |
672 | 704 | "psrah %[ftmp7], %[ftmp7], %[ftmp12] \n\t" \ |
673 | 705 | "psrah %[ftmp8], %[ftmp8], %[ftmp12] \n\t" \ |
674 | 706 | "packsshb %[ftmp3], %[ftmp7], %[ftmp8] \n\t" |
707 | /* clang-format on */ | |
675 | 708 | |
676 | 709 | void vp8_mbloop_filter_vertical_edge_mmi( |
677 | 710 | unsigned char *src_ptr, int src_pixel_step, const unsigned char *blimit, |
678 | 711 | const unsigned char *limit, const unsigned char *thresh, int count) { |
679 | 712 | mips_reg tmp[1]; |
680 | DECLARE_ALIGNED(8, const uint64_t, srct[1]); | |
713 | DECLARE_ALIGNED(8, const uint64_t, srct[2]); | |
681 | 714 | double ftmp[14]; |
682 | ||
715 | double ff_ph_003f, ff_ph_0900, ff_pb_fe, ff_pb_80, ff_pb_04, ff_pb_03; | |
716 | ||
717 | /* clang-format off */ | |
683 | 718 | __asm__ volatile ( |
719 | "dli %[tmp0], 0x003f003f003f003f \n\t" | |
720 | "dmtc1 %[tmp0], %[ff_ph_003f] \n\t" | |
721 | "dli %[tmp0], 0x0900090009000900 \n\t" | |
722 | "dmtc1 %[tmp0], %[ff_ph_0900] \n\t" | |
723 | "dli %[tmp0], 0xfefefefefefefefe \n\t" | |
724 | "dmtc1 %[tmp0], %[ff_pb_fe] \n\t" | |
725 | "dli %[tmp0], 0x8080808080808080 \n\t" | |
726 | "dmtc1 %[tmp0], %[ff_pb_80] \n\t" | |
727 | "dli %[tmp0], 0x0404040404040404 \n\t" | |
728 | "dmtc1 %[tmp0], %[ff_pb_04] \n\t" | |
729 | "dli %[tmp0], 0x0303030303030303 \n\t" | |
730 | "dmtc1 %[tmp0], %[ff_pb_03] \n\t" | |
684 | 731 | MMI_SUBU(%[src_ptr], %[src_ptr], 0x04) |
685 | 732 | |
686 | 733 | "1: \n\t" |
754 | 801 | /* abs (q2-q1) */ |
755 | 802 | "pasubub %[ftmp7], %[ftmp11], %[ftmp10] \n\t" |
756 | 803 | "psubusb %[ftmp7], %[ftmp7], %[ftmp13] \n\t" |
757 | "or %[ftmp0], %[ftmp0], %[ftmp7] \n\t" | |
804 | "por %[ftmp0], %[ftmp0], %[ftmp7] \n\t" | |
758 | 805 | /* ftmp3: abs(q1-q0) */ |
759 | 806 | "pasubub %[ftmp3], %[ftmp10], %[ftmp9] \n\t" |
760 | 807 | "psubusb %[ftmp7], %[ftmp3], %[ftmp13] \n\t" |
761 | "or %[ftmp0], %[ftmp0], %[ftmp7] \n\t" | |
808 | "por %[ftmp0], %[ftmp0], %[ftmp7] \n\t" | |
762 | 809 | /* ftmp4: abs(p1-p0) */ |
763 | 810 | "pasubub %[ftmp4], %[ftmp5], %[ftmp6] \n\t" |
764 | 811 | "psubusb %[ftmp7], %[ftmp4], %[ftmp13] \n\t" |
765 | "or %[ftmp0], %[ftmp0], %[ftmp7] \n\t" | |
812 | "por %[ftmp0], %[ftmp0], %[ftmp7] \n\t" | |
766 | 813 | /* abs (p2-p1) */ |
767 | 814 | "pasubub %[ftmp7], %[ftmp2], %[ftmp5] \n\t" |
768 | 815 | "psubusb %[ftmp7], %[ftmp7], %[ftmp13] \n\t" |
769 | "or %[ftmp0], %[ftmp0], %[ftmp7] \n\t" | |
816 | "por %[ftmp0], %[ftmp0], %[ftmp7] \n\t" | |
770 | 817 | /* abs (p3-p2) */ |
771 | 818 | "pasubub %[ftmp7], %[ftmp1], %[ftmp2] \n\t" |
772 | 819 | "psubusb %[ftmp7], %[ftmp7], %[ftmp13] \n\t" |
773 | "or %[ftmp0], %[ftmp0], %[ftmp7] \n\t" | |
820 | "por %[ftmp0], %[ftmp0], %[ftmp7] \n\t" | |
774 | 821 | |
775 | 822 | "gsldlc1 %[ftmp13], 0x07(%[blimit]) \n\t" |
776 | 823 | "gsldrc1 %[ftmp13], 0x00(%[blimit]) \n\t" |
781 | 828 | "paddusb %[ftmp1], %[ftmp1], %[ftmp1] \n\t" |
782 | 829 | /* abs (p1-q1) / 2 */ |
783 | 830 | "pasubub %[ftmp12], %[ftmp10], %[ftmp5] \n\t" |
784 | "and %[ftmp12], %[ftmp12], %[ff_pb_fe] \n\t" | |
785 | "li %[tmp0], 0x01 \n\t" | |
786 | "mtc1 %[tmp0], %[ftmp8] \n\t" | |
831 | "pand %[ftmp12], %[ftmp12], %[ff_pb_fe] \n\t" | |
832 | "dli %[tmp0], 0x01 \n\t" | |
833 | "dmtc1 %[tmp0], %[ftmp8] \n\t" | |
787 | 834 | "psrlh %[ftmp12], %[ftmp12], %[ftmp8] \n\t" |
788 | 835 | "paddusb %[ftmp12], %[ftmp1], %[ftmp12] \n\t" |
789 | 836 | "psubusb %[ftmp12], %[ftmp12], %[ftmp13] \n\t" |
790 | "or %[ftmp0], %[ftmp0], %[ftmp12] \n\t" | |
791 | "xor %[ftmp12], %[ftmp12], %[ftmp12] \n\t" | |
837 | "por %[ftmp0], %[ftmp0], %[ftmp12] \n\t" | |
838 | "pxor %[ftmp12], %[ftmp12], %[ftmp12] \n\t" | |
792 | 839 | /* ftmp0: mask */ |
793 | 840 | "pcmpeqb %[ftmp0], %[ftmp0], %[ftmp12] \n\t" |
794 | 841 | |
796 | 843 | "psubusb %[ftmp4], %[ftmp4], %[ftmp7] \n\t" |
797 | 844 | /* abs(q1-q0) - thresh */ |
798 | 845 | "psubusb %[ftmp3], %[ftmp3], %[ftmp7] \n\t" |
799 | "or %[ftmp3], %[ftmp4], %[ftmp3] \n\t" | |
846 | "por %[ftmp3], %[ftmp4], %[ftmp3] \n\t" | |
800 | 847 | "pcmpeqb %[ftmp3], %[ftmp3], %[ftmp12] \n\t" |
801 | 848 | "pcmpeqb %[ftmp1], %[ftmp1], %[ftmp1] \n\t" |
802 | 849 | /* ftmp1: hev */ |
803 | "xor %[ftmp1], %[ftmp3], %[ftmp1] \n\t" | |
850 | "pxor %[ftmp1], %[ftmp3], %[ftmp1] \n\t" | |
804 | 851 | |
805 | 852 | /* ftmp2:ps2, ftmp5:ps1, ftmp6:ps0, ftmp9:qs0, ftmp10:qs1, ftmp11:qs2 */ |
806 | "xor %[ftmp11], %[ftmp11], %[ff_pb_80] \n\t" | |
807 | "xor %[ftmp10], %[ftmp10], %[ff_pb_80] \n\t" | |
808 | "xor %[ftmp9], %[ftmp9], %[ff_pb_80] \n\t" | |
809 | "xor %[ftmp6], %[ftmp6], %[ff_pb_80] \n\t" | |
810 | "xor %[ftmp5], %[ftmp5], %[ff_pb_80] \n\t" | |
811 | "xor %[ftmp2], %[ftmp2], %[ff_pb_80] \n\t" | |
853 | "pxor %[ftmp11], %[ftmp11], %[ff_pb_80] \n\t" | |
854 | "pxor %[ftmp10], %[ftmp10], %[ff_pb_80] \n\t" | |
855 | "pxor %[ftmp9], %[ftmp9], %[ff_pb_80] \n\t" | |
856 | "pxor %[ftmp6], %[ftmp6], %[ff_pb_80] \n\t" | |
857 | "pxor %[ftmp5], %[ftmp5], %[ff_pb_80] \n\t" | |
858 | "pxor %[ftmp2], %[ftmp2], %[ff_pb_80] \n\t" | |
812 | 859 | |
813 | 860 | "psubsb %[ftmp3], %[ftmp5], %[ftmp10] \n\t" |
814 | 861 | "psubsb %[ftmp4], %[ftmp9], %[ftmp6] \n\t" |
816 | 863 | "paddsb %[ftmp3], %[ftmp3], %[ftmp4] \n\t" |
817 | 864 | "paddsb %[ftmp3], %[ftmp3], %[ftmp4] \n\t" |
818 | 865 | /* filter_value &= mask */ |
819 | "and %[ftmp0], %[ftmp0], %[ftmp3] \n\t" | |
866 | "pand %[ftmp0], %[ftmp0], %[ftmp3] \n\t" | |
820 | 867 | /* Filter2 = filter_value & hev */ |
821 | "and %[ftmp3], %[ftmp1], %[ftmp0] \n\t" | |
868 | "pand %[ftmp3], %[ftmp1], %[ftmp0] \n\t" | |
822 | 869 | /* filter_value &= ~hev */ |
823 | 870 | "pandn %[ftmp0], %[ftmp1], %[ftmp0] \n\t" |
824 | 871 | |
825 | 872 | "paddsb %[ftmp4], %[ftmp3], %[ff_pb_04] \n\t" |
826 | "li %[tmp0], 0x0b \n\t" | |
827 | "mtc1 %[tmp0], %[ftmp12] \n\t" | |
873 | "dli %[tmp0], 0x0b \n\t" | |
874 | "dmtc1 %[tmp0], %[ftmp12] \n\t" | |
828 | 875 | "punpcklbh %[ftmp7], %[ftmp7], %[ftmp4] \n\t" |
829 | 876 | "punpckhbh %[ftmp8], %[ftmp8], %[ftmp4] \n\t" |
830 | 877 | "psrah %[ftmp7], %[ftmp7], %[ftmp12] \n\t" |
841 | 888 | /* ftmp6: ps0 */ |
842 | 889 | "paddsb %[ftmp6], %[ftmp6], %[ftmp3] \n\t" |
843 | 890 | |
844 | "li %[tmp0], 0x07 \n\t" | |
845 | "mtc1 %[tmp0], %[ftmp12] \n\t" | |
891 | "dli %[tmp0], 0x07 \n\t" | |
892 | "dmtc1 %[tmp0], %[ftmp12] \n\t" | |
846 | 893 | VP8_MBLOOP_VPSRAB_ADDH |
847 | 894 | "paddh %[ftmp1], %[ff_ph_0900], %[ff_ph_0900] \n\t" |
848 | 895 | "paddh %[ftmp1], %[ftmp1], %[ff_ph_0900] \n\t" |
851 | 898 | VP8_MBLOOP_VPSRAB_ADDT |
852 | 899 | "psubsb %[ftmp4], %[ftmp9], %[ftmp3] \n\t" |
853 | 900 | /* ftmp9: oq0 */ |
854 | "xor %[ftmp9], %[ftmp4], %[ff_pb_80] \n\t" | |
901 | "pxor %[ftmp9], %[ftmp4], %[ff_pb_80] \n\t" | |
855 | 902 | "paddsb %[ftmp4], %[ftmp6], %[ftmp3] \n\t" |
856 | 903 | /* ftmp6: op0 */ |
857 | "xor %[ftmp6], %[ftmp4], %[ff_pb_80] \n\t" | |
904 | "pxor %[ftmp6], %[ftmp4], %[ff_pb_80] \n\t" | |
858 | 905 | |
859 | 906 | VP8_MBLOOP_VPSRAB_ADDH |
860 | 907 | "paddh %[ftmp1], %[ff_ph_0900], %[ff_ph_0900] \n\t" |
863 | 910 | VP8_MBLOOP_VPSRAB_ADDT |
864 | 911 | "psubsb %[ftmp4], %[ftmp10], %[ftmp3] \n\t" |
865 | 912 | /* ftmp10: oq1 */ |
866 | "xor %[ftmp10], %[ftmp4], %[ff_pb_80] \n\t" | |
913 | "pxor %[ftmp10], %[ftmp4], %[ff_pb_80] \n\t" | |
867 | 914 | "paddsb %[ftmp4], %[ftmp5], %[ftmp3] \n\t" |
868 | 915 | /* ftmp5: op1 */ |
869 | "xor %[ftmp5], %[ftmp4], %[ff_pb_80] \n\t" | |
916 | "pxor %[ftmp5], %[ftmp4], %[ff_pb_80] \n\t" | |
870 | 917 | |
871 | 918 | VP8_MBLOOP_VPSRAB_ADDH |
872 | 919 | "pmulhh %[ftmp7], %[ftmp7], %[ff_ph_0900] \n\t" |
874 | 921 | VP8_MBLOOP_VPSRAB_ADDT |
875 | 922 | "psubsb %[ftmp4], %[ftmp11], %[ftmp3] \n\t" |
876 | 923 | /* ftmp11: oq2 */ |
877 | "xor %[ftmp11], %[ftmp4], %[ff_pb_80] \n\t" | |
924 | "pxor %[ftmp11], %[ftmp4], %[ff_pb_80] \n\t" | |
878 | 925 | "paddsb %[ftmp4], %[ftmp2], %[ftmp3] \n\t" |
879 | 926 | /* ftmp2: op2 */ |
880 | "xor %[ftmp2], %[ftmp4], %[ff_pb_80] \n\t" | |
927 | "pxor %[ftmp2], %[ftmp4], %[ff_pb_80] \n\t" | |
881 | 928 | |
882 | 929 | "ldc1 %[ftmp12], 0x00(%[srct]) \n\t" |
883 | 930 | "ldc1 %[ftmp8], 0x08(%[srct]) \n\t" |
947 | 994 | [ftmp10]"=&f"(ftmp[10]), [ftmp11]"=&f"(ftmp[11]), |
948 | 995 | [ftmp12]"=&f"(ftmp[12]), [ftmp13]"=&f"(ftmp[13]), |
949 | 996 | [tmp0]"=&r"(tmp[0]), [src_ptr]"+&r"(src_ptr), |
950 | [count]"+&r"(count) | |
997 | [count]"+&r"(count), | |
998 | [ff_ph_003f]"=&f"(ff_ph_003f), [ff_ph_0900]"=&f"(ff_ph_0900), | |
999 | [ff_pb_03]"=&f"(ff_pb_03), [ff_pb_04]"=&f"(ff_pb_04), | |
1000 | [ff_pb_80]"=&f"(ff_pb_80), [ff_pb_fe]"=&f"(ff_pb_fe) | |
951 | 1001 | : [limit]"r"(limit), [blimit]"r"(blimit), |
952 | 1002 | [srct]"r"(srct), [thresh]"r"(thresh), |
953 | [src_pixel_step]"r"((mips_reg)src_pixel_step), | |
954 | [ff_ph_003f]"f"(ff_ph_003f), [ff_ph_0900]"f"(ff_ph_0900), | |
955 | [ff_pb_03]"f"(ff_pb_03), [ff_pb_04]"f"(ff_pb_04), | |
956 | [ff_pb_80]"f"(ff_pb_80), [ff_pb_fe]"f"(ff_pb_fe) | |
1003 | [src_pixel_step]"r"((mips_reg)src_pixel_step) | |
957 | 1004 | : "memory" |
958 | 1005 | ); |
1006 | /* clang-format on */ | |
959 | 1007 | } |
960 | 1008 | |
1009 | /* clang-format off */ | |
961 | 1010 | #define VP8_SIMPLE_HPSRAB \ |
962 | 1011 | "psllh %[ftmp0], %[ftmp5], %[ftmp8] \n\t" \ |
963 | 1012 | "psrah %[ftmp0], %[ftmp0], %[ftmp9] \n\t" \ |
964 | 1013 | "psrlh %[ftmp0], %[ftmp0], %[ftmp8] \n\t" \ |
965 | 1014 | "psrah %[ftmp1], %[ftmp5], %[ftmp10] \n\t" \ |
966 | 1015 | "psllh %[ftmp1], %[ftmp1], %[ftmp8] \n\t" \ |
967 | "or %[ftmp0], %[ftmp0], %[ftmp1] \n\t" | |
1016 | "por %[ftmp0], %[ftmp0], %[ftmp1] \n\t" | |
1017 | /* clang-format on */ | |
968 | 1018 | |
969 | 1019 | void vp8_loop_filter_simple_horizontal_edge_mmi(unsigned char *src_ptr, |
970 | 1020 | int src_pixel_step, |
971 | 1021 | const unsigned char *blimit) { |
972 | uint32_t tmp[1], count = 2; | |
1022 | uint64_t tmp[1], count = 2; | |
973 | 1023 | mips_reg addr[2]; |
974 | 1024 | double ftmp[12]; |
975 | ||
1025 | double ff_pb_fe, ff_pb_80, ff_pb_04, ff_pb_01; | |
1026 | ||
1027 | /* clang-format off */ | |
976 | 1028 | __asm__ volatile ( |
977 | "li %[tmp0], 0x08 \n\t" | |
978 | "mtc1 %[tmp0], %[ftmp8] \n\t" | |
979 | "li %[tmp0], 0x03 \n\t" | |
980 | "mtc1 %[tmp0], %[ftmp9] \n\t" | |
981 | "li %[tmp0], 0x0b \n\t" | |
982 | "mtc1 %[tmp0], %[ftmp10] \n\t" | |
983 | "li %[tmp0], 0x01 \n\t" | |
984 | "mtc1 %[tmp0], %[ftmp11] \n\t" | |
1029 | "dli %[tmp0], 0x0b \n\t" | |
1030 | "dmtc1 %[tmp0], %[ftmp10] \n\t" | |
1031 | "dli %[tmp0], 0x01 \n\t" | |
1032 | "dmtc1 %[tmp0], %[ftmp11] \n\t" | |
1033 | "dli %[tmp0], 0x08 \n\t" | |
1034 | "dmtc1 %[tmp0], %[ftmp8] \n\t" | |
1035 | "dli %[tmp0], 0x03 \n\t" | |
1036 | "dmtc1 %[tmp0], %[ftmp9] \n\t" | |
1037 | "dli %[tmp0], 0x0b \n\t" | |
1038 | "dmtc1 %[tmp0], %[ftmp10] \n\t" | |
1039 | "dli %[tmp0], 0x01 \n\t" | |
1040 | "dmtc1 %[tmp0], %[ftmp11] \n\t" | |
1041 | "dli %[tmp0], 0xfefefefefefefefe \n\t" | |
1042 | "dmtc1 %[tmp0], %[ff_pb_fe] \n\t" | |
1043 | "dli %[tmp0], 0x8080808080808080 \n\t" | |
1044 | "dmtc1 %[tmp0], %[ff_pb_80] \n\t" | |
1045 | "dli %[tmp0], 0x0404040404040404 \n\t" | |
1046 | "dmtc1 %[tmp0], %[ff_pb_04] \n\t" | |
1047 | "dli %[tmp0], 0x0101010101010101 \n\t" | |
1048 | "dmtc1 %[tmp0], %[ff_pb_01] \n\t" | |
985 | 1049 | |
986 | 1050 | "1: \n\t" |
987 | 1051 | "gsldlc1 %[ftmp3], 0x07(%[blimit]) \n\t" |
995 | 1059 | "gsldlc1 %[ftmp7], 0x07(%[addr0]) \n\t" |
996 | 1060 | "gsldrc1 %[ftmp7], 0x00(%[addr0]) \n\t" |
997 | 1061 | "pasubub %[ftmp1], %[ftmp7], %[ftmp2] \n\t" |
998 | "and %[ftmp1], %[ftmp1], %[ff_pb_fe] \n\t" | |
1062 | "pand %[ftmp1], %[ftmp1], %[ff_pb_fe] \n\t" | |
999 | 1063 | "psrlh %[ftmp1], %[ftmp1], %[ftmp11] \n\t" |
1000 | 1064 | |
1001 | 1065 | MMI_SUBU(%[addr1], %[src_ptr], %[src_pixel_step]) |
1007 | 1071 | "paddusb %[ftmp5], %[ftmp5], %[ftmp5] \n\t" |
1008 | 1072 | "paddusb %[ftmp5], %[ftmp5], %[ftmp1] \n\t" |
1009 | 1073 | "psubusb %[ftmp5], %[ftmp5], %[ftmp3] \n\t" |
1010 | "xor %[ftmp3], %[ftmp3], %[ftmp3] \n\t" | |
1074 | "pxor %[ftmp3], %[ftmp3], %[ftmp3] \n\t" | |
1011 | 1075 | "pcmpeqb %[ftmp5], %[ftmp5], %[ftmp3] \n\t" |
1012 | 1076 | |
1013 | "xor %[ftmp2], %[ftmp2], %[ff_pb_80] \n\t" | |
1014 | "xor %[ftmp7], %[ftmp7], %[ff_pb_80] \n\t" | |
1077 | "pxor %[ftmp2], %[ftmp2], %[ff_pb_80] \n\t" | |
1078 | "pxor %[ftmp7], %[ftmp7], %[ff_pb_80] \n\t" | |
1015 | 1079 | "psubsb %[ftmp2], %[ftmp2], %[ftmp7] \n\t" |
1016 | "xor %[ftmp6], %[ftmp6], %[ff_pb_80] \n\t" | |
1017 | "xor %[ftmp3], %[ftmp0], %[ff_pb_80] \n\t" | |
1080 | "pxor %[ftmp6], %[ftmp6], %[ff_pb_80] \n\t" | |
1081 | "pxor %[ftmp3], %[ftmp0], %[ff_pb_80] \n\t" | |
1018 | 1082 | "psubsb %[ftmp0], %[ftmp3], %[ftmp6] \n\t" |
1019 | 1083 | "paddsb %[ftmp2], %[ftmp2], %[ftmp0] \n\t" |
1020 | 1084 | "paddsb %[ftmp2], %[ftmp2], %[ftmp0] \n\t" |
1021 | 1085 | "paddsb %[ftmp2], %[ftmp2], %[ftmp0] \n\t" |
1022 | "and %[ftmp5], %[ftmp5], %[ftmp2] \n\t" | |
1086 | "pand %[ftmp5], %[ftmp5], %[ftmp2] \n\t" | |
1023 | 1087 | |
1024 | 1088 | "paddsb %[ftmp5], %[ftmp5], %[ff_pb_04] \n\t" |
1025 | 1089 | VP8_SIMPLE_HPSRAB |
1026 | 1090 | "psubsb %[ftmp3], %[ftmp3], %[ftmp0] \n\t" |
1027 | "xor %[ftmp3], %[ftmp3], %[ff_pb_80] \n\t" | |
1091 | "pxor %[ftmp3], %[ftmp3], %[ff_pb_80] \n\t" | |
1028 | 1092 | "gssdlc1 %[ftmp3], 0x07(%[src_ptr]) \n\t" |
1029 | 1093 | "gssdrc1 %[ftmp3], 0x00(%[src_ptr]) \n\t" |
1030 | 1094 | |
1031 | 1095 | "psubsb %[ftmp5], %[ftmp5], %[ff_pb_01] \n\t" |
1032 | 1096 | VP8_SIMPLE_HPSRAB |
1033 | 1097 | "paddsb %[ftmp6], %[ftmp6], %[ftmp0] \n\t" |
1034 | "xor %[ftmp6], %[ftmp6], %[ff_pb_80] \n\t" | |
1098 | "pxor %[ftmp6], %[ftmp6], %[ff_pb_80] \n\t" | |
1035 | 1099 | MMI_SUBU(%[addr1], %[src_ptr], %[src_pixel_step]) |
1036 | 1100 | "gssdlc1 %[ftmp6], 0x07(%[addr1]) \n\t" |
1037 | 1101 | "gssdrc1 %[ftmp6], 0x00(%[addr1]) \n\t" |
1047 | 1111 | [ftmp10]"=&f"(ftmp[10]), [ftmp11]"=&f"(ftmp[11]), |
1048 | 1112 | [tmp0]"=&r"(tmp[0]), |
1049 | 1113 | [addr0]"=&r"(addr[0]), [addr1]"=&r"(addr[1]), |
1050 | [src_ptr]"+&r"(src_ptr), [count]"+&r"(count) | |
1114 | [src_ptr]"+&r"(src_ptr), [count]"+&r"(count), | |
1115 | [ff_pb_fe]"=&f"(ff_pb_fe), [ff_pb_80]"=&f"(ff_pb_80), | |
1116 | [ff_pb_04]"=&f"(ff_pb_04), [ff_pb_01]"=&f"(ff_pb_01) | |
1051 | 1117 | : [blimit]"r"(blimit), |
1052 | 1118 | [src_pixel_step]"r"((mips_reg)src_pixel_step), |
1053 | [src_pixel_step_x2]"r"((mips_reg)(src_pixel_step<<1)), | |
1054 | [ff_pb_fe]"f"(ff_pb_fe), [ff_pb_80]"f"(ff_pb_80), | |
1055 | [ff_pb_04]"f"(ff_pb_04), [ff_pb_01]"f"(ff_pb_01) | |
1119 | [src_pixel_step_x2]"r"((mips_reg)(src_pixel_step<<1)) | |
1056 | 1120 | : "memory" |
1057 | 1121 | ); |
1122 | /* clang-format on */ | |
1058 | 1123 | } |
1059 | 1124 | |
1060 | 1125 | void vp8_loop_filter_simple_vertical_edge_mmi(unsigned char *src_ptr, |
1061 | 1126 | int src_pixel_step, |
1062 | 1127 | const unsigned char *blimit) { |
1063 | uint32_t tmp[1], count = 2; | |
1128 | uint64_t tmp[1], count = 2; | |
1064 | 1129 | mips_reg addr[2]; |
1065 | DECLARE_ALIGNED(8, const uint64_t, srct[1]); | |
1066 | double ftmp[12]; | |
1067 | ||
1130 | DECLARE_ALIGNED(8, const uint64_t, srct[2]); | |
1131 | double ftmp[12], ff_pb_fe, ff_pb_80, ff_pb_04, ff_pb_01; | |
1132 | ||
1133 | /* clang-format off */ | |
1068 | 1134 | __asm__ volatile ( |
1069 | "li %[tmp0], 0x08 \n\t" | |
1070 | "mtc1 %[tmp0], %[ftmp8] \n\t" | |
1071 | "li %[tmp0], 0x20 \n\t" | |
1072 | "mtc1 %[tmp0], %[ftmp10] \n\t" | |
1073 | ||
1135 | "dli %[tmp0], 0x08 \n\t" | |
1136 | "dmtc1 %[tmp0], %[ftmp8] \n\t" | |
1137 | "dli %[tmp0], 0x20 \n\t" | |
1138 | "dmtc1 %[tmp0], %[ftmp10] \n\t" | |
1139 | "dli %[tmp0], 0x08 \n\t" | |
1140 | "dmtc1 %[tmp0], %[ftmp8] \n\t" | |
1141 | "dli %[tmp0], 0x20 \n\t" | |
1142 | "dmtc1 %[tmp0], %[ftmp10] \n\t" | |
1143 | "dli %[tmp0], 0xfefefefefefefefe \n\t" | |
1144 | "dmtc1 %[tmp0], %[ff_pb_fe] \n\t" | |
1145 | "dli %[tmp0], 0x8080808080808080 \n\t" | |
1146 | "dmtc1 %[tmp0], %[ff_pb_80] \n\t" | |
1147 | "dli %[tmp0], 0x0404040404040404 \n\t" | |
1148 | "dmtc1 %[tmp0], %[ff_pb_04] \n\t" | |
1149 | "dli %[tmp0], 0x0101010101010101 \n\t" | |
1150 | "dmtc1 %[tmp0], %[ff_pb_01] \n\t" | |
1074 | 1151 | MMI_ADDU(%[src_ptr], %[src_ptr], %[src_pixel_step_x4]) |
1075 | 1152 | MMI_SUBU(%[src_ptr], %[src_ptr], 0x02) |
1076 | 1153 | |
1117 | 1194 | "punpckhwd %[ftmp3], %[ftmp2], %[ftmp5] \n\t" |
1118 | 1195 | "punpcklwd %[ftmp2], %[ftmp2], %[ftmp5] \n\t" |
1119 | 1196 | |
1120 | "li %[tmp0], 0x01 \n\t" | |
1121 | "mtc1 %[tmp0], %[ftmp9] \n\t" | |
1197 | "dli %[tmp0], 0x01 \n\t" | |
1198 | "dmtc1 %[tmp0], %[ftmp9] \n\t" | |
1122 | 1199 | "pasubub %[ftmp6], %[ftmp3], %[ftmp0] \n\t" |
1123 | "and %[ftmp6], %[ftmp6], %[ff_pb_fe] \n\t" | |
1200 | "pand %[ftmp6], %[ftmp6], %[ff_pb_fe] \n\t" | |
1124 | 1201 | "psrlh %[ftmp6], %[ftmp6], %[ftmp9] \n\t" |
1125 | 1202 | "pasubub %[ftmp5], %[ftmp1], %[ftmp2] \n\t" |
1126 | 1203 | "paddusb %[ftmp5], %[ftmp5], %[ftmp5] \n\t" |
1129 | 1206 | "gsldlc1 %[ftmp7], 0x07(%[blimit]) \n\t" |
1130 | 1207 | "gsldrc1 %[ftmp7], 0x00(%[blimit]) \n\t" |
1131 | 1208 | "psubusb %[ftmp5], %[ftmp5], %[ftmp7] \n\t" |
1132 | "xor %[ftmp7], %[ftmp7], %[ftmp7] \n\t" | |
1209 | "pxor %[ftmp7], %[ftmp7], %[ftmp7] \n\t" | |
1133 | 1210 | "pcmpeqb %[ftmp5], %[ftmp5], %[ftmp7] \n\t" |
1134 | 1211 | |
1135 | 1212 | "sdc1 %[ftmp0], 0x00(%[srct]) \n\t" |
1136 | 1213 | "sdc1 %[ftmp3], 0x08(%[srct]) \n\t" |
1137 | 1214 | |
1138 | "xor %[ftmp0], %[ftmp0], %[ff_pb_80] \n\t" | |
1139 | "xor %[ftmp3], %[ftmp3], %[ff_pb_80] \n\t" | |
1215 | "pxor %[ftmp0], %[ftmp0], %[ff_pb_80] \n\t" | |
1216 | "pxor %[ftmp3], %[ftmp3], %[ff_pb_80] \n\t" | |
1140 | 1217 | "psubsb %[ftmp0], %[ftmp0], %[ftmp3] \n\t" |
1141 | 1218 | |
1142 | "xor %[ftmp6], %[ftmp1], %[ff_pb_80] \n\t" | |
1143 | "xor %[ftmp3], %[ftmp2], %[ff_pb_80] \n\t" | |
1219 | "pxor %[ftmp6], %[ftmp1], %[ff_pb_80] \n\t" | |
1220 | "pxor %[ftmp3], %[ftmp2], %[ff_pb_80] \n\t" | |
1144 | 1221 | "psubsb %[ftmp7], %[ftmp3], %[ftmp6] \n\t" |
1145 | 1222 | "paddsb %[ftmp0], %[ftmp0], %[ftmp7] \n\t" |
1146 | 1223 | "paddsb %[ftmp0], %[ftmp0], %[ftmp7] \n\t" |
1147 | 1224 | "paddsb %[ftmp0], %[ftmp0], %[ftmp7] \n\t" |
1148 | "and %[ftmp5], %[ftmp5], %[ftmp0] \n\t" | |
1225 | "pand %[ftmp5], %[ftmp5], %[ftmp0] \n\t" | |
1149 | 1226 | "paddsb %[ftmp5], %[ftmp5], %[ff_pb_04] \n\t" |
1150 | 1227 | |
1151 | "li %[tmp0], 0x03 \n\t" | |
1152 | "mtc1 %[tmp0], %[ftmp9] \n\t" | |
1228 | "dli %[tmp0], 0x03 \n\t" | |
1229 | "dmtc1 %[tmp0], %[ftmp9] \n\t" | |
1153 | 1230 | "psllh %[ftmp0], %[ftmp5], %[ftmp8] \n\t" |
1154 | 1231 | "psrah %[ftmp0], %[ftmp0], %[ftmp9] \n\t" |
1155 | 1232 | "psrlh %[ftmp0], %[ftmp0], %[ftmp8] \n\t" |
1156 | 1233 | |
1157 | "li %[tmp0], 0x0b \n\t" | |
1158 | "mtc1 %[tmp0], %[ftmp9] \n\t" | |
1234 | "dli %[tmp0], 0x0b \n\t" | |
1235 | "dmtc1 %[tmp0], %[ftmp9] \n\t" | |
1159 | 1236 | "psrah %[ftmp7], %[ftmp5], %[ftmp9] \n\t" |
1160 | 1237 | "psllh %[ftmp7], %[ftmp7], %[ftmp8] \n\t" |
1161 | "or %[ftmp0], %[ftmp0], %[ftmp7] \n\t" | |
1238 | "por %[ftmp0], %[ftmp0], %[ftmp7] \n\t" | |
1162 | 1239 | "psubsb %[ftmp3], %[ftmp3], %[ftmp0] \n\t" |
1163 | "xor %[ftmp3], %[ftmp3], %[ff_pb_80] \n\t" | |
1240 | "pxor %[ftmp3], %[ftmp3], %[ff_pb_80] \n\t" | |
1164 | 1241 | "psubsb %[ftmp5], %[ftmp5], %[ff_pb_01] \n\t" |
1165 | 1242 | |
1166 | "li %[tmp0], 0x03 \n\t" | |
1167 | "mtc1 %[tmp0], %[ftmp9] \n\t" | |
1243 | "dli %[tmp0], 0x03 \n\t" | |
1244 | "dmtc1 %[tmp0], %[ftmp9] \n\t" | |
1168 | 1245 | "psllh %[ftmp0], %[ftmp5], %[ftmp8] \n\t" |
1169 | 1246 | "psrah %[ftmp0], %[ftmp0], %[ftmp9] \n\t" |
1170 | 1247 | "psrlh %[ftmp0], %[ftmp0], %[ftmp8] \n\t" |
1171 | 1248 | |
1172 | "li %[tmp0], 0x0b \n\t" | |
1173 | "mtc1 %[tmp0], %[ftmp9] \n\t" | |
1249 | "dli %[tmp0], 0x0b \n\t" | |
1250 | "dmtc1 %[tmp0], %[ftmp9] \n\t" | |
1174 | 1251 | "psrah %[ftmp5], %[ftmp5], %[ftmp9] \n\t" |
1175 | 1252 | "psllh %[ftmp5], %[ftmp5], %[ftmp8] \n\t" |
1176 | "or %[ftmp0], %[ftmp0], %[ftmp5] \n\t" | |
1253 | "por %[ftmp0], %[ftmp0], %[ftmp5] \n\t" | |
1177 | 1254 | "paddsb %[ftmp6], %[ftmp6], %[ftmp0] \n\t" |
1178 | "xor %[ftmp6], %[ftmp6], %[ff_pb_80] \n\t" | |
1255 | "pxor %[ftmp6], %[ftmp6], %[ff_pb_80] \n\t" | |
1179 | 1256 | |
1180 | 1257 | "ldc1 %[ftmp0], 0x00(%[srct]) \n\t" |
1181 | 1258 | "ldc1 %[ftmp4], 0x08(%[srct]) \n\t" |
1194 | 1271 | "punpckhhw %[ftmp5], %[ftmp1], %[ftmp3] \n\t" |
1195 | 1272 | "punpcklhw %[ftmp1], %[ftmp1], %[ftmp3] \n\t" |
1196 | 1273 | |
1197 | "dsrl %[ftmp0], %[ftmp0], %[ftmp10] \n\t" | |
1274 | "ssrld %[ftmp0], %[ftmp0], %[ftmp10] \n\t" | |
1198 | 1275 | MMI_SUBU(%[addr1], %[addr0], %[src_pixel_step_x4]) |
1199 | 1276 | "gsswlc1 %[ftmp0], 0x03(%[addr1]) \n\t" |
1200 | 1277 | "gsswrc1 %[ftmp0], 0x00(%[addr1]) \n\t" |
1202 | 1279 | "gsswlc1 %[ftmp6], 0x03(%[addr1]) \n\t" |
1203 | 1280 | "gsswrc1 %[ftmp6], 0x00(%[addr1]) \n\t" |
1204 | 1281 | |
1205 | "dsrl %[ftmp6], %[ftmp6], %[ftmp10] \n\t" | |
1282 | "ssrld %[ftmp6], %[ftmp6], %[ftmp10] \n\t" | |
1206 | 1283 | "gsswlc1 %[ftmp1], 0x03(%[src_ptr]) \n\t" |
1207 | 1284 | "gsswrc1 %[ftmp1], 0x00(%[src_ptr]) \n\t" |
1208 | 1285 | |
1214 | 1291 | "gsswlc1 %[ftmp5], 0x03(%[addr1]) \n\t" |
1215 | 1292 | "gsswrc1 %[ftmp5], 0x00(%[addr1]) \n\t" |
1216 | 1293 | |
1217 | "dsrl %[ftmp1], %[ftmp1], %[ftmp10] \n\t" | |
1294 | "ssrld %[ftmp1], %[ftmp1], %[ftmp10] \n\t" | |
1218 | 1295 | "gsswlc1 %[ftmp1], 0x03(%[addr0]) \n\t" |
1219 | 1296 | "gsswrc1 %[ftmp1], 0x00(%[addr0]) \n\t" |
1220 | 1297 | |
1221 | "dsrl %[ftmp5], %[ftmp5], %[ftmp10] \n\t" | |
1298 | "ssrld %[ftmp5], %[ftmp5], %[ftmp10] \n\t" | |
1222 | 1299 | MMI_ADDU(%[addr1], %[addr0], %[src_pixel_step_x2]) |
1223 | 1300 | "gsswlc1 %[ftmp5], 0x03(%[addr1]) \n\t" |
1224 | 1301 | "gsswrc1 %[ftmp5], 0x00(%[addr1]) \n\t" |
1234 | 1311 | [ftmp10]"=&f"(ftmp[10]), [ftmp11]"=&f"(ftmp[11]), |
1235 | 1312 | [tmp0]"=&r"(tmp[0]), |
1236 | 1313 | [addr0]"=&r"(addr[0]), [addr1]"=&r"(addr[1]), |
1237 | [src_ptr]"+&r"(src_ptr), [count]"+&r"(count) | |
1314 | [src_ptr]"+&r"(src_ptr), [count]"+&r"(count), | |
1315 | [ff_pb_fe]"=&f"(ff_pb_fe), [ff_pb_80]"=&f"(ff_pb_80), | |
1316 | [ff_pb_04]"=&f"(ff_pb_04), [ff_pb_01]"=&f"(ff_pb_01) | |
1238 | 1317 | : [blimit]"r"(blimit), [srct]"r"(srct), |
1239 | 1318 | [src_pixel_step]"r"((mips_reg)src_pixel_step), |
1240 | 1319 | [src_pixel_step_x2]"r"((mips_reg)(src_pixel_step<<1)), |
1241 | 1320 | [src_pixel_step_x4]"r"((mips_reg)(src_pixel_step<<2)), |
1242 | [src_pixel_step_x8]"r"((mips_reg)(src_pixel_step<<3)), | |
1243 | [ff_pb_fe]"f"(ff_pb_fe), [ff_pb_80]"f"(ff_pb_80), | |
1244 | [ff_pb_04]"f"(ff_pb_04), [ff_pb_01]"f"(ff_pb_01) | |
1321 | [src_pixel_step_x8]"r"((mips_reg)(src_pixel_step<<3)) | |
1245 | 1322 | : "memory" |
1246 | 1323 | ); |
1324 | /* clang-format on */ | |
1247 | 1325 | } |
1248 | 1326 | |
1249 | 1327 | /* Horizontal MB filtering */ |
69 | 69 | unsigned int output_height, |
70 | 70 | unsigned int output_width, |
71 | 71 | const int16_t *vp8_filter) { |
72 | uint32_t tmp[1]; | |
73 | DECLARE_ALIGNED(8, const uint64_t, ff_ph_40) = { 0x0040004000400040ULL }; | |
74 | ||
72 | uint64_t tmp[1]; | |
73 | double ff_ph_40; | |
75 | 74 | #if _MIPS_SIM == _ABIO32 |
76 | 75 | register double fzero asm("$f0"); |
77 | 76 | register double ftmp0 asm("$f2"); |
102 | 101 | register double ftmp11 asm("$f12"); |
103 | 102 | #endif // _MIPS_SIM == _ABIO32 |
104 | 103 | |
104 | /* clang-format off */ | |
105 | 105 | __asm__ volatile ( |
106 | "dli %[tmp0], 0x0040004000400040 \n\t" | |
107 | "dmtc1 %[tmp0], %[ff_ph_40] \n\t" | |
106 | 108 | "ldc1 %[ftmp0], 0x00(%[vp8_filter]) \n\t" |
107 | 109 | "ldc1 %[ftmp1], 0x10(%[vp8_filter]) \n\t" |
108 | 110 | "ldc1 %[ftmp2], 0x20(%[vp8_filter]) \n\t" |
109 | 111 | "ldc1 %[ftmp3], 0x30(%[vp8_filter]) \n\t" |
110 | 112 | "ldc1 %[ftmp4], 0x40(%[vp8_filter]) \n\t" |
111 | 113 | "ldc1 %[ftmp5], 0x50(%[vp8_filter]) \n\t" |
112 | "xor %[fzero], %[fzero], %[fzero] \n\t" | |
113 | "li %[tmp0], 0x07 \n\t" | |
114 | "mtc1 %[tmp0], %[ftmp7] \n\t" | |
115 | "li %[tmp0], 0x08 \n\t" | |
116 | "mtc1 %[tmp0], %[ftmp11] \n\t" | |
114 | "pxor %[fzero], %[fzero], %[fzero] \n\t" | |
115 | "dli %[tmp0], 0x07 \n\t" | |
116 | "dmtc1 %[tmp0], %[ftmp7] \n\t" | |
117 | "dli %[tmp0], 0x08 \n\t" | |
118 | "dmtc1 %[tmp0], %[ftmp11] \n\t" | |
117 | 119 | |
118 | 120 | "1: \n\t" |
119 | 121 | "gsldlc1 %[ftmp9], 0x05(%[src_ptr]) \n\t" |
136 | 138 | "pmullh %[ftmp6], %[ftmp6], %[ftmp5] \n\t" |
137 | 139 | "paddsh %[ftmp8], %[ftmp8], %[ftmp6] \n\t" |
138 | 140 | |
139 | "dsrl %[ftmp10], %[ftmp10], %[ftmp11] \n\t" | |
141 | "ssrld %[ftmp10], %[ftmp10], %[ftmp11] \n\t" | |
140 | 142 | "punpcklbh %[ftmp6], %[ftmp10], %[fzero] \n\t" |
141 | 143 | "pmullh %[ftmp6], %[ftmp6], %[ftmp2] \n\t" |
142 | 144 | "paddsh %[ftmp8], %[ftmp8], %[ftmp6] \n\t" |
143 | 145 | |
144 | "dsrl %[ftmp10], %[ftmp10], %[ftmp11] \n\t" | |
146 | "ssrld %[ftmp10], %[ftmp10], %[ftmp11] \n\t" | |
145 | 147 | "punpcklbh %[ftmp6], %[ftmp10], %[fzero] \n\t" |
146 | 148 | "pmullh %[ftmp6], %[ftmp6], %[ftmp3] \n\t" |
147 | 149 | "paddsh %[ftmp8], %[ftmp8], %[ftmp6] \n\t" |
165 | 167 | [ftmp9]"=&f"(ftmp9), [ftmp10]"=&f"(ftmp10), |
166 | 168 | [ftmp11]"=&f"(ftmp11), [tmp0]"=&r"(tmp[0]), |
167 | 169 | [output_ptr]"+&r"(output_ptr), [output_height]"+&r"(output_height), |
168 | [src_ptr]"+&r"(src_ptr) | |
170 | [src_ptr]"+&r"(src_ptr), [ff_ph_40]"=&f"(ff_ph_40) | |
169 | 171 | : [src_pixels_per_line]"r"((mips_reg)src_pixels_per_line), |
170 | [vp8_filter]"r"(vp8_filter), [output_width]"r"(output_width), | |
171 | [ff_ph_40]"f"(ff_ph_40) | |
172 | [vp8_filter]"r"(vp8_filter), [output_width]"r"(output_width) | |
172 | 173 | : "memory" |
173 | 174 | ); |
175 | /* clang-format on */ | |
174 | 176 | } |
175 | 177 | |
176 | 178 | /* Horizontal filter: pixel_step is always W */ |
177 | 179 | static INLINE void vp8_filter_block1dc_v6_mmi( |
178 | 180 | uint16_t *src_ptr, unsigned char *output_ptr, unsigned int output_height, |
179 | 181 | int output_pitch, unsigned int pixels_per_line, const int16_t *vp8_filter) { |
180 | DECLARE_ALIGNED(8, const uint64_t, ff_ph_40) = { 0x0040004000400040ULL }; | |
181 | uint32_t tmp[1]; | |
182 | double ff_ph_40; | |
183 | uint64_t tmp[1]; | |
182 | 184 | mips_reg addr[1]; |
185 | ||
183 | 186 | #if _MIPS_SIM == _ABIO32 |
184 | 187 | register double fzero asm("$f0"); |
185 | 188 | register double ftmp0 asm("$f2"); |
214 | 217 | register double ftmp13 asm("$f14"); |
215 | 218 | #endif // _MIPS_SIM == _ABIO32 |
216 | 219 | |
220 | /* clang-format off */ | |
217 | 221 | __asm__ volatile ( |
222 | "dli %[tmp0], 0x0040004000400040 \n\t" | |
223 | "dmtc1 %[tmp0], %[ff_ph_40] \n\t" | |
218 | 224 | "ldc1 %[ftmp0], 0x00(%[vp8_filter]) \n\t" |
219 | 225 | "ldc1 %[ftmp1], 0x10(%[vp8_filter]) \n\t" |
220 | 226 | "ldc1 %[ftmp2], 0x20(%[vp8_filter]) \n\t" |
221 | 227 | "ldc1 %[ftmp3], 0x30(%[vp8_filter]) \n\t" |
222 | 228 | "ldc1 %[ftmp4], 0x40(%[vp8_filter]) \n\t" |
223 | 229 | "ldc1 %[ftmp5], 0x50(%[vp8_filter]) \n\t" |
224 | "xor %[fzero], %[fzero], %[fzero] \n\t" | |
225 | "li %[tmp0], 0x07 \n\t" | |
226 | "mtc1 %[tmp0], %[ftmp13] \n\t" | |
230 | "pxor %[fzero], %[fzero], %[fzero] \n\t" | |
231 | "dli %[tmp0], 0x07 \n\t" | |
232 | "dmtc1 %[tmp0], %[ftmp13] \n\t" | |
227 | 233 | |
228 | 234 | /* In order to make full use of memory load delay slot, |
229 | 235 | * Operation of memory loading and calculating has been rearranged. |
284 | 290 | [ftmp11]"=&f"(ftmp11), [ftmp12]"=&f"(ftmp12), |
285 | 291 | [ftmp13]"=&f"(ftmp13), [tmp0]"=&r"(tmp[0]), |
286 | 292 | [addr0]"=&r"(addr[0]), [src_ptr]"+&r"(src_ptr), |
287 | [output_ptr]"+&r"(output_ptr), [output_height]"+&r"(output_height) | |
293 | [output_ptr]"+&r"(output_ptr), [output_height]"+&r"(output_height), | |
294 | [ff_ph_40]"=&f"(ff_ph_40) | |
288 | 295 | : [pixels_per_line]"r"((mips_reg)pixels_per_line), |
289 | 296 | [pixels_per_line_x2]"r"((mips_reg)(pixels_per_line<<1)), |
290 | 297 | [pixels_per_line_x4]"r"((mips_reg)(pixels_per_line<<2)), |
291 | 298 | [vp8_filter]"r"(vp8_filter), |
292 | [output_pitch]"r"((mips_reg)output_pitch), | |
293 | [ff_ph_40]"f"(ff_ph_40) | |
299 | [output_pitch]"r"((mips_reg)output_pitch) | |
294 | 300 | : "memory" |
295 | 301 | ); |
302 | /* clang-format on */ | |
296 | 303 | } |
297 | 304 | |
298 | 305 | /* When xoffset == 0, vp8_filter= {0,0,128,0,0,0}, |
312 | 319 | register double ftmp1 asm("$f2"); |
313 | 320 | #endif // _MIPS_SIM == _ABIO32 |
314 | 321 | |
322 | /* clang-format off */ | |
315 | 323 | __asm__ volatile ( |
316 | "xor %[fzero], %[fzero], %[fzero] \n\t" | |
324 | "pxor %[fzero], %[fzero], %[fzero] \n\t" | |
317 | 325 | |
318 | 326 | "1: \n\t" |
319 | 327 | "gsldlc1 %[ftmp0], 0x07(%[src_ptr]) \n\t" |
334 | 342 | [output_width]"r"(output_width) |
335 | 343 | : "memory" |
336 | 344 | ); |
345 | /* clang-format on */ | |
337 | 346 | } |
338 | 347 | |
339 | 348 | static INLINE void vp8_filter_block1dc_v6_filter0_mmi( |
349 | 358 | register double ftmp1 asm("$f2"); |
350 | 359 | #endif // _MIPS_SIM == _ABIO32 |
351 | 360 | |
361 | /* clang-format on */ | |
352 | 362 | __asm__ volatile ( |
353 | "xor %[fzero], %[fzero], %[fzero] \n\t" | |
363 | "pxor %[fzero], %[fzero], %[fzero] \n\t" | |
354 | 364 | |
355 | 365 | "1: \n\t" |
356 | 366 | "gsldlc1 %[ftmp0], 0x07(%[src_ptr]) \n\t" |
370 | 380 | [output_pitch]"r"((mips_reg)output_pitch) |
371 | 381 | : "memory" |
372 | 382 | ); |
383 | /* clang-format on */ | |
373 | 384 | } |
374 | 385 | |
375 | 386 | #define sixtapNxM(n, m) \ |
121 | 121 | const uint8_t *psrc_m = (const uint8_t *)(psrc); \ |
122 | 122 | uint32_t val_m; \ |
123 | 123 | \ |
124 | asm volatile("ulw %[val_m], %[psrc_m] \n\t" \ | |
125 | \ | |
126 | : [val_m] "=r"(val_m) \ | |
127 | : [psrc_m] "m"(*psrc_m)); \ | |
124 | asm volatile("lwr %[val_m], 0(%[psrc_m]) \n\t" \ | |
125 | "lwl %[val_m], 3(%[psrc_m]) \n\t" \ | |
126 | : [val_m] "=&r"(val_m) \ | |
127 | : [psrc_m] "r"(psrc_m)); \ | |
128 | 128 | \ |
129 | 129 | val_m; \ |
130 | 130 | }) |
135 | 135 | const uint8_t *psrc_m = (const uint8_t *)(psrc); \ |
136 | 136 | uint64_t val_m = 0; \ |
137 | 137 | \ |
138 | asm volatile("uld %[val_m], %[psrc_m] \n\t" \ | |
139 | \ | |
140 | : [val_m] "=r"(val_m) \ | |
141 | : [psrc_m] "m"(*psrc_m)); \ | |
138 | asm volatile("ldr %[val_m], 0(%[psrc_m]) \n\t" \ | |
139 | "ldl %[val_m], 7(%[psrc_m]) \n\t" \ | |
140 | : [val_m] "=&r"(val_m) \ | |
141 | : [psrc_m] "r"(psrc_m)); \ | |
142 | 142 | \ |
143 | 143 | val_m; \ |
144 | 144 | }) |
170 | 170 | #define sem_wait(sem) (semaphore_wait(*sem)) |
171 | 171 | #define sem_post(sem) semaphore_signal(*sem) |
172 | 172 | #define sem_destroy(sem) semaphore_destroy(mach_task_self(), *sem) |
173 | #define thread_sleep(nms) | |
174 | /* { struct timespec ts;ts.tv_sec=0; ts.tv_nsec = | |
175 | 1000*nms;nanosleep(&ts, NULL);} */ | |
176 | 173 | #else |
177 | 174 | #include <unistd.h> |
178 | 175 | #include <sched.h> |
179 | #define thread_sleep(nms) sched_yield(); | |
176 | #endif /* __APPLE__ */ | |
177 | /* Not Windows. Assume pthreads */ | |
178 | ||
179 | /* thread_sleep implementation: yield unless Linux/Unix. */ | |
180 | #if defined(__unix__) || defined(__APPLE__) | |
181 | #define thread_sleep(nms) | |
180 | 182 | /* {struct timespec ts;ts.tv_sec=0; |
181 | 183 | ts.tv_nsec = 1000*nms;nanosleep(&ts, NULL);} */ |
182 | #endif | |
183 | /* Not Windows. Assume pthreads */ | |
184 | #else | |
185 | #define thread_sleep(nms) sched_yield(); | |
186 | #endif /* __unix__ || __APPLE__ */ | |
184 | 187 | |
185 | 188 | #endif |
186 | 189 |
9 | 9 | |
10 | 10 | #include "vpx_config.h" |
11 | 11 | #include "vp8_rtcd.h" |
12 | #if !defined(WIN32) && CONFIG_OS_SUPPORT == 1 | |
12 | #if !defined(_WIN32) && CONFIG_OS_SUPPORT == 1 | |
13 | 13 | #include <unistd.h> |
14 | 14 | #endif |
15 | 15 | #include "onyxd_int.h" |
342 | 342 | const int nsync = cpi->mt_sync_range; |
343 | 343 | vpx_atomic_int rightmost_col = VPX_ATOMIC_INIT(cm->mb_cols + nsync); |
344 | 344 | const vpx_atomic_int *last_row_current_mb_col; |
345 | vpx_atomic_int *current_mb_col = &cpi->mt_current_mb_col[mb_row]; | |
346 | ||
345 | vpx_atomic_int *current_mb_col = NULL; | |
346 | ||
347 | if (vpx_atomic_load_acquire(&cpi->b_multi_threaded) != 0) { | |
348 | current_mb_col = &cpi->mt_current_mb_col[mb_row]; | |
349 | } | |
347 | 350 | if (vpx_atomic_load_acquire(&cpi->b_multi_threaded) != 0 && mb_row != 0) { |
348 | 351 | last_row_current_mb_col = &cpi->mt_current_mb_col[mb_row - 1]; |
349 | 352 | } else { |
23 | 23 | "punpcklhw %[ftmp5], %[ftmp1], %[ftmp0] \n\t" \ |
24 | 24 | "punpcklhw %[ftmp9], %[ftmp2], %[ftmp0] \n\t" \ |
25 | 25 | "pshufh %[ftmp9], %[ftmp9], %[ftmp10] \n\t" \ |
26 | "or %[ftmp5], %[ftmp5], %[ftmp9] \n\t" \ | |
26 | "por %[ftmp5], %[ftmp5], %[ftmp9] \n\t" \ | |
27 | 27 | "punpckhhw %[ftmp6], %[ftmp1], %[ftmp0] \n\t" \ |
28 | 28 | "punpckhhw %[ftmp9], %[ftmp2], %[ftmp0] \n\t" \ |
29 | 29 | "pshufh %[ftmp9], %[ftmp9], %[ftmp10] \n\t" \ |
30 | "or %[ftmp6], %[ftmp6], %[ftmp9] \n\t" \ | |
30 | "por %[ftmp6], %[ftmp6], %[ftmp9] \n\t" \ | |
31 | 31 | "punpcklhw %[ftmp7], %[ftmp3], %[ftmp0] \n\t" \ |
32 | 32 | "punpcklhw %[ftmp9], %[ftmp4], %[ftmp0] \n\t" \ |
33 | 33 | "pshufh %[ftmp9], %[ftmp9], %[ftmp10] \n\t" \ |
34 | "or %[ftmp7], %[ftmp7], %[ftmp9] \n\t" \ | |
34 | "por %[ftmp7], %[ftmp7], %[ftmp9] \n\t" \ | |
35 | 35 | "punpckhhw %[ftmp8], %[ftmp3], %[ftmp0] \n\t" \ |
36 | 36 | "punpckhhw %[ftmp9], %[ftmp4], %[ftmp0] \n\t" \ |
37 | 37 | "pshufh %[ftmp9], %[ftmp9], %[ftmp10] \n\t" \ |
38 | "or %[ftmp8], %[ftmp8], %[ftmp9] \n\t" \ | |
38 | "por %[ftmp8], %[ftmp8], %[ftmp9] \n\t" \ | |
39 | 39 | "punpcklwd %[ftmp1], %[ftmp5], %[ftmp7] \n\t" \ |
40 | 40 | "punpckhwd %[ftmp2], %[ftmp5], %[ftmp7] \n\t" \ |
41 | 41 | "punpcklwd %[ftmp3], %[ftmp6], %[ftmp8] \n\t" \ |
45 | 45 | void vp8_short_fdct4x4_mmi(int16_t *input, int16_t *output, int pitch) { |
46 | 46 | uint64_t tmp[1]; |
47 | 47 | int16_t *ip = input; |
48 | double ff_ph_op1, ff_ph_op3; | |
48 | 49 | |
49 | 50 | #if _MIPS_SIM == _ABIO32 |
50 | 51 | register double ftmp0 asm("$f0"); |
82 | 83 | DECLARE_ALIGNED(8, const uint64_t, ff_pw_51000) = { 0x0000c7380000c738ULL }; |
83 | 84 | DECLARE_ALIGNED(8, const uint64_t, ff_pw_14500) = { 0x000038a4000038a4ULL }; |
84 | 85 | DECLARE_ALIGNED(8, const uint64_t, ff_pw_7500) = { 0x00001d4c00001d4cULL }; |
85 | DECLARE_ALIGNED(8, const uint64_t, ff_ph_op1) = { 0x14e808a914e808a9ULL }; | |
86 | DECLARE_ALIGNED(8, const uint64_t, ff_ph_op3) = { 0xeb1808a9eb1808a9ULL }; | |
87 | 86 | DECLARE_ALIGNED(8, const uint64_t, ff_pw_5352) = { 0x000014e8000014e8ULL }; |
88 | 87 | DECLARE_ALIGNED(8, const uint64_t, ff_pw_2217) = { 0x000008a9000008a9ULL }; |
89 | 88 | DECLARE_ALIGNED(8, const uint64_t, ff_ph_8) = { 0x0008000800080008ULL }; |
90 | 89 | |
90 | /* clang-format off */ | |
91 | 91 | __asm__ volatile ( |
92 | "xor %[ftmp0], %[ftmp0], %[ftmp0] \n\t" | |
92 | "dli %[tmp0], 0x14e808a914e808a9 \n\t" | |
93 | "dmtc1 %[tmp0], %[ff_ph_op1] \n\t" | |
94 | "dli %[tmp0], 0xeb1808a9eb1808a9 \n\t" | |
95 | "dmtc1 %[tmp0], %[ff_ph_op3] \n\t" | |
96 | "pxor %[ftmp0], %[ftmp0], %[ftmp0] \n\t" | |
93 | 97 | "gsldlc1 %[ftmp1], 0x07(%[ip]) \n\t" |
94 | 98 | "gsldrc1 %[ftmp1], 0x00(%[ip]) \n\t" |
95 | 99 | MMI_ADDU(%[ip], %[ip], %[pitch]) |
128 | 132 | |
129 | 133 | // op[1] = (c1 * 2217 + d1 * 5352 + 14500) >> 12 |
130 | 134 | MMI_LI(%[tmp0], 0x0c) |
131 | "mtc1 %[tmp0], %[ftmp11] \n\t" | |
135 | "dmtc1 %[tmp0], %[ftmp11] \n\t" | |
132 | 136 | "ldc1 %[ftmp12], %[ff_pw_14500] \n\t" |
133 | 137 | "punpcklhw %[ftmp9], %[ftmp7], %[ftmp8] \n\t" |
134 | 138 | "pmaddhw %[ftmp5], %[ftmp9], %[ff_ph_op1] \n\t" |
168 | 172 | "paddh %[ftmp1], %[ftmp1], %[ftmp9] \n\t" |
169 | 173 | "paddh %[ftmp2], %[ftmp2], %[ftmp9] \n\t" |
170 | 174 | MMI_LI(%[tmp0], 0x04) |
171 | "mtc1 %[tmp0], %[ftmp9] \n\t" | |
175 | "dmtc1 %[tmp0], %[ftmp9] \n\t" | |
172 | 176 | "psrah %[ftmp1], %[ftmp1], %[ftmp9] \n\t" |
173 | 177 | "psrah %[ftmp2], %[ftmp2], %[ftmp9] \n\t" |
174 | 178 | |
210 | 214 | [ftmp3] "=&f"(ftmp3), [ftmp4] "=&f"(ftmp4), [ftmp5] "=&f"(ftmp5), |
211 | 215 | [ftmp6] "=&f"(ftmp6), [ftmp7] "=&f"(ftmp7), [ftmp8] "=&f"(ftmp8), |
212 | 216 | [ftmp9] "=&f"(ftmp9), [ftmp10] "=&f"(ftmp10), [ftmp11] "=&f"(ftmp11), |
213 | [ftmp12] "=&f"(ftmp12), [tmp0] "=&r"(tmp[0]), [ip]"+&r"(ip) | |
217 | [ftmp12] "=&f"(ftmp12), [tmp0] "=&r"(tmp[0]), [ip]"+&r"(ip), | |
218 | [ff_ph_op1] "=&f"(ff_ph_op1), [ff_ph_op3] "=&f"(ff_ph_op3) | |
214 | 219 | : [ff_ph_01] "m"(ff_ph_01), [ff_ph_07] "m"(ff_ph_07), |
215 | [ff_ph_op1] "f"(ff_ph_op1), [ff_ph_op3] "f"(ff_ph_op3), | |
216 | 220 | [ff_pw_14500] "m"(ff_pw_14500), [ff_pw_7500] "m"(ff_pw_7500), |
217 | 221 | [ff_pw_12000] "m"(ff_pw_12000), [ff_pw_51000] "m"(ff_pw_51000), |
218 | 222 | [ff_pw_5352]"m"(ff_pw_5352), [ff_pw_2217]"m"(ff_pw_2217), |
219 | 223 | [ff_ph_8]"m"(ff_ph_8), [pitch]"r"(pitch), [output] "r"(output) |
220 | 224 | : "memory" |
221 | 225 | ); |
226 | /* clang-format on */ | |
222 | 227 | } |
223 | 228 | |
224 | 229 | void vp8_short_fdct8x4_mmi(int16_t *input, int16_t *output, int pitch) { |
227 | 232 | } |
228 | 233 | |
229 | 234 | void vp8_short_walsh4x4_mmi(int16_t *input, int16_t *output, int pitch) { |
230 | double ftmp[13]; | |
231 | uint32_t tmp[1]; | |
232 | DECLARE_ALIGNED(8, const uint64_t, ff_ph_01) = { 0x0001000100010001ULL }; | |
233 | DECLARE_ALIGNED(8, const uint64_t, ff_pw_01) = { 0x0000000100000001ULL }; | |
234 | DECLARE_ALIGNED(8, const uint64_t, ff_pw_03) = { 0x0000000300000003ULL }; | |
235 | DECLARE_ALIGNED(8, const uint64_t, ff_pw_mask) = { 0x0001000000010000ULL }; | |
236 | ||
235 | double ftmp[13], ff_ph_01, ff_pw_01, ff_pw_03, ff_pw_mask; | |
236 | uint64_t tmp[1]; | |
237 | ||
238 | /* clang-format off */ | |
237 | 239 | __asm__ volatile ( |
240 | "dli %[tmp0], 0x0001000100010001 \n\t" | |
241 | "dmtc1 %[tmp0], %[ff_ph_01] \n\t" | |
242 | "dli %[tmp0], 0x0000000100000001 \n\t" | |
243 | "dmtc1 %[tmp0], %[ff_pw_01] \n\t" | |
244 | "dli %[tmp0], 0x0000000300000003 \n\t" | |
245 | "dmtc1 %[tmp0], %[ff_pw_03] \n\t" | |
246 | "dli %[tmp0], 0x0001000000010000 \n\t" | |
247 | "dmtc1 %[tmp0], %[ff_pw_mask] \n\t" | |
238 | 248 | MMI_LI(%[tmp0], 0x02) |
239 | "xor %[ftmp0], %[ftmp0], %[ftmp0] \n\t" | |
240 | "mtc1 %[tmp0], %[ftmp11] \n\t" | |
249 | "pxor %[ftmp0], %[ftmp0], %[ftmp0] \n\t" | |
250 | "dmtc1 %[tmp0], %[ftmp11] \n\t" | |
241 | 251 | |
242 | 252 | "gsldlc1 %[ftmp1], 0x07(%[ip]) \n\t" |
243 | 253 | "gsldrc1 %[ftmp1], 0x00(%[ip]) \n\t" |
336 | 346 | "psubw %[ftmp4], %[ftmp9], %[ftmp10] \n\t" |
337 | 347 | |
338 | 348 | MMI_LI(%[tmp0], 0x03) |
339 | "mtc1 %[tmp0], %[ftmp11] \n\t" | |
349 | "dmtc1 %[tmp0], %[ftmp11] \n\t" | |
340 | 350 | |
341 | 351 | "pcmpgtw %[ftmp9], %[ftmp0], %[ftmp1] \n\t" |
342 | "and %[ftmp9], %[ftmp9], %[ff_pw_01] \n\t" | |
352 | "pand %[ftmp9], %[ftmp9], %[ff_pw_01] \n\t" | |
343 | 353 | "paddw %[ftmp1], %[ftmp1], %[ftmp9] \n\t" |
344 | 354 | "paddw %[ftmp1], %[ftmp1], %[ff_pw_03] \n\t" |
345 | 355 | "psraw %[ftmp1], %[ftmp1], %[ftmp11] \n\t" |
346 | 356 | |
347 | 357 | "pcmpgtw %[ftmp9], %[ftmp0], %[ftmp2] \n\t" |
348 | "and %[ftmp9], %[ftmp9], %[ff_pw_01] \n\t" | |
358 | "pand %[ftmp9], %[ftmp9], %[ff_pw_01] \n\t" | |
349 | 359 | "paddw %[ftmp2], %[ftmp2], %[ftmp9] \n\t" |
350 | 360 | "paddw %[ftmp2], %[ftmp2], %[ff_pw_03] \n\t" |
351 | 361 | "psraw %[ftmp2], %[ftmp2], %[ftmp11] \n\t" |
352 | 362 | |
353 | 363 | "pcmpgtw %[ftmp9], %[ftmp0], %[ftmp3] \n\t" |
354 | "and %[ftmp9], %[ftmp9], %[ff_pw_01] \n\t" | |
364 | "pand %[ftmp9], %[ftmp9], %[ff_pw_01] \n\t" | |
355 | 365 | "paddw %[ftmp3], %[ftmp3], %[ftmp9] \n\t" |
356 | 366 | "paddw %[ftmp3], %[ftmp3], %[ff_pw_03] \n\t" |
357 | 367 | "psraw %[ftmp3], %[ftmp3], %[ftmp11] \n\t" |
358 | 368 | |
359 | 369 | "pcmpgtw %[ftmp9], %[ftmp0], %[ftmp4] \n\t" |
360 | "and %[ftmp9], %[ftmp9], %[ff_pw_01] \n\t" | |
370 | "pand %[ftmp9], %[ftmp9], %[ff_pw_01] \n\t" | |
361 | 371 | "paddw %[ftmp4], %[ftmp4], %[ftmp9] \n\t" |
362 | 372 | "paddw %[ftmp4], %[ftmp4], %[ff_pw_03] \n\t" |
363 | 373 | "psraw %[ftmp4], %[ftmp4], %[ftmp11] \n\t" |
364 | 374 | |
365 | 375 | "pcmpgtw %[ftmp9], %[ftmp0], %[ftmp5] \n\t" |
366 | "and %[ftmp9], %[ftmp9], %[ff_pw_01] \n\t" | |
376 | "pand %[ftmp9], %[ftmp9], %[ff_pw_01] \n\t" | |
367 | 377 | "paddw %[ftmp5], %[ftmp5], %[ftmp9] \n\t" |
368 | 378 | "paddw %[ftmp5], %[ftmp5], %[ff_pw_03] \n\t" |
369 | 379 | "psraw %[ftmp5], %[ftmp5], %[ftmp11] \n\t" |
370 | 380 | |
371 | 381 | "pcmpgtw %[ftmp9], %[ftmp0], %[ftmp6] \n\t" |
372 | "and %[ftmp9], %[ftmp9], %[ff_pw_01] \n\t" | |
382 | "pand %[ftmp9], %[ftmp9], %[ff_pw_01] \n\t" | |
373 | 383 | "paddw %[ftmp6], %[ftmp6], %[ftmp9] \n\t" |
374 | 384 | "paddw %[ftmp6], %[ftmp6], %[ff_pw_03] \n\t" |
375 | 385 | "psraw %[ftmp6], %[ftmp6], %[ftmp11] \n\t" |
376 | 386 | |
377 | 387 | "pcmpgtw %[ftmp9], %[ftmp0], %[ftmp7] \n\t" |
378 | "and %[ftmp9], %[ftmp9], %[ff_pw_01] \n\t" | |
388 | "pand %[ftmp9], %[ftmp9], %[ff_pw_01] \n\t" | |
379 | 389 | "paddw %[ftmp7], %[ftmp7], %[ftmp9] \n\t" |
380 | 390 | "paddw %[ftmp7], %[ftmp7], %[ff_pw_03] \n\t" |
381 | 391 | "psraw %[ftmp7], %[ftmp7], %[ftmp11] \n\t" |
382 | 392 | |
383 | 393 | "pcmpgtw %[ftmp9], %[ftmp0], %[ftmp8] \n\t" |
384 | "and %[ftmp9], %[ftmp9], %[ff_pw_01] \n\t" | |
394 | "pand %[ftmp9], %[ftmp9], %[ff_pw_01] \n\t" | |
385 | 395 | "paddw %[ftmp8], %[ftmp8], %[ftmp9] \n\t" |
386 | 396 | "paddw %[ftmp8], %[ftmp8], %[ff_pw_03] \n\t" |
387 | 397 | "psraw %[ftmp8], %[ftmp8], %[ftmp11] \n\t" |
392 | 402 | "packsswh %[ftmp4], %[ftmp4], %[ftmp8] \n\t" |
393 | 403 | |
394 | 404 | MMI_LI(%[tmp0], 0x72) |
395 | "mtc1 %[tmp0], %[ftmp11] \n\t" | |
405 | "dmtc1 %[tmp0], %[ftmp11] \n\t" | |
396 | 406 | "pshufh %[ftmp1], %[ftmp1], %[ftmp11] \n\t" |
397 | 407 | "pshufh %[ftmp2], %[ftmp2], %[ftmp11] \n\t" |
398 | 408 | "pshufh %[ftmp3], %[ftmp3], %[ftmp11] \n\t" |
412 | 422 | [ftmp6]"=&f"(ftmp[6]), [ftmp7]"=&f"(ftmp[7]), |
413 | 423 | [ftmp8]"=&f"(ftmp[8]), [ftmp9]"=&f"(ftmp[9]), |
414 | 424 | [ftmp10]"=&f"(ftmp[10]), [ftmp11]"=&f"(ftmp[11]), |
415 | [ftmp12]"=&f"(ftmp[12]), | |
416 | [tmp0]"=&r"(tmp[0]), | |
417 | [ip]"+&r"(input) | |
418 | : [op]"r"(output), | |
419 | [ff_pw_01]"f"(ff_pw_01), [pitch]"r"((mips_reg)pitch), | |
420 | [ff_pw_03]"f"(ff_pw_03), [ff_pw_mask]"f"(ff_pw_mask), | |
421 | [ff_ph_01]"f"(ff_ph_01) | |
425 | [ftmp12]"=&f"(ftmp[12]), [ff_pw_mask]"=&f"(ff_pw_mask), | |
426 | [tmp0]"=&r"(tmp[0]), [ff_pw_01]"=&f"(ff_pw_01), | |
427 | [ip]"+&r"(input), [ff_pw_03]"=&f"(ff_pw_03), | |
428 | [ff_ph_01]"=&f"(ff_ph_01) | |
429 | : [op]"r"(output), [pitch]"r"((mips_reg)pitch) | |
422 | 430 | : "memory" |
423 | 431 | ); |
432 | /* clang-format on */ | |
424 | 433 | } |
41 | 41 | |
42 | 42 | double ftmp[13]; |
43 | 43 | uint64_t tmp[1]; |
44 | DECLARE_ALIGNED(8, const uint64_t, ones) = { 0xffffffffffffffffULL }; | |
45 | int eob = 0; | |
44 | int64_t eob = 0; | |
45 | double ones; | |
46 | 46 | |
47 | 47 | __asm__ volatile( |
48 | 48 | // loop 0 ~ 7 |
49 | "xor %[ftmp0], %[ftmp0], %[ftmp0] \n\t" | |
49 | "pxor %[ftmp0], %[ftmp0], %[ftmp0] \n\t" | |
50 | "pcmpeqh %[ones], %[ones], %[ones] \n\t" | |
50 | 51 | "gsldlc1 %[ftmp1], 0x07(%[coeff_ptr]) \n\t" |
51 | 52 | "gsldrc1 %[ftmp1], 0x00(%[coeff_ptr]) \n\t" |
52 | "li %[tmp0], 0x0f \n\t" | |
53 | "mtc1 %[tmp0], %[ftmp9] \n\t" | |
53 | "dli %[tmp0], 0x0f \n\t" | |
54 | "dmtc1 %[tmp0], %[ftmp9] \n\t" | |
54 | 55 | "gsldlc1 %[ftmp2], 0x0f(%[coeff_ptr]) \n\t" |
55 | 56 | "gsldrc1 %[ftmp2], 0x08(%[coeff_ptr]) \n\t" |
56 | 57 | |
57 | 58 | "psrah %[ftmp3], %[ftmp1], %[ftmp9] \n\t" |
58 | "xor %[ftmp1], %[ftmp3], %[ftmp1] \n\t" | |
59 | "pxor %[ftmp1], %[ftmp3], %[ftmp1] \n\t" | |
59 | 60 | "psubh %[ftmp1], %[ftmp1], %[ftmp3] \n\t" |
60 | 61 | "psrah %[ftmp4], %[ftmp2], %[ftmp9] \n\t" |
61 | "xor %[ftmp2], %[ftmp4], %[ftmp2] \n\t" | |
62 | "pxor %[ftmp2], %[ftmp4], %[ftmp2] \n\t" | |
62 | 63 | "psubh %[ftmp2], %[ftmp2], %[ftmp4] \n\t" |
63 | 64 | |
64 | 65 | "gsldlc1 %[ftmp5], 0x07(%[round_ptr]) \n\t" |
74 | 75 | "pmulhuh %[ftmp5], %[ftmp5], %[ftmp7] \n\t" |
75 | 76 | "pmulhuh %[ftmp6], %[ftmp6], %[ftmp8] \n\t" |
76 | 77 | |
77 | "xor %[ftmp7], %[ftmp5], %[ftmp3] \n\t" | |
78 | "xor %[ftmp8], %[ftmp6], %[ftmp4] \n\t" | |
78 | "pxor %[ftmp7], %[ftmp5], %[ftmp3] \n\t" | |
79 | "pxor %[ftmp8], %[ftmp6], %[ftmp4] \n\t" | |
79 | 80 | "psubh %[ftmp7], %[ftmp7], %[ftmp3] \n\t" |
80 | 81 | "psubh %[ftmp8], %[ftmp8], %[ftmp4] \n\t" |
81 | 82 | "gssdlc1 %[ftmp7], 0x07(%[qcoeff_ptr]) \n\t" |
89 | 90 | "gsldrc1 %[ftmp2], 0x08(%[inv_zig_zag]) \n\t" |
90 | 91 | "pcmpeqh %[ftmp5], %[ftmp5], %[ftmp0] \n\t" |
91 | 92 | "pcmpeqh %[ftmp6], %[ftmp6], %[ftmp0] \n\t" |
92 | "xor %[ftmp5], %[ftmp5], %[ones] \n\t" | |
93 | "xor %[ftmp6], %[ftmp6], %[ones] \n\t" | |
94 | "and %[ftmp5], %[ftmp5], %[ftmp1] \n\t" | |
95 | "and %[ftmp6], %[ftmp6], %[ftmp2] \n\t" | |
93 | "pxor %[ftmp5], %[ftmp5], %[ones] \n\t" | |
94 | "pxor %[ftmp6], %[ftmp6], %[ones] \n\t" | |
95 | "pand %[ftmp5], %[ftmp5], %[ftmp1] \n\t" | |
96 | "pand %[ftmp6], %[ftmp6], %[ftmp2] \n\t" | |
96 | 97 | "pmaxsh %[ftmp10], %[ftmp5], %[ftmp6] \n\t" |
97 | 98 | |
98 | 99 | "gsldlc1 %[ftmp5], 0x07(%[dequant_ptr]) \n\t" |
113 | 114 | "gsldrc1 %[ftmp2], 0x18(%[coeff_ptr]) \n\t" |
114 | 115 | |
115 | 116 | "psrah %[ftmp3], %[ftmp1], %[ftmp9] \n\t" |
116 | "xor %[ftmp1], %[ftmp3], %[ftmp1] \n\t" | |
117 | "pxor %[ftmp1], %[ftmp3], %[ftmp1] \n\t" | |
117 | 118 | "psubh %[ftmp1], %[ftmp1], %[ftmp3] \n\t" |
118 | 119 | "psrah %[ftmp4], %[ftmp2], %[ftmp9] \n\t" |
119 | "xor %[ftmp2], %[ftmp4], %[ftmp2] \n\t" | |
120 | "pxor %[ftmp2], %[ftmp4], %[ftmp2] \n\t" | |
120 | 121 | "psubh %[ftmp2], %[ftmp2], %[ftmp4] \n\t" |
121 | 122 | |
122 | 123 | "gsldlc1 %[ftmp5], 0x17(%[round_ptr]) \n\t" |
132 | 133 | "pmulhuh %[ftmp5], %[ftmp5], %[ftmp7] \n\t" |
133 | 134 | "pmulhuh %[ftmp6], %[ftmp6], %[ftmp8] \n\t" |
134 | 135 | |
135 | "xor %[ftmp7], %[ftmp5], %[ftmp3] \n\t" | |
136 | "xor %[ftmp8], %[ftmp6], %[ftmp4] \n\t" | |
136 | "pxor %[ftmp7], %[ftmp5], %[ftmp3] \n\t" | |
137 | "pxor %[ftmp8], %[ftmp6], %[ftmp4] \n\t" | |
137 | 138 | "psubh %[ftmp7], %[ftmp7], %[ftmp3] \n\t" |
138 | 139 | "psubh %[ftmp8], %[ftmp8], %[ftmp4] \n\t" |
139 | 140 | "gssdlc1 %[ftmp7], 0x17(%[qcoeff_ptr]) \n\t" |
147 | 148 | "gsldrc1 %[ftmp2], 0x18(%[inv_zig_zag]) \n\t" |
148 | 149 | "pcmpeqh %[ftmp5], %[ftmp5], %[ftmp0] \n\t" |
149 | 150 | "pcmpeqh %[ftmp6], %[ftmp6], %[ftmp0] \n\t" |
150 | "xor %[ftmp5], %[ftmp5], %[ones] \n\t" | |
151 | "xor %[ftmp6], %[ftmp6], %[ones] \n\t" | |
152 | "and %[ftmp5], %[ftmp5], %[ftmp1] \n\t" | |
153 | "and %[ftmp6], %[ftmp6], %[ftmp2] \n\t" | |
151 | "pxor %[ftmp5], %[ftmp5], %[ones] \n\t" | |
152 | "pxor %[ftmp6], %[ftmp6], %[ones] \n\t" | |
153 | "pand %[ftmp5], %[ftmp5], %[ftmp1] \n\t" | |
154 | "pand %[ftmp6], %[ftmp6], %[ftmp2] \n\t" | |
154 | 155 | "pmaxsh %[ftmp11], %[ftmp5], %[ftmp6] \n\t" |
155 | 156 | |
156 | 157 | "gsldlc1 %[ftmp5], 0x17(%[dequant_ptr]) \n\t" |
164 | 165 | "gssdlc1 %[ftmp6], 0x1f(%[dqcoeff_ptr]) \n\t" |
165 | 166 | "gssdrc1 %[ftmp6], 0x18(%[dqcoeff_ptr]) \n\t" |
166 | 167 | |
167 | "li %[tmp0], 0x10 \n\t" | |
168 | "mtc1 %[tmp0], %[ftmp9] \n\t" | |
168 | "dli %[tmp0], 0x10 \n\t" | |
169 | "dmtc1 %[tmp0], %[ftmp9] \n\t" | |
169 | 170 | |
170 | 171 | "pmaxsh %[ftmp10], %[ftmp10], %[ftmp11] \n\t" |
171 | 172 | "psrlw %[ftmp11], %[ftmp10], %[ftmp9] \n\t" |
172 | 173 | "pmaxsh %[ftmp10], %[ftmp10], %[ftmp11] \n\t" |
173 | "li %[tmp0], 0xaa \n\t" | |
174 | "mtc1 %[tmp0], %[ftmp9] \n\t" | |
174 | "dli %[tmp0], 0xaa \n\t" | |
175 | "dmtc1 %[tmp0], %[ftmp9] \n\t" | |
175 | 176 | "pshufh %[ftmp11], %[ftmp10], %[ftmp9] \n\t" |
176 | 177 | "pmaxsh %[ftmp10], %[ftmp10], %[ftmp11] \n\t" |
177 | "li %[tmp0], 0xffff \n\t" | |
178 | "mtc1 %[tmp0], %[ftmp9] \n\t" | |
179 | "and %[ftmp10], %[ftmp10], %[ftmp9] \n\t" | |
178 | "dli %[tmp0], 0xffff \n\t" | |
179 | "dmtc1 %[tmp0], %[ftmp9] \n\t" | |
180 | "pand %[ftmp10], %[ftmp10], %[ftmp9] \n\t" | |
180 | 181 | "gssdlc1 %[ftmp10], 0x07(%[eob]) \n\t" |
181 | 182 | "gssdrc1 %[ftmp10], 0x00(%[eob]) \n\t" |
182 | 183 | : [ftmp0] "=&f"(ftmp[0]), [ftmp1] "=&f"(ftmp[1]), [ftmp2] "=&f"(ftmp[2]), |
183 | 184 | [ftmp3] "=&f"(ftmp[3]), [ftmp4] "=&f"(ftmp[4]), [ftmp5] "=&f"(ftmp[5]), |
184 | 185 | [ftmp6] "=&f"(ftmp[6]), [ftmp7] "=&f"(ftmp[7]), [ftmp8] "=&f"(ftmp[8]), |
185 | 186 | [ftmp9] "=&f"(ftmp[9]), [ftmp10] "=&f"(ftmp[10]), |
186 | [ftmp11] "=&f"(ftmp[11]), [ftmp12] "=&f"(ftmp[12]), [tmp0] "=&r"(tmp[0]) | |
187 | [ftmp11] "=&f"(ftmp[11]), [ftmp12] "=&f"(ftmp[12]), | |
188 | [tmp0] "=&r"(tmp[0]), [ones] "=&f"(ones) | |
187 | 189 | : [coeff_ptr] "r"((mips_reg)coeff_ptr), |
188 | 190 | [qcoeff_ptr] "r"((mips_reg)qcoeff_ptr), |
189 | 191 | [dequant_ptr] "r"((mips_reg)dequant_ptr), |
190 | 192 | [round_ptr] "r"((mips_reg)round_ptr), |
191 | 193 | [quant_ptr] "r"((mips_reg)quant_ptr), |
192 | 194 | [dqcoeff_ptr] "r"((mips_reg)dqcoeff_ptr), |
193 | [inv_zig_zag] "r"((mips_reg)inv_zig_zag), [eob] "r"((mips_reg)&eob), | |
194 | [ones] "f"(ones) | |
195 | [inv_zig_zag] "r"((mips_reg)inv_zig_zag), [eob] "r"((mips_reg)&eob) | |
195 | 196 | : "memory"); |
196 | 197 | |
197 | 198 | *d->eob = eob; |
216 | 217 | // memset(dqcoeff_ptr, 0, 32); |
217 | 218 | /* clang-format off */ |
218 | 219 | __asm__ volatile ( |
219 | "xor %[ftmp0], %[ftmp0], %[ftmp0] \n\t" | |
220 | "pxor %[ftmp0], %[ftmp0], %[ftmp0] \n\t" | |
220 | 221 | "gssdlc1 %[ftmp0], 0x07(%[qcoeff_ptr]) \n\t" |
221 | 222 | "gssdrc1 %[ftmp0], 0x00(%[qcoeff_ptr]) \n\t" |
222 | 223 | "gssdlc1 %[ftmp0], 0x0f(%[qcoeff_ptr]) \n\t" |
74 | 74 | |
75 | 75 | // TODO(angiebird): Set frame_index/frame_coding_index on the decoder side |
76 | 76 | // properly. |
77 | int frame_index; // Display order in the video, it's equivalent to the | |
78 | // show_idx defined in EncodeFrameInfo. | |
79 | #if CONFIG_RATE_CTRL | |
77 | int frame_index; // Display order in the video, it's equivalent to the | |
78 | // show_idx defined in EncodeFrameInfo. | |
80 | 79 | int frame_coding_index; // The coding order (starting from zero) of this |
81 | 80 | // frame. |
82 | #endif // CONFIG_RATE_CTRL | |
83 | 81 | vpx_codec_frame_buffer_t raw_frame_buffer; |
84 | 82 | YV12_BUFFER_CONFIG buf; |
85 | 83 | } RefCntBuffer; |
239 | 237 | // TODO(angiebird): current_video_frame/current_frame_coding_index into a |
240 | 238 | // structure |
241 | 239 | unsigned int current_video_frame; |
242 | #if CONFIG_RATE_CTRL | |
243 | 240 | // Each show or no show frame is assigned with a coding index based on its |
244 | 241 | // coding order (starting from zero). |
245 | 242 | |
246 | 243 | // Current frame's coding index. |
247 | 244 | int current_frame_coding_index; |
248 | #endif | |
249 | 245 | BITSTREAM_PROFILE profile; |
250 | 246 | |
251 | 247 | // VPX_BITS_8 in profile 0 or 1, VPX_BITS_10 or VPX_BITS_12 in profile 2 or 3. |
275 | 271 | |
276 | 272 | static INLINE void init_frame_indexes(VP9_COMMON *cm) { |
277 | 273 | cm->current_video_frame = 0; |
278 | #if CONFIG_RATE_CTRL | |
279 | 274 | cm->current_frame_coding_index = 0; |
280 | #endif // CONFIG_RATE_CTRL | |
281 | 275 | } |
282 | 276 | |
283 | 277 | static INLINE void update_frame_indexes(VP9_COMMON *cm, int show_frame) { |
286 | 280 | // update not a real frame |
287 | 281 | ++cm->current_video_frame; |
288 | 282 | } |
289 | #if CONFIG_RATE_CTRL | |
290 | 283 | ++cm->current_frame_coding_index; |
291 | #endif // CONFIG_RATE_CTRL | |
292 | 284 | } |
293 | 285 | |
294 | 286 | typedef struct { |
1023 | 1023 | #if CONFIG_RATE_CTRL |
1024 | 1024 | free_partition_info(cpi); |
1025 | 1025 | free_motion_vector_info(cpi); |
1026 | free_fp_motion_vector_info(cpi); | |
1027 | free_tpl_stats_info(cpi); | |
1026 | 1028 | #endif |
1027 | 1029 | |
1028 | 1030 | vp9_free_ref_frame_buffers(cm->buffer_pool); |
2314 | 2316 | cpi->frame_info = vp9_get_frame_info(oxcf); |
2315 | 2317 | |
2316 | 2318 | vp9_rc_init(&cpi->oxcf, oxcf->pass, &cpi->rc); |
2319 | vp9_init_rd_parameters(cpi); | |
2317 | 2320 | |
2318 | 2321 | init_frame_indexes(cm); |
2319 | 2322 | cpi->partition_search_skippable_frame = 0; |
2461 | 2464 | |
2462 | 2465 | cpi->allow_encode_breakout = ENCODE_BREAKOUT_ENABLED; |
2463 | 2466 | |
2467 | { | |
2468 | vpx_codec_err_t codec_status = vp9_extrc_init(&cpi->ext_ratectrl); | |
2469 | if (codec_status != VPX_CODEC_OK) { | |
2470 | vpx_internal_error(&cm->error, codec_status, "vp9_extrc_init() failed"); | |
2471 | } | |
2472 | } | |
2473 | ||
2464 | 2474 | #if !CONFIG_REALTIME_ONLY |
2465 | 2475 | if (oxcf->pass == 1) { |
2466 | 2476 | vp9_init_first_pass(cpi); |
2660 | 2670 | encode_command_init(&cpi->encode_command); |
2661 | 2671 | partition_info_init(cpi); |
2662 | 2672 | motion_vector_info_init(cpi); |
2673 | fp_motion_vector_info_init(cpi); | |
2674 | tpl_stats_info_init(cpi); | |
2663 | 2675 | #endif |
2664 | 2676 | |
2665 | 2677 | return cpi; |
2830 | 2842 | cpi->twopass.frame_mb_stats_buf = NULL; |
2831 | 2843 | } |
2832 | 2844 | #endif |
2845 | ||
2846 | vp9_extrc_delete(&cpi->ext_ratectrl); | |
2833 | 2847 | |
2834 | 2848 | vp9_remove_common(cm); |
2835 | 2849 | vp9_free_ref_frame_buffers(cm->buffer_pool); |
3310 | 3324 | // Skip loop filter in show_existing_frame mode. |
3311 | 3325 | if (cm->show_existing_frame) { |
3312 | 3326 | lf->filter_level = 0; |
3327 | return; | |
3328 | } | |
3329 | ||
3330 | if (cpi->loopfilter_ctrl == NO_LOOPFILTER || | |
3331 | (!is_reference_frame && cpi->loopfilter_ctrl == LOOPFILTER_REFERENCE)) { | |
3332 | lf->filter_level = 0; | |
3333 | vpx_extend_frame_inner_borders(cm->frame_to_show); | |
3313 | 3334 | return; |
3314 | 3335 | } |
3315 | 3336 | |
4043 | 4064 | // For 1 pass CBR SVC, only ZEROMV is allowed for spatial reference frame |
4044 | 4065 | // when svc->force_zero_mode_spatial_ref = 1. Under those conditions we can |
4045 | 4066 | // avoid this frame-level upsampling (for non intra_only frames). |
4067 | // For SVC single_layer mode, dynamic resize is allowed and we need to | |
4068 | // scale references for this case. | |
4046 | 4069 | if (frame_is_intra_only(cm) == 0 && |
4047 | !(is_one_pass_cbr_svc(cpi) && svc->force_zero_mode_spatial_ref)) { | |
4070 | ((svc->single_layer_svc && cpi->oxcf.resize_mode == RESIZE_DYNAMIC) || | |
4071 | !(is_one_pass_cbr_svc(cpi) && svc->force_zero_mode_spatial_ref))) { | |
4048 | 4072 | vp9_scale_references(cpi); |
4049 | 4073 | } |
4050 | 4074 | |
4189 | 4213 | return 1; |
4190 | 4214 | } |
4191 | 4215 | |
4216 | static int get_ref_frame_flags(const VP9_COMP *cpi) { | |
4217 | const int *const map = cpi->common.ref_frame_map; | |
4218 | const int gold_is_last = map[cpi->gld_fb_idx] == map[cpi->lst_fb_idx]; | |
4219 | const int alt_is_last = map[cpi->alt_fb_idx] == map[cpi->lst_fb_idx]; | |
4220 | const int gold_is_alt = map[cpi->gld_fb_idx] == map[cpi->alt_fb_idx]; | |
4221 | int flags = VP9_ALT_FLAG | VP9_GOLD_FLAG | VP9_LAST_FLAG; | |
4222 | ||
4223 | if (gold_is_last) flags &= ~VP9_GOLD_FLAG; | |
4224 | ||
4225 | if (cpi->rc.frames_till_gf_update_due == INT_MAX && | |
4226 | (cpi->svc.number_temporal_layers == 1 && | |
4227 | cpi->svc.number_spatial_layers == 1)) | |
4228 | flags &= ~VP9_GOLD_FLAG; | |
4229 | ||
4230 | if (alt_is_last) flags &= ~VP9_ALT_FLAG; | |
4231 | ||
4232 | if (gold_is_alt) flags &= ~VP9_ALT_FLAG; | |
4233 | ||
4234 | return flags; | |
4235 | } | |
4236 | ||
4192 | 4237 | #if !CONFIG_REALTIME_ONLY |
4193 | 4238 | #define MAX_QSTEP_ADJ 4 |
4194 | 4239 | static int get_qstep_adj(int rate_excess, int rate_limit) { |
4197 | 4242 | return VPXMIN(qstep, MAX_QSTEP_ADJ); |
4198 | 4243 | } |
4199 | 4244 | |
4200 | static void encode_with_recode_loop(VP9_COMP *cpi, size_t *size, | |
4201 | uint8_t *dest) { | |
4245 | #if CONFIG_RATE_CTRL | |
4246 | static void init_rq_history(RATE_QINDEX_HISTORY *rq_history) { | |
4247 | rq_history->recode_count = 0; | |
4248 | rq_history->q_index_high = 255; | |
4249 | rq_history->q_index_low = 0; | |
4250 | } | |
4251 | ||
4252 | static void update_rq_history(RATE_QINDEX_HISTORY *rq_history, int target_bits, | |
4253 | int actual_bits, int q_index) { | |
4254 | rq_history->q_index_history[rq_history->recode_count] = q_index; | |
4255 | rq_history->rate_history[rq_history->recode_count] = actual_bits; | |
4256 | if (actual_bits <= target_bits) { | |
4257 | rq_history->q_index_high = q_index; | |
4258 | } | |
4259 | if (actual_bits >= target_bits) { | |
4260 | rq_history->q_index_low = q_index; | |
4261 | } | |
4262 | rq_history->recode_count += 1; | |
4263 | } | |
4264 | ||
4265 | static int guess_q_index_from_model(const RATE_QSTEP_MODEL *rq_model, | |
4266 | int target_bits) { | |
4267 | // The model predicts bits as follows. | |
4268 | // target_bits = bias - ratio * log2(q_step) | |
4269 | // Given the target_bits, we compute the q_step as follows. | |
4270 | double q_step; | |
4271 | assert(rq_model->ratio > 0); | |
4272 | q_step = pow(2.0, (rq_model->bias - target_bits) / rq_model->ratio); | |
4273 | // TODO(angiebird): Make this function support highbitdepth. | |
4274 | return vp9_convert_q_to_qindex(q_step, VPX_BITS_8); | |
4275 | } | |
4276 | ||
4277 | static int guess_q_index_linear(int prev_q_index, int target_bits, | |
4278 | int actual_bits, int gap) { | |
4279 | int q_index = prev_q_index; | |
4280 | if (actual_bits < target_bits) { | |
4281 | q_index -= gap; | |
4282 | q_index = VPXMAX(q_index, 0); | |
4283 | } else { | |
4284 | q_index += gap; | |
4285 | q_index = VPXMIN(q_index, 255); | |
4286 | } | |
4287 | return q_index; | |
4288 | } | |
4289 | ||
4290 | static double get_bits_percent_diff(int target_bits, int actual_bits) { | |
4291 | double diff; | |
4292 | target_bits = VPXMAX(target_bits, 1); | |
4293 | diff = abs(target_bits - actual_bits) * 1. / target_bits; | |
4294 | return diff * 100; | |
4295 | } | |
4296 | ||
4297 | static int rq_model_predict_q_index(const RATE_QSTEP_MODEL *rq_model, | |
4298 | const RATE_QINDEX_HISTORY *rq_history, | |
4299 | int target_bits) { | |
4300 | int q_index = 128; | |
4301 | if (rq_history->recode_count > 0) { | |
4302 | const int actual_bits = | |
4303 | rq_history->rate_history[rq_history->recode_count - 1]; | |
4304 | const int prev_q_index = | |
4305 | rq_history->q_index_history[rq_history->recode_count - 1]; | |
4306 | const double percent_diff = get_bits_percent_diff(target_bits, actual_bits); | |
4307 | if (percent_diff > 50) { | |
4308 | // Binary search. | |
4309 | // When the actual_bits and target_bits are far apart, binary search | |
4310 | // q_index is faster. | |
4311 | q_index = (rq_history->q_index_low + rq_history->q_index_high) / 2; | |
4312 | } else { | |
4313 | if (rq_model->ready) { | |
4314 | q_index = guess_q_index_from_model(rq_model, target_bits); | |
4315 | } else { | |
4316 | // TODO(angiebird): Find a better way to set the gap. | |
4317 | q_index = | |
4318 | guess_q_index_linear(prev_q_index, target_bits, actual_bits, 20); | |
4319 | } | |
4320 | } | |
4321 | } else { | |
4322 | if (rq_model->ready) { | |
4323 | q_index = guess_q_index_from_model(rq_model, target_bits); | |
4324 | } | |
4325 | } | |
4326 | ||
4327 | assert(rq_history->q_index_low <= rq_history->q_index_high); | |
4328 | if (q_index <= rq_history->q_index_low) { | |
4329 | q_index = rq_history->q_index_low + 1; | |
4330 | } | |
4331 | if (q_index >= rq_history->q_index_high) { | |
4332 | q_index = rq_history->q_index_high - 1; | |
4333 | } | |
4334 | return q_index; | |
4335 | } | |
4336 | ||
4337 | static void rq_model_update(const RATE_QINDEX_HISTORY *rq_history, | |
4338 | int target_bits, RATE_QSTEP_MODEL *rq_model) { | |
4339 | const int recode_count = rq_history->recode_count; | |
4340 | const double delta = 0.00001; | |
4341 | if (recode_count >= 2) { | |
4342 | const int q_index1 = rq_history->q_index_history[recode_count - 2]; | |
4343 | const int q_index2 = rq_history->q_index_history[recode_count - 1]; | |
4344 | const int r1 = rq_history->rate_history[recode_count - 2]; | |
4345 | const int r2 = rq_history->rate_history[recode_count - 1]; | |
4346 | int valid = 0; | |
4347 | // lower q_index should yield higher bit rate | |
4348 | if (q_index1 < q_index2) { | |
4349 | valid = r1 > r2; | |
4350 | } else if (q_index1 > q_index2) { | |
4351 | valid = r1 < r2; | |
4352 | } | |
4353 | // Only update the model when the q_index and rate behave normally. | |
4354 | if (valid) { | |
4355 | // Fit the ratio and bias of rq_model based on last two recode histories. | |
4356 | const double s1 = vp9_convert_qindex_to_q(q_index1, VPX_BITS_8); | |
4357 | const double s2 = vp9_convert_qindex_to_q(q_index2, VPX_BITS_8); | |
4358 | if (fabs(log2(s1) - log2(s2)) > delta) { | |
4359 | rq_model->ratio = (r2 - r1) / (log2(s1) - log2(s2)); | |
4360 | rq_model->bias = r1 + (rq_model->ratio) * log2(s1); | |
4361 | if (rq_model->ratio > delta && rq_model->bias > delta) { | |
4362 | rq_model->ready = 1; | |
4363 | } | |
4364 | } | |
4365 | } | |
4366 | } else if (recode_count == 1) { | |
4367 | if (rq_model->ready) { | |
4368 | // Update the ratio only when the initial model exists and we only have | |
4369 | // one recode history. | |
4370 | const int prev_q = rq_history->q_index_history[recode_count - 1]; | |
4371 | const double prev_q_step = vp9_convert_qindex_to_q(prev_q, VPX_BITS_8); | |
4372 | if (fabs(log2(prev_q_step)) > delta) { | |
4373 | const int actual_bits = rq_history->rate_history[recode_count - 1]; | |
4374 | rq_model->ratio = | |
4375 | rq_model->ratio + (target_bits - actual_bits) / log2(prev_q_step); | |
4376 | } | |
4377 | } | |
4378 | } | |
4379 | } | |
4380 | #endif // CONFIG_RATE_CTRL | |
4381 | ||
4382 | static void encode_with_recode_loop(VP9_COMP *cpi, size_t *size, uint8_t *dest | |
4383 | #if CONFIG_RATE_CTRL | |
4384 | , | |
4385 | RATE_QINDEX_HISTORY *rq_history | |
4386 | #endif // CONFIG_RATE_CTRL | |
4387 | ) { | |
4202 | 4388 | const VP9EncoderConfig *const oxcf = &cpi->oxcf; |
4203 | 4389 | VP9_COMMON *const cm = &cpi->common; |
4204 | 4390 | RATE_CONTROL *const rc = &cpi->rc; |
4216 | 4402 | int qrange_adj = 1; |
4217 | 4403 | #endif |
4218 | 4404 | |
4405 | // A flag which indicates whether we are recoding the current frame | |
4406 | // when the current frame size is larger than the max frame size in the | |
4407 | // external rate control model. | |
4408 | // This flag doesn't have any impact when external rate control is not used. | |
4409 | int ext_rc_recode = 0; | |
4410 | // Maximal frame size allowed by the external rate control. | |
4411 | // case: 0, we ignore the max frame size limit, and encode with the qindex | |
4412 | // passed in by the external rate control model. | |
4413 | // case: -1, we take VP9's decision for the max frame size. | |
4414 | int ext_rc_max_frame_size = 0; | |
4415 | ||
4416 | #if CONFIG_RATE_CTRL | |
4417 | const FRAME_UPDATE_TYPE update_type = | |
4418 | cpi->twopass.gf_group.update_type[cpi->twopass.gf_group.index]; | |
4419 | const ENCODE_FRAME_TYPE frame_type = get_encode_frame_type(update_type); | |
4420 | RATE_QSTEP_MODEL *rq_model = &cpi->rq_model[frame_type]; | |
4421 | init_rq_history(rq_history); | |
4422 | #endif // CONFIG_RATE_CTRL | |
4423 | ||
4219 | 4424 | if (cm->show_existing_frame) { |
4220 | 4425 | rc->this_frame_target = 0; |
4221 | 4426 | if (is_psnr_calc_enabled(cpi)) set_raw_source_frame(cpi); |
4262 | 4467 | loop_at_this_size = 0; |
4263 | 4468 | } |
4264 | 4469 | |
4470 | #if CONFIG_RATE_CTRL | |
4471 | if (cpi->encode_command.use_external_target_frame_bits) { | |
4472 | q = rq_model_predict_q_index(rq_model, rq_history, rc->this_frame_target); | |
4473 | } | |
4474 | #endif // CONFIG_RATE_CTRL | |
4265 | 4475 | // Decide frame size bounds first time through. |
4266 | 4476 | if (loop_count == 0) { |
4267 | 4477 | vp9_rc_compute_frame_size_bounds(cpi, rc->this_frame_target, |
4308 | 4518 | q = cpi->encode_command.external_quantize_index; |
4309 | 4519 | } |
4310 | 4520 | #endif |
4521 | if (cpi->ext_ratectrl.ready && !ext_rc_recode) { | |
4522 | vpx_codec_err_t codec_status; | |
4523 | const GF_GROUP *gf_group = &cpi->twopass.gf_group; | |
4524 | vpx_rc_encodeframe_decision_t encode_frame_decision; | |
4525 | FRAME_UPDATE_TYPE update_type = gf_group->update_type[gf_group->index]; | |
4526 | const int ref_frame_flags = get_ref_frame_flags(cpi); | |
4527 | RefCntBuffer *ref_frame_bufs[MAX_INTER_REF_FRAMES]; | |
4528 | const RefCntBuffer *curr_frame_buf = | |
4529 | get_ref_cnt_buffer(cm, cm->new_fb_idx); | |
4530 | get_ref_frame_bufs(cpi, ref_frame_bufs); | |
4531 | codec_status = vp9_extrc_get_encodeframe_decision( | |
4532 | &cpi->ext_ratectrl, curr_frame_buf->frame_index, | |
4533 | cm->current_frame_coding_index, gf_group->index, update_type, | |
4534 | ref_frame_bufs, ref_frame_flags, &encode_frame_decision); | |
4535 | if (codec_status != VPX_CODEC_OK) { | |
4536 | vpx_internal_error(&cm->error, codec_status, | |
4537 | "vp9_extrc_get_encodeframe_decision() failed"); | |
4538 | } | |
4539 | q = encode_frame_decision.q_index; | |
4540 | ext_rc_max_frame_size = encode_frame_decision.max_frame_size; | |
4541 | } | |
4311 | 4542 | |
4312 | 4543 | vp9_set_quantizer(cpi, q); |
4313 | 4544 | |
4347 | 4578 | if (frame_over_shoot_limit == 0) frame_over_shoot_limit = 1; |
4348 | 4579 | } |
4349 | 4580 | |
4581 | if (cpi->ext_ratectrl.ready) { | |
4582 | // In general, for the external rate control, we take the qindex provided | |
4583 | // as input and encode the frame with this qindex faithfully. However, | |
4584 | // in some extreme scenarios, the provided qindex leads to a massive | |
4585 | // overshoot of frame size. In this case, we fall back to VP9's decision | |
4586 | // to pick a new qindex and recode the frame. We return the new qindex | |
4587 | // through the API to the external model. | |
4588 | if (ext_rc_max_frame_size == 0) { | |
4589 | break; | |
4590 | } else if (ext_rc_max_frame_size == -1) { | |
4591 | if (rc->projected_frame_size < rc->max_frame_bandwidth) { | |
4592 | break; | |
4593 | } | |
4594 | } else { | |
4595 | if (rc->projected_frame_size < ext_rc_max_frame_size) { | |
4596 | break; | |
4597 | } | |
4598 | } | |
4599 | ext_rc_recode = 1; | |
4600 | } | |
4350 | 4601 | #if CONFIG_RATE_CTRL |
4351 | 4602 | // This part needs to be after save_coding_context() because |
4352 | 4603 | // restore_coding_context will be called in the end of this function. |
4355 | 4606 | if (cpi->encode_command.use_external_quantize_index) { |
4356 | 4607 | break; |
4357 | 4608 | } |
4358 | #endif | |
4609 | ||
4610 | if (cpi->encode_command.use_external_target_frame_bits) { | |
4611 | const double percent_diff = get_bits_percent_diff( | |
4612 | rc->this_frame_target, rc->projected_frame_size); | |
4613 | update_rq_history(rq_history, rc->this_frame_target, | |
4614 | rc->projected_frame_size, q); | |
4615 | loop_count += 1; | |
4616 | ||
4617 | rq_model_update(rq_history, rc->this_frame_target, rq_model); | |
4618 | ||
4619 | // Check if we hit the target bitrate. | |
4620 | if (percent_diff <= cpi->encode_command.target_frame_bits_error_percent || | |
4621 | rq_history->recode_count >= RATE_CTRL_MAX_RECODE_NUM || | |
4622 | rq_history->q_index_low >= rq_history->q_index_high) { | |
4623 | break; | |
4624 | } | |
4625 | ||
4626 | loop = 1; | |
4627 | restore_coding_context(cpi); | |
4628 | continue; | |
4629 | } | |
4630 | #endif // CONFIG_RATE_CTRL | |
4359 | 4631 | |
4360 | 4632 | if (oxcf->rc_mode == VPX_Q) { |
4361 | 4633 | loop = 0; |
4569 | 4841 | } |
4570 | 4842 | } |
4571 | 4843 | #endif // !CONFIG_REALTIME_ONLY |
4572 | ||
4573 | static int get_ref_frame_flags(const VP9_COMP *cpi) { | |
4574 | const int *const map = cpi->common.ref_frame_map; | |
4575 | const int gold_is_last = map[cpi->gld_fb_idx] == map[cpi->lst_fb_idx]; | |
4576 | const int alt_is_last = map[cpi->alt_fb_idx] == map[cpi->lst_fb_idx]; | |
4577 | const int gold_is_alt = map[cpi->gld_fb_idx] == map[cpi->alt_fb_idx]; | |
4578 | int flags = VP9_ALT_FLAG | VP9_GOLD_FLAG | VP9_LAST_FLAG; | |
4579 | ||
4580 | if (gold_is_last) flags &= ~VP9_GOLD_FLAG; | |
4581 | ||
4582 | if (cpi->rc.frames_till_gf_update_due == INT_MAX && | |
4583 | (cpi->svc.number_temporal_layers == 1 && | |
4584 | cpi->svc.number_spatial_layers == 1)) | |
4585 | flags &= ~VP9_GOLD_FLAG; | |
4586 | ||
4587 | if (alt_is_last) flags &= ~VP9_ALT_FLAG; | |
4588 | ||
4589 | if (gold_is_alt) flags &= ~VP9_ALT_FLAG; | |
4590 | ||
4591 | return flags; | |
4592 | } | |
4593 | 4844 | |
4594 | 4845 | static void set_ext_overrides(VP9_COMP *cpi) { |
4595 | 4846 | // Overrides the defaults with the externally supplied values with |
4895 | 5146 | const GF_GROUP *const gf_group = &cpi->twopass.gf_group; |
4896 | 5147 | ref_buffer->frame_index = |
4897 | 5148 | cm->current_video_frame + gf_group->arf_src_offset[gf_group->index]; |
4898 | #if CONFIG_RATE_CTRL | |
4899 | 5149 | ref_buffer->frame_coding_index = cm->current_frame_coding_index; |
4900 | #endif // CONFIG_RATE_CTRL | |
4901 | 5150 | } |
4902 | 5151 | } |
4903 | 5152 | |
5100 | 5349 | #if CONFIG_RATE_CTRL |
5101 | 5350 | const PARTITION_INFO *partition_info, |
5102 | 5351 | const MOTION_VECTOR_INFO *motion_vector_info, |
5352 | const TplDepStats *tpl_stats_info, | |
5103 | 5353 | #endif // CONFIG_RATE_CTRL |
5104 | 5354 | ENCODE_FRAME_RESULT *encode_frame_result); |
5105 | 5355 | #endif // !CONFIG_REALTIME_ONLY |
5205 | 5455 | if (!encode_without_recode_loop(cpi, size, dest)) return; |
5206 | 5456 | } else { |
5207 | 5457 | #if !CONFIG_REALTIME_ONLY |
5458 | #if CONFIG_RATE_CTRL | |
5459 | encode_with_recode_loop(cpi, size, dest, &encode_frame_result->rq_history); | |
5460 | #else // CONFIG_RATE_CTRL | |
5208 | 5461 | encode_with_recode_loop(cpi, size, dest); |
5209 | #endif | |
5462 | #endif // CONFIG_RATE_CTRL | |
5463 | #endif // !CONFIG_REALTIME_ONLY | |
5210 | 5464 | } |
5211 | 5465 | |
5212 | 5466 | // TODO(jingning): When using show existing frame mode, we assume that the |
5271 | 5525 | // build the bitstream |
5272 | 5526 | vp9_pack_bitstream(cpi, dest, size); |
5273 | 5527 | |
5528 | { | |
5529 | const RefCntBuffer *coded_frame_buf = | |
5530 | get_ref_cnt_buffer(cm, cm->new_fb_idx); | |
5531 | vpx_codec_err_t codec_status = vp9_extrc_update_encodeframe_result( | |
5532 | &cpi->ext_ratectrl, (*size) << 3, cpi->Source, &coded_frame_buf->buf, | |
5533 | cm->bit_depth, cpi->oxcf.input_bit_depth, cm->base_qindex); | |
5534 | if (codec_status != VPX_CODEC_OK) { | |
5535 | vpx_internal_error(&cm->error, codec_status, | |
5536 | "vp9_extrc_update_encodeframe_result() failed"); | |
5537 | } | |
5538 | } | |
5274 | 5539 | #if CONFIG_REALTIME_ONLY |
5275 | 5540 | (void)encode_frame_result; |
5276 | 5541 | assert(encode_frame_result == NULL); |
5301 | 5566 | ref_frame_flags, |
5302 | 5567 | cpi->twopass.gf_group.update_type[cpi->twopass.gf_group.index], |
5303 | 5568 | cpi->Source, coded_frame_buf, ref_frame_bufs, vp9_get_quantizer(cpi), |
5304 | cpi->oxcf.input_bit_depth, cm->bit_depth, cpi->td.counts, | |
5569 | cm->bit_depth, cpi->oxcf.input_bit_depth, cpi->td.counts, | |
5305 | 5570 | #if CONFIG_RATE_CTRL |
5306 | cpi->partition_info, cpi->motion_vector_info, | |
5571 | cpi->partition_info, cpi->motion_vector_info, cpi->tpl_stats_info, | |
5307 | 5572 | #endif // CONFIG_RATE_CTRL |
5308 | 5573 | encode_frame_result); |
5309 | 5574 | } |
5458 | 5723 | unsigned int *frame_flags, |
5459 | 5724 | ENCODE_FRAME_RESULT *encode_frame_result) { |
5460 | 5725 | cpi->allow_encode_breakout = ENCODE_BREAKOUT_ENABLED; |
5726 | ||
5727 | if (cpi->common.current_frame_coding_index == 0) { | |
5728 | VP9_COMMON *cm = &cpi->common; | |
5729 | const vpx_codec_err_t codec_status = vp9_extrc_send_firstpass_stats( | |
5730 | &cpi->ext_ratectrl, &cpi->twopass.first_pass_info); | |
5731 | if (codec_status != VPX_CODEC_OK) { | |
5732 | vpx_internal_error(&cm->error, codec_status, | |
5733 | "vp9_extrc_send_firstpass_stats() failed"); | |
5734 | } | |
5735 | } | |
5461 | 5736 | #if CONFIG_MISMATCH_DEBUG |
5462 | 5737 | mismatch_move_frame_idx_w(); |
5463 | 5738 | #endif |
7149 | 7424 | } |
7150 | 7425 | } |
7151 | 7426 | |
7427 | #if CONFIG_RATE_CTRL | |
7428 | static void accumulate_frame_tpl_stats(VP9_COMP *cpi) { | |
7429 | VP9_COMMON *const cm = &cpi->common; | |
7430 | const GF_GROUP *gf_group = &cpi->twopass.gf_group; | |
7431 | int show_frame_count = 0; | |
7432 | int frame_idx; | |
7433 | // Accumulate tpl stats for each frame in the current group of picture. | |
7434 | for (frame_idx = 1; frame_idx < gf_group->gf_group_size; ++frame_idx) { | |
7435 | TplDepFrame *tpl_frame = &cpi->tpl_stats[frame_idx]; | |
7436 | TplDepStats *tpl_stats = tpl_frame->tpl_stats_ptr; | |
7437 | const int tpl_stride = tpl_frame->stride; | |
7438 | int64_t intra_cost_base = 0; | |
7439 | int64_t inter_cost_base = 0; | |
7440 | int64_t mc_dep_cost_base = 0; | |
7441 | int64_t mc_ref_cost_base = 0; | |
7442 | int64_t mc_flow_base = 0; | |
7443 | int row, col; | |
7444 | ||
7445 | if (!tpl_frame->is_valid) continue; | |
7446 | ||
7447 | for (row = 0; row < cm->mi_rows && tpl_frame->is_valid; ++row) { | |
7448 | for (col = 0; col < cm->mi_cols; ++col) { | |
7449 | TplDepStats *this_stats = &tpl_stats[row * tpl_stride + col]; | |
7450 | intra_cost_base += this_stats->intra_cost; | |
7451 | inter_cost_base += this_stats->inter_cost; | |
7452 | mc_dep_cost_base += this_stats->mc_dep_cost; | |
7453 | mc_ref_cost_base += this_stats->mc_ref_cost; | |
7454 | mc_flow_base += this_stats->mc_flow; | |
7455 | } | |
7456 | } | |
7457 | ||
7458 | cpi->tpl_stats_info[show_frame_count].intra_cost = intra_cost_base; | |
7459 | cpi->tpl_stats_info[show_frame_count].inter_cost = inter_cost_base; | |
7460 | cpi->tpl_stats_info[show_frame_count].mc_dep_cost = mc_dep_cost_base; | |
7461 | cpi->tpl_stats_info[show_frame_count].mc_ref_cost = mc_ref_cost_base; | |
7462 | cpi->tpl_stats_info[show_frame_count].mc_flow = mc_flow_base; | |
7463 | ||
7464 | ++show_frame_count; | |
7465 | } | |
7466 | } | |
7467 | #endif // CONFIG_RATE_CTRL | |
7468 | ||
7152 | 7469 | static void setup_tpl_stats(VP9_COMP *cpi) { |
7153 | 7470 | GF_PICTURE gf_picture[MAX_ARF_GOP_SIZE]; |
7154 | 7471 | const GF_GROUP *gf_group = &cpi->twopass.gf_group; |
7171 | 7488 | dump_tpl_stats(cpi, tpl_group_frames, gf_group, gf_picture, cpi->tpl_bsize); |
7172 | 7489 | #endif // DUMP_TPL_STATS |
7173 | 7490 | #endif // CONFIG_NON_GREEDY_MV |
7491 | ||
7492 | #if CONFIG_RATE_CTRL | |
7493 | accumulate_frame_tpl_stats(cpi); | |
7494 | #endif // CONFIG_RATE_CTRL | |
7495 | } | |
7496 | ||
7497 | void vp9_get_ref_frame_info(FRAME_UPDATE_TYPE update_type, int ref_frame_flags, | |
7498 | RefCntBuffer *ref_frame_bufs[MAX_INTER_REF_FRAMES], | |
7499 | int *ref_frame_coding_indexes, | |
7500 | int *ref_frame_valid_list) { | |
7501 | if (update_type != KF_UPDATE) { | |
7502 | const VP9_REFFRAME inter_ref_flags[MAX_INTER_REF_FRAMES] = { VP9_LAST_FLAG, | |
7503 | VP9_GOLD_FLAG, | |
7504 | VP9_ALT_FLAG }; | |
7505 | int i; | |
7506 | for (i = 0; i < MAX_INTER_REF_FRAMES; ++i) { | |
7507 | assert(ref_frame_bufs[i] != NULL); | |
7508 | ref_frame_coding_indexes[i] = ref_frame_bufs[i]->frame_coding_index; | |
7509 | ref_frame_valid_list[i] = (ref_frame_flags & inter_ref_flags[i]) != 0; | |
7510 | } | |
7511 | } else { | |
7512 | // No reference frame is available when this is a key frame. | |
7513 | int i; | |
7514 | for (i = 0; i < MAX_INTER_REF_FRAMES; ++i) { | |
7515 | ref_frame_coding_indexes[i] = -1; | |
7516 | ref_frame_valid_list[i] = 0; | |
7517 | } | |
7518 | } | |
7174 | 7519 | } |
7175 | 7520 | |
7176 | 7521 | #if !CONFIG_REALTIME_ONLY |
7320 | 7665 | } |
7321 | 7666 | } |
7322 | 7667 | #endif // CONFIG_RATE_CTRL |
7668 | ||
7323 | 7669 | static void update_encode_frame_result( |
7324 | 7670 | int ref_frame_flags, FRAME_UPDATE_TYPE update_type, |
7325 | 7671 | const YV12_BUFFER_CONFIG *source_frame, const RefCntBuffer *coded_frame_buf, |
7328 | 7674 | #if CONFIG_RATE_CTRL |
7329 | 7675 | const PARTITION_INFO *partition_info, |
7330 | 7676 | const MOTION_VECTOR_INFO *motion_vector_info, |
7677 | const TplDepStats *tpl_stats_info, | |
7331 | 7678 | #endif // CONFIG_RATE_CTRL |
7332 | 7679 | ENCODE_FRAME_RESULT *encode_frame_result) { |
7333 | 7680 | #if CONFIG_RATE_CTRL |
7334 | 7681 | PSNR_STATS psnr; |
7335 | 7682 | #if CONFIG_VP9_HIGHBITDEPTH |
7336 | vpx_calc_highbd_psnr(source_frame, coded_frame_buf->buf, &psnr, bit_depth, | |
7683 | vpx_calc_highbd_psnr(source_frame, &coded_frame_buf->buf, &psnr, bit_depth, | |
7337 | 7684 | input_bit_depth); |
7338 | 7685 | #else // CONFIG_VP9_HIGHBITDEPTH |
7339 | 7686 | (void)bit_depth; |
7342 | 7689 | #endif // CONFIG_VP9_HIGHBITDEPTH |
7343 | 7690 | encode_frame_result->frame_coding_index = coded_frame_buf->frame_coding_index; |
7344 | 7691 | |
7345 | if (update_type != KF_UPDATE) { | |
7346 | const VP9_REFFRAME inter_ref_flags[MAX_INTER_REF_FRAMES] = { VP9_LAST_FLAG, | |
7347 | VP9_GOLD_FLAG, | |
7348 | VP9_ALT_FLAG }; | |
7349 | int i; | |
7350 | for (i = 0; i < MAX_INTER_REF_FRAMES; ++i) { | |
7351 | assert(ref_frame_bufs[i] != NULL); | |
7352 | encode_frame_result->ref_frame_coding_indexes[i] = | |
7353 | ref_frame_bufs[i]->frame_coding_index; | |
7354 | encode_frame_result->ref_frame_valid_list[i] = | |
7355 | (ref_frame_flags & inter_ref_flags[i]) != 0; | |
7356 | } | |
7357 | } else { | |
7358 | // No reference frame is available when this is a key frame. | |
7359 | int i; | |
7360 | for (i = 0; i < MAX_INTER_REF_FRAMES; ++i) { | |
7361 | encode_frame_result->ref_frame_coding_indexes[i] = -1; | |
7362 | encode_frame_result->ref_frame_valid_list[i] = 0; | |
7363 | } | |
7364 | } | |
7692 | vp9_get_ref_frame_info(update_type, ref_frame_flags, ref_frame_bufs, | |
7693 | encode_frame_result->ref_frame_coding_indexes, | |
7694 | encode_frame_result->ref_frame_valid_list); | |
7695 | ||
7365 | 7696 | encode_frame_result->psnr = psnr.psnr[0]; |
7366 | 7697 | encode_frame_result->sse = psnr.sse[0]; |
7367 | 7698 | copy_frame_counts(counts, &encode_frame_result->frame_counts); |
7368 | 7699 | encode_frame_result->partition_info = partition_info; |
7369 | 7700 | encode_frame_result->motion_vector_info = motion_vector_info; |
7701 | encode_frame_result->tpl_stats_info = tpl_stats_info; | |
7370 | 7702 | if (encode_frame_result->coded_frame.allocated) { |
7371 | 7703 | yv12_buffer_to_image_buffer(&coded_frame_buf->buf, |
7372 | 7704 | &encode_frame_result->coded_frame); |
7392 | 7724 | encode_frame_result->frame_coding_index = -1; |
7393 | 7725 | vp9_zero(encode_frame_result->coded_frame); |
7394 | 7726 | encode_frame_result->coded_frame.allocated = 0; |
7727 | init_rq_history(&encode_frame_result->rq_history); | |
7395 | 7728 | #endif // CONFIG_RATE_CTRL |
7396 | 7729 | } |
7397 | 7730 | |
7578 | 7911 | cm->new_fb_idx = get_free_fb(cm); |
7579 | 7912 | |
7580 | 7913 | if (cm->new_fb_idx == INVALID_IDX) return -1; |
7581 | ||
7582 | 7914 | cm->cur_frame = &pool->frame_bufs[cm->new_fb_idx]; |
7583 | ||
7915 | // If the frame buffer for current frame is the same as previous frame, MV in | |
7916 | // the base layer shouldn't be used as it'll cause data race. | |
7917 | if (cpi->svc.spatial_layer_id > 0 && cm->cur_frame == cm->prev_frame) { | |
7918 | cpi->svc.use_base_mv = 0; | |
7919 | } | |
7584 | 7920 | // Start with a 0 size frame. |
7585 | 7921 | *size = 0; |
7586 | 7922 |
14 | 14 | |
15 | 15 | #include "./vpx_config.h" |
16 | 16 | #include "vpx/internal/vpx_codec_internal.h" |
17 | #include "vpx/vpx_ext_ratectrl.h" | |
17 | 18 | #include "vpx/vp8cx.h" |
18 | 19 | #if CONFIG_INTERNAL_STATS |
19 | 20 | #include "vpx_dsp/ssim.h" |
37 | 38 | #include "vp9/encoder/vp9_context_tree.h" |
38 | 39 | #include "vp9/encoder/vp9_encodemb.h" |
39 | 40 | #include "vp9/encoder/vp9_ethread.h" |
41 | #include "vp9/encoder/vp9_ext_ratectrl.h" | |
40 | 42 | #include "vp9/encoder/vp9_firstpass.h" |
41 | 43 | #include "vp9/encoder/vp9_job_queue.h" |
42 | 44 | #include "vp9/encoder/vp9_lookahead.h" |
145 | 147 | kLowVarHighSumdiff = 5, |
146 | 148 | kVeryHighSad = 6, |
147 | 149 | } CONTENT_STATE_SB; |
150 | ||
151 | typedef enum { | |
152 | LOOPFILTER_ALL = 0, | |
153 | LOOPFILTER_REFERENCE = 1, // Disable loopfilter on non reference frames. | |
154 | NO_LOOPFILTER = 2, // Disable loopfilter on all frames. | |
155 | } LOOPFILTER_CONTROL; | |
148 | 156 | |
149 | 157 | typedef struct VP9EncoderConfig { |
150 | 158 | BITSTREAM_PROFILE profile; |
559 | 567 | return gop_command->show_frame_count + gop_command->use_alt_ref; |
560 | 568 | } |
561 | 569 | |
570 | // TODO(angiebird): See if we can merge this one with FrameType in | |
571 | // simple_encode.h | |
572 | typedef enum ENCODE_FRAME_TYPE { | |
573 | ENCODE_FRAME_TYPE_KEY, | |
574 | ENCODE_FRAME_TYPE_INTER, | |
575 | ENCODE_FRAME_TYPE_ALTREF, | |
576 | ENCODE_FRAME_TYPE_OVERLAY, | |
577 | ENCODE_FRAME_TYPE_GOLDEN, | |
578 | ENCODE_FRAME_TYPES, | |
579 | } ENCODE_FRAME_TYPE; | |
580 | ||
581 | // TODO(angiebird): Merge this function with get_frame_type_from_update_type() | |
582 | static INLINE ENCODE_FRAME_TYPE | |
583 | get_encode_frame_type(FRAME_UPDATE_TYPE update_type) { | |
584 | switch (update_type) { | |
585 | case KF_UPDATE: return ENCODE_FRAME_TYPE_KEY; | |
586 | case ARF_UPDATE: return ENCODE_FRAME_TYPE_ALTREF; | |
587 | case GF_UPDATE: return ENCODE_FRAME_TYPE_GOLDEN; | |
588 | case OVERLAY_UPDATE: return ENCODE_FRAME_TYPE_OVERLAY; | |
589 | case LF_UPDATE: return ENCODE_FRAME_TYPE_INTER; | |
590 | default: | |
591 | fprintf(stderr, "Unsupported update_type %d\n", update_type); | |
592 | abort(); | |
593 | return ENCODE_FRAME_TYPE_INTER; | |
594 | } | |
595 | } | |
596 | ||
597 | typedef struct RATE_QSTEP_MODEL { | |
598 | // The rq model predicts the bit usage as follows. | |
599 | // rate = bias - ratio * log2(q_step) | |
600 | int ready; | |
601 | double bias; | |
602 | double ratio; | |
603 | } RATE_QSTEP_MODEL; | |
604 | ||
562 | 605 | typedef struct ENCODE_COMMAND { |
563 | 606 | int use_external_quantize_index; |
564 | 607 | int external_quantize_index; |
608 | ||
609 | int use_external_target_frame_bits; | |
610 | int target_frame_bits; | |
611 | double target_frame_bits_error_percent; | |
612 | ||
565 | 613 | GOP_COMMAND gop_command; |
566 | 614 | } ENCODE_COMMAND; |
567 | ||
568 | static INLINE void encode_command_init(ENCODE_COMMAND *encode_command) { | |
569 | vp9_zero(*encode_command); | |
570 | encode_command->use_external_quantize_index = 0; | |
571 | encode_command->external_quantize_index = -1; | |
572 | gop_command_off(&encode_command->gop_command); | |
573 | } | |
574 | 615 | |
575 | 616 | static INLINE void encode_command_set_gop_command( |
576 | 617 | ENCODE_COMMAND *encode_command, GOP_COMMAND gop_command) { |
589 | 630 | encode_command->external_quantize_index = -1; |
590 | 631 | } |
591 | 632 | |
633 | static INLINE void encode_command_set_target_frame_bits( | |
634 | ENCODE_COMMAND *encode_command, int target_frame_bits, | |
635 | double target_frame_bits_error_percent) { | |
636 | encode_command->use_external_target_frame_bits = 1; | |
637 | encode_command->target_frame_bits = target_frame_bits; | |
638 | encode_command->target_frame_bits_error_percent = | |
639 | target_frame_bits_error_percent; | |
640 | } | |
641 | ||
642 | static INLINE void encode_command_reset_target_frame_bits( | |
643 | ENCODE_COMMAND *encode_command) { | |
644 | encode_command->use_external_target_frame_bits = 0; | |
645 | encode_command->target_frame_bits = -1; | |
646 | encode_command->target_frame_bits_error_percent = 0; | |
647 | } | |
648 | ||
649 | static INLINE void encode_command_init(ENCODE_COMMAND *encode_command) { | |
650 | vp9_zero(*encode_command); | |
651 | encode_command_reset_external_quantize_index(encode_command); | |
652 | encode_command_reset_target_frame_bits(encode_command); | |
653 | gop_command_off(&encode_command->gop_command); | |
654 | } | |
655 | ||
592 | 656 | // Returns number of units in size of 4, if not multiple not a multiple of 4, |
593 | 657 | // round it up. For example, size is 7, return 2. |
594 | 658 | static INLINE int get_num_unit_4x4(int size) { return (size + 3) >> 2; } |
659 | // Returns number of units in size of 16, if not multiple not a multiple of 16, | |
660 | // round it up. For example, size is 17, return 2. | |
661 | static INLINE int get_num_unit_16x16(int size) { return (size + 15) >> 4; } | |
595 | 662 | #endif // CONFIG_RATE_CTRL |
596 | 663 | |
597 | 664 | typedef struct VP9_COMP { |
678 | 745 | // Ambient reconstruction err target for force key frames |
679 | 746 | int64_t ambient_err; |
680 | 747 | |
748 | RD_CONTROL rd_ctrl; | |
681 | 749 | RD_OPT rd; |
682 | 750 | |
683 | 751 | CODING_CONTEXT coding_context; |
898 | 966 | |
899 | 967 | int multi_layer_arf; |
900 | 968 | vpx_roi_map_t roi; |
969 | ||
970 | LOOPFILTER_CONTROL loopfilter_ctrl; | |
901 | 971 | #if CONFIG_RATE_CTRL |
902 | 972 | ENCODE_COMMAND encode_command; |
903 | 973 | PARTITION_INFO *partition_info; |
904 | 974 | MOTION_VECTOR_INFO *motion_vector_info; |
905 | #endif | |
975 | MOTION_VECTOR_INFO *fp_motion_vector_info; | |
976 | TplDepStats *tpl_stats_info; | |
977 | ||
978 | RATE_QSTEP_MODEL rq_model[ENCODE_FRAME_TYPES]; | |
979 | #endif | |
980 | EXT_RATECTRL ext_ratectrl; | |
906 | 981 | } VP9_COMP; |
907 | 982 | |
908 | 983 | #if CONFIG_RATE_CTRL |
927 | 1002 | cpi->partition_info = NULL; |
928 | 1003 | } |
929 | 1004 | |
1005 | static INLINE void reset_mv_info(MOTION_VECTOR_INFO *mv_info) { | |
1006 | mv_info->ref_frame[0] = NONE; | |
1007 | mv_info->ref_frame[1] = NONE; | |
1008 | mv_info->mv[0].as_int = INVALID_MV; | |
1009 | mv_info->mv[1].as_int = INVALID_MV; | |
1010 | } | |
1011 | ||
930 | 1012 | // Allocates memory for the motion vector information. |
931 | 1013 | // The unit size is each 4x4 block. |
932 | 1014 | // Only called once in vp9_create_compressor(). |
948 | 1030 | cpi->motion_vector_info = NULL; |
949 | 1031 | } |
950 | 1032 | |
1033 | // Allocates memory for the tpl stats information. | |
1034 | // Only called once in vp9_create_compressor(). | |
1035 | static INLINE void tpl_stats_info_init(struct VP9_COMP *cpi) { | |
1036 | VP9_COMMON *const cm = &cpi->common; | |
1037 | CHECK_MEM_ERROR( | |
1038 | cm, cpi->tpl_stats_info, | |
1039 | (TplDepStats *)vpx_calloc(MAX_LAG_BUFFERS, sizeof(TplDepStats))); | |
1040 | memset(cpi->tpl_stats_info, 0, MAX_LAG_BUFFERS * sizeof(TplDepStats)); | |
1041 | } | |
1042 | ||
1043 | // Frees memory of the tpl stats information. | |
1044 | // Only called once in dealloc_compressor_data(). | |
1045 | static INLINE void free_tpl_stats_info(struct VP9_COMP *cpi) { | |
1046 | vpx_free(cpi->tpl_stats_info); | |
1047 | cpi->tpl_stats_info = NULL; | |
1048 | } | |
1049 | ||
1050 | // Allocates memory for the first pass motion vector information. | |
1051 | // The unit size is each 16x16 block. | |
1052 | // Only called once in vp9_create_compressor(). | |
1053 | static INLINE void fp_motion_vector_info_init(struct VP9_COMP *cpi) { | |
1054 | VP9_COMMON *const cm = &cpi->common; | |
1055 | const int unit_width = get_num_unit_16x16(cpi->frame_info.frame_width); | |
1056 | const int unit_height = get_num_unit_16x16(cpi->frame_info.frame_height); | |
1057 | CHECK_MEM_ERROR(cm, cpi->fp_motion_vector_info, | |
1058 | (MOTION_VECTOR_INFO *)vpx_calloc(unit_width * unit_height, | |
1059 | sizeof(MOTION_VECTOR_INFO))); | |
1060 | } | |
1061 | ||
1062 | static INLINE void fp_motion_vector_info_reset( | |
1063 | int frame_width, int frame_height, | |
1064 | MOTION_VECTOR_INFO *fp_motion_vector_info) { | |
1065 | const int unit_width = get_num_unit_16x16(frame_width); | |
1066 | const int unit_height = get_num_unit_16x16(frame_height); | |
1067 | int i; | |
1068 | for (i = 0; i < unit_width * unit_height; ++i) { | |
1069 | reset_mv_info(fp_motion_vector_info + i); | |
1070 | } | |
1071 | } | |
1072 | ||
1073 | // Frees memory of the first pass motion vector information. | |
1074 | // Only called once in dealloc_compressor_data(). | |
1075 | static INLINE void free_fp_motion_vector_info(struct VP9_COMP *cpi) { | |
1076 | vpx_free(cpi->fp_motion_vector_info); | |
1077 | cpi->fp_motion_vector_info = NULL; | |
1078 | } | |
1079 | ||
951 | 1080 | // This is the c-version counter part of ImageBuffer |
952 | 1081 | typedef struct IMAGE_BUFFER { |
953 | 1082 | int allocated; |
955 | 1084 | int plane_height[3]; |
956 | 1085 | uint8_t *plane_buffer[3]; |
957 | 1086 | } IMAGE_BUFFER; |
1087 | ||
1088 | #define RATE_CTRL_MAX_RECODE_NUM 7 | |
1089 | ||
1090 | typedef struct RATE_QINDEX_HISTORY { | |
1091 | int recode_count; | |
1092 | int q_index_history[RATE_CTRL_MAX_RECODE_NUM]; | |
1093 | int rate_history[RATE_CTRL_MAX_RECODE_NUM]; | |
1094 | int q_index_high; | |
1095 | int q_index_low; | |
1096 | } RATE_QINDEX_HISTORY; | |
1097 | ||
958 | 1098 | #endif // CONFIG_RATE_CTRL |
959 | 1099 | |
960 | 1100 | typedef struct ENCODE_FRAME_RESULT { |
969 | 1109 | FRAME_COUNTS frame_counts; |
970 | 1110 | const PARTITION_INFO *partition_info; |
971 | 1111 | const MOTION_VECTOR_INFO *motion_vector_info; |
1112 | const TplDepStats *tpl_stats_info; | |
972 | 1113 | IMAGE_BUFFER coded_frame; |
1114 | RATE_QINDEX_HISTORY rq_history; | |
973 | 1115 | #endif // CONFIG_RATE_CTRL |
974 | 1116 | int quantize_index; |
975 | 1117 | } ENCODE_FRAME_RESULT; |
1144 | 1286 | void vp9_scale_references(VP9_COMP *cpi); |
1145 | 1287 | |
1146 | 1288 | void vp9_update_reference_frames(VP9_COMP *cpi); |
1289 | ||
1290 | void vp9_get_ref_frame_info(FRAME_UPDATE_TYPE update_type, int ref_frame_flags, | |
1291 | RefCntBuffer *ref_frame_bufs[MAX_INTER_REF_FRAMES], | |
1292 | int *ref_frame_coding_indexes, | |
1293 | int *ref_frame_valid_list); | |
1147 | 1294 | |
1148 | 1295 | void vp9_set_high_precision_mv(VP9_COMP *cpi, int allow_high_precision_mv); |
1149 | 1296 |
0 | /* | |
1 | * Copyright (c) 2020 The WebM project authors. All Rights Reserved. | |
2 | * | |
3 | * Use of this source code is governed by a BSD-style license | |
4 | * that can be found in the LICENSE file in the root of the source | |
5 | * tree. An additional intellectual property rights grant can be found | |
6 | * in the file PATENTS. All contributing project authors may | |
7 | * be found in the AUTHORS file in the root of the source tree. | |
8 | */ | |
9 | ||
10 | #include "vp9/encoder/vp9_ext_ratectrl.h" | |
11 | #include "vp9/encoder/vp9_encoder.h" | |
12 | #include "vp9/common/vp9_common.h" | |
13 | #include "vpx_dsp/psnr.h" | |
14 | ||
15 | vpx_codec_err_t vp9_extrc_init(EXT_RATECTRL *ext_ratectrl) { | |
16 | if (ext_ratectrl == NULL) { | |
17 | return VPX_CODEC_INVALID_PARAM; | |
18 | } | |
19 | vp9_zero(*ext_ratectrl); | |
20 | return VPX_CODEC_OK; | |
21 | } | |
22 | ||
23 | vpx_codec_err_t vp9_extrc_create(vpx_rc_funcs_t funcs, | |
24 | vpx_rc_config_t ratectrl_config, | |
25 | EXT_RATECTRL *ext_ratectrl) { | |
26 | vpx_rc_status_t rc_status; | |
27 | vpx_rc_firstpass_stats_t *rc_firstpass_stats; | |
28 | if (ext_ratectrl == NULL) { | |
29 | return VPX_CODEC_INVALID_PARAM; | |
30 | } | |
31 | vp9_extrc_delete(ext_ratectrl); | |
32 | ext_ratectrl->funcs = funcs; | |
33 | ext_ratectrl->ratectrl_config = ratectrl_config; | |
34 | rc_status = ext_ratectrl->funcs.create_model(ext_ratectrl->funcs.priv, | |
35 | &ext_ratectrl->ratectrl_config, | |
36 | &ext_ratectrl->model); | |
37 | if (rc_status == VPX_RC_ERROR) { | |
38 | return VPX_CODEC_ERROR; | |
39 | } | |
40 | rc_firstpass_stats = &ext_ratectrl->rc_firstpass_stats; | |
41 | rc_firstpass_stats->num_frames = ratectrl_config.show_frame_count; | |
42 | rc_firstpass_stats->frame_stats = | |
43 | vpx_malloc(sizeof(*rc_firstpass_stats->frame_stats) * | |
44 | rc_firstpass_stats->num_frames); | |
45 | if (rc_firstpass_stats->frame_stats == NULL) { | |
46 | return VPX_CODEC_MEM_ERROR; | |
47 | } | |
48 | ext_ratectrl->ready = 1; | |
49 | return VPX_CODEC_OK; | |
50 | } | |
51 | ||
52 | vpx_codec_err_t vp9_extrc_delete(EXT_RATECTRL *ext_ratectrl) { | |
53 | if (ext_ratectrl == NULL) { | |
54 | return VPX_CODEC_INVALID_PARAM; | |
55 | } | |
56 | if (ext_ratectrl->ready) { | |
57 | vpx_rc_status_t rc_status = | |
58 | ext_ratectrl->funcs.delete_model(ext_ratectrl->model); | |
59 | if (rc_status == VPX_RC_ERROR) { | |
60 | return VPX_CODEC_ERROR; | |
61 | } | |
62 | vpx_free(ext_ratectrl->rc_firstpass_stats.frame_stats); | |
63 | } | |
64 | return vp9_extrc_init(ext_ratectrl); | |
65 | } | |
66 | ||
67 | static void gen_rc_firstpass_stats(const FIRSTPASS_STATS *stats, | |
68 | vpx_rc_frame_stats_t *rc_frame_stats) { | |
69 | rc_frame_stats->frame = stats->frame; | |
70 | rc_frame_stats->weight = stats->weight; | |
71 | rc_frame_stats->intra_error = stats->intra_error; | |
72 | rc_frame_stats->coded_error = stats->coded_error; | |
73 | rc_frame_stats->sr_coded_error = stats->sr_coded_error; | |
74 | rc_frame_stats->frame_noise_energy = stats->frame_noise_energy; | |
75 | rc_frame_stats->pcnt_inter = stats->pcnt_inter; | |
76 | rc_frame_stats->pcnt_motion = stats->pcnt_motion; | |
77 | rc_frame_stats->pcnt_second_ref = stats->pcnt_second_ref; | |
78 | rc_frame_stats->pcnt_neutral = stats->pcnt_neutral; | |
79 | rc_frame_stats->pcnt_intra_low = stats->pcnt_intra_low; | |
80 | rc_frame_stats->pcnt_intra_high = stats->pcnt_intra_high; | |
81 | rc_frame_stats->intra_skip_pct = stats->intra_skip_pct; | |
82 | rc_frame_stats->intra_smooth_pct = stats->intra_smooth_pct; | |
83 | rc_frame_stats->inactive_zone_rows = stats->inactive_zone_rows; | |
84 | rc_frame_stats->inactive_zone_cols = stats->inactive_zone_cols; | |
85 | rc_frame_stats->MVr = stats->MVr; | |
86 | rc_frame_stats->mvr_abs = stats->mvr_abs; | |
87 | rc_frame_stats->MVc = stats->MVc; | |
88 | rc_frame_stats->mvc_abs = stats->mvc_abs; | |
89 | rc_frame_stats->MVrv = stats->MVrv; | |
90 | rc_frame_stats->MVcv = stats->MVcv; | |
91 | rc_frame_stats->mv_in_out_count = stats->mv_in_out_count; | |
92 | rc_frame_stats->duration = stats->duration; | |
93 | rc_frame_stats->count = stats->count; | |
94 | } | |
95 | ||
96 | vpx_codec_err_t vp9_extrc_send_firstpass_stats( | |
97 | EXT_RATECTRL *ext_ratectrl, const FIRST_PASS_INFO *first_pass_info) { | |
98 | if (ext_ratectrl == NULL) { | |
99 | return VPX_CODEC_INVALID_PARAM; | |
100 | } | |
101 | if (ext_ratectrl->ready) { | |
102 | vpx_rc_status_t rc_status; | |
103 | vpx_rc_firstpass_stats_t *rc_firstpass_stats = | |
104 | &ext_ratectrl->rc_firstpass_stats; | |
105 | int i; | |
106 | assert(rc_firstpass_stats->num_frames == first_pass_info->num_frames); | |
107 | for (i = 0; i < rc_firstpass_stats->num_frames; ++i) { | |
108 | gen_rc_firstpass_stats(&first_pass_info->stats[i], | |
109 | &rc_firstpass_stats->frame_stats[i]); | |
110 | } | |
111 | rc_status = ext_ratectrl->funcs.send_firstpass_stats(ext_ratectrl->model, | |
112 | rc_firstpass_stats); | |
113 | if (rc_status == VPX_RC_ERROR) { | |
114 | return VPX_CODEC_ERROR; | |
115 | } | |
116 | } | |
117 | return VPX_CODEC_OK; | |
118 | } | |
119 | ||
120 | static int extrc_get_frame_type(FRAME_UPDATE_TYPE update_type) { | |
121 | // TODO(angiebird): Add unit test to make sure this function behaves like | |
122 | // get_frame_type_from_update_type() | |
123 | // TODO(angiebird): Merge this function with get_frame_type_from_update_type() | |
124 | switch (update_type) { | |
125 | case KF_UPDATE: return 0; // kFrameTypeKey; | |
126 | case ARF_UPDATE: return 2; // kFrameTypeAltRef; | |
127 | case GF_UPDATE: return 4; // kFrameTypeGolden; | |
128 | case OVERLAY_UPDATE: return 3; // kFrameTypeOverlay; | |
129 | case LF_UPDATE: return 1; // kFrameTypeInter; | |
130 | default: | |
131 | fprintf(stderr, "Unsupported update_type %d\n", update_type); | |
132 | abort(); | |
133 | return 1; | |
134 | } | |
135 | } | |
136 | ||
137 | vpx_codec_err_t vp9_extrc_get_encodeframe_decision( | |
138 | EXT_RATECTRL *ext_ratectrl, int show_index, int coding_index, int gop_index, | |
139 | FRAME_UPDATE_TYPE update_type, | |
140 | RefCntBuffer *ref_frame_bufs[MAX_INTER_REF_FRAMES], int ref_frame_flags, | |
141 | vpx_rc_encodeframe_decision_t *encode_frame_decision) { | |
142 | if (ext_ratectrl == NULL) { | |
143 | return VPX_CODEC_INVALID_PARAM; | |
144 | } | |
145 | if (ext_ratectrl->ready) { | |
146 | vpx_rc_status_t rc_status; | |
147 | vpx_rc_encodeframe_info_t encode_frame_info; | |
148 | encode_frame_info.show_index = show_index; | |
149 | encode_frame_info.coding_index = coding_index; | |
150 | encode_frame_info.gop_index = gop_index; | |
151 | encode_frame_info.frame_type = extrc_get_frame_type(update_type); | |
152 | ||
153 | vp9_get_ref_frame_info(update_type, ref_frame_flags, ref_frame_bufs, | |
154 | encode_frame_info.ref_frame_coding_indexes, | |
155 | encode_frame_info.ref_frame_valid_list); | |
156 | ||
157 | rc_status = ext_ratectrl->funcs.get_encodeframe_decision( | |
158 | ext_ratectrl->model, &encode_frame_info, encode_frame_decision); | |
159 | if (rc_status == VPX_RC_ERROR) { | |
160 | return VPX_CODEC_ERROR; | |
161 | } | |
162 | } | |
163 | return VPX_CODEC_OK; | |
164 | } | |
165 | ||
166 | vpx_codec_err_t vp9_extrc_update_encodeframe_result( | |
167 | EXT_RATECTRL *ext_ratectrl, int64_t bit_count, | |
168 | const YV12_BUFFER_CONFIG *source_frame, | |
169 | const YV12_BUFFER_CONFIG *coded_frame, uint32_t bit_depth, | |
170 | uint32_t input_bit_depth, const int actual_encoding_qindex) { | |
171 | if (ext_ratectrl == NULL) { | |
172 | return VPX_CODEC_INVALID_PARAM; | |
173 | } | |
174 | if (ext_ratectrl->ready) { | |
175 | PSNR_STATS psnr; | |
176 | vpx_rc_status_t rc_status; | |
177 | vpx_rc_encodeframe_result_t encode_frame_result; | |
178 | encode_frame_result.bit_count = bit_count; | |
179 | encode_frame_result.pixel_count = | |
180 | source_frame->y_crop_width * source_frame->y_crop_height + | |
181 | 2 * source_frame->uv_crop_width * source_frame->uv_crop_height; | |
182 | encode_frame_result.actual_encoding_qindex = actual_encoding_qindex; | |
183 | #if CONFIG_VP9_HIGHBITDEPTH | |
184 | vpx_calc_highbd_psnr(source_frame, coded_frame, &psnr, bit_depth, | |
185 | input_bit_depth); | |
186 | #else | |
187 | (void)bit_depth; | |
188 | (void)input_bit_depth; | |
189 | vpx_calc_psnr(source_frame, coded_frame, &psnr); | |
190 | #endif | |
191 | encode_frame_result.sse = psnr.sse[0]; | |
192 | rc_status = ext_ratectrl->funcs.update_encodeframe_result( | |
193 | ext_ratectrl->model, &encode_frame_result); | |
194 | if (rc_status == VPX_RC_ERROR) { | |
195 | return VPX_CODEC_ERROR; | |
196 | } | |
197 | } | |
198 | return VPX_CODEC_OK; | |
199 | } |
0 | /* | |
1 | * Copyright (c) 2020 The WebM project authors. All Rights Reserved. | |
2 | * | |
3 | * Use of this source code is governed by a BSD-style license | |
4 | * that can be found in the LICENSE file in the root of the source | |
5 | * tree. An additional intellectual property rights grant can be found | |
6 | * in the file PATENTS. All contributing project authors may | |
7 | * be found in the AUTHORS file in the root of the source tree. | |
8 | */ | |
9 | ||
10 | #ifndef VPX_VP9_ENCODER_VP9_EXT_RATECTRL_H_ | |
11 | #define VPX_VP9_ENCODER_VP9_EXT_RATECTRL_H_ | |
12 | ||
13 | #include "vpx/vpx_ext_ratectrl.h" | |
14 | #include "vp9/encoder/vp9_firstpass.h" | |
15 | ||
16 | typedef struct EXT_RATECTRL { | |
17 | int ready; | |
18 | vpx_rc_model_t model; | |
19 | vpx_rc_funcs_t funcs; | |
20 | vpx_rc_config_t ratectrl_config; | |
21 | vpx_rc_firstpass_stats_t rc_firstpass_stats; | |
22 | } EXT_RATECTRL; | |
23 | ||
24 | vpx_codec_err_t vp9_extrc_init(EXT_RATECTRL *ext_ratectrl); | |
25 | ||
26 | vpx_codec_err_t vp9_extrc_create(vpx_rc_funcs_t funcs, | |
27 | vpx_rc_config_t ratectrl_config, | |
28 | EXT_RATECTRL *ext_ratectrl); | |
29 | ||
30 | vpx_codec_err_t vp9_extrc_delete(EXT_RATECTRL *ext_ratectrl); | |
31 | ||
32 | vpx_codec_err_t vp9_extrc_send_firstpass_stats( | |
33 | EXT_RATECTRL *ext_ratectrl, const FIRST_PASS_INFO *first_pass_info); | |
34 | ||
35 | vpx_codec_err_t vp9_extrc_get_encodeframe_decision( | |
36 | EXT_RATECTRL *ext_ratectrl, int show_index, int coding_index, int gop_index, | |
37 | FRAME_UPDATE_TYPE update_type, | |
38 | RefCntBuffer *ref_frame_bufs[MAX_INTER_REF_FRAMES], int ref_frame_flags, | |
39 | vpx_rc_encodeframe_decision_t *encode_frame_decision); | |
40 | ||
41 | vpx_codec_err_t vp9_extrc_update_encodeframe_result( | |
42 | EXT_RATECTRL *ext_ratectrl, int64_t bit_count, | |
43 | const YV12_BUFFER_CONFIG *source_frame, | |
44 | const YV12_BUFFER_CONFIG *coded_frame, uint32_t bit_depth, | |
45 | uint32_t input_bit_depth, const int actual_encoding_qindex); | |
46 | ||
47 | #endif // VPX_VP9_ENCODER_VP9_EXT_RATECTRL_H_ |
52 | 52 | |
53 | 53 | #define NCOUNT_INTRA_THRESH 8192 |
54 | 54 | #define NCOUNT_INTRA_FACTOR 3 |
55 | ||
56 | #define SR_DIFF_PART 0.0015 | |
57 | #define INTRA_PART 0.005 | |
58 | #define DEFAULT_DECAY_LIMIT 0.75 | |
59 | #define LOW_SR_DIFF_TRHESH 0.1 | |
60 | #define SR_DIFF_MAX 128.0 | |
61 | #define LOW_CODED_ERR_PER_MB 10.0 | |
62 | #define NCOUNT_FRAME_II_THRESH 6.0 | |
63 | #define BASELINE_ERR_PER_MB 12500.0 | |
64 | #define GF_MAX_FRAME_BOOST 96.0 | |
65 | ||
66 | #ifdef AGGRESSIVE_VBR | |
67 | #define KF_MAX_FRAME_BOOST 80.0 | |
68 | #define MAX_KF_TOT_BOOST 4800 | |
69 | #else | |
70 | #define KF_MAX_FRAME_BOOST 96.0 | |
71 | #define MAX_KF_TOT_BOOST 5400 | |
72 | #endif | |
73 | ||
74 | #define ZM_POWER_FACTOR 0.75 | |
75 | #define MINQ_ADJ_LIMIT 48 | |
76 | #define MINQ_ADJ_LIMIT_CQ 20 | |
77 | #define HIGH_UNDERSHOOT_RATIO 2 | |
78 | #define AV_WQ_FACTOR 4.0 | |
79 | #define DEF_EPMB_LOW 2000.0 | |
55 | 80 | |
56 | 81 | #define DOUBLE_DIVIDE_CHECK(x) ((x) < 0 ? (x)-0.000001 : (x) + 0.000001) |
57 | 82 | |
838 | 863 | fp_acc_data->image_data_start_row); |
839 | 864 | } |
840 | 865 | |
866 | #if CONFIG_RATE_CTRL | |
867 | static void store_fp_motion_vector(VP9_COMP *cpi, const MV *mv, | |
868 | const int mb_row, const int mb_col, | |
869 | MV_REFERENCE_FRAME frame_type, | |
870 | const int mv_idx) { | |
871 | VP9_COMMON *const cm = &cpi->common; | |
872 | const int mb_index = mb_row * cm->mb_cols + mb_col; | |
873 | MOTION_VECTOR_INFO *this_motion_vector_info = | |
874 | &cpi->fp_motion_vector_info[mb_index]; | |
875 | this_motion_vector_info->ref_frame[mv_idx] = frame_type; | |
876 | if (frame_type != INTRA_FRAME) { | |
877 | this_motion_vector_info->mv[mv_idx].as_mv = *mv; | |
878 | } | |
879 | } | |
880 | #endif // CONFIG_RATE_CTRL | |
881 | ||
841 | 882 | #define NZ_MOTION_PENALTY 128 |
842 | 883 | #define INTRA_MODE_PENALTY 1024 |
843 | 884 | void vp9_first_pass_encode_tile_mb_row(VP9_COMP *cpi, ThreadData *td, |
1064 | 1105 | x->mv_limits.col_max = |
1065 | 1106 | ((cm->mb_cols - 1 - mb_col) * 16) + BORDER_MV_PIXELS_B16; |
1066 | 1107 | |
1067 | // Other than for the first frame do a motion search. | |
1068 | if (cm->current_video_frame > 0) { | |
1108 | // Other than for intra-only frame do a motion search. | |
1109 | if (!frame_is_intra_only(cm)) { | |
1069 | 1110 | int tmp_err, motion_error, this_motion_error, raw_motion_error; |
1070 | 1111 | // Assume 0,0 motion with no mv overhead. |
1071 | 1112 | MV mv = { 0, 0 }, tmp_mv = { 0, 0 }; |
1072 | 1113 | struct buf_2d unscaled_last_source_buf_2d; |
1073 | 1114 | vp9_variance_fn_ptr_t v_fn_ptr = cpi->fn_ptr[bsize]; |
1115 | ||
1116 | #if CONFIG_RATE_CTRL | |
1117 | // Store zero mv as default | |
1118 | store_fp_motion_vector(cpi, &mv, mb_row, mb_col, LAST_FRAME, 0); | |
1119 | #endif // CONFIG_RAGE_CTRL | |
1074 | 1120 | |
1075 | 1121 | xd->plane[0].pre[0].buf = first_ref_buf->y_buffer + recon_yoffset; |
1076 | 1122 | #if CONFIG_VP9_HIGHBITDEPTH |
1136 | 1182 | vp9_get_mvpred_var(x, &tmp_mv, &zero_mv, &v_fn_ptr, 0); |
1137 | 1183 | } |
1138 | 1184 | } |
1185 | #if CONFIG_RATE_CTRL | |
1186 | store_fp_motion_vector(cpi, &mv, mb_row, mb_col, LAST_FRAME, 0); | |
1187 | #endif // CONFIG_RAGE_CTRL | |
1139 | 1188 | |
1140 | 1189 | // Search in an older reference frame. |
1141 | 1190 | if ((cm->current_video_frame > 1) && gld_yv12 != NULL) { |
1157 | 1206 | #endif // CONFIG_VP9_HIGHBITDEPTH |
1158 | 1207 | |
1159 | 1208 | first_pass_motion_search(cpi, x, &zero_mv, &tmp_mv, &gf_motion_error); |
1209 | #if CONFIG_RATE_CTRL | |
1210 | store_fp_motion_vector(cpi, &tmp_mv, mb_row, mb_col, GOLDEN_FRAME, 1); | |
1211 | #endif // CONFIG_RAGE_CTRL | |
1160 | 1212 | |
1161 | 1213 | if (gf_motion_error < motion_error && gf_motion_error < this_error) |
1162 | 1214 | ++(fp_acc_data->second_ref_count); |
1330 | 1382 | } |
1331 | 1383 | } else { |
1332 | 1384 | fp_acc_data->sr_coded_error += (int64_t)this_error; |
1385 | #if CONFIG_RATE_CTRL | |
1386 | store_fp_motion_vector(cpi, NULL, mb_row, mb_col, INTRA_FRAME, 0); | |
1387 | #endif // CONFIG_RAGE_CTRL | |
1333 | 1388 | } |
1334 | 1389 | fp_acc_data->coded_error += (int64_t)this_error; |
1335 | 1390 | |
1355 | 1410 | MV best_ref_mv; |
1356 | 1411 | // Tiling is ignored in the first pass. |
1357 | 1412 | vp9_tile_init(tile, cm, 0, 0); |
1413 | ||
1414 | #if CONFIG_RATE_CTRL | |
1415 | fp_motion_vector_info_reset(cpi->frame_info.frame_width, | |
1416 | cpi->frame_info.frame_height, | |
1417 | cpi->fp_motion_vector_info); | |
1418 | #endif | |
1358 | 1419 | |
1359 | 1420 | for (mb_row = 0; mb_row < cm->mb_rows; ++mb_row) { |
1360 | 1421 | best_ref_mv = zero_mv; |
1770 | 1831 | twopass->arnr_strength_adjustment = 0; |
1771 | 1832 | } |
1772 | 1833 | |
1773 | #define SR_DIFF_PART 0.0015 | |
1774 | #define INTRA_PART 0.005 | |
1775 | #define DEFAULT_DECAY_LIMIT 0.75 | |
1776 | #define LOW_SR_DIFF_TRHESH 0.1 | |
1777 | #define SR_DIFF_MAX 128.0 | |
1778 | #define LOW_CODED_ERR_PER_MB 10.0 | |
1779 | #define NCOUNT_FRAME_II_THRESH 6.0 | |
1780 | ||
1781 | 1834 | static double get_sr_decay_rate(const FRAME_INFO *frame_info, |
1782 | 1835 | const FIRSTPASS_STATS *frame) { |
1783 | 1836 | double sr_diff = (frame->sr_coded_error - frame->coded_error); |
1815 | 1868 | double sr_decay = get_sr_decay_rate(frame_info, frame_stats); |
1816 | 1869 | return VPXMIN(sr_decay, zero_motion_pct); |
1817 | 1870 | } |
1818 | ||
1819 | #define ZM_POWER_FACTOR 0.75 | |
1820 | 1871 | |
1821 | 1872 | static double get_prediction_decay_rate(const FRAME_INFO *frame_info, |
1822 | 1873 | const FIRSTPASS_STATS *frame_stats) { |
1905 | 1956 | } |
1906 | 1957 | } |
1907 | 1958 | |
1908 | #define BASELINE_ERR_PER_MB 12500.0 | |
1909 | #define GF_MAX_BOOST 96.0 | |
1910 | 1959 | static double calc_frame_boost(const FRAME_INFO *frame_info, |
1911 | 1960 | const FIRSTPASS_STATS *this_frame, |
1912 | 1961 | int avg_frame_qindex, |
1928 | 1977 | // Q correction and scalling |
1929 | 1978 | frame_boost = frame_boost * boost_q_correction; |
1930 | 1979 | |
1931 | return VPXMIN(frame_boost, GF_MAX_BOOST * boost_q_correction); | |
1980 | return VPXMIN(frame_boost, GF_MAX_FRAME_BOOST * boost_q_correction); | |
1932 | 1981 | } |
1933 | 1982 | |
1934 | 1983 | static double kf_err_per_mb(VP9_COMP *cpi) { |
3122 | 3171 | #define MIN_SCAN_FRAMES_FOR_KF_BOOST 32 |
3123 | 3172 | #define KF_ABS_ZOOM_THRESH 6.0 |
3124 | 3173 | |
3125 | #ifdef AGGRESSIVE_VBR | |
3126 | #define KF_MAX_FRAME_BOOST 80.0 | |
3127 | #define MAX_KF_TOT_BOOST 4800 | |
3128 | #else | |
3129 | #define KF_MAX_FRAME_BOOST 96.0 | |
3130 | #define MAX_KF_TOT_BOOST 5400 | |
3131 | #endif | |
3132 | ||
3133 | 3174 | int vp9_get_frames_to_next_key(const VP9EncoderConfig *oxcf, |
3134 | 3175 | const FRAME_INFO *frame_info, |
3135 | 3176 | const FIRST_PASS_INFO *first_pass_info, |
3433 | 3474 | twopass->stats_in->pcnt_inter - twopass->stats_in->pcnt_motion == 1); |
3434 | 3475 | } |
3435 | 3476 | |
3477 | // Configure image size specific vizier parameters. | |
3478 | // Later these will be set via additional command line options | |
3479 | static void init_vizier_params(RATE_CONTROL *const rc, int screen_area) { | |
3480 | if (1) { | |
3481 | // Force defaults for now | |
3482 | rc->active_wq_factor = AV_WQ_FACTOR; | |
3483 | rc->base_err_per_mb = BASELINE_ERR_PER_MB; | |
3484 | rc->sr_default_decay_limit = DEFAULT_DECAY_LIMIT; | |
3485 | rc->sr_diff_part = SR_DIFF_PART; | |
3486 | rc->gf_frame_max_boost = GF_MAX_FRAME_BOOST; | |
3487 | rc->gf_max_total_boost = MAX_GF_BOOST; | |
3488 | rc->kf_err_per_mb = DEF_EPMB_LOW; | |
3489 | rc->kf_frame_max_boost_first = KF_MAX_FRAME_BOOST; // Max for first kf. | |
3490 | rc->kf_frame_max_boost_subs = KF_MAX_FRAME_BOOST / 2; // Max for other kfs. | |
3491 | rc->kf_max_total_boost = MAX_KF_TOT_BOOST; | |
3492 | rc->zm_power_factor = ZM_POWER_FACTOR; | |
3493 | } else { | |
3494 | // Vizer experimental parameters from training. | |
3495 | // Later these will be set via the command line. | |
3496 | if (screen_area <= 176 * 144) { | |
3497 | rc->active_wq_factor = 46.0; | |
3498 | rc->base_err_per_mb = 37597.399760969536; | |
3499 | rc->sr_default_decay_limit = 0.3905639800962774; | |
3500 | rc->sr_diff_part = 0.009599023654146284; | |
3501 | rc->gf_frame_max_boost = 87.27362648627846; | |
3502 | rc->gf_max_total_boost = MAX_GF_BOOST; | |
3503 | rc->kf_err_per_mb = 1854.8255436877148; | |
3504 | rc->kf_frame_max_boost_first = KF_MAX_FRAME_BOOST; | |
3505 | rc->kf_frame_max_boost_subs = rc->kf_frame_max_boost_first / 2; | |
3506 | rc->kf_max_total_boost = MAX_KF_TOT_BOOST; | |
3507 | rc->zm_power_factor = 2.93715229184991; | |
3508 | } else if (screen_area <= 320 * 240) { | |
3509 | rc->active_wq_factor = 55.0; | |
3510 | rc->base_err_per_mb = 34525.33177195309; | |
3511 | rc->sr_default_decay_limit = 0.23901360046804604; | |
3512 | rc->sr_diff_part = 0.008581014394766773; | |
3513 | rc->gf_frame_max_boost = 127.34978204980285; | |
3514 | rc->gf_max_total_boost = MAX_GF_BOOST; | |
3515 | rc->kf_err_per_mb = 723.8337508755031; | |
3516 | rc->kf_frame_max_boost_first = KF_MAX_FRAME_BOOST; | |
3517 | rc->kf_frame_max_boost_subs = rc->kf_frame_max_boost_first / 2; | |
3518 | rc->kf_max_total_boost = MAX_KF_TOT_BOOST; | |
3519 | rc->zm_power_factor = 3.5299221493593413; | |
3520 | } else if (screen_area <= 640 * 360) { | |
3521 | rc->active_wq_factor = 12.5; | |
3522 | rc->base_err_per_mb = 18823.978018028298; | |
3523 | rc->sr_default_decay_limit = 0.6043527690301296; | |
3524 | rc->sr_diff_part = 0.00343296783885544; | |
3525 | rc->gf_frame_max_boost = 75.17672317013668; | |
3526 | rc->gf_max_total_boost = MAX_GF_BOOST; | |
3527 | rc->kf_err_per_mb = 422.2871502380377; | |
3528 | rc->kf_frame_max_boost_first = KF_MAX_FRAME_BOOST; | |
3529 | rc->kf_frame_max_boost_subs = rc->kf_frame_max_boost_first / 2; | |
3530 | rc->kf_max_total_boost = MAX_KF_TOT_BOOST; | |
3531 | rc->zm_power_factor = 2.265742666649307; | |
3532 | } else if (screen_area <= 854 * 480) { | |
3533 | rc->active_wq_factor = 51.5; | |
3534 | rc->base_err_per_mb = 33718.98307662595; | |
3535 | rc->sr_default_decay_limit = 0.33633414970713393; | |
3536 | rc->sr_diff_part = 0.00868988716928333; | |
3537 | rc->gf_frame_max_boost = 85.2868528581522; | |
3538 | rc->gf_max_total_boost = MAX_GF_BOOST; | |
3539 | rc->kf_err_per_mb = 1513.4883914008383; | |
3540 | rc->kf_frame_max_boost_first = KF_MAX_FRAME_BOOST; | |
3541 | rc->kf_frame_max_boost_subs = rc->kf_frame_max_boost_first / 2; | |
3542 | rc->kf_max_total_boost = MAX_KF_TOT_BOOST; | |
3543 | rc->zm_power_factor = 3.552278528517416; | |
3544 | } else if (screen_area <= 1280 * 720) { | |
3545 | rc->active_wq_factor = 41.5; | |
3546 | rc->base_err_per_mb = 29527.46375825401; | |
3547 | rc->sr_default_decay_limit = 0.5009117586299728; | |
3548 | rc->sr_diff_part = 0.005007364627260114; | |
3549 | rc->gf_frame_max_boost = GF_MAX_FRAME_BOOST; | |
3550 | rc->gf_max_total_boost = MAX_GF_BOOST; | |
3551 | rc->kf_err_per_mb = 998.6342911785146; | |
3552 | rc->kf_frame_max_boost_first = KF_MAX_FRAME_BOOST; | |
3553 | rc->kf_frame_max_boost_subs = rc->kf_frame_max_boost_first / 2; | |
3554 | rc->kf_max_total_boost = MAX_KF_TOT_BOOST; | |
3555 | rc->zm_power_factor = 2.568627575572356; | |
3556 | } else if (screen_area <= 1920 * 1080) { | |
3557 | rc->active_wq_factor = 31.0; | |
3558 | rc->base_err_per_mb = 34474.723463367416; | |
3559 | rc->sr_default_decay_limit = 0.23346886902707745; | |
3560 | rc->sr_diff_part = 0.011431716637966029; | |
3561 | rc->gf_frame_max_boost = 81.00472969483079; | |
3562 | rc->gf_max_total_boost = MAX_GF_BOOST; | |
3563 | rc->kf_err_per_mb = 35931.25734431429; | |
3564 | rc->kf_frame_max_boost_first = KF_MAX_FRAME_BOOST; | |
3565 | rc->kf_frame_max_boost_subs = rc->kf_frame_max_boost_first / 2; | |
3566 | rc->kf_max_total_boost = MAX_KF_TOT_BOOST; | |
3567 | rc->zm_power_factor = 5.5776463538431935; | |
3568 | } else { | |
3569 | rc->active_wq_factor = AV_WQ_FACTOR; | |
3570 | rc->base_err_per_mb = BASELINE_ERR_PER_MB; | |
3571 | rc->sr_default_decay_limit = DEFAULT_DECAY_LIMIT; | |
3572 | rc->sr_diff_part = SR_DIFF_PART; | |
3573 | rc->gf_frame_max_boost = GF_MAX_FRAME_BOOST; | |
3574 | rc->gf_max_total_boost = MAX_GF_BOOST; | |
3575 | rc->kf_err_per_mb = DEF_EPMB_LOW; | |
3576 | rc->kf_frame_max_boost_first = KF_MAX_FRAME_BOOST; | |
3577 | rc->kf_frame_max_boost_subs = rc->kf_frame_max_boost_first / 2; | |
3578 | rc->kf_max_total_boost = MAX_KF_TOT_BOOST; | |
3579 | rc->zm_power_factor = ZM_POWER_FACTOR; | |
3580 | } | |
3581 | } | |
3582 | } | |
3583 | ||
3436 | 3584 | void vp9_rc_get_second_pass_params(VP9_COMP *cpi) { |
3437 | 3585 | VP9_COMMON *const cm = &cpi->common; |
3438 | 3586 | RATE_CONTROL *const rc = &cpi->rc; |
3442 | 3590 | const int show_idx = cm->current_video_frame; |
3443 | 3591 | |
3444 | 3592 | if (!twopass->stats_in) return; |
3593 | ||
3594 | // Configure image size specific vizier parameters | |
3595 | if (cm->current_video_frame == 0) { | |
3596 | unsigned int screen_area = (cm->width * cm->height); | |
3597 | ||
3598 | init_vizier_params(rc, screen_area); | |
3599 | } | |
3445 | 3600 | |
3446 | 3601 | // If this is an arf frame then we dont want to read the stats file or |
3447 | 3602 | // advance the input pointer as we already have what we need. |
3568 | 3723 | subtract_stats(&twopass->total_left_stats, &this_frame); |
3569 | 3724 | } |
3570 | 3725 | |
3571 | #define MINQ_ADJ_LIMIT 48 | |
3572 | #define MINQ_ADJ_LIMIT_CQ 20 | |
3573 | #define HIGH_UNDERSHOOT_RATIO 2 | |
3574 | 3726 | void vp9_twopass_postencode_update(VP9_COMP *cpi) { |
3575 | 3727 | TWO_PASS *const twopass = &cpi->twopass; |
3576 | 3728 | RATE_CONTROL *const rc = &cpi->rc; |
81 | 81 | * This function will copy the source image into a new framebuffer with |
82 | 82 | * the expected stride/border. |
83 | 83 | * |
84 | * If active_map is non-NULL and there is only one frame in the queue, then copy | |
85 | * only active macroblocks. | |
86 | * | |
87 | 84 | * \param[in] ctx Pointer to the lookahead context |
88 | 85 | * \param[in] src Pointer to the image to enqueue |
89 | 86 | * \param[in] ts_start Timestamp for the start of this frame |
90 | 87 | * \param[in] ts_end Timestamp for the end of this frame |
91 | 88 | * \param[in] flags Flags set on this frame |
92 | * \param[in] active_map Map that specifies which macroblock is active | |
93 | 89 | */ |
94 | 90 | int vp9_lookahead_push(struct lookahead_ctx *ctx, YV12_BUFFER_CONFIG *src, |
95 | 91 | int64_t ts_start, int64_t ts_end, int use_highbitdepth, |
440 | 440 | rc->last_post_encode_dropped_scene_change = 0; |
441 | 441 | rc->use_post_encode_drop = 0; |
442 | 442 | rc->ext_use_post_encode_drop = 0; |
443 | rc->disable_overshoot_maxq_cbr = 0; | |
443 | 444 | rc->arf_active_best_quality_adjustment_factor = 1.0; |
444 | 445 | rc->arf_increase_active_best_quality = 0; |
445 | 446 | rc->preserve_arf_as_gld = 0; |
1712 | 1713 | |
1713 | 1714 | // Modify frame size target when down-scaling. |
1714 | 1715 | if (cpi->oxcf.resize_mode == RESIZE_DYNAMIC && |
1715 | rc->frame_size_selector != UNSCALED) | |
1716 | rc->frame_size_selector != UNSCALED) { | |
1716 | 1717 | rc->this_frame_target = (int)(rc->this_frame_target * |
1717 | 1718 | rate_thresh_mult[rc->frame_size_selector]); |
1719 | } | |
1720 | ||
1721 | #if CONFIG_RATE_CTRL | |
1722 | if (cpi->encode_command.use_external_target_frame_bits) { | |
1723 | rc->this_frame_target = cpi->encode_command.target_frame_bits; | |
1724 | } | |
1725 | #endif | |
1718 | 1726 | |
1719 | 1727 | // Target rate per SB64 (including partial SB64s. |
1720 | 1728 | rc->sb64_target_rate = (int)(((int64_t)rc->this_frame_target * 64 * 64) / |
1987 | 1995 | cpi->rc.rc_2_frame = 0; |
1988 | 1996 | cpi->rc.rc_1_frame = 0; |
1989 | 1997 | cpi->rc.last_avg_frame_bandwidth = cpi->rc.avg_frame_bandwidth; |
1998 | cpi->rc.last_q[INTER_FRAME] = cpi->common.base_qindex; | |
1990 | 1999 | // For SVC on dropped frame when framedrop_mode != LAYER_DROP: |
1991 | 2000 | // in this mode the whole superframe may be dropped if only a single layer |
1992 | 2001 | // has buffer underflow (below threshold). Since this can then lead to |
2392 | 2401 | cpi->resize_scale_num * lc->scaling_factor_num; |
2393 | 2402 | lc->scaling_factor_den_resize = |
2394 | 2403 | cpi->resize_scale_den * lc->scaling_factor_den; |
2404 | // Reset rate control for all temporal layers. | |
2405 | lc->rc.buffer_level = lc->rc.optimal_buffer_level; | |
2406 | lc->rc.bits_off_target = lc->rc.optimal_buffer_level; | |
2407 | lc->rc.rate_correction_factors[INTER_FRAME] = | |
2408 | rc->rate_correction_factors[INTER_FRAME]; | |
2395 | 2409 | } |
2396 | 2410 | // Set the size for this current temporal layer. |
2397 | 2411 | lc = &svc->layer_context[svc->spatial_layer_id * |
2666 | 2680 | int min_width = (320 * 4) / 3; |
2667 | 2681 | int min_height = (180 * 4) / 3; |
2668 | 2682 | int down_size_on = 1; |
2683 | int force_downsize_rate = 0; | |
2669 | 2684 | cpi->resize_scale_num = 1; |
2670 | 2685 | cpi->resize_scale_den = 1; |
2671 | 2686 | // Don't resize on key frame; reset the counters on key frame. |
2686 | 2701 | } |
2687 | 2702 | #endif |
2688 | 2703 | |
2704 | // Force downsize based on per-frame-bandwidth, for extreme case, | |
2705 | // for HD input. | |
2706 | if (cpi->resize_state == ORIG && cm->width * cm->height >= 1280 * 720) { | |
2707 | if (rc->avg_frame_bandwidth < 300000 / 30) { | |
2708 | resize_action = DOWN_ONEHALF; | |
2709 | cpi->resize_state = ONE_HALF; | |
2710 | force_downsize_rate = 1; | |
2711 | } else if (rc->avg_frame_bandwidth < 400000 / 30) { | |
2712 | resize_action = ONEHALFONLY_RESIZE ? DOWN_ONEHALF : DOWN_THREEFOUR; | |
2713 | cpi->resize_state = ONEHALFONLY_RESIZE ? ONE_HALF : THREE_QUARTER; | |
2714 | force_downsize_rate = 1; | |
2715 | } | |
2716 | } else if (cpi->resize_state == THREE_QUARTER && | |
2717 | cm->width * cm->height >= 960 * 540) { | |
2718 | if (rc->avg_frame_bandwidth < 300000 / 30) { | |
2719 | resize_action = DOWN_ONEHALF; | |
2720 | cpi->resize_state = ONE_HALF; | |
2721 | force_downsize_rate = 1; | |
2722 | } | |
2723 | } | |
2724 | ||
2689 | 2725 | // Resize based on average buffer underflow and QP over some window. |
2690 | 2726 | // Ignore samples close to key frame, since QP is usually high after key. |
2691 | if (cpi->rc.frames_since_key > 2 * cpi->framerate) { | |
2692 | const int window = (int)(4 * cpi->framerate); | |
2693 | cpi->resize_avg_qp += cm->base_qindex; | |
2727 | if (!force_downsize_rate && cpi->rc.frames_since_key > cpi->framerate) { | |
2728 | const int window = VPXMIN(30, (int)(2 * cpi->framerate)); | |
2729 | cpi->resize_avg_qp += rc->last_q[INTER_FRAME]; | |
2694 | 2730 | if (cpi->rc.buffer_level < (int)(30 * rc->optimal_buffer_level / 100)) |
2695 | 2731 | ++cpi->resize_buffer_underflow; |
2696 | 2732 | ++cpi->resize_count; |
3226 | 3262 | int tl = 0; |
3227 | 3263 | int sl = 0; |
3228 | 3264 | SVC *svc = &cpi->svc; |
3229 | for (sl = 0; sl < svc->first_spatial_layer_to_encode; ++sl) { | |
3265 | for (sl = 0; sl < VPXMAX(1, svc->first_spatial_layer_to_encode); ++sl) { | |
3230 | 3266 | for (tl = 0; tl < svc->number_temporal_layers; ++tl) { |
3231 | 3267 | const int layer = |
3232 | 3268 | LAYER_IDS_TO_IDX(sl, tl, svc->number_temporal_layers); |
194 | 194 | int use_post_encode_drop; |
195 | 195 | // External flag to enable post encode frame dropping, controlled by user. |
196 | 196 | int ext_use_post_encode_drop; |
197 | ||
197 | // Flag to disable CBR feature to increase Q on overshoot detection. | |
198 | int disable_overshoot_maxq_cbr; | |
198 | 199 | int damped_adjustment[RATE_FACTOR_LEVELS]; |
199 | 200 | double arf_active_best_quality_adjustment_factor; |
200 | 201 | int arf_increase_active_best_quality; |
202 | 203 | int preserve_arf_as_gld; |
203 | 204 | int preserve_next_arf_as_gld; |
204 | 205 | int show_arf_as_gld; |
206 | ||
207 | // Vizeir project experimental rate control parameters. | |
208 | double active_wq_factor; | |
209 | double base_err_per_mb; | |
210 | double sr_default_decay_limit; | |
211 | double sr_diff_part; | |
212 | double kf_frame_max_boost_first; // Max for first kf in a chunk. | |
213 | double kf_frame_max_boost_subs; // Max for subsequent mid chunk kfs. | |
214 | double kf_max_total_boost; | |
215 | double kf_err_per_mb; | |
216 | double gf_frame_max_boost; | |
217 | double gf_max_total_boost; | |
218 | double zm_power_factor; | |
205 | 219 | } RATE_CONTROL; |
206 | 220 | |
207 | 221 | struct VP9_COMP; |
196 | 196 | static const int rd_frame_type_factor[FRAME_UPDATE_TYPES] = { 128, 144, 128, |
197 | 197 | 128, 144, 144 }; |
198 | 198 | |
199 | // Configure Vizier RD parameters. | |
200 | // Later this function will use passed in command line values. | |
201 | void vp9_init_rd_parameters(VP9_COMP *cpi) { | |
202 | RD_CONTROL *const rdc = &cpi->rd_ctrl; | |
203 | unsigned int screen_area = (cpi->common.width * cpi->common.height); | |
204 | ||
205 | // Make sure this function is floating point safe. | |
206 | vpx_clear_system_state(); | |
207 | ||
208 | if (1) { | |
209 | // Non/pre-Vizer defaults | |
210 | rdc->rd_mult_q_sq_inter_low_qp = 4.0; | |
211 | rdc->rd_mult_q_sq_inter_mid_qp = 4.5; | |
212 | rdc->rd_mult_q_sq_inter_high_qp = 3.0; | |
213 | rdc->rd_mult_q_sq_key_ultralow_qp = 4.0; | |
214 | rdc->rd_mult_q_sq_key_low_qp = 3.5; | |
215 | rdc->rd_mult_q_sq_key_mid_qp = 4.5; | |
216 | rdc->rd_mult_q_sq_key_high_qp = 7.5; | |
217 | } else if (screen_area <= 176 * 144) { | |
218 | rdc->rd_mult_q_sq_inter_high_qp = 4.295745965132044; | |
219 | rdc->rd_mult_q_sq_inter_low_qp = 4.0718581295922025; | |
220 | rdc->rd_mult_q_sq_inter_mid_qp = 4.031435609256739; | |
221 | rdc->rd_mult_q_sq_key_low_qp = 5.7037775720838155; | |
222 | rdc->rd_mult_q_sq_key_mid_qp = 4.72424015517201; | |
223 | rdc->rd_mult_q_sq_key_ultralow_qp = 4.290774097327333; | |
224 | } else if (screen_area <= 320 * 240) { | |
225 | rdc->rd_mult_q_sq_inter_high_qp = 4.388244213131458; | |
226 | rdc->rd_mult_q_sq_inter_low_qp = 4.506676356706102; | |
227 | rdc->rd_mult_q_sq_inter_mid_qp = 4.489349899621181; | |
228 | rdc->rd_mult_q_sq_key_low_qp = 4.497000582319771; | |
229 | rdc->rd_mult_q_sq_key_mid_qp = 4.2825894884789735; | |
230 | rdc->rd_mult_q_sq_key_ultralow_qp = 4.217074424696166; | |
231 | } else if (screen_area <= 640 * 360) { | |
232 | rdc->rd_mult_q_sq_inter_high_qp = 4.3702861603380025; | |
233 | rdc->rd_mult_q_sq_inter_low_qp = 4.730644123689013; | |
234 | rdc->rd_mult_q_sq_inter_mid_qp = 4.314589509578551; | |
235 | rdc->rd_mult_q_sq_key_low_qp = 6.068652999601526; | |
236 | rdc->rd_mult_q_sq_key_mid_qp = 4.817707474077241; | |
237 | rdc->rd_mult_q_sq_key_ultralow_qp = 4.576902541873747; | |
238 | } else if (screen_area <= 854 * 480) { | |
239 | rdc->rd_mult_q_sq_inter_high_qp = 3.969083125219539; | |
240 | rdc->rd_mult_q_sq_inter_low_qp = 4.811470143416073; | |
241 | rdc->rd_mult_q_sq_inter_mid_qp = 4.621618127750201; | |
242 | rdc->rd_mult_q_sq_key_low_qp = 5.073157238799473; | |
243 | rdc->rd_mult_q_sq_key_mid_qp = 5.7587672849242635; | |
244 | rdc->rd_mult_q_sq_key_ultralow_qp = 4.9854544277222566; | |
245 | } else if (screen_area <= 1280 * 720) { | |
246 | rdc->rd_mult_q_sq_inter_high_qp = 4.410712348825541; | |
247 | rdc->rd_mult_q_sq_inter_low_qp = 5.119381136011107; | |
248 | rdc->rd_mult_q_sq_inter_mid_qp = 4.518613675766538; | |
249 | rdc->rd_mult_q_sq_key_low_qp = 5.848703119971484; | |
250 | rdc->rd_mult_q_sq_key_mid_qp = 5.368947246228739; | |
251 | rdc->rd_mult_q_sq_key_ultralow_qp = 3.9468491666607326; | |
252 | } else if (screen_area <= 1920 * 1080) { | |
253 | rdc->rd_mult_q_sq_inter_high_qp = 3.2141187537667797; | |
254 | rdc->rd_mult_q_sq_inter_low_qp = 6.00569815296199; | |
255 | rdc->rd_mult_q_sq_inter_mid_qp = 3.932565684947023; | |
256 | rdc->rd_mult_q_sq_key_low_qp = 10.582906599488298; | |
257 | rdc->rd_mult_q_sq_key_mid_qp = 6.274162346360692; | |
258 | rdc->rd_mult_q_sq_key_ultralow_qp = 4.399795006320089; | |
259 | } | |
260 | } | |
261 | ||
199 | 262 | int vp9_compute_rd_mult_based_on_qindex(const VP9_COMP *cpi, int qindex) { |
200 | // largest dc_quant is 21387, therefore rdmult should always fit in int32_t | |
263 | const RD_CONTROL *rdc = &cpi->rd_ctrl; | |
201 | 264 | const int q = vp9_dc_quant(qindex, 0, cpi->common.bit_depth); |
202 | uint32_t rdmult = q * q; | |
265 | // largest dc_quant is 21387, therefore rdmult should fit in int32_t | |
266 | int rdmult = q * q; | |
267 | ||
268 | // Make sure this function is floating point safe. | |
269 | vpx_clear_system_state(); | |
203 | 270 | |
204 | 271 | if (cpi->common.frame_type != KEY_FRAME) { |
205 | if (qindex < 128) | |
206 | rdmult = rdmult * 4; | |
207 | else if (qindex < 190) | |
208 | rdmult = rdmult * 4 + rdmult / 2; | |
209 | else | |
210 | rdmult = rdmult * 3; | |
272 | if (qindex < 128) { | |
273 | rdmult = (int)((double)rdmult * rdc->rd_mult_q_sq_inter_low_qp); | |
274 | } else if (qindex < 190) { | |
275 | rdmult = (int)((double)rdmult * rdc->rd_mult_q_sq_inter_mid_qp); | |
276 | } else { | |
277 | rdmult = (int)((double)rdmult * rdc->rd_mult_q_sq_inter_high_qp); | |
278 | } | |
211 | 279 | } else { |
212 | if (qindex < 64) | |
213 | rdmult = rdmult * 4; | |
214 | else if (qindex <= 128) | |
215 | rdmult = rdmult * 3 + rdmult / 2; | |
216 | else if (qindex < 190) | |
217 | rdmult = rdmult * 4 + rdmult / 2; | |
218 | else | |
219 | rdmult = rdmult * 7 + rdmult / 2; | |
220 | } | |
280 | if (qindex < 64) { | |
281 | rdmult = (int)((double)rdmult * rdc->rd_mult_q_sq_key_ultralow_qp); | |
282 | } else if (qindex <= 128) { | |
283 | rdmult = (int)((double)rdmult * rdc->rd_mult_q_sq_key_low_qp); | |
284 | } else if (qindex < 190) { | |
285 | rdmult = (int)((double)rdmult * rdc->rd_mult_q_sq_key_mid_qp); | |
286 | ||
287 | } else { | |
288 | rdmult = (int)((double)rdmult * rdc->rd_mult_q_sq_key_high_qp); | |
289 | } | |
290 | } | |
291 | ||
221 | 292 | #if CONFIG_VP9_HIGHBITDEPTH |
222 | 293 | switch (cpi->common.bit_depth) { |
223 | 294 | case VPX_BITS_10: rdmult = ROUND_POWER_OF_TWO(rdmult, 4); break; |
100 | 100 | THR_INTRA, |
101 | 101 | } THR_MODES_SUB8X8; |
102 | 102 | |
103 | typedef struct { | |
104 | // RD control parameters | |
105 | // Added for Vizier project. | |
106 | double rd_mult_q_sq_inter_low_qp; | |
107 | double rd_mult_q_sq_inter_mid_qp; | |
108 | double rd_mult_q_sq_inter_high_qp; | |
109 | double rd_mult_q_sq_key_ultralow_qp; | |
110 | double rd_mult_q_sq_key_low_qp; | |
111 | double rd_mult_q_sq_key_mid_qp; | |
112 | double rd_mult_q_sq_key_high_qp; | |
113 | } RD_CONTROL; | |
114 | ||
103 | 115 | typedef struct RD_OPT { |
104 | 116 | // Thresh_mult is used to set a threshold for the rd score. A higher value |
105 | 117 | // means that we will accept the best mode so far more often. This number |
142 | 154 | struct TileDataEnc; |
143 | 155 | struct VP9_COMP; |
144 | 156 | struct macroblock; |
157 | ||
158 | void vp9_init_rd_parameters(struct VP9_COMP *cpi); | |
145 | 159 | |
146 | 160 | int vp9_compute_rd_mult_based_on_qindex(const struct VP9_COMP *cpi, int qindex); |
147 | 161 |
4442 | 4442 | tmp_best_sse = total_sse; |
4443 | 4443 | tmp_best_skippable = skippable; |
4444 | 4444 | tmp_best_mbmode = *mi; |
4445 | x->sum_y_eobs[TX_4X4] = 0; | |
4445 | 4446 | for (i = 0; i < 4; i++) { |
4446 | 4447 | tmp_best_bmodes[i] = xd->mi[0]->bmi[i]; |
4447 | 4448 | x->zcoeff_blk[TX_4X4][i] = !x->plane[0].eobs[i]; |
4475 | 4476 | &rate, &rate_y, &distortion, &skippable, &total_sse, |
4476 | 4477 | (int)this_rd_thresh, seg_mvs, bsi, 0, mi_row, mi_col); |
4477 | 4478 | if (tmp_rd == INT64_MAX) continue; |
4479 | x->sum_y_eobs[TX_4X4] = 0; | |
4480 | for (i = 0; i < 4; i++) { | |
4481 | x->zcoeff_blk[TX_4X4][i] = !x->plane[0].eobs[i]; | |
4482 | x->sum_y_eobs[TX_4X4] += x->plane[0].eobs[i]; | |
4483 | } | |
4478 | 4484 | } else { |
4479 | 4485 | total_sse = tmp_best_sse; |
4480 | 4486 | rate = tmp_best_rate; |
620 | 620 | // increase in encoding time. |
621 | 621 | if (cpi->use_svc && svc->spatial_layer_id > 0) sf->nonrd_keyframe = 1; |
622 | 622 | if (cm->frame_type != KEY_FRAME && cpi->resize_state == ORIG && |
623 | cpi->oxcf.rc_mode == VPX_CBR) { | |
623 | cpi->oxcf.rc_mode == VPX_CBR && !cpi->rc.disable_overshoot_maxq_cbr) { | |
624 | 624 | if (cm->width * cm->height <= 352 * 288 && !cpi->use_svc && |
625 | 625 | cpi->oxcf.content != VP9E_CONTENT_SCREEN) |
626 | 626 | sf->overshoot_detection_cbr_rt = RE_ENCODE_MAXQ; |
667 | 667 | sf->base_mv_aggressive = 1; |
668 | 668 | } |
669 | 669 | if (cm->frame_type != KEY_FRAME && cpi->resize_state == ORIG && |
670 | cpi->oxcf.rc_mode == VPX_CBR) | |
670 | cpi->oxcf.rc_mode == VPX_CBR && !cpi->rc.disable_overshoot_maxq_cbr) | |
671 | 671 | sf->overshoot_detection_cbr_rt = FAST_DETECTION_MAXQ; |
672 | 672 | } |
673 | 673 |
356 | 356 | if (is_one_pass_cbr_svc(cpi) && lc->speed > 0) { |
357 | 357 | cpi->oxcf.speed = lc->speed; |
358 | 358 | } |
359 | cpi->loopfilter_ctrl = lc->loopfilter_ctrl; | |
359 | 360 | // Reset the frames_since_key and frames_to_key counters to their values |
360 | 361 | // before the layer restore. Keep these defined for the stream (not layer). |
361 | 362 | if (cpi->svc.number_temporal_layers > 1 || |
954 | 955 | if (cpi->common.frame_type != KEY_FRAME && !cpi->ext_refresh_last_frame && |
955 | 956 | !cpi->ext_refresh_golden_frame && !cpi->ext_refresh_alt_ref_frame) |
956 | 957 | svc->non_reference_frame = 1; |
957 | // For non-flexible mode, where update_buffer_slot is used, need to check if | |
958 | // For flexible mode, where update_buffer_slot is used, need to check if | |
958 | 959 | // all buffer slots are not refreshed. |
959 | 960 | if (svc->temporal_layering_mode == VP9E_TEMPORAL_LAYERING_MODE_BYPASS) { |
960 | 961 | if (svc->update_buffer_slot[svc->spatial_layer_id] != 0) |
70 | 70 | int actual_num_seg2_blocks; |
71 | 71 | int counter_encode_maxq_scene_change; |
72 | 72 | uint8_t speed; |
73 | int loopfilter_ctrl; | |
73 | 74 | } LAYER_CONTEXT; |
74 | 75 | |
75 | 76 | typedef struct SVC { |
158 | 158 | |
159 | 159 | int VP9RateControlRTC::GetLoopfilterLevel() const { |
160 | 160 | struct loopfilter *const lf = &cpi_->common.lf; |
161 | vp9_pick_filter_level(NULL, cpi_, LPF_PICK_FROM_Q); | |
161 | vp9_pick_filter_level(nullptr, cpi_, LPF_PICK_FROM_Q); | |
162 | 162 | return lf->filter_level; |
163 | 163 | } |
164 | 164 |
89 | 89 | return 1; |
90 | 90 | } |
91 | 91 | |
92 | // Assume every config in VP9EncoderConfig is less than 100 characters. | |
93 | #define ENCODE_CONFIG_BUF_SIZE 100 | |
94 | struct EncodeConfig { | |
95 | char name[ENCODE_CONFIG_BUF_SIZE]; | |
96 | char value[ENCODE_CONFIG_BUF_SIZE]; | |
97 | }; | |
98 | ||
92 | 99 | class SimpleEncode::EncodeImpl { |
93 | 100 | public: |
94 | 101 | VP9_COMP *cpi; |
95 | 102 | vpx_img_fmt_t img_fmt; |
96 | 103 | vpx_image_t tmp_img; |
97 | 104 | std::vector<FIRSTPASS_STATS> first_pass_stats; |
105 | std::vector<EncodeConfig> encode_config_list; | |
98 | 106 | }; |
99 | 107 | |
100 | 108 | static VP9_COMP *init_encoder(const VP9EncoderConfig *oxcf, |
166 | 174 | |
167 | 175 | static void update_motion_vector_info( |
168 | 176 | const MOTION_VECTOR_INFO *input_motion_vector_info, const int num_rows_4x4, |
169 | const int num_cols_4x4, MotionVectorInfo *output_motion_vector_info) { | |
177 | const int num_cols_4x4, MotionVectorInfo *output_motion_vector_info, | |
178 | int motion_vector_scale) { | |
170 | 179 | const int num_units_4x4 = num_rows_4x4 * num_cols_4x4; |
171 | 180 | for (int i = 0; i < num_units_4x4; ++i) { |
172 | 181 | const MV_REFERENCE_FRAME *in_ref_frame = |
184 | 193 | mv_ref_frame_to_ref_frame_type(in_ref_frame[1]); |
185 | 194 | output_motion_vector_info[i].mv_row[0] = |
186 | 195 | (double)input_motion_vector_info[i].mv[0].as_mv.row / |
187 | kMotionVectorPrecision; | |
196 | motion_vector_scale; | |
188 | 197 | output_motion_vector_info[i].mv_column[0] = |
189 | 198 | (double)input_motion_vector_info[i].mv[0].as_mv.col / |
190 | kMotionVectorPrecision; | |
199 | motion_vector_scale; | |
191 | 200 | output_motion_vector_info[i].mv_row[1] = |
192 | 201 | (double)input_motion_vector_info[i].mv[1].as_mv.row / |
193 | kMotionVectorPrecision; | |
202 | motion_vector_scale; | |
194 | 203 | output_motion_vector_info[i].mv_column[1] = |
195 | 204 | (double)input_motion_vector_info[i].mv[1].as_mv.col / |
196 | kMotionVectorPrecision; | |
205 | motion_vector_scale; | |
206 | } | |
207 | } | |
208 | ||
209 | static void update_tpl_stats_info(const TplDepStats *input_tpl_stats_info, | |
210 | const int show_frame_count, | |
211 | TplStatsInfo *output_tpl_stats_info) { | |
212 | int frame_idx; | |
213 | for (frame_idx = 0; frame_idx < show_frame_count; ++frame_idx) { | |
214 | output_tpl_stats_info[frame_idx].intra_cost = | |
215 | input_tpl_stats_info[frame_idx].intra_cost; | |
216 | output_tpl_stats_info[frame_idx].inter_cost = | |
217 | input_tpl_stats_info[frame_idx].inter_cost; | |
218 | output_tpl_stats_info[frame_idx].mc_flow = | |
219 | input_tpl_stats_info[frame_idx].mc_flow; | |
220 | output_tpl_stats_info[frame_idx].mc_dep_cost = | |
221 | input_tpl_stats_info[frame_idx].mc_dep_cost; | |
222 | output_tpl_stats_info[frame_idx].mc_ref_cost = | |
223 | input_tpl_stats_info[frame_idx].mc_ref_cost; | |
197 | 224 | } |
198 | 225 | } |
199 | 226 | |
470 | 497 | encode_frame_result->coding_data.reset( |
471 | 498 | new (std::nothrow) uint8_t[max_coding_data_byte_size]); |
472 | 499 | |
473 | encode_frame_result->num_rows_4x4 = get_num_unit_4x4(frame_width); | |
474 | encode_frame_result->num_cols_4x4 = get_num_unit_4x4(frame_height); | |
500 | encode_frame_result->num_rows_4x4 = get_num_unit_4x4(frame_height); | |
501 | encode_frame_result->num_cols_4x4 = get_num_unit_4x4(frame_width); | |
475 | 502 | encode_frame_result->partition_info.resize(encode_frame_result->num_rows_4x4 * |
476 | 503 | encode_frame_result->num_cols_4x4); |
477 | 504 | encode_frame_result->motion_vector_info.resize( |
478 | 505 | encode_frame_result->num_rows_4x4 * encode_frame_result->num_cols_4x4); |
506 | encode_frame_result->tpl_stats_info.resize(MAX_LAG_BUFFERS); | |
479 | 507 | |
480 | 508 | if (encode_frame_result->coding_data.get() == nullptr) { |
481 | 509 | return false; |
484 | 512 | frame_height, img_fmt); |
485 | 513 | } |
486 | 514 | |
515 | static void encode_frame_result_update_rq_history( | |
516 | const RATE_QINDEX_HISTORY *rq_history, | |
517 | EncodeFrameResult *encode_frame_result) { | |
518 | encode_frame_result->recode_count = rq_history->recode_count; | |
519 | for (int i = 0; i < encode_frame_result->recode_count; ++i) { | |
520 | const int q_index = rq_history->q_index_history[i]; | |
521 | const int rate = rq_history->rate_history[i]; | |
522 | encode_frame_result->q_index_history.push_back(q_index); | |
523 | encode_frame_result->rate_history.push_back(rate); | |
524 | } | |
525 | } | |
526 | ||
487 | 527 | static void update_encode_frame_result( |
488 | EncodeFrameResult *encode_frame_result, | |
528 | EncodeFrameResult *encode_frame_result, const int show_frame_count, | |
489 | 529 | const ENCODE_FRAME_RESULT *encode_frame_info) { |
490 | 530 | encode_frame_result->coding_data_bit_size = |
491 | 531 | encode_frame_result->coding_data_byte_size * 8; |
510 | 550 | update_motion_vector_info(encode_frame_info->motion_vector_info, |
511 | 551 | encode_frame_result->num_rows_4x4, |
512 | 552 | encode_frame_result->num_cols_4x4, |
513 | &encode_frame_result->motion_vector_info[0]); | |
553 | &encode_frame_result->motion_vector_info[0], | |
554 | kMotionVectorSubPixelPrecision); | |
514 | 555 | update_frame_counts(&encode_frame_info->frame_counts, |
515 | 556 | &encode_frame_result->frame_counts); |
557 | if (encode_frame_result->frame_type == kFrameTypeAltRef) { | |
558 | update_tpl_stats_info(encode_frame_info->tpl_stats_info, show_frame_count, | |
559 | &encode_frame_result->tpl_stats_info[0]); | |
560 | } | |
561 | encode_frame_result_update_rq_history(&encode_frame_info->rq_history, | |
562 | encode_frame_result); | |
516 | 563 | } |
517 | 564 | |
518 | 565 | static void IncreaseGroupOfPictureIndex(GroupOfPicture *group_of_picture) { |
694 | 741 | start_ref_frame_info, group_of_picture); |
695 | 742 | } |
696 | 743 | |
744 | #define SET_STRUCT_VALUE(config, structure, ret, field) \ | |
745 | if (strcmp(config.name, #field) == 0) { \ | |
746 | structure->field = atoi(config.value); \ | |
747 | ret = 1; \ | |
748 | } | |
749 | ||
750 | static void UpdateEncodeConfig(const EncodeConfig &config, | |
751 | VP9EncoderConfig *oxcf) { | |
752 | int ret = 0; | |
753 | SET_STRUCT_VALUE(config, oxcf, ret, key_freq); | |
754 | SET_STRUCT_VALUE(config, oxcf, ret, two_pass_vbrmin_section); | |
755 | SET_STRUCT_VALUE(config, oxcf, ret, two_pass_vbrmax_section); | |
756 | SET_STRUCT_VALUE(config, oxcf, ret, under_shoot_pct); | |
757 | SET_STRUCT_VALUE(config, oxcf, ret, over_shoot_pct); | |
758 | SET_STRUCT_VALUE(config, oxcf, ret, max_threads); | |
759 | SET_STRUCT_VALUE(config, oxcf, ret, frame_parallel_decoding_mode); | |
760 | SET_STRUCT_VALUE(config, oxcf, ret, tile_columns); | |
761 | SET_STRUCT_VALUE(config, oxcf, ret, arnr_max_frames); | |
762 | SET_STRUCT_VALUE(config, oxcf, ret, arnr_strength); | |
763 | SET_STRUCT_VALUE(config, oxcf, ret, lag_in_frames); | |
764 | SET_STRUCT_VALUE(config, oxcf, ret, encode_breakout); | |
765 | SET_STRUCT_VALUE(config, oxcf, ret, enable_tpl_model); | |
766 | SET_STRUCT_VALUE(config, oxcf, ret, enable_auto_arf); | |
767 | if (strcmp(config.name, "rc_mode") == 0) { | |
768 | int rc_mode = atoi(config.value); | |
769 | if (rc_mode >= VPX_VBR && rc_mode <= VPX_Q) { | |
770 | oxcf->rc_mode = (enum vpx_rc_mode)rc_mode; | |
771 | ret = 1; | |
772 | } else { | |
773 | fprintf(stderr, "Invalid rc_mode value: %d\n", rc_mode); | |
774 | } | |
775 | } | |
776 | SET_STRUCT_VALUE(config, oxcf, ret, cq_level); | |
777 | if (ret == 0) { | |
778 | fprintf(stderr, "Ignored unsupported encode_config %s\n", config.name); | |
779 | } | |
780 | } | |
781 | ||
782 | static VP9EncoderConfig GetEncodeConfig( | |
783 | int frame_width, int frame_height, vpx_rational_t frame_rate, | |
784 | int target_bitrate, int encode_speed, vpx_enc_pass enc_pass, | |
785 | const std::vector<EncodeConfig> &encode_config_list) { | |
786 | VP9EncoderConfig oxcf = | |
787 | vp9_get_encoder_config(frame_width, frame_height, frame_rate, | |
788 | target_bitrate, encode_speed, enc_pass); | |
789 | for (const auto &config : encode_config_list) { | |
790 | UpdateEncodeConfig(config, &oxcf); | |
791 | } | |
792 | if (enc_pass == VPX_RC_FIRST_PASS) { | |
793 | oxcf.lag_in_frames = 0; | |
794 | } | |
795 | return oxcf; | |
796 | } | |
797 | ||
697 | 798 | SimpleEncode::SimpleEncode(int frame_width, int frame_height, |
698 | 799 | int frame_rate_num, int frame_rate_den, |
699 | 800 | int target_bitrate, int num_frames, |
705 | 806 | frame_rate_den_ = frame_rate_den; |
706 | 807 | target_bitrate_ = target_bitrate; |
707 | 808 | num_frames_ = num_frames; |
809 | encode_speed_ = 0; | |
708 | 810 | |
709 | 811 | frame_coding_index_ = 0; |
710 | 812 | show_frame_count_ = 0; |
726 | 828 | InitRefFrameInfo(&ref_frame_info_); |
727 | 829 | } |
728 | 830 | |
831 | void SimpleEncode::SetEncodeSpeed(int encode_speed) { | |
832 | encode_speed_ = encode_speed; | |
833 | } | |
834 | ||
835 | StatusCode SimpleEncode::SetEncodeConfig(const char *name, const char *value) { | |
836 | if (name == nullptr || value == nullptr) { | |
837 | fprintf(stderr, "SetEncodeConfig: null pointer, name %p value %p\n", name, | |
838 | value); | |
839 | return StatusError; | |
840 | } | |
841 | EncodeConfig config; | |
842 | snprintf(config.name, ENCODE_CONFIG_BUF_SIZE, "%s", name); | |
843 | snprintf(config.value, ENCODE_CONFIG_BUF_SIZE, "%s", value); | |
844 | impl_ptr_->encode_config_list.push_back(config); | |
845 | return StatusOk; | |
846 | } | |
847 | ||
848 | StatusCode SimpleEncode::DumpEncodeConfigs(int pass, FILE *fp) { | |
849 | if (fp == nullptr) { | |
850 | fprintf(stderr, "DumpEncodeConfigs: null pointer, fp %p\n", fp); | |
851 | return StatusError; | |
852 | } | |
853 | vpx_enc_pass enc_pass; | |
854 | if (pass == 1) { | |
855 | enc_pass = VPX_RC_FIRST_PASS; | |
856 | } else { | |
857 | enc_pass = VPX_RC_LAST_PASS; | |
858 | } | |
859 | const vpx_rational_t frame_rate = | |
860 | make_vpx_rational(frame_rate_num_, frame_rate_den_); | |
861 | const VP9EncoderConfig oxcf = | |
862 | GetEncodeConfig(frame_width_, frame_height_, frame_rate, target_bitrate_, | |
863 | encode_speed_, enc_pass, impl_ptr_->encode_config_list); | |
864 | vp9_dump_encoder_config(&oxcf, fp); | |
865 | return StatusOk; | |
866 | } | |
867 | ||
729 | 868 | void SimpleEncode::ComputeFirstPassStats() { |
730 | 869 | vpx_rational_t frame_rate = |
731 | 870 | make_vpx_rational(frame_rate_num_, frame_rate_den_); |
732 | const VP9EncoderConfig oxcf = | |
733 | vp9_get_encoder_config(frame_width_, frame_height_, frame_rate, | |
734 | target_bitrate_, VPX_RC_FIRST_PASS); | |
871 | const VP9EncoderConfig oxcf = GetEncodeConfig( | |
872 | frame_width_, frame_height_, frame_rate, target_bitrate_, encode_speed_, | |
873 | VPX_RC_FIRST_PASS, impl_ptr_->encode_config_list); | |
735 | 874 | VP9_COMP *cpi = init_encoder(&oxcf, impl_ptr_->img_fmt); |
736 | 875 | struct lookahead_ctx *lookahead = cpi->lookahead; |
737 | 876 | int i; |
738 | 877 | int use_highbitdepth = 0; |
878 | const int num_rows_16x16 = get_num_unit_16x16(frame_height_); | |
879 | const int num_cols_16x16 = get_num_unit_16x16(frame_width_); | |
739 | 880 | #if CONFIG_VP9_HIGHBITDEPTH |
740 | 881 | use_highbitdepth = cpi->common.use_highbitdepth; |
741 | 882 | #endif |
768 | 909 | // vp9_get_compressed_data only generates first pass stats not |
769 | 910 | // compresses data |
770 | 911 | assert(size == 0); |
912 | // Get vp9 first pass motion vector info. | |
913 | std::vector<MotionVectorInfo> mv_info(num_rows_16x16 * num_cols_16x16); | |
914 | update_motion_vector_info(cpi->fp_motion_vector_info, num_rows_16x16, | |
915 | num_cols_16x16, mv_info.data(), | |
916 | kMotionVectorFullPixelPrecision); | |
917 | fp_motion_vector_info_.push_back(mv_info); | |
771 | 918 | } |
772 | 919 | impl_ptr_->first_pass_stats.push_back(vp9_get_frame_stats(&cpi->twopass)); |
773 | 920 | } |
805 | 952 | return output_stats; |
806 | 953 | } |
807 | 954 | |
808 | void SimpleEncode::SetExternalGroupOfPicturesMap(std::vector<int> gop_map) { | |
809 | gop_map_ = gop_map; | |
955 | std::vector<std::vector<MotionVectorInfo>> | |
956 | SimpleEncode::ObserveFirstPassMotionVectors() { | |
957 | return fp_motion_vector_info_; | |
958 | } | |
959 | ||
960 | void SimpleEncode::SetExternalGroupOfPicturesMap(int *gop_map, | |
961 | int gop_map_size) { | |
962 | for (int i = 0; i < gop_map_size; ++i) { | |
963 | gop_map_.push_back(gop_map[i]); | |
964 | } | |
810 | 965 | // The following will check and modify gop_map_ to make sure the |
811 | 966 | // gop_map_ satisfies the constraints. |
812 | 967 | // 1) Each key frame position should be at the start of a gop. |
847 | 1002 | |
848 | 1003 | static GOP_COMMAND GetGopCommand(const std::vector<int> &gop_map, |
849 | 1004 | int start_show_index) { |
850 | assert(static_cast<size_t>(start_show_index) < gop_map.size()); | |
851 | assert((gop_map[start_show_index] & kGopMapFlagStart) != 0); | |
852 | 1005 | GOP_COMMAND gop_command; |
853 | 1006 | if (gop_map.size() > 0) { |
1007 | assert(static_cast<size_t>(start_show_index) < gop_map.size()); | |
1008 | assert((gop_map[start_show_index] & kGopMapFlagStart) != 0); | |
854 | 1009 | int end_show_index = start_show_index + 1; |
855 | 1010 | // gop_map[end_show_index] & kGopMapFlagStart == 0 means this is |
856 | 1011 | // the start of a gop. |
875 | 1030 | assert(impl_ptr_->first_pass_stats.size() > 0); |
876 | 1031 | vpx_rational_t frame_rate = |
877 | 1032 | make_vpx_rational(frame_rate_num_, frame_rate_den_); |
878 | VP9EncoderConfig oxcf = | |
879 | vp9_get_encoder_config(frame_width_, frame_height_, frame_rate, | |
880 | target_bitrate_, VPX_RC_LAST_PASS); | |
1033 | VP9EncoderConfig oxcf = GetEncodeConfig( | |
1034 | frame_width_, frame_height_, frame_rate, target_bitrate_, encode_speed_, | |
1035 | VPX_RC_LAST_PASS, impl_ptr_->encode_config_list); | |
1036 | ||
881 | 1037 | vpx_fixed_buf_t stats; |
882 | 1038 | stats.buf = GetVectorData(impl_ptr_->first_pass_stats); |
883 | 1039 | stats.sz = sizeof(impl_ptr_->first_pass_stats[0]) * |
1045 | 1201 | abort(); |
1046 | 1202 | } |
1047 | 1203 | |
1048 | update_encode_frame_result(encode_frame_result, &encode_frame_info); | |
1204 | const GroupOfPicture group_of_picture = this->ObserveGroupOfPicture(); | |
1205 | const int show_frame_count = group_of_picture.show_frame_count; | |
1206 | update_encode_frame_result(encode_frame_result, show_frame_count, | |
1207 | &encode_frame_info); | |
1049 | 1208 | PostUpdateState(*encode_frame_result); |
1050 | 1209 | } else { |
1051 | 1210 | // TODO(angiebird): Clean up encode_frame_result. |
1060 | 1219 | quantize_index); |
1061 | 1220 | EncodeFrame(encode_frame_result); |
1062 | 1221 | encode_command_reset_external_quantize_index(&impl_ptr_->cpi->encode_command); |
1222 | } | |
1223 | ||
1224 | void SimpleEncode::EncodeFrameWithTargetFrameBits( | |
1225 | EncodeFrameResult *encode_frame_result, int target_frame_bits, | |
1226 | double percent_diff) { | |
1227 | encode_command_set_target_frame_bits(&impl_ptr_->cpi->encode_command, | |
1228 | target_frame_bits, percent_diff); | |
1229 | EncodeFrame(encode_frame_result); | |
1230 | encode_command_reset_target_frame_bits(&impl_ptr_->cpi->encode_command); | |
1063 | 1231 | } |
1064 | 1232 | |
1065 | 1233 | static int GetCodingFrameNumFromGopMap(const std::vector<int> &gop_map) { |
1085 | 1253 | const int allow_alt_ref = 1; |
1086 | 1254 | vpx_rational_t frame_rate = |
1087 | 1255 | make_vpx_rational(frame_rate_num_, frame_rate_den_); |
1088 | const VP9EncoderConfig oxcf = | |
1089 | vp9_get_encoder_config(frame_width_, frame_height_, frame_rate, | |
1090 | target_bitrate_, VPX_RC_LAST_PASS); | |
1256 | const VP9EncoderConfig oxcf = GetEncodeConfig( | |
1257 | frame_width_, frame_height_, frame_rate, target_bitrate_, encode_speed_, | |
1258 | VPX_RC_LAST_PASS, impl_ptr_->encode_config_list); | |
1091 | 1259 | FRAME_INFO frame_info = vp9_get_frame_info(&oxcf); |
1092 | 1260 | FIRST_PASS_INFO first_pass_info; |
1093 | 1261 | fps_init_first_pass_info(&first_pass_info, |
1098 | 1266 | } |
1099 | 1267 | |
1100 | 1268 | std::vector<int> SimpleEncode::ComputeKeyFrameMap() const { |
1101 | assert(impl_ptr_->first_pass_stats.size() == num_frames_); | |
1269 | // The last entry of first_pass_stats is the overall stats. | |
1270 | assert(impl_ptr_->first_pass_stats.size() == num_frames_ + 1); | |
1102 | 1271 | vpx_rational_t frame_rate = |
1103 | 1272 | make_vpx_rational(frame_rate_num_, frame_rate_den_); |
1104 | const VP9EncoderConfig oxcf = | |
1105 | vp9_get_encoder_config(frame_width_, frame_height_, frame_rate, | |
1106 | target_bitrate_, VPX_RC_LAST_PASS); | |
1273 | const VP9EncoderConfig oxcf = GetEncodeConfig( | |
1274 | frame_width_, frame_height_, frame_rate, target_bitrate_, encode_speed_, | |
1275 | VPX_RC_LAST_PASS, impl_ptr_->encode_config_list); | |
1107 | 1276 | FRAME_INFO frame_info = vp9_get_frame_info(&oxcf); |
1108 | 1277 | FIRST_PASS_INFO first_pass_info; |
1109 | 1278 | fps_init_first_pass_info(&first_pass_info, |
18 | 18 | |
19 | 19 | namespace vp9 { |
20 | 20 | |
21 | enum StatusCode { | |
22 | StatusOk = 0, | |
23 | StatusError, | |
24 | }; | |
25 | ||
21 | 26 | // TODO(angiebird): Add description for each frame type. |
22 | 27 | enum FrameType { |
23 | 28 | kFrameTypeKey = 0, |
24 | kFrameTypeInter, | |
25 | kFrameTypeAltRef, | |
26 | kFrameTypeOverlay, | |
27 | kFrameTypeGolden, | |
29 | kFrameTypeInter = 1, | |
30 | kFrameTypeAltRef = 2, | |
31 | kFrameTypeOverlay = 3, | |
32 | kFrameTypeGolden = 4, | |
28 | 33 | }; |
29 | 34 | |
30 | 35 | // TODO(angiebird): Add description for each reference frame type. |
57 | 62 | int height; // prediction block height |
58 | 63 | }; |
59 | 64 | |
60 | constexpr int kMotionVectorPrecision = 8; | |
61 | ||
62 | // The frame is split to 4x4 blocks. | |
65 | constexpr int kMotionVectorSubPixelPrecision = 8; | |
66 | constexpr int kMotionVectorFullPixelPrecision = 1; | |
67 | ||
68 | // In the first pass. The frame is split to 16x16 blocks. | |
69 | // This structure contains the information of each 16x16 block. | |
70 | // In the second pass. The frame is split to 4x4 blocks. | |
63 | 71 | // This structure contains the information of each 4x4 block. |
64 | 72 | struct MotionVectorInfo { |
65 | 73 | // Number of valid motion vectors, always 0 if this block is in the key frame. |
67 | 75 | int mv_count; |
68 | 76 | // The reference frame for motion vectors. If the second motion vector does |
69 | 77 | // not exist (mv_count = 1), the reference frame is kNoneRefFrame. |
70 | // Otherwise, the reference frame is either kLastFrame, or kGoldenFrame, | |
71 | // or kAltRefFrame. | |
78 | // Otherwise, the reference frame is either kRefFrameTypeLast, or | |
79 | // kRefFrameTypePast, or kRefFrameTypeFuture. | |
72 | 80 | RefFrameType ref_frame[2]; |
73 | 81 | // The row offset of motion vectors in the unit of pixel. |
74 | 82 | // If the second motion vector does not exist, the value is 0. |
76 | 84 | // The column offset of motion vectors in the unit of pixel. |
77 | 85 | // If the second motion vector does not exist, the value is 0. |
78 | 86 | double mv_column[2]; |
87 | }; | |
88 | ||
89 | // Accumulated tpl stats of all blocks in one frame. | |
90 | // For each frame, the tpl stats are computed per 32x32 block. | |
91 | struct TplStatsInfo { | |
92 | // Intra complexity: the sum of absolute transform difference (SATD) of | |
93 | // intra predicted residuals. | |
94 | int64_t intra_cost; | |
95 | // Inter complexity: the SATD of inter predicted residuals. | |
96 | int64_t inter_cost; | |
97 | // Motion compensated information flow. It measures how much information | |
98 | // is propagated from the current frame to other frames. | |
99 | int64_t mc_flow; | |
100 | // Motion compensated dependency cost. It equals to its own intra_cost | |
101 | // plus the mc_flow. | |
102 | int64_t mc_dep_cost; | |
103 | // Motion compensated reference cost. | |
104 | int64_t mc_ref_cost; | |
79 | 105 | }; |
80 | 106 | |
81 | 107 | struct RefFrameInfo { |
244 | 270 | std::vector<PartitionInfo> partition_info; |
245 | 271 | // A vector of the motion vector information of the frame. |
246 | 272 | // The number of elements is |num_rows_4x4| * |num_cols_4x4|. |
247 | // The frame is divided 4x4 blocks of |num_rows_4x4| rows and | |
273 | // The frame is divided into 4x4 blocks of |num_rows_4x4| rows and | |
248 | 274 | // |num_cols_4x4| columns. |
249 | 275 | // Each 4x4 block contains 0 motion vector if this is an intra predicted |
250 | 276 | // frame (for example, the key frame). If the frame is inter predicted, |
252 | 278 | // Similar to partition info, all 4x4 blocks inside the same partition block |
253 | 279 | // share the same motion vector information. |
254 | 280 | std::vector<MotionVectorInfo> motion_vector_info; |
281 | // A vector of the tpl stats information. | |
282 | // The tpl stats measure the complexity of a frame, as well as the | |
283 | // information propagated along the motion trajectory between frames, in | |
284 | // the reference frame structure. | |
285 | // The tpl stats could be used as a more accurate spatial and temporal | |
286 | // complexity measure in addition to the first pass stats. | |
287 | // The vector contains tpl stats for all show frames in a GOP. | |
288 | // The tpl stats stored in the vector is according to the encoding order. | |
289 | // For example, suppose there are N show frames for the current GOP. | |
290 | // Then tpl_stats_info[0] stores the information of the first frame to be | |
291 | // encoded for this GOP, i.e, the AltRef frame. | |
292 | std::vector<TplStatsInfo> tpl_stats_info; | |
255 | 293 | ImageBuffer coded_frame; |
294 | ||
295 | // recode_count, q_index_history and rate_history are only available when | |
296 | // EncodeFrameWithTargetFrameBits() is used. | |
297 | int recode_count; | |
298 | std::vector<int> q_index_history; | |
299 | std::vector<int> rate_history; | |
256 | 300 | }; |
257 | 301 | |
258 | 302 | struct GroupOfPicture { |
303 | 347 | SimpleEncode(SimpleEncode &) = delete; |
304 | 348 | SimpleEncode &operator=(const SimpleEncode &) = delete; |
305 | 349 | |
350 | // Adjusts the encoder's coding speed. | |
351 | // If this function is not called, the encoder will use default encode_speed | |
352 | // 0. Call this function before ComputeFirstPassStats() if needed. | |
353 | // The encode_speed is equivalent to --cpu-used of the vpxenc command. | |
354 | // The encode_speed's range should be [0, 9]. | |
355 | // Setting the encode_speed to a higher level will yield faster coding | |
356 | // at the cost of lower compression efficiency. | |
357 | void SetEncodeSpeed(int encode_speed); | |
358 | ||
359 | // Set encoder config | |
360 | // The following configs in VP9EncoderConfig are allowed to change in this | |
361 | // function. See https://ffmpeg.org/ffmpeg-codecs.html#libvpx for each | |
362 | // config's meaning. | |
363 | // Configs in VP9EncoderConfig: Equivalent configs in ffmpeg: | |
364 | // 1 key_freq -g | |
365 | // 2 two_pass_vbrmin_section -minrate * 100LL / bit_rate | |
366 | // 3 two_pass_vbrmax_section -maxrate * 100LL / bit_rate | |
367 | // 4 under_shoot_pct -undershoot-pct | |
368 | // 5 over_shoot_pct -overshoot-pct | |
369 | // 6 max_threads -threads | |
370 | // 7 frame_parallel_decoding_mode -frame-parallel | |
371 | // 8 tile_column -tile-columns | |
372 | // 9 arnr_max_frames -arnr-maxframes | |
373 | // 10 arnr_strength -arnr-strength | |
374 | // 11 lag_in_frames -rc_lookahead | |
375 | // 12 encode_breakout -static-thresh | |
376 | // 13 enable_tpl_model -enable-tpl | |
377 | // 14 enable_auto_arf -auto-alt-ref | |
378 | // 15 rc_mode | |
379 | // Possible Settings: | |
380 | // 0 - Variable Bit Rate (VPX_VBR) -b:v <bit_rate> | |
381 | // 1 - Constant Bit Rate (VPX_CBR) -b:v <bit_rate> -minrate <bit_rate> | |
382 | // -maxrate <bit_rate> | |
383 | // two_pass_vbrmin_section == 100 i.e. bit_rate == minrate == maxrate | |
384 | // two_pass_vbrmax_section == 100 | |
385 | // 2 - Constrained Quality (VPX_CQ) -crf <cq_level> -b:v bit_rate | |
386 | // 3 - Constant Quality (VPX_Q) -crf <cq_level> -b:v 0 | |
387 | // See https://trac.ffmpeg.org/wiki/Encode/VP9 for more details. | |
388 | // 16 cq_level see rc_mode for details. | |
389 | StatusCode SetEncodeConfig(const char *name, const char *value); | |
390 | ||
391 | // A debug function that dumps configs from VP9EncoderConfig | |
392 | // pass = 1: first pass, pass = 2: second pass | |
393 | // fp: file pointer for dumping config | |
394 | StatusCode DumpEncodeConfigs(int pass, FILE *fp); | |
395 | ||
306 | 396 | // Makes encoder compute the first pass stats and store it at |
307 | 397 | // impl_ptr_->first_pass_stats. key_frame_map_ is also computed based on the |
308 | 398 | // first pass stats. |
313 | 403 | // each video frame. The stats of each video frame is a vector of 25 double |
314 | 404 | // values. For details, please check FIRSTPASS_STATS in vp9_firstpass.h |
315 | 405 | std::vector<std::vector<double>> ObserveFirstPassStats(); |
406 | ||
407 | // Outputs the first pass motion vectors represented by a 2-D vector. | |
408 | // One can use the frame index at first dimension to retrieve the mvs for | |
409 | // each video frame. The frame is divided into 16x16 blocks. The number of | |
410 | // elements is round_up(|num_rows_4x4| / 4) * round_up(|num_cols_4x4| / 4). | |
411 | std::vector<std::vector<MotionVectorInfo>> ObserveFirstPassMotionVectors(); | |
316 | 412 | |
317 | 413 | // Ouputs a copy of key_frame_map_, a binary vector with size equal to the |
318 | 414 | // number of show frames in the video. For each entry in the vector, 1 |
334 | 430 | // constraints. |
335 | 431 | // 1) Each key frame position should be at the start of a gop. |
336 | 432 | // 2) The last gop should not use an alt ref. |
337 | void SetExternalGroupOfPicturesMap(std::vector<int> gop_map); | |
433 | void SetExternalGroupOfPicturesMap(int *gop_map, int gop_map_size); | |
338 | 434 | |
339 | 435 | // Observe the group of pictures map set through |
340 | 436 | // SetExternalGroupOfPicturesMap(). This function should be called after |
371 | 467 | // This function should be called after StartEncode() and before EndEncode(). |
372 | 468 | void EncodeFrameWithQuantizeIndex(EncodeFrameResult *encode_frame_result, |
373 | 469 | int quantize_index); |
470 | ||
471 | // Encode a frame with target frame bits usage. | |
472 | // The encoder will find a quantize index to make the actual frame bits usage | |
473 | // match the target. EncodeFrameWithTargetFrameBits() will recode the frame | |
474 | // up to 7 times to find a q_index to make the actual_frame_bits satisfy the | |
475 | // following inequality. |actual_frame_bits - target_frame_bits| * 100 / | |
476 | // target_frame_bits | |
477 | // <= percent_diff. | |
478 | void EncodeFrameWithTargetFrameBits(EncodeFrameResult *encode_frame_result, | |
479 | int target_frame_bits, | |
480 | double percent_diff); | |
374 | 481 | |
375 | 482 | // Gets the number of coding frames for the video. The coding frames include |
376 | 483 | // show frame and no show frame. |
404 | 511 | int frame_rate_den_; |
405 | 512 | int target_bitrate_; |
406 | 513 | int num_frames_; |
514 | int encode_speed_; | |
407 | 515 | |
408 | 516 | std::FILE *in_file_; |
409 | 517 | std::FILE *out_file_; |
434 | 542 | // frame appears? |
435 | 543 | // Reference frames info of the to-be-coded frame. |
436 | 544 | RefFrameInfo ref_frame_info_; |
545 | ||
546 | // A 2-D vector of motion vector information of the frame collected | |
547 | // from the first pass. The first dimension is the frame index. | |
548 | // Each frame is divided into 16x16 blocks. The number of elements is | |
549 | // round_up(|num_rows_4x4| / 4) * round_up(|num_cols_4x4| / 4). | |
550 | // Each 16x16 block contains 0 motion vector if this is an intra predicted | |
551 | // frame (for example, the key frame). If the frame is inter predicted, | |
552 | // each 16x16 block contains either 1 or 2 motion vectors. | |
553 | // The first motion vector is always from the LAST_FRAME. | |
554 | // The second motion vector is always from the GOLDEN_FRAME. | |
555 | std::vector<std::vector<MotionVectorInfo>> fp_motion_vector_info_; | |
437 | 556 | }; |
438 | 557 | |
439 | 558 | } // namespace vp9 |
12 | 12 | |
13 | 13 | #include "./vpx_config.h" |
14 | 14 | #include "vpx/vpx_encoder.h" |
15 | #include "vpx/vpx_ext_ratectrl.h" | |
15 | 16 | #include "vpx_dsp/psnr.h" |
16 | 17 | #include "vpx_ports/vpx_once.h" |
17 | 18 | #include "vpx_ports/static_assert.h" |
632 | 633 | } |
633 | 634 | |
634 | 635 | if (get_level_index(oxcf->target_level) >= 0) config_target_level(oxcf); |
635 | // vp9_dump_encoder_config(oxcf); | |
636 | // vp9_dump_encoder_config(oxcf, stderr); | |
636 | 637 | return VPX_CODEC_OK; |
637 | 638 | } |
638 | 639 | |
1571 | 1572 | lc->scaling_factor_num = params->scaling_factor_num[sl]; |
1572 | 1573 | lc->scaling_factor_den = params->scaling_factor_den[sl]; |
1573 | 1574 | lc->speed = params->speed_per_layer[sl]; |
1575 | lc->loopfilter_ctrl = params->loopfilter_ctrl[sl]; | |
1574 | 1576 | } |
1575 | 1577 | } |
1576 | 1578 | |
1712 | 1714 | VP9_COMP *const cpi = ctx->cpi; |
1713 | 1715 | const unsigned int data = va_arg(args, unsigned int); |
1714 | 1716 | cpi->rc.ext_use_post_encode_drop = data; |
1717 | return VPX_CODEC_OK; | |
1718 | } | |
1719 | ||
1720 | static vpx_codec_err_t ctrl_set_disable_overshoot_maxq_cbr( | |
1721 | vpx_codec_alg_priv_t *ctx, va_list args) { | |
1722 | VP9_COMP *const cpi = ctx->cpi; | |
1723 | const unsigned int data = va_arg(args, unsigned int); | |
1724 | cpi->rc.disable_overshoot_maxq_cbr = data; | |
1725 | return VPX_CODEC_OK; | |
1726 | } | |
1727 | ||
1728 | static vpx_codec_err_t ctrl_set_disable_loopfilter(vpx_codec_alg_priv_t *ctx, | |
1729 | va_list args) { | |
1730 | VP9_COMP *const cpi = ctx->cpi; | |
1731 | const unsigned int data = va_arg(args, unsigned int); | |
1732 | cpi->loopfilter_ctrl = data; | |
1733 | return VPX_CODEC_OK; | |
1734 | } | |
1735 | ||
1736 | static vpx_codec_err_t ctrl_set_external_rate_control(vpx_codec_alg_priv_t *ctx, | |
1737 | va_list args) { | |
1738 | vpx_rc_funcs_t funcs = *CAST(VP9E_SET_EXTERNAL_RATE_CONTROL, args); | |
1739 | VP9_COMP *cpi = ctx->cpi; | |
1740 | EXT_RATECTRL *ext_ratectrl = &cpi->ext_ratectrl; | |
1741 | const VP9EncoderConfig *oxcf = &cpi->oxcf; | |
1742 | // TODO(angiebird): Check the possibility of this flag being set at pass == 1 | |
1743 | if (oxcf->pass == 2) { | |
1744 | const FRAME_INFO *frame_info = &cpi->frame_info; | |
1745 | vpx_rc_config_t ratectrl_config; | |
1746 | vpx_codec_err_t codec_status; | |
1747 | ||
1748 | ratectrl_config.frame_width = frame_info->frame_width; | |
1749 | ratectrl_config.frame_height = frame_info->frame_height; | |
1750 | ratectrl_config.show_frame_count = cpi->twopass.first_pass_info.num_frames; | |
1751 | ||
1752 | // TODO(angiebird): Double check whether this is the proper way to set up | |
1753 | // target_bitrate and frame_rate. | |
1754 | ratectrl_config.target_bitrate_kbps = (int)(oxcf->target_bandwidth / 1000); | |
1755 | ratectrl_config.frame_rate_num = oxcf->g_timebase.den; | |
1756 | ratectrl_config.frame_rate_den = oxcf->g_timebase.num; | |
1757 | ||
1758 | codec_status = vp9_extrc_create(funcs, ratectrl_config, ext_ratectrl); | |
1759 | if (codec_status != VPX_CODEC_OK) { | |
1760 | return codec_status; | |
1761 | } | |
1762 | } | |
1715 | 1763 | return VPX_CODEC_OK; |
1716 | 1764 | } |
1717 | 1765 | |
1759 | 1807 | { VP9E_SET_TARGET_LEVEL, ctrl_set_target_level }, |
1760 | 1808 | { VP9E_SET_ROW_MT, ctrl_set_row_mt }, |
1761 | 1809 | { VP9E_SET_POSTENCODE_DROP, ctrl_set_postencode_drop }, |
1810 | { VP9E_SET_DISABLE_OVERSHOOT_MAXQ_CBR, ctrl_set_disable_overshoot_maxq_cbr }, | |
1762 | 1811 | { VP9E_ENABLE_MOTION_VECTOR_UNIT_TEST, ctrl_enable_motion_vector_unit_test }, |
1763 | 1812 | { VP9E_SET_SVC_INTER_LAYER_PRED, ctrl_set_svc_inter_layer_pred }, |
1764 | 1813 | { VP9E_SET_SVC_FRAME_DROP_LAYER, ctrl_set_svc_frame_drop_layer }, |
1765 | 1814 | { VP9E_SET_SVC_GF_TEMPORAL_REF, ctrl_set_svc_gf_temporal_ref }, |
1766 | 1815 | { VP9E_SET_SVC_SPATIAL_LAYER_SYNC, ctrl_set_svc_spatial_layer_sync }, |
1767 | 1816 | { VP9E_SET_DELTA_Q_UV, ctrl_set_delta_q_uv }, |
1817 | { VP9E_SET_DISABLE_LOOPFILTER, ctrl_set_disable_loopfilter }, | |
1818 | { VP9E_SET_EXTERNAL_RATE_CONTROL, ctrl_set_external_rate_control }, | |
1768 | 1819 | |
1769 | 1820 | // Getters |
1770 | 1821 | { VP8E_GET_LAST_QUANTIZER, ctrl_get_quantizer }, |
1898 | 1949 | |
1899 | 1950 | VP9EncoderConfig vp9_get_encoder_config(int frame_width, int frame_height, |
1900 | 1951 | vpx_rational_t frame_rate, |
1901 | int target_bitrate, | |
1952 | int target_bitrate, int encode_speed, | |
1902 | 1953 | vpx_enc_pass enc_pass) { |
1903 | 1954 | /* This function will generate the same VP9EncoderConfig used by the |
1904 | 1955 | * vpxenc command given below. |
1909 | 1960 | * HEIGHT: frame_height |
1910 | 1961 | * FPS: frame_rate |
1911 | 1962 | * BITRATE: target_bitrate |
1963 | * CPU_USED:encode_speed | |
1912 | 1964 | * |
1913 | 1965 | * INPUT, OUTPUT, LIMIT will not affect VP9EncoderConfig |
1914 | 1966 | * |
1920 | 1972 | * BITRATE=600 |
1921 | 1973 | * FPS=30/1 |
1922 | 1974 | * LIMIT=150 |
1975 | * CPU_USED=0 | |
1923 | 1976 | * ./vpxenc --limit=$LIMIT --width=$WIDTH --height=$HEIGHT --fps=$FPS |
1924 | 1977 | * --lag-in-frames=25 \ |
1925 | * --codec=vp9 --good --cpu-used=0 --threads=0 --profile=0 \ | |
1978 | * --codec=vp9 --good --cpu-used=CPU_USED --threads=0 --profile=0 \ | |
1926 | 1979 | * --min-q=0 --max-q=63 --auto-alt-ref=1 --passes=2 --kf-max-dist=150 \ |
1927 | 1980 | * --kf-min-dist=0 --drop-frame=0 --static-thresh=0 --bias-pct=50 \ |
1928 | 1981 | * --minsection-pct=0 --maxsection-pct=150 --arnr-maxframes=7 --psnr \ |
1945 | 1998 | oxcf.tile_columns = 0; |
1946 | 1999 | oxcf.frame_parallel_decoding_mode = 0; |
1947 | 2000 | oxcf.two_pass_vbrmax_section = 150; |
2001 | oxcf.speed = abs(encode_speed); | |
1948 | 2002 | return oxcf; |
1949 | 2003 | } |
1950 | 2004 | |
1951 | #define DUMP_STRUCT_VALUE(struct, value) \ | |
1952 | printf(#value " %" PRId64 "\n", (int64_t)(struct)->value) | |
1953 | ||
1954 | void vp9_dump_encoder_config(const VP9EncoderConfig *oxcf) { | |
1955 | DUMP_STRUCT_VALUE(oxcf, profile); | |
1956 | DUMP_STRUCT_VALUE(oxcf, bit_depth); | |
1957 | DUMP_STRUCT_VALUE(oxcf, width); | |
1958 | DUMP_STRUCT_VALUE(oxcf, height); | |
1959 | DUMP_STRUCT_VALUE(oxcf, input_bit_depth); | |
1960 | DUMP_STRUCT_VALUE(oxcf, init_framerate); | |
2005 | #define DUMP_STRUCT_VALUE(fp, structure, value) \ | |
2006 | fprintf(fp, #value " %" PRId64 "\n", (int64_t)(structure)->value) | |
2007 | ||
2008 | void vp9_dump_encoder_config(const VP9EncoderConfig *oxcf, FILE *fp) { | |
2009 | DUMP_STRUCT_VALUE(fp, oxcf, profile); | |
2010 | DUMP_STRUCT_VALUE(fp, oxcf, bit_depth); | |
2011 | DUMP_STRUCT_VALUE(fp, oxcf, width); | |
2012 | DUMP_STRUCT_VALUE(fp, oxcf, height); | |
2013 | DUMP_STRUCT_VALUE(fp, oxcf, input_bit_depth); | |
2014 | DUMP_STRUCT_VALUE(fp, oxcf, init_framerate); | |
1961 | 2015 | // TODO(angiebird): dump g_timebase |
1962 | 2016 | // TODO(angiebird): dump g_timebase_in_ts |
1963 | 2017 | |
1964 | DUMP_STRUCT_VALUE(oxcf, target_bandwidth); | |
1965 | ||
1966 | DUMP_STRUCT_VALUE(oxcf, noise_sensitivity); | |
1967 | DUMP_STRUCT_VALUE(oxcf, sharpness); | |
1968 | DUMP_STRUCT_VALUE(oxcf, speed); | |
1969 | DUMP_STRUCT_VALUE(oxcf, rc_max_intra_bitrate_pct); | |
1970 | DUMP_STRUCT_VALUE(oxcf, rc_max_inter_bitrate_pct); | |
1971 | DUMP_STRUCT_VALUE(oxcf, gf_cbr_boost_pct); | |
1972 | ||
1973 | DUMP_STRUCT_VALUE(oxcf, mode); | |
1974 | DUMP_STRUCT_VALUE(oxcf, pass); | |
2018 | DUMP_STRUCT_VALUE(fp, oxcf, target_bandwidth); | |
2019 | ||
2020 | DUMP_STRUCT_VALUE(fp, oxcf, noise_sensitivity); | |
2021 | DUMP_STRUCT_VALUE(fp, oxcf, sharpness); | |
2022 | DUMP_STRUCT_VALUE(fp, oxcf, speed); | |
2023 | DUMP_STRUCT_VALUE(fp, oxcf, rc_max_intra_bitrate_pct); | |
2024 | DUMP_STRUCT_VALUE(fp, oxcf, rc_max_inter_bitrate_pct); | |
2025 | DUMP_STRUCT_VALUE(fp, oxcf, gf_cbr_boost_pct); | |
2026 | ||
2027 | DUMP_STRUCT_VALUE(fp, oxcf, mode); | |
2028 | DUMP_STRUCT_VALUE(fp, oxcf, pass); | |
1975 | 2029 | |
1976 | 2030 | // Key Framing Operations |
1977 | DUMP_STRUCT_VALUE(oxcf, auto_key); | |
1978 | DUMP_STRUCT_VALUE(oxcf, key_freq); | |
1979 | ||
1980 | DUMP_STRUCT_VALUE(oxcf, lag_in_frames); | |
2031 | DUMP_STRUCT_VALUE(fp, oxcf, auto_key); | |
2032 | DUMP_STRUCT_VALUE(fp, oxcf, key_freq); | |
2033 | ||
2034 | DUMP_STRUCT_VALUE(fp, oxcf, lag_in_frames); | |
1981 | 2035 | |
1982 | 2036 | // ---------------------------------------------------------------- |
1983 | 2037 | // DATARATE CONTROL OPTIONS |
1984 | 2038 | |
1985 | 2039 | // vbr, cbr, constrained quality or constant quality |
1986 | DUMP_STRUCT_VALUE(oxcf, rc_mode); | |
2040 | DUMP_STRUCT_VALUE(fp, oxcf, rc_mode); | |
1987 | 2041 | |
1988 | 2042 | // buffer targeting aggressiveness |
1989 | DUMP_STRUCT_VALUE(oxcf, under_shoot_pct); | |
1990 | DUMP_STRUCT_VALUE(oxcf, over_shoot_pct); | |
2043 | DUMP_STRUCT_VALUE(fp, oxcf, under_shoot_pct); | |
2044 | DUMP_STRUCT_VALUE(fp, oxcf, over_shoot_pct); | |
1991 | 2045 | |
1992 | 2046 | // buffering parameters |
1993 | 2047 | // TODO(angiebird): dump tarting_buffer_level_ms |
1995 | 2049 | // TODO(angiebird): dump maximum_buffer_size_ms |
1996 | 2050 | |
1997 | 2051 | // Frame drop threshold. |
1998 | DUMP_STRUCT_VALUE(oxcf, drop_frames_water_mark); | |
2052 | DUMP_STRUCT_VALUE(fp, oxcf, drop_frames_water_mark); | |
1999 | 2053 | |
2000 | 2054 | // controlling quality |
2001 | DUMP_STRUCT_VALUE(oxcf, fixed_q); | |
2002 | DUMP_STRUCT_VALUE(oxcf, worst_allowed_q); | |
2003 | DUMP_STRUCT_VALUE(oxcf, best_allowed_q); | |
2004 | DUMP_STRUCT_VALUE(oxcf, cq_level); | |
2005 | DUMP_STRUCT_VALUE(oxcf, aq_mode); | |
2055 | DUMP_STRUCT_VALUE(fp, oxcf, fixed_q); | |
2056 | DUMP_STRUCT_VALUE(fp, oxcf, worst_allowed_q); | |
2057 | DUMP_STRUCT_VALUE(fp, oxcf, best_allowed_q); | |
2058 | DUMP_STRUCT_VALUE(fp, oxcf, cq_level); | |
2059 | DUMP_STRUCT_VALUE(fp, oxcf, aq_mode); | |
2006 | 2060 | |
2007 | 2061 | // Special handling of Adaptive Quantization for AltRef frames |
2008 | DUMP_STRUCT_VALUE(oxcf, alt_ref_aq); | |
2062 | DUMP_STRUCT_VALUE(fp, oxcf, alt_ref_aq); | |
2009 | 2063 | |
2010 | 2064 | // Internal frame size scaling. |
2011 | DUMP_STRUCT_VALUE(oxcf, resize_mode); | |
2012 | DUMP_STRUCT_VALUE(oxcf, scaled_frame_width); | |
2013 | DUMP_STRUCT_VALUE(oxcf, scaled_frame_height); | |
2065 | DUMP_STRUCT_VALUE(fp, oxcf, resize_mode); | |
2066 | DUMP_STRUCT_VALUE(fp, oxcf, scaled_frame_width); | |
2067 | DUMP_STRUCT_VALUE(fp, oxcf, scaled_frame_height); | |
2014 | 2068 | |
2015 | 2069 | // Enable feature to reduce the frame quantization every x frames. |
2016 | DUMP_STRUCT_VALUE(oxcf, frame_periodic_boost); | |
2070 | DUMP_STRUCT_VALUE(fp, oxcf, frame_periodic_boost); | |
2017 | 2071 | |
2018 | 2072 | // two pass datarate control |
2019 | DUMP_STRUCT_VALUE(oxcf, two_pass_vbrbias); | |
2020 | DUMP_STRUCT_VALUE(oxcf, two_pass_vbrmin_section); | |
2021 | DUMP_STRUCT_VALUE(oxcf, two_pass_vbrmax_section); | |
2022 | DUMP_STRUCT_VALUE(oxcf, vbr_corpus_complexity); | |
2073 | DUMP_STRUCT_VALUE(fp, oxcf, two_pass_vbrbias); | |
2074 | DUMP_STRUCT_VALUE(fp, oxcf, two_pass_vbrmin_section); | |
2075 | DUMP_STRUCT_VALUE(fp, oxcf, two_pass_vbrmax_section); | |
2076 | DUMP_STRUCT_VALUE(fp, oxcf, vbr_corpus_complexity); | |
2023 | 2077 | // END DATARATE CONTROL OPTIONS |
2024 | 2078 | // ---------------------------------------------------------------- |
2025 | 2079 | |
2026 | 2080 | // Spatial and temporal scalability. |
2027 | DUMP_STRUCT_VALUE(oxcf, ss_number_layers); | |
2028 | DUMP_STRUCT_VALUE(oxcf, ts_number_layers); | |
2081 | DUMP_STRUCT_VALUE(fp, oxcf, ss_number_layers); | |
2082 | DUMP_STRUCT_VALUE(fp, oxcf, ts_number_layers); | |
2029 | 2083 | |
2030 | 2084 | // Bitrate allocation for spatial layers. |
2031 | 2085 | // TODO(angiebird): dump layer_target_bitrate[VPX_MAX_LAYERS] |
2033 | 2087 | // TODO(angiebird): dump ss_enable_auto_arf[VPX_SS_MAX_LAYERS] |
2034 | 2088 | // TODO(angiebird): dump ts_rate_decimator[VPX_TS_MAX_LAYERS] |
2035 | 2089 | |
2036 | DUMP_STRUCT_VALUE(oxcf, enable_auto_arf); | |
2037 | DUMP_STRUCT_VALUE(oxcf, encode_breakout); | |
2038 | DUMP_STRUCT_VALUE(oxcf, error_resilient_mode); | |
2039 | DUMP_STRUCT_VALUE(oxcf, frame_parallel_decoding_mode); | |
2040 | ||
2041 | DUMP_STRUCT_VALUE(oxcf, arnr_max_frames); | |
2042 | DUMP_STRUCT_VALUE(oxcf, arnr_strength); | |
2043 | ||
2044 | DUMP_STRUCT_VALUE(oxcf, min_gf_interval); | |
2045 | DUMP_STRUCT_VALUE(oxcf, max_gf_interval); | |
2046 | ||
2047 | DUMP_STRUCT_VALUE(oxcf, tile_columns); | |
2048 | DUMP_STRUCT_VALUE(oxcf, tile_rows); | |
2049 | ||
2050 | DUMP_STRUCT_VALUE(oxcf, enable_tpl_model); | |
2051 | ||
2052 | DUMP_STRUCT_VALUE(oxcf, max_threads); | |
2053 | ||
2054 | DUMP_STRUCT_VALUE(oxcf, target_level); | |
2090 | DUMP_STRUCT_VALUE(fp, oxcf, enable_auto_arf); | |
2091 | DUMP_STRUCT_VALUE(fp, oxcf, encode_breakout); | |
2092 | DUMP_STRUCT_VALUE(fp, oxcf, error_resilient_mode); | |
2093 | DUMP_STRUCT_VALUE(fp, oxcf, frame_parallel_decoding_mode); | |
2094 | ||
2095 | DUMP_STRUCT_VALUE(fp, oxcf, arnr_max_frames); | |
2096 | DUMP_STRUCT_VALUE(fp, oxcf, arnr_strength); | |
2097 | ||
2098 | DUMP_STRUCT_VALUE(fp, oxcf, min_gf_interval); | |
2099 | DUMP_STRUCT_VALUE(fp, oxcf, max_gf_interval); | |
2100 | ||
2101 | DUMP_STRUCT_VALUE(fp, oxcf, tile_columns); | |
2102 | DUMP_STRUCT_VALUE(fp, oxcf, tile_rows); | |
2103 | ||
2104 | DUMP_STRUCT_VALUE(fp, oxcf, enable_tpl_model); | |
2105 | ||
2106 | DUMP_STRUCT_VALUE(fp, oxcf, max_threads); | |
2107 | ||
2108 | DUMP_STRUCT_VALUE(fp, oxcf, target_level); | |
2055 | 2109 | |
2056 | 2110 | // TODO(angiebird): dump two_pass_stats_in |
2057 | 2111 | |
2059 | 2113 | // TODO(angiebird): dump firstpass_mb_stats_in |
2060 | 2114 | #endif |
2061 | 2115 | |
2062 | DUMP_STRUCT_VALUE(oxcf, tuning); | |
2063 | DUMP_STRUCT_VALUE(oxcf, content); | |
2116 | DUMP_STRUCT_VALUE(fp, oxcf, tuning); | |
2117 | DUMP_STRUCT_VALUE(fp, oxcf, content); | |
2064 | 2118 | #if CONFIG_VP9_HIGHBITDEPTH |
2065 | DUMP_STRUCT_VALUE(oxcf, use_highbitdepth); | |
2119 | DUMP_STRUCT_VALUE(fp, oxcf, use_highbitdepth); | |
2066 | 2120 | #endif |
2067 | DUMP_STRUCT_VALUE(oxcf, color_space); | |
2068 | DUMP_STRUCT_VALUE(oxcf, color_range); | |
2069 | DUMP_STRUCT_VALUE(oxcf, render_width); | |
2070 | DUMP_STRUCT_VALUE(oxcf, render_height); | |
2071 | DUMP_STRUCT_VALUE(oxcf, temporal_layering_mode); | |
2072 | ||
2073 | DUMP_STRUCT_VALUE(oxcf, row_mt); | |
2074 | DUMP_STRUCT_VALUE(oxcf, motion_vector_unit_test); | |
2121 | DUMP_STRUCT_VALUE(fp, oxcf, color_space); | |
2122 | DUMP_STRUCT_VALUE(fp, oxcf, color_range); | |
2123 | DUMP_STRUCT_VALUE(fp, oxcf, render_width); | |
2124 | DUMP_STRUCT_VALUE(fp, oxcf, render_height); | |
2125 | DUMP_STRUCT_VALUE(fp, oxcf, temporal_layering_mode); | |
2126 | ||
2127 | DUMP_STRUCT_VALUE(fp, oxcf, row_mt); | |
2128 | DUMP_STRUCT_VALUE(fp, oxcf, motion_vector_unit_test); | |
2075 | 2129 | } |
2076 | 2130 | |
2077 | 2131 | FRAME_INFO vp9_get_frame_info(const VP9EncoderConfig *oxcf) { |
18 | 18 | |
19 | 19 | VP9EncoderConfig vp9_get_encoder_config(int frame_width, int frame_height, |
20 | 20 | vpx_rational_t frame_rate, |
21 | int target_bitrate, | |
21 | int target_bitrate, int encode_speed, | |
22 | 22 | vpx_enc_pass enc_pass); |
23 | 23 | |
24 | void vp9_dump_encoder_config(const VP9EncoderConfig *oxcf); | |
24 | void vp9_dump_encoder_config(const VP9EncoderConfig *oxcf, FILE *fp); | |
25 | 25 | |
26 | 26 | FRAME_INFO vp9_get_frame_info(const VP9EncoderConfig *oxcf); |
27 | 27 |
95 | 95 | VP9_CX_SRCS-yes += encoder/vp9_skin_detection.h |
96 | 96 | VP9_CX_SRCS-yes += encoder/vp9_noise_estimate.c |
97 | 97 | VP9_CX_SRCS-yes += encoder/vp9_noise_estimate.h |
98 | VP9_CX_SRCS-yes += encoder/vp9_ext_ratectrl.c | |
99 | VP9_CX_SRCS-yes += encoder/vp9_ext_ratectrl.h | |
98 | 100 | ifeq ($(CONFIG_VP9_POSTPROC),yes) |
99 | 101 | VP9_CX_SRCS-$(CONFIG_INTERNAL_STATS) += common/vp9_postproc.h |
100 | 102 | VP9_CX_SRCS-$(CONFIG_INTERNAL_STATS) += common/vp9_postproc.c |
16 | 16 | */ |
17 | 17 | #include "./vp8.h" |
18 | 18 | #include "./vpx_encoder.h" |
19 | #include "./vpx_ext_ratectrl.h" | |
19 | 20 | |
20 | 21 | /*!\file |
21 | 22 | * \brief Provides definitions for using VP8 or VP9 encoder algorithm within the |
683 | 684 | * Supported in codecs: VP9 |
684 | 685 | */ |
685 | 686 | VP9E_SET_DELTA_Q_UV, |
687 | ||
688 | /*!\brief Codec control function to disable increase Q on overshoot in CBR. | |
689 | * | |
690 | * 0: On (default), 1: Disable. | |
691 | * | |
692 | * Supported in codecs: VP9 | |
693 | */ | |
694 | VP9E_SET_DISABLE_OVERSHOOT_MAXQ_CBR, | |
695 | ||
696 | /*!\brief Codec control function to disable loopfilter. | |
697 | * | |
698 | * 0: Loopfilter on all frames, 1: Disable on non reference frames. | |
699 | * 2: Disable on all frames. | |
700 | * | |
701 | * Supported in codecs: VP9 | |
702 | */ | |
703 | VP9E_SET_DISABLE_LOOPFILTER, | |
704 | ||
705 | /*!\brief Codec control function to enable external rate control library. | |
706 | * | |
707 | * args[0]: path of the rate control library | |
708 | * | |
709 | * args[1]: private config of the rate control library | |
710 | * | |
711 | * Supported in codecs: VP9 | |
712 | */ | |
713 | VP9E_SET_EXTERNAL_RATE_CONTROL, | |
686 | 714 | }; |
687 | 715 | |
688 | 716 | /*!\brief vpx 1-D scaling mode |
1033 | 1061 | VPX_CTRL_USE_TYPE(VP9E_SET_DELTA_Q_UV, int) |
1034 | 1062 | #define VPX_CTRL_VP9E_SET_DELTA_Q_UV |
1035 | 1063 | |
1064 | VPX_CTRL_USE_TYPE(VP9E_SET_DISABLE_OVERSHOOT_MAXQ_CBR, int) | |
1065 | #define VPX_CTRL_VP9E_SET_DISABLE_OVERSHOOT_MAXQ_CBR | |
1066 | ||
1067 | VPX_CTRL_USE_TYPE(VP9E_SET_DISABLE_LOOPFILTER, int) | |
1068 | #define VPX_CTRL_VP9E_SET_DISABLE_LOOPFILTER | |
1069 | ||
1070 | VPX_CTRL_USE_TYPE(VP9E_SET_EXTERNAL_RATE_CONTROL, vpx_rc_funcs_t *) | |
1071 | #define VPX_CTRL_VP9E_SET_EXTERNAL_RATE_CONTROL | |
1072 | ||
1036 | 1073 | /*!\endcond */ |
1037 | 1074 | /*! @} - end defgroup vp8_encoder */ |
1038 | 1075 | #ifdef __cplusplus |
23 | 23 | API_DOC_SRCS-yes += vpx_codec.h |
24 | 24 | API_DOC_SRCS-yes += vpx_decoder.h |
25 | 25 | API_DOC_SRCS-yes += vpx_encoder.h |
26 | API_DOC_SRCS-yes += vpx_ext_ratectrl.h | |
26 | 27 | API_DOC_SRCS-yes += vpx_frame_buffer.h |
27 | 28 | API_DOC_SRCS-yes += vpx_image.h |
28 | 29 | |
38 | 39 | API_SRCS-yes += vpx_frame_buffer.h |
39 | 40 | API_SRCS-yes += vpx_image.h |
40 | 41 | API_SRCS-yes += vpx_integer.h |
42 | API_SRCS-yes += vpx_ext_ratectrl.h |
29 | 29 | #endif |
30 | 30 | |
31 | 31 | #include "./vpx_codec.h" |
32 | #include "./vpx_ext_ratectrl.h" | |
32 | 33 | |
33 | 34 | /*! Temporal Scalability: Maximum length of the sequence defining frame |
34 | 35 | * layer membership |
56 | 57 | * fields to structures |
57 | 58 | */ |
58 | 59 | #define VPX_ENCODER_ABI_VERSION \ |
59 | (14 + VPX_CODEC_ABI_VERSION) /**<\hideinitializer*/ | |
60 | (14 + VPX_CODEC_ABI_VERSION + \ | |
61 | VPX_EXT_RATECTRL_ABI_VERSION) /**<\hideinitializer*/ | |
60 | 62 | |
61 | 63 | /*! \brief Encoder capabilities bitfield |
62 | 64 | * |
704 | 706 | int scaling_factor_den[VPX_MAX_LAYERS]; /**< Scaling factor-denominator */ |
705 | 707 | int speed_per_layer[VPX_MAX_LAYERS]; /**< Speed setting for each sl */ |
706 | 708 | int temporal_layering_mode; /**< Temporal layering mode */ |
709 | int loopfilter_ctrl[VPX_MAX_LAYERS]; /**< Loopfilter ctrl for each sl */ | |
707 | 710 | } vpx_svc_extra_cfg_t; |
708 | 711 | |
709 | 712 | /*!\brief Initialize an encoder instance |
0 | /* | |
1 | * Copyright (c) 2020 The WebM project authors. All Rights Reserved. | |
2 | * | |
3 | * Use of this source code is governed by a BSD-style license | |
4 | * that can be found in the LICENSE file in the root of the source | |
5 | * tree. An additional intellectual property rights grant can be found | |
6 | * in the file PATENTS. All contributing project authors may | |
7 | * be found in the AUTHORS file in the root of the source tree. | |
8 | */ | |
9 | ||
10 | #ifndef VPX_VPX_VPX_EXT_RATECTRL_H_ | |
11 | #define VPX_VPX_VPX_EXT_RATECTRL_H_ | |
12 | ||
13 | #ifdef __cplusplus | |
14 | extern "C" { | |
15 | #endif | |
16 | ||
17 | #include "./vpx_integer.h" | |
18 | ||
19 | /*!\brief Current ABI version number | |
20 | * | |
21 | * \internal | |
22 | * If this file is altered in any way that changes the ABI, this value | |
23 | * must be bumped. Examples include, but are not limited to, changing | |
24 | * types, removing or reassigning enums, adding/removing/rearranging | |
25 | * fields to structures. | |
26 | */ | |
27 | #define VPX_EXT_RATECTRL_ABI_VERSION (1) | |
28 | ||
29 | /*!\brief Abstract rate control model handler | |
30 | * | |
31 | * The encoder will receive the model handler from create_model() defined in | |
32 | * vpx_rc_funcs_t. | |
33 | */ | |
34 | typedef void *vpx_rc_model_t; | |
35 | ||
36 | /*!\brief Encode frame decision made by the external rate control model | |
37 | * | |
38 | * The encoder will receive the decision from the external rate control model | |
39 | * through get_encodeframe_decision() defined in vpx_rc_funcs_t. | |
40 | * | |
41 | * If max_frame_size = 0, the encoding ignores max frame size limit. | |
42 | * If max_frame_size = -1, the encoding uses VP9's max frame size as the limit. | |
43 | * If the encoded frame size is larger than max_frame_size, the frame is | |
44 | * recoded to meet the size limit, following VP9's recoding principles. | |
45 | */ | |
46 | typedef struct vpx_rc_encodeframe_decision { | |
47 | int q_index; /**< Quantizer step index [0..255]*/ | |
48 | int max_frame_size; /**< Maximal frame size allowed to encode a frame*/ | |
49 | } vpx_rc_encodeframe_decision_t; | |
50 | ||
51 | /*!\brief Information for the frame to be encoded. | |
52 | * | |
53 | * The encoder will send the information to external rate control model through | |
54 | * get_encodeframe_decision() defined in vpx_rc_funcs_t. | |
55 | * | |
56 | */ | |
57 | typedef struct vpx_rc_encodeframe_info { | |
58 | /*! | |
59 | * 0: Key frame | |
60 | * 1: Inter frame | |
61 | * 2: Alternate reference frame | |
62 | * 3: Overlay frame | |
63 | * 4: Golden frame | |
64 | */ | |
65 | int frame_type; | |
66 | int show_index; /**< display index, starts from zero*/ | |
67 | int coding_index; /**< coding index, starts from zero*/ | |
68 | /*! | |
69 | * index in group of picture, starts from zero. | |
70 | */ | |
71 | int gop_index; | |
72 | int ref_frame_coding_indexes[3]; /**< three reference frames' coding indices*/ | |
73 | /*! | |
74 | * The validity of the three reference frames. | |
75 | * 0: Invalid | |
76 | * 1: Valid | |
77 | */ | |
78 | int ref_frame_valid_list[3]; | |
79 | } vpx_rc_encodeframe_info_t; | |
80 | ||
81 | /*!\brief Frame coding result | |
82 | * | |
83 | * The encoder will send the result to the external rate control model through | |
84 | * update_encodeframe_result() defined in vpx_rc_funcs_t. | |
85 | */ | |
86 | typedef struct vpx_rc_encodeframe_result { | |
87 | int64_t sse; /**< sum of squared error of the reconstructed frame */ | |
88 | int64_t bit_count; /**< number of bits spent on coding the frame*/ | |
89 | int64_t pixel_count; /**< number of pixels in YUV planes of the frame*/ | |
90 | int actual_encoding_qindex; /**< the actual qindex used to encode the frame*/ | |
91 | } vpx_rc_encodeframe_result_t; | |
92 | ||
93 | /*!\brief Status returned by rate control callback functions. | |
94 | */ | |
95 | typedef enum vpx_rc_status { | |
96 | VPX_RC_OK = 0, | |
97 | VPX_RC_ERROR = 1, | |
98 | } vpx_rc_status_t; | |
99 | ||
100 | /*!\brief First pass frame stats | |
101 | * This is a mirror of vp9's FIRSTPASS_STATS except that spatial_layer_id is | |
102 | * omitted | |
103 | */ | |
104 | typedef struct vpx_rc_frame_stats { | |
105 | /*! | |
106 | * Frame number in display order, if stats are for a single frame. | |
107 | * No real meaning for a collection of frames. | |
108 | */ | |
109 | double frame; | |
110 | /*! | |
111 | * Weight assigned to this frame (or total weight for the collection of | |
112 | * frames) currently based on intra factor and brightness factor. This is used | |
113 | * to distribute bits between easier and harder frames. | |
114 | */ | |
115 | double weight; | |
116 | /*! | |
117 | * Intra prediction error. | |
118 | */ | |
119 | double intra_error; | |
120 | /*! | |
121 | * Best of intra pred error and inter pred error using last frame as ref. | |
122 | */ | |
123 | double coded_error; | |
124 | /*! | |
125 | * Best of intra pred error and inter pred error using golden frame as ref. | |
126 | */ | |
127 | double sr_coded_error; | |
128 | /*! | |
129 | * Estimate the noise energy of the current frame. | |
130 | */ | |
131 | double frame_noise_energy; | |
132 | /*! | |
133 | * Percentage of blocks with inter pred error < intra pred error. | |
134 | */ | |
135 | double pcnt_inter; | |
136 | /*! | |
137 | * Percentage of blocks using (inter prediction and) non-zero motion vectors. | |
138 | */ | |
139 | double pcnt_motion; | |
140 | /*! | |
141 | * Percentage of blocks where golden frame was better than last or intra: | |
142 | * inter pred error using golden frame < inter pred error using last frame and | |
143 | * inter pred error using golden frame < intra pred error | |
144 | */ | |
145 | double pcnt_second_ref; | |
146 | /*! | |
147 | * Percentage of blocks where intra and inter prediction errors were very | |
148 | * close. | |
149 | */ | |
150 | double pcnt_neutral; | |
151 | /*! | |
152 | * Percentage of blocks that have intra error < inter error and inter error < | |
153 | * LOW_I_THRESH | |
154 | * - bit_depth 8: LOW_I_THRESH = 24000 | |
155 | * - bit_depth 10: LOW_I_THRESH = 24000 << 4 | |
156 | * - bit_depth 12: LOW_I_THRESH = 24000 << 8 | |
157 | */ | |
158 | double pcnt_intra_low; | |
159 | /*! | |
160 | * Percentage of blocks that have intra error < inter error and intra error < | |
161 | * LOW_I_THRESH but inter error >= LOW_I_THRESH LOW_I_THRESH | |
162 | * - bit_depth 8: LOW_I_THRESH = 24000 | |
163 | * - bit_depth 10: LOW_I_THRESH = 24000 << 4 | |
164 | * - bit_depth 12: LOW_I_THRESH = 24000 << 8 | |
165 | */ | |
166 | double pcnt_intra_high; | |
167 | /*! | |
168 | * Percentage of blocks that have almost no intra error residual | |
169 | * (i.e. are in effect completely flat and untextured in the intra | |
170 | * domain). In natural videos this is uncommon, but it is much more | |
171 | * common in animations, graphics and screen content, so may be used | |
172 | * as a signal to detect these types of content. | |
173 | */ | |
174 | double intra_skip_pct; | |
175 | /*! | |
176 | * Percentage of blocks that have intra error < SMOOTH_INTRA_THRESH | |
177 | * - bit_depth 8: SMOOTH_INTRA_THRESH = 4000 | |
178 | * - bit_depth 10: SMOOTH_INTRA_THRESH = 4000 << 4 | |
179 | * - bit_depth 12: SMOOTH_INTRA_THRESH = 4000 << 8 | |
180 | */ | |
181 | double intra_smooth_pct; | |
182 | /*! | |
183 | * Image mask rows top and bottom. | |
184 | */ | |
185 | double inactive_zone_rows; | |
186 | /*! | |
187 | * Image mask columns at left and right edges. | |
188 | */ | |
189 | double inactive_zone_cols; | |
190 | /*! | |
191 | * Mean of row motion vectors. | |
192 | */ | |
193 | double MVr; | |
194 | /*! | |
195 | * Mean of absolute value of row motion vectors. | |
196 | */ | |
197 | double mvr_abs; | |
198 | /*! | |
199 | * Mean of column motion vectors. | |
200 | */ | |
201 | double MVc; | |
202 | /*! | |
203 | * Mean of absolute value of column motion vectors. | |
204 | */ | |
205 | double mvc_abs; | |
206 | /*! | |
207 | * Variance of row motion vectors. | |
208 | */ | |
209 | double MVrv; | |
210 | /*! | |
211 | * Variance of column motion vectors. | |
212 | */ | |
213 | double MVcv; | |
214 | /*! | |
215 | * Value in range [-1,1] indicating fraction of row and column motion vectors | |
216 | * that point inwards (negative MV value) or outwards (positive MV value). | |
217 | * For example, value of 1 indicates, all row/column MVs are inwards. | |
218 | */ | |
219 | double mv_in_out_count; | |
220 | /*! | |
221 | * Duration of the frame / collection of frames. | |
222 | */ | |
223 | double duration; | |
224 | /*! | |
225 | * 1.0 if stats are for a single frame, or | |
226 | * number of frames whose stats are accumulated. | |
227 | */ | |
228 | double count; | |
229 | } vpx_rc_frame_stats_t; | |
230 | ||
231 | /*!\brief Collection of first pass frame stats | |
232 | */ | |
233 | typedef struct vpx_rc_firstpass_stats { | |
234 | /*! | |
235 | * Pointer to first pass frame stats. | |
236 | * The pointed array of vpx_rc_frame_stats_t should have length equal to | |
237 | * number of show frames in the video. | |
238 | */ | |
239 | vpx_rc_frame_stats_t *frame_stats; | |
240 | /*! | |
241 | * Number of show frames in the video. | |
242 | */ | |
243 | int num_frames; | |
244 | } vpx_rc_firstpass_stats_t; | |
245 | ||
246 | /*!\brief Encode config sent to external rate control model | |
247 | */ | |
248 | typedef struct vpx_rc_config { | |
249 | int frame_width; /**< frame width */ | |
250 | int frame_height; /**< frame height */ | |
251 | int show_frame_count; /**< number of visible frames in the video */ | |
252 | /*! | |
253 | * Target bitrate in kilobytes per second | |
254 | */ | |
255 | int target_bitrate_kbps; | |
256 | int frame_rate_num; /**< numerator of frame rate */ | |
257 | int frame_rate_den; /**< denominator of frame rate */ | |
258 | } vpx_rc_config_t; | |
259 | ||
260 | /*!\brief Create an external rate control model callback prototype | |
261 | * | |
262 | * This callback is invoked by the encoder to create an external rate control | |
263 | * model. | |
264 | * | |
265 | * \param[in] priv Callback's private data | |
266 | * \param[in] ratectrl_config Pointer to vpx_rc_config_t | |
267 | * \param[out] rate_ctrl_model_pt Pointer to vpx_rc_model_t | |
268 | */ | |
269 | typedef vpx_rc_status_t (*vpx_rc_create_model_cb_fn_t)( | |
270 | void *priv, const vpx_rc_config_t *ratectrl_config, | |
271 | vpx_rc_model_t *rate_ctrl_model_pt); | |
272 | ||
273 | /*!\brief Send first pass stats to the external rate control model callback | |
274 | * prototype | |
275 | * | |
276 | * This callback is invoked by the encoder to send first pass stats to the | |
277 | * external rate control model. | |
278 | * | |
279 | * \param[in] rate_ctrl_model rate control model | |
280 | * \param[in] first_pass_stats first pass stats | |
281 | */ | |
282 | typedef vpx_rc_status_t (*vpx_rc_send_firstpass_stats_cb_fn_t)( | |
283 | vpx_rc_model_t rate_ctrl_model, | |
284 | const vpx_rc_firstpass_stats_t *first_pass_stats); | |
285 | ||
286 | /*!\brief Receive encode frame decision callback prototype | |
287 | * | |
288 | * This callback is invoked by the encoder to receive encode frame decision from | |
289 | * the external rate control model. | |
290 | * | |
291 | * \param[in] rate_ctrl_model rate control model | |
292 | * \param[in] encode_frame_info information of the coding frame | |
293 | * \param[out] frame_decision encode decision of the coding frame | |
294 | */ | |
295 | typedef vpx_rc_status_t (*vpx_rc_get_encodeframe_decision_cb_fn_t)( | |
296 | vpx_rc_model_t rate_ctrl_model, | |
297 | const vpx_rc_encodeframe_info_t *encode_frame_info, | |
298 | vpx_rc_encodeframe_decision_t *frame_decision); | |
299 | ||
300 | /*!\brief Update encode frame result callback prototype | |
301 | * | |
302 | * This callback is invoked by the encoder to update encode frame result to the | |
303 | * external rate control model. | |
304 | * | |
305 | * \param[in] rate_ctrl_model rate control model | |
306 | * \param[out] encode_frame_result encode result of the coding frame | |
307 | */ | |
308 | typedef vpx_rc_status_t (*vpx_rc_update_encodeframe_result_cb_fn_t)( | |
309 | vpx_rc_model_t rate_ctrl_model, | |
310 | const vpx_rc_encodeframe_result_t *encode_frame_result); | |
311 | ||
312 | /*!\brief Delete the external rate control model callback prototype | |
313 | * | |
314 | * This callback is invoked by the encoder to delete the external rate control | |
315 | * model. | |
316 | * | |
317 | * \param[in] rate_ctrl_model rate control model | |
318 | */ | |
319 | typedef vpx_rc_status_t (*vpx_rc_delete_model_cb_fn_t)( | |
320 | vpx_rc_model_t rate_ctrl_model); | |
321 | ||
322 | /*!\brief Callback function set for external rate control. | |
323 | * | |
324 | * The user can enable external rate control by registering | |
325 | * a set of callback functions with the codec control flag | |
326 | * VP9E_SET_EXTERNAL_RATE_CONTROL. | |
327 | */ | |
328 | typedef struct vpx_rc_funcs { | |
329 | /*! | |
330 | * Create an external rate control model. | |
331 | */ | |
332 | vpx_rc_create_model_cb_fn_t create_model; | |
333 | /*! | |
334 | * Send first pass stats to the external rate control model. | |
335 | */ | |
336 | vpx_rc_send_firstpass_stats_cb_fn_t send_firstpass_stats; | |
337 | /*! | |
338 | * Get encodeframe decision from the external rate control model. | |
339 | */ | |
340 | vpx_rc_get_encodeframe_decision_cb_fn_t get_encodeframe_decision; | |
341 | /*! | |
342 | * Update encodeframe result to the external rate control model. | |
343 | */ | |
344 | vpx_rc_update_encodeframe_result_cb_fn_t update_encodeframe_result; | |
345 | /*! | |
346 | * Delete the external rate control model. | |
347 | */ | |
348 | vpx_rc_delete_model_cb_fn_t delete_model; | |
349 | /*! | |
350 | * Private data for the external rate control model. | |
351 | */ | |
352 | void *priv; | |
353 | } vpx_rc_funcs_t; | |
354 | ||
355 | #ifdef __cplusplus | |
356 | } // extern "C" | |
357 | #endif | |
358 | ||
359 | #endif // VPX_VPX_VPX_EXT_RATECTRL_H_ |
660 | 660 | vpx_highbd_lpf_vertical_8_neon(s + 8 * p, p, blimit1, limit1, thresh1, bd); |
661 | 661 | } |
662 | 662 | |
663 | // Quiet warnings of the form: 'vpx_dsp/arm/highbd_loopfilter_neon.c|675 col 67| | |
664 | // warning: 'oq1' may be used uninitialized in this function | |
665 | // [-Wmaybe-uninitialized]', for oq1-op1. Without reworking the code or adding | |
666 | // an additional branch this warning cannot be silenced otherwise. The | |
667 | // loopfilter is only called when needed for a block so these output pixels | |
668 | // will be set. | |
669 | #if defined(__GNUC__) && __GNUC__ >= 4 && !defined(__clang__) | |
670 | #pragma GCC diagnostic push | |
671 | #pragma GCC diagnostic ignored "-Wmaybe-uninitialized" | |
672 | #endif | |
673 | ||
663 | 674 | static void lpf_horizontal_16_kernel(uint16_t *s, int p, |
664 | 675 | const uint16x8_t blimit_vec, |
665 | 676 | const uint16x8_t limit_vec, |
722 | 733 | } |
723 | 734 | } |
724 | 735 | |
736 | #if defined(__GNUC__) && __GNUC__ >= 4 && !defined(__clang__) | |
737 | #pragma GCC diagnostic pop | |
738 | #endif | |
739 | ||
725 | 740 | void vpx_highbd_lpf_horizontal_16_neon(uint16_t *s, int p, |
726 | 741 | const uint8_t *blimit, |
727 | 742 | const uint8_t *limit, |
974 | 974 | FUN_LPF_16_KERNEL(_dual_, 16) // lpf_16_dual_kernel |
975 | 975 | #undef FUN_LPF_16_KERNEL |
976 | 976 | |
977 | // Quiet warnings of the form: 'vpx_dsp/arm/loopfilter_neon.c|981 col 42| | |
978 | // warning: 'oq1' may be used uninitialized in this function | |
979 | // [-Wmaybe-uninitialized]', for oq1-op1. Without reworking the code or adding | |
980 | // an additional branch this warning cannot be silenced otherwise. The | |
981 | // loopfilter is only called when needed for a block so these output pixels | |
982 | // will be set. | |
983 | #if defined(__GNUC__) && __GNUC__ >= 4 && !defined(__clang__) | |
984 | #pragma GCC diagnostic push | |
985 | #pragma GCC diagnostic ignored "-Wmaybe-uninitialized" | |
986 | #endif | |
987 | ||
977 | 988 | void vpx_lpf_horizontal_16_neon(uint8_t *s, int p, const uint8_t *blimit, |
978 | 989 | const uint8_t *limit, const uint8_t *thresh) { |
979 | 990 | uint8x8_t p7, p6, p5, p4, p3, p2, p1, p0, q0, q1, q2, q3, q4, q5, q6, q7, op6, |
1089 | 1100 | vget_high_u8(oq0), vget_high_u8(oq1)); |
1090 | 1101 | } |
1091 | 1102 | } |
1103 | ||
1104 | #if defined(__GNUC__) && __GNUC__ >= 4 && !defined(__clang__) | |
1105 | #pragma GCC diagnostic pop | |
1106 | #endif |
87 | 87 | const uint8_t *psrc_lw_m = (const uint8_t *)(psrc); \ |
88 | 88 | uint32_t val_lw_m; \ |
89 | 89 | \ |
90 | __asm__ __volatile__("ulw %[val_lw_m], %[psrc_lw_m] \n\t" \ | |
91 | \ | |
92 | : [val_lw_m] "=r"(val_lw_m) \ | |
93 | : [psrc_lw_m] "m"(*psrc_lw_m)); \ | |
90 | __asm__ __volatile__("lwr %[val_lw_m], 0(%[psrc_lw_m]) \n\t" \ | |
91 | "lwl %[val_lw_m], 3(%[psrc_lw_m]) \n\t" \ | |
92 | : [val_lw_m] "=&r"(val_lw_m) \ | |
93 | : [psrc_lw_m] "r"(psrc_lw_m)); \ | |
94 | 94 | \ |
95 | 95 | val_lw_m; \ |
96 | 96 | }) |
101 | 101 | const uint8_t *psrc_ld_m = (const uint8_t *)(psrc); \ |
102 | 102 | uint64_t val_ld_m = 0; \ |
103 | 103 | \ |
104 | __asm__ __volatile__("uld %[val_ld_m], %[psrc_ld_m] \n\t" \ | |
105 | \ | |
106 | : [val_ld_m] "=r"(val_ld_m) \ | |
107 | : [psrc_ld_m] "m"(*psrc_ld_m)); \ | |
104 | __asm__ __volatile__("ldr %[val_ld_m], 0(%[psrc_ld_m]) \n\t" \ | |
105 | "ldl %[val_ld_m], 7(%[psrc_ld_m]) \n\t" \ | |
106 | : [val_ld_m] "=&r"(val_ld_m) \ | |
107 | : [psrc_ld_m] "r"(psrc_ld_m)); \ | |
108 | 108 | \ |
109 | 109 | val_ld_m; \ |
110 | 110 | }) |
363 | 363 | double ftmp1, ftmp2, ftmp3, ftmp4, ftmp5; |
364 | 364 | mips_reg l_counter = counter; |
365 | 365 | |
366 | __asm__ volatile ( | |
367 | "xor %[ftmp5], %[ftmp5], %[ftmp5] \n\t" | |
366 | /* clang-format off */ | |
367 | __asm__ volatile ( | |
368 | "pxor %[ftmp5], %[ftmp5], %[ftmp5] \n\t" | |
368 | 369 | "1: \n\t" |
369 | 370 | // Include two loop body, to reduce loop time. |
370 | 371 | SAD_SRC_REF_ABS_SUB_64 |
382 | 383 | : [src_stride]"r"((mips_reg)src_stride), |
383 | 384 | [ref_stride]"r"((mips_reg)ref_stride) |
384 | 385 | ); |
386 | /* clang-format on */ | |
385 | 387 | |
386 | 388 | return sad; |
387 | 389 | } |
404 | 406 | unsigned int sad; |
405 | 407 | double ftmp1, ftmp2, ftmp3, ftmp4, ftmp5; |
406 | 408 | mips_reg l_counter = counter; |
407 | ||
408 | __asm__ volatile ( | |
409 | "xor %[ftmp5], %[ftmp5], %[ftmp5] \n\t" | |
409 | mips_reg l_second_pred = (mips_reg)second_pred; | |
410 | ||
411 | /* clang-format off */ | |
412 | __asm__ volatile ( | |
413 | "pxor %[ftmp5], %[ftmp5], %[ftmp5] \n\t" | |
410 | 414 | "1: \n\t" |
411 | 415 | // Include two loop body, to reduce loop time. |
412 | 416 | SAD_SRC_AVGREF_ABS_SUB_64 |
423 | 427 | : [ftmp1]"=&f"(ftmp1), [ftmp2]"=&f"(ftmp2), [ftmp3]"=&f"(ftmp3), |
424 | 428 | [ftmp4]"=&f"(ftmp4), [ftmp5]"=&f"(ftmp5), [counter]"+&r"(l_counter), |
425 | 429 | [src]"+&r"(src), [ref]"+&r"(ref), |
426 | [second_pred]"+&r"((mips_reg)second_pred), | |
430 | [second_pred]"+&r"(l_second_pred), | |
427 | 431 | [sad]"=&r"(sad) |
428 | 432 | : [src_stride]"r"((mips_reg)src_stride), |
429 | 433 | [ref_stride]"r"((mips_reg)ref_stride) |
430 | 434 | ); |
435 | /* clang-format on */ | |
431 | 436 | |
432 | 437 | return sad; |
433 | 438 | } |
449 | 454 | double ftmp1, ftmp2, ftmp3, ftmp4, ftmp5; |
450 | 455 | mips_reg l_counter = counter; |
451 | 456 | |
452 | __asm__ volatile ( | |
453 | "xor %[ftmp5], %[ftmp5], %[ftmp5] \n\t" | |
457 | /* clang-format off */ | |
458 | __asm__ volatile ( | |
459 | "pxor %[ftmp5], %[ftmp5], %[ftmp5] \n\t" | |
454 | 460 | "1: \n\t" |
455 | 461 | // Include two loop body, to reduce loop time. |
456 | 462 | SAD_SRC_REF_ABS_SUB_32 |
468 | 474 | : [src_stride]"r"((mips_reg)src_stride), |
469 | 475 | [ref_stride]"r"((mips_reg)ref_stride) |
470 | 476 | ); |
477 | /* clang-format on */ | |
471 | 478 | |
472 | 479 | return sad; |
473 | 480 | } |
492 | 499 | unsigned int sad; |
493 | 500 | double ftmp1, ftmp2, ftmp3, ftmp4, ftmp5; |
494 | 501 | mips_reg l_counter = counter; |
495 | ||
496 | __asm__ volatile ( | |
497 | "xor %[ftmp5], %[ftmp5], %[ftmp5] \n\t" | |
502 | mips_reg l_second_pred = (mips_reg)second_pred; | |
503 | ||
504 | /* clang-format off */ | |
505 | __asm__ volatile ( | |
506 | "pxor %[ftmp5], %[ftmp5], %[ftmp5] \n\t" | |
498 | 507 | "1: \n\t" |
499 | 508 | // Include two loop body, to reduce loop time. |
500 | 509 | SAD_SRC_AVGREF_ABS_SUB_32 |
511 | 520 | : [ftmp1]"=&f"(ftmp1), [ftmp2]"=&f"(ftmp2), [ftmp3]"=&f"(ftmp3), |
512 | 521 | [ftmp4]"=&f"(ftmp4), [ftmp5]"=&f"(ftmp5), [counter]"+&r"(l_counter), |
513 | 522 | [src]"+&r"(src), [ref]"+&r"(ref), |
514 | [second_pred]"+&r"((mips_reg)second_pred), | |
523 | [second_pred]"+&r"(l_second_pred), | |
515 | 524 | [sad]"=&r"(sad) |
516 | 525 | : [src_stride]"r"((mips_reg)src_stride), |
517 | 526 | [ref_stride]"r"((mips_reg)ref_stride) |
518 | 527 | ); |
528 | /* clang-format on */ | |
519 | 529 | |
520 | 530 | return sad; |
521 | 531 | } |
538 | 548 | double ftmp1, ftmp2, ftmp3, ftmp4, ftmp5; |
539 | 549 | mips_reg l_counter = counter; |
540 | 550 | |
541 | __asm__ volatile ( | |
542 | "xor %[ftmp5], %[ftmp5], %[ftmp5] \n\t" | |
551 | /* clang-format off */ | |
552 | __asm__ volatile ( | |
553 | "pxor %[ftmp5], %[ftmp5], %[ftmp5] \n\t" | |
543 | 554 | "1: \n\t" |
544 | 555 | // Include two loop body, to reduce loop time. |
545 | 556 | SAD_SRC_REF_ABS_SUB_16 |
557 | 568 | : [src_stride]"r"((mips_reg)src_stride), |
558 | 569 | [ref_stride]"r"((mips_reg)ref_stride) |
559 | 570 | ); |
571 | /* clang-format on */ | |
560 | 572 | |
561 | 573 | return sad; |
562 | 574 | } |
585 | 597 | unsigned int sad; |
586 | 598 | double ftmp1, ftmp2, ftmp3, ftmp4, ftmp5; |
587 | 599 | mips_reg l_counter = counter; |
588 | ||
589 | __asm__ volatile ( | |
590 | "xor %[ftmp5], %[ftmp5], %[ftmp5] \n\t" | |
600 | mips_reg l_second_pred = (mips_reg)second_pred; | |
601 | ||
602 | /* clang-format off */ | |
603 | __asm__ volatile ( | |
604 | "pxor %[ftmp5], %[ftmp5], %[ftmp5] \n\t" | |
591 | 605 | "1: \n\t" |
592 | 606 | // Include two loop body, to reduce loop time. |
593 | 607 | SAD_SRC_AVGREF_ABS_SUB_16 |
604 | 618 | : [ftmp1]"=&f"(ftmp1), [ftmp2]"=&f"(ftmp2), [ftmp3]"=&f"(ftmp3), |
605 | 619 | [ftmp4]"=&f"(ftmp4), [ftmp5]"=&f"(ftmp5), [counter]"+&r"(l_counter), |
606 | 620 | [src]"+&r"(src), [ref]"+&r"(ref), |
607 | [second_pred]"+&r"((mips_reg)second_pred), | |
621 | [second_pred]"+&r"(l_second_pred), | |
608 | 622 | [sad]"=&r"(sad) |
609 | 623 | : [src_stride]"r"((mips_reg)src_stride), |
610 | 624 | [ref_stride]"r"((mips_reg)ref_stride) |
611 | 625 | ); |
626 | /* clang-format on */ | |
612 | 627 | |
613 | 628 | return sad; |
614 | 629 | } |
631 | 646 | double ftmp1, ftmp2, ftmp3; |
632 | 647 | mips_reg l_counter = counter; |
633 | 648 | |
634 | __asm__ volatile ( | |
635 | "xor %[ftmp3], %[ftmp3], %[ftmp3] \n\t" | |
649 | /* clang-format off */ | |
650 | __asm__ volatile ( | |
651 | "pxor %[ftmp3], %[ftmp3], %[ftmp3] \n\t" | |
636 | 652 | "1: \n\t" |
637 | 653 | // Include two loop body, to reduce loop time. |
638 | 654 | SAD_SRC_REF_ABS_SUB_8 |
650 | 666 | : [src_stride]"r"((mips_reg)src_stride), |
651 | 667 | [ref_stride]"r"((mips_reg)ref_stride) |
652 | 668 | ); |
669 | /* clang-format on */ | |
653 | 670 | |
654 | 671 | return sad; |
655 | 672 | } |
678 | 695 | unsigned int sad; |
679 | 696 | double ftmp1, ftmp2, ftmp3; |
680 | 697 | mips_reg l_counter = counter; |
681 | ||
682 | __asm__ volatile ( | |
683 | "xor %[ftmp3], %[ftmp3], %[ftmp3] \n\t" | |
698 | mips_reg l_second_pred = (mips_reg)second_pred; | |
699 | ||
700 | /* clang-format off */ | |
701 | __asm__ volatile ( | |
702 | "pxor %[ftmp3], %[ftmp3], %[ftmp3] \n\t" | |
684 | 703 | "1: \n\t" |
685 | 704 | // Include two loop body, to reduce loop time. |
686 | 705 | SAD_SRC_AVGREF_ABS_SUB_8 |
696 | 715 | "mfc1 %[sad], %[ftmp3] \n\t" |
697 | 716 | : [ftmp1]"=&f"(ftmp1), [ftmp2]"=&f"(ftmp2), [ftmp3]"=&f"(ftmp3), |
698 | 717 | [counter]"+&r"(l_counter), [src]"+&r"(src), [ref]"+&r"(ref), |
699 | [second_pred]"+&r"((mips_reg)second_pred), | |
718 | [second_pred]"+&r"(l_second_pred), | |
700 | 719 | [sad]"=&r"(sad) |
701 | 720 | : [src_stride]"r"((mips_reg)src_stride), |
702 | 721 | [ref_stride]"r"((mips_reg)ref_stride) |
703 | 722 | ); |
723 | /* clang-format on */ | |
704 | 724 | |
705 | 725 | return sad; |
706 | 726 | } |
723 | 743 | double ftmp1, ftmp2, ftmp3; |
724 | 744 | mips_reg l_counter = counter; |
725 | 745 | |
726 | __asm__ volatile ( | |
727 | "xor %[ftmp3], %[ftmp3], %[ftmp3] \n\t" | |
746 | /* clang-format off */ | |
747 | __asm__ volatile ( | |
748 | "pxor %[ftmp3], %[ftmp3], %[ftmp3] \n\t" | |
728 | 749 | "1: \n\t" |
729 | 750 | // Include two loop body, to reduce loop time. |
730 | 751 | SAD_SRC_REF_ABS_SUB_4 |
742 | 763 | : [src_stride]"r"((mips_reg)src_stride), |
743 | 764 | [ref_stride]"r"((mips_reg)ref_stride) |
744 | 765 | ); |
766 | /* clang-format on */ | |
745 | 767 | |
746 | 768 | return sad; |
747 | 769 | } |
766 | 788 | unsigned int sad; |
767 | 789 | double ftmp1, ftmp2, ftmp3; |
768 | 790 | mips_reg l_counter = counter; |
769 | ||
770 | __asm__ volatile ( | |
771 | "xor %[ftmp3], %[ftmp3], %[ftmp3] \n\t" | |
791 | mips_reg l_second_pred = (mips_reg)second_pred; | |
792 | ||
793 | /* clang-format off */ | |
794 | __asm__ volatile ( | |
795 | "pxor %[ftmp3], %[ftmp3], %[ftmp3] \n\t" | |
772 | 796 | "1: \n\t" |
773 | 797 | // Include two loop body, to reduce loop time. |
774 | 798 | SAD_SRC_AVGREF_ABS_SUB_4 |
784 | 808 | "mfc1 %[sad], %[ftmp3] \n\t" |
785 | 809 | : [ftmp1]"=&f"(ftmp1), [ftmp2]"=&f"(ftmp2), [ftmp3]"=&f"(ftmp3), |
786 | 810 | [counter]"+&r"(l_counter), [src]"+&r"(src), [ref]"+&r"(ref), |
787 | [second_pred]"+&r"((mips_reg)second_pred), | |
811 | [second_pred]"+&r"(l_second_pred), | |
788 | 812 | [sad]"=&r"(sad) |
789 | 813 | : [src_stride]"r"((mips_reg)src_stride), |
790 | 814 | [ref_stride]"r"((mips_reg)ref_stride) |
791 | 815 | ); |
816 | /* clang-format on */ | |
792 | 817 | |
793 | 818 | return sad; |
794 | 819 | } |
23 | 23 | switch (rows) { |
24 | 24 | case 4: |
25 | 25 | __asm__ volatile( |
26 | "xor %[ftmp0], %[ftmp0], %[ftmp0] \n\t" | |
26 | "pxor %[ftmp0], %[ftmp0], %[ftmp0] \n\t" | |
27 | 27 | #if _MIPS_SIM == _ABIO32 |
28 | 28 | "ulw %[tmp0], 0x00(%[src]) \n\t" |
29 | 29 | "mtc1 %[tmp0], %[ftmp1] \n\t" |
117 | 117 | break; |
118 | 118 | case 8: |
119 | 119 | __asm__ volatile( |
120 | "xor %[ftmp0], %[ftmp0], %[ftmp0] \n\t" | |
120 | "pxor %[ftmp0], %[ftmp0], %[ftmp0] \n\t" | |
121 | 121 | "li %[tmp0], 0x02 \n\t" |
122 | 122 | "1: \n\t" |
123 | 123 | "gsldlc1 %[ftmp1], 0x07(%[src]) \n\t" |
205 | 205 | break; |
206 | 206 | case 16: |
207 | 207 | __asm__ volatile( |
208 | "xor %[ftmp0], %[ftmp0], %[ftmp0] \n\t" | |
208 | "pxor %[ftmp0], %[ftmp0], %[ftmp0] \n\t" | |
209 | 209 | "li %[tmp0], 0x08 \n\t" |
210 | 210 | "1: \n\t" |
211 | 211 | "gsldlc1 %[ftmp1], 0x07(%[src]) \n\t" |
149 | 149 | "psrlh %[ftmp2], %[ftmp2], %[ftmp6] \n\t" \ |
150 | 150 | \ |
151 | 151 | /* store: temp2[0] ~ temp2[3] */ \ |
152 | "and %[ftmp2], %[ftmp2], %[mask] \n\t" \ | |
152 | "pand %[ftmp2], %[ftmp2], %[mask] \n\t" \ | |
153 | 153 | "packushb %[ftmp2], %[ftmp2], %[ftmp0] \n\t" \ |
154 | 154 | "gssdrc1 %[ftmp2], 0x00(%[temp2_ptr]) \n\t" |
155 | 155 | |
162 | 162 | "psrlh %[ftmp4], %[ftmp4], %[ftmp6] \n\t" \ |
163 | 163 | \ |
164 | 164 | /* store: temp2[0] ~ temp2[3] */ \ |
165 | "and %[ftmp4], %[ftmp4], %[mask] \n\t" \ | |
165 | "pand %[ftmp4], %[ftmp4], %[mask] \n\t" \ | |
166 | 166 | "packushb %[ftmp4], %[ftmp4], %[ftmp0] \n\t" \ |
167 | 167 | "gssdrc1 %[ftmp4], 0x00(%[temp2_ptr]) \n\t" |
168 | 168 | |
224 | 224 | "psrlh %[ftmp3], %[ftmp3], %[ftmp14] \n\t" \ |
225 | 225 | \ |
226 | 226 | /* store: temp2[0] ~ temp2[7] */ \ |
227 | "and %[ftmp2], %[ftmp2], %[mask] \n\t" \ | |
228 | "and %[ftmp3], %[ftmp3], %[mask] \n\t" \ | |
227 | "pand %[ftmp2], %[ftmp2], %[mask] \n\t" \ | |
228 | "pand %[ftmp3], %[ftmp3], %[mask] \n\t" \ | |
229 | 229 | "packushb %[ftmp2], %[ftmp2], %[ftmp3] \n\t" \ |
230 | 230 | "gssdlc1 %[ftmp2], 0x07(%[temp2_ptr]) \n\t" \ |
231 | 231 | "gssdrc1 %[ftmp2], 0x00(%[temp2_ptr]) \n\t" |
246 | 246 | "psrlh %[ftmp9], %[ftmp9], %[ftmp14] \n\t" \ |
247 | 247 | \ |
248 | 248 | /* store: temp2[0] ~ temp2[7] */ \ |
249 | "and %[ftmp8], %[ftmp8], %[mask] \n\t" \ | |
250 | "and %[ftmp9], %[ftmp9], %[mask] \n\t" \ | |
249 | "pand %[ftmp8], %[ftmp8], %[mask] \n\t" \ | |
250 | "pand %[ftmp9], %[ftmp9], %[mask] \n\t" \ | |
251 | 251 | "packushb %[ftmp8], %[ftmp8], %[ftmp9] \n\t" \ |
252 | 252 | "gssdlc1 %[ftmp8], 0x07(%[temp2_ptr]) \n\t" \ |
253 | 253 | "gssdrc1 %[ftmp8], 0x00(%[temp2_ptr]) \n\t" |
318 | 318 | "psrlh %[ftmp5], %[ftmp5], %[ftmp14] \n\t" \ |
319 | 319 | \ |
320 | 320 | /* store: temp2[8] ~ temp2[15] */ \ |
321 | "and %[ftmp4], %[ftmp4], %[mask] \n\t" \ | |
322 | "and %[ftmp5], %[ftmp5], %[mask] \n\t" \ | |
321 | "pand %[ftmp4], %[ftmp4], %[mask] \n\t" \ | |
322 | "pand %[ftmp5], %[ftmp5], %[mask] \n\t" \ | |
323 | 323 | "packushb %[ftmp4], %[ftmp4], %[ftmp5] \n\t" \ |
324 | 324 | "gssdlc1 %[ftmp4], 0x0f(%[temp2_ptr]) \n\t" \ |
325 | 325 | "gssdrc1 %[ftmp4], 0x08(%[temp2_ptr]) \n\t" |
342 | 342 | "psrlh %[ftmp11], %[ftmp11], %[ftmp14] \n\t" \ |
343 | 343 | \ |
344 | 344 | /* store: temp2[8] ~ temp2[15] */ \ |
345 | "and %[ftmp10], %[ftmp10], %[mask] \n\t" \ | |
346 | "and %[ftmp11], %[ftmp11], %[mask] \n\t" \ | |
345 | "pand %[ftmp10], %[ftmp10], %[mask] \n\t" \ | |
346 | "pand %[ftmp11], %[ftmp11], %[mask] \n\t" \ | |
347 | 347 | "packushb %[ftmp10], %[ftmp10], %[ftmp11] \n\t" \ |
348 | 348 | "gssdlc1 %[ftmp10], 0x0f(%[temp2_ptr]) \n\t" \ |
349 | 349 | "gssdrc1 %[ftmp10], 0x08(%[temp2_ptr]) \n\t" |
413 | 413 | |
414 | 414 | *sse = 0; |
415 | 415 | |
416 | /* clang-format off */ | |
416 | 417 | __asm__ volatile ( |
417 | 418 | "li %[tmp0], 0x20 \n\t" |
418 | 419 | "mtc1 %[tmp0], %[ftmp11] \n\t" |
419 | 420 | MMI_L(%[tmp0], %[high], 0x00) |
420 | "xor %[ftmp0], %[ftmp0], %[ftmp0] \n\t" | |
421 | "xor %[ftmp9], %[ftmp9], %[ftmp9] \n\t" | |
422 | "xor %[ftmp10], %[ftmp10], %[ftmp10] \n\t" | |
421 | "pxor %[ftmp0], %[ftmp0], %[ftmp0] \n\t" | |
422 | "pxor %[ftmp9], %[ftmp9], %[ftmp9] \n\t" | |
423 | "pxor %[ftmp10], %[ftmp10], %[ftmp10] \n\t" | |
423 | 424 | "1: \n\t" |
424 | 425 | "gsldlc1 %[ftmp1], 0x07(%[src_ptr]) \n\t" |
425 | 426 | "gsldrc1 %[ftmp1], 0x00(%[src_ptr]) \n\t" |
477 | 478 | "mfc1 %[tmp1], %[ftmp9] \n\t" |
478 | 479 | "mfhc1 %[tmp2], %[ftmp9] \n\t" |
479 | 480 | "addu %[sum], %[tmp1], %[tmp2] \n\t" |
480 | "dsrl %[ftmp1], %[ftmp10], %[ftmp11] \n\t" | |
481 | "ssrld %[ftmp1], %[ftmp10], %[ftmp11] \n\t" | |
481 | 482 | "paddw %[ftmp1], %[ftmp1], %[ftmp10] \n\t" |
482 | 483 | "swc1 %[ftmp1], 0x00(%[sse]) \n\t" |
483 | 484 | : [ftmp0]"=&f"(ftmp[0]), [ftmp1]"=&f"(ftmp[1]), |
495 | 496 | [high]"r"(&high), [sse]"r"(sse) |
496 | 497 | : "memory" |
497 | 498 | ); |
499 | /* clang-format on */ | |
498 | 500 | |
499 | 501 | return *sse - (((int64_t)sum * sum) / (64 * high)); |
500 | 502 | } |
518 | 520 | |
519 | 521 | *sse = 0; |
520 | 522 | |
523 | /* clang-format off */ | |
521 | 524 | __asm__ volatile ( |
522 | 525 | "li %[tmp0], 0x20 \n\t" |
523 | 526 | "mtc1 %[tmp0], %[ftmp11] \n\t" |
524 | 527 | "li %[tmp0], 0x40 \n\t" |
525 | "xor %[ftmp0], %[ftmp0], %[ftmp0] \n\t" | |
526 | "xor %[ftmp9], %[ftmp9], %[ftmp9] \n\t" | |
527 | "xor %[ftmp10], %[ftmp10], %[ftmp10] \n\t" | |
528 | "pxor %[ftmp0], %[ftmp0], %[ftmp0] \n\t" | |
529 | "pxor %[ftmp9], %[ftmp9], %[ftmp9] \n\t" | |
530 | "pxor %[ftmp10], %[ftmp10], %[ftmp10] \n\t" | |
528 | 531 | "1: \n\t" |
529 | 532 | "gsldlc1 %[ftmp1], 0x07(%[src_ptr]) \n\t" |
530 | 533 | "gsldrc1 %[ftmp1], 0x00(%[src_ptr]) \n\t" |
558 | 561 | "mfc1 %[tmp1], %[ftmp9] \n\t" |
559 | 562 | "mfhc1 %[tmp2], %[ftmp9] \n\t" |
560 | 563 | "addu %[sum], %[tmp1], %[tmp2] \n\t" |
561 | "dsrl %[ftmp1], %[ftmp10], %[ftmp11] \n\t" | |
564 | "ssrld %[ftmp1], %[ftmp10], %[ftmp11] \n\t" | |
562 | 565 | "paddw %[ftmp1], %[ftmp1], %[ftmp10] \n\t" |
563 | 566 | "swc1 %[ftmp1], 0x00(%[sse]) \n\t" |
564 | 567 | : [ftmp0]"=&f"(ftmp[0]), [ftmp1]"=&f"(ftmp[1]), |
576 | 579 | [sse]"r"(sse) |
577 | 580 | : "memory" |
578 | 581 | ); |
582 | /* clang-format on */ | |
579 | 583 | |
580 | 584 | return *sse - (((int64_t)sum * sum) / 2048); |
581 | 585 | } |
589 | 593 | |
590 | 594 | *sse = 0; |
591 | 595 | |
596 | /* clang-format off */ | |
592 | 597 | __asm__ volatile ( |
593 | 598 | "li %[tmp0], 0x20 \n\t" |
594 | 599 | "mtc1 %[tmp0], %[ftmp11] \n\t" |
595 | 600 | MMI_L(%[tmp0], %[high], 0x00) |
596 | "xor %[ftmp0], %[ftmp0], %[ftmp0] \n\t" | |
597 | "xor %[ftmp8], %[ftmp8], %[ftmp8] \n\t" | |
598 | "xor %[ftmp10], %[ftmp10], %[ftmp10] \n\t" | |
599 | "xor %[ftmp12], %[ftmp12], %[ftmp12] \n\t" | |
601 | "pxor %[ftmp0], %[ftmp0], %[ftmp0] \n\t" | |
602 | "pxor %[ftmp8], %[ftmp8], %[ftmp8] \n\t" | |
603 | "pxor %[ftmp10], %[ftmp10], %[ftmp10] \n\t" | |
604 | "pxor %[ftmp12], %[ftmp12], %[ftmp12] \n\t" | |
600 | 605 | "1: \n\t" |
601 | 606 | "gsldlc1 %[ftmp1], 0x07(%[src_ptr]) \n\t" |
602 | 607 | "gsldrc1 %[ftmp1], 0x00(%[src_ptr]) \n\t" |
624 | 629 | MMI_ADDU(%[ref_ptr], %[ref_ptr], %[ref_stride]) |
625 | 630 | "bnez %[tmp0], 1b \n\t" |
626 | 631 | |
627 | "dsrl %[ftmp9], %[ftmp8], %[ftmp11] \n\t" | |
632 | "ssrld %[ftmp9], %[ftmp8], %[ftmp11] \n\t" | |
628 | 633 | "paddw %[ftmp9], %[ftmp9], %[ftmp8] \n\t" |
629 | 634 | "swc1 %[ftmp9], 0x00(%[sse]) \n\t" |
630 | 635 | |
635 | 640 | "paddw %[ftmp3], %[ftmp3], %[ftmp4] \n\t" |
636 | 641 | "psubw %[ftmp3], %[ftmp3], %[ftmp5] \n\t" |
637 | 642 | "psubw %[ftmp3], %[ftmp3], %[ftmp6] \n\t" |
638 | "dsrl %[ftmp0], %[ftmp3], %[ftmp11] \n\t" | |
643 | "ssrld %[ftmp0], %[ftmp3], %[ftmp11] \n\t" | |
639 | 644 | "paddw %[ftmp0], %[ftmp0], %[ftmp3] \n\t" |
640 | 645 | "swc1 %[ftmp0], 0x00(%[sum]) \n\t" |
641 | 646 | |
652 | 657 | [high]"r"(&high), [sse]"r"(sse), [sum]"r"(&sum) |
653 | 658 | : "memory" |
654 | 659 | ); |
660 | /* clang-format on */ | |
655 | 661 | |
656 | 662 | return *sse - (((int64_t)sum * sum) / (32 * high)); |
657 | 663 | } |
675 | 681 | |
676 | 682 | *sse = 0; |
677 | 683 | |
684 | /* clang-format off */ | |
678 | 685 | __asm__ volatile ( |
679 | 686 | "li %[tmp0], 0x20 \n\t" |
680 | 687 | "mtc1 %[tmp0], %[ftmp11] \n\t" |
681 | 688 | MMI_L(%[tmp0], %[high], 0x00) |
682 | "xor %[ftmp0], %[ftmp0], %[ftmp0] \n\t" | |
683 | "xor %[ftmp8], %[ftmp8], %[ftmp8] \n\t" | |
684 | "xor %[ftmp10], %[ftmp10], %[ftmp10] \n\t" | |
685 | "xor %[ftmp12], %[ftmp12], %[ftmp12] \n\t" | |
689 | "pxor %[ftmp0], %[ftmp0], %[ftmp0] \n\t" | |
690 | "pxor %[ftmp8], %[ftmp8], %[ftmp8] \n\t" | |
691 | "pxor %[ftmp10], %[ftmp10], %[ftmp10] \n\t" | |
692 | "pxor %[ftmp12], %[ftmp12], %[ftmp12] \n\t" | |
686 | 693 | "1: \n\t" |
687 | 694 | "gsldlc1 %[ftmp1], 0x07(%[src_ptr]) \n\t" |
688 | 695 | "gsldrc1 %[ftmp1], 0x00(%[src_ptr]) \n\t" |
700 | 707 | MMI_ADDU(%[ref_ptr], %[ref_ptr], %[ref_stride]) |
701 | 708 | "bnez %[tmp0], 1b \n\t" |
702 | 709 | |
703 | "dsrl %[ftmp9], %[ftmp8], %[ftmp11] \n\t" | |
710 | "ssrld %[ftmp9], %[ftmp8], %[ftmp11] \n\t" | |
704 | 711 | "paddw %[ftmp9], %[ftmp9], %[ftmp8] \n\t" |
705 | 712 | "swc1 %[ftmp9], 0x00(%[sse]) \n\t" |
706 | 713 | |
711 | 718 | "paddw %[ftmp3], %[ftmp3], %[ftmp4] \n\t" |
712 | 719 | "psubw %[ftmp3], %[ftmp3], %[ftmp5] \n\t" |
713 | 720 | "psubw %[ftmp3], %[ftmp3], %[ftmp6] \n\t" |
714 | "dsrl %[ftmp0], %[ftmp3], %[ftmp11] \n\t" | |
721 | "ssrld %[ftmp0], %[ftmp3], %[ftmp11] \n\t" | |
715 | 722 | "paddw %[ftmp0], %[ftmp0], %[ftmp3] \n\t" |
716 | 723 | "swc1 %[ftmp0], 0x00(%[sum]) \n\t" |
717 | 724 | |
728 | 735 | [high]"r"(&high), [sse]"r"(sse), [sum]"r"(&sum) |
729 | 736 | : "memory" |
730 | 737 | ); |
738 | /* clang-format on */ | |
731 | 739 | |
732 | 740 | return *sse - (((int64_t)sum * sum) / (16 * high)); |
733 | 741 | } |
752 | 760 | |
753 | 761 | *sse = 0; |
754 | 762 | |
763 | /* clang-format off */ | |
755 | 764 | __asm__ volatile ( |
756 | 765 | "li %[tmp0], 0x20 \n\t" |
757 | 766 | "mtc1 %[tmp0], %[ftmp11] \n\t" |
758 | 767 | MMI_L(%[tmp0], %[high], 0x00) |
759 | "xor %[ftmp0], %[ftmp0], %[ftmp0] \n\t" | |
760 | "xor %[ftmp8], %[ftmp8], %[ftmp8] \n\t" | |
761 | "xor %[ftmp10], %[ftmp10], %[ftmp10] \n\t" | |
762 | "xor %[ftmp12], %[ftmp12], %[ftmp12] \n\t" | |
768 | "pxor %[ftmp0], %[ftmp0], %[ftmp0] \n\t" | |
769 | "pxor %[ftmp8], %[ftmp8], %[ftmp8] \n\t" | |
770 | "pxor %[ftmp10], %[ftmp10], %[ftmp10] \n\t" | |
771 | "pxor %[ftmp12], %[ftmp12], %[ftmp12] \n\t" | |
763 | 772 | "1: \n\t" |
764 | 773 | "gsldlc1 %[ftmp1], 0x07(%[src_ptr]) \n\t" |
765 | 774 | "gsldrc1 %[ftmp1], 0x00(%[src_ptr]) \n\t" |
772 | 781 | MMI_ADDU(%[ref_ptr], %[ref_ptr], %[ref_stride]) |
773 | 782 | "bnez %[tmp0], 1b \n\t" |
774 | 783 | |
775 | "dsrl %[ftmp9], %[ftmp8], %[ftmp11] \n\t" | |
784 | "ssrld %[ftmp9], %[ftmp8], %[ftmp11] \n\t" | |
776 | 785 | "paddw %[ftmp9], %[ftmp9], %[ftmp8] \n\t" |
777 | 786 | "swc1 %[ftmp9], 0x00(%[sse]) \n\t" |
778 | 787 | |
783 | 792 | "paddw %[ftmp3], %[ftmp3], %[ftmp4] \n\t" |
784 | 793 | "psubw %[ftmp3], %[ftmp3], %[ftmp5] \n\t" |
785 | 794 | "psubw %[ftmp3], %[ftmp3], %[ftmp6] \n\t" |
786 | "dsrl %[ftmp0], %[ftmp3], %[ftmp11] \n\t" | |
795 | "ssrld %[ftmp0], %[ftmp3], %[ftmp11] \n\t" | |
787 | 796 | "paddw %[ftmp0], %[ftmp0], %[ftmp3] \n\t" |
788 | 797 | "swc1 %[ftmp0], 0x00(%[sum]) \n\t" |
789 | 798 | |
800 | 809 | [high]"r"(&high), [sse]"r"(sse), [sum]"r"(&sum) |
801 | 810 | : "memory" |
802 | 811 | ); |
812 | /* clang-format on */ | |
803 | 813 | |
804 | 814 | return *sse - (((int64_t)sum * sum) / (8 * high)); |
805 | 815 | } |
824 | 834 | |
825 | 835 | *sse = 0; |
826 | 836 | |
837 | /* clang-format off */ | |
827 | 838 | __asm__ volatile ( |
828 | 839 | "li %[tmp0], 0x20 \n\t" |
829 | 840 | "mtc1 %[tmp0], %[ftmp10] \n\t" |
830 | 841 | MMI_L(%[tmp0], %[high], 0x00) |
831 | "xor %[ftmp0], %[ftmp0], %[ftmp0] \n\t" | |
832 | "xor %[ftmp6], %[ftmp6], %[ftmp6] \n\t" | |
833 | "xor %[ftmp7], %[ftmp7], %[ftmp7] \n\t" | |
834 | "xor %[ftmp8], %[ftmp8], %[ftmp8] \n\t" | |
842 | "pxor %[ftmp0], %[ftmp0], %[ftmp0] \n\t" | |
843 | "pxor %[ftmp6], %[ftmp6], %[ftmp6] \n\t" | |
844 | "pxor %[ftmp7], %[ftmp7], %[ftmp7] \n\t" | |
845 | "pxor %[ftmp8], %[ftmp8], %[ftmp8] \n\t" | |
835 | 846 | "1: \n\t" |
836 | 847 | "gsldlc1 %[ftmp1], 0x07(%[src_ptr]) \n\t" |
837 | 848 | "gsldrc1 %[ftmp1], 0x00(%[src_ptr]) \n\t" |
844 | 855 | MMI_ADDU(%[ref_ptr], %[ref_ptr], %[ref_stride]) |
845 | 856 | "bnez %[tmp0], 1b \n\t" |
846 | 857 | |
847 | "dsrl %[ftmp9], %[ftmp6], %[ftmp10] \n\t" | |
858 | "ssrld %[ftmp9], %[ftmp6], %[ftmp10] \n\t" | |
848 | 859 | "paddw %[ftmp9], %[ftmp9], %[ftmp6] \n\t" |
849 | 860 | "swc1 %[ftmp9], 0x00(%[sse]) \n\t" |
850 | 861 | |
855 | 866 | "paddw %[ftmp3], %[ftmp3], %[ftmp4] \n\t" |
856 | 867 | "psubw %[ftmp3], %[ftmp3], %[ftmp5] \n\t" |
857 | 868 | "psubw %[ftmp3], %[ftmp3], %[ftmp6] \n\t" |
858 | "dsrl %[ftmp0], %[ftmp3], %[ftmp10] \n\t" | |
869 | "ssrld %[ftmp0], %[ftmp3], %[ftmp10] \n\t" | |
859 | 870 | "paddw %[ftmp0], %[ftmp0], %[ftmp3] \n\t" |
860 | 871 | "swc1 %[ftmp0], 0x00(%[sum]) \n\t" |
861 | 872 | : [ftmp0]"=&f"(ftmp[0]), [ftmp1]"=&f"(ftmp[1]), |
871 | 882 | [high]"r"(&high), [sse]"r"(sse), [sum]"r"(&sum) |
872 | 883 | : "memory" |
873 | 884 | ); |
885 | /* clang-format on */ | |
874 | 886 | |
875 | 887 | return *sse - (((int64_t)sum * sum) / (4 * high)); |
876 | 888 | } |
893 | 905 | |
894 | 906 | *sse = 0; |
895 | 907 | |
908 | /* clang-format off */ | |
896 | 909 | __asm__ volatile ( |
897 | 910 | "li %[tmp0], 0x20 \n\t" |
898 | 911 | "mtc1 %[tmp0], %[ftmp11] \n\t" |
899 | 912 | MMI_L(%[tmp0], %[high], 0x00) |
900 | "xor %[ftmp0], %[ftmp0], %[ftmp0] \n\t" | |
901 | "xor %[ftmp8], %[ftmp8], %[ftmp8] \n\t" | |
913 | "pxor %[ftmp0], %[ftmp0], %[ftmp0] \n\t" | |
914 | "pxor %[ftmp8], %[ftmp8], %[ftmp8] \n\t" | |
902 | 915 | |
903 | 916 | "1: \n\t" |
904 | 917 | VARIANCE_SSE_16 |
908 | 921 | MMI_ADDU(%[ref_ptr], %[ref_ptr], %[ref_stride]) |
909 | 922 | "bnez %[tmp0], 1b \n\t" |
910 | 923 | |
911 | "dsrl %[ftmp9], %[ftmp8], %[ftmp11] \n\t" | |
924 | "ssrld %[ftmp9], %[ftmp8], %[ftmp11] \n\t" | |
912 | 925 | "paddw %[ftmp9], %[ftmp9], %[ftmp8] \n\t" |
913 | 926 | "swc1 %[ftmp9], 0x00(%[sse]) \n\t" |
914 | 927 | : [ftmp0]"=&f"(ftmp[0]), [ftmp1]"=&f"(ftmp[1]), |
924 | 937 | [high]"r"(&high), [sse]"r"(sse) |
925 | 938 | : "memory" |
926 | 939 | ); |
940 | /* clang-format on */ | |
927 | 941 | |
928 | 942 | return *sse; |
929 | 943 | } |
946 | 960 | |
947 | 961 | *sse = 0; |
948 | 962 | |
963 | /* clang-format off */ | |
949 | 964 | __asm__ volatile ( |
950 | 965 | "li %[tmp0], 0x20 \n\t" |
951 | 966 | "mtc1 %[tmp0], %[ftmp11] \n\t" |
952 | 967 | MMI_L(%[tmp0], %[high], 0x00) |
953 | "xor %[ftmp0], %[ftmp0], %[ftmp0] \n\t" | |
954 | "xor %[ftmp8], %[ftmp8], %[ftmp8] \n\t" | |
968 | "pxor %[ftmp0], %[ftmp0], %[ftmp0] \n\t" | |
969 | "pxor %[ftmp8], %[ftmp8], %[ftmp8] \n\t" | |
955 | 970 | |
956 | 971 | "1: \n\t" |
957 | 972 | VARIANCE_SSE_8 |
961 | 976 | MMI_ADDU(%[ref_ptr], %[ref_ptr], %[ref_stride]) |
962 | 977 | "bnez %[tmp0], 1b \n\t" |
963 | 978 | |
964 | "dsrl %[ftmp9], %[ftmp8], %[ftmp11] \n\t" | |
979 | "ssrld %[ftmp9], %[ftmp8], %[ftmp11] \n\t" | |
965 | 980 | "paddw %[ftmp9], %[ftmp9], %[ftmp8] \n\t" |
966 | 981 | "swc1 %[ftmp9], 0x00(%[sse]) \n\t" |
967 | 982 | : [ftmp0]"=&f"(ftmp[0]), [ftmp1]"=&f"(ftmp[1]), |
977 | 992 | [high]"r"(&high), [sse]"r"(sse) |
978 | 993 | : "memory" |
979 | 994 | ); |
995 | /* clang-format on */ | |
980 | 996 | |
981 | 997 | return *sse; |
982 | 998 | } |
1020 | 1036 | uint8_t *temp2_ptr = temp2; |
1021 | 1037 | mips_reg l_counter = counter; |
1022 | 1038 | double ftmp[15]; |
1039 | double ff_ph_40, mask; | |
1040 | double filter_x0, filter_x1, filter_y0, filter_y1; | |
1023 | 1041 | mips_reg tmp[2]; |
1024 | DECLARE_ALIGNED(8, const uint64_t, ff_ph_40) = { 0x0040004000400040ULL }; | |
1025 | DECLARE_ALIGNED(8, const uint64_t, mask) = { 0x00ff00ff00ff00ffULL }; | |
1042 | uint64_t x0, x1, y0, y1, all; | |
1026 | 1043 | |
1027 | 1044 | const uint8_t *filter_x = bilinear_filters[x_offset]; |
1028 | 1045 | const uint8_t *filter_y = bilinear_filters[y_offset]; |
1029 | ||
1046 | x0 = (uint64_t)filter_x[0]; | |
1047 | x1 = (uint64_t)filter_x[1]; | |
1048 | y0 = (uint64_t)filter_y[0]; | |
1049 | y1 = (uint64_t)filter_y[1]; | |
1050 | all = x0 | x1 << 8 | y0 << 16 | y1 << 24; | |
1051 | ||
1052 | /* clang-format off */ | |
1030 | 1053 | __asm__ volatile ( |
1031 | "xor %[ftmp0], %[ftmp0], %[ftmp0] \n\t" | |
1054 | "pxor %[ftmp0], %[ftmp0], %[ftmp0] \n\t" | |
1055 | MMI_MTC1(%[all], %[ftmp14]) | |
1056 | "punpcklbh %[ftmp14], %[ftmp14], %[ftmp0] \n\t" | |
1057 | "pshufh %[filter_x0], %[ftmp14], %[ftmp0] \n\t" | |
1058 | MMI_LI(%[tmp0], 0x10) | |
1059 | MMI_MTC1(%[tmp0], %[mask]) | |
1060 | "ssrld %[ftmp14], %[ftmp14], %[mask] \n\t" | |
1061 | "pshufh %[filter_x1], %[ftmp14], %[ftmp0] \n\t" | |
1062 | "ssrld %[ftmp14], %[ftmp14], %[mask] \n\t" | |
1063 | "pshufh %[filter_y0], %[ftmp14], %[ftmp0] \n\t" | |
1064 | "ssrld %[ftmp14], %[ftmp14], %[mask] \n\t" | |
1065 | "pshufh %[filter_y1], %[ftmp14], %[ftmp0] \n\t" | |
1032 | 1066 | MMI_LI(%[tmp0], 0x07) |
1033 | 1067 | MMI_MTC1(%[tmp0], %[ftmp14]) |
1034 | "pshufh %[filter_x0], %[filter_x0], %[ftmp0] \n\t" | |
1035 | "pshufh %[filter_x1], %[filter_x1], %[ftmp0] \n\t" | |
1036 | "pshufh %[filter_y0], %[filter_y0], %[ftmp0] \n\t" | |
1037 | "pshufh %[filter_y1], %[filter_y1], %[ftmp0] \n\t" | |
1038 | ||
1068 | MMI_LI(%[tmp0], 0x0040004000400040) | |
1069 | MMI_MTC1(%[tmp0], %[ff_ph_40]) | |
1070 | MMI_LI(%[tmp0], 0x00ff00ff00ff00ff) | |
1071 | MMI_MTC1(%[tmp0], %[mask]) | |
1039 | 1072 | // fdata3: fdata3[0] ~ fdata3[15] |
1040 | 1073 | VAR_FILTER_BLOCK2D_BIL_FIRST_PASS_16_A |
1041 | 1074 | |
1071 | 1104 | [ftmp11] "=&f"(ftmp[11]), [ftmp12] "=&f"(ftmp[12]), |
1072 | 1105 | [ftmp13] "=&f"(ftmp[13]), [ftmp14] "=&f"(ftmp[14]), |
1073 | 1106 | [tmp0] "=&r"(tmp[0]), [src_ptr] "+&r"(src_ptr), [temp2_ptr] "+&r"(temp2_ptr), |
1074 | [counter]"+&r"(l_counter) | |
1075 | : [filter_x0] "f"((uint64_t)filter_x[0]), | |
1076 | [filter_x1] "f"((uint64_t)filter_x[1]), | |
1077 | [filter_y0] "f"((uint64_t)filter_y[0]), | |
1078 | [filter_y1] "f"((uint64_t)filter_y[1]), | |
1079 | [src_stride] "r"((mips_reg)src_stride), [ff_ph_40] "f"(ff_ph_40), | |
1080 | [mask] "f"(mask) | |
1107 | [counter]"+&r"(l_counter), [ff_ph_40] "=&f"(ff_ph_40), [mask] "=&f"(mask), | |
1108 | [filter_x0] "=&f"(filter_x0), [filter_x1] "=&f"(filter_x1), | |
1109 | [filter_y0] "=&f"(filter_y0), [filter_y1] "=&f"(filter_y1) | |
1110 | : [src_stride] "r"((mips_reg)src_stride), [all] "r"(all) | |
1081 | 1111 | : "memory" |
1082 | 1112 | ); |
1113 | /* clang-format on */ | |
1083 | 1114 | } |
1084 | 1115 | |
1085 | 1116 | #define SUBPIX_VAR16XN(H) \ |
1104 | 1135 | mips_reg l_counter = counter; |
1105 | 1136 | double ftmp[15]; |
1106 | 1137 | mips_reg tmp[2]; |
1107 | DECLARE_ALIGNED(8, const uint64_t, ff_ph_40) = { 0x0040004000400040ULL }; | |
1108 | DECLARE_ALIGNED(8, const uint64_t, mask) = { 0x00ff00ff00ff00ffULL }; | |
1138 | double ff_ph_40, mask; | |
1139 | uint64_t x0, x1, y0, y1, all; | |
1140 | double filter_x0, filter_x1, filter_y0, filter_y1; | |
1109 | 1141 | const uint8_t *filter_x = bilinear_filters[x_offset]; |
1110 | 1142 | const uint8_t *filter_y = bilinear_filters[y_offset]; |
1111 | ||
1143 | x0 = (uint64_t)filter_x[0]; | |
1144 | x1 = (uint64_t)filter_x[1]; | |
1145 | y0 = (uint64_t)filter_y[0]; | |
1146 | y1 = (uint64_t)filter_y[1]; | |
1147 | all = x0 | x1 << 8 | y0 << 16 | y1 << 24; | |
1148 | ||
1149 | /* clang-format off */ | |
1112 | 1150 | __asm__ volatile ( |
1113 | "xor %[ftmp0], %[ftmp0], %[ftmp0] \n\t" | |
1151 | "pxor %[ftmp0], %[ftmp0], %[ftmp0] \n\t" | |
1152 | MMI_MTC1(%[all], %[ftmp14]) | |
1153 | "punpcklbh %[ftmp14], %[ftmp14], %[ftmp0] \n\t" | |
1154 | "pshufh %[filter_x0], %[ftmp14], %[ftmp0] \n\t" | |
1155 | MMI_LI(%[tmp0], 0x10) | |
1156 | MMI_MTC1(%[tmp0], %[mask]) | |
1157 | "ssrld %[ftmp14], %[ftmp14], %[mask] \n\t" | |
1158 | "pshufh %[filter_x1], %[ftmp14], %[ftmp0] \n\t" | |
1159 | "ssrld %[ftmp14], %[ftmp14], %[mask] \n\t" | |
1160 | "pshufh %[filter_y0], %[ftmp14], %[ftmp0] \n\t" | |
1161 | "ssrld %[ftmp14], %[ftmp14], %[mask] \n\t" | |
1162 | "pshufh %[filter_y1], %[ftmp14], %[ftmp0] \n\t" | |
1163 | "pxor %[ftmp0], %[ftmp0], %[ftmp0] \n\t" | |
1114 | 1164 | MMI_LI(%[tmp0], 0x07) |
1115 | 1165 | MMI_MTC1(%[tmp0], %[ftmp14]) |
1116 | "pshufh %[filter_x0], %[filter_x0], %[ftmp0] \n\t" | |
1117 | "pshufh %[filter_x1], %[filter_x1], %[ftmp0] \n\t" | |
1118 | "pshufh %[filter_y0], %[filter_y0], %[ftmp0] \n\t" | |
1119 | "pshufh %[filter_y1], %[filter_y1], %[ftmp0] \n\t" | |
1166 | MMI_LI(%[tmp0], 0x0040004000400040) | |
1167 | MMI_MTC1(%[tmp0], %[ff_ph_40]) | |
1168 | MMI_LI(%[tmp0], 0x00ff00ff00ff00ff) | |
1169 | MMI_MTC1(%[tmp0], %[mask]) | |
1120 | 1170 | |
1121 | 1171 | // fdata3: fdata3[0] ~ fdata3[7] |
1122 | 1172 | VAR_FILTER_BLOCK2D_BIL_FIRST_PASS_8_A |
1153 | 1203 | [ftmp11] "=&f"(ftmp[11]), [ftmp12] "=&f"(ftmp[12]), |
1154 | 1204 | [ftmp13] "=&f"(ftmp[13]), [ftmp14] "=&f"(ftmp[14]), |
1155 | 1205 | [tmp0] "=&r"(tmp[0]), [src_ptr] "+&r"(src_ptr), [temp2_ptr] "+&r"(temp2_ptr), |
1156 | [counter]"+&r"(l_counter) | |
1157 | : [filter_x0] "f"((uint64_t)filter_x[0]), | |
1158 | [filter_x1] "f"((uint64_t)filter_x[1]), | |
1159 | [filter_y0] "f"((uint64_t)filter_y[0]), | |
1160 | [filter_y1] "f"((uint64_t)filter_y[1]), | |
1161 | [src_stride] "r"((mips_reg)src_stride), [ff_ph_40] "f"(ff_ph_40), | |
1162 | [mask] "f"(mask) | |
1206 | [counter]"+&r"(l_counter), [ff_ph_40] "=&f"(ff_ph_40), [mask] "=&f"(mask), | |
1207 | [filter_x0] "=&f"(filter_x0), [filter_x1] "=&f"(filter_x1), | |
1208 | [filter_y0] "=&f"(filter_y0), [filter_y1] "=&f"(filter_y1) | |
1209 | : [src_stride] "r"((mips_reg)src_stride), [all] "r"(all) | |
1163 | 1210 | : "memory" |
1164 | 1211 | ); |
1212 | /* clang-format on */ | |
1165 | 1213 | } |
1166 | 1214 | |
1167 | 1215 | #define SUBPIX_VAR8XN(H) \ |
1187 | 1235 | mips_reg l_counter = counter; |
1188 | 1236 | double ftmp[7]; |
1189 | 1237 | mips_reg tmp[2]; |
1190 | DECLARE_ALIGNED(8, const uint64_t, ff_ph_40) = { 0x0040004000400040ULL }; | |
1191 | DECLARE_ALIGNED(8, const uint64_t, mask) = { 0x00ff00ff00ff00ffULL }; | |
1238 | double ff_ph_40, mask; | |
1239 | uint64_t x0, x1, y0, y1, all; | |
1240 | double filter_x0, filter_x1, filter_y0, filter_y1; | |
1192 | 1241 | const uint8_t *filter_x = bilinear_filters[x_offset]; |
1193 | 1242 | const uint8_t *filter_y = bilinear_filters[y_offset]; |
1194 | ||
1243 | x0 = (uint64_t)filter_x[0]; | |
1244 | x1 = (uint64_t)filter_x[1]; | |
1245 | y0 = (uint64_t)filter_y[0]; | |
1246 | y1 = (uint64_t)filter_y[1]; | |
1247 | all = x0 | x1 << 8 | y0 << 16 | y1 << 24; | |
1248 | ||
1249 | /* clang-format off */ | |
1195 | 1250 | __asm__ volatile ( |
1196 | "xor %[ftmp0], %[ftmp0], %[ftmp0] \n\t" | |
1251 | "pxor %[ftmp0], %[ftmp0], %[ftmp0] \n\t" | |
1252 | MMI_MTC1(%[all], %[ftmp6]) | |
1253 | "punpcklbh %[ftmp6], %[ftmp6], %[ftmp0] \n\t" | |
1254 | "pshufh %[filter_x0], %[ftmp6], %[ftmp0] \n\t" | |
1255 | MMI_LI(%[tmp0], 0x10) | |
1256 | MMI_MTC1(%[tmp0], %[mask]) | |
1257 | "ssrld %[ftmp6], %[ftmp6], %[mask] \n\t" | |
1258 | "pshufh %[filter_x1], %[ftmp6], %[ftmp0] \n\t" | |
1259 | "ssrld %[ftmp6], %[ftmp6], %[mask] \n\t" | |
1260 | "pshufh %[filter_y0], %[ftmp6], %[ftmp0] \n\t" | |
1261 | "ssrld %[ftmp6], %[ftmp6], %[mask] \n\t" | |
1262 | "pshufh %[filter_y1], %[ftmp6], %[ftmp0] \n\t" | |
1263 | "pxor %[ftmp0], %[ftmp0], %[ftmp0] \n\t" | |
1197 | 1264 | MMI_LI(%[tmp0], 0x07) |
1198 | 1265 | MMI_MTC1(%[tmp0], %[ftmp6]) |
1199 | "pshufh %[filter_x0], %[filter_x0], %[ftmp0] \n\t" | |
1200 | "pshufh %[filter_x1], %[filter_x1], %[ftmp0] \n\t" | |
1201 | "pshufh %[filter_y0], %[filter_y0], %[ftmp0] \n\t" | |
1202 | "pshufh %[filter_y1], %[filter_y1], %[ftmp0] \n\t" | |
1266 | MMI_LI(%[tmp0], 0x0040004000400040) | |
1267 | MMI_MTC1(%[tmp0], %[ff_ph_40]) | |
1268 | MMI_LI(%[tmp0], 0x00ff00ff00ff00ff) | |
1269 | MMI_MTC1(%[tmp0], %[mask]) | |
1203 | 1270 | // fdata3: fdata3[0] ~ fdata3[3] |
1204 | 1271 | VAR_FILTER_BLOCK2D_BIL_FIRST_PASS_4_A |
1205 | 1272 | |
1231 | 1298 | : [ftmp0] "=&f"(ftmp[0]), [ftmp1] "=&f"(ftmp[1]), [ftmp2] "=&f"(ftmp[2]), |
1232 | 1299 | [ftmp3] "=&f"(ftmp[3]), [ftmp4] "=&f"(ftmp[4]), [ftmp5] "=&f"(ftmp[5]), |
1233 | 1300 | [ftmp6] "=&f"(ftmp[6]), [tmp0] "=&r"(tmp[0]), [src_ptr] "+&r"(src_ptr), |
1234 | [temp2_ptr] "+&r"(temp2_ptr), [counter]"+&r"(l_counter) | |
1235 | : [filter_x0] "f"((uint64_t)filter_x[0]), | |
1236 | [filter_x1] "f"((uint64_t)filter_x[1]), | |
1237 | [filter_y0] "f"((uint64_t)filter_y[0]), | |
1238 | [filter_y1] "f"((uint64_t)filter_y[1]), | |
1239 | [src_stride] "r"((mips_reg)src_stride), [ff_ph_40] "f"(ff_ph_40), | |
1240 | [mask] "f"(mask) | |
1301 | [temp2_ptr] "+&r"(temp2_ptr), [counter]"+&r"(l_counter), | |
1302 | [ff_ph_40] "=&f"(ff_ph_40), [mask] "=&f"(mask), | |
1303 | [filter_x0] "=&f"(filter_x0), [filter_x1] "=&f"(filter_x1), | |
1304 | [filter_y0] "=&f"(filter_y0), [filter_y1] "=&f"(filter_y1) | |
1305 | : [src_stride] "r"((mips_reg)src_stride), [all] "r"(all) | |
1241 | 1306 | : "memory" |
1242 | 1307 | ); |
1308 | /* clang-format on */ | |
1243 | 1309 | } |
1244 | 1310 | |
1245 | 1311 | #define SUBPIX_VAR4XN(H) \ |
104 | 104 | /* clang-format off */ |
105 | 105 | __asm__ volatile( |
106 | 106 | "move %[tmp1], %[width] \n\t" |
107 | "xor %[ftmp0], %[ftmp0], %[ftmp0] \n\t" | |
107 | "pxor %[ftmp0], %[ftmp0], %[ftmp0] \n\t" | |
108 | 108 | "gsldlc1 %[filter1], 0x03(%[filter]) \n\t" |
109 | 109 | "gsldrc1 %[filter1], 0x00(%[filter]) \n\t" |
110 | 110 | "gsldlc1 %[filter2], 0x0b(%[filter]) \n\t" |
177 | 177 | (void)y_step_q4; |
178 | 178 | |
179 | 179 | __asm__ volatile( |
180 | "xor %[ftmp0], %[ftmp0], %[ftmp0] \n\t" | |
180 | "pxor %[ftmp0], %[ftmp0], %[ftmp0] \n\t" | |
181 | 181 | "gsldlc1 %[ftmp4], 0x03(%[filter]) \n\t" |
182 | 182 | "gsldrc1 %[ftmp4], 0x00(%[filter]) \n\t" |
183 | 183 | "gsldlc1 %[ftmp5], 0x0b(%[filter]) \n\t" |
270 | 270 | |
271 | 271 | __asm__ volatile( |
272 | 272 | "move %[tmp1], %[width] \n\t" |
273 | "xor %[ftmp0], %[ftmp0], %[ftmp0] \n\t" | |
273 | "pxor %[ftmp0], %[ftmp0], %[ftmp0] \n\t" | |
274 | 274 | "gsldlc1 %[filter1], 0x03(%[filter]) \n\t" |
275 | 275 | "gsldrc1 %[filter1], 0x00(%[filter]) \n\t" |
276 | 276 | "gsldlc1 %[filter2], 0x0b(%[filter]) \n\t" |
353 | 353 | (void)y_step_q4; |
354 | 354 | |
355 | 355 | __asm__ volatile( |
356 | "xor %[ftmp0], %[ftmp0], %[ftmp0] \n\t" | |
356 | "pxor %[ftmp0], %[ftmp0], %[ftmp0] \n\t" | |
357 | 357 | "gsldlc1 %[ftmp4], 0x03(%[filter]) \n\t" |
358 | 358 | "gsldrc1 %[ftmp4], 0x00(%[filter]) \n\t" |
359 | 359 | "gsldlc1 %[ftmp5], 0x0b(%[filter]) \n\t" |
466 | 466 | |
467 | 467 | __asm__ volatile( |
468 | 468 | "move %[tmp1], %[width] \n\t" |
469 | "xor %[ftmp0], %[ftmp0], %[ftmp0] \n\t" | |
469 | "pxor %[ftmp0], %[ftmp0], %[ftmp0] \n\t" | |
470 | 470 | "li %[tmp0], 0x10001 \n\t" |
471 | 471 | MMI_MTC1(%[tmp0], %[ftmp3]) |
472 | 472 | "punpcklhw %[ftmp3], %[ftmp3], %[ftmp3] \n\t" |
33 | 33 | "ld " #reg ", " #bias "(" #addr ") \n\t" |
34 | 34 | |
35 | 35 | #define MMI_SRL(reg1, reg2, shift) \ |
36 | "dsrl " #reg1 ", " #reg2 ", " #shift " \n\t" | |
36 | "ssrld " #reg1 ", " #reg2 ", " #shift " \n\t" | |
37 | 37 | |
38 | 38 | #define MMI_SLL(reg1, reg2, shift) \ |
39 | 39 | "dsll " #reg1 ", " #reg2 ", " #shift " \n\t" |
62 | 62 | "lw " #reg ", " #bias "(" #addr ") \n\t" |
63 | 63 | |
64 | 64 | #define MMI_SRL(reg1, reg2, shift) \ |
65 | "srl " #reg1 ", " #reg2 ", " #shift " \n\t" | |
65 | "ssrlw " #reg1 ", " #reg2 ", " #shift " \n\t" | |
66 | 66 | |
67 | 67 | #define MMI_SLL(reg1, reg2, shift) \ |
68 | 68 | "sll " #reg1 ", " #reg2 ", " #shift " \n\t" |
0 | /* | |
1 | * Copyright (c) 2020 The WebM project authors. All Rights Reserved. | |
2 | * | |
3 | * Use of this source code is governed by a BSD-style license | |
4 | * that can be found in the LICENSE file in the root of the source | |
5 | * tree. An additional intellectual property rights grant can be found | |
6 | * in the file PATENTS. All contributing project authors may | |
7 | * be found in the AUTHORS file in the root of the source tree. | |
8 | */ | |
9 | ||
10 | #ifndef VPX_PORTS_MIPS_H_ | |
11 | #define VPX_PORTS_MIPS_H_ | |
12 | ||
13 | #ifdef __cplusplus | |
14 | extern "C" { | |
15 | #endif | |
16 | ||
17 | #define HAS_MMI 0x01 | |
18 | #define HAS_MSA 0x02 | |
19 | ||
20 | int mips_cpu_caps(void); | |
21 | ||
22 | #ifdef __cplusplus | |
23 | } // extern "C" | |
24 | #endif | |
25 | ||
26 | #endif // VPX_PORTS_MIPS_H_ |
0 | /* | |
1 | * Copyright (c) 2020 The WebM project authors. All Rights Reserved. | |
2 | * | |
3 | * Use of this source code is governed by a BSD-style license | |
4 | * that can be found in the LICENSE file in the root of the source | |
5 | * tree. An additional intellectual property rights grant can be found | |
6 | * in the file PATENTS. All contributing project authors may | |
7 | * be found in the AUTHORS file in the root of the source tree. | |
8 | */ | |
9 | #include <stdio.h> | |
10 | #include <string.h> | |
11 | #include "./vpx_config.h" | |
12 | #include "vpx_ports/mips.h" | |
13 | ||
14 | #if CONFIG_RUNTIME_CPU_DETECT | |
15 | #if defined(__mips__) && defined(__linux__) | |
16 | int mips_cpu_caps(void) { | |
17 | char cpuinfo_line[512]; | |
18 | int flag = 0x0; | |
19 | FILE *f = fopen("/proc/cpuinfo", "r"); | |
20 | if (!f) { | |
21 | // Assume nothing if /proc/cpuinfo is unavailable. | |
22 | // This will occur for Chrome sandbox for Pepper or Render process. | |
23 | return 0; | |
24 | } | |
25 | while (fgets(cpuinfo_line, sizeof(cpuinfo_line) - 1, f)) { | |
26 | if (memcmp(cpuinfo_line, "cpu model", 9) == 0) { | |
27 | // Workaround early kernel without mmi in ASEs line. | |
28 | if (strstr(cpuinfo_line, "Loongson-3")) { | |
29 | flag |= HAS_MMI; | |
30 | } else if (strstr(cpuinfo_line, "Loongson-2K")) { | |
31 | flag |= HAS_MMI | HAS_MSA; | |
32 | } | |
33 | } | |
34 | if (memcmp(cpuinfo_line, "ASEs implemented", 16) == 0) { | |
35 | if (strstr(cpuinfo_line, "loongson-mmi") && | |
36 | strstr(cpuinfo_line, "loongson-ext")) { | |
37 | flag |= HAS_MMI; | |
38 | } | |
39 | if (strstr(cpuinfo_line, "msa")) { | |
40 | flag |= HAS_MSA; | |
41 | } | |
42 | // ASEs is the last line, so we can break here. | |
43 | break; | |
44 | } | |
45 | } | |
46 | fclose(f); | |
47 | return flag; | |
48 | } | |
49 | #else /* end __mips__ && __linux__ */ | |
50 | #error \ | |
51 | "--enable-runtime-cpu-detect selected, but no CPU detection method " \ | |
52 | "available for your platform. Reconfigure with --disable-runtime-cpu-detect." | |
53 | #endif | |
54 | #else /* end CONFIG_RUNTIME_CPU_DETECT */ | |
55 | int mips_cpu_caps(void) { return 0; } | |
56 | #endif |
41 | 41 | PORTS_SRCS-$(VPX_ARCH_PPC) += ppc_cpudetect.c |
42 | 42 | PORTS_SRCS-$(VPX_ARCH_PPC) += ppc.h |
43 | 43 | |
44 | PORTS_SRCS-$(VPX_ARCH_MIPS) += mips_cpudetect.c | |
45 | PORTS_SRCS-$(VPX_ARCH_MIPS) += mips.h | |
46 | ||
44 | 47 | ifeq ($(VPX_ARCH_MIPS), yes) |
45 | 48 | PORTS_SRCS-yes += asmdefs_mmi.h |
46 | 49 | endif |
464 | 464 | static const arg_def_t row_mt = |
465 | 465 | ARG_DEF(NULL, "row-mt", 1, |
466 | 466 | "Enable row based non-deterministic multi-threading in VP9"); |
467 | ||
468 | static const arg_def_t disable_loopfilter = | |
469 | ARG_DEF(NULL, "disable-loopfilter", 1, | |
470 | "Control Loopfilter in VP9\n" | |
471 | "0: Loopfilter on for all frames (default)\n" | |
472 | "1: Loopfilter off for non reference frames\n" | |
473 | "2: Loopfilter off for all frames"); | |
467 | 474 | #endif |
468 | 475 | |
469 | 476 | #if CONFIG_VP9_ENCODER |
494 | 501 | &max_gf_interval, |
495 | 502 | &target_level, |
496 | 503 | &row_mt, |
504 | &disable_loopfilter, | |
505 | // NOTE: The entries above have a corresponding entry in vp9_arg_ctrl_map. The | |
506 | // entries below do not have a corresponding entry in vp9_arg_ctrl_map. They | |
507 | // must be listed at the end of vp9_args. | |
497 | 508 | #if CONFIG_VP9_HIGHBITDEPTH |
498 | 509 | &bitdeptharg, |
499 | 510 | &inbitdeptharg, |
526 | 537 | VP9E_SET_MAX_GF_INTERVAL, |
527 | 538 | VP9E_SET_TARGET_LEVEL, |
528 | 539 | VP9E_SET_ROW_MT, |
540 | VP9E_SET_DISABLE_LOOPFILTER, | |
529 | 541 | 0 }; |
530 | 542 | #endif |
531 | 543 | |
1623 | 1635 | int res = 0; |
1624 | 1636 | |
1625 | 1637 | memset(&input, 0, sizeof(input)); |
1638 | memset(&raw, 0, sizeof(raw)); | |
1626 | 1639 | exec_name = argv_[0]; |
1627 | 1640 | |
1628 | 1641 | /* Setup default input stream settings */ |
1768 | 1781 | FOREACH_STREAM(show_stream_config(stream, &global, &input)); |
1769 | 1782 | |
1770 | 1783 | if (pass == (global.pass ? global.pass - 1 : 0)) { |
1771 | if (input.file_type == FILE_TYPE_Y4M) | |
1772 | /*The Y4M reader does its own allocation. | |
1773 | Just initialize this here to avoid problems if we never read any | |
1774 | frames.*/ | |
1775 | memset(&raw, 0, sizeof(raw)); | |
1776 | else | |
1784 | // The Y4M reader does its own allocation. | |
1785 | if (input.file_type != FILE_TYPE_Y4M) { | |
1777 | 1786 | vpx_img_alloc(&raw, input.fmt, input.width, input.height, 32); |
1778 | ||
1787 | } | |
1779 | 1788 | FOREACH_STREAM(stream->rate_hist = init_rate_histogram( |
1780 | 1789 | &stream->config.cfg, &global.framerate)); |
1781 | 1790 | } |
18 | 18 | namespace { |
19 | 19 | |
20 | 20 | void reset(struct WebmInputContext *const webm_ctx) { |
21 | if (webm_ctx->reader != NULL) { | |
21 | if (webm_ctx->reader != nullptr) { | |
22 | 22 | mkvparser::MkvReader *const reader = |
23 | 23 | reinterpret_cast<mkvparser::MkvReader *>(webm_ctx->reader); |
24 | 24 | delete reader; |
25 | 25 | } |
26 | if (webm_ctx->segment != NULL) { | |
26 | if (webm_ctx->segment != nullptr) { | |
27 | 27 | mkvparser::Segment *const segment = |
28 | 28 | reinterpret_cast<mkvparser::Segment *>(webm_ctx->segment); |
29 | 29 | delete segment; |
30 | 30 | } |
31 | if (webm_ctx->buffer != NULL) { | |
31 | if (webm_ctx->buffer != nullptr) { | |
32 | 32 | delete[] webm_ctx->buffer; |
33 | 33 | } |
34 | webm_ctx->reader = NULL; | |
35 | webm_ctx->segment = NULL; | |
36 | webm_ctx->buffer = NULL; | |
37 | webm_ctx->cluster = NULL; | |
38 | webm_ctx->block_entry = NULL; | |
39 | webm_ctx->block = NULL; | |
34 | webm_ctx->reader = nullptr; | |
35 | webm_ctx->segment = nullptr; | |
36 | webm_ctx->buffer = nullptr; | |
37 | webm_ctx->cluster = nullptr; | |
38 | webm_ctx->block_entry = nullptr; | |
39 | webm_ctx->block = nullptr; | |
40 | 40 | webm_ctx->block_frame_index = 0; |
41 | 41 | webm_ctx->video_track_index = 0; |
42 | 42 | webm_ctx->timestamp_ns = 0; |
83 | 83 | } |
84 | 84 | |
85 | 85 | const mkvparser::Tracks *const tracks = segment->GetTracks(); |
86 | const mkvparser::VideoTrack *video_track = NULL; | |
86 | const mkvparser::VideoTrack *video_track = nullptr; | |
87 | 87 | for (unsigned long i = 0; i < tracks->GetTracksCount(); ++i) { |
88 | 88 | const mkvparser::Track *const track = tracks->GetTrackByIndex(i); |
89 | 89 | if (track->GetType() == mkvparser::Track::kVideo) { |
93 | 93 | } |
94 | 94 | } |
95 | 95 | |
96 | if (video_track == NULL || video_track->GetCodecId() == NULL) { | |
96 | if (video_track == nullptr || video_track->GetCodecId() == nullptr) { | |
97 | 97 | rewind_and_reset(webm_ctx, vpx_ctx); |
98 | 98 | return 0; |
99 | 99 | } |
136 | 136 | do { |
137 | 137 | long status = 0; |
138 | 138 | bool get_new_block = false; |
139 | if (block_entry == NULL && !block_entry_eos) { | |
139 | if (block_entry == nullptr && !block_entry_eos) { | |
140 | 140 | status = cluster->GetFirst(block_entry); |
141 | 141 | get_new_block = true; |
142 | 142 | } else if (block_entry_eos || block_entry->EOS()) { |
143 | 143 | cluster = segment->GetNext(cluster); |
144 | if (cluster == NULL || cluster->EOS()) { | |
144 | if (cluster == nullptr || cluster->EOS()) { | |
145 | 145 | *buffer_size = 0; |
146 | 146 | webm_ctx->reached_eos = 1; |
147 | 147 | return 1; |
149 | 149 | status = cluster->GetFirst(block_entry); |
150 | 150 | block_entry_eos = false; |
151 | 151 | get_new_block = true; |
152 | } else if (block == NULL || | |
152 | } else if (block == nullptr || | |
153 | 153 | webm_ctx->block_frame_index == block->GetFrameCount() || |
154 | 154 | block->GetTrackNumber() != webm_ctx->video_track_index) { |
155 | 155 | status = cluster->GetNext(block_entry, block_entry); |
156 | if (block_entry == NULL || block_entry->EOS()) { | |
156 | if (block_entry == nullptr || block_entry->EOS()) { | |
157 | 157 | block_entry_eos = true; |
158 | 158 | continue; |
159 | 159 | } |
160 | 160 | get_new_block = true; |
161 | 161 | } |
162 | if (status || block_entry == NULL) { | |
162 | if (status || block_entry == nullptr) { | |
163 | 163 | return -1; |
164 | 164 | } |
165 | 165 | if (get_new_block) { |
166 | 166 | block = block_entry->GetBlock(); |
167 | if (block == NULL) return -1; | |
167 | if (block == nullptr) return -1; | |
168 | 168 | webm_ctx->block_frame_index = 0; |
169 | 169 | } |
170 | 170 | } while (block_entry_eos || |
180 | 180 | if (frame.len > static_cast<long>(*buffer_size)) { |
181 | 181 | delete[] * buffer; |
182 | 182 | *buffer = new uint8_t[frame.len]; |
183 | if (*buffer == NULL) { | |
183 | if (*buffer == nullptr) { | |
184 | 184 | return -1; |
185 | 185 | } |
186 | 186 | webm_ctx->buffer = *buffer; |
197 | 197 | int webm_guess_framerate(struct WebmInputContext *webm_ctx, |
198 | 198 | struct VpxInputContext *vpx_ctx) { |
199 | 199 | uint32_t i = 0; |
200 | uint8_t *buffer = NULL; | |
200 | uint8_t *buffer = nullptr; | |
201 | 201 | size_t buffer_size = 0; |
202 | 202 | while (webm_ctx->timestamp_ns < 1000000000 && i < 50) { |
203 | 203 | if (webm_read_frame(webm_ctx, &buffer, &buffer_size)) { |
211 | 211 | delete[] buffer; |
212 | 212 | |
213 | 213 | get_first_cluster(webm_ctx); |
214 | webm_ctx->block = NULL; | |
215 | webm_ctx->block_entry = NULL; | |
214 | webm_ctx->block = nullptr; | |
215 | webm_ctx->block_entry = nullptr; | |
216 | 216 | webm_ctx->block_frame_index = 0; |
217 | 217 | webm_ctx->timestamp_ns = 0; |
218 | 218 | webm_ctx->reached_eos = 0; |
89 | 89 | segment->Finalize(); |
90 | 90 | delete segment; |
91 | 91 | delete writer; |
92 | webm_ctx->writer = NULL; | |
93 | webm_ctx->segment = NULL; | |
92 | webm_ctx->writer = nullptr; | |
93 | webm_ctx->segment = nullptr; | |
94 | 94 | } |
9 | 9 | * Based on code from the OggTheora software codec source code, |
10 | 10 | * Copyright (C) 2002-2010 The Xiph.Org Foundation and contributors. |
11 | 11 | */ |
12 | #include <assert.h> | |
12 | 13 | #include <errno.h> |
13 | 14 | #include <stdlib.h> |
14 | 15 | #include <string.h> |
50 | 51 | } |
51 | 52 | |
52 | 53 | static int y4m_parse_tags(y4m_input *_y4m, char *_tags) { |
53 | int got_w; | |
54 | int got_h; | |
55 | int got_fps; | |
56 | int got_interlace; | |
57 | int got_par; | |
58 | int got_chroma; | |
59 | 54 | char *p; |
60 | 55 | char *q; |
61 | got_w = got_h = got_fps = got_interlace = got_par = got_chroma = 0; | |
62 | 56 | for (p = _tags;; p = q) { |
63 | 57 | /*Skip any leading spaces.*/ |
64 | 58 | while (*p == ' ') p++; |
71 | 65 | switch (p[0]) { |
72 | 66 | case 'W': { |
73 | 67 | if (sscanf(p + 1, "%d", &_y4m->pic_w) != 1) return -1; |
74 | got_w = 1; | |
75 | 68 | break; |
76 | 69 | } |
77 | 70 | case 'H': { |
78 | 71 | if (sscanf(p + 1, "%d", &_y4m->pic_h) != 1) return -1; |
79 | got_h = 1; | |
80 | 72 | break; |
81 | 73 | } |
82 | 74 | case 'F': { |
83 | 75 | if (sscanf(p + 1, "%d:%d", &_y4m->fps_n, &_y4m->fps_d) != 2) { |
84 | 76 | return -1; |
85 | 77 | } |
86 | got_fps = 1; | |
87 | 78 | break; |
88 | 79 | } |
89 | 80 | case 'I': { |
90 | 81 | _y4m->interlace = p[1]; |
91 | got_interlace = 1; | |
92 | 82 | break; |
93 | 83 | } |
94 | 84 | case 'A': { |
95 | 85 | if (sscanf(p + 1, "%d:%d", &_y4m->par_n, &_y4m->par_d) != 2) { |
96 | 86 | return -1; |
97 | 87 | } |
98 | got_par = 1; | |
99 | 88 | break; |
100 | 89 | } |
101 | 90 | case 'C': { |
102 | 91 | if (q - p > 16) return -1; |
103 | 92 | memcpy(_y4m->chroma_type, p + 1, q - p - 1); |
104 | 93 | _y4m->chroma_type[q - p - 1] = '\0'; |
105 | got_chroma = 1; | |
106 | 94 | break; |
107 | 95 | } |
108 | 96 | /*Ignore unknown tags.*/ |
109 | 97 | } |
110 | 98 | } |
111 | if (!got_w || !got_h || !got_fps) return -1; | |
112 | if (!got_interlace) _y4m->interlace = '?'; | |
113 | if (!got_par) _y4m->par_n = _y4m->par_d = 0; | |
114 | /*Chroma-type is not specified in older files, e.g., those generated by | |
115 | mplayer.*/ | |
116 | if (!got_chroma) strcpy(_y4m->chroma_type, "420"); | |
117 | 99 | return 0; |
100 | } | |
101 | ||
102 | // Copy a single tag into the buffer, along with a null character. | |
103 | // Returns 0 if any file IO errors occur. | |
104 | static int copy_tag(char *buf, size_t buf_len, char *end_tag, FILE *file) { | |
105 | size_t i; | |
106 | assert(buf_len >= 1); | |
107 | // Skip leading space characters. | |
108 | do { | |
109 | if (!file_read(buf, 1, file)) { | |
110 | return 0; | |
111 | } | |
112 | } while (buf[0] == ' '); | |
113 | ||
114 | // If we hit the newline, treat this as the "empty" tag. | |
115 | if (buf[0] == '\n') { | |
116 | buf[0] = '\0'; | |
117 | *end_tag = '\n'; | |
118 | return 1; | |
119 | } | |
120 | ||
121 | // Copy over characters until a space is hit, or the buffer is exhausted. | |
122 | for (i = 1; i < buf_len; ++i) { | |
123 | if (!file_read(buf + i, 1, file)) { | |
124 | return 0; | |
125 | } | |
126 | if (buf[i] == ' ' || buf[i] == '\n') { | |
127 | break; | |
128 | } | |
129 | } | |
130 | if (i == buf_len) { | |
131 | fprintf(stderr, "Error: Y4M header tags must be less than %lu characters\n", | |
132 | (unsigned long)i); | |
133 | return 0; | |
134 | } | |
135 | *end_tag = buf[i]; | |
136 | buf[i] = '\0'; | |
137 | return 1; | |
138 | } | |
139 | ||
140 | /* Returns 1 if tags were parsed successfully, 0 otherwise. */ | |
141 | static int parse_tags(y4m_input *y4m_ctx, FILE *file) { | |
142 | char tag[256]; | |
143 | char end; /* Character denoting the end of the tag, ' ' or '\n'. */ | |
144 | /* Set Y4M tags to defaults, updating them as processing occurs. Mandatory | |
145 | fields are marked with -1 and will be checked after the tags are parsed. */ | |
146 | y4m_ctx->pic_w = -1; | |
147 | y4m_ctx->pic_h = -1; | |
148 | y4m_ctx->fps_n = -1; /* Also serves as marker for fps_d */ | |
149 | y4m_ctx->par_n = 0; | |
150 | y4m_ctx->par_d = 0; | |
151 | y4m_ctx->interlace = '?'; | |
152 | snprintf(y4m_ctx->chroma_type, sizeof(y4m_ctx->chroma_type), "420"); | |
153 | ||
154 | /* Find one tag at a time. */ | |
155 | do { | |
156 | if (!copy_tag(tag, sizeof(tag), &end, file)) { | |
157 | return 0; | |
158 | } | |
159 | /* y4m_parse_tags returns 0 on success. */ | |
160 | if (y4m_parse_tags(y4m_ctx, tag)) { | |
161 | return 0; | |
162 | } | |
163 | } while (end != '\n'); | |
164 | ||
165 | /* Check the mandatory fields. */ | |
166 | if (y4m_ctx->pic_w == -1) { | |
167 | fprintf(stderr, "Width field missing\n"); | |
168 | return 0; | |
169 | } | |
170 | if (y4m_ctx->pic_h == -1) { | |
171 | fprintf(stderr, "Height field missing\n"); | |
172 | return 0; | |
173 | } | |
174 | if (y4m_ctx->fps_n == -1) { | |
175 | fprintf(stderr, "FPS field missing\n"); | |
176 | return 0; | |
177 | } | |
178 | return 1; | |
118 | 179 | } |
119 | 180 | |
120 | 181 | /*All anti-aliasing filters in the following conversion functions are based on |
783 | 844 | (void)_aux; |
784 | 845 | } |
785 | 846 | |
786 | int y4m_input_open(y4m_input *_y4m, FILE *_fin, char *_skip, int _nskip, | |
787 | int only_420) { | |
788 | char buffer[80] = { 0 }; | |
789 | int ret; | |
790 | int i; | |
791 | /*Read until newline, or 80 cols, whichever happens first.*/ | |
792 | for (i = 0; i < 79; i++) { | |
793 | if (_nskip > 0) { | |
794 | buffer[i] = *_skip++; | |
795 | _nskip--; | |
796 | } else { | |
797 | if (!file_read(buffer + i, 1, _fin)) return -1; | |
798 | } | |
799 | if (buffer[i] == '\n') break; | |
800 | } | |
801 | /*We skipped too much header data.*/ | |
802 | if (_nskip > 0) return -1; | |
803 | if (i == 79) { | |
804 | fprintf(stderr, "Error parsing header; not a YUV2MPEG2 file?\n"); | |
847 | static const char TAG[] = "YUV4MPEG2"; | |
848 | ||
849 | int y4m_input_open(y4m_input *y4m_ctx, FILE *file, char *skip_buffer, | |
850 | int num_skip, int only_420) { | |
851 | // File must start with |TAG|. | |
852 | char tag_buffer[9]; // 9 == strlen(TAG) | |
853 | // Read as much as possible from |skip_buffer|, which were characters | |
854 | // that were previously read from the file to do input-type detection. | |
855 | assert(num_skip >= 0 && num_skip <= 8); | |
856 | if (num_skip > 0) { | |
857 | memcpy(tag_buffer, skip_buffer, num_skip); | |
858 | } | |
859 | // Start reading from the file now that the |skip_buffer| is depleted. | |
860 | if (!file_read(tag_buffer + num_skip, 9 - num_skip, file)) { | |
805 | 861 | return -1; |
806 | 862 | } |
807 | buffer[i] = '\0'; | |
808 | if (memcmp(buffer, "YUV4MPEG", 8)) { | |
809 | fprintf(stderr, "Incomplete magic for YUV4MPEG file.\n"); | |
863 | if (memcmp(TAG, tag_buffer, 9) != 0) { | |
864 | fprintf(stderr, "Error parsing header: must start with %s\n", TAG); | |
810 | 865 | return -1; |
811 | 866 | } |
812 | if (buffer[8] != '2') { | |
813 | fprintf(stderr, "Incorrect YUV input file version; YUV4MPEG2 required.\n"); | |
814 | } | |
815 | ret = y4m_parse_tags(_y4m, buffer + 5); | |
816 | if (ret < 0) { | |
817 | fprintf(stderr, "Error parsing YUV4MPEG2 header.\n"); | |
818 | return ret; | |
819 | } | |
820 | if (_y4m->interlace == '?') { | |
867 | // Next character must be a space. | |
868 | if (!file_read(tag_buffer, 1, file) || tag_buffer[0] != ' ') { | |
869 | fprintf(stderr, "Error parsing header: space must follow %s\n", TAG); | |
870 | return -1; | |
871 | } | |
872 | if (!parse_tags(y4m_ctx, file)) { | |
873 | fprintf(stderr, "Error parsing %s header.\n", TAG); | |
874 | } | |
875 | if (y4m_ctx->interlace == '?') { | |
821 | 876 | fprintf(stderr, |
822 | 877 | "Warning: Input video interlacing format unknown; " |
823 | 878 | "assuming progressive scan.\n"); |
824 | } else if (_y4m->interlace != 'p') { | |
879 | } else if (y4m_ctx->interlace != 'p') { | |
825 | 880 | fprintf(stderr, |
826 | 881 | "Input video is interlaced; " |
827 | 882 | "Only progressive scan handled.\n"); |
828 | 883 | return -1; |
829 | 884 | } |
830 | _y4m->vpx_fmt = VPX_IMG_FMT_I420; | |
831 | _y4m->bps = 12; | |
832 | _y4m->bit_depth = 8; | |
833 | if (strcmp(_y4m->chroma_type, "420") == 0 || | |
834 | strcmp(_y4m->chroma_type, "420jpeg") == 0) { | |
835 | _y4m->src_c_dec_h = _y4m->dst_c_dec_h = _y4m->src_c_dec_v = | |
836 | _y4m->dst_c_dec_v = 2; | |
837 | _y4m->dst_buf_read_sz = | |
838 | _y4m->pic_w * _y4m->pic_h + | |
839 | 2 * ((_y4m->pic_w + 1) / 2) * ((_y4m->pic_h + 1) / 2); | |
885 | y4m_ctx->vpx_fmt = VPX_IMG_FMT_I420; | |
886 | y4m_ctx->bps = 12; | |
887 | y4m_ctx->bit_depth = 8; | |
888 | y4m_ctx->aux_buf = NULL; | |
889 | y4m_ctx->dst_buf = NULL; | |
890 | if (strcmp(y4m_ctx->chroma_type, "420") == 0 || | |
891 | strcmp(y4m_ctx->chroma_type, "420jpeg") == 0) { | |
892 | y4m_ctx->src_c_dec_h = y4m_ctx->dst_c_dec_h = y4m_ctx->src_c_dec_v = | |
893 | y4m_ctx->dst_c_dec_v = 2; | |
894 | y4m_ctx->dst_buf_read_sz = | |
895 | y4m_ctx->pic_w * y4m_ctx->pic_h + | |
896 | 2 * ((y4m_ctx->pic_w + 1) / 2) * ((y4m_ctx->pic_h + 1) / 2); | |
840 | 897 | /* Natively supported: no conversion required. */ |
841 | _y4m->aux_buf_sz = _y4m->aux_buf_read_sz = 0; | |
842 | _y4m->convert = y4m_convert_null; | |
843 | } else if (strcmp(_y4m->chroma_type, "420p10") == 0) { | |
844 | _y4m->src_c_dec_h = 2; | |
845 | _y4m->dst_c_dec_h = 2; | |
846 | _y4m->src_c_dec_v = 2; | |
847 | _y4m->dst_c_dec_v = 2; | |
848 | _y4m->dst_buf_read_sz = | |
849 | 2 * (_y4m->pic_w * _y4m->pic_h + | |
850 | 2 * ((_y4m->pic_w + 1) / 2) * ((_y4m->pic_h + 1) / 2)); | |
898 | y4m_ctx->aux_buf_sz = y4m_ctx->aux_buf_read_sz = 0; | |
899 | y4m_ctx->convert = y4m_convert_null; | |
900 | } else if (strcmp(y4m_ctx->chroma_type, "420p10") == 0) { | |
901 | y4m_ctx->src_c_dec_h = 2; | |
902 | y4m_ctx->dst_c_dec_h = 2; | |
903 | y4m_ctx->src_c_dec_v = 2; | |
904 | y4m_ctx->dst_c_dec_v = 2; | |
905 | y4m_ctx->dst_buf_read_sz = | |
906 | 2 * (y4m_ctx->pic_w * y4m_ctx->pic_h + | |
907 | 2 * ((y4m_ctx->pic_w + 1) / 2) * ((y4m_ctx->pic_h + 1) / 2)); | |
851 | 908 | /* Natively supported: no conversion required. */ |
852 | _y4m->aux_buf_sz = _y4m->aux_buf_read_sz = 0; | |
853 | _y4m->convert = y4m_convert_null; | |
854 | _y4m->bit_depth = 10; | |
855 | _y4m->bps = 15; | |
856 | _y4m->vpx_fmt = VPX_IMG_FMT_I42016; | |
909 | y4m_ctx->aux_buf_sz = y4m_ctx->aux_buf_read_sz = 0; | |
910 | y4m_ctx->convert = y4m_convert_null; | |
911 | y4m_ctx->bit_depth = 10; | |
912 | y4m_ctx->bps = 15; | |
913 | y4m_ctx->vpx_fmt = VPX_IMG_FMT_I42016; | |
857 | 914 | if (only_420) { |
858 | 915 | fprintf(stderr, "Unsupported conversion from 420p10 to 420jpeg\n"); |
859 | 916 | return -1; |
860 | 917 | } |
861 | } else if (strcmp(_y4m->chroma_type, "420p12") == 0) { | |
862 | _y4m->src_c_dec_h = 2; | |
863 | _y4m->dst_c_dec_h = 2; | |
864 | _y4m->src_c_dec_v = 2; | |
865 | _y4m->dst_c_dec_v = 2; | |
866 | _y4m->dst_buf_read_sz = | |
867 | 2 * (_y4m->pic_w * _y4m->pic_h + | |
868 | 2 * ((_y4m->pic_w + 1) / 2) * ((_y4m->pic_h + 1) / 2)); | |
918 | } else if (strcmp(y4m_ctx->chroma_type, "420p12") == 0) { | |
919 | y4m_ctx->src_c_dec_h = 2; | |
920 | y4m_ctx->dst_c_dec_h = 2; | |
921 | y4m_ctx->src_c_dec_v = 2; | |
922 | y4m_ctx->dst_c_dec_v = 2; | |
923 | y4m_ctx->dst_buf_read_sz = | |
924 | 2 * (y4m_ctx->pic_w * y4m_ctx->pic_h + | |
925 | 2 * ((y4m_ctx->pic_w + 1) / 2) * ((y4m_ctx->pic_h + 1) / 2)); | |
869 | 926 | /* Natively supported: no conversion required. */ |
870 | _y4m->aux_buf_sz = _y4m->aux_buf_read_sz = 0; | |
871 | _y4m->convert = y4m_convert_null; | |
872 | _y4m->bit_depth = 12; | |
873 | _y4m->bps = 18; | |
874 | _y4m->vpx_fmt = VPX_IMG_FMT_I42016; | |
927 | y4m_ctx->aux_buf_sz = y4m_ctx->aux_buf_read_sz = 0; | |
928 | y4m_ctx->convert = y4m_convert_null; | |
929 | y4m_ctx->bit_depth = 12; | |
930 | y4m_ctx->bps = 18; | |
931 | y4m_ctx->vpx_fmt = VPX_IMG_FMT_I42016; | |
875 | 932 | if (only_420) { |
876 | 933 | fprintf(stderr, "Unsupported conversion from 420p12 to 420jpeg\n"); |
877 | 934 | return -1; |
878 | 935 | } |
879 | } else if (strcmp(_y4m->chroma_type, "420mpeg2") == 0) { | |
880 | _y4m->src_c_dec_h = _y4m->dst_c_dec_h = _y4m->src_c_dec_v = | |
881 | _y4m->dst_c_dec_v = 2; | |
882 | _y4m->dst_buf_read_sz = _y4m->pic_w * _y4m->pic_h; | |
936 | } else if (strcmp(y4m_ctx->chroma_type, "420mpeg2") == 0) { | |
937 | y4m_ctx->src_c_dec_h = y4m_ctx->dst_c_dec_h = y4m_ctx->src_c_dec_v = | |
938 | y4m_ctx->dst_c_dec_v = 2; | |
939 | y4m_ctx->dst_buf_read_sz = y4m_ctx->pic_w * y4m_ctx->pic_h; | |
883 | 940 | /*Chroma filter required: read into the aux buf first.*/ |
884 | _y4m->aux_buf_sz = _y4m->aux_buf_read_sz = | |
885 | 2 * ((_y4m->pic_w + 1) / 2) * ((_y4m->pic_h + 1) / 2); | |
886 | _y4m->convert = y4m_convert_42xmpeg2_42xjpeg; | |
887 | } else if (strcmp(_y4m->chroma_type, "420paldv") == 0) { | |
888 | _y4m->src_c_dec_h = _y4m->dst_c_dec_h = _y4m->src_c_dec_v = | |
889 | _y4m->dst_c_dec_v = 2; | |
890 | _y4m->dst_buf_read_sz = _y4m->pic_w * _y4m->pic_h; | |
941 | y4m_ctx->aux_buf_sz = y4m_ctx->aux_buf_read_sz = | |
942 | 2 * ((y4m_ctx->pic_w + 1) / 2) * ((y4m_ctx->pic_h + 1) / 2); | |
943 | y4m_ctx->convert = y4m_convert_42xmpeg2_42xjpeg; | |
944 | } else if (strcmp(y4m_ctx->chroma_type, "420paldv") == 0) { | |
945 | y4m_ctx->src_c_dec_h = y4m_ctx->dst_c_dec_h = y4m_ctx->src_c_dec_v = | |
946 | y4m_ctx->dst_c_dec_v = 2; | |
947 | y4m_ctx->dst_buf_read_sz = y4m_ctx->pic_w * y4m_ctx->pic_h; | |
891 | 948 | /*Chroma filter required: read into the aux buf first. |
892 | 949 | We need to make two filter passes, so we need some extra space in the |
893 | 950 | aux buffer.*/ |
894 | _y4m->aux_buf_sz = 3 * ((_y4m->pic_w + 1) / 2) * ((_y4m->pic_h + 1) / 2); | |
895 | _y4m->aux_buf_read_sz = | |
896 | 2 * ((_y4m->pic_w + 1) / 2) * ((_y4m->pic_h + 1) / 2); | |
897 | _y4m->convert = y4m_convert_42xpaldv_42xjpeg; | |
898 | } else if (strcmp(_y4m->chroma_type, "422jpeg") == 0) { | |
899 | _y4m->src_c_dec_h = _y4m->dst_c_dec_h = 2; | |
900 | _y4m->src_c_dec_v = 1; | |
901 | _y4m->dst_c_dec_v = 2; | |
902 | _y4m->dst_buf_read_sz = _y4m->pic_w * _y4m->pic_h; | |
951 | y4m_ctx->aux_buf_sz = | |
952 | 3 * ((y4m_ctx->pic_w + 1) / 2) * ((y4m_ctx->pic_h + 1) / 2); | |
953 | y4m_ctx->aux_buf_read_sz = | |
954 | 2 * ((y4m_ctx->pic_w + 1) / 2) * ((y4m_ctx->pic_h + 1) / 2); | |
955 | y4m_ctx->convert = y4m_convert_42xpaldv_42xjpeg; | |
956 | } else if (strcmp(y4m_ctx->chroma_type, "422jpeg") == 0) { | |
957 | y4m_ctx->src_c_dec_h = y4m_ctx->dst_c_dec_h = 2; | |
958 | y4m_ctx->src_c_dec_v = 1; | |
959 | y4m_ctx->dst_c_dec_v = 2; | |
960 | y4m_ctx->dst_buf_read_sz = y4m_ctx->pic_w * y4m_ctx->pic_h; | |
903 | 961 | /*Chroma filter required: read into the aux buf first.*/ |
904 | _y4m->aux_buf_sz = _y4m->aux_buf_read_sz = | |
905 | 2 * ((_y4m->pic_w + 1) / 2) * _y4m->pic_h; | |
906 | _y4m->convert = y4m_convert_422jpeg_420jpeg; | |
907 | } else if (strcmp(_y4m->chroma_type, "422") == 0) { | |
908 | _y4m->src_c_dec_h = 2; | |
909 | _y4m->src_c_dec_v = 1; | |
962 | y4m_ctx->aux_buf_sz = y4m_ctx->aux_buf_read_sz = | |
963 | 2 * ((y4m_ctx->pic_w + 1) / 2) * y4m_ctx->pic_h; | |
964 | y4m_ctx->convert = y4m_convert_422jpeg_420jpeg; | |
965 | } else if (strcmp(y4m_ctx->chroma_type, "422") == 0) { | |
966 | y4m_ctx->src_c_dec_h = 2; | |
967 | y4m_ctx->src_c_dec_v = 1; | |
910 | 968 | if (only_420) { |
911 | _y4m->dst_c_dec_h = 2; | |
912 | _y4m->dst_c_dec_v = 2; | |
913 | _y4m->dst_buf_read_sz = _y4m->pic_w * _y4m->pic_h; | |
969 | y4m_ctx->dst_c_dec_h = 2; | |
970 | y4m_ctx->dst_c_dec_v = 2; | |
971 | y4m_ctx->dst_buf_read_sz = y4m_ctx->pic_w * y4m_ctx->pic_h; | |
914 | 972 | /*Chroma filter required: read into the aux buf first. |
915 | 973 | We need to make two filter passes, so we need some extra space in the |
916 | 974 | aux buffer.*/ |
917 | _y4m->aux_buf_read_sz = 2 * ((_y4m->pic_w + 1) / 2) * _y4m->pic_h; | |
918 | _y4m->aux_buf_sz = | |
919 | _y4m->aux_buf_read_sz + ((_y4m->pic_w + 1) / 2) * _y4m->pic_h; | |
920 | _y4m->convert = y4m_convert_422_420jpeg; | |
975 | y4m_ctx->aux_buf_read_sz = | |
976 | 2 * ((y4m_ctx->pic_w + 1) / 2) * y4m_ctx->pic_h; | |
977 | y4m_ctx->aux_buf_sz = y4m_ctx->aux_buf_read_sz + | |
978 | ((y4m_ctx->pic_w + 1) / 2) * y4m_ctx->pic_h; | |
979 | y4m_ctx->convert = y4m_convert_422_420jpeg; | |
921 | 980 | } else { |
922 | _y4m->vpx_fmt = VPX_IMG_FMT_I422; | |
923 | _y4m->bps = 16; | |
924 | _y4m->dst_c_dec_h = _y4m->src_c_dec_h; | |
925 | _y4m->dst_c_dec_v = _y4m->src_c_dec_v; | |
926 | _y4m->dst_buf_read_sz = | |
927 | _y4m->pic_w * _y4m->pic_h + 2 * ((_y4m->pic_w + 1) / 2) * _y4m->pic_h; | |
981 | y4m_ctx->vpx_fmt = VPX_IMG_FMT_I422; | |
982 | y4m_ctx->bps = 16; | |
983 | y4m_ctx->dst_c_dec_h = y4m_ctx->src_c_dec_h; | |
984 | y4m_ctx->dst_c_dec_v = y4m_ctx->src_c_dec_v; | |
985 | y4m_ctx->dst_buf_read_sz = | |
986 | y4m_ctx->pic_w * y4m_ctx->pic_h + | |
987 | 2 * ((y4m_ctx->pic_w + 1) / 2) * y4m_ctx->pic_h; | |
928 | 988 | /*Natively supported: no conversion required.*/ |
929 | _y4m->aux_buf_sz = _y4m->aux_buf_read_sz = 0; | |
930 | _y4m->convert = y4m_convert_null; | |
931 | } | |
932 | } else if (strcmp(_y4m->chroma_type, "422p10") == 0) { | |
933 | _y4m->src_c_dec_h = 2; | |
934 | _y4m->src_c_dec_v = 1; | |
935 | _y4m->vpx_fmt = VPX_IMG_FMT_I42216; | |
936 | _y4m->bps = 20; | |
937 | _y4m->bit_depth = 10; | |
938 | _y4m->dst_c_dec_h = _y4m->src_c_dec_h; | |
939 | _y4m->dst_c_dec_v = _y4m->src_c_dec_v; | |
940 | _y4m->dst_buf_read_sz = 2 * (_y4m->pic_w * _y4m->pic_h + | |
941 | 2 * ((_y4m->pic_w + 1) / 2) * _y4m->pic_h); | |
942 | _y4m->aux_buf_sz = _y4m->aux_buf_read_sz = 0; | |
943 | _y4m->convert = y4m_convert_null; | |
989 | y4m_ctx->aux_buf_sz = y4m_ctx->aux_buf_read_sz = 0; | |
990 | y4m_ctx->convert = y4m_convert_null; | |
991 | } | |
992 | } else if (strcmp(y4m_ctx->chroma_type, "422p10") == 0) { | |
993 | y4m_ctx->src_c_dec_h = 2; | |
994 | y4m_ctx->src_c_dec_v = 1; | |
995 | y4m_ctx->vpx_fmt = VPX_IMG_FMT_I42216; | |
996 | y4m_ctx->bps = 20; | |
997 | y4m_ctx->bit_depth = 10; | |
998 | y4m_ctx->dst_c_dec_h = y4m_ctx->src_c_dec_h; | |
999 | y4m_ctx->dst_c_dec_v = y4m_ctx->src_c_dec_v; | |
1000 | y4m_ctx->dst_buf_read_sz = | |
1001 | 2 * (y4m_ctx->pic_w * y4m_ctx->pic_h + | |
1002 | 2 * ((y4m_ctx->pic_w + 1) / 2) * y4m_ctx->pic_h); | |
1003 | y4m_ctx->aux_buf_sz = y4m_ctx->aux_buf_read_sz = 0; | |
1004 | y4m_ctx->convert = y4m_convert_null; | |
944 | 1005 | if (only_420) { |
945 | 1006 | fprintf(stderr, "Unsupported conversion from 422p10 to 420jpeg\n"); |
946 | 1007 | return -1; |
947 | 1008 | } |
948 | } else if (strcmp(_y4m->chroma_type, "422p12") == 0) { | |
949 | _y4m->src_c_dec_h = 2; | |
950 | _y4m->src_c_dec_v = 1; | |
951 | _y4m->vpx_fmt = VPX_IMG_FMT_I42216; | |
952 | _y4m->bps = 24; | |
953 | _y4m->bit_depth = 12; | |
954 | _y4m->dst_c_dec_h = _y4m->src_c_dec_h; | |
955 | _y4m->dst_c_dec_v = _y4m->src_c_dec_v; | |
956 | _y4m->dst_buf_read_sz = 2 * (_y4m->pic_w * _y4m->pic_h + | |
957 | 2 * ((_y4m->pic_w + 1) / 2) * _y4m->pic_h); | |
958 | _y4m->aux_buf_sz = _y4m->aux_buf_read_sz = 0; | |
959 | _y4m->convert = y4m_convert_null; | |
1009 | } else if (strcmp(y4m_ctx->chroma_type, "422p12") == 0) { | |
1010 | y4m_ctx->src_c_dec_h = 2; | |
1011 | y4m_ctx->src_c_dec_v = 1; | |
1012 | y4m_ctx->vpx_fmt = VPX_IMG_FMT_I42216; | |
1013 | y4m_ctx->bps = 24; | |
1014 | y4m_ctx->bit_depth = 12; | |
1015 | y4m_ctx->dst_c_dec_h = y4m_ctx->src_c_dec_h; | |
1016 | y4m_ctx->dst_c_dec_v = y4m_ctx->src_c_dec_v; | |
1017 | y4m_ctx->dst_buf_read_sz = | |
1018 | 2 * (y4m_ctx->pic_w * y4m_ctx->pic_h + | |
1019 | 2 * ((y4m_ctx->pic_w + 1) / 2) * y4m_ctx->pic_h); | |
1020 | y4m_ctx->aux_buf_sz = y4m_ctx->aux_buf_read_sz = 0; | |
1021 | y4m_ctx->convert = y4m_convert_null; | |
960 | 1022 | if (only_420) { |
961 | 1023 | fprintf(stderr, "Unsupported conversion from 422p12 to 420jpeg\n"); |
962 | 1024 | return -1; |
963 | 1025 | } |
964 | } else if (strcmp(_y4m->chroma_type, "411") == 0) { | |
965 | _y4m->src_c_dec_h = 4; | |
966 | _y4m->dst_c_dec_h = 2; | |
967 | _y4m->src_c_dec_v = 1; | |
968 | _y4m->dst_c_dec_v = 2; | |
969 | _y4m->dst_buf_read_sz = _y4m->pic_w * _y4m->pic_h; | |
1026 | } else if (strcmp(y4m_ctx->chroma_type, "411") == 0) { | |
1027 | y4m_ctx->src_c_dec_h = 4; | |
1028 | y4m_ctx->dst_c_dec_h = 2; | |
1029 | y4m_ctx->src_c_dec_v = 1; | |
1030 | y4m_ctx->dst_c_dec_v = 2; | |
1031 | y4m_ctx->dst_buf_read_sz = y4m_ctx->pic_w * y4m_ctx->pic_h; | |
970 | 1032 | /*Chroma filter required: read into the aux buf first. |
971 | 1033 | We need to make two filter passes, so we need some extra space in the |
972 | 1034 | aux buffer.*/ |
973 | _y4m->aux_buf_read_sz = 2 * ((_y4m->pic_w + 3) / 4) * _y4m->pic_h; | |
974 | _y4m->aux_buf_sz = | |
975 | _y4m->aux_buf_read_sz + ((_y4m->pic_w + 1) / 2) * _y4m->pic_h; | |
976 | _y4m->convert = y4m_convert_411_420jpeg; | |
1035 | y4m_ctx->aux_buf_read_sz = 2 * ((y4m_ctx->pic_w + 3) / 4) * y4m_ctx->pic_h; | |
1036 | y4m_ctx->aux_buf_sz = | |
1037 | y4m_ctx->aux_buf_read_sz + ((y4m_ctx->pic_w + 1) / 2) * y4m_ctx->pic_h; | |
1038 | y4m_ctx->convert = y4m_convert_411_420jpeg; | |
977 | 1039 | fprintf(stderr, "Unsupported conversion from yuv 411\n"); |
978 | 1040 | return -1; |
979 | } else if (strcmp(_y4m->chroma_type, "444") == 0) { | |
980 | _y4m->src_c_dec_h = 1; | |
981 | _y4m->src_c_dec_v = 1; | |
1041 | } else if (strcmp(y4m_ctx->chroma_type, "444") == 0) { | |
1042 | y4m_ctx->src_c_dec_h = 1; | |
1043 | y4m_ctx->src_c_dec_v = 1; | |
982 | 1044 | if (only_420) { |
983 | _y4m->dst_c_dec_h = 2; | |
984 | _y4m->dst_c_dec_v = 2; | |
985 | _y4m->dst_buf_read_sz = _y4m->pic_w * _y4m->pic_h; | |
1045 | y4m_ctx->dst_c_dec_h = 2; | |
1046 | y4m_ctx->dst_c_dec_v = 2; | |
1047 | y4m_ctx->dst_buf_read_sz = y4m_ctx->pic_w * y4m_ctx->pic_h; | |
986 | 1048 | /*Chroma filter required: read into the aux buf first. |
987 | 1049 | We need to make two filter passes, so we need some extra space in the |
988 | 1050 | aux buffer.*/ |
989 | _y4m->aux_buf_read_sz = 2 * _y4m->pic_w * _y4m->pic_h; | |
990 | _y4m->aux_buf_sz = | |
991 | _y4m->aux_buf_read_sz + ((_y4m->pic_w + 1) / 2) * _y4m->pic_h; | |
992 | _y4m->convert = y4m_convert_444_420jpeg; | |
1051 | y4m_ctx->aux_buf_read_sz = 2 * y4m_ctx->pic_w * y4m_ctx->pic_h; | |
1052 | y4m_ctx->aux_buf_sz = y4m_ctx->aux_buf_read_sz + | |
1053 | ((y4m_ctx->pic_w + 1) / 2) * y4m_ctx->pic_h; | |
1054 | y4m_ctx->convert = y4m_convert_444_420jpeg; | |
993 | 1055 | } else { |
994 | _y4m->vpx_fmt = VPX_IMG_FMT_I444; | |
995 | _y4m->bps = 24; | |
996 | _y4m->dst_c_dec_h = _y4m->src_c_dec_h; | |
997 | _y4m->dst_c_dec_v = _y4m->src_c_dec_v; | |
998 | _y4m->dst_buf_read_sz = 3 * _y4m->pic_w * _y4m->pic_h; | |
1056 | y4m_ctx->vpx_fmt = VPX_IMG_FMT_I444; | |
1057 | y4m_ctx->bps = 24; | |
1058 | y4m_ctx->dst_c_dec_h = y4m_ctx->src_c_dec_h; | |
1059 | y4m_ctx->dst_c_dec_v = y4m_ctx->src_c_dec_v; | |
1060 | y4m_ctx->dst_buf_read_sz = 3 * y4m_ctx->pic_w * y4m_ctx->pic_h; | |
999 | 1061 | /*Natively supported: no conversion required.*/ |
1000 | _y4m->aux_buf_sz = _y4m->aux_buf_read_sz = 0; | |
1001 | _y4m->convert = y4m_convert_null; | |
1002 | } | |
1003 | } else if (strcmp(_y4m->chroma_type, "444p10") == 0) { | |
1004 | _y4m->src_c_dec_h = 1; | |
1005 | _y4m->src_c_dec_v = 1; | |
1006 | _y4m->vpx_fmt = VPX_IMG_FMT_I44416; | |
1007 | _y4m->bps = 30; | |
1008 | _y4m->bit_depth = 10; | |
1009 | _y4m->dst_c_dec_h = _y4m->src_c_dec_h; | |
1010 | _y4m->dst_c_dec_v = _y4m->src_c_dec_v; | |
1011 | _y4m->dst_buf_read_sz = 2 * 3 * _y4m->pic_w * _y4m->pic_h; | |
1012 | _y4m->aux_buf_sz = _y4m->aux_buf_read_sz = 0; | |
1013 | _y4m->convert = y4m_convert_null; | |
1062 | y4m_ctx->aux_buf_sz = y4m_ctx->aux_buf_read_sz = 0; | |
1063 | y4m_ctx->convert = y4m_convert_null; | |
1064 | } | |
1065 | } else if (strcmp(y4m_ctx->chroma_type, "444p10") == 0) { | |
1066 | y4m_ctx->src_c_dec_h = 1; | |
1067 | y4m_ctx->src_c_dec_v = 1; | |
1068 | y4m_ctx->vpx_fmt = VPX_IMG_FMT_I44416; | |
1069 | y4m_ctx->bps = 30; | |
1070 | y4m_ctx->bit_depth = 10; | |
1071 | y4m_ctx->dst_c_dec_h = y4m_ctx->src_c_dec_h; | |
1072 | y4m_ctx->dst_c_dec_v = y4m_ctx->src_c_dec_v; | |
1073 | y4m_ctx->dst_buf_read_sz = 2 * 3 * y4m_ctx->pic_w * y4m_ctx->pic_h; | |
1074 | y4m_ctx->aux_buf_sz = y4m_ctx->aux_buf_read_sz = 0; | |
1075 | y4m_ctx->convert = y4m_convert_null; | |
1014 | 1076 | if (only_420) { |
1015 | 1077 | fprintf(stderr, "Unsupported conversion from 444p10 to 420jpeg\n"); |
1016 | 1078 | return -1; |
1017 | 1079 | } |
1018 | } else if (strcmp(_y4m->chroma_type, "444p12") == 0) { | |
1019 | _y4m->src_c_dec_h = 1; | |
1020 | _y4m->src_c_dec_v = 1; | |
1021 | _y4m->vpx_fmt = VPX_IMG_FMT_I44416; | |
1022 | _y4m->bps = 36; | |
1023 | _y4m->bit_depth = 12; | |
1024 | _y4m->dst_c_dec_h = _y4m->src_c_dec_h; | |
1025 | _y4m->dst_c_dec_v = _y4m->src_c_dec_v; | |
1026 | _y4m->dst_buf_read_sz = 2 * 3 * _y4m->pic_w * _y4m->pic_h; | |
1027 | _y4m->aux_buf_sz = _y4m->aux_buf_read_sz = 0; | |
1028 | _y4m->convert = y4m_convert_null; | |
1080 | } else if (strcmp(y4m_ctx->chroma_type, "444p12") == 0) { | |
1081 | y4m_ctx->src_c_dec_h = 1; | |
1082 | y4m_ctx->src_c_dec_v = 1; | |
1083 | y4m_ctx->vpx_fmt = VPX_IMG_FMT_I44416; | |
1084 | y4m_ctx->bps = 36; | |
1085 | y4m_ctx->bit_depth = 12; | |
1086 | y4m_ctx->dst_c_dec_h = y4m_ctx->src_c_dec_h; | |
1087 | y4m_ctx->dst_c_dec_v = y4m_ctx->src_c_dec_v; | |
1088 | y4m_ctx->dst_buf_read_sz = 2 * 3 * y4m_ctx->pic_w * y4m_ctx->pic_h; | |
1089 | y4m_ctx->aux_buf_sz = y4m_ctx->aux_buf_read_sz = 0; | |
1090 | y4m_ctx->convert = y4m_convert_null; | |
1029 | 1091 | if (only_420) { |
1030 | 1092 | fprintf(stderr, "Unsupported conversion from 444p12 to 420jpeg\n"); |
1031 | 1093 | return -1; |
1032 | 1094 | } |
1033 | } else if (strcmp(_y4m->chroma_type, "mono") == 0) { | |
1034 | _y4m->src_c_dec_h = _y4m->src_c_dec_v = 0; | |
1035 | _y4m->dst_c_dec_h = _y4m->dst_c_dec_v = 2; | |
1036 | _y4m->dst_buf_read_sz = _y4m->pic_w * _y4m->pic_h; | |
1095 | } else if (strcmp(y4m_ctx->chroma_type, "mono") == 0) { | |
1096 | y4m_ctx->src_c_dec_h = y4m_ctx->src_c_dec_v = 0; | |
1097 | y4m_ctx->dst_c_dec_h = y4m_ctx->dst_c_dec_v = 2; | |
1098 | y4m_ctx->dst_buf_read_sz = y4m_ctx->pic_w * y4m_ctx->pic_h; | |
1037 | 1099 | /*No extra space required, but we need to clear the chroma planes.*/ |
1038 | _y4m->aux_buf_sz = _y4m->aux_buf_read_sz = 0; | |
1039 | _y4m->convert = y4m_convert_mono_420jpeg; | |
1100 | y4m_ctx->aux_buf_sz = y4m_ctx->aux_buf_read_sz = 0; | |
1101 | y4m_ctx->convert = y4m_convert_mono_420jpeg; | |
1040 | 1102 | } else { |
1041 | fprintf(stderr, "Unknown chroma sampling type: %s\n", _y4m->chroma_type); | |
1103 | fprintf(stderr, "Unknown chroma sampling type: %s\n", y4m_ctx->chroma_type); | |
1042 | 1104 | return -1; |
1043 | 1105 | } |
1044 | 1106 | /*The size of the final frame buffers is always computed from the |
1045 | 1107 | destination chroma decimation type.*/ |
1046 | _y4m->dst_buf_sz = | |
1047 | _y4m->pic_w * _y4m->pic_h + | |
1048 | 2 * ((_y4m->pic_w + _y4m->dst_c_dec_h - 1) / _y4m->dst_c_dec_h) * | |
1049 | ((_y4m->pic_h + _y4m->dst_c_dec_v - 1) / _y4m->dst_c_dec_v); | |
1050 | if (_y4m->bit_depth == 8) | |
1051 | _y4m->dst_buf = (unsigned char *)malloc(_y4m->dst_buf_sz); | |
1108 | y4m_ctx->dst_buf_sz = | |
1109 | y4m_ctx->pic_w * y4m_ctx->pic_h + | |
1110 | 2 * ((y4m_ctx->pic_w + y4m_ctx->dst_c_dec_h - 1) / y4m_ctx->dst_c_dec_h) * | |
1111 | ((y4m_ctx->pic_h + y4m_ctx->dst_c_dec_v - 1) / y4m_ctx->dst_c_dec_v); | |
1112 | if (y4m_ctx->bit_depth == 8) | |
1113 | y4m_ctx->dst_buf = (unsigned char *)malloc(y4m_ctx->dst_buf_sz); | |
1052 | 1114 | else |
1053 | _y4m->dst_buf = (unsigned char *)malloc(2 * _y4m->dst_buf_sz); | |
1054 | ||
1055 | if (_y4m->aux_buf_sz > 0) | |
1056 | _y4m->aux_buf = (unsigned char *)malloc(_y4m->aux_buf_sz); | |
1115 | y4m_ctx->dst_buf = (unsigned char *)malloc(2 * y4m_ctx->dst_buf_sz); | |
1116 | ||
1117 | if (y4m_ctx->aux_buf_sz > 0) | |
1118 | y4m_ctx->aux_buf = (unsigned char *)malloc(y4m_ctx->aux_buf_sz); | |
1057 | 1119 | return 0; |
1058 | 1120 | } |
1059 | 1121 |
55 | 55 | unsigned int bit_depth; |
56 | 56 | }; |
57 | 57 | |
58 | int y4m_input_open(y4m_input *_y4m, FILE *_fin, char *_skip, int _nskip, | |
59 | int only_420); | |
58 | /** | |
59 | * Open the input file, treating it as Y4M. |y4m_ctx| is filled in after | |
60 | * reading it. The |skip_buffer| indicates bytes that were previously read | |
61 | * from |file|, to do input-type detection; this buffer will be read before | |
62 | * the |file| is read. It is of size |num_skip|, which *must* be 8 or less. | |
63 | * | |
64 | * Returns 0 on success, -1 on failure. | |
65 | */ | |
66 | int y4m_input_open(y4m_input *y4m_ctx, FILE *file, char *skip_buffer, | |
67 | int num_skip, int only_420); | |
60 | 68 | void y4m_input_close(y4m_input *_y4m); |
61 | 69 | int y4m_input_fetch_frame(y4m_input *_y4m, FILE *_fin, vpx_image_t *img); |
62 | 70 |