Compare commits
1434 Commits
v1.6.1
...
sandbox/wa
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
eea111f16a | ||
|
|
90ce21e519 | ||
|
|
e83d00f584 | ||
|
|
bdbecea1ba | ||
|
|
65df957df6 | ||
|
|
401e00792f | ||
|
|
460dbc01b5 | ||
|
|
8d0e7ac29a | ||
|
|
298f5ca47d | ||
|
|
8099220e6c | ||
|
|
c22ab8ab9f | ||
|
|
9dbefc4b57 | ||
|
|
2e701f7c29 | ||
|
|
5044779e77 | ||
|
|
b409863c48 | ||
|
|
392e0188f6 | ||
|
|
8d70aef05f | ||
|
|
9116e3d957 | ||
|
|
3437fe484a | ||
|
|
49f51af4c9 | ||
|
|
0e94522338 | ||
|
|
3ae909b0f9 | ||
|
|
a60da3a2eb | ||
|
|
d49bf26b1c | ||
|
|
339f4dcaee | ||
|
|
9966cc8d12 | ||
|
|
c5f5f4ed17 | ||
|
|
9bd3f1e30d | ||
|
|
a0ca2a4079 | ||
|
|
f0b4868625 | ||
|
|
bd990cad72 | ||
|
|
cbe62b9c2d | ||
|
|
9639641cd4 | ||
|
|
50fc0d896b | ||
|
|
bc29863b96 | ||
|
|
f49360d740 | ||
|
|
dd4cc5b596 | ||
|
|
0cc23242b0 | ||
|
|
559166acfe | ||
|
|
8b7a6ca60a | ||
|
|
07a0bf038f | ||
|
|
849b3c238d | ||
|
|
c66eeab30e | ||
|
|
55eacca945 | ||
|
|
4bd2a59e9b | ||
|
|
ea14a1a965 | ||
|
|
44473e7eb9 | ||
|
|
1aea1675c0 | ||
|
|
3e3a568616 | ||
|
|
05302360c9 | ||
|
|
03c1a827ac | ||
|
|
607e45f420 | ||
|
|
b3c93d60c2 | ||
|
|
8d471fcee2 | ||
|
|
7839fb98a8 | ||
|
|
9df11a7c52 | ||
|
|
0d2555bd2e | ||
|
|
becab42eee | ||
|
|
a73cee2870 | ||
|
|
55fc4d95af | ||
|
|
2eddfb46a9 | ||
|
|
f5817fa612 | ||
|
|
8e6022844f | ||
|
|
8c7213bc00 | ||
|
|
1ff68ec035 | ||
|
|
6c0011a255 | ||
|
|
10cb17aec0 | ||
|
|
6246d8aa76 | ||
|
|
0665b09661 | ||
|
|
fdb054a05d | ||
|
|
2387024f41 | ||
|
|
bdb8b3ad86 | ||
|
|
62ab5e99c1 | ||
|
|
d6e29868ac | ||
|
|
adbb4c4d32 | ||
|
|
a68bbcff29 | ||
|
|
cf8039c25f | ||
|
|
93e83fd7cf | ||
|
|
6fbc354c97 | ||
|
|
b383a17fa4 | ||
|
|
eb7d431cb5 | ||
|
|
5fe82459ec | ||
|
|
3ba9a2c8b2 | ||
|
|
34805d6d0d | ||
|
|
0c84b9b703 | ||
|
|
18b470f486 | ||
|
|
c77822615e | ||
|
|
cc47231187 | ||
|
|
acb9460929 | ||
|
|
3bf02ad74a | ||
|
|
037e596f04 | ||
|
|
ae35425ae6 | ||
|
|
e0aa6b24aa | ||
|
|
0738d90169 | ||
|
|
512bf4e029 | ||
|
|
4906cea027 | ||
|
|
b58259ab55 | ||
|
|
199971d606 | ||
|
|
0c493cbe2b | ||
|
|
d8c34a2552 | ||
|
|
55c126a5d7 | ||
|
|
401e6d48bf | ||
|
|
bd6d82e881 | ||
|
|
ec2fced451 | ||
|
|
b3a36f7946 | ||
|
|
df15220a89 | ||
|
|
dbb8926b86 | ||
|
|
9336e01621 | ||
|
|
0d2e95193b | ||
|
|
55805e2786 | ||
|
|
577d4fa792 | ||
|
|
580d32240f | ||
|
|
a9248457b1 | ||
|
|
12df840777 | ||
|
|
eaa593d293 | ||
|
|
8842ee0b0d | ||
|
|
3e2770de4f | ||
|
|
28d1c0535d | ||
|
|
a673b4f4af | ||
|
|
175b36cb6d | ||
|
|
caa116c9be | ||
|
|
2b247ae91c | ||
|
|
288890cd43 | ||
|
|
f70de09f2a | ||
|
|
bc4098a8e9 | ||
|
|
72c69e14ad | ||
|
|
1fa3ec3023 | ||
|
|
416b7051d7 | ||
|
|
e8ed2bb762 | ||
|
|
16166bfdaa | ||
|
|
dcfae2cc64 | ||
|
|
33c598990b | ||
|
|
54f7d68c5c | ||
|
|
017257a317 | ||
|
|
963cc22cef | ||
|
|
06d231c9fa | ||
|
|
741bd6df4f | ||
|
|
1b2f92ee8e | ||
|
|
27d21a3d13 | ||
|
|
e1ae3772da | ||
|
|
9ca06bcdd2 | ||
|
|
807248ec81 | ||
|
|
5bc4c37a89 | ||
|
|
bcbc6ed82d | ||
|
|
e405eb06b1 | ||
|
|
7af6c6c9ca | ||
|
|
9311ef18b4 | ||
|
|
d2fb834ebd | ||
|
|
e8ed030da3 | ||
|
|
107eb6a9d4 | ||
|
|
e095bcce44 | ||
|
|
18262a8576 | ||
|
|
014976c251 | ||
|
|
4bc1fc58b6 | ||
|
|
6a42bdd25f | ||
|
|
127864deb3 | ||
|
|
b809442521 | ||
|
|
77e51e2035 | ||
|
|
9a71811d98 | ||
|
|
ffa3a3c441 | ||
|
|
98dbf31c87 | ||
|
|
ab2bd340ac | ||
|
|
66b6b87471 | ||
|
|
bc4bc9b622 | ||
|
|
6543213e87 | ||
|
|
0f756a307d | ||
|
|
c8678fb7f3 | ||
|
|
67c38c92e7 | ||
|
|
fe7b869104 | ||
|
|
33e10dfa7e | ||
|
|
0e55b0b0a7 | ||
|
|
2c560c3c22 | ||
|
|
3c700052be | ||
|
|
fb7fc1dbda | ||
|
|
c8f6e7b99e | ||
|
|
f2c3d0a7a3 | ||
|
|
3bbd62ed27 | ||
|
|
4cae64c32c | ||
|
|
5a40c8fde1 | ||
|
|
a2ef180dd0 | ||
|
|
3b8cc214ef | ||
|
|
03e8f13337 | ||
|
|
c493ea1a6b | ||
|
|
786b124e20 | ||
|
|
80992a746c | ||
|
|
8d438dc313 | ||
|
|
690fa6bb6e | ||
|
|
6175f285a9 | ||
|
|
dbbbd44304 | ||
|
|
19c45ccd43 | ||
|
|
535b7b915a | ||
|
|
530e60143a | ||
|
|
d203a91a09 | ||
|
|
878464150b | ||
|
|
f12e786c54 | ||
|
|
767503504f | ||
|
|
819c5b365d | ||
|
|
d5094cfde8 | ||
|
|
9e52d3910b | ||
|
|
9d0d13e939 | ||
|
|
28762341ac | ||
|
|
73102d1ed2 | ||
|
|
23eccb3ca7 | ||
|
|
a059dc0986 | ||
|
|
cf82f7276e | ||
|
|
691585f6b8 | ||
|
|
10bab1ec29 | ||
|
|
0b08f8892f | ||
|
|
42373b21ce | ||
|
|
d586cdb4d4 | ||
|
|
76a3d3fcc5 | ||
|
|
64653fa133 | ||
|
|
f7b276c26b | ||
|
|
24afb5d036 | ||
|
|
f407b30490 | ||
|
|
b85e391ac8 | ||
|
|
15bea62176 | ||
|
|
7c0529728a | ||
|
|
f357335c38 | ||
|
|
bf8bdae913 | ||
|
|
bc86e2c6a2 | ||
|
|
aaa6cdcc2e | ||
|
|
2a7c0e1c4b | ||
|
|
cd463c7acb | ||
|
|
310e388423 | ||
|
|
ebb015a539 | ||
|
|
a80bdfd081 | ||
|
|
9d278465b5 | ||
|
|
2aacfa1acd | ||
|
|
ad31fe36a8 | ||
|
|
65f1c90652 | ||
|
|
08fda52e18 | ||
|
|
90ed0d2f73 | ||
|
|
c12b39626f | ||
|
|
293734b755 | ||
|
|
c24d911847 | ||
|
|
baf658ec4c | ||
|
|
c3a6943c16 | ||
|
|
b81de66171 | ||
|
|
5b558592f5 | ||
|
|
4ca8f8f5e2 | ||
|
|
535dee0fb6 | ||
|
|
0726dd97d3 | ||
|
|
949730e2dc | ||
|
|
ed3a80cb5e | ||
|
|
83e59914e5 | ||
|
|
fa01426ade | ||
|
|
eb4238ac70 | ||
|
|
afee58f2c4 | ||
|
|
30f1ff94e0 | ||
|
|
c39cd9235e | ||
|
|
a9bbe53dbb | ||
|
|
d6c9bbc2b6 | ||
|
|
761f2f5cb4 | ||
|
|
fb40b5d7a7 | ||
|
|
9dfa76f948 | ||
|
|
5c95fd921e | ||
|
|
9a2dd7e67e | ||
|
|
0657f4732c | ||
|
|
d7caee2170 | ||
|
|
43cbdc216d | ||
|
|
2c7b7424c5 | ||
|
|
ef41c6286d | ||
|
|
71b38a144e | ||
|
|
3ec20445b2 | ||
|
|
d5d2cbcc75 | ||
|
|
7219f31904 | ||
|
|
0e95039bd9 | ||
|
|
6822fb2f09 | ||
|
|
d331e7a1c0 | ||
|
|
bc4bcca3fd | ||
|
|
0095213790 | ||
|
|
f4150163a2 | ||
|
|
d49a1a5329 | ||
|
|
7587a97551 | ||
|
|
053bd263eb | ||
|
|
be2ba48cac | ||
|
|
334e9abb0b | ||
|
|
9ab4d9df38 | ||
|
|
03191f738e | ||
|
|
d42e876164 | ||
|
|
ab5704f02c | ||
|
|
20973508da | ||
|
|
ebf3ae1a29 | ||
|
|
f8f64c309b | ||
|
|
297c110dcb | ||
|
|
d7ba519b9f | ||
|
|
c39a05ff61 | ||
|
|
2d0c11093e | ||
|
|
f783e3a75d | ||
|
|
fed52670a2 | ||
|
|
2f5fb37dac | ||
|
|
81f45ff798 | ||
|
|
30d9a1916c | ||
|
|
7c10251f22 | ||
|
|
df9ce12259 | ||
|
|
64c55576b7 | ||
|
|
255241c6d0 | ||
|
|
43b9e785ba | ||
|
|
a0de2692fc | ||
|
|
3e069846b9 | ||
|
|
a74593b30c | ||
|
|
8c42237bb2 | ||
|
|
ece1989fa2 | ||
|
|
34e48d6115 | ||
|
|
ccae8da7c6 | ||
|
|
6c21650c0e | ||
|
|
9e4647c7ab | ||
|
|
d14777157e | ||
|
|
258122fdc6 | ||
|
|
f60d1dcd3d | ||
|
|
1787e7dbe0 | ||
|
|
92aafefa1e | ||
|
|
2dc0a5132d | ||
|
|
d080c92524 | ||
|
|
30c261b1eb | ||
|
|
e89344d61a | ||
|
|
f53b656207 | ||
|
|
c9ff7b6637 | ||
|
|
1aad50c092 | ||
|
|
dfafd10ef5 | ||
|
|
7c27872164 | ||
|
|
2a5aa98a35 | ||
|
|
e83d99d7b8 | ||
|
|
59e065b6ed | ||
|
|
0207f17144 | ||
|
|
103e4e50a8 | ||
|
|
a31461c853 | ||
|
|
b9c1dcc5fa | ||
|
|
7f2993f5e4 | ||
|
|
75752ab7c0 | ||
|
|
ab27b68693 | ||
|
|
7a178a5631 | ||
|
|
419ce36294 | ||
|
|
bff5aa9827 | ||
|
|
2c56bb97f2 | ||
|
|
c02fdd0258 | ||
|
|
b527b47312 | ||
|
|
7b13d99b98 | ||
|
|
661efeca97 | ||
|
|
13eed991f9 | ||
|
|
eab3f5e0cc | ||
|
|
2c5478e383 | ||
|
|
2f7497f341 | ||
|
|
1426f04e91 | ||
|
|
7d82e57f5b | ||
|
|
bb15fd51be | ||
|
|
7f602d6114 | ||
|
|
e038d1610e | ||
|
|
f64e14047d | ||
|
|
372336d1e5 | ||
|
|
f95686895b | ||
|
|
b814e2d898 | ||
|
|
48110d0f79 | ||
|
|
0472382dbe | ||
|
|
e15be3025b | ||
|
|
6b9c691daf | ||
|
|
14437d0fa6 | ||
|
|
a153080b55 | ||
|
|
c59d1a4dc7 | ||
|
|
e9ccc6fe79 | ||
|
|
77ed4414d6 | ||
|
|
7e8357d664 | ||
|
|
08cb7b5c68 | ||
|
|
ca393c9726 | ||
|
|
5009302bce | ||
|
|
d72e20b123 | ||
|
|
69775d2f40 | ||
|
|
3f05a70c41 | ||
|
|
fa85cf131c | ||
|
|
ff184e482a | ||
|
|
45b39750d6 | ||
|
|
2caff16151 | ||
|
|
1ab60466ec | ||
|
|
c06d6649c5 | ||
|
|
746c0eab3b | ||
|
|
e702b68b6c | ||
|
|
e022ce84ac | ||
|
|
d48be6ad73 | ||
|
|
0f8ebddec4 | ||
|
|
15193ce51f | ||
|
|
9bb8ce5efb | ||
|
|
0b393ae505 | ||
|
|
db8fa86a6c | ||
|
|
39da7fb786 | ||
|
|
68805583e9 | ||
|
|
357adb68b2 | ||
|
|
1092cc7f1a | ||
|
|
93166c5e51 | ||
|
|
d52cb59729 | ||
|
|
427de67e63 | ||
|
|
853165ba39 | ||
|
|
d670678f26 | ||
|
|
fa829e0e5a | ||
|
|
c9fb719ee1 | ||
|
|
7f20c3ac44 | ||
|
|
22b6dc9fdf | ||
|
|
0c61331244 | ||
|
|
cbb83ba4aa | ||
|
|
9578a84205 | ||
|
|
c42517568d | ||
|
|
39e8b8dac6 | ||
|
|
e921c7ba8d | ||
|
|
f6c6f37e0c | ||
|
|
563d58ab84 | ||
|
|
6624f20785 | ||
|
|
8334a48d3a | ||
|
|
76d77aa013 | ||
|
|
6843e7c7f3 | ||
|
|
15a47db730 | ||
|
|
8c0ab7607e | ||
|
|
bfd0f41f9b | ||
|
|
787970a625 | ||
|
|
b9577e07fc | ||
|
|
698e56f26c | ||
|
|
1059b5cc52 | ||
|
|
632fe8286a | ||
|
|
0e87b16022 | ||
|
|
6738ad7aaf | ||
|
|
c0490b52b1 | ||
|
|
847394fe77 | ||
|
|
3be14200fc | ||
|
|
c22b17dcef | ||
|
|
5d6c1c2d8f | ||
|
|
bf14d468c1 | ||
|
|
78e2da3e42 | ||
|
|
2d6b5df657 | ||
|
|
2758de5cb2 | ||
|
|
ebb023deb6 | ||
|
|
999bd6ea84 | ||
|
|
f027908ad0 | ||
|
|
78155b7ed5 | ||
|
|
facb124941 | ||
|
|
c9266b8547 | ||
|
|
d35b627340 | ||
|
|
5d0bef4763 | ||
|
|
e48dfcead1 | ||
|
|
ac211fe23e | ||
|
|
064fc570ff | ||
|
|
7105e66d19 | ||
|
|
75653b7032 | ||
|
|
3c73e587d1 | ||
|
|
5232e35bc2 | ||
|
|
7f4acf8700 | ||
|
|
aa1c4cd140 | ||
|
|
9c43d81bc2 | ||
|
|
a83e1f1d53 | ||
|
|
905b8ec27f | ||
|
|
56d95b77f5 | ||
|
|
1c666465af | ||
|
|
62682ac8ad | ||
|
|
85736e616e | ||
|
|
666c543f7b | ||
|
|
b0f1ae1475 | ||
|
|
8836e46ffd | ||
|
|
8c7a60e04d | ||
|
|
e8bd534c42 | ||
|
|
0c30b75f40 | ||
|
|
494188505b | ||
|
|
af08fbb444 | ||
|
|
c782f27ead | ||
|
|
4702bb26be | ||
|
|
e1809501d0 | ||
|
|
9dd992b6f0 | ||
|
|
bde2e4aa36 | ||
|
|
b72d3e8a25 | ||
|
|
89a116f4cb | ||
|
|
8ad9338e2e | ||
|
|
4526644615 | ||
|
|
59e461db1f | ||
|
|
babef23a5f | ||
|
|
56d3f1573a | ||
|
|
4b9a848bb3 | ||
|
|
fd216268ad | ||
|
|
03f5e300d6 | ||
|
|
101981b736 | ||
|
|
adbfc4308a | ||
|
|
c7ebe82253 | ||
|
|
cb61ba02f4 | ||
|
|
817f68cdcf | ||
|
|
ad56371343 | ||
|
|
0c9e2f4c15 | ||
|
|
9223b947ca | ||
|
|
682135fa60 | ||
|
|
666e394d41 | ||
|
|
e3fa4ae8e3 | ||
|
|
960466939d | ||
|
|
b578d59623 | ||
|
|
e0d79bc7b5 | ||
|
|
f6586b8bf8 | ||
|
|
3158752980 | ||
|
|
e381753926 | ||
|
|
e1bde306c8 | ||
|
|
807ce8fb1e | ||
|
|
8152b0904d | ||
|
|
dd4347e9ec | ||
|
|
1dee320446 | ||
|
|
df18412f32 | ||
|
|
5322a31b18 | ||
|
|
7d5afa227a | ||
|
|
1a4d8f2033 | ||
|
|
689ad89e86 | ||
|
|
3818a3723b | ||
|
|
3d6b0cb825 | ||
|
|
66a96fd3de | ||
|
|
87610ac45e | ||
|
|
4b78c6e6f7 | ||
|
|
125a532b34 | ||
|
|
109faffe9b | ||
|
|
2ac7c549e9 | ||
|
|
4e16f70703 | ||
|
|
5d6060b62f | ||
|
|
6c375b9cd0 | ||
|
|
e4e08556db | ||
|
|
6ae8f8dbe8 | ||
|
|
67cffc1ef6 | ||
|
|
b0d15713be | ||
|
|
527e0c9b1c | ||
|
|
3c18acf452 | ||
|
|
9b253f9f0a | ||
|
|
2075af4b16 | ||
|
|
80b83c73ba | ||
|
|
777ca80f0a | ||
|
|
a15c6a7ebf | ||
|
|
8c3f18efa1 | ||
|
|
26a9a4cd64 | ||
|
|
d6423b3166 | ||
|
|
63bdc574e5 | ||
|
|
6bac3f80ee | ||
|
|
75b00592c7 | ||
|
|
5227b8200b | ||
|
|
48c4a038eb | ||
|
|
af3cab7b24 | ||
|
|
4ffd8350be | ||
|
|
0d245d42c4 | ||
|
|
f2b1dc529f | ||
|
|
e3cafbc8df | ||
|
|
24d0391efb | ||
|
|
9a05f9771a | ||
|
|
a22bb9809e | ||
|
|
3e08a88854 | ||
|
|
23d60be414 | ||
|
|
a6531cbc54 | ||
|
|
b6321025cd | ||
|
|
da2ad47d66 | ||
|
|
5b44ef0c50 | ||
|
|
a1af335f44 | ||
|
|
b0459ec8ea | ||
|
|
7d526c1654 | ||
|
|
6cb3178192 | ||
|
|
fb135ff050 | ||
|
|
c757d6dde4 | ||
|
|
d8c277030c | ||
|
|
f7645138d4 | ||
|
|
3dd993e4be | ||
|
|
3ae458f2f3 | ||
|
|
a876d04072 | ||
|
|
8710c6d884 | ||
|
|
329dabf57e | ||
|
|
27e37e1a8a | ||
|
|
af3ab45867 | ||
|
|
5a8e4110c7 | ||
|
|
37e03b1d13 | ||
|
|
f781cc8a46 | ||
|
|
2290898ac7 | ||
|
|
1e3a93e72e | ||
|
|
70b7713059 | ||
|
|
303cb3106b | ||
|
|
bc837b223b | ||
|
|
78fe5ca360 | ||
|
|
ba76b662af | ||
|
|
fb134e759a | ||
|
|
86d51dfbf5 | ||
|
|
469986f963 | ||
|
|
c2044fda1d | ||
|
|
ce5b17f9ad | ||
|
|
89d3dc043e | ||
|
|
c338f3635e | ||
|
|
ee5cb8d87f | ||
|
|
0fa59a4baf | ||
|
|
9ac78ae35f | ||
|
|
e3c8f2f152 | ||
|
|
dcdb013b55 | ||
|
|
ab76f1f224 | ||
|
|
67d7a6df2d | ||
|
|
e5bdab98e9 | ||
|
|
508ef2a6e3 | ||
|
|
8d1bda93f4 | ||
|
|
bd77931421 | ||
|
|
74dc640565 | ||
|
|
9fe510c12a | ||
|
|
f310ddc470 | ||
|
|
4959dd3eb3 | ||
|
|
cf75ab6ccd | ||
|
|
81e25512c3 | ||
|
|
d91af5f905 | ||
|
|
35f8515c3f | ||
|
|
5ac88162b9 | ||
|
|
ad011aaab8 | ||
|
|
77a648885c | ||
|
|
469643757f | ||
|
|
e40e78be24 | ||
|
|
46d8660ce3 | ||
|
|
8582d33a0d | ||
|
|
e0330c4810 | ||
|
|
88d11f473c | ||
|
|
515fed8f38 | ||
|
|
a220b931f5 | ||
|
|
d4595de5db | ||
|
|
0bb31a46a4 | ||
|
|
39972d999d | ||
|
|
ddae8f7632 | ||
|
|
a76b6b232c | ||
|
|
f749905d0a | ||
|
|
ec4afbf74a | ||
|
|
30eeb4dc32 | ||
|
|
6ff5de68dd | ||
|
|
4bb99ee27e | ||
|
|
ee1fcb0e69 | ||
|
|
8ad23a072a | ||
|
|
8253a27904 | ||
|
|
b8a4b5dd8d | ||
|
|
b0c4d87ac7 | ||
|
|
0d1c782306 | ||
|
|
54bcd98314 | ||
|
|
18805eee6c | ||
|
|
e187b27438 | ||
|
|
88a302e743 | ||
|
|
a377f99088 | ||
|
|
794a5ad713 | ||
|
|
b28fc490aa | ||
|
|
4f917912b9 | ||
|
|
c5f9de573f | ||
|
|
92145006c3 | ||
|
|
e67660cf37 | ||
|
|
efe1982e63 | ||
|
|
d7515b1187 | ||
|
|
33a9394eb1 | ||
|
|
dd88bd87db | ||
|
|
828a1fa6de | ||
|
|
7c0788b07f | ||
|
|
44418c659f | ||
|
|
b24ed95f44 | ||
|
|
b093d998fc | ||
|
|
eb8226b903 | ||
|
|
864bc77e7a | ||
|
|
d5d6a609d0 | ||
|
|
1d86383512 | ||
|
|
18335f193d | ||
|
|
07f847873b | ||
|
|
9a329b5285 | ||
|
|
3f296533f6 | ||
|
|
9e1d2de67c | ||
|
|
21afafa31a | ||
|
|
8cf6f78fce | ||
|
|
fbba31e241 | ||
|
|
355432b0d2 | ||
|
|
466b667ff3 | ||
|
|
42522ce0b7 | ||
|
|
2b43a1ee18 | ||
|
|
96ec8a425b | ||
|
|
1c48915233 | ||
|
|
0aa3677d9d | ||
|
|
9e03eedf62 | ||
|
|
d96ed96c0f | ||
|
|
492d52b9cc | ||
|
|
ae3a173352 | ||
|
|
a929911339 | ||
|
|
737aa5c9e4 | ||
|
|
b55240057f | ||
|
|
782aacc3d3 | ||
|
|
4ebb9a36f1 | ||
|
|
ed56ddfef8 | ||
|
|
ada640a508 | ||
|
|
ff7fb4b280 | ||
|
|
bf41a982b4 | ||
|
|
112cd95507 | ||
|
|
31d6ba9a54 | ||
|
|
038522e4a0 | ||
|
|
a36017e007 | ||
|
|
27c2185954 | ||
|
|
c7e4917e97 | ||
|
|
98967645a1 | ||
|
|
a4ea7e131b | ||
|
|
8d391a111a | ||
|
|
8b48f68c0d | ||
|
|
6da6a23291 | ||
|
|
d6eeef9ee6 | ||
|
|
9c72e85e4c | ||
|
|
cbb991b6b8 | ||
|
|
4f9d852759 | ||
|
|
98666368ee | ||
|
|
b6e1bdfc76 | ||
|
|
21e1661b54 | ||
|
|
a46bc0268b | ||
|
|
e540ca7155 | ||
|
|
ff2d220d21 | ||
|
|
6dcd9b37ea | ||
|
|
8aa4ee1f10 | ||
|
|
65f4299d65 | ||
|
|
92373a5bb2 | ||
|
|
5aee8ea752 | ||
|
|
c12d1d9b98 | ||
|
|
b3a262dff3 | ||
|
|
45daecb4f7 | ||
|
|
e50ea014c3 | ||
|
|
943f9ee25c | ||
|
|
903375a48a | ||
|
|
658e854252 | ||
|
|
21d2273efa | ||
|
|
eae7cf2368 | ||
|
|
9cea3a3c4e | ||
|
|
0c4f74d129 | ||
|
|
14d4718043 | ||
|
|
902d63759e | ||
|
|
4a37e3e2a0 | ||
|
|
f08581c1d0 | ||
|
|
13b02a8efe | ||
|
|
ff42e04f9c | ||
|
|
27b34a109d | ||
|
|
7d2f5f8e9d | ||
|
|
de4cb716ee | ||
|
|
8659764a07 | ||
|
|
cf07d85809 | ||
|
|
6df142e2ab | ||
|
|
968a5d6bc2 | ||
|
|
4753c23983 | ||
|
|
ffe0f9b7fb | ||
|
|
f3a9ae5baa | ||
|
|
e30781ff80 | ||
|
|
ff637d1903 | ||
|
|
8c6fa5c5e3 | ||
|
|
68f035026f | ||
|
|
e254969df2 | ||
|
|
f1a300acc4 | ||
|
|
755b3daf90 | ||
|
|
32d8992147 | ||
|
|
30ea3ef283 | ||
|
|
f695b30ac2 | ||
|
|
c39526da8a | ||
|
|
45048dc9dc | ||
|
|
b9649d2407 | ||
|
|
48c0e13286 | ||
|
|
ea8b4a450d | ||
|
|
a5ab38093f | ||
|
|
42ce25821d | ||
|
|
2693b89c19 | ||
|
|
47174d60c8 | ||
|
|
0afa2dad76 | ||
|
|
146005a911 | ||
|
|
9ec9415fd9 | ||
|
|
4be18ab295 | ||
|
|
ea914456af | ||
|
|
327c9bb1da | ||
|
|
747cf7a505 | ||
|
|
f3c97ed32e | ||
|
|
d204c4bf01 | ||
|
|
de1a9c77a7 | ||
|
|
b11a37f540 | ||
|
|
f0279ceb92 | ||
|
|
566f6d75bd | ||
|
|
8bf6eaf433 | ||
|
|
6444958f62 | ||
|
|
36f1b183e4 | ||
|
|
bcfd9c9750 | ||
|
|
f6fcd3410d | ||
|
|
188d58eaa9 | ||
|
|
9b0d306a2f | ||
|
|
e0d294c3af | ||
|
|
27beada6d0 | ||
|
|
67ac68e399 | ||
|
|
c167345ffb | ||
|
|
d217c87139 | ||
|
|
e7cac13016 | ||
|
|
b3bf91bdc6 | ||
|
|
2adc0443dd | ||
|
|
ff9395eb3b | ||
|
|
b5055002d7 | ||
|
|
3c603eadb4 | ||
|
|
a7977ece93 | ||
|
|
1205e3207e | ||
|
|
6b6ff9c969 | ||
|
|
2ba4729ef8 | ||
|
|
5680b4517f | ||
|
|
7b742da63e | ||
|
|
2057d3ef75 | ||
|
|
a2dfbbd7d6 | ||
|
|
13918a9ccc | ||
|
|
bde2c04fb7 | ||
|
|
4733df333f | ||
|
|
3210ca6d60 | ||
|
|
105503b839 | ||
|
|
42e5073f94 | ||
|
|
18e8baa5c0 | ||
|
|
31cb852a90 | ||
|
|
2300e16675 | ||
|
|
baef5486bf | ||
|
|
13d4a0d011 | ||
|
|
b9987a7c25 | ||
|
|
3704807805 | ||
|
|
dac3b59721 | ||
|
|
7498fe2e54 | ||
|
|
3fbc371e99 | ||
|
|
8739a182c8 | ||
|
|
1088b4f87c | ||
|
|
4a7424adba | ||
|
|
bcbc3929ae | ||
|
|
6b9d130214 | ||
|
|
4c0655f26b | ||
|
|
1fcd5cca3c | ||
|
|
0d88e15454 | ||
|
|
9a66582604 | ||
|
|
ac8f58f6ab | ||
|
|
143b21e362 | ||
|
|
6d225eb5f9 | ||
|
|
a7f8bd451b | ||
|
|
f48532e271 | ||
|
|
0b15bf1e54 | ||
|
|
a12ea1d5e9 | ||
|
|
629279a45c | ||
|
|
c64667c338 | ||
|
|
37cdd3bfc2 | ||
|
|
c5c31b9eb6 | ||
|
|
c5a4376aed | ||
|
|
3caaf21c5b | ||
|
|
d35541fe29 | ||
|
|
9a7625652c | ||
|
|
76567d84ce | ||
|
|
f7e767d8ee | ||
|
|
2f11a65c99 | ||
|
|
eaa6715b02 | ||
|
|
597d1f4c03 | ||
|
|
8477a66fc8 | ||
|
|
cc7f0c0f3e | ||
|
|
764b3b8090 | ||
|
|
2574573fea | ||
|
|
d3aebeee4e | ||
|
|
d713ec3c46 | ||
|
|
db2fad7516 | ||
|
|
fcd6e4a1c2 | ||
|
|
1b59964162 | ||
|
|
4e23998fb4 | ||
|
|
870cf4356c | ||
|
|
f532504864 | ||
|
|
ecd1eb2162 | ||
|
|
8053dba5a1 | ||
|
|
9586d5e682 | ||
|
|
f7d1486f48 | ||
|
|
1814463864 | ||
|
|
2c3a2ad6f1 | ||
|
|
f4653c1efc | ||
|
|
9b729748ac | ||
|
|
3453c8d6c4 | ||
|
|
83a2bfd7dc | ||
|
|
fff358fb06 | ||
|
|
069eedb3a0 | ||
|
|
a082c562d0 | ||
|
|
34cce144d8 | ||
|
|
38f440120c | ||
|
|
af69ed20c4 | ||
|
|
2346a6da4a | ||
|
|
19e1ec8359 | ||
|
|
462e29703c | ||
|
|
d6a7489dd5 | ||
|
|
cb9133c72f | ||
|
|
a24e1e8027 | ||
|
|
2231669a83 | ||
|
|
d5de63d2be | ||
|
|
081b39f2b7 | ||
|
|
5048d6e7ee | ||
|
|
f701a44305 | ||
|
|
a3452996a1 | ||
|
|
a10a5cb356 | ||
|
|
5599e4275a | ||
|
|
e2ad89092d | ||
|
|
e6ca81ee67 | ||
|
|
a65f1771ad | ||
|
|
77772350f3 | ||
|
|
08edb85bd0 | ||
|
|
0178d974e5 | ||
|
|
4412996d59 | ||
|
|
a7a57d9756 | ||
|
|
240a5a15ef | ||
|
|
cd94d5f68e | ||
|
|
b1a31f8066 | ||
|
|
1e112bce37 | ||
|
|
e8655d49f5 | ||
|
|
3d33a462b3 | ||
|
|
760c214519 | ||
|
|
ee3df31d74 | ||
|
|
ae0215f945 | ||
|
|
8394990b27 | ||
|
|
2ff01aa1e4 | ||
|
|
2930903d51 | ||
|
|
d51d3934f5 | ||
|
|
63860ba7b8 | ||
|
|
ef5918098d | ||
|
|
ce2e278059 | ||
|
|
04de501229 | ||
|
|
bea27a5809 | ||
|
|
657f3e9f14 | ||
|
|
94ebdba71d | ||
|
|
26aebd77b8 | ||
|
|
0e8fea6c13 | ||
|
|
ef15d38df0 | ||
|
|
6dfeea6592 | ||
|
|
43e0e082d1 | ||
|
|
b68f14d0ed | ||
|
|
54c4e0f7a5 | ||
|
|
004fab120a | ||
|
|
66117b97c5 | ||
|
|
d01c9febe9 | ||
|
|
8069f31076 | ||
|
|
15ee8a8c45 | ||
|
|
997e54ea43 | ||
|
|
c614164cb6 | ||
|
|
69b0242e9a | ||
|
|
4758d20227 | ||
|
|
51dc998f3a | ||
|
|
0be513e8e8 | ||
|
|
92ec0674fd | ||
|
|
10a497bd38 | ||
|
|
c530208ae3 | ||
|
|
b35f64241f | ||
|
|
bca4564683 | ||
|
|
58fe1bde59 | ||
|
|
5de0e9ed08 | ||
|
|
7ae1e321a1 | ||
|
|
25c1bada72 | ||
|
|
29938b3a5a | ||
|
|
30ef50b522 | ||
|
|
17559cd8b5 | ||
|
|
85ca2e8a8b | ||
|
|
3134a52d26 | ||
|
|
8975436466 | ||
|
|
914b160fb5 | ||
|
|
0b9be93205 | ||
|
|
ee9325b0bd | ||
|
|
2904eb5800 | ||
|
|
58245d7050 | ||
|
|
6b4a65e8b1 | ||
|
|
92e33c7b31 | ||
|
|
a5469a00a8 | ||
|
|
cc868da526 | ||
|
|
7a7dc9e624 | ||
|
|
c08baa2900 | ||
|
|
22ca468c7c | ||
|
|
ad9dea1f6d | ||
|
|
d68d37872c | ||
|
|
f9d20e6df2 | ||
|
|
0d9417de4a | ||
|
|
a81f037f15 | ||
|
|
e96e49c2f9 | ||
|
|
fbbdba3b04 | ||
|
|
bf8a49abbd | ||
|
|
977356a72b | ||
|
|
f34be01190 | ||
|
|
348bdc0195 | ||
|
|
479443a570 | ||
|
|
c8f5a55df4 | ||
|
|
7b0e12934e | ||
|
|
a7a2d1653b | ||
|
|
7ad1faa6f8 | ||
|
|
a39b723eb3 | ||
|
|
3252e6b63d | ||
|
|
a02f391cbe | ||
|
|
15afee1938 | ||
|
|
ad2e3598d2 | ||
|
|
a6095333a7 | ||
|
|
9aa429a66d | ||
|
|
d578bdad02 | ||
|
|
9fa24f03b5 | ||
|
|
9e19102972 | ||
|
|
069b772915 | ||
|
|
4ba20da8b1 | ||
|
|
aa5a941992 | ||
|
|
7178e68bbe | ||
|
|
e3b2710b04 | ||
|
|
e9b7f98c56 | ||
|
|
5f39262dcc | ||
|
|
b937f1c839 | ||
|
|
eaa7cdf05d | ||
|
|
bdb593ab20 | ||
|
|
adb9b4eddf | ||
|
|
f0ccaff553 | ||
|
|
6bff6cb5a9 | ||
|
|
863f860bfc | ||
|
|
28a8622143 | ||
|
|
f22b828d68 | ||
|
|
2420f44342 | ||
|
|
f16f08e55b | ||
|
|
6557baf336 | ||
|
|
ff1fef9607 | ||
|
|
f496032686 | ||
|
|
349c3118bd | ||
|
|
18b54ef468 | ||
|
|
04e9456567 | ||
|
|
6af42f5102 | ||
|
|
b82b574e76 | ||
|
|
3227a9be5f | ||
|
|
c9fbb1881a | ||
|
|
705fc9f107 | ||
|
|
1aa46abbdf | ||
|
|
7ac3acf762 | ||
|
|
b3e2eb14c5 | ||
|
|
47b9a09120 | ||
|
|
288d73c861 | ||
|
|
511a207444 | ||
|
|
2136de9374 | ||
|
|
58ba880b94 | ||
|
|
6fc2e57c2c | ||
|
|
fb60204d4c | ||
|
|
8097b49997 | ||
|
|
6b3f4bc794 | ||
|
|
41fac44707 | ||
|
|
9d403d6f48 | ||
|
|
bf15ca1091 | ||
|
|
002cf38837 | ||
|
|
f1600db3e4 | ||
|
|
c824eda6cc | ||
|
|
8e7c5a3c8d | ||
|
|
6fed5692d2 | ||
|
|
01d23109ab | ||
|
|
7fde349b25 | ||
|
|
fc83fcb7c4 | ||
|
|
32b3d2f174 | ||
|
|
fe432cacf8 | ||
|
|
ddd75573a7 | ||
|
|
3cc57e67a9 | ||
|
|
eec92e8a5b | ||
|
|
6e99ed72a5 | ||
|
|
0169a985d9 | ||
|
|
66c6b4d6fc | ||
|
|
aefc1088a2 | ||
|
|
67cde46dd7 | ||
|
|
e05f4cf8f4 | ||
|
|
d45617c702 | ||
|
|
07ad5a15c2 | ||
|
|
4ffdf60b85 | ||
|
|
10164407fb | ||
|
|
d7b220b467 | ||
|
|
d856157388 | ||
|
|
8ee9b855a0 | ||
|
|
4863e07c01 | ||
|
|
f16ea6a6eb | ||
|
|
ff0e0a76e8 | ||
|
|
4d50991320 | ||
|
|
dcd6c87b80 | ||
|
|
83dd9b36f4 | ||
|
|
c099d6be1c | ||
|
|
e097bb1d39 | ||
|
|
5661cd8ff4 | ||
|
|
f91c3bb3ab | ||
|
|
36d732c22b | ||
|
|
e45c1f55b4 | ||
|
|
20c2892693 | ||
|
|
2fac50fa0e | ||
|
|
74f4c5cd12 | ||
|
|
4ddde47d8c | ||
|
|
dbed479d79 | ||
|
|
cb9b277b2f | ||
|
|
1935dfb294 | ||
|
|
266868a40b | ||
|
|
6f13620761 | ||
|
|
e0b4c4d1ae | ||
|
|
6d71d33d55 | ||
|
|
05c7259525 | ||
|
|
bf43b4c4b4 | ||
|
|
3135b85423 | ||
|
|
8dc1523057 | ||
|
|
06c8713e89 | ||
|
|
d642dd4311 | ||
|
|
9c2552a1c1 | ||
|
|
ca9bedd538 | ||
|
|
ab71181545 | ||
|
|
36533e8c5a | ||
|
|
775569473d | ||
|
|
9675affae0 | ||
|
|
0842daa24e | ||
|
|
5da2e500d7 | ||
|
|
27530d484e | ||
|
|
50b13f75b8 | ||
|
|
2882778310 | ||
|
|
65e9fb65e8 | ||
|
|
68efc64b72 | ||
|
|
02975a604c | ||
|
|
3a6ec9ea72 | ||
|
|
976ddb61d3 | ||
|
|
83ba1880bf | ||
|
|
eeeb71ed97 | ||
|
|
cd3d7cf4ac | ||
|
|
bc7d4935bb | ||
|
|
ba8bfaafa7 | ||
|
|
bf40776aa4 | ||
|
|
ec73bf53a5 | ||
|
|
405b94c661 | ||
|
|
cd47c1942e | ||
|
|
a340c64a79 | ||
|
|
b5f7f7737a | ||
|
|
2c8430e223 | ||
|
|
deea4ede59 | ||
|
|
e54231d613 | ||
|
|
8440cc4817 | ||
|
|
d9a9a4ffea | ||
|
|
27d5a57072 | ||
|
|
c756eb01c8 | ||
|
|
2fa7092808 | ||
|
|
02463273c9 | ||
|
|
fedcf83f33 | ||
|
|
1b91f41935 | ||
|
|
c3e290963d | ||
|
|
78a6946904 | ||
|
|
c0c789ab50 | ||
|
|
c216c8d6f2 | ||
|
|
a14a987c82 | ||
|
|
507204316a | ||
|
|
b0bfcc368c | ||
|
|
f0a22b23fe | ||
|
|
670101439f | ||
|
|
b39f7c3364 | ||
|
|
8c18df7fcd | ||
|
|
48fca113d1 | ||
|
|
c09b290cea | ||
|
|
0af189c00d | ||
|
|
169c846575 | ||
|
|
018290a344 | ||
|
|
ffb3c50da1 | ||
|
|
327add990f | ||
|
|
f951881e8c | ||
|
|
cb60e66085 | ||
|
|
94655569fe | ||
|
|
ccd23215ed | ||
|
|
2f31a16445 | ||
|
|
04aa9e28d5 | ||
|
|
ea3c817ac2 | ||
|
|
97b6a6f037 | ||
|
|
834f26c3b9 | ||
|
|
42a1b310e1 | ||
|
|
6a86492adf | ||
|
|
099e9bf1ff | ||
|
|
77311e0dff | ||
|
|
51289302ab | ||
|
|
48f5886605 | ||
|
|
2fa710aa6d | ||
|
|
45de35fc58 | ||
|
|
c4e5c54d69 | ||
|
|
3cf5c213f1 | ||
|
|
c4c0331f65 | ||
|
|
88a888f022 | ||
|
|
393d9d0195 | ||
|
|
47cf7c25a2 | ||
|
|
15dac923b9 | ||
|
|
9c3c1f3725 | ||
|
|
bcd12de6c3 | ||
|
|
9e7140b451 | ||
|
|
1bb63bf669 | ||
|
|
b60617f5ff | ||
|
|
453f18040f | ||
|
|
07c48ccfe0 | ||
|
|
b71245683b | ||
|
|
bcd0c49af3 | ||
|
|
8697d14ec8 | ||
|
|
66919e370b | ||
|
|
3ab8a05b37 | ||
|
|
b58a8ccb02 | ||
|
|
4684d286de | ||
|
|
3833905ff2 | ||
|
|
3fa7e5c62c | ||
|
|
defe094e9e | ||
|
|
ddfe906be2 | ||
|
|
5881601488 | ||
|
|
8121f85473 | ||
|
|
47d6f16a04 | ||
|
|
af9002dd16 | ||
|
|
cc168054a8 | ||
|
|
e96ab22462 | ||
|
|
904b957ae9 | ||
|
|
aa911e8b41 | ||
|
|
0998a146d4 | ||
|
|
3c16bbb73b | ||
|
|
57e987576f | ||
|
|
1d12a125e7 | ||
|
|
a6b6258284 | ||
|
|
84f106f198 | ||
|
|
7e7d820d5b | ||
|
|
0acc270830 | ||
|
|
7e79831016 | ||
|
|
672100a84e | ||
|
|
3d1fa00fce | ||
|
|
66f36f4735 | ||
|
|
b1dcaf7f1e | ||
|
|
7f2daa74a0 | ||
|
|
6036a0d24f | ||
|
|
1e224dcb83 | ||
|
|
0d1e5a21c4 | ||
|
|
62a332160f | ||
|
|
4d4231352c | ||
|
|
f091752a9c | ||
|
|
4e1ba35458 | ||
|
|
97d6a4cbd1 | ||
|
|
bf6fcebfed | ||
|
|
52b3e1a633 | ||
|
|
9cb470eba7 | ||
|
|
1f8e8e5bf1 | ||
|
|
3e7025022e | ||
|
|
a63adac604 | ||
|
|
bf05cd3c99 | ||
|
|
c7342f35c8 | ||
|
|
f62dcc9c33 | ||
|
|
b5bc9ee02d | ||
|
|
a9b81da575 | ||
|
|
0620081731 | ||
|
|
0f014c97e5 | ||
|
|
e9d07c0c2a | ||
|
|
d218b0914e | ||
|
|
06a82af0de | ||
|
|
ca4e27f5da | ||
|
|
6ab0870d45 | ||
|
|
6c2d732bf4 | ||
|
|
1cb44945fb | ||
|
|
2104454607 | ||
|
|
cc43012674 | ||
|
|
72a43e2378 | ||
|
|
0bf6b51572 | ||
|
|
ff37a911ce | ||
|
|
4682130b60 | ||
|
|
ac3996a6d1 | ||
|
|
44600442dc | ||
|
|
5127e58dab | ||
|
|
60a10116d1 | ||
|
|
543ebc900f | ||
|
|
9216ba58d8 | ||
|
|
e6c1993f1b | ||
|
|
fddf66b741 | ||
|
|
b63e88e506 | ||
|
|
61d05c1e67 | ||
|
|
cc04ae1565 | ||
|
|
e6cf741ae6 | ||
|
|
158b300952 | ||
|
|
2865de86ec | ||
|
|
d12f25f216 | ||
|
|
725606a678 | ||
|
|
106c342659 | ||
|
|
d5edf56bb5 | ||
|
|
f82280820a | ||
|
|
716c1d5ff5 | ||
|
|
81914ce68a | ||
|
|
ccada0636b | ||
|
|
cfc79a357a | ||
|
|
b89ba05ab4 | ||
|
|
76550dfdc0 | ||
|
|
945ccfee59 | ||
|
|
7635ee0f37 | ||
|
|
1cd926d665 | ||
|
|
61927ba4ac | ||
|
|
e07e74fb0f | ||
|
|
f2c1aea118 | ||
|
|
71061e9332 | ||
|
|
615566aa81 | ||
|
|
86fed469ec | ||
|
|
327a02d77e | ||
|
|
3e7aa8fda9 | ||
|
|
9c2bb7f342 | ||
|
|
429e652809 | ||
|
|
4b402746ca | ||
|
|
f670628ca5 | ||
|
|
c1a90dc160 | ||
|
|
bd86de1ac8 | ||
|
|
2b24aa87d9 | ||
|
|
25301a84a8 | ||
|
|
eeb288d568 | ||
|
|
de9ae32b93 | ||
|
|
8a1fb40273 | ||
|
|
5ad4159ebb | ||
|
|
4526ec7907 | ||
|
|
5ecde212a8 | ||
|
|
318ca07657 | ||
|
|
e7db593a46 | ||
|
|
45664383f1 | ||
|
|
7a48bfab47 | ||
|
|
f024518387 | ||
|
|
3c4ea94210 | ||
|
|
016933ad48 | ||
|
|
ce7b38459a | ||
|
|
91f87e7513 | ||
|
|
22dcfa80aa | ||
|
|
943f9c0356 | ||
|
|
c3f095c8b3 | ||
|
|
82b88a7fd0 | ||
|
|
bc1c18e18c | ||
|
|
ac04d11abc | ||
|
|
0fefc6873a | ||
|
|
b73f99745b | ||
|
|
71f5314993 | ||
|
|
b106abe570 | ||
|
|
259e835b1b | ||
|
|
1a5482d4d8 | ||
|
|
cf76ee2cb7 | ||
|
|
3c2f076ad0 | ||
|
|
66695533a8 | ||
|
|
537949a9df | ||
|
|
91f01a2060 | ||
|
|
85f3a82355 | ||
|
|
aa327a1ed4 | ||
|
|
641fda79bb | ||
|
|
dbc5090b5e | ||
|
|
2a21b45fdc | ||
|
|
a16ca80b09 | ||
|
|
bb40844e32 | ||
|
|
0b60d3ffa5 | ||
|
|
8d5d21aaec | ||
|
|
d89b4f5ece | ||
|
|
12ec948490 | ||
|
|
5b10674b5c | ||
|
|
726556dde9 | ||
|
|
ce6318f254 | ||
|
|
e4985cf619 | ||
|
|
8f95389742 | ||
|
|
770c6663d6 | ||
|
|
dc90501ba3 | ||
|
|
359a6796da | ||
|
|
5cc0a364ae | ||
|
|
bfd62cdaff | ||
|
|
f60171bb4f | ||
|
|
f8d744d91a | ||
|
|
2ba383474d | ||
|
|
0f751ecee3 | ||
|
|
1eb8a718bf | ||
|
|
2dac808dd1 | ||
|
|
3bda634576 | ||
|
|
a7949f2dd2 | ||
|
|
59917dd18e | ||
|
|
969957f9f2 | ||
|
|
32f68cc58c | ||
|
|
9efc42f4f8 | ||
|
|
750e753134 | ||
|
|
df7e1fecc1 | ||
|
|
280ad35553 | ||
|
|
dcfff3ccc8 | ||
|
|
d47f257484 | ||
|
|
106c620a23 | ||
|
|
4ce20fb3f4 | ||
|
|
164db8278f | ||
|
|
9b1a2aa82b | ||
|
|
d94d0ed12f | ||
|
|
6d38ad4146 | ||
|
|
6985a0f516 | ||
|
|
ad1aad69fb | ||
|
|
d0495132aa | ||
|
|
b16c77cdc4 | ||
|
|
407fad2356 | ||
|
|
c1553f859f | ||
|
|
db99840bf6 | ||
|
|
f380a1658d | ||
|
|
eacc3b4ccf | ||
|
|
fe4791b0d5 | ||
|
|
4d50dc5ab5 | ||
|
|
37cd112b0f | ||
|
|
3b2d08a93b | ||
|
|
519b2e48a8 | ||
|
|
70a3652693 | ||
|
|
a762cef917 | ||
|
|
633dbcb458 | ||
|
|
3a7ad43fb8 | ||
|
|
8b0c11c358 | ||
|
|
8d0c8c5e6b | ||
|
|
8e8e2d11bf | ||
|
|
ac1358cd56 | ||
|
|
91aa1fae2a | ||
|
|
75d2443bf0 | ||
|
|
182ea677a0 | ||
|
|
d82b9f62a9 | ||
|
|
b987bc36af | ||
|
|
40ffa2839f | ||
|
|
270fadc135 | ||
|
|
f38ed0c560 | ||
|
|
b71ff28a1a | ||
|
|
881bef00c7 | ||
|
|
f4169936ee | ||
|
|
219cdab676 | ||
|
|
b0d8a75e48 | ||
|
|
b608c09781 | ||
|
|
13234d3c43 | ||
|
|
0f9760ab6f | ||
|
|
e0c0e65378 | ||
|
|
ee5b29ae30 | ||
|
|
e758f9d457 | ||
|
|
70c9b3c668 | ||
|
|
9152d434dc | ||
|
|
255866419d | ||
|
|
0c65aed099 | ||
|
|
add0587fae | ||
|
|
34be6057da | ||
|
|
a9ae351667 | ||
|
|
5f21aba4b0 | ||
|
|
c42a281439 | ||
|
|
159cc3b33c | ||
|
|
f217049dbe | ||
|
|
47270b6858 | ||
|
|
b6fe63a505 | ||
|
|
553e9e291f | ||
|
|
a981cb2809 | ||
|
|
888bb6c133 | ||
|
|
2ff2376fbc | ||
|
|
d630cda597 | ||
|
|
39fff1bea0 | ||
|
|
f65170ea84 | ||
|
|
297dfd8696 | ||
|
|
baa4a290eb | ||
|
|
3628975a15 | ||
|
|
70ead526f1 | ||
|
|
6e07bf3634 | ||
|
|
9f27d1f843 | ||
|
|
605ca82e7f | ||
|
|
d98bd7cc5f | ||
|
|
f129e09529 | ||
|
|
68d0f46ec0 | ||
|
|
6886da7547 | ||
|
|
7a0bfa6ec6 | ||
|
|
7e3a82c384 | ||
|
|
9a780fa7db | ||
|
|
91fc730d83 | ||
|
|
299ef2f8eb | ||
|
|
198b834c97 | ||
|
|
5b1a8ca5e8 | ||
|
|
9480da21e8 | ||
|
|
62cce50d55 | ||
|
|
35c4a13eb7 | ||
|
|
bea22782e9 | ||
|
|
371a64bfe7 | ||
|
|
c23970ec25 | ||
|
|
6abdd31555 | ||
|
|
d3db846cc5 | ||
|
|
380a26112c |
@@ -1,7 +1,7 @@
|
||||
---
|
||||
Language: Cpp
|
||||
# BasedOnStyle: Google
|
||||
# Generated with clang-format 3.8.1
|
||||
# Generated with clang-format 4.0.1
|
||||
AccessModifierOffset: -1
|
||||
AlignAfterOpenBracket: Align
|
||||
AlignConsecutiveAssignments: false
|
||||
@@ -37,6 +37,8 @@ BreakBeforeBinaryOperators: None
|
||||
BreakBeforeBraces: Attach
|
||||
BreakBeforeTernaryOperators: true
|
||||
BreakConstructorInitializersBeforeComma: false
|
||||
BreakAfterJavaFieldAnnotations: false
|
||||
BreakStringLiterals: true
|
||||
ColumnLimit: 80
|
||||
CommentPragmas: '^ IWYU pragma:'
|
||||
ConstructorInitializerAllOnOneLineOrOnePerLine: false
|
||||
@@ -54,9 +56,12 @@ IncludeCategories:
|
||||
Priority: 2
|
||||
- Regex: '.*'
|
||||
Priority: 3
|
||||
IncludeIsMainRegex: '([-_](test|unittest))?$'
|
||||
IndentCaseLabels: true
|
||||
IndentWidth: 2
|
||||
IndentWrappedFunctionNames: false
|
||||
JavaScriptQuotes: Leave
|
||||
JavaScriptWrapImports: true
|
||||
KeepEmptyLinesAtTheStartOfBlocks: false
|
||||
MacroBlockBegin: ''
|
||||
MacroBlockEnd: ''
|
||||
@@ -75,6 +80,7 @@ PointerAlignment: Right
|
||||
ReflowComments: true
|
||||
SortIncludes: false
|
||||
SpaceAfterCStyleCast: false
|
||||
SpaceAfterTemplateKeyword: true
|
||||
SpaceBeforeAssignmentOperators: true
|
||||
SpaceBeforeParens: ControlStatements
|
||||
SpaceInEmptyParentheses: false
|
||||
|
||||
1
.mailmap
1
.mailmap
@@ -33,5 +33,6 @@ Tero Rintaluoma <teror@google.com> <tero.rintaluoma@on2.com>
|
||||
Timothy B. Terriberry <tterribe@xiph.org> <tterriberry@mozilla.com>
|
||||
Tom Finegan <tomfinegan@google.com>
|
||||
Tom Finegan <tomfinegan@google.com> <tomfinegan@chromium.org>
|
||||
Yaowu Xu <yaowu@google.com> <adam@xuyaowu.com>
|
||||
Yaowu Xu <yaowu@google.com> <yaowu@xuyaowu.com>
|
||||
Yaowu Xu <yaowu@google.com> <Yaowu Xu>
|
||||
|
||||
1
AUTHORS
1
AUTHORS
@@ -131,6 +131,7 @@ Sean McGovern <gseanmcg@gmail.com>
|
||||
Sergey Kolomenkin <kolomenkin@gmail.com>
|
||||
Sergey Ulanov <sergeyu@chromium.org>
|
||||
Shimon Doodkin <helpmepro1@gmail.com>
|
||||
Shiyou Yin <yinshiyou-hf@loongson.cn>
|
||||
Shunyao Li <shunyaoli@google.com>
|
||||
Stefan Holmer <holmer@google.com>
|
||||
Suman Sunkara <sunkaras@google.com>
|
||||
|
||||
7
README
7
README
@@ -1,4 +1,4 @@
|
||||
README - 9 January 2017
|
||||
README - 26 January 2017
|
||||
|
||||
Welcome to the WebM VP8/VP9 Codec SDK!
|
||||
|
||||
@@ -58,6 +58,7 @@ COMPILING THE APPLICATIONS/LIBRARIES:
|
||||
armv7-win32-vs11
|
||||
armv7-win32-vs12
|
||||
armv7-win32-vs14
|
||||
armv7-win32-vs15
|
||||
armv7s-darwin-gcc
|
||||
armv8-linux-gcc
|
||||
mips32-linux-gcc
|
||||
@@ -74,6 +75,7 @@ COMPILING THE APPLICATIONS/LIBRARIES:
|
||||
x86-darwin13-gcc
|
||||
x86-darwin14-gcc
|
||||
x86-darwin15-gcc
|
||||
x86-darwin16-gcc
|
||||
x86-iphonesimulator-gcc
|
||||
x86-linux-gcc
|
||||
x86-linux-icc
|
||||
@@ -84,6 +86,7 @@ COMPILING THE APPLICATIONS/LIBRARIES:
|
||||
x86-win32-vs11
|
||||
x86-win32-vs12
|
||||
x86-win32-vs14
|
||||
x86-win32-vs15
|
||||
x86_64-android-gcc
|
||||
x86_64-darwin9-gcc
|
||||
x86_64-darwin10-gcc
|
||||
@@ -92,6 +95,7 @@ COMPILING THE APPLICATIONS/LIBRARIES:
|
||||
x86_64-darwin13-gcc
|
||||
x86_64-darwin14-gcc
|
||||
x86_64-darwin15-gcc
|
||||
x86_64-darwin16-gcc
|
||||
x86_64-iphonesimulator-gcc
|
||||
x86_64-linux-gcc
|
||||
x86_64-linux-icc
|
||||
@@ -101,6 +105,7 @@ COMPILING THE APPLICATIONS/LIBRARIES:
|
||||
x86_64-win64-vs11
|
||||
x86_64-win64-vs12
|
||||
x86_64-win64-vs14
|
||||
x86_64-win64-vs15
|
||||
generic-gnu
|
||||
|
||||
The generic-gnu target, in conjunction with the CROSS environment variable,
|
||||
|
||||
@@ -124,6 +124,7 @@ ifeq ($(TOOLCHAIN), x86-os2-gcc)
|
||||
CFLAGS += -mstackrealign
|
||||
endif
|
||||
|
||||
# x86[_64]
|
||||
$(BUILD_PFX)%_mmx.c.d: CFLAGS += -mmmx
|
||||
$(BUILD_PFX)%_mmx.c.o: CFLAGS += -mmmx
|
||||
$(BUILD_PFX)%_sse2.c.d: CFLAGS += -msse2
|
||||
@@ -138,6 +139,12 @@ $(BUILD_PFX)%_avx.c.d: CFLAGS += -mavx
|
||||
$(BUILD_PFX)%_avx.c.o: CFLAGS += -mavx
|
||||
$(BUILD_PFX)%_avx2.c.d: CFLAGS += -mavx2
|
||||
$(BUILD_PFX)%_avx2.c.o: CFLAGS += -mavx2
|
||||
$(BUILD_PFX)%_avx512.c.d: CFLAGS += -mavx512f -mavx512cd -mavx512bw -mavx512dq -mavx512vl
|
||||
$(BUILD_PFX)%_avx512.c.o: CFLAGS += -mavx512f -mavx512cd -mavx512bw -mavx512dq -mavx512vl
|
||||
|
||||
# POWER
|
||||
$(BUILD_PFX)%_vsx.c.d: CFLAGS += -maltivec -mvsx
|
||||
$(BUILD_PFX)%_vsx.c.o: CFLAGS += -maltivec -mvsx
|
||||
|
||||
$(BUILD_PFX)%.c.d: %.c
|
||||
$(if $(quiet),@echo " [DEP] $@")
|
||||
|
||||
@@ -403,6 +403,23 @@ check_gcc_machine_option() {
|
||||
fi
|
||||
}
|
||||
|
||||
# tests for -m$2, -m$3, -m$4... toggling the feature given in $1.
|
||||
check_gcc_machine_options() {
|
||||
feature="$1"
|
||||
shift
|
||||
flags="-m$1"
|
||||
shift
|
||||
for opt in $*; do
|
||||
flags="$flags -m$opt"
|
||||
done
|
||||
|
||||
if enabled gcc && ! disabled "$feature" && ! check_cflags $flags; then
|
||||
RTCD_OPTIONS="${RTCD_OPTIONS}--disable-$feature "
|
||||
else
|
||||
soft_enable "$feature"
|
||||
fi
|
||||
}
|
||||
|
||||
write_common_config_banner() {
|
||||
print_webm_license config.mk "##" ""
|
||||
echo '# This file automatically generated by configure. Do not edit!' >> config.mk
|
||||
@@ -674,7 +691,6 @@ check_xcode_minimum_version() {
|
||||
process_common_toolchain() {
|
||||
if [ -z "$toolchain" ]; then
|
||||
gcctarget="${CHOST:-$(gcc -dumpmachine 2> /dev/null)}"
|
||||
|
||||
# detect tgt_isa
|
||||
case "$gcctarget" in
|
||||
aarch64*)
|
||||
@@ -697,6 +713,18 @@ process_common_toolchain() {
|
||||
*sparc*)
|
||||
tgt_isa=sparc
|
||||
;;
|
||||
power*64*-*)
|
||||
tgt_isa=ppc64
|
||||
;;
|
||||
power*)
|
||||
tgt_isa=ppc
|
||||
;;
|
||||
*mips64el*)
|
||||
tgt_isa=mips64
|
||||
;;
|
||||
*mips32el*)
|
||||
tgt_isa=mips32
|
||||
;;
|
||||
esac
|
||||
|
||||
# detect tgt_os
|
||||
@@ -725,9 +753,16 @@ process_common_toolchain() {
|
||||
tgt_isa=x86_64
|
||||
tgt_os=darwin15
|
||||
;;
|
||||
*darwin16*)
|
||||
tgt_isa=x86_64
|
||||
tgt_os=darwin16
|
||||
;;
|
||||
x86_64*mingw32*)
|
||||
tgt_os=win64
|
||||
;;
|
||||
x86_64*cygwin*)
|
||||
tgt_os=win64
|
||||
;;
|
||||
*mingw32*|*cygwin*)
|
||||
[ -z "$tgt_isa" ] && tgt_isa=x86
|
||||
tgt_os=win32
|
||||
@@ -775,6 +810,9 @@ process_common_toolchain() {
|
||||
mips*)
|
||||
enable_feature mips
|
||||
;;
|
||||
ppc*)
|
||||
enable_feature ppc
|
||||
;;
|
||||
esac
|
||||
|
||||
# PIC is probably what we want when building shared libs
|
||||
@@ -843,6 +881,10 @@ process_common_toolchain() {
|
||||
add_cflags "-mmacosx-version-min=10.11"
|
||||
add_ldflags "-mmacosx-version-min=10.11"
|
||||
;;
|
||||
*-darwin16-*)
|
||||
add_cflags "-mmacosx-version-min=10.12"
|
||||
add_ldflags "-mmacosx-version-min=10.12"
|
||||
;;
|
||||
*-iphonesimulator-*)
|
||||
add_cflags "-miphoneos-version-min=${IOS_VERSION_MIN}"
|
||||
add_ldflags "-miphoneos-version-min=${IOS_VERSION_MIN}"
|
||||
@@ -1144,10 +1186,20 @@ EOF
|
||||
fi
|
||||
fi
|
||||
|
||||
if enabled mmi; then
|
||||
tgt_isa=loongson3a
|
||||
check_add_ldflags -march=loongson3a
|
||||
fi
|
||||
|
||||
check_add_cflags -march=${tgt_isa}
|
||||
check_add_asflags -march=${tgt_isa}
|
||||
check_add_asflags -KPIC
|
||||
;;
|
||||
ppc*)
|
||||
link_with_cc=gcc
|
||||
setup_gnu_toolchain
|
||||
check_gcc_machine_option "vsx"
|
||||
;;
|
||||
x86*)
|
||||
case ${tgt_os} in
|
||||
win*)
|
||||
@@ -1202,6 +1254,13 @@ EOF
|
||||
AS=msvs
|
||||
msvs_arch_dir=x86-msvs
|
||||
vc_version=${tgt_cc##vs}
|
||||
case $vc_version in
|
||||
7|8|9|10|11|12|13|14)
|
||||
echo "${tgt_cc} does not support avx512, disabling....."
|
||||
RTCD_OPTIONS="${RTCD_OPTIONS}--disable-avx512 "
|
||||
soft_disable avx512
|
||||
;;
|
||||
esac
|
||||
case $vc_version in
|
||||
7|8|9|10)
|
||||
echo "${tgt_cc} does not support avx/avx2, disabling....."
|
||||
@@ -1246,8 +1305,12 @@ EOF
|
||||
elif disabled $ext; then
|
||||
disable_exts="yes"
|
||||
else
|
||||
# use the shortened version for the flag: sse4_1 -> sse4
|
||||
check_gcc_machine_option ${ext%_*} $ext
|
||||
if [ "$ext" = "avx512" ]; then
|
||||
check_gcc_machine_options $ext avx512f avx512cd avx512bw avx512dq avx512vl
|
||||
else
|
||||
# use the shortened version for the flag: sse4_1 -> sse4
|
||||
check_gcc_machine_option ${ext%_*} $ext
|
||||
fi
|
||||
fi
|
||||
done
|
||||
|
||||
@@ -1273,7 +1336,6 @@ EOF
|
||||
esac
|
||||
log_echo " using $AS"
|
||||
fi
|
||||
[ "${AS##*/}" = nasm ] && add_asflags -Ox
|
||||
AS_SFX=.asm
|
||||
case ${tgt_os} in
|
||||
win32)
|
||||
@@ -1282,7 +1344,7 @@ EOF
|
||||
EXE_SFX=.exe
|
||||
;;
|
||||
win64)
|
||||
add_asflags -f x64
|
||||
add_asflags -f win64
|
||||
enabled debug && add_asflags -g cv8
|
||||
EXE_SFX=.exe
|
||||
;;
|
||||
@@ -1416,6 +1478,10 @@ EOF
|
||||
echo "msa optimizations are available only for little endian platforms"
|
||||
disable_feature msa
|
||||
fi
|
||||
if enabled mmi; then
|
||||
echo "mmi optimizations are available only for little endian platforms"
|
||||
disable_feature mmi
|
||||
fi
|
||||
fi
|
||||
;;
|
||||
esac
|
||||
|
||||
@@ -25,7 +25,7 @@ files.
|
||||
Options:
|
||||
--help Print this message
|
||||
--out=outfile Redirect output to a file
|
||||
--ver=version Version (7,8,9,10,11,12,14) of visual studio to generate for
|
||||
--ver=version Version (7,8,9,10,11,12,14,15) of visual studio to generate for
|
||||
--target=isa-os-cc Target specifier
|
||||
EOF
|
||||
exit 1
|
||||
@@ -215,7 +215,7 @@ for opt in "$@"; do
|
||||
;;
|
||||
--ver=*) vs_ver="$optval"
|
||||
case $optval in
|
||||
10|11|12|14)
|
||||
10|11|12|14|15)
|
||||
;;
|
||||
*) die Unrecognized Visual Studio Version in $opt
|
||||
;;
|
||||
@@ -240,9 +240,12 @@ case "${vs_ver:-10}" in
|
||||
12) sln_vers="12.00"
|
||||
sln_vers_str="Visual Studio 2013"
|
||||
;;
|
||||
14) sln_vers="14.00"
|
||||
14) sln_vers="12.00"
|
||||
sln_vers_str="Visual Studio 2015"
|
||||
;;
|
||||
15) sln_vers="12.00"
|
||||
sln_vers_str="Visual Studio 2017"
|
||||
;;
|
||||
esac
|
||||
sfx=vcxproj
|
||||
|
||||
|
||||
@@ -34,7 +34,7 @@ Options:
|
||||
--name=project_name Name of the project (required)
|
||||
--proj-guid=GUID GUID to use for the project
|
||||
--module-def=filename File containing export definitions (for DLLs)
|
||||
--ver=version Version (10,11,12,14) of visual studio to generate for
|
||||
--ver=version Version (10,11,12,14,15) of visual studio to generate for
|
||||
--src-path-bare=dir Path to root of source tree
|
||||
-Ipath/to/include Additional include directories
|
||||
-DFLAG[=value] Preprocessor macros to define
|
||||
@@ -168,7 +168,7 @@ for opt in "$@"; do
|
||||
--ver=*)
|
||||
vs_ver="$optval"
|
||||
case "$optval" in
|
||||
10|11|12|14)
|
||||
10|11|12|14|15)
|
||||
;;
|
||||
*) die Unrecognized Visual Studio Version in $opt
|
||||
;;
|
||||
@@ -218,7 +218,7 @@ guid=${guid:-`generate_uuid`}
|
||||
asm_use_custom_step=false
|
||||
uses_asm=${uses_asm:-false}
|
||||
case "${vs_ver:-11}" in
|
||||
10|11|12|14)
|
||||
10|11|12|14|15)
|
||||
asm_use_custom_step=$uses_asm
|
||||
;;
|
||||
esac
|
||||
@@ -347,6 +347,9 @@ generate_vcxproj() {
|
||||
if [ "$vs_ver" = "14" ]; then
|
||||
tag_content PlatformToolset v140
|
||||
fi
|
||||
if [ "$vs_ver" = "15" ]; then
|
||||
tag_content PlatformToolset v141
|
||||
fi
|
||||
tag_content CharacterSet Unicode
|
||||
if [ "$config" = "Release" ]; then
|
||||
tag_content WholeProgramOptimization true
|
||||
|
||||
@@ -35,8 +35,8 @@ ARM_TARGETS="arm64-darwin-gcc
|
||||
armv7s-darwin-gcc"
|
||||
SIM_TARGETS="x86-iphonesimulator-gcc
|
||||
x86_64-iphonesimulator-gcc"
|
||||
OSX_TARGETS="x86-darwin15-gcc
|
||||
x86_64-darwin15-gcc"
|
||||
OSX_TARGETS="x86-darwin16-gcc
|
||||
x86_64-darwin16-gcc"
|
||||
TARGETS="${ARM_TARGETS} ${SIM_TARGETS}"
|
||||
|
||||
# Configures for the target specified by $1, and invokes make with the dist
|
||||
@@ -271,7 +271,7 @@ cat << EOF
|
||||
--help: Display this message and exit.
|
||||
--enable-shared: Build a dynamic framework for use on iOS 8 or later.
|
||||
--extra-configure-args <args>: Extra args to pass when configuring libvpx.
|
||||
--macosx: Uses darwin15 targets instead of iphonesimulator targets for x86
|
||||
--macosx: Uses darwin16 targets instead of iphonesimulator targets for x86
|
||||
and x86_64. Allows linking to framework when builds target MacOSX
|
||||
instead of iOS.
|
||||
--preserve-build-output: Do not delete the build directory.
|
||||
|
||||
@@ -335,6 +335,36 @@ EOF
|
||||
common_bottom;
|
||||
}
|
||||
|
||||
sub ppc() {
|
||||
determine_indirection("c", @ALL_ARCHS);
|
||||
|
||||
# Assign the helper variable for each enabled extension
|
||||
foreach my $opt (@ALL_ARCHS) {
|
||||
my $opt_uc = uc $opt;
|
||||
eval "\$have_${opt}=\"flags & HAS_${opt_uc}\"";
|
||||
}
|
||||
|
||||
common_top;
|
||||
print <<EOF;
|
||||
#include "vpx_config.h"
|
||||
|
||||
#ifdef RTCD_C
|
||||
#include "vpx_ports/ppc.h"
|
||||
static void setup_rtcd_internal(void)
|
||||
{
|
||||
int flags = ppc_simd_caps();
|
||||
(void)flags;
|
||||
EOF
|
||||
|
||||
set_function_pointers("c", @ALL_ARCHS);
|
||||
|
||||
print <<EOF;
|
||||
}
|
||||
#endif
|
||||
EOF
|
||||
common_bottom;
|
||||
}
|
||||
|
||||
sub unoptimized() {
|
||||
determine_indirection "c";
|
||||
common_top;
|
||||
@@ -361,10 +391,10 @@ EOF
|
||||
|
||||
&require("c");
|
||||
if ($opts{arch} eq 'x86') {
|
||||
@ALL_ARCHS = filter(qw/mmx sse sse2 sse3 ssse3 sse4_1 avx avx2/);
|
||||
@ALL_ARCHS = filter(qw/mmx sse sse2 sse3 ssse3 sse4_1 avx avx2 avx512/);
|
||||
x86;
|
||||
} elsif ($opts{arch} eq 'x86_64') {
|
||||
@ALL_ARCHS = filter(qw/mmx sse sse2 sse3 ssse3 sse4_1 avx avx2/);
|
||||
@ALL_ARCHS = filter(qw/mmx sse sse2 sse3 ssse3 sse4_1 avx avx2 avx512/);
|
||||
@REQUIRES = filter(keys %required ? keys %required : qw/mmx sse sse2/);
|
||||
&require(@REQUIRES);
|
||||
x86;
|
||||
@@ -381,6 +411,10 @@ if ($opts{arch} eq 'x86') {
|
||||
@ALL_ARCHS = filter("$opts{arch}", qw/msa/);
|
||||
last;
|
||||
}
|
||||
if (/HAVE_MMI=yes/) {
|
||||
@ALL_ARCHS = filter("$opts{arch}", qw/mmi/);
|
||||
last;
|
||||
}
|
||||
}
|
||||
close CONFIG_FILE;
|
||||
mips;
|
||||
@@ -390,6 +424,9 @@ if ($opts{arch} eq 'x86') {
|
||||
} elsif ($opts{arch} eq 'armv8' || $opts{arch} eq 'arm64' ) {
|
||||
@ALL_ARCHS = filter(qw/neon/);
|
||||
arm;
|
||||
} elsif ($opts{arch} =~ /^ppc/ ) {
|
||||
@ALL_ARCHS = filter(qw/vsx/);
|
||||
ppc;
|
||||
} else {
|
||||
unoptimized;
|
||||
}
|
||||
|
||||
35
configure
vendored
35
configure
vendored
@@ -109,10 +109,13 @@ all_platforms="${all_platforms} armv7-none-rvct" #neon Cortex-A8
|
||||
all_platforms="${all_platforms} armv7-win32-vs11"
|
||||
all_platforms="${all_platforms} armv7-win32-vs12"
|
||||
all_platforms="${all_platforms} armv7-win32-vs14"
|
||||
all_platforms="${all_platforms} armv7-win32-vs15"
|
||||
all_platforms="${all_platforms} armv7s-darwin-gcc"
|
||||
all_platforms="${all_platforms} armv8-linux-gcc"
|
||||
all_platforms="${all_platforms} mips32-linux-gcc"
|
||||
all_platforms="${all_platforms} mips64-linux-gcc"
|
||||
all_platforms="${all_platforms} ppc64-linux-gcc"
|
||||
all_platforms="${all_platforms} ppc64le-linux-gcc"
|
||||
all_platforms="${all_platforms} sparc-solaris-gcc"
|
||||
all_platforms="${all_platforms} x86-android-gcc"
|
||||
all_platforms="${all_platforms} x86-darwin8-gcc"
|
||||
@@ -125,6 +128,7 @@ all_platforms="${all_platforms} x86-darwin12-gcc"
|
||||
all_platforms="${all_platforms} x86-darwin13-gcc"
|
||||
all_platforms="${all_platforms} x86-darwin14-gcc"
|
||||
all_platforms="${all_platforms} x86-darwin15-gcc"
|
||||
all_platforms="${all_platforms} x86-darwin16-gcc"
|
||||
all_platforms="${all_platforms} x86-iphonesimulator-gcc"
|
||||
all_platforms="${all_platforms} x86-linux-gcc"
|
||||
all_platforms="${all_platforms} x86-linux-icc"
|
||||
@@ -135,6 +139,7 @@ all_platforms="${all_platforms} x86-win32-vs10"
|
||||
all_platforms="${all_platforms} x86-win32-vs11"
|
||||
all_platforms="${all_platforms} x86-win32-vs12"
|
||||
all_platforms="${all_platforms} x86-win32-vs14"
|
||||
all_platforms="${all_platforms} x86-win32-vs15"
|
||||
all_platforms="${all_platforms} x86_64-android-gcc"
|
||||
all_platforms="${all_platforms} x86_64-darwin9-gcc"
|
||||
all_platforms="${all_platforms} x86_64-darwin10-gcc"
|
||||
@@ -143,6 +148,7 @@ all_platforms="${all_platforms} x86_64-darwin12-gcc"
|
||||
all_platforms="${all_platforms} x86_64-darwin13-gcc"
|
||||
all_platforms="${all_platforms} x86_64-darwin14-gcc"
|
||||
all_platforms="${all_platforms} x86_64-darwin15-gcc"
|
||||
all_platforms="${all_platforms} x86_64-darwin16-gcc"
|
||||
all_platforms="${all_platforms} x86_64-iphonesimulator-gcc"
|
||||
all_platforms="${all_platforms} x86_64-linux-gcc"
|
||||
all_platforms="${all_platforms} x86_64-linux-icc"
|
||||
@@ -152,6 +158,7 @@ all_platforms="${all_platforms} x86_64-win64-vs10"
|
||||
all_platforms="${all_platforms} x86_64-win64-vs11"
|
||||
all_platforms="${all_platforms} x86_64-win64-vs12"
|
||||
all_platforms="${all_platforms} x86_64-win64-vs14"
|
||||
all_platforms="${all_platforms} x86_64-win64-vs15"
|
||||
all_platforms="${all_platforms} generic-gnu"
|
||||
|
||||
# all_targets is a list of all targets that can be configured
|
||||
@@ -163,11 +170,14 @@ for t in ${all_targets}; do
|
||||
[ -f "${source_path}/${t}.mk" ] && enable_feature ${t}
|
||||
done
|
||||
|
||||
if ! diff --version >/dev/null; then
|
||||
die "diff missing: Try installing diffutils via your package manager."
|
||||
fi
|
||||
|
||||
if ! perl --version >/dev/null; then
|
||||
die "Perl is required to build"
|
||||
fi
|
||||
|
||||
|
||||
if [ "`cd \"${source_path}\" && pwd`" != "`pwd`" ]; then
|
||||
# test to see if source_path already configured
|
||||
if [ -f "${source_path}/vpx_config.h" ]; then
|
||||
@@ -223,6 +233,7 @@ ARCH_LIST="
|
||||
mips
|
||||
x86
|
||||
x86_64
|
||||
ppc
|
||||
"
|
||||
ARCH_EXT_LIST_X86="
|
||||
mmx
|
||||
@@ -233,7 +244,13 @@ ARCH_EXT_LIST_X86="
|
||||
sse4_1
|
||||
avx
|
||||
avx2
|
||||
avx512
|
||||
"
|
||||
|
||||
ARCH_EXT_LIST_LOONGSON="
|
||||
mmi
|
||||
"
|
||||
|
||||
ARCH_EXT_LIST="
|
||||
neon
|
||||
neon_asm
|
||||
@@ -244,6 +261,10 @@ ARCH_EXT_LIST="
|
||||
mips64
|
||||
|
||||
${ARCH_EXT_LIST_X86}
|
||||
|
||||
vsx
|
||||
|
||||
${ARCH_EXT_LIST_LOONGSON}
|
||||
"
|
||||
HAVE_LIST="
|
||||
${ARCH_EXT_LIST}
|
||||
@@ -255,7 +276,6 @@ EXPERIMENT_LIST="
|
||||
spatial_svc
|
||||
fp_mb_stats
|
||||
emulate_hardware
|
||||
misc_fixes
|
||||
"
|
||||
CONFIG_LIST="
|
||||
dependency_tracking
|
||||
@@ -310,6 +330,7 @@ CONFIG_LIST="
|
||||
better_hw_compatibility
|
||||
experimental
|
||||
size_limit
|
||||
always_adjust_bpm
|
||||
${EXPERIMENT_LIST}
|
||||
"
|
||||
CMDLINE_SELECT="
|
||||
@@ -369,6 +390,7 @@ CMDLINE_SELECT="
|
||||
better_hw_compatibility
|
||||
vp9_highbitdepth
|
||||
experimental
|
||||
always_adjust_bpm
|
||||
"
|
||||
|
||||
process_cmdline() {
|
||||
@@ -570,6 +592,7 @@ process_toolchain() {
|
||||
check_add_cflags -Wdeclaration-after-statement
|
||||
check_add_cflags -Wdisabled-optimization
|
||||
check_add_cflags -Wfloat-conversion
|
||||
check_add_cflags -Wparentheses-equality
|
||||
check_add_cflags -Wpointer-arith
|
||||
check_add_cflags -Wtype-limits
|
||||
check_add_cflags -Wcast-qual
|
||||
@@ -588,11 +611,9 @@ process_toolchain() {
|
||||
if enabled mips || [ -z "${INLINE}" ]; then
|
||||
enabled extra_warnings || check_add_cflags -Wno-unused-function
|
||||
fi
|
||||
if ! enabled vp9_highbitdepth; then
|
||||
# Avoid this warning for third_party C++ sources. Some reorganization
|
||||
# would be needed to apply this only to test/*.cc.
|
||||
check_cflags -Wshorten-64-to-32 && add_cflags_only -Wshorten-64-to-32
|
||||
fi
|
||||
# Avoid this warning for third_party C++ sources. Some reorganization
|
||||
# would be needed to apply this only to test/*.cc.
|
||||
check_cflags -Wshorten-64-to-32 && add_cflags_only -Wshorten-64-to-32
|
||||
fi
|
||||
|
||||
if enabled icc; then
|
||||
|
||||
@@ -151,7 +151,7 @@ static void write_ivf_frame_header(FILE *outfile,
|
||||
if (pkt->kind != VPX_CODEC_CX_FRAME_PKT) return;
|
||||
|
||||
pts = pkt->data.frame.pts;
|
||||
mem_put_le32(header, pkt->data.frame.sz);
|
||||
mem_put_le32(header, (int)pkt->data.frame.sz);
|
||||
mem_put_le32(header + 4, pts & 0xFFFFFFFF);
|
||||
mem_put_le32(header + 8, pts >> 32);
|
||||
|
||||
@@ -190,7 +190,7 @@ static void set_temporal_layer_pattern(int num_temporal_layers,
|
||||
cfg->ts_layer_id[0] = 0;
|
||||
cfg->ts_layer_id[1] = 1;
|
||||
// Use 60/40 bit allocation as example.
|
||||
cfg->ts_target_bitrate[0] = 0.6f * bitrate;
|
||||
cfg->ts_target_bitrate[0] = (int)(0.6f * bitrate);
|
||||
cfg->ts_target_bitrate[1] = bitrate;
|
||||
|
||||
/* 0=L, 1=GF */
|
||||
@@ -241,8 +241,8 @@ static void set_temporal_layer_pattern(int num_temporal_layers,
|
||||
cfg->ts_layer_id[2] = 1;
|
||||
cfg->ts_layer_id[3] = 2;
|
||||
// Use 45/20/35 bit allocation as example.
|
||||
cfg->ts_target_bitrate[0] = 0.45f * bitrate;
|
||||
cfg->ts_target_bitrate[1] = 0.65f * bitrate;
|
||||
cfg->ts_target_bitrate[0] = (int)(0.45f * bitrate);
|
||||
cfg->ts_target_bitrate[1] = (int)(0.65f * bitrate);
|
||||
cfg->ts_target_bitrate[2] = bitrate;
|
||||
|
||||
/* 0=L, 1=GF, 2=ARF */
|
||||
@@ -294,8 +294,8 @@ int main(int argc, char **argv) {
|
||||
vpx_codec_err_t res[NUM_ENCODERS];
|
||||
|
||||
int i;
|
||||
long width;
|
||||
long height;
|
||||
int width;
|
||||
int height;
|
||||
int length_frame;
|
||||
int frame_avail;
|
||||
int got_data;
|
||||
@@ -347,9 +347,9 @@ int main(int argc, char **argv) {
|
||||
|
||||
printf("Using %s\n", vpx_codec_iface_name(interface));
|
||||
|
||||
width = strtol(argv[1], NULL, 0);
|
||||
height = strtol(argv[2], NULL, 0);
|
||||
framerate = strtol(argv[3], NULL, 0);
|
||||
width = (int)strtol(argv[1], NULL, 0);
|
||||
height = (int)strtol(argv[2], NULL, 0);
|
||||
framerate = (int)strtol(argv[3], NULL, 0);
|
||||
|
||||
if (width < 16 || width % 2 || height < 16 || height % 2)
|
||||
die("Invalid resolution: %ldx%ld", width, height);
|
||||
@@ -371,12 +371,13 @@ int main(int argc, char **argv) {
|
||||
|
||||
// Bitrates per spatial layer: overwrite default rates above.
|
||||
for (i = 0; i < NUM_ENCODERS; i++) {
|
||||
target_bitrate[i] = strtol(argv[NUM_ENCODERS + 5 + i], NULL, 0);
|
||||
target_bitrate[i] = (int)strtol(argv[NUM_ENCODERS + 5 + i], NULL, 0);
|
||||
}
|
||||
|
||||
// Temporal layers per spatial layers: overwrite default settings above.
|
||||
for (i = 0; i < NUM_ENCODERS; i++) {
|
||||
num_temporal_layers[i] = strtol(argv[2 * NUM_ENCODERS + 5 + i], NULL, 0);
|
||||
num_temporal_layers[i] =
|
||||
(int)strtol(argv[2 * NUM_ENCODERS + 5 + i], NULL, 0);
|
||||
if (num_temporal_layers[i] < 1 || num_temporal_layers[i] > 3)
|
||||
die("Invalid temporal layers: %d, Must be 1, 2, or 3. \n",
|
||||
num_temporal_layers);
|
||||
@@ -391,9 +392,9 @@ int main(int argc, char **argv) {
|
||||
downsampled_input[i] = fopen(filename, "wb");
|
||||
}
|
||||
|
||||
key_frame_insert = strtol(argv[3 * NUM_ENCODERS + 5], NULL, 0);
|
||||
key_frame_insert = (int)strtol(argv[3 * NUM_ENCODERS + 5], NULL, 0);
|
||||
|
||||
show_psnr = strtol(argv[3 * NUM_ENCODERS + 6], NULL, 0);
|
||||
show_psnr = (int)strtol(argv[3 * NUM_ENCODERS + 6], NULL, 0);
|
||||
|
||||
/* Populate default encoder configuration */
|
||||
for (i = 0; i < NUM_ENCODERS; i++) {
|
||||
@@ -469,7 +470,7 @@ int main(int argc, char **argv) {
|
||||
if (!vpx_img_alloc(&raw[i], VPX_IMG_FMT_I420, cfg[i].g_w, cfg[i].g_h, 32))
|
||||
die("Failed to allocate image", cfg[i].g_w, cfg[i].g_h);
|
||||
|
||||
if (raw[0].stride[VPX_PLANE_Y] == raw[0].d_w)
|
||||
if (raw[0].stride[VPX_PLANE_Y] == (int)raw[0].d_w)
|
||||
read_frame_p = read_frame;
|
||||
else
|
||||
read_frame_p = read_frame_by_row;
|
||||
@@ -558,7 +559,8 @@ int main(int argc, char **argv) {
|
||||
/* Write out down-sampled input. */
|
||||
length_frame = cfg[i].g_w * cfg[i].g_h * 3 / 2;
|
||||
if (fwrite(raw[i].planes[0], 1, length_frame,
|
||||
downsampled_input[NUM_ENCODERS - i - 1]) != length_frame) {
|
||||
downsampled_input[NUM_ENCODERS - i - 1]) !=
|
||||
(unsigned int)length_frame) {
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
}
|
||||
@@ -619,10 +621,6 @@ int main(int argc, char **argv) {
|
||||
break;
|
||||
default: break;
|
||||
}
|
||||
printf(pkt[i]->kind == VPX_CODEC_CX_FRAME_PKT &&
|
||||
(pkt[i]->data.frame.flags & VPX_FRAME_IS_KEY)
|
||||
? "K"
|
||||
: "");
|
||||
fflush(stdout);
|
||||
}
|
||||
}
|
||||
@@ -663,7 +661,6 @@ int main(int argc, char **argv) {
|
||||
write_ivf_file_header(outfile[i], &cfg[i], frame_cnt - 1);
|
||||
fclose(outfile[i]);
|
||||
}
|
||||
printf("\n");
|
||||
|
||||
return EXIT_SUCCESS;
|
||||
}
|
||||
|
||||
@@ -168,7 +168,7 @@ void usage_exit(void) {
|
||||
static void parse_command_line(int argc, const char **argv_,
|
||||
AppInput *app_input, SvcContext *svc_ctx,
|
||||
vpx_codec_enc_cfg_t *enc_cfg) {
|
||||
struct arg arg = { 0 };
|
||||
struct arg arg;
|
||||
char **argv = NULL;
|
||||
char **argi = NULL;
|
||||
char **argj = NULL;
|
||||
@@ -509,7 +509,7 @@ static void printout_rate_control_summary(struct RateControlStats *rc,
|
||||
}
|
||||
|
||||
vpx_codec_err_t parse_superframe_index(const uint8_t *data, size_t data_sz,
|
||||
uint32_t sizes[8], int *count) {
|
||||
uint64_t sizes[8], int *count) {
|
||||
// A chunk ending with a byte matching 0xc0 is an invalid chunk unless
|
||||
// it is a super frame index. If the last byte of real video compression
|
||||
// data is 0xc0 the encoder must add a 0 byte. If we have the marker but
|
||||
@@ -606,9 +606,9 @@ void set_frame_flags_bypass_mode(int sl, int tl, int num_spatial_layers,
|
||||
}
|
||||
|
||||
int main(int argc, const char **argv) {
|
||||
AppInput app_input = { 0 };
|
||||
AppInput app_input;
|
||||
VpxVideoWriter *writer = NULL;
|
||||
VpxVideoInfo info = { 0 };
|
||||
VpxVideoInfo info;
|
||||
vpx_codec_ctx_t codec;
|
||||
vpx_codec_enc_cfg_t enc_cfg;
|
||||
SvcContext svc_ctx;
|
||||
@@ -640,8 +640,9 @@ int main(int argc, const char **argv) {
|
||||
|
||||
// Allocate image buffer
|
||||
#if CONFIG_VP9_HIGHBITDEPTH
|
||||
if (!vpx_img_alloc(&raw, enc_cfg.g_input_bit_depth == 8 ? VPX_IMG_FMT_I420
|
||||
: VPX_IMG_FMT_I42016,
|
||||
if (!vpx_img_alloc(&raw,
|
||||
enc_cfg.g_input_bit_depth == 8 ? VPX_IMG_FMT_I420
|
||||
: VPX_IMG_FMT_I42016,
|
||||
enc_cfg.g_w, enc_cfg.g_h, 32)) {
|
||||
die("Failed to allocate image %dx%d\n", enc_cfg.g_w, enc_cfg.g_h);
|
||||
}
|
||||
@@ -697,12 +698,18 @@ int main(int argc, const char **argv) {
|
||||
|
||||
if (svc_ctx.speed != -1)
|
||||
vpx_codec_control(&codec, VP8E_SET_CPUUSED, svc_ctx.speed);
|
||||
if (svc_ctx.threads)
|
||||
if (svc_ctx.threads) {
|
||||
vpx_codec_control(&codec, VP9E_SET_TILE_COLUMNS, (svc_ctx.threads >> 1));
|
||||
if (svc_ctx.threads > 1)
|
||||
vpx_codec_control(&codec, VP9E_SET_ROW_MT, 1);
|
||||
else
|
||||
vpx_codec_control(&codec, VP9E_SET_ROW_MT, 0);
|
||||
}
|
||||
if (svc_ctx.speed >= 5 && svc_ctx.aqmode == 1)
|
||||
vpx_codec_control(&codec, VP9E_SET_AQ_MODE, 3);
|
||||
if (svc_ctx.speed >= 5)
|
||||
vpx_codec_control(&codec, VP8E_SET_STATIC_THRESHOLD, 1);
|
||||
vpx_codec_control(&codec, VP8E_SET_MAX_INTRA_BITRATE_PCT, 900);
|
||||
|
||||
// Encode frames
|
||||
while (!end_of_stream) {
|
||||
@@ -763,7 +770,7 @@ int main(int argc, const char **argv) {
|
||||
SvcInternal_t *const si = (SvcInternal_t *)svc_ctx.internal;
|
||||
if (cx_pkt->data.frame.sz > 0) {
|
||||
#if OUTPUT_RC_STATS
|
||||
uint32_t sizes[8];
|
||||
uint64_t sizes[8];
|
||||
int count = 0;
|
||||
#endif
|
||||
vpx_video_writer_write_frame(writer, cx_pkt->data.frame.buf,
|
||||
@@ -775,6 +782,8 @@ int main(int argc, const char **argv) {
|
||||
vpx_codec_control(&codec, VP9E_GET_SVC_LAYER_ID, &layer_id);
|
||||
parse_superframe_index(cx_pkt->data.frame.buf,
|
||||
cx_pkt->data.frame.sz, sizes, &count);
|
||||
if (enc_cfg.ss_number_layers == 1)
|
||||
sizes[0] = cx_pkt->data.frame.sz;
|
||||
// Note computing input_layer_frames here won't account for frame
|
||||
// drops in rate control stats.
|
||||
// TODO(marpan): Fix this for non-bypass mode so we can get stats
|
||||
|
||||
@@ -26,6 +26,8 @@
|
||||
#include "../tools_common.h"
|
||||
#include "../video_writer.h"
|
||||
|
||||
#define VP8_ROI_MAP 0
|
||||
|
||||
static const char *exec_name;
|
||||
|
||||
void usage_exit(void) { exit(EXIT_FAILURE); }
|
||||
@@ -154,6 +156,53 @@ static void printout_rate_control_summary(struct RateControlMetrics *rc,
|
||||
die("Error: Number of input frames not equal to output! \n");
|
||||
}
|
||||
|
||||
#if VP8_ROI_MAP
|
||||
static void vp8_set_roi_map(vpx_codec_enc_cfg_t *cfg, vpx_roi_map_t *roi) {
|
||||
unsigned int i, j;
|
||||
memset(roi, 0, sizeof(*roi));
|
||||
|
||||
// ROI is based on the segments (4 for vp8, 8 for vp9), smallest unit for
|
||||
// segment is 16x16 for vp8, 8x8 for vp9.
|
||||
roi->rows = (cfg->g_h + 15) / 16;
|
||||
roi->cols = (cfg->g_w + 15) / 16;
|
||||
|
||||
// Applies delta QP on the segment blocks, varies from -63 to 63.
|
||||
// Setting to negative means lower QP (better quality).
|
||||
// Below we set delta_q to the extreme (-63) to show strong effect.
|
||||
roi->delta_q[0] = 0;
|
||||
roi->delta_q[1] = -63;
|
||||
roi->delta_q[2] = 0;
|
||||
roi->delta_q[3] = 0;
|
||||
|
||||
// Applies delta loopfilter strength on the segment blocks, varies from -63 to
|
||||
// 63. Setting to positive means stronger loopfilter.
|
||||
roi->delta_lf[0] = 0;
|
||||
roi->delta_lf[1] = 0;
|
||||
roi->delta_lf[2] = 0;
|
||||
roi->delta_lf[3] = 0;
|
||||
|
||||
// Applies skip encoding threshold on the segment blocks, varies from 0 to
|
||||
// UINT_MAX. Larger value means more skipping of encoding is possible.
|
||||
// This skip threshold only applies on delta frames.
|
||||
roi->static_threshold[0] = 0;
|
||||
roi->static_threshold[1] = 0;
|
||||
roi->static_threshold[2] = 0;
|
||||
roi->static_threshold[3] = 0;
|
||||
|
||||
// Use 2 states: 1 is center square, 0 is the rest.
|
||||
roi->roi_map =
|
||||
(uint8_t *)calloc(roi->rows * roi->cols, sizeof(*roi->roi_map));
|
||||
for (i = 0; i < roi->rows; ++i) {
|
||||
for (j = 0; j < roi->cols; ++j) {
|
||||
if (i > (roi->rows >> 2) && i < ((roi->rows * 3) >> 2) &&
|
||||
j > (roi->cols >> 2) && j < ((roi->cols * 3) >> 2)) {
|
||||
roi->roi_map[i * roi->cols + j] = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
// Temporal scaling parameters:
|
||||
// NOTE: The 3 prediction frames cannot be used interchangeably due to
|
||||
// differences in the way they are handled throughout the code. The
|
||||
@@ -495,6 +544,7 @@ int main(int argc, char **argv) {
|
||||
vpx_codec_err_t res;
|
||||
unsigned int width;
|
||||
unsigned int height;
|
||||
uint32_t error_resilient = 0;
|
||||
int speed;
|
||||
int frame_avail;
|
||||
int got_data;
|
||||
@@ -505,16 +555,15 @@ int main(int argc, char **argv) {
|
||||
int layering_mode = 0;
|
||||
int layer_flags[VPX_TS_MAX_PERIODICITY] = { 0 };
|
||||
int flag_periodicity = 1;
|
||||
#if VPX_ENCODER_ABI_VERSION > (4 + VPX_CODEC_ABI_VERSION)
|
||||
vpx_svc_layer_id_t layer_id = { 0, 0 };
|
||||
#else
|
||||
vpx_svc_layer_id_t layer_id = { 0 };
|
||||
#if VP8_ROI_MAP
|
||||
vpx_roi_map_t roi;
|
||||
#endif
|
||||
vpx_svc_layer_id_t layer_id = { 0, 0 };
|
||||
const VpxInterface *encoder = NULL;
|
||||
FILE *infile = NULL;
|
||||
struct RateControlMetrics rc;
|
||||
int64_t cx_time = 0;
|
||||
const int min_args_base = 12;
|
||||
const int min_args_base = 13;
|
||||
#if CONFIG_VP9_HIGHBITDEPTH
|
||||
vpx_bit_depth_t bit_depth = VPX_BITS_8;
|
||||
int input_bit_depth = 8;
|
||||
@@ -531,12 +580,14 @@ int main(int argc, char **argv) {
|
||||
if (argc < min_args) {
|
||||
#if CONFIG_VP9_HIGHBITDEPTH
|
||||
die("Usage: %s <infile> <outfile> <codec_type(vp8/vp9)> <width> <height> "
|
||||
"<rate_num> <rate_den> <speed> <frame_drop_threshold> <threads> <mode> "
|
||||
"<rate_num> <rate_den> <speed> <frame_drop_threshold> "
|
||||
"<error_resilient> <threads> <mode> "
|
||||
"<Rate_0> ... <Rate_nlayers-1> <bit-depth> \n",
|
||||
argv[0]);
|
||||
#else
|
||||
die("Usage: %s <infile> <outfile> <codec_type(vp8/vp9)> <width> <height> "
|
||||
"<rate_num> <rate_den> <speed> <frame_drop_threshold> <threads> <mode> "
|
||||
"<rate_num> <rate_den> <speed> <frame_drop_threshold> "
|
||||
"<error_resilient> <threads> <mode> "
|
||||
"<Rate_0> ... <Rate_nlayers-1> \n",
|
||||
argv[0]);
|
||||
#endif // CONFIG_VP9_HIGHBITDEPTH
|
||||
@@ -553,9 +604,9 @@ int main(int argc, char **argv) {
|
||||
die("Invalid resolution: %d x %d", width, height);
|
||||
}
|
||||
|
||||
layering_mode = (int)strtol(argv[11], NULL, 0);
|
||||
layering_mode = (int)strtol(argv[12], NULL, 0);
|
||||
if (layering_mode < 0 || layering_mode > 13) {
|
||||
die("Invalid layering mode (0..12) %s", argv[11]);
|
||||
die("Invalid layering mode (0..12) %s", argv[12]);
|
||||
}
|
||||
|
||||
if (argc != min_args + mode_to_num_layers[layering_mode]) {
|
||||
@@ -619,11 +670,11 @@ int main(int argc, char **argv) {
|
||||
|
||||
for (i = min_args_base;
|
||||
(int)i < min_args_base + mode_to_num_layers[layering_mode]; ++i) {
|
||||
rc.layer_target_bitrate[i - 12] = (int)strtol(argv[i], NULL, 0);
|
||||
rc.layer_target_bitrate[i - 13] = (int)strtol(argv[i], NULL, 0);
|
||||
if (strncmp(encoder->name, "vp8", 3) == 0)
|
||||
cfg.ts_target_bitrate[i - 12] = rc.layer_target_bitrate[i - 12];
|
||||
cfg.ts_target_bitrate[i - 13] = rc.layer_target_bitrate[i - 13];
|
||||
else if (strncmp(encoder->name, "vp9", 3) == 0)
|
||||
cfg.layer_target_bitrate[i - 12] = rc.layer_target_bitrate[i - 12];
|
||||
cfg.layer_target_bitrate[i - 13] = rc.layer_target_bitrate[i - 13];
|
||||
}
|
||||
|
||||
// Real time parameters.
|
||||
@@ -634,7 +685,7 @@ int main(int argc, char **argv) {
|
||||
if (strncmp(encoder->name, "vp9", 3) == 0) cfg.rc_max_quantizer = 52;
|
||||
cfg.rc_undershoot_pct = 50;
|
||||
cfg.rc_overshoot_pct = 50;
|
||||
cfg.rc_buf_initial_sz = 500;
|
||||
cfg.rc_buf_initial_sz = 600;
|
||||
cfg.rc_buf_optimal_sz = 600;
|
||||
cfg.rc_buf_sz = 1000;
|
||||
|
||||
@@ -642,10 +693,14 @@ int main(int argc, char **argv) {
|
||||
cfg.rc_resize_allowed = 0;
|
||||
|
||||
// Use 1 thread as default.
|
||||
cfg.g_threads = (unsigned int)strtoul(argv[10], NULL, 0);
|
||||
cfg.g_threads = (unsigned int)strtoul(argv[11], NULL, 0);
|
||||
|
||||
error_resilient = (uint32_t)strtoul(argv[10], NULL, 0);
|
||||
if (error_resilient != 0 && error_resilient != 1) {
|
||||
die("Invalid value for error resilient (0, 1): %d.", error_resilient);
|
||||
}
|
||||
// Enable error resilient mode.
|
||||
cfg.g_error_resilient = 1;
|
||||
cfg.g_error_resilient = error_resilient;
|
||||
cfg.g_lag_in_frames = 0;
|
||||
cfg.kf_mode = VPX_KF_AUTO;
|
||||
|
||||
@@ -703,6 +758,12 @@ int main(int argc, char **argv) {
|
||||
vpx_codec_control(&codec, VP8E_SET_NOISE_SENSITIVITY, kDenoiserOff);
|
||||
vpx_codec_control(&codec, VP8E_SET_STATIC_THRESHOLD, 1);
|
||||
vpx_codec_control(&codec, VP8E_SET_GF_CBR_BOOST_PCT, 0);
|
||||
#if VP8_ROI_MAP
|
||||
vp8_set_roi_map(&cfg, &roi);
|
||||
if (vpx_codec_control(&codec, VP8E_SET_ROI_MAP, &roi))
|
||||
die_codec(&codec, "Failed to set ROI map");
|
||||
#endif
|
||||
|
||||
} else if (strncmp(encoder->name, "vp9", 3) == 0) {
|
||||
vpx_svc_extra_cfg_t svc_params;
|
||||
memset(&svc_params, 0, sizeof(svc_params));
|
||||
@@ -715,6 +776,12 @@ int main(int argc, char **argv) {
|
||||
vpx_codec_control(&codec, VP8E_SET_STATIC_THRESHOLD, 1);
|
||||
vpx_codec_control(&codec, VP9E_SET_TUNE_CONTENT, 0);
|
||||
vpx_codec_control(&codec, VP9E_SET_TILE_COLUMNS, (cfg.g_threads >> 1));
|
||||
// TODO(marpan/jianj): There is an issue with row-mt for low resolutons at
|
||||
// high speed settings, disable its use for those cases for now.
|
||||
if (cfg.g_threads > 1 && ((cfg.g_w > 320 && cfg.g_h > 240) || speed < 7))
|
||||
vpx_codec_control(&codec, VP9E_SET_ROW_MT, 1);
|
||||
else
|
||||
vpx_codec_control(&codec, VP9E_SET_ROW_MT, 0);
|
||||
if (vpx_codec_control(&codec, VP9E_SET_SVC, layering_mode > 0 ? 1 : 0))
|
||||
die_codec(&codec, "Failed to set SVC");
|
||||
for (i = 0; i < cfg.ts_number_layers; ++i) {
|
||||
@@ -733,7 +800,7 @@ int main(int argc, char **argv) {
|
||||
// For generating smaller key frames, use a smaller max_intra_size_pct
|
||||
// value, like 100 or 200.
|
||||
{
|
||||
const int max_intra_size_pct = 900;
|
||||
const int max_intra_size_pct = 1000;
|
||||
vpx_codec_control(&codec, VP8E_SET_MAX_INTRA_BITRATE_PCT,
|
||||
max_intra_size_pct);
|
||||
}
|
||||
@@ -743,10 +810,8 @@ int main(int argc, char **argv) {
|
||||
struct vpx_usec_timer timer;
|
||||
vpx_codec_iter_t iter = NULL;
|
||||
const vpx_codec_cx_pkt_t *pkt;
|
||||
#if VPX_ENCODER_ABI_VERSION > (4 + VPX_CODEC_ABI_VERSION)
|
||||
// Update the temporal layer_id. No spatial layers in this test.
|
||||
layer_id.spatial_layer_id = 0;
|
||||
#endif
|
||||
layer_id.temporal_layer_id =
|
||||
cfg.ts_layer_id[frame_cnt % cfg.ts_periodicity];
|
||||
if (strncmp(encoder->name, "vp9", 3) == 0) {
|
||||
|
||||
29
libs.mk
29
libs.mk
@@ -149,6 +149,7 @@ CODEC_SRCS-yes += $(BUILD_PFX)vpx_config.c
|
||||
INSTALL-SRCS-no += $(BUILD_PFX)vpx_config.c
|
||||
ifeq ($(ARCH_X86)$(ARCH_X86_64),yes)
|
||||
INSTALL-SRCS-$(CONFIG_CODEC_SRCS) += third_party/x86inc/x86inc.asm
|
||||
INSTALL-SRCS-$(CONFIG_CODEC_SRCS) += vpx_dsp/x86/bitdepth_conversion_sse2.asm
|
||||
endif
|
||||
CODEC_EXPORTS-yes += vpx/exports_com
|
||||
CODEC_EXPORTS-$(CONFIG_ENCODERS) += vpx/exports_enc
|
||||
@@ -187,6 +188,13 @@ libvpx_srcs.txt:
|
||||
@echo $(CODEC_SRCS) | xargs -n1 echo | LC_ALL=C sort -u > $@
|
||||
CLEAN-OBJS += libvpx_srcs.txt
|
||||
|
||||
# Assembly files that are included, but don't define symbols themselves.
|
||||
# Filtered out to avoid Windows build warnings.
|
||||
ASM_INCLUDES := \
|
||||
third_party/x86inc/x86inc.asm \
|
||||
vpx_config.asm \
|
||||
vpx_ports/x86_abi_support.asm \
|
||||
vpx_dsp/x86/bitdepth_conversion_sse2.asm \
|
||||
|
||||
ifeq ($(CONFIG_EXTERNAL_BUILD),yes)
|
||||
ifeq ($(CONFIG_MSVS),yes)
|
||||
@@ -198,13 +206,6 @@ vpx.def: $(call enabled,CODEC_EXPORTS)
|
||||
--out=$@ $^
|
||||
CLEAN-OBJS += vpx.def
|
||||
|
||||
# Assembly files that are included, but don't define symbols themselves.
|
||||
# Filtered out to avoid Visual Studio build warnings.
|
||||
ASM_INCLUDES := \
|
||||
third_party/x86inc/x86inc.asm \
|
||||
vpx_config.asm \
|
||||
vpx_ports/x86_abi_support.asm \
|
||||
|
||||
vpx.$(VCPROJ_SFX): $(CODEC_SRCS) vpx.def
|
||||
@echo " [CREATE] $@"
|
||||
$(qexec)$(GEN_VCPROJ) \
|
||||
@@ -227,7 +228,7 @@ vpx.$(VCPROJ_SFX): $(RTCD)
|
||||
|
||||
endif
|
||||
else
|
||||
LIBVPX_OBJS=$(call objs,$(CODEC_SRCS))
|
||||
LIBVPX_OBJS=$(call objs, $(filter-out $(ASM_INCLUDES), $(CODEC_SRCS)))
|
||||
OBJS-yes += $(LIBVPX_OBJS)
|
||||
LIBS-$(if yes,$(CONFIG_STATIC)) += $(BUILD_PFX)libvpx.a $(BUILD_PFX)libvpx_g.a
|
||||
$(BUILD_PFX)libvpx_g.a: $(LIBVPX_OBJS)
|
||||
@@ -404,8 +405,16 @@ CLEAN-OBJS += libvpx_test_srcs.txt
|
||||
|
||||
$(LIBVPX_TEST_DATA): $(SRC_PATH_BARE)/test/test-data.sha1
|
||||
@echo " [DOWNLOAD] $@"
|
||||
$(qexec)trap 'rm -f $@' INT TERM &&\
|
||||
curl --retry 1 -L -o $@ $(call libvpx_test_data_url,$(@F))
|
||||
# Attempt to download the file using curl, retrying once if it fails for a
|
||||
# partial file (18).
|
||||
$(qexec)( \
|
||||
trap 'rm -f $@' INT TERM; \
|
||||
curl="curl --retry 1 -L -o $@ $(call libvpx_test_data_url,$(@F))"; \
|
||||
$$curl; \
|
||||
case "$$?" in \
|
||||
18) $$curl -C -;; \
|
||||
esac \
|
||||
)
|
||||
|
||||
testdata:: $(LIBVPX_TEST_DATA)
|
||||
$(qexec)[ -x "$$(which sha1sum)" ] && sha1sum=sha1sum;\
|
||||
|
||||
25
rate_hist.c
25
rate_hist.c
@@ -37,7 +37,13 @@ struct rate_hist {
|
||||
struct rate_hist *init_rate_histogram(const vpx_codec_enc_cfg_t *cfg,
|
||||
const vpx_rational_t *fps) {
|
||||
int i;
|
||||
struct rate_hist *hist = malloc(sizeof(*hist));
|
||||
struct rate_hist *hist = calloc(1, sizeof(*hist));
|
||||
|
||||
if (hist == NULL || cfg == NULL || fps == NULL || fps->num == 0 ||
|
||||
fps->den == 0) {
|
||||
destroy_rate_histogram(hist);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// Determine the number of samples in the buffer. Use the file's framerate
|
||||
// to determine the number of frames in rc_buf_sz milliseconds, with an
|
||||
@@ -80,7 +86,11 @@ void update_rate_histogram(struct rate_hist *hist,
|
||||
(uint64_t)cfg->g_timebase.num /
|
||||
(uint64_t)cfg->g_timebase.den;
|
||||
|
||||
int idx = hist->frames++ % hist->samples;
|
||||
int idx;
|
||||
|
||||
if (hist == NULL || cfg == NULL || pkt == NULL) return;
|
||||
|
||||
idx = hist->frames++ % hist->samples;
|
||||
hist->pts[idx] = now;
|
||||
hist->sz[idx] = (int)pkt->data.frame.sz;
|
||||
|
||||
@@ -116,9 +126,14 @@ void update_rate_histogram(struct rate_hist *hist,
|
||||
static int merge_hist_buckets(struct hist_bucket *bucket, int max_buckets,
|
||||
int *num_buckets) {
|
||||
int small_bucket = 0, merge_bucket = INT_MAX, big_bucket = 0;
|
||||
int buckets = *num_buckets;
|
||||
int buckets;
|
||||
int i;
|
||||
|
||||
assert(bucket != NULL);
|
||||
assert(num_buckets != NULL);
|
||||
|
||||
buckets = *num_buckets;
|
||||
|
||||
/* Find the extrema for this list of buckets */
|
||||
big_bucket = small_bucket = 0;
|
||||
for (i = 0; i < buckets; i++) {
|
||||
@@ -181,6 +196,8 @@ static void show_histogram(const struct hist_bucket *bucket, int buckets,
|
||||
const char *pat1, *pat2;
|
||||
int i;
|
||||
|
||||
assert(bucket != NULL);
|
||||
|
||||
switch ((int)(log(bucket[buckets - 1].high) / log(10)) + 1) {
|
||||
case 1:
|
||||
case 2:
|
||||
@@ -259,6 +276,8 @@ void show_rate_histogram(struct rate_hist *hist, const vpx_codec_enc_cfg_t *cfg,
|
||||
int i, scale;
|
||||
int buckets = 0;
|
||||
|
||||
if (hist == NULL || cfg == NULL) return;
|
||||
|
||||
for (i = 0; i < RATE_BINS; i++) {
|
||||
if (hist->bucket[i].low == INT_MAX) continue;
|
||||
hist->bucket[buckets++] = hist->bucket[i];
|
||||
|
||||
@@ -11,6 +11,10 @@
|
||||
#ifndef TEST_ACM_RANDOM_H_
|
||||
#define TEST_ACM_RANDOM_H_
|
||||
|
||||
#include <assert.h>
|
||||
|
||||
#include <limits>
|
||||
|
||||
#include "third_party/googletest/src/include/gtest/gtest.h"
|
||||
|
||||
#include "vpx/vpx_integer.h"
|
||||
@@ -50,6 +54,13 @@ class ACMRandom {
|
||||
return r < 128 ? r << 4 : r >> 4;
|
||||
}
|
||||
|
||||
uint32_t RandRange(const uint32_t range) {
|
||||
// testing::internal::Random::Generate provides values in the range
|
||||
// testing::internal::Random::kMaxRange.
|
||||
assert(range <= testing::internal::Random::kMaxRange);
|
||||
return random_.Generate(range);
|
||||
}
|
||||
|
||||
int PseudoUniform(int range) { return random_.Generate(range); }
|
||||
|
||||
int operator()(int n) { return PseudoUniform(n); }
|
||||
|
||||
@@ -32,6 +32,7 @@ LOCAL_CPP_EXTENSION := .cc
|
||||
LOCAL_MODULE := gtest
|
||||
LOCAL_C_INCLUDES := $(LOCAL_PATH)/third_party/googletest/src/
|
||||
LOCAL_C_INCLUDES += $(LOCAL_PATH)/third_party/googletest/src/include/
|
||||
LOCAL_EXPORT_C_INCLUDES := $(LOCAL_PATH)/third_party/googletest/src/include/
|
||||
LOCAL_SRC_FILES := ./third_party/googletest/src/src/gtest-all.cc
|
||||
include $(BUILD_STATIC_LIBRARY)
|
||||
|
||||
|
||||
198
test/avg_test.cc
198
test/avg_test.cc
@@ -14,6 +14,7 @@
|
||||
|
||||
#include "third_party/googletest/src/include/gtest/gtest.h"
|
||||
|
||||
#include "./vp9_rtcd.h"
|
||||
#include "./vpx_config.h"
|
||||
#include "./vpx_dsp_rtcd.h"
|
||||
|
||||
@@ -22,6 +23,7 @@
|
||||
#include "test/register_state_check.h"
|
||||
#include "test/util.h"
|
||||
#include "vpx_mem/vpx_mem.h"
|
||||
#include "vpx_ports/vpx_timer.h"
|
||||
|
||||
using libvpx_test::ACMRandom;
|
||||
|
||||
@@ -186,7 +188,7 @@ class IntProColTest : public AverageTestBase,
|
||||
int16_t sum_c_;
|
||||
};
|
||||
|
||||
typedef int (*SatdFunc)(const int16_t *coeffs, int length);
|
||||
typedef int (*SatdFunc)(const tran_low_t *coeffs, int length);
|
||||
typedef std::tr1::tuple<int, SatdFunc> SatdTestParam;
|
||||
|
||||
class SatdTest : public ::testing::Test,
|
||||
@@ -196,7 +198,7 @@ class SatdTest : public ::testing::Test,
|
||||
satd_size_ = GET_PARAM(0);
|
||||
satd_func_ = GET_PARAM(1);
|
||||
rnd_.Reset(ACMRandom::DeterministicSeed());
|
||||
src_ = reinterpret_cast<int16_t *>(
|
||||
src_ = reinterpret_cast<tran_low_t *>(
|
||||
vpx_memalign(16, sizeof(*src_) * satd_size_));
|
||||
ASSERT_TRUE(src_ != NULL);
|
||||
}
|
||||
@@ -206,12 +208,15 @@ class SatdTest : public ::testing::Test,
|
||||
vpx_free(src_);
|
||||
}
|
||||
|
||||
void FillConstant(const int16_t val) {
|
||||
void FillConstant(const tran_low_t val) {
|
||||
for (int i = 0; i < satd_size_; ++i) src_[i] = val;
|
||||
}
|
||||
|
||||
void FillRandom() {
|
||||
for (int i = 0; i < satd_size_; ++i) src_[i] = rnd_.Rand16();
|
||||
for (int i = 0; i < satd_size_; ++i) {
|
||||
const int16_t tmp = rnd_.Rand16();
|
||||
src_[i] = (tran_low_t)tmp;
|
||||
}
|
||||
}
|
||||
|
||||
void Check(const int expected) {
|
||||
@@ -223,11 +228,66 @@ class SatdTest : public ::testing::Test,
|
||||
int satd_size_;
|
||||
|
||||
private:
|
||||
int16_t *src_;
|
||||
tran_low_t *src_;
|
||||
SatdFunc satd_func_;
|
||||
ACMRandom rnd_;
|
||||
};
|
||||
|
||||
typedef int64_t (*BlockErrorFunc)(const tran_low_t *coeff,
|
||||
const tran_low_t *dqcoeff, int block_size);
|
||||
typedef std::tr1::tuple<int, BlockErrorFunc> BlockErrorTestFPParam;
|
||||
|
||||
class BlockErrorTestFP
|
||||
: public ::testing::Test,
|
||||
public ::testing::WithParamInterface<BlockErrorTestFPParam> {
|
||||
protected:
|
||||
virtual void SetUp() {
|
||||
txfm_size_ = GET_PARAM(0);
|
||||
block_error_func_ = GET_PARAM(1);
|
||||
rnd_.Reset(ACMRandom::DeterministicSeed());
|
||||
coeff_ = reinterpret_cast<tran_low_t *>(
|
||||
vpx_memalign(16, sizeof(*coeff_) * txfm_size_));
|
||||
dqcoeff_ = reinterpret_cast<tran_low_t *>(
|
||||
vpx_memalign(16, sizeof(*dqcoeff_) * txfm_size_));
|
||||
ASSERT_TRUE(coeff_ != NULL);
|
||||
ASSERT_TRUE(dqcoeff_ != NULL);
|
||||
}
|
||||
|
||||
virtual void TearDown() {
|
||||
libvpx_test::ClearSystemState();
|
||||
vpx_free(coeff_);
|
||||
vpx_free(dqcoeff_);
|
||||
}
|
||||
|
||||
void FillConstant(const tran_low_t coeff_val, const tran_low_t dqcoeff_val) {
|
||||
for (int i = 0; i < txfm_size_; ++i) coeff_[i] = coeff_val;
|
||||
for (int i = 0; i < txfm_size_; ++i) dqcoeff_[i] = dqcoeff_val;
|
||||
}
|
||||
|
||||
void FillRandom() {
|
||||
// Just two fixed seeds
|
||||
rnd_.Reset(0xb0b9);
|
||||
for (int i = 0; i < txfm_size_; ++i) coeff_[i] = rnd_.Rand16() >> 1;
|
||||
rnd_.Reset(0xb0c8);
|
||||
for (int i = 0; i < txfm_size_; ++i) dqcoeff_[i] = rnd_.Rand16() >> 1;
|
||||
}
|
||||
|
||||
void Check(const int64_t expected) {
|
||||
int64_t total;
|
||||
ASM_REGISTER_STATE_CHECK(
|
||||
total = block_error_func_(coeff_, dqcoeff_, txfm_size_));
|
||||
EXPECT_EQ(expected, total);
|
||||
}
|
||||
|
||||
int txfm_size_;
|
||||
|
||||
private:
|
||||
tran_low_t *coeff_;
|
||||
tran_low_t *dqcoeff_;
|
||||
BlockErrorFunc block_error_func_;
|
||||
ACMRandom rnd_;
|
||||
};
|
||||
|
||||
uint8_t *AverageTestBase::source_data_ = NULL;
|
||||
|
||||
TEST_P(AverageTest, MinValue) {
|
||||
@@ -308,6 +368,66 @@ TEST_P(SatdTest, Random) {
|
||||
Check(expected);
|
||||
}
|
||||
|
||||
TEST_P(SatdTest, DISABLED_Speed) {
|
||||
const int kCountSpeedTestBlock = 20000;
|
||||
vpx_usec_timer timer;
|
||||
DECLARE_ALIGNED(16, tran_low_t, coeff[1024]);
|
||||
const int blocksize = GET_PARAM(0);
|
||||
|
||||
vpx_usec_timer_start(&timer);
|
||||
for (int i = 0; i < kCountSpeedTestBlock; ++i) {
|
||||
GET_PARAM(1)(coeff, blocksize);
|
||||
}
|
||||
vpx_usec_timer_mark(&timer);
|
||||
const int elapsed_time = static_cast<int>(vpx_usec_timer_elapsed(&timer));
|
||||
printf("blocksize: %4d time: %4d us\n", blocksize, elapsed_time);
|
||||
}
|
||||
|
||||
TEST_P(BlockErrorTestFP, MinValue) {
|
||||
const int64_t kMin = -32640;
|
||||
const int64_t expected = kMin * kMin * txfm_size_;
|
||||
FillConstant(kMin, 0);
|
||||
Check(expected);
|
||||
}
|
||||
|
||||
TEST_P(BlockErrorTestFP, MaxValue) {
|
||||
const int64_t kMax = 32640;
|
||||
const int64_t expected = kMax * kMax * txfm_size_;
|
||||
FillConstant(kMax, 0);
|
||||
Check(expected);
|
||||
}
|
||||
|
||||
TEST_P(BlockErrorTestFP, Random) {
|
||||
int64_t expected;
|
||||
switch (txfm_size_) {
|
||||
case 16: expected = 2051681432; break;
|
||||
case 64: expected = 11075114379; break;
|
||||
case 256: expected = 44386271116; break;
|
||||
case 1024: expected = 184774996089; break;
|
||||
default:
|
||||
FAIL() << "Invalid satd size (" << txfm_size_
|
||||
<< ") valid: 16/64/256/1024";
|
||||
}
|
||||
FillRandom();
|
||||
Check(expected);
|
||||
}
|
||||
|
||||
TEST_P(BlockErrorTestFP, DISABLED_Speed) {
|
||||
const int kCountSpeedTestBlock = 20000;
|
||||
vpx_usec_timer timer;
|
||||
DECLARE_ALIGNED(16, tran_low_t, coeff[1024]);
|
||||
DECLARE_ALIGNED(16, tran_low_t, dqcoeff[1024]);
|
||||
const int blocksize = GET_PARAM(0);
|
||||
|
||||
vpx_usec_timer_start(&timer);
|
||||
for (int i = 0; i < kCountSpeedTestBlock; ++i) {
|
||||
GET_PARAM(1)(coeff, dqcoeff, blocksize);
|
||||
}
|
||||
vpx_usec_timer_mark(&timer);
|
||||
const int elapsed_time = static_cast<int>(vpx_usec_timer_elapsed(&timer));
|
||||
printf("blocksize: %4d time: %4d us\n", blocksize, elapsed_time);
|
||||
}
|
||||
|
||||
using std::tr1::make_tuple;
|
||||
|
||||
INSTANTIATE_TEST_CASE_P(
|
||||
@@ -321,6 +441,13 @@ INSTANTIATE_TEST_CASE_P(C, SatdTest,
|
||||
make_tuple(256, &vpx_satd_c),
|
||||
make_tuple(1024, &vpx_satd_c)));
|
||||
|
||||
INSTANTIATE_TEST_CASE_P(
|
||||
C, BlockErrorTestFP,
|
||||
::testing::Values(make_tuple(16, &vp9_block_error_fp_c),
|
||||
make_tuple(64, &vp9_block_error_fp_c),
|
||||
make_tuple(256, &vp9_block_error_fp_c),
|
||||
make_tuple(1024, &vp9_block_error_fp_c)));
|
||||
|
||||
#if HAVE_SSE2
|
||||
INSTANTIATE_TEST_CASE_P(
|
||||
SSE2, AverageTest,
|
||||
@@ -350,6 +477,28 @@ INSTANTIATE_TEST_CASE_P(SSE2, SatdTest,
|
||||
make_tuple(64, &vpx_satd_sse2),
|
||||
make_tuple(256, &vpx_satd_sse2),
|
||||
make_tuple(1024, &vpx_satd_sse2)));
|
||||
|
||||
INSTANTIATE_TEST_CASE_P(
|
||||
SSE2, BlockErrorTestFP,
|
||||
::testing::Values(make_tuple(16, &vp9_block_error_fp_sse2),
|
||||
make_tuple(64, &vp9_block_error_fp_sse2),
|
||||
make_tuple(256, &vp9_block_error_fp_sse2),
|
||||
make_tuple(1024, &vp9_block_error_fp_sse2)));
|
||||
#endif // HAVE_SSE2
|
||||
|
||||
#if HAVE_AVX2
|
||||
INSTANTIATE_TEST_CASE_P(AVX2, SatdTest,
|
||||
::testing::Values(make_tuple(16, &vpx_satd_avx2),
|
||||
make_tuple(64, &vpx_satd_avx2),
|
||||
make_tuple(256, &vpx_satd_avx2),
|
||||
make_tuple(1024, &vpx_satd_avx2)));
|
||||
|
||||
INSTANTIATE_TEST_CASE_P(
|
||||
AVX2, BlockErrorTestFP,
|
||||
::testing::Values(make_tuple(16, &vp9_block_error_fp_avx2),
|
||||
make_tuple(64, &vp9_block_error_fp_avx2),
|
||||
make_tuple(256, &vp9_block_error_fp_avx2),
|
||||
make_tuple(1024, &vp9_block_error_fp_avx2)));
|
||||
#endif
|
||||
|
||||
#if HAVE_NEON
|
||||
@@ -381,7 +530,18 @@ INSTANTIATE_TEST_CASE_P(NEON, SatdTest,
|
||||
make_tuple(64, &vpx_satd_neon),
|
||||
make_tuple(256, &vpx_satd_neon),
|
||||
make_tuple(1024, &vpx_satd_neon)));
|
||||
#endif
|
||||
|
||||
// TODO(jianj): Remove the highbitdepth flag once the SIMD functions are
|
||||
// in place.
|
||||
#if !CONFIG_VP9_HIGHBITDEPTH
|
||||
INSTANTIATE_TEST_CASE_P(
|
||||
NEON, BlockErrorTestFP,
|
||||
::testing::Values(make_tuple(16, &vp9_block_error_fp_neon),
|
||||
make_tuple(64, &vp9_block_error_fp_neon),
|
||||
make_tuple(256, &vp9_block_error_fp_neon),
|
||||
make_tuple(1024, &vp9_block_error_fp_neon)));
|
||||
#endif // !CONFIG_VP9_HIGHBITDEPTH
|
||||
#endif // HAVE_NEON
|
||||
|
||||
#if HAVE_MSA
|
||||
INSTANTIATE_TEST_CASE_P(
|
||||
@@ -392,6 +552,30 @@ INSTANTIATE_TEST_CASE_P(
|
||||
make_tuple(16, 16, 0, 4, &vpx_avg_4x4_msa),
|
||||
make_tuple(16, 16, 5, 4, &vpx_avg_4x4_msa),
|
||||
make_tuple(32, 32, 15, 4, &vpx_avg_4x4_msa)));
|
||||
#endif
|
||||
|
||||
INSTANTIATE_TEST_CASE_P(
|
||||
MSA, IntProRowTest,
|
||||
::testing::Values(make_tuple(16, &vpx_int_pro_row_msa, &vpx_int_pro_row_c),
|
||||
make_tuple(32, &vpx_int_pro_row_msa, &vpx_int_pro_row_c),
|
||||
make_tuple(64, &vpx_int_pro_row_msa,
|
||||
&vpx_int_pro_row_c)));
|
||||
|
||||
INSTANTIATE_TEST_CASE_P(
|
||||
MSA, IntProColTest,
|
||||
::testing::Values(make_tuple(16, &vpx_int_pro_col_msa, &vpx_int_pro_col_c),
|
||||
make_tuple(32, &vpx_int_pro_col_msa, &vpx_int_pro_col_c),
|
||||
make_tuple(64, &vpx_int_pro_col_msa,
|
||||
&vpx_int_pro_col_c)));
|
||||
|
||||
// TODO(jingning): Remove the highbitdepth flag once the SIMD functions are
|
||||
// in place.
|
||||
#if !CONFIG_VP9_HIGHBITDEPTH
|
||||
INSTANTIATE_TEST_CASE_P(MSA, SatdTest,
|
||||
::testing::Values(make_tuple(16, &vpx_satd_msa),
|
||||
make_tuple(64, &vpx_satd_msa),
|
||||
make_tuple(256, &vpx_satd_msa),
|
||||
make_tuple(1024, &vpx_satd_msa)));
|
||||
#endif // !CONFIG_VP9_HIGHBITDEPTH
|
||||
#endif // HAVE_MSA
|
||||
|
||||
} // namespace
|
||||
|
||||
382
test/buffer.h
Normal file
382
test/buffer.h
Normal file
@@ -0,0 +1,382 @@
|
||||
/*
|
||||
* Copyright (c) 2016 The WebM project authors. All Rights Reserved.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license
|
||||
* that can be found in the LICENSE file in the root of the source
|
||||
* tree. An additional intellectual property rights grant can be found
|
||||
* in the file PATENTS. All contributing project authors may
|
||||
* be found in the AUTHORS file in the root of the source tree.
|
||||
*/
|
||||
|
||||
#ifndef TEST_BUFFER_H_
|
||||
#define TEST_BUFFER_H_
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
#include <limits>
|
||||
|
||||
#include "third_party/googletest/src/include/gtest/gtest.h"
|
||||
|
||||
#include "test/acm_random.h"
|
||||
#include "vpx/vpx_integer.h"
|
||||
#include "vpx_mem/vpx_mem.h"
|
||||
|
||||
namespace libvpx_test {
|
||||
|
||||
template <typename T>
|
||||
class Buffer {
|
||||
public:
|
||||
Buffer(int width, int height, int top_padding, int left_padding,
|
||||
int right_padding, int bottom_padding)
|
||||
: width_(width), height_(height), top_padding_(top_padding),
|
||||
left_padding_(left_padding), right_padding_(right_padding),
|
||||
bottom_padding_(bottom_padding), alignment_(0), padding_value_(0),
|
||||
stride_(0), raw_size_(0), num_elements_(0), raw_buffer_(NULL) {}
|
||||
|
||||
Buffer(int width, int height, int top_padding, int left_padding,
|
||||
int right_padding, int bottom_padding, unsigned int alignment)
|
||||
: width_(width), height_(height), top_padding_(top_padding),
|
||||
left_padding_(left_padding), right_padding_(right_padding),
|
||||
bottom_padding_(bottom_padding), alignment_(alignment),
|
||||
padding_value_(0), stride_(0), raw_size_(0), num_elements_(0),
|
||||
raw_buffer_(NULL) {}
|
||||
|
||||
Buffer(int width, int height, int padding)
|
||||
: width_(width), height_(height), top_padding_(padding),
|
||||
left_padding_(padding), right_padding_(padding),
|
||||
bottom_padding_(padding), alignment_(0), padding_value_(0), stride_(0),
|
||||
raw_size_(0), num_elements_(0), raw_buffer_(NULL) {}
|
||||
|
||||
Buffer(int width, int height, int padding, unsigned int alignment)
|
||||
: width_(width), height_(height), top_padding_(padding),
|
||||
left_padding_(padding), right_padding_(padding),
|
||||
bottom_padding_(padding), alignment_(alignment), padding_value_(0),
|
||||
stride_(0), raw_size_(0), num_elements_(0), raw_buffer_(NULL) {}
|
||||
|
||||
~Buffer() {
|
||||
if (alignment_) {
|
||||
vpx_free(raw_buffer_);
|
||||
} else {
|
||||
delete[] raw_buffer_;
|
||||
}
|
||||
}
|
||||
|
||||
T *TopLeftPixel() const;
|
||||
|
||||
int stride() const { return stride_; }
|
||||
|
||||
// Set the buffer (excluding padding) to 'value'.
|
||||
void Set(const T value);
|
||||
|
||||
// Set the buffer (excluding padding) to the output of ACMRandom function
|
||||
// 'rand_func'.
|
||||
void Set(ACMRandom *rand_class, T (ACMRandom::*rand_func)());
|
||||
|
||||
// Set the buffer (excluding padding) to the output of ACMRandom function
|
||||
// 'RandRange' with range 'low' to 'high' which typically must be within
|
||||
// testing::internal::Random::kMaxRange (1u << 31). However, because we want
|
||||
// to allow negative low (and high) values, it is restricted to INT32_MAX
|
||||
// here.
|
||||
void Set(ACMRandom *rand_class, const T low, const T high);
|
||||
|
||||
// Copy the contents of Buffer 'a' (excluding padding).
|
||||
void CopyFrom(const Buffer<T> &a);
|
||||
|
||||
void DumpBuffer() const;
|
||||
|
||||
// Highlight the differences between two buffers if they are the same size.
|
||||
void PrintDifference(const Buffer<T> &a) const;
|
||||
|
||||
bool HasPadding() const;
|
||||
|
||||
// Sets all the values in the buffer to 'padding_value'.
|
||||
void SetPadding(const T padding_value);
|
||||
|
||||
// Checks if all the values (excluding padding) are equal to 'value' if the
|
||||
// Buffers are the same size.
|
||||
bool CheckValues(const T value) const;
|
||||
|
||||
// Check that padding matches the expected value or there is no padding.
|
||||
bool CheckPadding() const;
|
||||
|
||||
// Compare the non-padding portion of two buffers if they are the same size.
|
||||
bool CheckValues(const Buffer<T> &a) const;
|
||||
|
||||
bool Init() {
|
||||
if (raw_buffer_ != NULL) return false;
|
||||
EXPECT_GT(width_, 0);
|
||||
EXPECT_GT(height_, 0);
|
||||
EXPECT_GE(top_padding_, 0);
|
||||
EXPECT_GE(left_padding_, 0);
|
||||
EXPECT_GE(right_padding_, 0);
|
||||
EXPECT_GE(bottom_padding_, 0);
|
||||
stride_ = left_padding_ + width_ + right_padding_;
|
||||
num_elements_ = stride_ * (top_padding_ + height_ + bottom_padding_);
|
||||
raw_size_ = num_elements_ * sizeof(T);
|
||||
if (alignment_) {
|
||||
EXPECT_GE(alignment_, sizeof(T));
|
||||
// Ensure alignment of the first value will be preserved.
|
||||
EXPECT_EQ((left_padding_ * sizeof(T)) % alignment_, 0u);
|
||||
// Ensure alignment of the subsequent rows will be preserved when there is
|
||||
// a stride.
|
||||
if (stride_ != width_) {
|
||||
EXPECT_EQ((stride_ * sizeof(T)) % alignment_, 0u);
|
||||
}
|
||||
raw_buffer_ = reinterpret_cast<T *>(vpx_memalign(alignment_, raw_size_));
|
||||
} else {
|
||||
raw_buffer_ = new (std::nothrow) T[num_elements_];
|
||||
}
|
||||
EXPECT_TRUE(raw_buffer_ != NULL);
|
||||
SetPadding(std::numeric_limits<T>::max());
|
||||
return !::testing::Test::HasFailure();
|
||||
}
|
||||
|
||||
private:
|
||||
bool BufferSizesMatch(const Buffer<T> &a) const;
|
||||
|
||||
const int width_;
|
||||
const int height_;
|
||||
const int top_padding_;
|
||||
const int left_padding_;
|
||||
const int right_padding_;
|
||||
const int bottom_padding_;
|
||||
const unsigned int alignment_;
|
||||
T padding_value_;
|
||||
int stride_;
|
||||
int raw_size_;
|
||||
int num_elements_;
|
||||
T *raw_buffer_;
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
T *Buffer<T>::TopLeftPixel() const {
|
||||
if (!raw_buffer_) return NULL;
|
||||
return raw_buffer_ + (top_padding_ * stride_) + left_padding_;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
void Buffer<T>::Set(const T value) {
|
||||
if (!raw_buffer_) return;
|
||||
T *src = TopLeftPixel();
|
||||
for (int height = 0; height < height_; ++height) {
|
||||
for (int width = 0; width < width_; ++width) {
|
||||
src[width] = value;
|
||||
}
|
||||
src += stride_;
|
||||
}
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
void Buffer<T>::Set(ACMRandom *rand_class, T (ACMRandom::*rand_func)()) {
|
||||
if (!raw_buffer_) return;
|
||||
T *src = TopLeftPixel();
|
||||
for (int height = 0; height < height_; ++height) {
|
||||
for (int width = 0; width < width_; ++width) {
|
||||
src[width] = (*rand_class.*rand_func)();
|
||||
}
|
||||
src += stride_;
|
||||
}
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
void Buffer<T>::Set(ACMRandom *rand_class, const T low, const T high) {
|
||||
if (!raw_buffer_) return;
|
||||
|
||||
EXPECT_LE(low, high);
|
||||
EXPECT_LE(static_cast<int64_t>(high) - low,
|
||||
std::numeric_limits<int32_t>::max());
|
||||
|
||||
T *src = TopLeftPixel();
|
||||
for (int height = 0; height < height_; ++height) {
|
||||
for (int width = 0; width < width_; ++width) {
|
||||
// 'low' will be promoted to unsigned given the return type of RandRange.
|
||||
// Store the value as an int to avoid unsigned overflow warnings when
|
||||
// 'low' is negative.
|
||||
const int32_t value =
|
||||
static_cast<int32_t>((*rand_class).RandRange(high - low));
|
||||
src[width] = static_cast<T>(value + low);
|
||||
}
|
||||
src += stride_;
|
||||
}
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
void Buffer<T>::CopyFrom(const Buffer<T> &a) {
|
||||
if (!raw_buffer_) return;
|
||||
if (!BufferSizesMatch(a)) return;
|
||||
|
||||
T *a_src = a.TopLeftPixel();
|
||||
T *b_src = this->TopLeftPixel();
|
||||
for (int height = 0; height < height_; ++height) {
|
||||
for (int width = 0; width < width_; ++width) {
|
||||
b_src[width] = a_src[width];
|
||||
}
|
||||
a_src += a.stride();
|
||||
b_src += this->stride();
|
||||
}
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
void Buffer<T>::DumpBuffer() const {
|
||||
if (!raw_buffer_) return;
|
||||
for (int height = 0; height < height_ + top_padding_ + bottom_padding_;
|
||||
++height) {
|
||||
for (int width = 0; width < stride_; ++width) {
|
||||
printf("%4d", raw_buffer_[height + width * stride_]);
|
||||
}
|
||||
printf("\n");
|
||||
}
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
bool Buffer<T>::HasPadding() const {
|
||||
if (!raw_buffer_) return false;
|
||||
return top_padding_ || left_padding_ || right_padding_ || bottom_padding_;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
void Buffer<T>::PrintDifference(const Buffer<T> &a) const {
|
||||
if (!raw_buffer_) return;
|
||||
if (!BufferSizesMatch(a)) return;
|
||||
|
||||
T *a_src = a.TopLeftPixel();
|
||||
T *b_src = TopLeftPixel();
|
||||
|
||||
printf("This buffer:\n");
|
||||
for (int height = 0; height < height_; ++height) {
|
||||
for (int width = 0; width < width_; ++width) {
|
||||
if (a_src[width] != b_src[width]) {
|
||||
printf("*%3d", b_src[width]);
|
||||
} else {
|
||||
printf("%4d", b_src[width]);
|
||||
}
|
||||
}
|
||||
printf("\n");
|
||||
a_src += a.stride();
|
||||
b_src += this->stride();
|
||||
}
|
||||
|
||||
a_src = a.TopLeftPixel();
|
||||
b_src = TopLeftPixel();
|
||||
|
||||
printf("Reference buffer:\n");
|
||||
for (int height = 0; height < height_; ++height) {
|
||||
for (int width = 0; width < width_; ++width) {
|
||||
if (a_src[width] != b_src[width]) {
|
||||
printf("*%3d", a_src[width]);
|
||||
} else {
|
||||
printf("%4d", a_src[width]);
|
||||
}
|
||||
}
|
||||
printf("\n");
|
||||
a_src += a.stride();
|
||||
b_src += this->stride();
|
||||
}
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
void Buffer<T>::SetPadding(const T padding_value) {
|
||||
if (!raw_buffer_) return;
|
||||
padding_value_ = padding_value;
|
||||
|
||||
T *src = raw_buffer_;
|
||||
for (int i = 0; i < num_elements_; ++i) {
|
||||
src[i] = padding_value;
|
||||
}
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
bool Buffer<T>::CheckValues(const T value) const {
|
||||
if (!raw_buffer_) return false;
|
||||
T *src = TopLeftPixel();
|
||||
for (int height = 0; height < height_; ++height) {
|
||||
for (int width = 0; width < width_; ++width) {
|
||||
if (value != src[width]) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
src += stride_;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
bool Buffer<T>::CheckPadding() const {
|
||||
if (!raw_buffer_) return false;
|
||||
if (!HasPadding()) return true;
|
||||
|
||||
// Top padding.
|
||||
T const *top = raw_buffer_;
|
||||
for (int i = 0; i < stride_ * top_padding_; ++i) {
|
||||
if (padding_value_ != top[i]) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// Left padding.
|
||||
T const *left = TopLeftPixel() - left_padding_;
|
||||
for (int height = 0; height < height_; ++height) {
|
||||
for (int width = 0; width < left_padding_; ++width) {
|
||||
if (padding_value_ != left[width]) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
left += stride_;
|
||||
}
|
||||
|
||||
// Right padding.
|
||||
T const *right = TopLeftPixel() + width_;
|
||||
for (int height = 0; height < height_; ++height) {
|
||||
for (int width = 0; width < right_padding_; ++width) {
|
||||
if (padding_value_ != right[width]) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
right += stride_;
|
||||
}
|
||||
|
||||
// Bottom padding
|
||||
T const *bottom = raw_buffer_ + (top_padding_ + height_) * stride_;
|
||||
for (int i = 0; i < stride_ * bottom_padding_; ++i) {
|
||||
if (padding_value_ != bottom[i]) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
bool Buffer<T>::CheckValues(const Buffer<T> &a) const {
|
||||
if (!raw_buffer_) return false;
|
||||
if (!BufferSizesMatch(a)) return false;
|
||||
|
||||
T *a_src = a.TopLeftPixel();
|
||||
T *b_src = this->TopLeftPixel();
|
||||
for (int height = 0; height < height_; ++height) {
|
||||
for (int width = 0; width < width_; ++width) {
|
||||
if (a_src[width] != b_src[width]) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
a_src += a.stride();
|
||||
b_src += this->stride();
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
bool Buffer<T>::BufferSizesMatch(const Buffer<T> &a) const {
|
||||
if (!raw_buffer_) return false;
|
||||
if (a.width_ != this->width_ || a.height_ != this->height_) {
|
||||
printf(
|
||||
"Reference buffer of size %dx%d does not match this buffer which is "
|
||||
"size %dx%d\n",
|
||||
a.width_, a.height_, this->width_, this->height_);
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
} // namespace libvpx_test
|
||||
#endif // TEST_BUFFER_H_
|
||||
@@ -128,8 +128,8 @@ class ByteAlignmentTest
|
||||
// TODO(fgalligan): Move the MD5 testing code into another class.
|
||||
void OpenMd5File(const std::string &md5_file_name_) {
|
||||
md5_file_ = libvpx_test::OpenTestDataFile(md5_file_name_);
|
||||
ASSERT_TRUE(md5_file_ != NULL) << "MD5 file open failed. Filename: "
|
||||
<< md5_file_name_;
|
||||
ASSERT_TRUE(md5_file_ != NULL)
|
||||
<< "MD5 file open failed. Filename: " << md5_file_name_;
|
||||
}
|
||||
|
||||
void CheckMd5(const vpx_image_t &img) {
|
||||
|
||||
182
test/comp_avg_pred_test.cc
Normal file
182
test/comp_avg_pred_test.cc
Normal file
@@ -0,0 +1,182 @@
|
||||
/*
|
||||
* Copyright (c) 2017 The WebM project authors. All Rights Reserved.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license
|
||||
* that can be found in the LICENSE file in the root of the source
|
||||
* tree. An additional intellectual property rights grant can be found
|
||||
* in the file PATENTS. All contributing project authors may
|
||||
* be found in the AUTHORS file in the root of the source tree.
|
||||
*/
|
||||
|
||||
#include "third_party/googletest/src/include/gtest/gtest.h"
|
||||
|
||||
#include "./vpx_dsp_rtcd.h"
|
||||
|
||||
#include "test/acm_random.h"
|
||||
#include "test/buffer.h"
|
||||
#include "test/register_state_check.h"
|
||||
#include "vpx_ports/vpx_timer.h"
|
||||
|
||||
namespace {
|
||||
|
||||
using ::libvpx_test::ACMRandom;
|
||||
using ::libvpx_test::Buffer;
|
||||
|
||||
typedef void (*AvgPredFunc)(uint8_t *a, const uint8_t *b, int w, int h,
|
||||
const uint8_t *c, int c_stride);
|
||||
|
||||
uint8_t avg_with_rounding(uint8_t a, uint8_t b) { return (a + b + 1) >> 1; }
|
||||
|
||||
void reference_pred(const Buffer<uint8_t> &pred, const Buffer<uint8_t> &ref,
|
||||
int width, int height, Buffer<uint8_t> *avg) {
|
||||
for (int y = 0; y < height; ++y) {
|
||||
for (int x = 0; x < width; ++x) {
|
||||
avg->TopLeftPixel()[y * avg->stride() + x] =
|
||||
avg_with_rounding(pred.TopLeftPixel()[y * pred.stride() + x],
|
||||
ref.TopLeftPixel()[y * ref.stride() + x]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class AvgPredTest : public ::testing::TestWithParam<AvgPredFunc> {
|
||||
public:
|
||||
virtual void SetUp() {
|
||||
avg_pred_func_ = GetParam();
|
||||
rnd_.Reset(ACMRandom::DeterministicSeed());
|
||||
}
|
||||
|
||||
protected:
|
||||
AvgPredFunc avg_pred_func_;
|
||||
ACMRandom rnd_;
|
||||
};
|
||||
|
||||
TEST_P(AvgPredTest, SizeCombinations) {
|
||||
// This is called as part of the sub pixel variance. As such it must be one of
|
||||
// the variance block sizes.
|
||||
|
||||
for (int width_pow = 2; width_pow <= 6; ++width_pow) {
|
||||
for (int height_pow = width_pow - 1; height_pow <= width_pow + 1;
|
||||
++height_pow) {
|
||||
// Don't test 4x2 or 64x128
|
||||
if (height_pow == 1 || height_pow == 7) continue;
|
||||
|
||||
// The sse2 special-cases when ref width == stride, so make sure to test
|
||||
// it.
|
||||
for (int ref_padding = 0; ref_padding < 2; ref_padding++) {
|
||||
const int width = 1 << width_pow;
|
||||
const int height = 1 << height_pow;
|
||||
// Only the reference buffer may have a stride not equal to width.
|
||||
Buffer<uint8_t> ref =
|
||||
Buffer<uint8_t>(width, height, ref_padding ? 8 : 0);
|
||||
ASSERT_TRUE(ref.Init());
|
||||
Buffer<uint8_t> pred = Buffer<uint8_t>(width, height, 0, 16);
|
||||
ASSERT_TRUE(pred.Init());
|
||||
Buffer<uint8_t> avg_ref = Buffer<uint8_t>(width, height, 0, 16);
|
||||
ASSERT_TRUE(avg_ref.Init());
|
||||
Buffer<uint8_t> avg_chk = Buffer<uint8_t>(width, height, 0, 16);
|
||||
ASSERT_TRUE(avg_chk.Init());
|
||||
|
||||
ref.Set(&rnd_, &ACMRandom::Rand8);
|
||||
pred.Set(&rnd_, &ACMRandom::Rand8);
|
||||
|
||||
reference_pred(pred, ref, width, height, &avg_ref);
|
||||
ASM_REGISTER_STATE_CHECK(
|
||||
avg_pred_func_(avg_chk.TopLeftPixel(), pred.TopLeftPixel(), width,
|
||||
height, ref.TopLeftPixel(), ref.stride()));
|
||||
|
||||
EXPECT_TRUE(avg_chk.CheckValues(avg_ref));
|
||||
if (HasFailure()) {
|
||||
printf("Width: %d Height: %d\n", width, height);
|
||||
avg_chk.PrintDifference(avg_ref);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
TEST_P(AvgPredTest, CompareReferenceRandom) {
|
||||
const int width = 64;
|
||||
const int height = 32;
|
||||
Buffer<uint8_t> ref = Buffer<uint8_t>(width, height, 8);
|
||||
ASSERT_TRUE(ref.Init());
|
||||
Buffer<uint8_t> pred = Buffer<uint8_t>(width, height, 0, 16);
|
||||
ASSERT_TRUE(pred.Init());
|
||||
Buffer<uint8_t> avg_ref = Buffer<uint8_t>(width, height, 0, 16);
|
||||
ASSERT_TRUE(avg_ref.Init());
|
||||
Buffer<uint8_t> avg_chk = Buffer<uint8_t>(width, height, 0, 16);
|
||||
ASSERT_TRUE(avg_chk.Init());
|
||||
|
||||
for (int i = 0; i < 500; ++i) {
|
||||
ref.Set(&rnd_, &ACMRandom::Rand8);
|
||||
pred.Set(&rnd_, &ACMRandom::Rand8);
|
||||
|
||||
reference_pred(pred, ref, width, height, &avg_ref);
|
||||
ASM_REGISTER_STATE_CHECK(avg_pred_func_(avg_chk.TopLeftPixel(),
|
||||
pred.TopLeftPixel(), width, height,
|
||||
ref.TopLeftPixel(), ref.stride()));
|
||||
EXPECT_TRUE(avg_chk.CheckValues(avg_ref));
|
||||
if (HasFailure()) {
|
||||
printf("Width: %d Height: %d\n", width, height);
|
||||
avg_chk.PrintDifference(avg_ref);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
TEST_P(AvgPredTest, DISABLED_Speed) {
|
||||
for (int width_pow = 2; width_pow <= 6; ++width_pow) {
|
||||
for (int height_pow = width_pow - 1; height_pow <= width_pow + 1;
|
||||
++height_pow) {
|
||||
// Don't test 4x2 or 64x128
|
||||
if (height_pow == 1 || height_pow == 7) continue;
|
||||
|
||||
for (int ref_padding = 0; ref_padding < 2; ref_padding++) {
|
||||
const int width = 1 << width_pow;
|
||||
const int height = 1 << height_pow;
|
||||
Buffer<uint8_t> ref =
|
||||
Buffer<uint8_t>(width, height, ref_padding ? 8 : 0);
|
||||
ASSERT_TRUE(ref.Init());
|
||||
Buffer<uint8_t> pred = Buffer<uint8_t>(width, height, 0, 16);
|
||||
ASSERT_TRUE(pred.Init());
|
||||
Buffer<uint8_t> avg = Buffer<uint8_t>(width, height, 0, 16);
|
||||
ASSERT_TRUE(avg.Init());
|
||||
|
||||
ref.Set(&rnd_, &ACMRandom::Rand8);
|
||||
pred.Set(&rnd_, &ACMRandom::Rand8);
|
||||
|
||||
vpx_usec_timer timer;
|
||||
vpx_usec_timer_start(&timer);
|
||||
for (int i = 0; i < 10000000 / (width * height); ++i) {
|
||||
avg_pred_func_(avg.TopLeftPixel(), pred.TopLeftPixel(), width, height,
|
||||
ref.TopLeftPixel(), ref.stride());
|
||||
}
|
||||
vpx_usec_timer_mark(&timer);
|
||||
|
||||
const int elapsed_time =
|
||||
static_cast<int>(vpx_usec_timer_elapsed(&timer));
|
||||
printf("Average Test (ref_padding: %d) %dx%d time: %5d us\n",
|
||||
ref_padding, width, height, elapsed_time);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
INSTANTIATE_TEST_CASE_P(C, AvgPredTest,
|
||||
::testing::Values(&vpx_comp_avg_pred_c));
|
||||
|
||||
#if HAVE_SSE2
|
||||
INSTANTIATE_TEST_CASE_P(SSE2, AvgPredTest,
|
||||
::testing::Values(&vpx_comp_avg_pred_sse2));
|
||||
#endif // HAVE_SSE2
|
||||
|
||||
#if HAVE_NEON
|
||||
INSTANTIATE_TEST_CASE_P(NEON, AvgPredTest,
|
||||
::testing::Values(&vpx_comp_avg_pred_neon));
|
||||
#endif // HAVE_NEON
|
||||
|
||||
#if HAVE_VSX
|
||||
INSTANTIATE_TEST_CASE_P(VSX, AvgPredTest,
|
||||
::testing::Values(&vpx_comp_avg_pred_vsx));
|
||||
#endif // HAVE_VSX
|
||||
} // namespace
|
||||
@@ -25,6 +25,7 @@
|
||||
#include "vpx_dsp/vpx_filter.h"
|
||||
#include "vpx_mem/vpx_mem.h"
|
||||
#include "vpx_ports/mem.h"
|
||||
#include "vpx_ports/vpx_timer.h"
|
||||
|
||||
namespace {
|
||||
|
||||
@@ -32,9 +33,9 @@ static const unsigned int kMaxDimension = 64;
|
||||
|
||||
typedef void (*ConvolveFunc)(const uint8_t *src, ptrdiff_t src_stride,
|
||||
uint8_t *dst, ptrdiff_t dst_stride,
|
||||
const int16_t *filter_x, int filter_x_stride,
|
||||
const int16_t *filter_y, int filter_y_stride,
|
||||
int w, int h);
|
||||
const InterpKernel *filter, int x0_q4,
|
||||
int x_step_q4, int y0_q4, int y_step_q4, int w,
|
||||
int h);
|
||||
|
||||
typedef void (*WrapperFilterBlock2d8Func)(
|
||||
const uint8_t *src_ptr, const unsigned int src_stride,
|
||||
@@ -300,9 +301,9 @@ void wrapper_filter_average_block2d_8_c(
|
||||
filter_average_block2d_8_c(src_ptr, src_stride, hfilter, vfilter, dst_ptr,
|
||||
dst_stride, output_width, output_height);
|
||||
} else {
|
||||
highbd_filter_average_block2d_8_c(CONVERT_TO_SHORTPTR(src_ptr), src_stride,
|
||||
highbd_filter_average_block2d_8_c(CAST_TO_SHORTPTR(src_ptr), src_stride,
|
||||
hfilter, vfilter,
|
||||
CONVERT_TO_SHORTPTR(dst_ptr), dst_stride,
|
||||
CAST_TO_SHORTPTR(dst_ptr), dst_stride,
|
||||
output_width, output_height, use_highbd);
|
||||
}
|
||||
#else
|
||||
@@ -323,8 +324,8 @@ void wrapper_filter_block2d_8_c(const uint8_t *src_ptr,
|
||||
filter_block2d_8_c(src_ptr, src_stride, hfilter, vfilter, dst_ptr,
|
||||
dst_stride, output_width, output_height);
|
||||
} else {
|
||||
highbd_filter_block2d_8_c(CONVERT_TO_SHORTPTR(src_ptr), src_stride, hfilter,
|
||||
vfilter, CONVERT_TO_SHORTPTR(dst_ptr), dst_stride,
|
||||
highbd_filter_block2d_8_c(CAST_TO_SHORTPTR(src_ptr), src_stride, hfilter,
|
||||
vfilter, CAST_TO_SHORTPTR(dst_ptr), dst_stride,
|
||||
output_width, output_height, use_highbd);
|
||||
}
|
||||
#else
|
||||
@@ -459,7 +460,7 @@ class ConvolveTest : public ::testing::TestWithParam<ConvolveParam> {
|
||||
if (UUT_->use_highbd_ == 0) {
|
||||
return input_ + offset;
|
||||
} else {
|
||||
return CONVERT_TO_BYTEPTR(input16_) + offset;
|
||||
return CAST_TO_BYTEPTR(input16_ + offset);
|
||||
}
|
||||
#else
|
||||
return input_ + offset;
|
||||
@@ -472,7 +473,7 @@ class ConvolveTest : public ::testing::TestWithParam<ConvolveParam> {
|
||||
if (UUT_->use_highbd_ == 0) {
|
||||
return output_ + offset;
|
||||
} else {
|
||||
return CONVERT_TO_BYTEPTR(output16_) + offset;
|
||||
return CAST_TO_BYTEPTR(output16_ + offset);
|
||||
}
|
||||
#else
|
||||
return output_ + offset;
|
||||
@@ -485,7 +486,7 @@ class ConvolveTest : public ::testing::TestWithParam<ConvolveParam> {
|
||||
if (UUT_->use_highbd_ == 0) {
|
||||
return output_ref_ + offset;
|
||||
} else {
|
||||
return CONVERT_TO_BYTEPTR(output16_ref_) + offset;
|
||||
return CAST_TO_BYTEPTR(output16_ref_ + offset);
|
||||
}
|
||||
#else
|
||||
return output_ref_ + offset;
|
||||
@@ -497,7 +498,7 @@ class ConvolveTest : public ::testing::TestWithParam<ConvolveParam> {
|
||||
if (UUT_->use_highbd_ == 0) {
|
||||
return list[index];
|
||||
} else {
|
||||
return CONVERT_TO_SHORTPTR(list)[index];
|
||||
return CAST_TO_SHORTPTR(list)[index];
|
||||
}
|
||||
#else
|
||||
return list[index];
|
||||
@@ -509,7 +510,7 @@ class ConvolveTest : public ::testing::TestWithParam<ConvolveParam> {
|
||||
if (UUT_->use_highbd_ == 0) {
|
||||
list[index] = (uint8_t)val;
|
||||
} else {
|
||||
CONVERT_TO_SHORTPTR(list)[index] = val;
|
||||
CAST_TO_SHORTPTR(list)[index] = val;
|
||||
}
|
||||
#else
|
||||
list[index] = (uint8_t)val;
|
||||
@@ -539,12 +540,167 @@ uint16_t *ConvolveTest::output16_ref_ = NULL;
|
||||
|
||||
TEST_P(ConvolveTest, GuardBlocks) { CheckGuardBlocks(); }
|
||||
|
||||
TEST_P(ConvolveTest, DISABLED_Copy_Speed) {
|
||||
const uint8_t *const in = input();
|
||||
uint8_t *const out = output();
|
||||
const int kNumTests = 5000000;
|
||||
const int width = Width();
|
||||
const int height = Height();
|
||||
vpx_usec_timer timer;
|
||||
|
||||
vpx_usec_timer_start(&timer);
|
||||
for (int n = 0; n < kNumTests; ++n) {
|
||||
UUT_->copy_[0](in, kInputStride, out, kOutputStride, NULL, 0, 0, 0, 0,
|
||||
width, height);
|
||||
}
|
||||
vpx_usec_timer_mark(&timer);
|
||||
|
||||
const int elapsed_time = static_cast<int>(vpx_usec_timer_elapsed(&timer));
|
||||
printf("convolve_copy_%dx%d_%d: %d us\n", width, height,
|
||||
UUT_->use_highbd_ ? UUT_->use_highbd_ : 8, elapsed_time);
|
||||
}
|
||||
|
||||
TEST_P(ConvolveTest, DISABLED_Avg_Speed) {
|
||||
const uint8_t *const in = input();
|
||||
uint8_t *const out = output();
|
||||
const int kNumTests = 5000000;
|
||||
const int width = Width();
|
||||
const int height = Height();
|
||||
vpx_usec_timer timer;
|
||||
|
||||
vpx_usec_timer_start(&timer);
|
||||
for (int n = 0; n < kNumTests; ++n) {
|
||||
UUT_->copy_[1](in, kInputStride, out, kOutputStride, NULL, 0, 0, 0, 0,
|
||||
width, height);
|
||||
}
|
||||
vpx_usec_timer_mark(&timer);
|
||||
|
||||
const int elapsed_time = static_cast<int>(vpx_usec_timer_elapsed(&timer));
|
||||
printf("convolve_avg_%dx%d_%d: %d us\n", width, height,
|
||||
UUT_->use_highbd_ ? UUT_->use_highbd_ : 8, elapsed_time);
|
||||
}
|
||||
|
||||
TEST_P(ConvolveTest, DISABLED_Scale_Speed) {
|
||||
const uint8_t *const in = input();
|
||||
uint8_t *const out = output();
|
||||
const InterpKernel *const eighttap = vp9_filter_kernels[EIGHTTAP];
|
||||
const int kNumTests = 5000000;
|
||||
const int width = Width();
|
||||
const int height = Height();
|
||||
vpx_usec_timer timer;
|
||||
|
||||
SetConstantInput(127);
|
||||
|
||||
vpx_usec_timer_start(&timer);
|
||||
for (int n = 0; n < kNumTests; ++n) {
|
||||
UUT_->shv8_[0](in, kInputStride, out, kOutputStride, eighttap, 8, 16, 8, 16,
|
||||
width, height);
|
||||
}
|
||||
vpx_usec_timer_mark(&timer);
|
||||
|
||||
const int elapsed_time = static_cast<int>(vpx_usec_timer_elapsed(&timer));
|
||||
printf("convolve_scale_%dx%d_%d: %d us\n", width, height,
|
||||
UUT_->use_highbd_ ? UUT_->use_highbd_ : 8, elapsed_time);
|
||||
}
|
||||
|
||||
TEST_P(ConvolveTest, DISABLED_8Tap_Speed) {
|
||||
const uint8_t *const in = input();
|
||||
uint8_t *const out = output();
|
||||
const InterpKernel *const eighttap = vp9_filter_kernels[EIGHTTAP_SHARP];
|
||||
const int kNumTests = 5000000;
|
||||
const int width = Width();
|
||||
const int height = Height();
|
||||
vpx_usec_timer timer;
|
||||
|
||||
SetConstantInput(127);
|
||||
|
||||
vpx_usec_timer_start(&timer);
|
||||
for (int n = 0; n < kNumTests; ++n) {
|
||||
UUT_->hv8_[0](in, kInputStride, out, kOutputStride, eighttap, 8, 16, 8, 16,
|
||||
width, height);
|
||||
}
|
||||
vpx_usec_timer_mark(&timer);
|
||||
|
||||
const int elapsed_time = static_cast<int>(vpx_usec_timer_elapsed(&timer));
|
||||
printf("convolve8_%dx%d_%d: %d us\n", width, height,
|
||||
UUT_->use_highbd_ ? UUT_->use_highbd_ : 8, elapsed_time);
|
||||
}
|
||||
|
||||
TEST_P(ConvolveTest, DISABLED_8Tap_Horiz_Speed) {
|
||||
const uint8_t *const in = input();
|
||||
uint8_t *const out = output();
|
||||
const InterpKernel *const eighttap = vp9_filter_kernels[EIGHTTAP_SHARP];
|
||||
const int kNumTests = 5000000;
|
||||
const int width = Width();
|
||||
const int height = Height();
|
||||
vpx_usec_timer timer;
|
||||
|
||||
SetConstantInput(127);
|
||||
|
||||
vpx_usec_timer_start(&timer);
|
||||
for (int n = 0; n < kNumTests; ++n) {
|
||||
UUT_->h8_[0](in, kInputStride, out, kOutputStride, eighttap, 8, 16, 8, 16,
|
||||
width, height);
|
||||
}
|
||||
vpx_usec_timer_mark(&timer);
|
||||
|
||||
const int elapsed_time = static_cast<int>(vpx_usec_timer_elapsed(&timer));
|
||||
printf("convolve8_horiz_%dx%d_%d: %d us\n", width, height,
|
||||
UUT_->use_highbd_ ? UUT_->use_highbd_ : 8, elapsed_time);
|
||||
}
|
||||
|
||||
TEST_P(ConvolveTest, DISABLED_8Tap_Vert_Speed) {
|
||||
const uint8_t *const in = input();
|
||||
uint8_t *const out = output();
|
||||
const InterpKernel *const eighttap = vp9_filter_kernels[EIGHTTAP_SHARP];
|
||||
const int kNumTests = 5000000;
|
||||
const int width = Width();
|
||||
const int height = Height();
|
||||
vpx_usec_timer timer;
|
||||
|
||||
SetConstantInput(127);
|
||||
|
||||
vpx_usec_timer_start(&timer);
|
||||
for (int n = 0; n < kNumTests; ++n) {
|
||||
UUT_->v8_[0](in, kInputStride, out, kOutputStride, eighttap, 8, 16, 8, 16,
|
||||
width, height);
|
||||
}
|
||||
vpx_usec_timer_mark(&timer);
|
||||
|
||||
const int elapsed_time = static_cast<int>(vpx_usec_timer_elapsed(&timer));
|
||||
printf("convolve8_vert_%dx%d_%d: %d us\n", width, height,
|
||||
UUT_->use_highbd_ ? UUT_->use_highbd_ : 8, elapsed_time);
|
||||
}
|
||||
|
||||
TEST_P(ConvolveTest, DISABLED_8Tap_Avg_Speed) {
|
||||
const uint8_t *const in = input();
|
||||
uint8_t *const out = output();
|
||||
const InterpKernel *const eighttap = vp9_filter_kernels[EIGHTTAP_SHARP];
|
||||
const int kNumTests = 5000000;
|
||||
const int width = Width();
|
||||
const int height = Height();
|
||||
vpx_usec_timer timer;
|
||||
|
||||
SetConstantInput(127);
|
||||
|
||||
vpx_usec_timer_start(&timer);
|
||||
for (int n = 0; n < kNumTests; ++n) {
|
||||
UUT_->hv8_[1](in, kInputStride, out, kOutputStride, eighttap, 8, 16, 8, 16,
|
||||
width, height);
|
||||
}
|
||||
vpx_usec_timer_mark(&timer);
|
||||
|
||||
const int elapsed_time = static_cast<int>(vpx_usec_timer_elapsed(&timer));
|
||||
printf("convolve8_avg_%dx%d_%d: %d us\n", width, height,
|
||||
UUT_->use_highbd_ ? UUT_->use_highbd_ : 8, elapsed_time);
|
||||
}
|
||||
|
||||
TEST_P(ConvolveTest, Copy) {
|
||||
uint8_t *const in = input();
|
||||
uint8_t *const out = output();
|
||||
|
||||
ASM_REGISTER_STATE_CHECK(UUT_->copy_[0](in, kInputStride, out, kOutputStride,
|
||||
NULL, 0, NULL, 0, Width(), Height()));
|
||||
NULL, 0, 0, 0, 0, Width(), Height()));
|
||||
|
||||
CheckGuardBlocks();
|
||||
|
||||
@@ -563,7 +719,7 @@ TEST_P(ConvolveTest, Avg) {
|
||||
CopyOutputToRef();
|
||||
|
||||
ASM_REGISTER_STATE_CHECK(UUT_->copy_[1](in, kInputStride, out, kOutputStride,
|
||||
NULL, 0, NULL, 0, Width(), Height()));
|
||||
NULL, 0, 0, 0, 0, Width(), Height()));
|
||||
|
||||
CheckGuardBlocks();
|
||||
|
||||
@@ -580,12 +736,10 @@ TEST_P(ConvolveTest, Avg) {
|
||||
TEST_P(ConvolveTest, CopyHoriz) {
|
||||
uint8_t *const in = input();
|
||||
uint8_t *const out = output();
|
||||
DECLARE_ALIGNED(256, const int16_t,
|
||||
filter8[8]) = { 0, 0, 0, 128, 0, 0, 0, 0 };
|
||||
|
||||
ASM_REGISTER_STATE_CHECK(UUT_->sh8_[0](in, kInputStride, out, kOutputStride,
|
||||
filter8, 16, filter8, 16, Width(),
|
||||
Height()));
|
||||
vp9_filter_kernels[0], 0, 16, 0, 16,
|
||||
Width(), Height()));
|
||||
|
||||
CheckGuardBlocks();
|
||||
|
||||
@@ -600,12 +754,10 @@ TEST_P(ConvolveTest, CopyHoriz) {
|
||||
TEST_P(ConvolveTest, CopyVert) {
|
||||
uint8_t *const in = input();
|
||||
uint8_t *const out = output();
|
||||
DECLARE_ALIGNED(256, const int16_t,
|
||||
filter8[8]) = { 0, 0, 0, 128, 0, 0, 0, 0 };
|
||||
|
||||
ASM_REGISTER_STATE_CHECK(UUT_->sv8_[0](in, kInputStride, out, kOutputStride,
|
||||
filter8, 16, filter8, 16, Width(),
|
||||
Height()));
|
||||
vp9_filter_kernels[0], 0, 16, 0, 16,
|
||||
Width(), Height()));
|
||||
|
||||
CheckGuardBlocks();
|
||||
|
||||
@@ -620,12 +772,10 @@ TEST_P(ConvolveTest, CopyVert) {
|
||||
TEST_P(ConvolveTest, Copy2D) {
|
||||
uint8_t *const in = input();
|
||||
uint8_t *const out = output();
|
||||
DECLARE_ALIGNED(256, const int16_t,
|
||||
filter8[8]) = { 0, 0, 0, 128, 0, 0, 0, 0 };
|
||||
|
||||
ASM_REGISTER_STATE_CHECK(UUT_->shv8_[0](in, kInputStride, out, kOutputStride,
|
||||
filter8, 16, filter8, 16, Width(),
|
||||
Height()));
|
||||
vp9_filter_kernels[0], 0, 16, 0, 16,
|
||||
Width(), Height()));
|
||||
|
||||
CheckGuardBlocks();
|
||||
|
||||
@@ -661,7 +811,6 @@ TEST(ConvolveTest, FiltersWontSaturateWhenAddedPairwise) {
|
||||
}
|
||||
}
|
||||
|
||||
const int16_t kInvalidFilter[8] = { 0 };
|
||||
const WrapperFilterBlock2d8Func wrapper_filter_block2d_8[2] = {
|
||||
wrapper_filter_block2d_8_c, wrapper_filter_average_block2d_8_c
|
||||
};
|
||||
@@ -677,7 +826,7 @@ TEST_P(ConvolveTest, MatchesReferenceSubpixelFilter) {
|
||||
if (UUT_->use_highbd_ == 0) {
|
||||
ref = ref8;
|
||||
} else {
|
||||
ref = CONVERT_TO_BYTEPTR(ref16);
|
||||
ref = CAST_TO_BYTEPTR(ref16);
|
||||
}
|
||||
#else
|
||||
uint8_t ref[kOutputStride * kMaxDimension];
|
||||
@@ -714,21 +863,21 @@ TEST_P(ConvolveTest, MatchesReferenceSubpixelFilter) {
|
||||
Width(), Height(), UUT_->use_highbd_);
|
||||
|
||||
if (filter_x && filter_y)
|
||||
ASM_REGISTER_STATE_CHECK(UUT_->hv8_[i](
|
||||
in, kInputStride, out, kOutputStride, filters[filter_x], 16,
|
||||
filters[filter_y], 16, Width(), Height()));
|
||||
ASM_REGISTER_STATE_CHECK(
|
||||
UUT_->hv8_[i](in, kInputStride, out, kOutputStride, filters,
|
||||
filter_x, 16, filter_y, 16, Width(), Height()));
|
||||
else if (filter_y)
|
||||
ASM_REGISTER_STATE_CHECK(UUT_->v8_[i](
|
||||
in, kInputStride, out, kOutputStride, kInvalidFilter, 16,
|
||||
filters[filter_y], 16, Width(), Height()));
|
||||
ASM_REGISTER_STATE_CHECK(
|
||||
UUT_->v8_[i](in, kInputStride, out, kOutputStride, filters, 0,
|
||||
16, filter_y, 16, Width(), Height()));
|
||||
else if (filter_x)
|
||||
ASM_REGISTER_STATE_CHECK(UUT_->h8_[i](
|
||||
in, kInputStride, out, kOutputStride, filters[filter_x], 16,
|
||||
kInvalidFilter, 16, Width(), Height()));
|
||||
ASM_REGISTER_STATE_CHECK(
|
||||
UUT_->h8_[i](in, kInputStride, out, kOutputStride, filters,
|
||||
filter_x, 16, 0, 16, Width(), Height()));
|
||||
else
|
||||
ASM_REGISTER_STATE_CHECK(UUT_->copy_[i](
|
||||
in, kInputStride, out, kOutputStride, kInvalidFilter, 0,
|
||||
kInvalidFilter, 0, Width(), Height()));
|
||||
ASM_REGISTER_STATE_CHECK(UUT_->copy_[i](in, kInputStride, out,
|
||||
kOutputStride, NULL, 0, 0,
|
||||
0, 0, Width(), Height()));
|
||||
|
||||
CheckGuardBlocks();
|
||||
|
||||
@@ -756,7 +905,7 @@ TEST_P(ConvolveTest, FilterExtremes) {
|
||||
if (UUT_->use_highbd_ == 0) {
|
||||
ref = ref8;
|
||||
} else {
|
||||
ref = CONVERT_TO_BYTEPTR(ref16);
|
||||
ref = CAST_TO_BYTEPTR(ref16);
|
||||
}
|
||||
#else
|
||||
uint8_t ref[kOutputStride * kMaxDimension];
|
||||
@@ -812,21 +961,21 @@ TEST_P(ConvolveTest, FilterExtremes) {
|
||||
filters[filter_y], ref, kOutputStride,
|
||||
Width(), Height(), UUT_->use_highbd_);
|
||||
if (filter_x && filter_y)
|
||||
ASM_REGISTER_STATE_CHECK(UUT_->hv8_[0](
|
||||
in, kInputStride, out, kOutputStride, filters[filter_x], 16,
|
||||
filters[filter_y], 16, Width(), Height()));
|
||||
ASM_REGISTER_STATE_CHECK(
|
||||
UUT_->hv8_[0](in, kInputStride, out, kOutputStride, filters,
|
||||
filter_x, 16, filter_y, 16, Width(), Height()));
|
||||
else if (filter_y)
|
||||
ASM_REGISTER_STATE_CHECK(UUT_->v8_[0](
|
||||
in, kInputStride, out, kOutputStride, kInvalidFilter, 16,
|
||||
filters[filter_y], 16, Width(), Height()));
|
||||
ASM_REGISTER_STATE_CHECK(
|
||||
UUT_->v8_[0](in, kInputStride, out, kOutputStride, filters, 0,
|
||||
16, filter_y, 16, Width(), Height()));
|
||||
else if (filter_x)
|
||||
ASM_REGISTER_STATE_CHECK(UUT_->h8_[0](
|
||||
in, kInputStride, out, kOutputStride, filters[filter_x], 16,
|
||||
kInvalidFilter, 16, Width(), Height()));
|
||||
ASM_REGISTER_STATE_CHECK(
|
||||
UUT_->h8_[0](in, kInputStride, out, kOutputStride, filters,
|
||||
filter_x, 16, 0, 16, Width(), Height()));
|
||||
else
|
||||
ASM_REGISTER_STATE_CHECK(UUT_->copy_[0](
|
||||
in, kInputStride, out, kOutputStride, kInvalidFilter, 0,
|
||||
kInvalidFilter, 0, Width(), Height()));
|
||||
ASM_REGISTER_STATE_CHECK(UUT_->copy_[0](in, kInputStride, out,
|
||||
kOutputStride, NULL, 0, 0,
|
||||
0, 0, Width(), Height()));
|
||||
|
||||
for (int y = 0; y < Height(); ++y) {
|
||||
for (int x = 0; x < Width(); ++x)
|
||||
@@ -845,33 +994,51 @@ TEST_P(ConvolveTest, FilterExtremes) {
|
||||
|
||||
/* This test exercises that enough rows and columns are filtered with every
|
||||
possible initial fractional positions and scaling steps. */
|
||||
#if !CONFIG_VP9_HIGHBITDEPTH
|
||||
static const ConvolveFunc scaled_2d_c_funcs[2] = { vpx_scaled_2d_c,
|
||||
vpx_scaled_avg_2d_c };
|
||||
|
||||
TEST_P(ConvolveTest, CheckScalingFiltering) {
|
||||
uint8_t *const in = input();
|
||||
uint8_t *const out = output();
|
||||
const InterpKernel *const eighttap = vp9_filter_kernels[EIGHTTAP];
|
||||
uint8_t ref[kOutputStride * kMaxDimension];
|
||||
|
||||
SetConstantInput(127);
|
||||
::libvpx_test::ACMRandom prng;
|
||||
for (int y = 0; y < Height(); ++y) {
|
||||
for (int x = 0; x < Width(); ++x) {
|
||||
const uint16_t r = prng.Rand8Extremes();
|
||||
assign_val(in, y * kInputStride + x, r);
|
||||
}
|
||||
}
|
||||
|
||||
for (int frac = 0; frac < 16; ++frac) {
|
||||
for (int step = 1; step <= 32; ++step) {
|
||||
/* Test the horizontal and vertical filters in combination. */
|
||||
ASM_REGISTER_STATE_CHECK(
|
||||
UUT_->shv8_[0](in, kInputStride, out, kOutputStride, eighttap[frac],
|
||||
step, eighttap[frac], step, Width(), Height()));
|
||||
for (int i = 0; i < 2; ++i) {
|
||||
for (INTERP_FILTER filter_type = 0; filter_type < 4; ++filter_type) {
|
||||
const InterpKernel *const eighttap = vp9_filter_kernels[filter_type];
|
||||
for (int frac = 0; frac < 16; ++frac) {
|
||||
for (int step = 1; step <= 32; ++step) {
|
||||
/* Test the horizontal and vertical filters in combination. */
|
||||
scaled_2d_c_funcs[i](in, kInputStride, ref, kOutputStride, eighttap,
|
||||
frac, step, frac, step, Width(), Height());
|
||||
ASM_REGISTER_STATE_CHECK(
|
||||
UUT_->shv8_[i](in, kInputStride, out, kOutputStride, eighttap,
|
||||
frac, step, frac, step, Width(), Height()));
|
||||
|
||||
CheckGuardBlocks();
|
||||
CheckGuardBlocks();
|
||||
|
||||
for (int y = 0; y < Height(); ++y) {
|
||||
for (int x = 0; x < Width(); ++x) {
|
||||
ASSERT_EQ(lookup(in, y * kInputStride + x),
|
||||
lookup(out, y * kOutputStride + x))
|
||||
<< "x == " << x << ", y == " << y << ", frac == " << frac
|
||||
<< ", step == " << step;
|
||||
for (int y = 0; y < Height(); ++y) {
|
||||
for (int x = 0; x < Width(); ++x) {
|
||||
ASSERT_EQ(lookup(ref, y * kOutputStride + x),
|
||||
lookup(out, y * kOutputStride + x))
|
||||
<< "x == " << x << ", y == " << y << ", frac == " << frac
|
||||
<< ", step == " << step;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
using std::tr1::make_tuple;
|
||||
|
||||
@@ -879,10 +1046,11 @@ using std::tr1::make_tuple;
|
||||
#define WRAP(func, bd) \
|
||||
void wrap_##func##_##bd( \
|
||||
const uint8_t *src, ptrdiff_t src_stride, uint8_t *dst, \
|
||||
ptrdiff_t dst_stride, const int16_t *filter_x, int filter_x_stride, \
|
||||
const int16_t *filter_y, int filter_y_stride, int w, int h) { \
|
||||
vpx_highbd_##func(src, src_stride, dst, dst_stride, filter_x, \
|
||||
filter_x_stride, filter_y, filter_y_stride, w, h, bd); \
|
||||
ptrdiff_t dst_stride, const InterpKernel *filter, int x0_q4, \
|
||||
int x_step_q4, int y0_q4, int y_step_q4, int w, int h) { \
|
||||
vpx_highbd_##func(reinterpret_cast<const uint16_t *>(src), src_stride, \
|
||||
reinterpret_cast<uint16_t *>(dst), dst_stride, filter, \
|
||||
x0_q4, x_step_q4, y0_q4, y_step_q4, w, h, bd); \
|
||||
}
|
||||
|
||||
#if HAVE_SSE2 && ARCH_X86_64
|
||||
@@ -912,6 +1080,35 @@ WRAP(convolve8_sse2, 12)
|
||||
WRAP(convolve8_avg_sse2, 12)
|
||||
#endif // HAVE_SSE2 && ARCH_X86_64
|
||||
|
||||
#if HAVE_AVX2
|
||||
WRAP(convolve_copy_avx2, 8)
|
||||
WRAP(convolve_avg_avx2, 8)
|
||||
WRAP(convolve8_horiz_avx2, 8)
|
||||
WRAP(convolve8_avg_horiz_avx2, 8)
|
||||
WRAP(convolve8_vert_avx2, 8)
|
||||
WRAP(convolve8_avg_vert_avx2, 8)
|
||||
WRAP(convolve8_avx2, 8)
|
||||
WRAP(convolve8_avg_avx2, 8)
|
||||
|
||||
WRAP(convolve_copy_avx2, 10)
|
||||
WRAP(convolve_avg_avx2, 10)
|
||||
WRAP(convolve8_avx2, 10)
|
||||
WRAP(convolve8_horiz_avx2, 10)
|
||||
WRAP(convolve8_vert_avx2, 10)
|
||||
WRAP(convolve8_avg_avx2, 10)
|
||||
WRAP(convolve8_avg_horiz_avx2, 10)
|
||||
WRAP(convolve8_avg_vert_avx2, 10)
|
||||
|
||||
WRAP(convolve_copy_avx2, 12)
|
||||
WRAP(convolve_avg_avx2, 12)
|
||||
WRAP(convolve8_avx2, 12)
|
||||
WRAP(convolve8_horiz_avx2, 12)
|
||||
WRAP(convolve8_vert_avx2, 12)
|
||||
WRAP(convolve8_avg_avx2, 12)
|
||||
WRAP(convolve8_avg_horiz_avx2, 12)
|
||||
WRAP(convolve8_avg_vert_avx2, 12)
|
||||
#endif // HAVE_AVX2
|
||||
|
||||
#if HAVE_NEON
|
||||
WRAP(convolve_copy_neon, 8)
|
||||
WRAP(convolve_avg_neon, 8)
|
||||
@@ -1057,18 +1254,48 @@ INSTANTIATE_TEST_CASE_P(SSSE3, ConvolveTest,
|
||||
::testing::ValuesIn(kArrayConvolve8_ssse3));
|
||||
#endif
|
||||
|
||||
#if HAVE_AVX2 && HAVE_SSSE3
|
||||
#if HAVE_AVX2
|
||||
#if CONFIG_VP9_HIGHBITDEPTH
|
||||
const ConvolveFunctions convolve8_avx2(
|
||||
wrap_convolve_copy_avx2_8, wrap_convolve_avg_avx2_8,
|
||||
wrap_convolve8_horiz_avx2_8, wrap_convolve8_avg_horiz_avx2_8,
|
||||
wrap_convolve8_vert_avx2_8, wrap_convolve8_avg_vert_avx2_8,
|
||||
wrap_convolve8_avx2_8, wrap_convolve8_avg_avx2_8, wrap_convolve8_horiz_c_8,
|
||||
wrap_convolve8_avg_horiz_c_8, wrap_convolve8_vert_c_8,
|
||||
wrap_convolve8_avg_vert_c_8, wrap_convolve8_c_8, wrap_convolve8_avg_c_8, 8);
|
||||
const ConvolveFunctions convolve10_avx2(
|
||||
wrap_convolve_copy_avx2_10, wrap_convolve_avg_avx2_10,
|
||||
wrap_convolve8_horiz_avx2_10, wrap_convolve8_avg_horiz_avx2_10,
|
||||
wrap_convolve8_vert_avx2_10, wrap_convolve8_avg_vert_avx2_10,
|
||||
wrap_convolve8_avx2_10, wrap_convolve8_avg_avx2_10,
|
||||
wrap_convolve8_horiz_c_10, wrap_convolve8_avg_horiz_c_10,
|
||||
wrap_convolve8_vert_c_10, wrap_convolve8_avg_vert_c_10, wrap_convolve8_c_10,
|
||||
wrap_convolve8_avg_c_10, 10);
|
||||
const ConvolveFunctions convolve12_avx2(
|
||||
wrap_convolve_copy_avx2_12, wrap_convolve_avg_avx2_12,
|
||||
wrap_convolve8_horiz_avx2_12, wrap_convolve8_avg_horiz_avx2_12,
|
||||
wrap_convolve8_vert_avx2_12, wrap_convolve8_avg_vert_avx2_12,
|
||||
wrap_convolve8_avx2_12, wrap_convolve8_avg_avx2_12,
|
||||
wrap_convolve8_horiz_c_12, wrap_convolve8_avg_horiz_c_12,
|
||||
wrap_convolve8_vert_c_12, wrap_convolve8_avg_vert_c_12, wrap_convolve8_c_12,
|
||||
wrap_convolve8_avg_c_12, 12);
|
||||
const ConvolveParam kArrayConvolve8_avx2[] = { ALL_SIZES(convolve8_avx2),
|
||||
ALL_SIZES(convolve10_avx2),
|
||||
ALL_SIZES(convolve12_avx2) };
|
||||
INSTANTIATE_TEST_CASE_P(AVX2, ConvolveTest,
|
||||
::testing::ValuesIn(kArrayConvolve8_avx2));
|
||||
#else // !CONFIG_VP9_HIGHBITDEPTH
|
||||
const ConvolveFunctions convolve8_avx2(
|
||||
vpx_convolve_copy_c, vpx_convolve_avg_c, vpx_convolve8_horiz_avx2,
|
||||
vpx_convolve8_avg_horiz_ssse3, vpx_convolve8_vert_avx2,
|
||||
vpx_convolve8_avg_vert_ssse3, vpx_convolve8_avx2, vpx_convolve8_avg_ssse3,
|
||||
vpx_convolve8_avg_horiz_avx2, vpx_convolve8_vert_avx2,
|
||||
vpx_convolve8_avg_vert_avx2, vpx_convolve8_avx2, vpx_convolve8_avg_avx2,
|
||||
vpx_scaled_horiz_c, vpx_scaled_avg_horiz_c, vpx_scaled_vert_c,
|
||||
vpx_scaled_avg_vert_c, vpx_scaled_2d_c, vpx_scaled_avg_2d_c, 0);
|
||||
|
||||
const ConvolveParam kArrayConvolve8_avx2[] = { ALL_SIZES(convolve8_avx2) };
|
||||
INSTANTIATE_TEST_CASE_P(AVX2, ConvolveTest,
|
||||
::testing::ValuesIn(kArrayConvolve8_avx2));
|
||||
#endif // HAVE_AVX2 && HAVE_SSSE3
|
||||
#endif // CONFIG_VP9_HIGHBITDEPTH
|
||||
#endif // HAVE_AVX2
|
||||
|
||||
#if HAVE_NEON
|
||||
#if CONFIG_VP9_HIGHBITDEPTH
|
||||
@@ -1105,7 +1332,7 @@ const ConvolveFunctions convolve8_neon(
|
||||
vpx_convolve8_avg_horiz_neon, vpx_convolve8_vert_neon,
|
||||
vpx_convolve8_avg_vert_neon, vpx_convolve8_neon, vpx_convolve8_avg_neon,
|
||||
vpx_scaled_horiz_c, vpx_scaled_avg_horiz_c, vpx_scaled_vert_c,
|
||||
vpx_scaled_avg_vert_c, vpx_scaled_2d_c, vpx_scaled_avg_2d_c, 0);
|
||||
vpx_scaled_avg_vert_c, vpx_scaled_2d_neon, vpx_scaled_avg_2d_c, 0);
|
||||
|
||||
const ConvolveParam kArrayConvolve_neon[] = { ALL_SIZES(convolve8_neon) };
|
||||
#endif // CONFIG_VP9_HIGHBITDEPTH
|
||||
@@ -1132,10 +1359,22 @@ const ConvolveFunctions convolve8_msa(
|
||||
vpx_convolve8_avg_horiz_msa, vpx_convolve8_vert_msa,
|
||||
vpx_convolve8_avg_vert_msa, vpx_convolve8_msa, vpx_convolve8_avg_msa,
|
||||
vpx_scaled_horiz_c, vpx_scaled_avg_horiz_c, vpx_scaled_vert_c,
|
||||
vpx_scaled_avg_vert_c, vpx_scaled_2d_c, vpx_scaled_avg_2d_c, 0);
|
||||
vpx_scaled_avg_vert_c, vpx_scaled_2d_msa, vpx_scaled_avg_2d_c, 0);
|
||||
|
||||
const ConvolveParam kArrayConvolve8_msa[] = { ALL_SIZES(convolve8_msa) };
|
||||
INSTANTIATE_TEST_CASE_P(MSA, ConvolveTest,
|
||||
::testing::ValuesIn(kArrayConvolve8_msa));
|
||||
#endif // HAVE_MSA
|
||||
|
||||
#if HAVE_VSX
|
||||
const ConvolveFunctions convolve8_vsx(
|
||||
vpx_convolve_copy_vsx, vpx_convolve_avg_vsx, vpx_convolve8_horiz_vsx,
|
||||
vpx_convolve8_avg_horiz_vsx, vpx_convolve8_vert_vsx,
|
||||
vpx_convolve8_avg_vert_vsx, vpx_convolve8_vsx, vpx_convolve8_avg_vsx,
|
||||
vpx_scaled_horiz_c, vpx_scaled_avg_horiz_c, vpx_scaled_vert_c,
|
||||
vpx_scaled_avg_vert_c, vpx_scaled_2d_c, vpx_scaled_avg_2d_c, 0);
|
||||
const ConvolveParam kArrayConvolve_vsx[] = { ALL_SIZES(convolve8_vsx) };
|
||||
INSTANTIATE_TEST_CASE_P(VSX, ConvolveTest,
|
||||
::testing::ValuesIn(kArrayConvolve_vsx));
|
||||
#endif // HAVE_VSX
|
||||
} // namespace
|
||||
|
||||
@@ -44,6 +44,7 @@ class DatarateTestLarge
|
||||
denoiser_offon_test_ = 0;
|
||||
denoiser_offon_period_ = -1;
|
||||
gf_boost_ = 0;
|
||||
use_roi_ = 0;
|
||||
}
|
||||
|
||||
virtual void PreEncodeFrameHook(::libvpx_test::VideoSource *video,
|
||||
@@ -54,6 +55,12 @@ class DatarateTestLarge
|
||||
encoder->Control(VP8E_SET_GF_CBR_BOOST_PCT, gf_boost_);
|
||||
}
|
||||
|
||||
#if CONFIG_VP8_ENCODER
|
||||
if (use_roi_ == 1) {
|
||||
encoder->Control(VP8E_SET_ROI_MAP, &roi_);
|
||||
}
|
||||
#endif
|
||||
|
||||
if (denoiser_offon_test_) {
|
||||
ASSERT_GT(denoiser_offon_period_, 0)
|
||||
<< "denoiser_offon_period_ is not positive.";
|
||||
@@ -91,8 +98,8 @@ class DatarateTestLarge
|
||||
const bool key_frame =
|
||||
(pkt->data.frame.flags & VPX_FRAME_IS_KEY) ? true : false;
|
||||
if (!key_frame) {
|
||||
ASSERT_GE(bits_in_buffer_model_, 0) << "Buffer Underrun at frame "
|
||||
<< pkt->data.frame.pts;
|
||||
ASSERT_GE(bits_in_buffer_model_, 0)
|
||||
<< "Buffer Underrun at frame " << pkt->data.frame.pts;
|
||||
}
|
||||
|
||||
const int64_t frame_size_in_bits = pkt->data.frame.sz * 8;
|
||||
@@ -145,6 +152,8 @@ class DatarateTestLarge
|
||||
int denoiser_offon_period_;
|
||||
int set_cpu_used_;
|
||||
int gf_boost_;
|
||||
int use_roi_;
|
||||
vpx_roi_map_t roi_;
|
||||
};
|
||||
|
||||
#if CONFIG_TEMPORAL_DENOISING
|
||||
@@ -258,14 +267,6 @@ TEST_P(DatarateTestLarge, ChangingDropFrameThresh) {
|
||||
}
|
||||
}
|
||||
|
||||
// Disabled for tsan, see:
|
||||
// https://bugs.chromium.org/p/webm/issues/detail?id=1049
|
||||
#if defined(__has_feature)
|
||||
#if __has_feature(thread_sanitizer)
|
||||
#define BUILDING_WITH_TSAN
|
||||
#endif
|
||||
#endif
|
||||
#ifndef BUILDING_WITH_TSAN
|
||||
TEST_P(DatarateTestLarge, DropFramesMultiThreads) {
|
||||
denoiser_on_ = 0;
|
||||
cfg_.rc_buf_initial_sz = 500;
|
||||
@@ -285,7 +286,6 @@ TEST_P(DatarateTestLarge, DropFramesMultiThreads) {
|
||||
ASSERT_LE(cfg_.rc_target_bitrate, file_datarate_ * 1.4)
|
||||
<< " The datarate for the file missed the target!";
|
||||
}
|
||||
#endif // !BUILDING_WITH_TSAN
|
||||
|
||||
class DatarateTestRealTime : public DatarateTestLarge {
|
||||
public:
|
||||
@@ -402,10 +402,6 @@ TEST_P(DatarateTestRealTime, ChangingDropFrameThresh) {
|
||||
}
|
||||
}
|
||||
|
||||
// Disabled for tsan, see:
|
||||
// https://bugs.chromium.org/p/webm/issues/detail?id=1049
|
||||
|
||||
#ifndef BUILDING_WITH_TSAN
|
||||
TEST_P(DatarateTestRealTime, DropFramesMultiThreads) {
|
||||
denoiser_on_ = 0;
|
||||
cfg_.rc_buf_initial_sz = 500;
|
||||
@@ -426,7 +422,67 @@ TEST_P(DatarateTestRealTime, DropFramesMultiThreads) {
|
||||
ASSERT_LE(cfg_.rc_target_bitrate, file_datarate_ * 1.4)
|
||||
<< " The datarate for the file missed the target!";
|
||||
}
|
||||
#endif
|
||||
|
||||
TEST_P(DatarateTestRealTime, RegionOfInterest) {
|
||||
denoiser_on_ = 0;
|
||||
cfg_.rc_buf_initial_sz = 500;
|
||||
cfg_.rc_dropframe_thresh = 0;
|
||||
cfg_.rc_max_quantizer = 56;
|
||||
cfg_.rc_end_usage = VPX_CBR;
|
||||
// Encode using multiple threads.
|
||||
cfg_.g_threads = 2;
|
||||
|
||||
::libvpx_test::I420VideoSource video("hantro_collage_w352h288.yuv", 352, 288,
|
||||
30, 1, 0, 300);
|
||||
cfg_.rc_target_bitrate = 450;
|
||||
cfg_.g_w = 352;
|
||||
cfg_.g_h = 288;
|
||||
|
||||
ResetModel();
|
||||
|
||||
// Set ROI parameters
|
||||
use_roi_ = 1;
|
||||
memset(&roi_, 0, sizeof(roi_));
|
||||
|
||||
roi_.rows = (cfg_.g_h + 15) / 16;
|
||||
roi_.cols = (cfg_.g_w + 15) / 16;
|
||||
|
||||
roi_.delta_q[0] = 0;
|
||||
roi_.delta_q[1] = -20;
|
||||
roi_.delta_q[2] = 0;
|
||||
roi_.delta_q[3] = 0;
|
||||
|
||||
roi_.delta_lf[0] = 0;
|
||||
roi_.delta_lf[1] = -20;
|
||||
roi_.delta_lf[2] = 0;
|
||||
roi_.delta_lf[3] = 0;
|
||||
|
||||
roi_.static_threshold[0] = 0;
|
||||
roi_.static_threshold[1] = 1000;
|
||||
roi_.static_threshold[2] = 0;
|
||||
roi_.static_threshold[3] = 0;
|
||||
|
||||
// Use 2 states: 1 is center square, 0 is the rest.
|
||||
roi_.roi_map =
|
||||
(uint8_t *)calloc(roi_.rows * roi_.cols, sizeof(*roi_.roi_map));
|
||||
for (unsigned int i = 0; i < roi_.rows; ++i) {
|
||||
for (unsigned int j = 0; j < roi_.cols; ++j) {
|
||||
if (i > (roi_.rows >> 2) && i < ((roi_.rows * 3) >> 2) &&
|
||||
j > (roi_.cols >> 2) && j < ((roi_.cols * 3) >> 2)) {
|
||||
roi_.roi_map[i * roi_.cols + j] = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ASSERT_NO_FATAL_FAILURE(RunLoop(&video));
|
||||
ASSERT_GE(cfg_.rc_target_bitrate, effective_datarate_ * 0.95)
|
||||
<< " The datarate for the file exceeds the target!";
|
||||
|
||||
ASSERT_LE(cfg_.rc_target_bitrate, file_datarate_ * 1.4)
|
||||
<< " The datarate for the file missed the target!";
|
||||
|
||||
free(roi_.roi_map);
|
||||
}
|
||||
|
||||
TEST_P(DatarateTestRealTime, GFBoost) {
|
||||
denoiser_on_ = 0;
|
||||
@@ -482,6 +538,7 @@ class DatarateTestVP9Large
|
||||
}
|
||||
denoiser_offon_test_ = 0;
|
||||
denoiser_offon_period_ = -1;
|
||||
frame_parallel_decoding_mode_ = 1;
|
||||
}
|
||||
|
||||
//
|
||||
@@ -496,8 +553,8 @@ class DatarateTestVP9Large
|
||||
// 2 6
|
||||
// 0 4 ....
|
||||
// LAST is always update on base/layer 0, GOLDEN is updated on layer 1.
|
||||
// For this 3 layer example, the 2nd enhancement layer (layer 2) does not
|
||||
// update any reference frames.
|
||||
// For this 3 layer example, the 2nd enhancement layer (layer 2) updates
|
||||
// the altref frame.
|
||||
int SetFrameFlags(int frame_num, int num_temp_layers) {
|
||||
int frame_flags = 0;
|
||||
if (num_temp_layers == 2) {
|
||||
@@ -519,9 +576,8 @@ class DatarateTestVP9Large
|
||||
// Layer 1: predict from L, G, ARF; update G.
|
||||
frame_flags = VP8_EFLAG_NO_UPD_ARF | VP8_EFLAG_NO_UPD_LAST;
|
||||
} else if ((frame_num - 1) % 2 == 0) {
|
||||
// Layer 2: predict from L, G, ARF; update none.
|
||||
frame_flags =
|
||||
VP8_EFLAG_NO_UPD_GF | VP8_EFLAG_NO_UPD_ARF | VP8_EFLAG_NO_UPD_LAST;
|
||||
// Layer 2: predict from L, G, ARF; update ARF.
|
||||
frame_flags = VP8_EFLAG_NO_UPD_GF | VP8_EFLAG_NO_UPD_LAST;
|
||||
}
|
||||
}
|
||||
return frame_flags;
|
||||
@@ -561,6 +617,9 @@ class DatarateTestVP9Large
|
||||
}
|
||||
|
||||
encoder->Control(VP9E_SET_NOISE_SENSITIVITY, denoiser_on_);
|
||||
encoder->Control(VP9E_SET_TILE_COLUMNS, (cfg_.g_threads >> 1));
|
||||
encoder->Control(VP9E_SET_FRAME_PARALLEL_DECODING,
|
||||
frame_parallel_decoding_mode_);
|
||||
|
||||
if (cfg_.ts_number_layers > 1) {
|
||||
if (video->frame() == 0) {
|
||||
@@ -599,8 +658,8 @@ class DatarateTestVP9Large
|
||||
duration * timebase_ * cfg_.rc_target_bitrate * 1000);
|
||||
|
||||
// Buffer should not go negative.
|
||||
ASSERT_GE(bits_in_buffer_model_, 0) << "Buffer Underrun at frame "
|
||||
<< pkt->data.frame.pts;
|
||||
ASSERT_GE(bits_in_buffer_model_, 0)
|
||||
<< "Buffer Underrun at frame " << pkt->data.frame.pts;
|
||||
|
||||
const size_t frame_size_in_bits = pkt->data.frame.sz * 8;
|
||||
|
||||
@@ -641,6 +700,7 @@ class DatarateTestVP9Large
|
||||
int denoiser_on_;
|
||||
int denoiser_offon_test_;
|
||||
int denoiser_offon_period_;
|
||||
int frame_parallel_decoding_mode_;
|
||||
};
|
||||
|
||||
// Check basic rate targeting for VBR mode with 0 lag.
|
||||
@@ -659,7 +719,7 @@ TEST_P(DatarateTestVP9Large, BasicRateTargetingVBRLagZero) {
|
||||
ASSERT_NO_FATAL_FAILURE(RunLoop(&video));
|
||||
ASSERT_GE(effective_datarate_[0], cfg_.rc_target_bitrate * 0.75)
|
||||
<< " The datarate for the file is lower than target by too much!";
|
||||
ASSERT_LE(effective_datarate_[0], cfg_.rc_target_bitrate * 1.25)
|
||||
ASSERT_LE(effective_datarate_[0], cfg_.rc_target_bitrate * 1.30)
|
||||
<< " The datarate for the file is greater than target by too much!";
|
||||
}
|
||||
}
|
||||
@@ -686,7 +746,37 @@ TEST_P(DatarateTestVP9Large, BasicRateTargetingVBRLagNonZero) {
|
||||
ASSERT_NO_FATAL_FAILURE(RunLoop(&video));
|
||||
ASSERT_GE(effective_datarate_[0], cfg_.rc_target_bitrate * 0.75)
|
||||
<< " The datarate for the file is lower than target by too much!";
|
||||
ASSERT_LE(effective_datarate_[0], cfg_.rc_target_bitrate * 1.25)
|
||||
ASSERT_LE(effective_datarate_[0], cfg_.rc_target_bitrate * 1.30)
|
||||
<< " The datarate for the file is greater than target by too much!";
|
||||
}
|
||||
}
|
||||
|
||||
// Check basic rate targeting for VBR mode with non-zero lag, with
|
||||
// frame_parallel_decoding_mode off. This enables the adapt_coeff/mode/mv probs
|
||||
// since error_resilience is off.
|
||||
TEST_P(DatarateTestVP9Large, BasicRateTargetingVBRLagNonZeroFrameParDecOff) {
|
||||
cfg_.rc_min_quantizer = 0;
|
||||
cfg_.rc_max_quantizer = 63;
|
||||
cfg_.g_error_resilient = 0;
|
||||
cfg_.rc_end_usage = VPX_VBR;
|
||||
// For non-zero lag, rate control will work (be within bounds) for
|
||||
// real-time mode.
|
||||
if (deadline_ == VPX_DL_REALTIME) {
|
||||
cfg_.g_lag_in_frames = 15;
|
||||
} else {
|
||||
cfg_.g_lag_in_frames = 0;
|
||||
}
|
||||
|
||||
::libvpx_test::I420VideoSource video("hantro_collage_w352h288.yuv", 352, 288,
|
||||
30, 1, 0, 300);
|
||||
for (int i = 400; i <= 800; i += 400) {
|
||||
cfg_.rc_target_bitrate = i;
|
||||
ResetModel();
|
||||
frame_parallel_decoding_mode_ = 0;
|
||||
ASSERT_NO_FATAL_FAILURE(RunLoop(&video));
|
||||
ASSERT_GE(effective_datarate_[0], cfg_.rc_target_bitrate * 0.75)
|
||||
<< " The datarate for the file is lower than target by too much!";
|
||||
ASSERT_LE(effective_datarate_[0], cfg_.rc_target_bitrate * 1.30)
|
||||
<< " The datarate for the file is greater than target by too much!";
|
||||
}
|
||||
}
|
||||
@@ -715,6 +805,33 @@ TEST_P(DatarateTestVP9Large, BasicRateTargeting) {
|
||||
}
|
||||
}
|
||||
|
||||
// Check basic rate targeting for CBR mode, with frame_parallel_decoding_mode
|
||||
// off( and error_resilience off).
|
||||
TEST_P(DatarateTestVP9Large, BasicRateTargetingFrameParDecOff) {
|
||||
cfg_.rc_buf_initial_sz = 500;
|
||||
cfg_.rc_buf_optimal_sz = 500;
|
||||
cfg_.rc_buf_sz = 1000;
|
||||
cfg_.rc_dropframe_thresh = 1;
|
||||
cfg_.rc_min_quantizer = 0;
|
||||
cfg_.rc_max_quantizer = 63;
|
||||
cfg_.rc_end_usage = VPX_CBR;
|
||||
cfg_.g_lag_in_frames = 0;
|
||||
cfg_.g_error_resilient = 0;
|
||||
|
||||
::libvpx_test::I420VideoSource video("hantro_collage_w352h288.yuv", 352, 288,
|
||||
30, 1, 0, 140);
|
||||
for (int i = 150; i < 800; i += 200) {
|
||||
cfg_.rc_target_bitrate = i;
|
||||
ResetModel();
|
||||
frame_parallel_decoding_mode_ = 0;
|
||||
ASSERT_NO_FATAL_FAILURE(RunLoop(&video));
|
||||
ASSERT_GE(effective_datarate_[0], cfg_.rc_target_bitrate * 0.85)
|
||||
<< " The datarate for the file is lower than target by too much!";
|
||||
ASSERT_LE(effective_datarate_[0], cfg_.rc_target_bitrate * 1.15)
|
||||
<< " The datarate for the file is greater than target by too much!";
|
||||
}
|
||||
}
|
||||
|
||||
// Check basic rate targeting for CBR mode, with 2 threads and dropped frames.
|
||||
TEST_P(DatarateTestVP9Large, BasicRateTargetingDropFramesMultiThreads) {
|
||||
cfg_.rc_buf_initial_sz = 500;
|
||||
@@ -759,7 +876,7 @@ TEST_P(DatarateTestVP9Large, BasicRateTargeting444) {
|
||||
ResetModel();
|
||||
ASSERT_NO_FATAL_FAILURE(RunLoop(&video));
|
||||
ASSERT_GE(static_cast<double>(cfg_.rc_target_bitrate),
|
||||
effective_datarate_[0] * 0.85)
|
||||
effective_datarate_[0] * 0.80)
|
||||
<< " The datarate for the file exceeds the target by too much!";
|
||||
ASSERT_LE(static_cast<double>(cfg_.rc_target_bitrate),
|
||||
effective_datarate_[0] * 1.15)
|
||||
@@ -792,26 +909,29 @@ TEST_P(DatarateTestVP9Large, ChangingDropFrameThresh) {
|
||||
30, 1, 0, 140);
|
||||
|
||||
const int kDropFrameThreshTestStep = 30;
|
||||
vpx_codec_pts_t last_drop = 140;
|
||||
int last_num_drops = 0;
|
||||
for (int i = 10; i < 100; i += kDropFrameThreshTestStep) {
|
||||
cfg_.rc_dropframe_thresh = i;
|
||||
ResetModel();
|
||||
ASSERT_NO_FATAL_FAILURE(RunLoop(&video));
|
||||
ASSERT_GE(effective_datarate_[0], cfg_.rc_target_bitrate * 0.85)
|
||||
<< " The datarate for the file is lower than target by too much!";
|
||||
ASSERT_LE(effective_datarate_[0], cfg_.rc_target_bitrate * 1.15)
|
||||
<< " The datarate for the file is greater than target by too much!";
|
||||
ASSERT_LE(first_drop_, last_drop)
|
||||
<< " The first dropped frame for drop_thresh " << i
|
||||
<< " > first dropped frame for drop_thresh "
|
||||
<< i - kDropFrameThreshTestStep;
|
||||
ASSERT_GE(num_drops_, last_num_drops * 0.85)
|
||||
<< " The number of dropped frames for drop_thresh " << i
|
||||
<< " < number of dropped frames for drop_thresh "
|
||||
<< i - kDropFrameThreshTestStep;
|
||||
last_drop = first_drop_;
|
||||
last_num_drops = num_drops_;
|
||||
for (int j = 50; j <= 150; j += 100) {
|
||||
cfg_.rc_target_bitrate = j;
|
||||
vpx_codec_pts_t last_drop = 140;
|
||||
int last_num_drops = 0;
|
||||
for (int i = 10; i < 100; i += kDropFrameThreshTestStep) {
|
||||
cfg_.rc_dropframe_thresh = i;
|
||||
ResetModel();
|
||||
ASSERT_NO_FATAL_FAILURE(RunLoop(&video));
|
||||
ASSERT_GE(effective_datarate_[0], cfg_.rc_target_bitrate * 0.85)
|
||||
<< " The datarate for the file is lower than target by too much!";
|
||||
ASSERT_LE(effective_datarate_[0], cfg_.rc_target_bitrate * 1.25)
|
||||
<< " The datarate for the file is greater than target by too much!";
|
||||
ASSERT_LE(first_drop_, last_drop)
|
||||
<< " The first dropped frame for drop_thresh " << i
|
||||
<< " > first dropped frame for drop_thresh "
|
||||
<< i - kDropFrameThreshTestStep;
|
||||
ASSERT_GE(num_drops_, last_num_drops * 0.85)
|
||||
<< " The number of dropped frames for drop_thresh " << i
|
||||
<< " < number of dropped frames for drop_thresh "
|
||||
<< i - kDropFrameThreshTestStep;
|
||||
last_drop = first_drop_;
|
||||
last_num_drops = num_drops_;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -988,7 +1108,7 @@ TEST_P(DatarateTestVP9LargeDenoiser, LowNoise) {
|
||||
}
|
||||
|
||||
// Check basic datarate targeting, for a single bitrate, when denoiser is on,
|
||||
// for clip with high noise level.
|
||||
// for clip with high noise level. Use 2 threads.
|
||||
TEST_P(DatarateTestVP9LargeDenoiser, HighNoise) {
|
||||
cfg_.rc_buf_initial_sz = 500;
|
||||
cfg_.rc_buf_optimal_sz = 500;
|
||||
@@ -998,9 +1118,39 @@ TEST_P(DatarateTestVP9LargeDenoiser, HighNoise) {
|
||||
cfg_.rc_max_quantizer = 56;
|
||||
cfg_.rc_end_usage = VPX_CBR;
|
||||
cfg_.g_lag_in_frames = 0;
|
||||
cfg_.g_threads = 2;
|
||||
|
||||
::libvpx_test::Y4mVideoSource video("noisy_clip_640_360.y4m", 0, 200);
|
||||
|
||||
// For the temporal denoiser (#if CONFIG_VP9_TEMPORAL_DENOISING),
|
||||
// there is only one denoiser mode: kDenoiserOnYOnly(which is 1),
|
||||
// but may add more modes in the future.
|
||||
cfg_.rc_target_bitrate = 1000;
|
||||
ResetModel();
|
||||
// Turn on the denoiser.
|
||||
denoiser_on_ = 1;
|
||||
ASSERT_NO_FATAL_FAILURE(RunLoop(&video));
|
||||
ASSERT_GE(effective_datarate_[0], cfg_.rc_target_bitrate * 0.85)
|
||||
<< " The datarate for the file is lower than target by too much!";
|
||||
ASSERT_LE(effective_datarate_[0], cfg_.rc_target_bitrate * 1.15)
|
||||
<< " The datarate for the file is greater than target by too much!";
|
||||
}
|
||||
|
||||
// Check basic datarate targeting, for a single bitrate, when denoiser is on,
|
||||
// for 1280x720 clip with 4 threads.
|
||||
TEST_P(DatarateTestVP9LargeDenoiser, 4threads) {
|
||||
cfg_.rc_buf_initial_sz = 500;
|
||||
cfg_.rc_buf_optimal_sz = 500;
|
||||
cfg_.rc_buf_sz = 1000;
|
||||
cfg_.rc_dropframe_thresh = 1;
|
||||
cfg_.rc_min_quantizer = 2;
|
||||
cfg_.rc_max_quantizer = 56;
|
||||
cfg_.rc_end_usage = VPX_CBR;
|
||||
cfg_.g_lag_in_frames = 0;
|
||||
cfg_.g_threads = 4;
|
||||
|
||||
::libvpx_test::Y4mVideoSource video("niklas_1280_720_30.y4m", 0, 300);
|
||||
|
||||
// For the temporal denoiser (#if CONFIG_VP9_TEMPORAL_DENOISING),
|
||||
// there is only one denoiser mode: denoiserYonly(which is 1),
|
||||
// but may add more modes in the future.
|
||||
@@ -1011,7 +1161,7 @@ TEST_P(DatarateTestVP9LargeDenoiser, HighNoise) {
|
||||
ASSERT_NO_FATAL_FAILURE(RunLoop(&video));
|
||||
ASSERT_GE(effective_datarate_[0], cfg_.rc_target_bitrate * 0.85)
|
||||
<< " The datarate for the file is lower than target by too much!";
|
||||
ASSERT_LE(effective_datarate_[0], cfg_.rc_target_bitrate * 1.15)
|
||||
ASSERT_LE(effective_datarate_[0], cfg_.rc_target_bitrate * 1.29)
|
||||
<< " The datarate for the file is greater than target by too much!";
|
||||
}
|
||||
|
||||
@@ -1073,6 +1223,9 @@ class DatarateOnePassCbrSvc
|
||||
duration_ = 0.0;
|
||||
mismatch_psnr_ = 0.0;
|
||||
mismatch_nframes_ = 0;
|
||||
denoiser_on_ = 0;
|
||||
tune_content_ = 0;
|
||||
base_speed_setting_ = 5;
|
||||
}
|
||||
virtual void BeginPassHook(unsigned int /*pass*/) {}
|
||||
virtual void PreEncodeFrameHook(::libvpx_test::VideoSource *video,
|
||||
@@ -1083,17 +1236,21 @@ class DatarateOnePassCbrSvc
|
||||
svc_params_.max_quantizers[i] = 63;
|
||||
svc_params_.min_quantizers[i] = 0;
|
||||
}
|
||||
svc_params_.speed_per_layer[0] = 5;
|
||||
svc_params_.speed_per_layer[0] = base_speed_setting_;
|
||||
for (i = 1; i < VPX_SS_MAX_LAYERS; ++i) {
|
||||
svc_params_.speed_per_layer[i] = speed_setting_;
|
||||
}
|
||||
|
||||
encoder->Control(VP9E_SET_NOISE_SENSITIVITY, denoiser_on_);
|
||||
encoder->Control(VP9E_SET_SVC, 1);
|
||||
encoder->Control(VP9E_SET_SVC_PARAMETERS, &svc_params_);
|
||||
encoder->Control(VP8E_SET_CPUUSED, speed_setting_);
|
||||
encoder->Control(VP9E_SET_TILE_COLUMNS, 0);
|
||||
encoder->Control(VP8E_SET_MAX_INTRA_BITRATE_PCT, 300);
|
||||
encoder->Control(VP9E_SET_TILE_COLUMNS, (cfg_.g_threads >> 1));
|
||||
encoder->Control(VP9E_SET_ROW_MT, 1);
|
||||
encoder->Control(VP8E_SET_STATIC_THRESHOLD, 1);
|
||||
encoder->Control(VP9E_SET_TUNE_CONTENT, tune_content_);
|
||||
}
|
||||
const vpx_rational_t tb = video->timebase();
|
||||
timebase_ = static_cast<double>(tb.num) / tb.den;
|
||||
@@ -1149,6 +1306,9 @@ class DatarateOnePassCbrSvc
|
||||
int speed_setting_;
|
||||
double mismatch_psnr_;
|
||||
int mismatch_nframes_;
|
||||
int denoiser_on_;
|
||||
int tune_content_;
|
||||
int base_speed_setting_;
|
||||
};
|
||||
static void assign_layer_bitrates(vpx_codec_enc_cfg_t *const enc_cfg,
|
||||
const vpx_svc_extra_cfg_t *svc_params,
|
||||
@@ -1180,9 +1340,43 @@ static void assign_layer_bitrates(vpx_codec_enc_cfg_t *const enc_cfg,
|
||||
}
|
||||
}
|
||||
|
||||
// Check basic rate targeting for 1 pass CBR SVC: 2 spatial layers and 1
|
||||
// temporal layer, with screen content mode on and same speed setting for all
|
||||
// layers.
|
||||
TEST_P(DatarateOnePassCbrSvc, OnePassCbrSvc2SL1TLScreenContent1) {
|
||||
cfg_.rc_buf_initial_sz = 500;
|
||||
cfg_.rc_buf_optimal_sz = 500;
|
||||
cfg_.rc_buf_sz = 1000;
|
||||
cfg_.rc_min_quantizer = 0;
|
||||
cfg_.rc_max_quantizer = 63;
|
||||
cfg_.rc_end_usage = VPX_CBR;
|
||||
cfg_.g_lag_in_frames = 0;
|
||||
cfg_.ss_number_layers = 2;
|
||||
cfg_.ts_number_layers = 1;
|
||||
cfg_.ts_rate_decimator[0] = 1;
|
||||
cfg_.g_error_resilient = 1;
|
||||
cfg_.g_threads = 1;
|
||||
cfg_.temporal_layering_mode = 0;
|
||||
svc_params_.scaling_factor_num[0] = 144;
|
||||
svc_params_.scaling_factor_den[0] = 288;
|
||||
svc_params_.scaling_factor_num[1] = 288;
|
||||
svc_params_.scaling_factor_den[1] = 288;
|
||||
cfg_.rc_dropframe_thresh = 10;
|
||||
cfg_.kf_max_dist = 9999;
|
||||
::libvpx_test::Y4mVideoSource video("niklas_1280_720_30.y4m", 0, 300);
|
||||
cfg_.rc_target_bitrate = 500;
|
||||
ResetModel();
|
||||
tune_content_ = 1;
|
||||
base_speed_setting_ = speed_setting_;
|
||||
assign_layer_bitrates(&cfg_, &svc_params_, cfg_.ss_number_layers,
|
||||
cfg_.ts_number_layers, cfg_.temporal_layering_mode);
|
||||
ASSERT_NO_FATAL_FAILURE(RunLoop(&video));
|
||||
EXPECT_EQ(static_cast<unsigned int>(0), GetMismatchFrames());
|
||||
}
|
||||
|
||||
// Check basic rate targeting for 1 pass CBR SVC: 2 spatial layers and
|
||||
// 3 temporal layers. Run CIF clip with 1 thread.
|
||||
TEST_P(DatarateOnePassCbrSvc, OnePassCbrSvc2SpatialLayers) {
|
||||
TEST_P(DatarateOnePassCbrSvc, OnePassCbrSvc2SL3TL) {
|
||||
cfg_.rc_buf_initial_sz = 500;
|
||||
cfg_.rc_buf_optimal_sz = 500;
|
||||
cfg_.rc_buf_sz = 1000;
|
||||
@@ -1202,7 +1396,7 @@ TEST_P(DatarateOnePassCbrSvc, OnePassCbrSvc2SpatialLayers) {
|
||||
svc_params_.scaling_factor_den[0] = 288;
|
||||
svc_params_.scaling_factor_num[1] = 288;
|
||||
svc_params_.scaling_factor_den[1] = 288;
|
||||
cfg_.rc_dropframe_thresh = 10;
|
||||
cfg_.rc_dropframe_thresh = 0;
|
||||
cfg_.kf_max_dist = 9999;
|
||||
::libvpx_test::I420VideoSource video("hantro_collage_w352h288.yuv", 352, 288,
|
||||
30, 1, 0, 200);
|
||||
@@ -1214,17 +1408,71 @@ TEST_P(DatarateOnePassCbrSvc, OnePassCbrSvc2SpatialLayers) {
|
||||
assign_layer_bitrates(&cfg_, &svc_params_, cfg_.ss_number_layers,
|
||||
cfg_.ts_number_layers, cfg_.temporal_layering_mode);
|
||||
ASSERT_NO_FATAL_FAILURE(RunLoop(&video));
|
||||
ASSERT_GE(cfg_.rc_target_bitrate, file_datarate_ * 0.85)
|
||||
ASSERT_GE(cfg_.rc_target_bitrate, file_datarate_ * 0.78)
|
||||
<< " The datarate for the file exceeds the target by too much!";
|
||||
ASSERT_LE(cfg_.rc_target_bitrate, file_datarate_ * 1.15)
|
||||
<< " The datarate for the file is lower than the target by too much!";
|
||||
EXPECT_EQ(static_cast<unsigned int>(0), GetMismatchFrames());
|
||||
#if CONFIG_VP9_DECODER
|
||||
// Number of temporal layers > 1, so half of the frames in this SVC pattern
|
||||
// will be non-reference frame and hence encoder will avoid loopfilter.
|
||||
// Since frame dropper is off, we can expcet 100 (half of the sequence)
|
||||
// mismatched frames.
|
||||
EXPECT_EQ(static_cast<unsigned int>(100), GetMismatchFrames());
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
// Check basic rate targeting for 1 pass CBR SVC with denoising.
|
||||
// 2 spatial layers and 3 temporal layer. Run HD clip with 2 threads.
|
||||
TEST_P(DatarateOnePassCbrSvc, OnePassCbrSvc2SL3TLDenoiserOn) {
|
||||
cfg_.rc_buf_initial_sz = 500;
|
||||
cfg_.rc_buf_optimal_sz = 500;
|
||||
cfg_.rc_buf_sz = 1000;
|
||||
cfg_.rc_min_quantizer = 0;
|
||||
cfg_.rc_max_quantizer = 63;
|
||||
cfg_.rc_end_usage = VPX_CBR;
|
||||
cfg_.g_lag_in_frames = 0;
|
||||
cfg_.ss_number_layers = 2;
|
||||
cfg_.ts_number_layers = 3;
|
||||
cfg_.ts_rate_decimator[0] = 4;
|
||||
cfg_.ts_rate_decimator[1] = 2;
|
||||
cfg_.ts_rate_decimator[2] = 1;
|
||||
cfg_.g_error_resilient = 1;
|
||||
cfg_.g_threads = 2;
|
||||
cfg_.temporal_layering_mode = 3;
|
||||
svc_params_.scaling_factor_num[0] = 144;
|
||||
svc_params_.scaling_factor_den[0] = 288;
|
||||
svc_params_.scaling_factor_num[1] = 288;
|
||||
svc_params_.scaling_factor_den[1] = 288;
|
||||
cfg_.rc_dropframe_thresh = 0;
|
||||
cfg_.kf_max_dist = 9999;
|
||||
::libvpx_test::Y4mVideoSource video("niklas_1280_720_30.y4m", 0, 300);
|
||||
// TODO(marpan): Check that effective_datarate for each layer hits the
|
||||
// layer target_bitrate.
|
||||
for (int i = 600; i <= 1000; i += 200) {
|
||||
cfg_.rc_target_bitrate = i;
|
||||
ResetModel();
|
||||
denoiser_on_ = 1;
|
||||
assign_layer_bitrates(&cfg_, &svc_params_, cfg_.ss_number_layers,
|
||||
cfg_.ts_number_layers, cfg_.temporal_layering_mode);
|
||||
ASSERT_NO_FATAL_FAILURE(RunLoop(&video));
|
||||
ASSERT_GE(cfg_.rc_target_bitrate, file_datarate_ * 0.78)
|
||||
<< " The datarate for the file exceeds the target by too much!";
|
||||
ASSERT_LE(cfg_.rc_target_bitrate, file_datarate_ * 1.15)
|
||||
<< " The datarate for the file is lower than the target by too much!";
|
||||
#if CONFIG_VP9_DECODER
|
||||
// Number of temporal layers > 1, so half of the frames in this SVC pattern
|
||||
// will be non-reference frame and hence encoder will avoid loopfilter.
|
||||
// Since frame dropper is off, we can expcet 150 (half of the sequence)
|
||||
// mismatched frames.
|
||||
EXPECT_EQ(static_cast<unsigned int>(150), GetMismatchFrames());
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
// Check basic rate targeting for 1 pass CBR SVC: 2 spatial layers and 3
|
||||
// temporal layers. Run CIF clip with 1 thread, and few short key frame periods.
|
||||
TEST_P(DatarateOnePassCbrSvc, OnePassCbrSvc2SpatialLayersSmallKf) {
|
||||
TEST_P(DatarateOnePassCbrSvc, DISABLED_OnePassCbrSvc2SL3TLSmallKf) {
|
||||
cfg_.rc_buf_initial_sz = 500;
|
||||
cfg_.rc_buf_optimal_sz = 500;
|
||||
cfg_.rc_buf_sz = 1000;
|
||||
@@ -1256,17 +1504,16 @@ TEST_P(DatarateOnePassCbrSvc, OnePassCbrSvc2SpatialLayersSmallKf) {
|
||||
assign_layer_bitrates(&cfg_, &svc_params_, cfg_.ss_number_layers,
|
||||
cfg_.ts_number_layers, cfg_.temporal_layering_mode);
|
||||
ASSERT_NO_FATAL_FAILURE(RunLoop(&video));
|
||||
ASSERT_GE(cfg_.rc_target_bitrate, file_datarate_ * 0.85)
|
||||
ASSERT_GE(cfg_.rc_target_bitrate, file_datarate_ * 0.80)
|
||||
<< " The datarate for the file exceeds the target by too much!";
|
||||
ASSERT_LE(cfg_.rc_target_bitrate, file_datarate_ * 1.15)
|
||||
<< " The datarate for the file is lower than the target by too much!";
|
||||
EXPECT_EQ(static_cast<unsigned int>(0), GetMismatchFrames());
|
||||
}
|
||||
}
|
||||
|
||||
// Check basic rate targeting for 1 pass CBR SVC: 2 spatial layers and
|
||||
// 3 temporal layers. Run HD clip with 4 threads.
|
||||
TEST_P(DatarateOnePassCbrSvc, OnePassCbrSvc2SpatialLayers4threads) {
|
||||
TEST_P(DatarateOnePassCbrSvc, OnePassCbrSvc2SL3TL4Threads) {
|
||||
cfg_.rc_buf_initial_sz = 500;
|
||||
cfg_.rc_buf_optimal_sz = 500;
|
||||
cfg_.rc_buf_sz = 1000;
|
||||
@@ -1286,7 +1533,7 @@ TEST_P(DatarateOnePassCbrSvc, OnePassCbrSvc2SpatialLayers4threads) {
|
||||
svc_params_.scaling_factor_den[0] = 288;
|
||||
svc_params_.scaling_factor_num[1] = 288;
|
||||
svc_params_.scaling_factor_den[1] = 288;
|
||||
cfg_.rc_dropframe_thresh = 10;
|
||||
cfg_.rc_dropframe_thresh = 0;
|
||||
cfg_.kf_max_dist = 9999;
|
||||
::libvpx_test::Y4mVideoSource video("niklas_1280_720_30.y4m", 0, 300);
|
||||
cfg_.rc_target_bitrate = 800;
|
||||
@@ -1294,16 +1541,22 @@ TEST_P(DatarateOnePassCbrSvc, OnePassCbrSvc2SpatialLayers4threads) {
|
||||
assign_layer_bitrates(&cfg_, &svc_params_, cfg_.ss_number_layers,
|
||||
cfg_.ts_number_layers, cfg_.temporal_layering_mode);
|
||||
ASSERT_NO_FATAL_FAILURE(RunLoop(&video));
|
||||
ASSERT_GE(cfg_.rc_target_bitrate, file_datarate_ * 0.85)
|
||||
ASSERT_GE(cfg_.rc_target_bitrate, file_datarate_ * 0.78)
|
||||
<< " The datarate for the file exceeds the target by too much!";
|
||||
ASSERT_LE(cfg_.rc_target_bitrate, file_datarate_ * 1.15)
|
||||
<< " The datarate for the file is lower than the target by too much!";
|
||||
EXPECT_EQ(static_cast<unsigned int>(0), GetMismatchFrames());
|
||||
#if CONFIG_VP9_DECODER
|
||||
// Number of temporal layers > 1, so half of the frames in this SVC pattern
|
||||
// will be non-reference frame and hence encoder will avoid loopfilter.
|
||||
// Since frame dropper is off, we can expcet 150 (half of the sequence)
|
||||
// mismatched frames.
|
||||
EXPECT_EQ(static_cast<unsigned int>(150), GetMismatchFrames());
|
||||
#endif
|
||||
}
|
||||
|
||||
// Check basic rate targeting for 1 pass CBR SVC: 3 spatial layers and
|
||||
// 3 temporal layers. Run CIF clip with 1 thread.
|
||||
TEST_P(DatarateOnePassCbrSvc, OnePassCbrSvc3SpatialLayers) {
|
||||
TEST_P(DatarateOnePassCbrSvc, OnePassCbrSvc3SL3TL) {
|
||||
cfg_.rc_buf_initial_sz = 500;
|
||||
cfg_.rc_buf_optimal_sz = 500;
|
||||
cfg_.rc_buf_sz = 1000;
|
||||
@@ -1325,7 +1578,7 @@ TEST_P(DatarateOnePassCbrSvc, OnePassCbrSvc3SpatialLayers) {
|
||||
svc_params_.scaling_factor_den[1] = 288;
|
||||
svc_params_.scaling_factor_num[2] = 288;
|
||||
svc_params_.scaling_factor_den[2] = 288;
|
||||
cfg_.rc_dropframe_thresh = 10;
|
||||
cfg_.rc_dropframe_thresh = 0;
|
||||
cfg_.kf_max_dist = 9999;
|
||||
::libvpx_test::Y4mVideoSource video("niklas_1280_720_30.y4m", 0, 300);
|
||||
cfg_.rc_target_bitrate = 800;
|
||||
@@ -1333,16 +1586,22 @@ TEST_P(DatarateOnePassCbrSvc, OnePassCbrSvc3SpatialLayers) {
|
||||
assign_layer_bitrates(&cfg_, &svc_params_, cfg_.ss_number_layers,
|
||||
cfg_.ts_number_layers, cfg_.temporal_layering_mode);
|
||||
ASSERT_NO_FATAL_FAILURE(RunLoop(&video));
|
||||
ASSERT_GE(cfg_.rc_target_bitrate, file_datarate_ * 0.85)
|
||||
ASSERT_GE(cfg_.rc_target_bitrate, file_datarate_ * 0.78)
|
||||
<< " The datarate for the file exceeds the target by too much!";
|
||||
ASSERT_LE(cfg_.rc_target_bitrate, file_datarate_ * 1.22)
|
||||
<< " The datarate for the file is lower than the target by too much!";
|
||||
EXPECT_EQ(static_cast<unsigned int>(0), GetMismatchFrames());
|
||||
#if CONFIG_VP9_DECODER
|
||||
// Number of temporal layers > 1, so half of the frames in this SVC pattern
|
||||
// will be non-reference frame and hence encoder will avoid loopfilter.
|
||||
// Since frame dropper is off, we can expcet 150 (half of the sequence)
|
||||
// mismatched frames.
|
||||
EXPECT_EQ(static_cast<unsigned int>(150), GetMismatchFrames());
|
||||
#endif
|
||||
}
|
||||
|
||||
// Check basic rate targeting for 1 pass CBR SVC: 3 spatial layers and 3
|
||||
// temporal layers. Run CIF clip with 1 thread, and few short key frame periods.
|
||||
TEST_P(DatarateOnePassCbrSvc, OnePassCbrSvc3SpatialLayersSmallKf) {
|
||||
TEST_P(DatarateOnePassCbrSvc, OnePassCbrSvc3SL3TLSmallKf) {
|
||||
cfg_.rc_buf_initial_sz = 500;
|
||||
cfg_.rc_buf_optimal_sz = 500;
|
||||
cfg_.rc_buf_sz = 1000;
|
||||
@@ -1375,17 +1634,16 @@ TEST_P(DatarateOnePassCbrSvc, OnePassCbrSvc3SpatialLayersSmallKf) {
|
||||
assign_layer_bitrates(&cfg_, &svc_params_, cfg_.ss_number_layers,
|
||||
cfg_.ts_number_layers, cfg_.temporal_layering_mode);
|
||||
ASSERT_NO_FATAL_FAILURE(RunLoop(&video));
|
||||
ASSERT_GE(cfg_.rc_target_bitrate, file_datarate_ * 0.85)
|
||||
ASSERT_GE(cfg_.rc_target_bitrate, file_datarate_ * 0.80)
|
||||
<< " The datarate for the file exceeds the target by too much!";
|
||||
ASSERT_LE(cfg_.rc_target_bitrate, file_datarate_ * 1.30)
|
||||
<< " The datarate for the file is lower than the target by too much!";
|
||||
EXPECT_EQ(static_cast<unsigned int>(0), GetMismatchFrames());
|
||||
}
|
||||
}
|
||||
|
||||
// Check basic rate targeting for 1 pass CBR SVC: 3 spatial layers and
|
||||
// 3 temporal layers. Run HD clip with 4 threads.
|
||||
TEST_P(DatarateOnePassCbrSvc, OnePassCbrSvc3SpatialLayers4threads) {
|
||||
TEST_P(DatarateOnePassCbrSvc, OnePassCbrSvc3SL3TL4threads) {
|
||||
cfg_.rc_buf_initial_sz = 500;
|
||||
cfg_.rc_buf_optimal_sz = 500;
|
||||
cfg_.rc_buf_sz = 1000;
|
||||
@@ -1407,7 +1665,7 @@ TEST_P(DatarateOnePassCbrSvc, OnePassCbrSvc3SpatialLayers4threads) {
|
||||
svc_params_.scaling_factor_den[1] = 288;
|
||||
svc_params_.scaling_factor_num[2] = 288;
|
||||
svc_params_.scaling_factor_den[2] = 288;
|
||||
cfg_.rc_dropframe_thresh = 10;
|
||||
cfg_.rc_dropframe_thresh = 0;
|
||||
cfg_.kf_max_dist = 9999;
|
||||
::libvpx_test::Y4mVideoSource video("niklas_1280_720_30.y4m", 0, 300);
|
||||
cfg_.rc_target_bitrate = 800;
|
||||
@@ -1415,16 +1673,22 @@ TEST_P(DatarateOnePassCbrSvc, OnePassCbrSvc3SpatialLayers4threads) {
|
||||
assign_layer_bitrates(&cfg_, &svc_params_, cfg_.ss_number_layers,
|
||||
cfg_.ts_number_layers, cfg_.temporal_layering_mode);
|
||||
ASSERT_NO_FATAL_FAILURE(RunLoop(&video));
|
||||
ASSERT_GE(cfg_.rc_target_bitrate, file_datarate_ * 0.85)
|
||||
ASSERT_GE(cfg_.rc_target_bitrate, file_datarate_ * 0.78)
|
||||
<< " The datarate for the file exceeds the target by too much!";
|
||||
ASSERT_LE(cfg_.rc_target_bitrate, file_datarate_ * 1.22)
|
||||
<< " The datarate for the file is lower than the target by too much!";
|
||||
EXPECT_EQ(static_cast<unsigned int>(0), GetMismatchFrames());
|
||||
#if CONFIG_VP9_DECODER
|
||||
// Number of temporal layers > 1, so half of the frames in this SVC pattern
|
||||
// will be non-reference frame and hence encoder will avoid loopfilter.
|
||||
// Since frame dropper is off, we can expcet 150 (half of the sequence)
|
||||
// mismatched frames.
|
||||
EXPECT_EQ(static_cast<unsigned int>(150), GetMismatchFrames());
|
||||
#endif
|
||||
}
|
||||
|
||||
// Run SVC encoder for 1 temporal layer, 2 spatial layers, with spatial
|
||||
// downscale 5x5.
|
||||
TEST_P(DatarateOnePassCbrSvc, OnePassCbrSvc2SpatialLayers5x5MultipleRuns) {
|
||||
TEST_P(DatarateOnePassCbrSvc, OnePassCbrSvc2SL1TL5x5MultipleRuns) {
|
||||
cfg_.rc_buf_initial_sz = 500;
|
||||
cfg_.rc_buf_optimal_sz = 500;
|
||||
cfg_.rc_buf_sz = 1000;
|
||||
@@ -1442,7 +1706,7 @@ TEST_P(DatarateOnePassCbrSvc, OnePassCbrSvc2SpatialLayers5x5MultipleRuns) {
|
||||
svc_params_.scaling_factor_den[0] = 1280;
|
||||
svc_params_.scaling_factor_num[1] = 1280;
|
||||
svc_params_.scaling_factor_den[1] = 1280;
|
||||
cfg_.rc_dropframe_thresh = 0;
|
||||
cfg_.rc_dropframe_thresh = 10;
|
||||
cfg_.kf_max_dist = 999999;
|
||||
cfg_.kf_min_dist = 0;
|
||||
cfg_.ss_target_bitrate[0] = 300;
|
||||
|
||||
@@ -255,11 +255,11 @@ void iht16x16_ref(const tran_low_t *in, uint8_t *dest, int stride,
|
||||
|
||||
#if CONFIG_VP9_HIGHBITDEPTH
|
||||
void idct16x16_10(const tran_low_t *in, uint8_t *out, int stride) {
|
||||
vpx_highbd_idct16x16_256_add_c(in, out, stride, 10);
|
||||
vpx_highbd_idct16x16_256_add_c(in, CAST_TO_SHORTPTR(out), stride, 10);
|
||||
}
|
||||
|
||||
void idct16x16_12(const tran_low_t *in, uint8_t *out, int stride) {
|
||||
vpx_highbd_idct16x16_256_add_c(in, out, stride, 12);
|
||||
vpx_highbd_idct16x16_256_add_c(in, CAST_TO_SHORTPTR(out), stride, 12);
|
||||
}
|
||||
|
||||
void idct16x16_10_ref(const tran_low_t *in, uint8_t *out, int stride,
|
||||
@@ -273,36 +273,36 @@ void idct16x16_12_ref(const tran_low_t *in, uint8_t *out, int stride,
|
||||
}
|
||||
|
||||
void iht16x16_10(const tran_low_t *in, uint8_t *out, int stride, int tx_type) {
|
||||
vp9_highbd_iht16x16_256_add_c(in, out, stride, tx_type, 10);
|
||||
vp9_highbd_iht16x16_256_add_c(in, CAST_TO_SHORTPTR(out), stride, tx_type, 10);
|
||||
}
|
||||
|
||||
void iht16x16_12(const tran_low_t *in, uint8_t *out, int stride, int tx_type) {
|
||||
vp9_highbd_iht16x16_256_add_c(in, out, stride, tx_type, 12);
|
||||
vp9_highbd_iht16x16_256_add_c(in, CAST_TO_SHORTPTR(out), stride, tx_type, 12);
|
||||
}
|
||||
|
||||
#if HAVE_SSE2
|
||||
void idct16x16_10_add_10_c(const tran_low_t *in, uint8_t *out, int stride) {
|
||||
vpx_highbd_idct16x16_10_add_c(in, out, stride, 10);
|
||||
vpx_highbd_idct16x16_10_add_c(in, CAST_TO_SHORTPTR(out), stride, 10);
|
||||
}
|
||||
|
||||
void idct16x16_10_add_12_c(const tran_low_t *in, uint8_t *out, int stride) {
|
||||
vpx_highbd_idct16x16_10_add_c(in, out, stride, 12);
|
||||
vpx_highbd_idct16x16_10_add_c(in, CAST_TO_SHORTPTR(out), stride, 12);
|
||||
}
|
||||
|
||||
void idct16x16_256_add_10_sse2(const tran_low_t *in, uint8_t *out, int stride) {
|
||||
vpx_highbd_idct16x16_256_add_sse2(in, out, stride, 10);
|
||||
vpx_highbd_idct16x16_256_add_sse2(in, CAST_TO_SHORTPTR(out), stride, 10);
|
||||
}
|
||||
|
||||
void idct16x16_256_add_12_sse2(const tran_low_t *in, uint8_t *out, int stride) {
|
||||
vpx_highbd_idct16x16_256_add_sse2(in, out, stride, 12);
|
||||
vpx_highbd_idct16x16_256_add_sse2(in, CAST_TO_SHORTPTR(out), stride, 12);
|
||||
}
|
||||
|
||||
void idct16x16_10_add_10_sse2(const tran_low_t *in, uint8_t *out, int stride) {
|
||||
vpx_highbd_idct16x16_10_add_sse2(in, out, stride, 10);
|
||||
vpx_highbd_idct16x16_10_add_sse2(in, CAST_TO_SHORTPTR(out), stride, 10);
|
||||
}
|
||||
|
||||
void idct16x16_10_add_12_sse2(const tran_low_t *in, uint8_t *out, int stride) {
|
||||
vpx_highbd_idct16x16_10_add_sse2(in, out, stride, 12);
|
||||
vpx_highbd_idct16x16_10_add_sse2(in, CAST_TO_SHORTPTR(out), stride, 12);
|
||||
}
|
||||
#endif // HAVE_SSE2
|
||||
#endif // CONFIG_VP9_HIGHBITDEPTH
|
||||
@@ -353,7 +353,7 @@ class Trans16x16TestBase {
|
||||
#if CONFIG_VP9_HIGHBITDEPTH
|
||||
} else {
|
||||
ASM_REGISTER_STATE_CHECK(
|
||||
RunInvTxfm(test_temp_block, CONVERT_TO_BYTEPTR(dst16), pitch_));
|
||||
RunInvTxfm(test_temp_block, CAST_TO_BYTEPTR(dst16), pitch_));
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -475,10 +475,10 @@ class Trans16x16TestBase {
|
||||
ASM_REGISTER_STATE_CHECK(RunInvTxfm(output_ref_block, dst, pitch_));
|
||||
#if CONFIG_VP9_HIGHBITDEPTH
|
||||
} else {
|
||||
inv_txfm_ref(output_ref_block, CONVERT_TO_BYTEPTR(ref16), pitch_,
|
||||
inv_txfm_ref(output_ref_block, CAST_TO_BYTEPTR(ref16), pitch_,
|
||||
tx_type_);
|
||||
ASM_REGISTER_STATE_CHECK(
|
||||
RunInvTxfm(output_ref_block, CONVERT_TO_BYTEPTR(dst16), pitch_));
|
||||
RunInvTxfm(output_ref_block, CAST_TO_BYTEPTR(dst16), pitch_));
|
||||
#endif
|
||||
}
|
||||
if (bit_depth_ == VPX_BITS_8) {
|
||||
@@ -530,8 +530,7 @@ class Trans16x16TestBase {
|
||||
ASM_REGISTER_STATE_CHECK(RunInvTxfm(coeff, dst, 16));
|
||||
#if CONFIG_VP9_HIGHBITDEPTH
|
||||
} else {
|
||||
ASM_REGISTER_STATE_CHECK(
|
||||
RunInvTxfm(coeff, CONVERT_TO_BYTEPTR(dst16), 16));
|
||||
ASM_REGISTER_STATE_CHECK(RunInvTxfm(coeff, CAST_TO_BYTEPTR(dst16), 16));
|
||||
#endif // CONFIG_VP9_HIGHBITDEPTH
|
||||
}
|
||||
|
||||
@@ -543,8 +542,8 @@ class Trans16x16TestBase {
|
||||
const uint32_t diff = dst[j] - src[j];
|
||||
#endif // CONFIG_VP9_HIGHBITDEPTH
|
||||
const uint32_t error = diff * diff;
|
||||
EXPECT_GE(1u, error) << "Error: 16x16 IDCT has error " << error
|
||||
<< " at index " << j;
|
||||
EXPECT_GE(1u, error)
|
||||
<< "Error: 16x16 IDCT has error " << error << " at index " << j;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -585,9 +584,9 @@ class Trans16x16TestBase {
|
||||
ASM_REGISTER_STATE_CHECK(RunInvTxfm(coeff, dst, pitch_));
|
||||
} else {
|
||||
#if CONFIG_VP9_HIGHBITDEPTH
|
||||
ref_txfm(coeff, CONVERT_TO_BYTEPTR(ref16), pitch_);
|
||||
ref_txfm(coeff, CAST_TO_BYTEPTR(ref16), pitch_);
|
||||
ASM_REGISTER_STATE_CHECK(
|
||||
RunInvTxfm(coeff, CONVERT_TO_BYTEPTR(dst16), pitch_));
|
||||
RunInvTxfm(coeff, CAST_TO_BYTEPTR(dst16), pitch_));
|
||||
#endif // CONFIG_VP9_HIGHBITDEPTH
|
||||
}
|
||||
|
||||
@@ -745,66 +744,6 @@ TEST_P(InvTrans16x16DCT, CompareReference) {
|
||||
CompareInvReference(ref_txfm_, thresh_);
|
||||
}
|
||||
|
||||
class PartialTrans16x16Test : public ::testing::TestWithParam<
|
||||
std::tr1::tuple<FdctFunc, vpx_bit_depth_t> > {
|
||||
public:
|
||||
virtual ~PartialTrans16x16Test() {}
|
||||
virtual void SetUp() {
|
||||
fwd_txfm_ = GET_PARAM(0);
|
||||
bit_depth_ = GET_PARAM(1);
|
||||
}
|
||||
|
||||
virtual void TearDown() { libvpx_test::ClearSystemState(); }
|
||||
|
||||
protected:
|
||||
vpx_bit_depth_t bit_depth_;
|
||||
FdctFunc fwd_txfm_;
|
||||
};
|
||||
|
||||
TEST_P(PartialTrans16x16Test, Extremes) {
|
||||
#if CONFIG_VP9_HIGHBITDEPTH
|
||||
const int16_t maxval =
|
||||
static_cast<int16_t>(clip_pixel_highbd(1 << 30, bit_depth_));
|
||||
#else
|
||||
const int16_t maxval = 255;
|
||||
#endif
|
||||
const int minval = -maxval;
|
||||
DECLARE_ALIGNED(16, int16_t, input[kNumCoeffs]);
|
||||
DECLARE_ALIGNED(16, tran_low_t, output[kNumCoeffs]);
|
||||
|
||||
for (int i = 0; i < kNumCoeffs; ++i) input[i] = maxval;
|
||||
output[0] = 0;
|
||||
ASM_REGISTER_STATE_CHECK(fwd_txfm_(input, output, 16));
|
||||
EXPECT_EQ((maxval * kNumCoeffs) >> 1, output[0]);
|
||||
|
||||
for (int i = 0; i < kNumCoeffs; ++i) input[i] = minval;
|
||||
output[0] = 0;
|
||||
ASM_REGISTER_STATE_CHECK(fwd_txfm_(input, output, 16));
|
||||
EXPECT_EQ((minval * kNumCoeffs) >> 1, output[0]);
|
||||
}
|
||||
|
||||
TEST_P(PartialTrans16x16Test, Random) {
|
||||
#if CONFIG_VP9_HIGHBITDEPTH
|
||||
const int16_t maxval =
|
||||
static_cast<int16_t>(clip_pixel_highbd(1 << 30, bit_depth_));
|
||||
#else
|
||||
const int16_t maxval = 255;
|
||||
#endif
|
||||
DECLARE_ALIGNED(16, int16_t, input[kNumCoeffs]);
|
||||
DECLARE_ALIGNED(16, tran_low_t, output[kNumCoeffs]);
|
||||
ACMRandom rnd(ACMRandom::DeterministicSeed());
|
||||
|
||||
int sum = 0;
|
||||
for (int i = 0; i < kNumCoeffs; ++i) {
|
||||
const int val = (i & 1) ? -rnd(maxval + 1) : rnd(maxval + 1);
|
||||
input[i] = val;
|
||||
sum += val;
|
||||
}
|
||||
output[0] = 0;
|
||||
ASM_REGISTER_STATE_CHECK(fwd_txfm_(input, output, 16));
|
||||
EXPECT_EQ(sum >> 1, output[0]);
|
||||
}
|
||||
|
||||
using std::tr1::make_tuple;
|
||||
|
||||
#if CONFIG_VP9_HIGHBITDEPTH
|
||||
@@ -837,11 +776,6 @@ INSTANTIATE_TEST_CASE_P(
|
||||
make_tuple(&vp9_fht16x16_c, &vp9_iht16x16_256_add_c, 1, VPX_BITS_8),
|
||||
make_tuple(&vp9_fht16x16_c, &vp9_iht16x16_256_add_c, 2, VPX_BITS_8),
|
||||
make_tuple(&vp9_fht16x16_c, &vp9_iht16x16_256_add_c, 3, VPX_BITS_8)));
|
||||
INSTANTIATE_TEST_CASE_P(
|
||||
C, PartialTrans16x16Test,
|
||||
::testing::Values(make_tuple(&vpx_highbd_fdct16x16_1_c, VPX_BITS_8),
|
||||
make_tuple(&vpx_highbd_fdct16x16_1_c, VPX_BITS_10),
|
||||
make_tuple(&vpx_highbd_fdct16x16_1_c, VPX_BITS_12)));
|
||||
#else
|
||||
INSTANTIATE_TEST_CASE_P(
|
||||
C, Trans16x16HT,
|
||||
@@ -850,17 +784,14 @@ INSTANTIATE_TEST_CASE_P(
|
||||
make_tuple(&vp9_fht16x16_c, &vp9_iht16x16_256_add_c, 1, VPX_BITS_8),
|
||||
make_tuple(&vp9_fht16x16_c, &vp9_iht16x16_256_add_c, 2, VPX_BITS_8),
|
||||
make_tuple(&vp9_fht16x16_c, &vp9_iht16x16_256_add_c, 3, VPX_BITS_8)));
|
||||
INSTANTIATE_TEST_CASE_P(C, PartialTrans16x16Test,
|
||||
::testing::Values(make_tuple(&vpx_fdct16x16_1_c,
|
||||
VPX_BITS_8)));
|
||||
#endif // CONFIG_VP9_HIGHBITDEPTH
|
||||
|
||||
#if HAVE_NEON && !CONFIG_VP9_HIGHBITDEPTH && !CONFIG_EMULATE_HARDWARE
|
||||
#if HAVE_NEON && !CONFIG_EMULATE_HARDWARE
|
||||
INSTANTIATE_TEST_CASE_P(
|
||||
NEON, Trans16x16DCT,
|
||||
::testing::Values(make_tuple(&vpx_fdct16x16_c, &vpx_idct16x16_256_add_neon,
|
||||
0, VPX_BITS_8)));
|
||||
#endif
|
||||
::testing::Values(make_tuple(&vpx_fdct16x16_neon,
|
||||
&vpx_idct16x16_256_add_neon, 0, VPX_BITS_8)));
|
||||
#endif // HAVE_NEON && !CONFIG_EMULATE_HARDWARE
|
||||
|
||||
#if HAVE_SSE2 && !CONFIG_VP9_HIGHBITDEPTH && !CONFIG_EMULATE_HARDWARE
|
||||
INSTANTIATE_TEST_CASE_P(
|
||||
@@ -877,9 +808,6 @@ INSTANTIATE_TEST_CASE_P(
|
||||
2, VPX_BITS_8),
|
||||
make_tuple(&vp9_fht16x16_sse2, &vp9_iht16x16_256_add_sse2,
|
||||
3, VPX_BITS_8)));
|
||||
INSTANTIATE_TEST_CASE_P(SSE2, PartialTrans16x16Test,
|
||||
::testing::Values(make_tuple(&vpx_fdct16x16_1_sse2,
|
||||
VPX_BITS_8)));
|
||||
#endif // HAVE_SSE2 && !CONFIG_VP9_HIGHBITDEPTH && !CONFIG_EMULATE_HARDWARE
|
||||
|
||||
#if HAVE_SSE2 && CONFIG_VP9_HIGHBITDEPTH && !CONFIG_EMULATE_HARDWARE
|
||||
@@ -914,9 +842,6 @@ INSTANTIATE_TEST_CASE_P(
|
||||
&idct16x16_10_add_12_sse2, 3167, VPX_BITS_12),
|
||||
make_tuple(&idct16x16_12, &idct16x16_256_add_12_sse2,
|
||||
3167, VPX_BITS_12)));
|
||||
INSTANTIATE_TEST_CASE_P(SSE2, PartialTrans16x16Test,
|
||||
::testing::Values(make_tuple(&vpx_fdct16x16_1_sse2,
|
||||
VPX_BITS_8)));
|
||||
#endif // HAVE_SSE2 && CONFIG_VP9_HIGHBITDEPTH && !CONFIG_EMULATE_HARDWARE
|
||||
|
||||
#if HAVE_MSA && !CONFIG_VP9_HIGHBITDEPTH && !CONFIG_EMULATE_HARDWARE
|
||||
@@ -932,8 +857,12 @@ INSTANTIATE_TEST_CASE_P(
|
||||
make_tuple(&vp9_fht16x16_msa, &vp9_iht16x16_256_add_msa, 2, VPX_BITS_8),
|
||||
make_tuple(&vp9_fht16x16_msa, &vp9_iht16x16_256_add_msa, 3,
|
||||
VPX_BITS_8)));
|
||||
INSTANTIATE_TEST_CASE_P(MSA, PartialTrans16x16Test,
|
||||
::testing::Values(make_tuple(&vpx_fdct16x16_1_msa,
|
||||
VPX_BITS_8)));
|
||||
#endif // HAVE_MSA && !CONFIG_VP9_HIGHBITDEPTH && !CONFIG_EMULATE_HARDWARE
|
||||
|
||||
#if HAVE_VSX && !CONFIG_VP9_HIGHBITDEPTH && !CONFIG_EMULATE_HARDWARE
|
||||
INSTANTIATE_TEST_CASE_P(VSX, Trans16x16DCT,
|
||||
::testing::Values(make_tuple(&vpx_fdct16x16_c,
|
||||
&vpx_idct16x16_256_add_vsx,
|
||||
0, VPX_BITS_8)));
|
||||
#endif // HAVE_VSX && !CONFIG_VP9_HIGHBITDEPTH && !CONFIG_EMULATE_HARDWARE
|
||||
} // namespace
|
||||
|
||||
@@ -71,11 +71,11 @@ typedef std::tr1::tuple<FwdTxfmFunc, InvTxfmFunc, int, vpx_bit_depth_t>
|
||||
|
||||
#if CONFIG_VP9_HIGHBITDEPTH
|
||||
void idct32x32_10(const tran_low_t *in, uint8_t *out, int stride) {
|
||||
vpx_highbd_idct32x32_1024_add_c(in, out, stride, 10);
|
||||
vpx_highbd_idct32x32_1024_add_c(in, CAST_TO_SHORTPTR(out), stride, 10);
|
||||
}
|
||||
|
||||
void idct32x32_12(const tran_low_t *in, uint8_t *out, int stride) {
|
||||
vpx_highbd_idct32x32_1024_add_c(in, out, stride, 12);
|
||||
vpx_highbd_idct32x32_1024_add_c(in, CAST_TO_SHORTPTR(out), stride, 12);
|
||||
}
|
||||
#endif // CONFIG_VP9_HIGHBITDEPTH
|
||||
|
||||
@@ -137,7 +137,7 @@ TEST_P(Trans32x32Test, AccuracyCheck) {
|
||||
#if CONFIG_VP9_HIGHBITDEPTH
|
||||
} else {
|
||||
ASM_REGISTER_STATE_CHECK(
|
||||
inv_txfm_(test_temp_block, CONVERT_TO_BYTEPTR(dst16), 32));
|
||||
inv_txfm_(test_temp_block, CAST_TO_BYTEPTR(dst16), 32));
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -275,7 +275,7 @@ TEST_P(Trans32x32Test, InverseAccuracy) {
|
||||
ASM_REGISTER_STATE_CHECK(inv_txfm_(coeff, dst, 32));
|
||||
#if CONFIG_VP9_HIGHBITDEPTH
|
||||
} else {
|
||||
ASM_REGISTER_STATE_CHECK(inv_txfm_(coeff, CONVERT_TO_BYTEPTR(dst16), 32));
|
||||
ASM_REGISTER_STATE_CHECK(inv_txfm_(coeff, CAST_TO_BYTEPTR(dst16), 32));
|
||||
#endif
|
||||
}
|
||||
for (int j = 0; j < kNumCoeffs; ++j) {
|
||||
@@ -292,67 +292,6 @@ TEST_P(Trans32x32Test, InverseAccuracy) {
|
||||
}
|
||||
}
|
||||
|
||||
class PartialTrans32x32Test
|
||||
: public ::testing::TestWithParam<
|
||||
std::tr1::tuple<FwdTxfmFunc, vpx_bit_depth_t> > {
|
||||
public:
|
||||
virtual ~PartialTrans32x32Test() {}
|
||||
virtual void SetUp() {
|
||||
fwd_txfm_ = GET_PARAM(0);
|
||||
bit_depth_ = GET_PARAM(1);
|
||||
}
|
||||
|
||||
virtual void TearDown() { libvpx_test::ClearSystemState(); }
|
||||
|
||||
protected:
|
||||
vpx_bit_depth_t bit_depth_;
|
||||
FwdTxfmFunc fwd_txfm_;
|
||||
};
|
||||
|
||||
TEST_P(PartialTrans32x32Test, Extremes) {
|
||||
#if CONFIG_VP9_HIGHBITDEPTH
|
||||
const int16_t maxval =
|
||||
static_cast<int16_t>(clip_pixel_highbd(1 << 30, bit_depth_));
|
||||
#else
|
||||
const int16_t maxval = 255;
|
||||
#endif
|
||||
const int minval = -maxval;
|
||||
DECLARE_ALIGNED(16, int16_t, input[kNumCoeffs]);
|
||||
DECLARE_ALIGNED(16, tran_low_t, output[kNumCoeffs]);
|
||||
|
||||
for (int i = 0; i < kNumCoeffs; ++i) input[i] = maxval;
|
||||
output[0] = 0;
|
||||
ASM_REGISTER_STATE_CHECK(fwd_txfm_(input, output, 32));
|
||||
EXPECT_EQ((maxval * kNumCoeffs) >> 3, output[0]);
|
||||
|
||||
for (int i = 0; i < kNumCoeffs; ++i) input[i] = minval;
|
||||
output[0] = 0;
|
||||
ASM_REGISTER_STATE_CHECK(fwd_txfm_(input, output, 32));
|
||||
EXPECT_EQ((minval * kNumCoeffs) >> 3, output[0]);
|
||||
}
|
||||
|
||||
TEST_P(PartialTrans32x32Test, Random) {
|
||||
#if CONFIG_VP9_HIGHBITDEPTH
|
||||
const int16_t maxval =
|
||||
static_cast<int16_t>(clip_pixel_highbd(1 << 30, bit_depth_));
|
||||
#else
|
||||
const int16_t maxval = 255;
|
||||
#endif
|
||||
DECLARE_ALIGNED(16, int16_t, input[kNumCoeffs]);
|
||||
DECLARE_ALIGNED(16, tran_low_t, output[kNumCoeffs]);
|
||||
ACMRandom rnd(ACMRandom::DeterministicSeed());
|
||||
|
||||
int sum = 0;
|
||||
for (int i = 0; i < kNumCoeffs; ++i) {
|
||||
const int val = (i & 1) ? -rnd(maxval + 1) : rnd(maxval + 1);
|
||||
input[i] = val;
|
||||
sum += val;
|
||||
}
|
||||
output[0] = 0;
|
||||
ASM_REGISTER_STATE_CHECK(fwd_txfm_(input, output, 32));
|
||||
EXPECT_EQ(sum >> 3, output[0]);
|
||||
}
|
||||
|
||||
using std::tr1::make_tuple;
|
||||
|
||||
#if CONFIG_VP9_HIGHBITDEPTH
|
||||
@@ -366,11 +305,6 @@ INSTANTIATE_TEST_CASE_P(
|
||||
make_tuple(&vpx_fdct32x32_c, &vpx_idct32x32_1024_add_c, 0, VPX_BITS_8),
|
||||
make_tuple(&vpx_fdct32x32_rd_c, &vpx_idct32x32_1024_add_c, 1,
|
||||
VPX_BITS_8)));
|
||||
INSTANTIATE_TEST_CASE_P(
|
||||
C, PartialTrans32x32Test,
|
||||
::testing::Values(make_tuple(&vpx_highbd_fdct32x32_1_c, VPX_BITS_8),
|
||||
make_tuple(&vpx_highbd_fdct32x32_1_c, VPX_BITS_10),
|
||||
make_tuple(&vpx_highbd_fdct32x32_1_c, VPX_BITS_12)));
|
||||
#else
|
||||
INSTANTIATE_TEST_CASE_P(
|
||||
C, Trans32x32Test,
|
||||
@@ -378,19 +312,16 @@ INSTANTIATE_TEST_CASE_P(
|
||||
VPX_BITS_8),
|
||||
make_tuple(&vpx_fdct32x32_rd_c, &vpx_idct32x32_1024_add_c,
|
||||
1, VPX_BITS_8)));
|
||||
INSTANTIATE_TEST_CASE_P(C, PartialTrans32x32Test,
|
||||
::testing::Values(make_tuple(&vpx_fdct32x32_1_c,
|
||||
VPX_BITS_8)));
|
||||
#endif // CONFIG_VP9_HIGHBITDEPTH
|
||||
|
||||
#if HAVE_NEON && !CONFIG_VP9_HIGHBITDEPTH && !CONFIG_EMULATE_HARDWARE
|
||||
#if HAVE_NEON && !CONFIG_EMULATE_HARDWARE
|
||||
INSTANTIATE_TEST_CASE_P(
|
||||
NEON, Trans32x32Test,
|
||||
::testing::Values(make_tuple(&vpx_fdct32x32_c, &vpx_idct32x32_1024_add_neon,
|
||||
0, VPX_BITS_8),
|
||||
make_tuple(&vpx_fdct32x32_rd_c,
|
||||
::testing::Values(make_tuple(&vpx_fdct32x32_neon,
|
||||
&vpx_idct32x32_1024_add_neon, 0, VPX_BITS_8),
|
||||
make_tuple(&vpx_fdct32x32_rd_neon,
|
||||
&vpx_idct32x32_1024_add_neon, 1, VPX_BITS_8)));
|
||||
#endif // HAVE_NEON && !CONFIG_VP9_HIGHBITDEPTH && !CONFIG_EMULATE_HARDWARE
|
||||
#endif // HAVE_NEON && !CONFIG_EMULATE_HARDWARE
|
||||
|
||||
#if HAVE_SSE2 && !CONFIG_VP9_HIGHBITDEPTH && !CONFIG_EMULATE_HARDWARE
|
||||
INSTANTIATE_TEST_CASE_P(
|
||||
@@ -399,9 +330,6 @@ INSTANTIATE_TEST_CASE_P(
|
||||
&vpx_idct32x32_1024_add_sse2, 0, VPX_BITS_8),
|
||||
make_tuple(&vpx_fdct32x32_rd_sse2,
|
||||
&vpx_idct32x32_1024_add_sse2, 1, VPX_BITS_8)));
|
||||
INSTANTIATE_TEST_CASE_P(SSE2, PartialTrans32x32Test,
|
||||
::testing::Values(make_tuple(&vpx_fdct32x32_1_sse2,
|
||||
VPX_BITS_8)));
|
||||
#endif // HAVE_SSE2 && !CONFIG_VP9_HIGHBITDEPTH && !CONFIG_EMULATE_HARDWARE
|
||||
|
||||
#if HAVE_SSE2 && CONFIG_VP9_HIGHBITDEPTH && !CONFIG_EMULATE_HARDWARE
|
||||
@@ -418,9 +346,6 @@ INSTANTIATE_TEST_CASE_P(
|
||||
VPX_BITS_8),
|
||||
make_tuple(&vpx_fdct32x32_rd_sse2, &vpx_idct32x32_1024_add_c, 1,
|
||||
VPX_BITS_8)));
|
||||
INSTANTIATE_TEST_CASE_P(SSE2, PartialTrans32x32Test,
|
||||
::testing::Values(make_tuple(&vpx_fdct32x32_1_sse2,
|
||||
VPX_BITS_8)));
|
||||
#endif // HAVE_SSE2 && CONFIG_VP9_HIGHBITDEPTH && !CONFIG_EMULATE_HARDWARE
|
||||
|
||||
#if HAVE_AVX2 && !CONFIG_VP9_HIGHBITDEPTH && !CONFIG_EMULATE_HARDWARE
|
||||
@@ -439,8 +364,14 @@ INSTANTIATE_TEST_CASE_P(
|
||||
&vpx_idct32x32_1024_add_msa, 0, VPX_BITS_8),
|
||||
make_tuple(&vpx_fdct32x32_rd_msa,
|
||||
&vpx_idct32x32_1024_add_msa, 1, VPX_BITS_8)));
|
||||
INSTANTIATE_TEST_CASE_P(MSA, PartialTrans32x32Test,
|
||||
::testing::Values(make_tuple(&vpx_fdct32x32_1_msa,
|
||||
VPX_BITS_8)));
|
||||
#endif // HAVE_MSA && !CONFIG_VP9_HIGHBITDEPTH && !CONFIG_EMULATE_HARDWARE
|
||||
|
||||
#if HAVE_VSX && !CONFIG_VP9_HIGHBITDEPTH && !CONFIG_EMULATE_HARDWARE
|
||||
INSTANTIATE_TEST_CASE_P(
|
||||
VSX, Trans32x32Test,
|
||||
::testing::Values(make_tuple(&vpx_fdct32x32_c, &vpx_idct32x32_1024_add_vsx,
|
||||
0, VPX_BITS_8),
|
||||
make_tuple(&vpx_fdct32x32_rd_c,
|
||||
&vpx_idct32x32_1024_add_vsx, 1, VPX_BITS_8)));
|
||||
#endif // HAVE_VSX && !CONFIG_VP9_HIGHBITDEPTH && !CONFIG_EMULATE_HARDWARE
|
||||
} // namespace
|
||||
|
||||
169
test/dct_partial_test.cc
Normal file
169
test/dct_partial_test.cc
Normal file
@@ -0,0 +1,169 @@
|
||||
/*
|
||||
* Copyright (c) 2017 The WebM project authors. All Rights Reserved.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license
|
||||
* that can be found in the LICENSE file in the root of the source
|
||||
* tree. An additional intellectual property rights grant can be found
|
||||
* in the file PATENTS. All contributing project authors may
|
||||
* be found in the AUTHORS file in the root of the source tree.
|
||||
*/
|
||||
|
||||
#include <math.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <limits>
|
||||
|
||||
#include "third_party/googletest/src/include/gtest/gtest.h"
|
||||
|
||||
#include "./vpx_dsp_rtcd.h"
|
||||
#include "test/acm_random.h"
|
||||
#include "test/buffer.h"
|
||||
#include "test/clear_system_state.h"
|
||||
#include "test/register_state_check.h"
|
||||
#include "test/util.h"
|
||||
#include "vpx/vpx_codec.h"
|
||||
#include "vpx/vpx_integer.h"
|
||||
#include "vpx_dsp/vpx_dsp_common.h"
|
||||
|
||||
using libvpx_test::ACMRandom;
|
||||
using libvpx_test::Buffer;
|
||||
using std::tr1::tuple;
|
||||
using std::tr1::make_tuple;
|
||||
|
||||
namespace {
|
||||
typedef void (*PartialFdctFunc)(const int16_t *in, tran_low_t *out, int stride);
|
||||
|
||||
typedef tuple<PartialFdctFunc, int /* size */, vpx_bit_depth_t>
|
||||
PartialFdctParam;
|
||||
|
||||
tran_low_t partial_fdct_ref(const Buffer<int16_t> &in, int size) {
|
||||
int64_t sum = 0;
|
||||
for (int y = 0; y < size; ++y) {
|
||||
for (int x = 0; x < size; ++x) {
|
||||
sum += in.TopLeftPixel()[y * in.stride() + x];
|
||||
}
|
||||
}
|
||||
|
||||
switch (size) {
|
||||
case 4: sum *= 2; break;
|
||||
case 8: /*sum = sum;*/ break;
|
||||
case 16: sum >>= 1; break;
|
||||
case 32: sum >>= 3; break;
|
||||
}
|
||||
|
||||
return static_cast<tran_low_t>(sum);
|
||||
}
|
||||
|
||||
class PartialFdctTest : public ::testing::TestWithParam<PartialFdctParam> {
|
||||
public:
|
||||
PartialFdctTest() {
|
||||
fwd_txfm_ = GET_PARAM(0);
|
||||
size_ = GET_PARAM(1);
|
||||
bit_depth_ = GET_PARAM(2);
|
||||
}
|
||||
|
||||
virtual void TearDown() { libvpx_test::ClearSystemState(); }
|
||||
|
||||
protected:
|
||||
void RunTest() {
|
||||
ACMRandom rnd(ACMRandom::DeterministicSeed());
|
||||
const int16_t maxvalue =
|
||||
clip_pixel_highbd(std::numeric_limits<int16_t>::max(), bit_depth_);
|
||||
const int16_t minvalue = -maxvalue;
|
||||
Buffer<int16_t> input_block =
|
||||
Buffer<int16_t>(size_, size_, 8, size_ == 4 ? 0 : 16);
|
||||
ASSERT_TRUE(input_block.Init());
|
||||
Buffer<tran_low_t> output_block = Buffer<tran_low_t>(size_, size_, 0, 16);
|
||||
ASSERT_TRUE(output_block.Init());
|
||||
|
||||
for (int i = 0; i < 100; ++i) {
|
||||
if (i == 0) {
|
||||
input_block.Set(maxvalue);
|
||||
} else if (i == 1) {
|
||||
input_block.Set(minvalue);
|
||||
} else {
|
||||
input_block.Set(&rnd, minvalue, maxvalue);
|
||||
}
|
||||
|
||||
ASM_REGISTER_STATE_CHECK(fwd_txfm_(input_block.TopLeftPixel(),
|
||||
output_block.TopLeftPixel(),
|
||||
input_block.stride()));
|
||||
|
||||
EXPECT_EQ(partial_fdct_ref(input_block, size_),
|
||||
output_block.TopLeftPixel()[0]);
|
||||
}
|
||||
}
|
||||
|
||||
PartialFdctFunc fwd_txfm_;
|
||||
vpx_bit_depth_t bit_depth_;
|
||||
int size_;
|
||||
};
|
||||
|
||||
TEST_P(PartialFdctTest, PartialFdctTest) { RunTest(); }
|
||||
|
||||
#if CONFIG_VP9_HIGHBITDEPTH
|
||||
INSTANTIATE_TEST_CASE_P(
|
||||
C, PartialFdctTest,
|
||||
::testing::Values(make_tuple(&vpx_highbd_fdct32x32_1_c, 32, VPX_BITS_12),
|
||||
make_tuple(&vpx_highbd_fdct32x32_1_c, 32, VPX_BITS_10),
|
||||
make_tuple(&vpx_fdct32x32_1_c, 32, VPX_BITS_8),
|
||||
make_tuple(&vpx_highbd_fdct16x16_1_c, 16, VPX_BITS_12),
|
||||
make_tuple(&vpx_highbd_fdct16x16_1_c, 16, VPX_BITS_10),
|
||||
make_tuple(&vpx_fdct16x16_1_c, 16, VPX_BITS_8),
|
||||
make_tuple(&vpx_highbd_fdct8x8_1_c, 8, VPX_BITS_12),
|
||||
make_tuple(&vpx_highbd_fdct8x8_1_c, 8, VPX_BITS_10),
|
||||
make_tuple(&vpx_fdct8x8_1_c, 8, VPX_BITS_8),
|
||||
make_tuple(&vpx_fdct4x4_1_c, 4, VPX_BITS_8)));
|
||||
#else
|
||||
INSTANTIATE_TEST_CASE_P(
|
||||
C, PartialFdctTest,
|
||||
::testing::Values(make_tuple(&vpx_fdct32x32_1_c, 32, VPX_BITS_8),
|
||||
make_tuple(&vpx_fdct16x16_1_c, 16, VPX_BITS_8),
|
||||
make_tuple(&vpx_fdct8x8_1_c, 8, VPX_BITS_8),
|
||||
make_tuple(&vpx_fdct4x4_1_c, 4, VPX_BITS_8)));
|
||||
#endif // CONFIG_VP9_HIGHBITDEPTH
|
||||
|
||||
#if HAVE_SSE2
|
||||
INSTANTIATE_TEST_CASE_P(
|
||||
SSE2, PartialFdctTest,
|
||||
::testing::Values(make_tuple(&vpx_fdct32x32_1_sse2, 32, VPX_BITS_8),
|
||||
make_tuple(&vpx_fdct16x16_1_sse2, 16, VPX_BITS_8),
|
||||
make_tuple(&vpx_fdct8x8_1_sse2, 8, VPX_BITS_8),
|
||||
make_tuple(&vpx_fdct4x4_1_sse2, 4, VPX_BITS_8)));
|
||||
#endif // HAVE_SSE2
|
||||
|
||||
#if HAVE_NEON
|
||||
#if CONFIG_VP9_HIGHBITDEPTH
|
||||
INSTANTIATE_TEST_CASE_P(
|
||||
NEON, PartialFdctTest,
|
||||
::testing::Values(make_tuple(&vpx_fdct32x32_1_neon, 32, VPX_BITS_8),
|
||||
make_tuple(&vpx_fdct16x16_1_neon, 16, VPX_BITS_8),
|
||||
make_tuple(&vpx_fdct8x8_1_neon, 8, VPX_BITS_12),
|
||||
make_tuple(&vpx_fdct8x8_1_neon, 8, VPX_BITS_10),
|
||||
make_tuple(&vpx_fdct8x8_1_neon, 8, VPX_BITS_8),
|
||||
make_tuple(&vpx_fdct4x4_1_neon, 4, VPX_BITS_8)));
|
||||
#else
|
||||
INSTANTIATE_TEST_CASE_P(
|
||||
NEON, PartialFdctTest,
|
||||
::testing::Values(make_tuple(&vpx_fdct32x32_1_neon, 32, VPX_BITS_8),
|
||||
make_tuple(&vpx_fdct16x16_1_neon, 16, VPX_BITS_8),
|
||||
make_tuple(&vpx_fdct8x8_1_neon, 8, VPX_BITS_8),
|
||||
make_tuple(&vpx_fdct4x4_1_neon, 4, VPX_BITS_8)));
|
||||
#endif // CONFIG_VP9_HIGHBITDEPTH
|
||||
#endif // HAVE_NEON
|
||||
|
||||
#if HAVE_MSA
|
||||
#if CONFIG_VP9_HIGHBITDEPTH
|
||||
INSTANTIATE_TEST_CASE_P(MSA, PartialFdctTest,
|
||||
::testing::Values(make_tuple(&vpx_fdct8x8_1_msa, 8,
|
||||
VPX_BITS_8)));
|
||||
#else // !CONFIG_VP9_HIGHBITDEPTH
|
||||
INSTANTIATE_TEST_CASE_P(
|
||||
MSA, PartialFdctTest,
|
||||
::testing::Values(make_tuple(&vpx_fdct32x32_1_msa, 32, VPX_BITS_8),
|
||||
make_tuple(&vpx_fdct16x16_1_msa, 16, VPX_BITS_8),
|
||||
make_tuple(&vpx_fdct8x8_1_msa, 8, VPX_BITS_8)));
|
||||
#endif // CONFIG_VP9_HIGHBITDEPTH
|
||||
#endif // HAVE_MSA
|
||||
} // namespace
|
||||
737
test/dct_test.cc
Normal file
737
test/dct_test.cc
Normal file
@@ -0,0 +1,737 @@
|
||||
/*
|
||||
* Copyright (c) 2017 The WebM project authors. All Rights Reserved.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license
|
||||
* that can be found in the LICENSE file in the root of the source
|
||||
* tree. An additional intellectual property rights grant can be found
|
||||
* in the file PATENTS. All contributing project authors may
|
||||
* be found in the AUTHORS file in the root of the source tree.
|
||||
*/
|
||||
|
||||
#include <math.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "third_party/googletest/src/include/gtest/gtest.h"
|
||||
|
||||
#include "./vp9_rtcd.h"
|
||||
#include "./vpx_dsp_rtcd.h"
|
||||
#include "test/acm_random.h"
|
||||
#include "test/buffer.h"
|
||||
#include "test/clear_system_state.h"
|
||||
#include "test/register_state_check.h"
|
||||
#include "test/util.h"
|
||||
#include "vp9/common/vp9_entropy.h"
|
||||
#include "vpx/vpx_codec.h"
|
||||
#include "vpx/vpx_integer.h"
|
||||
#include "vpx_ports/mem.h"
|
||||
|
||||
using libvpx_test::ACMRandom;
|
||||
using libvpx_test::Buffer;
|
||||
using std::tr1::tuple;
|
||||
using std::tr1::make_tuple;
|
||||
|
||||
namespace {
|
||||
typedef void (*FdctFunc)(const int16_t *in, tran_low_t *out, int stride);
|
||||
typedef void (*IdctFunc)(const tran_low_t *in, uint8_t *out, int stride);
|
||||
typedef void (*FhtFunc)(const int16_t *in, tran_low_t *out, int stride,
|
||||
int tx_type);
|
||||
typedef void (*FhtFuncRef)(const Buffer<int16_t> &in, Buffer<tran_low_t> *out,
|
||||
int size, int tx_type);
|
||||
typedef void (*IhtFunc)(const tran_low_t *in, uint8_t *out, int stride,
|
||||
int tx_type);
|
||||
|
||||
/* forward transform, inverse transform, size, transform type, bit depth */
|
||||
typedef tuple<FdctFunc, IdctFunc, int, int, vpx_bit_depth_t> DctParam;
|
||||
typedef tuple<FhtFunc, IhtFunc, int, int, vpx_bit_depth_t> HtParam;
|
||||
|
||||
void fdct_ref(const Buffer<int16_t> &in, Buffer<tran_low_t> *out, int size,
|
||||
int /*tx_type*/) {
|
||||
const int16_t *i = in.TopLeftPixel();
|
||||
const int i_stride = in.stride();
|
||||
tran_low_t *o = out->TopLeftPixel();
|
||||
if (size == 4) {
|
||||
vpx_fdct4x4_c(i, o, i_stride);
|
||||
} else if (size == 8) {
|
||||
vpx_fdct8x8_c(i, o, i_stride);
|
||||
} else if (size == 16) {
|
||||
vpx_fdct16x16_c(i, o, i_stride);
|
||||
} else if (size == 32) {
|
||||
vpx_fdct32x32_c(i, o, i_stride);
|
||||
}
|
||||
}
|
||||
|
||||
void fht_ref(const Buffer<int16_t> &in, Buffer<tran_low_t> *out, int size,
|
||||
int tx_type) {
|
||||
const int16_t *i = in.TopLeftPixel();
|
||||
const int i_stride = in.stride();
|
||||
tran_low_t *o = out->TopLeftPixel();
|
||||
if (size == 4) {
|
||||
vp9_fht4x4_c(i, o, i_stride, tx_type);
|
||||
} else if (size == 8) {
|
||||
vp9_fht8x8_c(i, o, i_stride, tx_type);
|
||||
} else if (size == 16) {
|
||||
vp9_fht16x16_c(i, o, i_stride, tx_type);
|
||||
}
|
||||
}
|
||||
|
||||
void fwht_ref(const Buffer<int16_t> &in, Buffer<tran_low_t> *out, int size,
|
||||
int /*tx_type*/) {
|
||||
ASSERT_EQ(size, 4);
|
||||
vp9_fwht4x4_c(in.TopLeftPixel(), out->TopLeftPixel(), in.stride());
|
||||
}
|
||||
|
||||
#if CONFIG_VP9_HIGHBITDEPTH
|
||||
#define idctNxN(n, coeffs, bitdepth) \
|
||||
void idct##n##x##n##_##bitdepth(const tran_low_t *in, uint8_t *out, \
|
||||
int stride) { \
|
||||
vpx_highbd_idct##n##x##n##_##coeffs##_add_c(in, CAST_TO_SHORTPTR(out), \
|
||||
stride, bitdepth); \
|
||||
}
|
||||
|
||||
idctNxN(4, 16, 10);
|
||||
idctNxN(4, 16, 12);
|
||||
idctNxN(8, 64, 10);
|
||||
idctNxN(8, 64, 12);
|
||||
idctNxN(16, 256, 10);
|
||||
idctNxN(16, 256, 12);
|
||||
idctNxN(32, 1024, 10);
|
||||
idctNxN(32, 1024, 12);
|
||||
|
||||
#define ihtNxN(n, coeffs, bitdepth) \
|
||||
void iht##n##x##n##_##bitdepth(const tran_low_t *in, uint8_t *out, \
|
||||
int stride, int tx_type) { \
|
||||
vp9_highbd_iht##n##x##n##_##coeffs##_add_c(in, CAST_TO_SHORTPTR(out), \
|
||||
stride, tx_type, bitdepth); \
|
||||
}
|
||||
|
||||
ihtNxN(4, 16, 10);
|
||||
ihtNxN(4, 16, 12);
|
||||
ihtNxN(8, 64, 10);
|
||||
ihtNxN(8, 64, 12);
|
||||
ihtNxN(16, 256, 10);
|
||||
// ihtNxN(16, 256, 12);
|
||||
|
||||
void iwht4x4_10(const tran_low_t *in, uint8_t *out, int stride) {
|
||||
vpx_highbd_iwht4x4_16_add_c(in, CAST_TO_SHORTPTR(out), stride, 10);
|
||||
}
|
||||
|
||||
void iwht4x4_12(const tran_low_t *in, uint8_t *out, int stride) {
|
||||
vpx_highbd_iwht4x4_16_add_c(in, CAST_TO_SHORTPTR(out), stride, 12);
|
||||
}
|
||||
#endif // CONFIG_VP9_HIGHBITDEPTH
|
||||
|
||||
class TransTestBase {
|
||||
public:
|
||||
virtual void TearDown() { libvpx_test::ClearSystemState(); }
|
||||
|
||||
protected:
|
||||
virtual void RunFwdTxfm(const Buffer<int16_t> &in,
|
||||
Buffer<tran_low_t> *out) = 0;
|
||||
|
||||
virtual void RunInvTxfm(const Buffer<tran_low_t> &in, uint8_t *out) = 0;
|
||||
|
||||
void RunAccuracyCheck(int limit) {
|
||||
ACMRandom rnd(ACMRandom::DeterministicSeed());
|
||||
Buffer<int16_t> test_input_block =
|
||||
Buffer<int16_t>(size_, size_, 8, size_ == 4 ? 0 : 16);
|
||||
ASSERT_TRUE(test_input_block.Init());
|
||||
Buffer<tran_low_t> test_temp_block =
|
||||
Buffer<tran_low_t>(size_, size_, 0, 16);
|
||||
ASSERT_TRUE(test_temp_block.Init());
|
||||
Buffer<uint8_t> dst = Buffer<uint8_t>(size_, size_, 0, 16);
|
||||
ASSERT_TRUE(dst.Init());
|
||||
Buffer<uint8_t> src = Buffer<uint8_t>(size_, size_, 0, 16);
|
||||
ASSERT_TRUE(src.Init());
|
||||
#if CONFIG_VP9_HIGHBITDEPTH
|
||||
Buffer<uint16_t> dst16 = Buffer<uint16_t>(size_, size_, 0, 16);
|
||||
ASSERT_TRUE(dst16.Init());
|
||||
Buffer<uint16_t> src16 = Buffer<uint16_t>(size_, size_, 0, 16);
|
||||
ASSERT_TRUE(src16.Init());
|
||||
#endif // CONFIG_VP9_HIGHBITDEPTH
|
||||
uint32_t max_error = 0;
|
||||
int64_t total_error = 0;
|
||||
const int count_test_block = 10000;
|
||||
for (int i = 0; i < count_test_block; ++i) {
|
||||
if (bit_depth_ == 8) {
|
||||
src.Set(&rnd, &ACMRandom::Rand8);
|
||||
dst.Set(&rnd, &ACMRandom::Rand8);
|
||||
// Initialize a test block with input range [-255, 255].
|
||||
for (int h = 0; h < size_; ++h) {
|
||||
for (int w = 0; w < size_; ++w) {
|
||||
test_input_block.TopLeftPixel()[h * test_input_block.stride() + w] =
|
||||
src.TopLeftPixel()[h * src.stride() + w] -
|
||||
dst.TopLeftPixel()[h * dst.stride() + w];
|
||||
}
|
||||
}
|
||||
#if CONFIG_VP9_HIGHBITDEPTH
|
||||
} else {
|
||||
src16.Set(&rnd, 0, max_pixel_value_);
|
||||
dst16.Set(&rnd, 0, max_pixel_value_);
|
||||
for (int h = 0; h < size_; ++h) {
|
||||
for (int w = 0; w < size_; ++w) {
|
||||
test_input_block.TopLeftPixel()[h * test_input_block.stride() + w] =
|
||||
src16.TopLeftPixel()[h * src16.stride() + w] -
|
||||
dst16.TopLeftPixel()[h * dst16.stride() + w];
|
||||
}
|
||||
}
|
||||
#endif // CONFIG_VP9_HIGHBITDEPTH
|
||||
}
|
||||
|
||||
ASM_REGISTER_STATE_CHECK(RunFwdTxfm(test_input_block, &test_temp_block));
|
||||
if (bit_depth_ == VPX_BITS_8) {
|
||||
ASM_REGISTER_STATE_CHECK(
|
||||
RunInvTxfm(test_temp_block, dst.TopLeftPixel()));
|
||||
#if CONFIG_VP9_HIGHBITDEPTH
|
||||
} else {
|
||||
ASM_REGISTER_STATE_CHECK(
|
||||
RunInvTxfm(test_temp_block, CAST_TO_BYTEPTR(dst16.TopLeftPixel())));
|
||||
#endif // CONFIG_VP9_HIGHBITDEPTH
|
||||
}
|
||||
|
||||
for (int h = 0; h < size_; ++h) {
|
||||
for (int w = 0; w < size_; ++w) {
|
||||
int diff;
|
||||
#if CONFIG_VP9_HIGHBITDEPTH
|
||||
if (bit_depth_ != 8) {
|
||||
diff = dst16.TopLeftPixel()[h * dst16.stride() + w] -
|
||||
src16.TopLeftPixel()[h * src16.stride() + w];
|
||||
} else {
|
||||
#endif // CONFIG_VP9_HIGHBITDEPTH
|
||||
diff = dst.TopLeftPixel()[h * dst.stride() + w] -
|
||||
src.TopLeftPixel()[h * src.stride() + w];
|
||||
#if CONFIG_VP9_HIGHBITDEPTH
|
||||
}
|
||||
#endif // CONFIG_VP9_HIGHBITDEPTH
|
||||
const uint32_t error = diff * diff;
|
||||
if (max_error < error) max_error = error;
|
||||
total_error += error;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
EXPECT_GE(static_cast<uint32_t>(limit), max_error)
|
||||
<< "Error: 4x4 FHT/IHT has an individual round trip error > " << limit;
|
||||
|
||||
EXPECT_GE(count_test_block * limit, total_error)
|
||||
<< "Error: 4x4 FHT/IHT has average round trip error > " << limit
|
||||
<< " per block";
|
||||
}
|
||||
|
||||
void RunCoeffCheck() {
|
||||
ACMRandom rnd(ACMRandom::DeterministicSeed());
|
||||
const int count_test_block = 5000;
|
||||
Buffer<int16_t> input_block =
|
||||
Buffer<int16_t>(size_, size_, 8, size_ == 4 ? 0 : 16);
|
||||
ASSERT_TRUE(input_block.Init());
|
||||
Buffer<tran_low_t> output_ref_block = Buffer<tran_low_t>(size_, size_, 0);
|
||||
ASSERT_TRUE(output_ref_block.Init());
|
||||
Buffer<tran_low_t> output_block = Buffer<tran_low_t>(size_, size_, 0, 16);
|
||||
ASSERT_TRUE(output_block.Init());
|
||||
|
||||
for (int i = 0; i < count_test_block; ++i) {
|
||||
// Initialize a test block with input range [-max_pixel_value_,
|
||||
// max_pixel_value_].
|
||||
input_block.Set(&rnd, -max_pixel_value_, max_pixel_value_);
|
||||
|
||||
fwd_txfm_ref(input_block, &output_ref_block, size_, tx_type_);
|
||||
ASM_REGISTER_STATE_CHECK(RunFwdTxfm(input_block, &output_block));
|
||||
|
||||
// The minimum quant value is 4.
|
||||
EXPECT_TRUE(output_block.CheckValues(output_ref_block));
|
||||
if (::testing::Test::HasFailure()) {
|
||||
printf("Size: %d Transform type: %d\n", size_, tx_type_);
|
||||
output_block.PrintDifference(output_ref_block);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void RunMemCheck() {
|
||||
ACMRandom rnd(ACMRandom::DeterministicSeed());
|
||||
const int count_test_block = 5000;
|
||||
Buffer<int16_t> input_extreme_block =
|
||||
Buffer<int16_t>(size_, size_, 8, size_ == 4 ? 0 : 16);
|
||||
ASSERT_TRUE(input_extreme_block.Init());
|
||||
Buffer<tran_low_t> output_ref_block = Buffer<tran_low_t>(size_, size_, 0);
|
||||
ASSERT_TRUE(output_ref_block.Init());
|
||||
Buffer<tran_low_t> output_block = Buffer<tran_low_t>(size_, size_, 0, 16);
|
||||
ASSERT_TRUE(output_block.Init());
|
||||
|
||||
for (int i = 0; i < count_test_block; ++i) {
|
||||
// Initialize a test block with -max_pixel_value_ or max_pixel_value_.
|
||||
if (i == 0) {
|
||||
input_extreme_block.Set(max_pixel_value_);
|
||||
} else if (i == 1) {
|
||||
input_extreme_block.Set(-max_pixel_value_);
|
||||
} else {
|
||||
for (int h = 0; h < size_; ++h) {
|
||||
for (int w = 0; w < size_; ++w) {
|
||||
input_extreme_block
|
||||
.TopLeftPixel()[h * input_extreme_block.stride() + w] =
|
||||
rnd.Rand8() % 2 ? max_pixel_value_ : -max_pixel_value_;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fwd_txfm_ref(input_extreme_block, &output_ref_block, size_, tx_type_);
|
||||
ASM_REGISTER_STATE_CHECK(RunFwdTxfm(input_extreme_block, &output_block));
|
||||
|
||||
// The minimum quant value is 4.
|
||||
EXPECT_TRUE(output_block.CheckValues(output_ref_block));
|
||||
for (int h = 0; h < size_; ++h) {
|
||||
for (int w = 0; w < size_; ++w) {
|
||||
EXPECT_GE(
|
||||
4 * DCT_MAX_VALUE << (bit_depth_ - 8),
|
||||
abs(output_block.TopLeftPixel()[h * output_block.stride() + w]))
|
||||
<< "Error: 4x4 FDCT has coefficient larger than "
|
||||
"4*DCT_MAX_VALUE"
|
||||
<< " at " << w << "," << h;
|
||||
if (::testing::Test::HasFailure()) {
|
||||
printf("Size: %d Transform type: %d\n", size_, tx_type_);
|
||||
output_block.DumpBuffer();
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void RunInvAccuracyCheck(int limit) {
|
||||
ACMRandom rnd(ACMRandom::DeterministicSeed());
|
||||
const int count_test_block = 1000;
|
||||
Buffer<int16_t> in = Buffer<int16_t>(size_, size_, 4);
|
||||
ASSERT_TRUE(in.Init());
|
||||
Buffer<tran_low_t> coeff = Buffer<tran_low_t>(size_, size_, 0, 16);
|
||||
ASSERT_TRUE(coeff.Init());
|
||||
Buffer<uint8_t> dst = Buffer<uint8_t>(size_, size_, 0, 16);
|
||||
ASSERT_TRUE(dst.Init());
|
||||
Buffer<uint8_t> src = Buffer<uint8_t>(size_, size_, 0);
|
||||
ASSERT_TRUE(src.Init());
|
||||
Buffer<uint16_t> dst16 = Buffer<uint16_t>(size_, size_, 0, 16);
|
||||
ASSERT_TRUE(dst16.Init());
|
||||
Buffer<uint16_t> src16 = Buffer<uint16_t>(size_, size_, 0);
|
||||
ASSERT_TRUE(src16.Init());
|
||||
|
||||
for (int i = 0; i < count_test_block; ++i) {
|
||||
// Initialize a test block with input range [-max_pixel_value_,
|
||||
// max_pixel_value_].
|
||||
if (bit_depth_ == VPX_BITS_8) {
|
||||
src.Set(&rnd, &ACMRandom::Rand8);
|
||||
dst.Set(&rnd, &ACMRandom::Rand8);
|
||||
for (int h = 0; h < size_; ++h) {
|
||||
for (int w = 0; w < size_; ++w) {
|
||||
in.TopLeftPixel()[h * in.stride() + w] =
|
||||
src.TopLeftPixel()[h * src.stride() + w] -
|
||||
dst.TopLeftPixel()[h * dst.stride() + w];
|
||||
}
|
||||
}
|
||||
#if CONFIG_VP9_HIGHBITDEPTH
|
||||
} else {
|
||||
src16.Set(&rnd, 0, max_pixel_value_);
|
||||
dst16.Set(&rnd, 0, max_pixel_value_);
|
||||
for (int h = 0; h < size_; ++h) {
|
||||
for (int w = 0; w < size_; ++w) {
|
||||
in.TopLeftPixel()[h * in.stride() + w] =
|
||||
src16.TopLeftPixel()[h * src16.stride() + w] -
|
||||
dst16.TopLeftPixel()[h * dst16.stride() + w];
|
||||
}
|
||||
}
|
||||
#endif // CONFIG_VP9_HIGHBITDEPTH
|
||||
}
|
||||
|
||||
fwd_txfm_ref(in, &coeff, size_, tx_type_);
|
||||
|
||||
if (bit_depth_ == VPX_BITS_8) {
|
||||
ASM_REGISTER_STATE_CHECK(RunInvTxfm(coeff, dst.TopLeftPixel()));
|
||||
#if CONFIG_VP9_HIGHBITDEPTH
|
||||
} else {
|
||||
ASM_REGISTER_STATE_CHECK(
|
||||
RunInvTxfm(coeff, CAST_TO_BYTEPTR(dst16.TopLeftPixel())));
|
||||
#endif // CONFIG_VP9_HIGHBITDEPTH
|
||||
}
|
||||
|
||||
for (int h = 0; h < size_; ++h) {
|
||||
for (int w = 0; w < size_; ++w) {
|
||||
int diff;
|
||||
#if CONFIG_VP9_HIGHBITDEPTH
|
||||
if (bit_depth_ != 8) {
|
||||
diff = dst16.TopLeftPixel()[h * dst16.stride() + w] -
|
||||
src16.TopLeftPixel()[h * src16.stride() + w];
|
||||
} else {
|
||||
#endif // CONFIG_VP9_HIGHBITDEPTH
|
||||
diff = dst.TopLeftPixel()[h * dst.stride() + w] -
|
||||
src.TopLeftPixel()[h * src.stride() + w];
|
||||
#if CONFIG_VP9_HIGHBITDEPTH
|
||||
}
|
||||
#endif // CONFIG_VP9_HIGHBITDEPTH
|
||||
const uint32_t error = diff * diff;
|
||||
EXPECT_GE(static_cast<uint32_t>(limit), error)
|
||||
<< "Error: " << size_ << "x" << size_ << " IDCT has error "
|
||||
<< error << " at " << w << "," << h;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
FhtFuncRef fwd_txfm_ref;
|
||||
vpx_bit_depth_t bit_depth_;
|
||||
int tx_type_;
|
||||
int max_pixel_value_;
|
||||
int size_;
|
||||
};
|
||||
|
||||
class TransDCT : public TransTestBase,
|
||||
public ::testing::TestWithParam<DctParam> {
|
||||
public:
|
||||
TransDCT() {
|
||||
fwd_txfm_ref = fdct_ref;
|
||||
fwd_txfm_ = GET_PARAM(0);
|
||||
inv_txfm_ = GET_PARAM(1);
|
||||
size_ = GET_PARAM(2);
|
||||
tx_type_ = GET_PARAM(3);
|
||||
bit_depth_ = GET_PARAM(4);
|
||||
max_pixel_value_ = (1 << bit_depth_) - 1;
|
||||
}
|
||||
|
||||
protected:
|
||||
void RunFwdTxfm(const Buffer<int16_t> &in, Buffer<tran_low_t> *out) {
|
||||
fwd_txfm_(in.TopLeftPixel(), out->TopLeftPixel(), in.stride());
|
||||
}
|
||||
|
||||
void RunInvTxfm(const Buffer<tran_low_t> &in, uint8_t *out) {
|
||||
inv_txfm_(in.TopLeftPixel(), out, in.stride());
|
||||
}
|
||||
|
||||
FdctFunc fwd_txfm_;
|
||||
IdctFunc inv_txfm_;
|
||||
};
|
||||
|
||||
TEST_P(TransDCT, AccuracyCheck) { RunAccuracyCheck(1); }
|
||||
|
||||
TEST_P(TransDCT, CoeffCheck) { RunCoeffCheck(); }
|
||||
|
||||
TEST_P(TransDCT, MemCheck) { RunMemCheck(); }
|
||||
|
||||
TEST_P(TransDCT, InvAccuracyCheck) { RunInvAccuracyCheck(1); }
|
||||
|
||||
#if CONFIG_VP9_HIGHBITDEPTH
|
||||
INSTANTIATE_TEST_CASE_P(
|
||||
C, TransDCT,
|
||||
::testing::Values(
|
||||
make_tuple(&vpx_highbd_fdct32x32_c, &idct32x32_10, 32, 0, VPX_BITS_10),
|
||||
make_tuple(&vpx_highbd_fdct32x32_c, &idct32x32_12, 32, 0, VPX_BITS_10),
|
||||
make_tuple(&vpx_fdct32x32_c, &vpx_idct32x32_1024_add_c, 32, 0,
|
||||
VPX_BITS_8),
|
||||
make_tuple(&vpx_highbd_fdct16x16_c, &idct16x16_10, 16, 0, VPX_BITS_10),
|
||||
make_tuple(&vpx_highbd_fdct16x16_c, &idct16x16_12, 16, 0, VPX_BITS_10),
|
||||
make_tuple(&vpx_fdct16x16_c, &vpx_idct16x16_256_add_c, 16, 0,
|
||||
VPX_BITS_8),
|
||||
make_tuple(&vpx_highbd_fdct8x8_c, &idct8x8_10, 8, 0, VPX_BITS_10),
|
||||
make_tuple(&vpx_highbd_fdct8x8_c, &idct8x8_12, 8, 0, VPX_BITS_10),
|
||||
make_tuple(&vpx_fdct8x8_c, &vpx_idct8x8_64_add_c, 8, 0, VPX_BITS_8),
|
||||
make_tuple(&vpx_highbd_fdct4x4_c, &idct4x4_10, 4, 0, VPX_BITS_10),
|
||||
make_tuple(&vpx_highbd_fdct4x4_c, &idct4x4_12, 4, 0, VPX_BITS_12),
|
||||
make_tuple(&vpx_fdct4x4_c, &vpx_idct4x4_16_add_c, 4, 0, VPX_BITS_8)));
|
||||
#else
|
||||
INSTANTIATE_TEST_CASE_P(
|
||||
C, TransDCT,
|
||||
::testing::Values(
|
||||
make_tuple(&vpx_fdct32x32_c, &vpx_idct32x32_1024_add_c, 32, 0,
|
||||
VPX_BITS_8),
|
||||
make_tuple(&vpx_fdct16x16_c, &vpx_idct16x16_256_add_c, 16, 0,
|
||||
VPX_BITS_8),
|
||||
make_tuple(&vpx_fdct8x8_c, &vpx_idct8x8_64_add_c, 8, 0, VPX_BITS_8),
|
||||
make_tuple(&vpx_fdct4x4_c, &vpx_idct4x4_16_add_c, 4, 0, VPX_BITS_8)));
|
||||
#endif // CONFIG_VP9_HIGHBITDEPTH
|
||||
|
||||
#if HAVE_SSE2
|
||||
#if !CONFIG_EMULATE_HARDWARE
|
||||
#if CONFIG_VP9_HIGHBITDEPTH
|
||||
/* TODO:(johannkoenig) Determine why these fail AccuracyCheck
|
||||
make_tuple(&vpx_highbd_fdct32x32_sse2, &idct32x32_12, 32, 0, VPX_BITS_12),
|
||||
make_tuple(&vpx_highbd_fdct16x16_sse2, &idct16x16_12, 16, 0, VPX_BITS_12),
|
||||
*/
|
||||
INSTANTIATE_TEST_CASE_P(
|
||||
SSE2, TransDCT,
|
||||
::testing::Values(
|
||||
make_tuple(&vpx_highbd_fdct32x32_sse2, &idct32x32_10, 32, 0,
|
||||
VPX_BITS_10),
|
||||
make_tuple(&vpx_fdct32x32_sse2, &vpx_idct32x32_1024_add_sse2, 32, 0,
|
||||
VPX_BITS_8),
|
||||
make_tuple(&vpx_highbd_fdct16x16_sse2, &idct16x16_10, 16, 0,
|
||||
VPX_BITS_10),
|
||||
make_tuple(&vpx_fdct16x16_sse2, &vpx_idct16x16_256_add_sse2, 16, 0,
|
||||
VPX_BITS_8),
|
||||
make_tuple(&vpx_highbd_fdct8x8_sse2, &idct8x8_10, 8, 0, VPX_BITS_10),
|
||||
make_tuple(&vpx_highbd_fdct8x8_sse2, &idct8x8_12, 8, 0, VPX_BITS_12),
|
||||
make_tuple(&vpx_fdct8x8_sse2, &vpx_idct8x8_64_add_sse2, 8, 0,
|
||||
VPX_BITS_8),
|
||||
make_tuple(&vpx_highbd_fdct4x4_sse2, &idct4x4_10, 4, 0, VPX_BITS_10),
|
||||
make_tuple(&vpx_highbd_fdct4x4_sse2, &idct4x4_12, 4, 0, VPX_BITS_12),
|
||||
make_tuple(&vpx_fdct4x4_sse2, &vpx_idct4x4_16_add_sse2, 4, 0,
|
||||
VPX_BITS_8)));
|
||||
#else
|
||||
INSTANTIATE_TEST_CASE_P(
|
||||
SSE2, TransDCT,
|
||||
::testing::Values(make_tuple(&vpx_fdct32x32_sse2,
|
||||
&vpx_idct32x32_1024_add_sse2, 32, 0,
|
||||
VPX_BITS_8),
|
||||
make_tuple(&vpx_fdct16x16_sse2,
|
||||
&vpx_idct16x16_256_add_sse2, 16, 0,
|
||||
VPX_BITS_8),
|
||||
make_tuple(&vpx_fdct8x8_sse2, &vpx_idct8x8_64_add_sse2, 8,
|
||||
0, VPX_BITS_8),
|
||||
make_tuple(&vpx_fdct4x4_sse2, &vpx_idct4x4_16_add_sse2, 4,
|
||||
0, VPX_BITS_8)));
|
||||
#endif // CONFIG_VP9_HIGHBITDEPTH
|
||||
#endif // !CONFIG_EMULATE_HARDWARE
|
||||
#endif // HAVE_SSE2
|
||||
|
||||
#if !CONFIG_VP9_HIGHBITDEPTH
|
||||
#if HAVE_SSSE3 && !CONFIG_EMULATE_HARDWARE
|
||||
#if !ARCH_X86_64
|
||||
// TODO(johannkoenig): high bit depth fdct8x8.
|
||||
INSTANTIATE_TEST_CASE_P(
|
||||
SSSE3, TransDCT,
|
||||
::testing::Values(make_tuple(&vpx_fdct32x32_c, &vpx_idct32x32_1024_add_sse2,
|
||||
32, 0, VPX_BITS_8),
|
||||
make_tuple(&vpx_fdct8x8_c, &vpx_idct8x8_64_add_sse2, 8, 0,
|
||||
VPX_BITS_8)));
|
||||
#else
|
||||
// vpx_fdct8x8_ssse3 is only available in 64 bit builds.
|
||||
INSTANTIATE_TEST_CASE_P(
|
||||
SSSE3, TransDCT,
|
||||
::testing::Values(make_tuple(&vpx_fdct32x32_c, &vpx_idct32x32_1024_add_sse2,
|
||||
32, 0, VPX_BITS_8),
|
||||
make_tuple(&vpx_fdct8x8_ssse3, &vpx_idct8x8_64_add_sse2,
|
||||
8, 0, VPX_BITS_8)));
|
||||
#endif // !ARCH_X86_64
|
||||
#endif // HAVE_SSSE3 && !CONFIG_EMULATE_HARDWARE
|
||||
#endif // !CONFIG_VP9_HIGHBITDEPTH
|
||||
|
||||
#if !CONFIG_VP9_HIGHBITDEPTH && HAVE_AVX2 && !CONFIG_EMULATE_HARDWARE
|
||||
// TODO(johannkoenig): high bit depth fdct32x32.
|
||||
INSTANTIATE_TEST_CASE_P(
|
||||
AVX2, TransDCT, ::testing::Values(make_tuple(&vpx_fdct32x32_avx2,
|
||||
&vpx_idct32x32_1024_add_sse2,
|
||||
32, 0, VPX_BITS_8)));
|
||||
|
||||
#endif // !CONFIG_VP9_HIGHBITDEPTH && HAVE_AVX2 && !CONFIG_EMULATE_HARDWARE
|
||||
|
||||
#if HAVE_NEON
|
||||
#if !CONFIG_EMULATE_HARDWARE
|
||||
INSTANTIATE_TEST_CASE_P(
|
||||
NEON, TransDCT,
|
||||
::testing::Values(make_tuple(&vpx_fdct32x32_neon,
|
||||
&vpx_idct32x32_1024_add_neon, 32, 0,
|
||||
VPX_BITS_8),
|
||||
make_tuple(&vpx_fdct16x16_neon,
|
||||
&vpx_idct16x16_256_add_neon, 16, 0,
|
||||
VPX_BITS_8),
|
||||
make_tuple(&vpx_fdct8x8_neon, &vpx_idct8x8_64_add_neon, 8,
|
||||
0, VPX_BITS_8),
|
||||
make_tuple(&vpx_fdct4x4_neon, &vpx_idct4x4_16_add_neon, 4,
|
||||
0, VPX_BITS_8)));
|
||||
#endif // !CONFIG_EMULATE_HARDWARE
|
||||
#endif // HAVE_NEON
|
||||
|
||||
#if HAVE_MSA
|
||||
#if !CONFIG_VP9_HIGHBITDEPTH
|
||||
#if !CONFIG_EMULATE_HARDWARE
|
||||
INSTANTIATE_TEST_CASE_P(
|
||||
MSA, TransDCT,
|
||||
::testing::Values(
|
||||
make_tuple(&vpx_fdct32x32_msa, &vpx_idct32x32_1024_add_msa, 32, 0,
|
||||
VPX_BITS_8),
|
||||
make_tuple(&vpx_fdct16x16_msa, &vpx_idct16x16_256_add_msa, 16, 0,
|
||||
VPX_BITS_8),
|
||||
make_tuple(&vpx_fdct8x8_msa, &vpx_idct8x8_64_add_msa, 8, 0, VPX_BITS_8),
|
||||
make_tuple(&vpx_fdct4x4_msa, &vpx_idct4x4_16_add_msa, 4, 0,
|
||||
VPX_BITS_8)));
|
||||
#endif // !CONFIG_EMULATE_HARDWARE
|
||||
#endif // !CONFIG_VP9_HIGHBITDEPTH
|
||||
#endif // HAVE_MSA
|
||||
|
||||
#if HAVE_VSX && !CONFIG_VP9_HIGHBITDEPTH && !CONFIG_EMULATE_HARDWARE
|
||||
INSTANTIATE_TEST_CASE_P(VSX, TransDCT,
|
||||
::testing::Values(make_tuple(&vpx_fdct4x4_c,
|
||||
&vpx_idct4x4_16_add_vsx, 4,
|
||||
0, VPX_BITS_8)));
|
||||
#endif // HAVE_VSX && !CONFIG_VP9_HIGHBITDEPTH && !CONFIG_EMULATE_HARDWARE
|
||||
|
||||
class TransHT : public TransTestBase, public ::testing::TestWithParam<HtParam> {
|
||||
public:
|
||||
TransHT() {
|
||||
fwd_txfm_ref = fht_ref;
|
||||
fwd_txfm_ = GET_PARAM(0);
|
||||
inv_txfm_ = GET_PARAM(1);
|
||||
size_ = GET_PARAM(2);
|
||||
tx_type_ = GET_PARAM(3);
|
||||
bit_depth_ = GET_PARAM(4);
|
||||
max_pixel_value_ = (1 << bit_depth_) - 1;
|
||||
}
|
||||
|
||||
protected:
|
||||
void RunFwdTxfm(const Buffer<int16_t> &in, Buffer<tran_low_t> *out) {
|
||||
fwd_txfm_(in.TopLeftPixel(), out->TopLeftPixel(), in.stride(), tx_type_);
|
||||
}
|
||||
|
||||
void RunInvTxfm(const Buffer<tran_low_t> &in, uint8_t *out) {
|
||||
inv_txfm_(in.TopLeftPixel(), out, in.stride(), tx_type_);
|
||||
}
|
||||
|
||||
FhtFunc fwd_txfm_;
|
||||
IhtFunc inv_txfm_;
|
||||
};
|
||||
|
||||
TEST_P(TransHT, AccuracyCheck) { RunAccuracyCheck(1); }
|
||||
|
||||
TEST_P(TransHT, CoeffCheck) { RunCoeffCheck(); }
|
||||
|
||||
TEST_P(TransHT, MemCheck) { RunMemCheck(); }
|
||||
|
||||
TEST_P(TransHT, InvAccuracyCheck) { RunInvAccuracyCheck(1); }
|
||||
|
||||
/* TODO:(johannkoenig) Determine why these fail AccuracyCheck
|
||||
make_tuple(&vp9_highbd_fht16x16_c, &iht16x16_12, 16, 0, VPX_BITS_12),
|
||||
make_tuple(&vp9_highbd_fht16x16_c, &iht16x16_12, 16, 1, VPX_BITS_12),
|
||||
make_tuple(&vp9_highbd_fht16x16_c, &iht16x16_12, 16, 2, VPX_BITS_12),
|
||||
make_tuple(&vp9_highbd_fht16x16_c, &iht16x16_12, 16, 3, VPX_BITS_12),
|
||||
*/
|
||||
#if CONFIG_VP9_HIGHBITDEPTH
|
||||
INSTANTIATE_TEST_CASE_P(
|
||||
C, TransHT,
|
||||
::testing::Values(
|
||||
make_tuple(&vp9_highbd_fht16x16_c, &iht16x16_10, 16, 0, VPX_BITS_10),
|
||||
make_tuple(&vp9_highbd_fht16x16_c, &iht16x16_10, 16, 1, VPX_BITS_10),
|
||||
make_tuple(&vp9_highbd_fht16x16_c, &iht16x16_10, 16, 2, VPX_BITS_10),
|
||||
make_tuple(&vp9_highbd_fht16x16_c, &iht16x16_10, 16, 3, VPX_BITS_10),
|
||||
make_tuple(&vp9_fht16x16_c, &vp9_iht16x16_256_add_c, 16, 0, VPX_BITS_8),
|
||||
make_tuple(&vp9_fht16x16_c, &vp9_iht16x16_256_add_c, 16, 1, VPX_BITS_8),
|
||||
make_tuple(&vp9_fht16x16_c, &vp9_iht16x16_256_add_c, 16, 2, VPX_BITS_8),
|
||||
make_tuple(&vp9_fht16x16_c, &vp9_iht16x16_256_add_c, 16, 3, VPX_BITS_8),
|
||||
make_tuple(&vp9_highbd_fht8x8_c, &iht8x8_10, 8, 0, VPX_BITS_10),
|
||||
make_tuple(&vp9_highbd_fht8x8_c, &iht8x8_10, 8, 1, VPX_BITS_10),
|
||||
make_tuple(&vp9_highbd_fht8x8_c, &iht8x8_10, 8, 2, VPX_BITS_10),
|
||||
make_tuple(&vp9_highbd_fht8x8_c, &iht8x8_10, 8, 3, VPX_BITS_10),
|
||||
make_tuple(&vp9_highbd_fht8x8_c, &iht8x8_12, 8, 0, VPX_BITS_12),
|
||||
make_tuple(&vp9_highbd_fht8x8_c, &iht8x8_12, 8, 1, VPX_BITS_12),
|
||||
make_tuple(&vp9_highbd_fht8x8_c, &iht8x8_12, 8, 2, VPX_BITS_12),
|
||||
make_tuple(&vp9_highbd_fht8x8_c, &iht8x8_12, 8, 3, VPX_BITS_12),
|
||||
make_tuple(&vp9_fht8x8_c, &vp9_iht8x8_64_add_c, 8, 0, VPX_BITS_8),
|
||||
make_tuple(&vp9_fht8x8_c, &vp9_iht8x8_64_add_c, 8, 1, VPX_BITS_8),
|
||||
make_tuple(&vp9_fht8x8_c, &vp9_iht8x8_64_add_c, 8, 2, VPX_BITS_8),
|
||||
make_tuple(&vp9_fht8x8_c, &vp9_iht8x8_64_add_c, 8, 3, VPX_BITS_8),
|
||||
make_tuple(&vp9_highbd_fht4x4_c, &iht4x4_10, 4, 0, VPX_BITS_10),
|
||||
make_tuple(&vp9_highbd_fht4x4_c, &iht4x4_10, 4, 1, VPX_BITS_10),
|
||||
make_tuple(&vp9_highbd_fht4x4_c, &iht4x4_10, 4, 2, VPX_BITS_10),
|
||||
make_tuple(&vp9_highbd_fht4x4_c, &iht4x4_10, 4, 3, VPX_BITS_10),
|
||||
make_tuple(&vp9_highbd_fht4x4_c, &iht4x4_12, 4, 0, VPX_BITS_12),
|
||||
make_tuple(&vp9_highbd_fht4x4_c, &iht4x4_12, 4, 1, VPX_BITS_12),
|
||||
make_tuple(&vp9_highbd_fht4x4_c, &iht4x4_12, 4, 2, VPX_BITS_12),
|
||||
make_tuple(&vp9_highbd_fht4x4_c, &iht4x4_12, 4, 3, VPX_BITS_12),
|
||||
make_tuple(&vp9_fht4x4_c, &vp9_iht4x4_16_add_c, 4, 0, VPX_BITS_8),
|
||||
make_tuple(&vp9_fht4x4_c, &vp9_iht4x4_16_add_c, 4, 1, VPX_BITS_8),
|
||||
make_tuple(&vp9_fht4x4_c, &vp9_iht4x4_16_add_c, 4, 2, VPX_BITS_8),
|
||||
make_tuple(&vp9_fht4x4_c, &vp9_iht4x4_16_add_c, 4, 3, VPX_BITS_8)));
|
||||
#else
|
||||
INSTANTIATE_TEST_CASE_P(
|
||||
C, TransHT,
|
||||
::testing::Values(
|
||||
make_tuple(&vp9_fht16x16_c, &vp9_iht16x16_256_add_c, 16, 0, VPX_BITS_8),
|
||||
make_tuple(&vp9_fht16x16_c, &vp9_iht16x16_256_add_c, 16, 1, VPX_BITS_8),
|
||||
make_tuple(&vp9_fht16x16_c, &vp9_iht16x16_256_add_c, 16, 2, VPX_BITS_8),
|
||||
make_tuple(&vp9_fht16x16_c, &vp9_iht16x16_256_add_c, 16, 3, VPX_BITS_8),
|
||||
|
||||
make_tuple(&vp9_fht8x8_c, &vp9_iht8x8_64_add_c, 8, 0, VPX_BITS_8),
|
||||
make_tuple(&vp9_fht8x8_c, &vp9_iht8x8_64_add_c, 8, 1, VPX_BITS_8),
|
||||
make_tuple(&vp9_fht8x8_c, &vp9_iht8x8_64_add_c, 8, 2, VPX_BITS_8),
|
||||
make_tuple(&vp9_fht8x8_c, &vp9_iht8x8_64_add_c, 8, 3, VPX_BITS_8),
|
||||
|
||||
make_tuple(&vp9_fht4x4_c, &vp9_iht4x4_16_add_c, 4, 0, VPX_BITS_8),
|
||||
make_tuple(&vp9_fht4x4_c, &vp9_iht4x4_16_add_c, 4, 1, VPX_BITS_8),
|
||||
make_tuple(&vp9_fht4x4_c, &vp9_iht4x4_16_add_c, 4, 2, VPX_BITS_8),
|
||||
make_tuple(&vp9_fht4x4_c, &vp9_iht4x4_16_add_c, 4, 3, VPX_BITS_8)));
|
||||
#endif // CONFIG_VP9_HIGHBITDEPTH
|
||||
|
||||
#if HAVE_SSE2
|
||||
INSTANTIATE_TEST_CASE_P(
|
||||
SSE2, TransHT,
|
||||
::testing::Values(
|
||||
make_tuple(&vp9_fht16x16_sse2, &vp9_iht16x16_256_add_sse2, 16, 0,
|
||||
VPX_BITS_8),
|
||||
make_tuple(&vp9_fht16x16_sse2, &vp9_iht16x16_256_add_sse2, 16, 1,
|
||||
VPX_BITS_8),
|
||||
make_tuple(&vp9_fht16x16_sse2, &vp9_iht16x16_256_add_sse2, 16, 2,
|
||||
VPX_BITS_8),
|
||||
make_tuple(&vp9_fht16x16_sse2, &vp9_iht16x16_256_add_sse2, 16, 3,
|
||||
VPX_BITS_8),
|
||||
|
||||
make_tuple(&vp9_fht8x8_sse2, &vp9_iht8x8_64_add_sse2, 8, 0, VPX_BITS_8),
|
||||
make_tuple(&vp9_fht8x8_sse2, &vp9_iht8x8_64_add_sse2, 8, 1, VPX_BITS_8),
|
||||
make_tuple(&vp9_fht8x8_sse2, &vp9_iht8x8_64_add_sse2, 8, 2, VPX_BITS_8),
|
||||
make_tuple(&vp9_fht8x8_sse2, &vp9_iht8x8_64_add_sse2, 8, 3, VPX_BITS_8),
|
||||
|
||||
make_tuple(&vp9_fht4x4_sse2, &vp9_iht4x4_16_add_sse2, 4, 0, VPX_BITS_8),
|
||||
make_tuple(&vp9_fht4x4_sse2, &vp9_iht4x4_16_add_sse2, 4, 1, VPX_BITS_8),
|
||||
make_tuple(&vp9_fht4x4_sse2, &vp9_iht4x4_16_add_sse2, 4, 2, VPX_BITS_8),
|
||||
make_tuple(&vp9_fht4x4_sse2, &vp9_iht4x4_16_add_sse2, 4, 3,
|
||||
VPX_BITS_8)));
|
||||
#endif // HAVE_SSE2
|
||||
|
||||
class TransWHT : public TransTestBase,
|
||||
public ::testing::TestWithParam<DctParam> {
|
||||
public:
|
||||
TransWHT() {
|
||||
fwd_txfm_ref = fwht_ref;
|
||||
fwd_txfm_ = GET_PARAM(0);
|
||||
inv_txfm_ = GET_PARAM(1);
|
||||
size_ = GET_PARAM(2);
|
||||
tx_type_ = GET_PARAM(3);
|
||||
bit_depth_ = GET_PARAM(4);
|
||||
max_pixel_value_ = (1 << bit_depth_) - 1;
|
||||
}
|
||||
|
||||
protected:
|
||||
void RunFwdTxfm(const Buffer<int16_t> &in, Buffer<tran_low_t> *out) {
|
||||
fwd_txfm_(in.TopLeftPixel(), out->TopLeftPixel(), in.stride());
|
||||
}
|
||||
|
||||
void RunInvTxfm(const Buffer<tran_low_t> &in, uint8_t *out) {
|
||||
inv_txfm_(in.TopLeftPixel(), out, in.stride());
|
||||
}
|
||||
|
||||
FdctFunc fwd_txfm_;
|
||||
IdctFunc inv_txfm_;
|
||||
};
|
||||
|
||||
TEST_P(TransWHT, AccuracyCheck) { RunAccuracyCheck(0); }
|
||||
|
||||
TEST_P(TransWHT, CoeffCheck) { RunCoeffCheck(); }
|
||||
|
||||
TEST_P(TransWHT, MemCheck) { RunMemCheck(); }
|
||||
|
||||
TEST_P(TransWHT, InvAccuracyCheck) { RunInvAccuracyCheck(0); }
|
||||
|
||||
#if CONFIG_VP9_HIGHBITDEPTH
|
||||
INSTANTIATE_TEST_CASE_P(
|
||||
C, TransWHT,
|
||||
::testing::Values(
|
||||
make_tuple(&vp9_highbd_fwht4x4_c, &iwht4x4_10, 4, 0, VPX_BITS_10),
|
||||
make_tuple(&vp9_highbd_fwht4x4_c, &iwht4x4_12, 4, 0, VPX_BITS_12),
|
||||
make_tuple(&vp9_fwht4x4_c, &vpx_iwht4x4_16_add_c, 4, 0, VPX_BITS_8)));
|
||||
#else
|
||||
INSTANTIATE_TEST_CASE_P(C, TransWHT,
|
||||
::testing::Values(make_tuple(&vp9_fwht4x4_c,
|
||||
&vpx_iwht4x4_16_add_c, 4,
|
||||
0, VPX_BITS_8)));
|
||||
#endif // CONFIG_VP9_HIGHBITDEPTH
|
||||
|
||||
#if HAVE_SSE2
|
||||
INSTANTIATE_TEST_CASE_P(SSE2, TransWHT,
|
||||
::testing::Values(make_tuple(&vp9_fwht4x4_sse2,
|
||||
&vpx_iwht4x4_16_add_sse2,
|
||||
4, 0, VPX_BITS_8)));
|
||||
#endif // HAVE_SSE2
|
||||
} // namespace
|
||||
@@ -172,4 +172,21 @@ TEST(DecodeAPI, Vp9PeekSI) {
|
||||
}
|
||||
#endif // CONFIG_VP9_DECODER
|
||||
|
||||
TEST(DecodeAPI, HighBitDepthCapability) {
|
||||
// VP8 should not claim VP9 HBD as a capability.
|
||||
#if CONFIG_VP8_DECODER
|
||||
const vpx_codec_caps_t vp8_caps = vpx_codec_get_caps(&vpx_codec_vp8_dx_algo);
|
||||
EXPECT_EQ(vp8_caps & VPX_CODEC_CAP_HIGHBITDEPTH, 0);
|
||||
#endif
|
||||
|
||||
#if CONFIG_VP9_DECODER
|
||||
const vpx_codec_caps_t vp9_caps = vpx_codec_get_caps(&vpx_codec_vp9_dx_algo);
|
||||
#if CONFIG_VP9_HIGHBITDEPTH
|
||||
EXPECT_EQ(vp9_caps & VPX_CODEC_CAP_HIGHBITDEPTH, VPX_CODEC_CAP_HIGHBITDEPTH);
|
||||
#else
|
||||
EXPECT_EQ(vp9_caps & VPX_CODEC_CAP_HIGHBITDEPTH, 0);
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
@@ -53,13 +53,13 @@ void DecoderTest::HandlePeekResult(Decoder *const decoder,
|
||||
* pass it is not a keyframe, so we only expect VPX_CODEC_OK on the first
|
||||
* frame, which must be a keyframe. */
|
||||
if (video->frame_number() == 0)
|
||||
ASSERT_EQ(VPX_CODEC_OK, res_peek) << "Peek return failed: "
|
||||
<< vpx_codec_err_to_string(res_peek);
|
||||
ASSERT_EQ(VPX_CODEC_OK, res_peek)
|
||||
<< "Peek return failed: " << vpx_codec_err_to_string(res_peek);
|
||||
} else {
|
||||
/* The Vp9 implementation of PeekStream returns an error only if the
|
||||
* data passed to it isn't a valid Vp9 chunk. */
|
||||
ASSERT_EQ(VPX_CODEC_OK, res_peek) << "Peek return failed: "
|
||||
<< vpx_codec_err_to_string(res_peek);
|
||||
ASSERT_EQ(VPX_CODEC_OK, res_peek)
|
||||
<< "Peek return failed: " << vpx_codec_err_to_string(res_peek);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -62,4 +62,48 @@ TEST(EncodeAPI, InvalidParams) {
|
||||
}
|
||||
}
|
||||
|
||||
TEST(EncodeAPI, HighBitDepthCapability) {
|
||||
// VP8 should not claim VP9 HBD as a capability.
|
||||
#if CONFIG_VP8_ENCODER
|
||||
const vpx_codec_caps_t vp8_caps = vpx_codec_get_caps(&vpx_codec_vp8_cx_algo);
|
||||
EXPECT_EQ(vp8_caps & VPX_CODEC_CAP_HIGHBITDEPTH, 0);
|
||||
#endif
|
||||
|
||||
#if CONFIG_VP9_ENCODER
|
||||
const vpx_codec_caps_t vp9_caps = vpx_codec_get_caps(&vpx_codec_vp9_cx_algo);
|
||||
#if CONFIG_VP9_HIGHBITDEPTH
|
||||
EXPECT_EQ(vp9_caps & VPX_CODEC_CAP_HIGHBITDEPTH, VPX_CODEC_CAP_HIGHBITDEPTH);
|
||||
#else
|
||||
EXPECT_EQ(vp9_caps & VPX_CODEC_CAP_HIGHBITDEPTH, 0);
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
|
||||
#if CONFIG_VP8_ENCODER
|
||||
TEST(EncodeAPI, ImageSizeSetting) {
|
||||
const int width = 711;
|
||||
const int height = 360;
|
||||
const int bps = 12;
|
||||
vpx_image_t img;
|
||||
vpx_codec_ctx_t enc;
|
||||
vpx_codec_enc_cfg_t cfg;
|
||||
uint8_t *img_buf = reinterpret_cast<uint8_t *>(
|
||||
calloc(width * height * bps / 8, sizeof(*img_buf)));
|
||||
vpx_codec_enc_config_default(vpx_codec_vp8_cx(), &cfg, 0);
|
||||
|
||||
cfg.g_w = width;
|
||||
cfg.g_h = height;
|
||||
|
||||
vpx_img_wrap(&img, VPX_IMG_FMT_I420, width, height, 1, img_buf);
|
||||
|
||||
vpx_codec_enc_init(&enc, vpx_codec_vp8_cx(), &cfg, 0);
|
||||
|
||||
EXPECT_EQ(VPX_CODEC_OK, vpx_codec_encode(&enc, &img, 0, 1, 0, 0));
|
||||
|
||||
free(img_buf);
|
||||
|
||||
vpx_codec_destroy(&enc);
|
||||
}
|
||||
#endif
|
||||
|
||||
} // namespace
|
||||
|
||||
@@ -226,6 +226,8 @@ void EncoderTest::RunLoop(VideoSource *video) {
|
||||
|
||||
case VPX_CODEC_PSNR_PKT: PSNRPktHook(pkt); break;
|
||||
|
||||
case VPX_CODEC_STATS_PKT: StatsPktHook(pkt); break;
|
||||
|
||||
default: break;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -139,6 +139,13 @@ class Encoder {
|
||||
}
|
||||
#endif
|
||||
|
||||
#if CONFIG_VP8_ENCODER
|
||||
void Control(int ctrl_id, vpx_roi_map_t *arg) {
|
||||
const vpx_codec_err_t res = vpx_codec_control_(&encoder_, ctrl_id, arg);
|
||||
ASSERT_EQ(VPX_CODEC_OK, res) << EncoderError();
|
||||
}
|
||||
#endif
|
||||
|
||||
void Config(const vpx_codec_enc_cfg_t *cfg) {
|
||||
const vpx_codec_err_t res = vpx_codec_enc_config_set(&encoder_, cfg);
|
||||
ASSERT_EQ(VPX_CODEC_OK, res) << EncoderError();
|
||||
@@ -218,6 +225,9 @@ class EncoderTest {
|
||||
// Hook to be called on every PSNR packet.
|
||||
virtual void PSNRPktHook(const vpx_codec_cx_pkt_t * /*pkt*/) {}
|
||||
|
||||
// Hook to be called on every first pass stats packet.
|
||||
virtual void StatsPktHook(const vpx_codec_cx_pkt_t * /*pkt*/) {}
|
||||
|
||||
// Hook to determine whether the encode loop should continue.
|
||||
virtual bool Continue() const {
|
||||
return !(::testing::Test::HasFatalFailure() || abort_);
|
||||
|
||||
@@ -34,7 +34,8 @@ struct ExternalFrameBuffer {
|
||||
// Class to manipulate a list of external frame buffers.
|
||||
class ExternalFrameBufferList {
|
||||
public:
|
||||
ExternalFrameBufferList() : num_buffers_(0), ext_fb_list_(NULL) {}
|
||||
ExternalFrameBufferList()
|
||||
: num_buffers_(0), num_used_buffers_(0), ext_fb_list_(NULL) {}
|
||||
|
||||
virtual ~ExternalFrameBufferList() {
|
||||
for (int i = 0; i < num_buffers_; ++i) {
|
||||
@@ -71,6 +72,8 @@ class ExternalFrameBufferList {
|
||||
}
|
||||
|
||||
SetFrameBuffer(idx, fb);
|
||||
|
||||
num_used_buffers_++;
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -106,6 +109,7 @@ class ExternalFrameBufferList {
|
||||
}
|
||||
EXPECT_EQ(1, ext_fb->in_use);
|
||||
ext_fb->in_use = 0;
|
||||
num_used_buffers_--;
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -121,6 +125,8 @@ class ExternalFrameBufferList {
|
||||
}
|
||||
}
|
||||
|
||||
int num_used_buffers() const { return num_used_buffers_; }
|
||||
|
||||
private:
|
||||
// Returns the index of the first free frame buffer. Returns |num_buffers_|
|
||||
// if there are no free frame buffers.
|
||||
@@ -145,6 +151,7 @@ class ExternalFrameBufferList {
|
||||
}
|
||||
|
||||
int num_buffers_;
|
||||
int num_used_buffers_;
|
||||
ExternalFrameBuffer *ext_fb_list_;
|
||||
};
|
||||
|
||||
@@ -220,8 +227,8 @@ class ExternalFrameBufferMD5Test
|
||||
|
||||
void OpenMD5File(const std::string &md5_file_name_) {
|
||||
md5_file_ = libvpx_test::OpenTestDataFile(md5_file_name_);
|
||||
ASSERT_TRUE(md5_file_ != NULL) << "Md5 file open failed. Filename: "
|
||||
<< md5_file_name_;
|
||||
ASSERT_TRUE(md5_file_ != NULL)
|
||||
<< "Md5 file open failed. Filename: " << md5_file_name_;
|
||||
}
|
||||
|
||||
virtual void DecompressedFrameHook(const vpx_image_t &img,
|
||||
@@ -273,6 +280,7 @@ class ExternalFrameBufferMD5Test
|
||||
|
||||
#if CONFIG_WEBM_IO
|
||||
const char kVP9TestFile[] = "vp90-2-02-size-lf-1920x1080.webm";
|
||||
const char kVP9NonRefTestFile[] = "vp90-2-22-svc_1280x720_1.webm";
|
||||
|
||||
// Class for testing passing in external frame buffers to libvpx.
|
||||
class ExternalFrameBufferTest : public ::testing::Test {
|
||||
@@ -292,7 +300,9 @@ class ExternalFrameBufferTest : public ::testing::Test {
|
||||
|
||||
virtual void TearDown() {
|
||||
delete decoder_;
|
||||
decoder_ = NULL;
|
||||
delete video_;
|
||||
video_ = NULL;
|
||||
}
|
||||
|
||||
// Passes the external frame buffer information to libvpx.
|
||||
@@ -325,7 +335,7 @@ class ExternalFrameBufferTest : public ::testing::Test {
|
||||
return VPX_CODEC_OK;
|
||||
}
|
||||
|
||||
private:
|
||||
protected:
|
||||
void CheckDecodedFrames() {
|
||||
libvpx_test::DxDataIterator dec_iter = decoder_->GetDxData();
|
||||
const vpx_image_t *img = NULL;
|
||||
@@ -341,6 +351,25 @@ class ExternalFrameBufferTest : public ::testing::Test {
|
||||
int num_buffers_;
|
||||
ExternalFrameBufferList fb_list_;
|
||||
};
|
||||
|
||||
class ExternalFrameBufferNonRefTest : public ExternalFrameBufferTest {
|
||||
protected:
|
||||
virtual void SetUp() {
|
||||
video_ = new libvpx_test::WebMVideoSource(kVP9NonRefTestFile);
|
||||
ASSERT_TRUE(video_ != NULL);
|
||||
video_->Init();
|
||||
video_->Begin();
|
||||
|
||||
vpx_codec_dec_cfg_t cfg = vpx_codec_dec_cfg_t();
|
||||
decoder_ = new libvpx_test::VP9Decoder(cfg, 0);
|
||||
ASSERT_TRUE(decoder_ != NULL);
|
||||
}
|
||||
|
||||
virtual void CheckFrameBufferRelease() {
|
||||
TearDown();
|
||||
ASSERT_EQ(0, fb_list_.num_used_buffers());
|
||||
}
|
||||
};
|
||||
#endif // CONFIG_WEBM_IO
|
||||
|
||||
// This test runs through the set of test vectors, and decodes them.
|
||||
@@ -419,6 +448,8 @@ TEST_F(ExternalFrameBufferTest, NotEnoughBuffers) {
|
||||
SetFrameBufferFunctions(num_buffers, get_vp9_frame_buffer,
|
||||
release_vp9_frame_buffer));
|
||||
ASSERT_EQ(VPX_CODEC_OK, DecodeOneFrame());
|
||||
// Only run this on long clips. Decoding a very short clip will return
|
||||
// VPX_CODEC_OK even with only 2 buffers.
|
||||
ASSERT_EQ(VPX_CODEC_MEM_ERROR, DecodeRemainingFrames());
|
||||
}
|
||||
|
||||
@@ -467,6 +498,15 @@ TEST_F(ExternalFrameBufferTest, SetAfterDecode) {
|
||||
SetFrameBufferFunctions(num_buffers, get_vp9_frame_buffer,
|
||||
release_vp9_frame_buffer));
|
||||
}
|
||||
|
||||
TEST_F(ExternalFrameBufferNonRefTest, ReleaseNonRefFrameBuffer) {
|
||||
const int num_buffers = VP9_MAXIMUM_REF_BUFFERS + VPX_MAXIMUM_WORK_BUFFERS;
|
||||
ASSERT_EQ(VPX_CODEC_OK,
|
||||
SetFrameBufferFunctions(num_buffers, get_vp9_frame_buffer,
|
||||
release_vp9_frame_buffer));
|
||||
ASSERT_EQ(VPX_CODEC_OK, DecodeRemainingFrames());
|
||||
CheckFrameBufferRelease();
|
||||
}
|
||||
#endif // CONFIG_WEBM_IO
|
||||
|
||||
VP9_INSTANTIATE_TEST_CASE(
|
||||
|
||||
@@ -1,511 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2012 The WebM project authors. All Rights Reserved.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license
|
||||
* that can be found in the LICENSE file in the root of the source
|
||||
* tree. An additional intellectual property rights grant can be found
|
||||
* in the file PATENTS. All contributing project authors may
|
||||
* be found in the AUTHORS file in the root of the source tree.
|
||||
*/
|
||||
|
||||
#include <math.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "third_party/googletest/src/include/gtest/gtest.h"
|
||||
|
||||
#include "./vp9_rtcd.h"
|
||||
#include "./vpx_dsp_rtcd.h"
|
||||
#include "test/acm_random.h"
|
||||
#include "test/clear_system_state.h"
|
||||
#include "test/register_state_check.h"
|
||||
#include "test/util.h"
|
||||
#include "vp9/common/vp9_entropy.h"
|
||||
#include "vpx/vpx_codec.h"
|
||||
#include "vpx/vpx_integer.h"
|
||||
#include "vpx_ports/mem.h"
|
||||
|
||||
using libvpx_test::ACMRandom;
|
||||
|
||||
namespace {
|
||||
const int kNumCoeffs = 16;
|
||||
typedef void (*FdctFunc)(const int16_t *in, tran_low_t *out, int stride);
|
||||
typedef void (*IdctFunc)(const tran_low_t *in, uint8_t *out, int stride);
|
||||
typedef void (*FhtFunc)(const int16_t *in, tran_low_t *out, int stride,
|
||||
int tx_type);
|
||||
typedef void (*IhtFunc)(const tran_low_t *in, uint8_t *out, int stride,
|
||||
int tx_type);
|
||||
|
||||
typedef std::tr1::tuple<FdctFunc, IdctFunc, int, vpx_bit_depth_t> Dct4x4Param;
|
||||
typedef std::tr1::tuple<FhtFunc, IhtFunc, int, vpx_bit_depth_t> Ht4x4Param;
|
||||
|
||||
void fdct4x4_ref(const int16_t *in, tran_low_t *out, int stride,
|
||||
int /*tx_type*/) {
|
||||
vpx_fdct4x4_c(in, out, stride);
|
||||
}
|
||||
|
||||
void fht4x4_ref(const int16_t *in, tran_low_t *out, int stride, int tx_type) {
|
||||
vp9_fht4x4_c(in, out, stride, tx_type);
|
||||
}
|
||||
|
||||
void fwht4x4_ref(const int16_t *in, tran_low_t *out, int stride,
|
||||
int /*tx_type*/) {
|
||||
vp9_fwht4x4_c(in, out, stride);
|
||||
}
|
||||
|
||||
#if CONFIG_VP9_HIGHBITDEPTH
|
||||
void idct4x4_10(const tran_low_t *in, uint8_t *out, int stride) {
|
||||
vpx_highbd_idct4x4_16_add_c(in, out, stride, 10);
|
||||
}
|
||||
|
||||
void idct4x4_12(const tran_low_t *in, uint8_t *out, int stride) {
|
||||
vpx_highbd_idct4x4_16_add_c(in, out, stride, 12);
|
||||
}
|
||||
|
||||
void iht4x4_10(const tran_low_t *in, uint8_t *out, int stride, int tx_type) {
|
||||
vp9_highbd_iht4x4_16_add_c(in, out, stride, tx_type, 10);
|
||||
}
|
||||
|
||||
void iht4x4_12(const tran_low_t *in, uint8_t *out, int stride, int tx_type) {
|
||||
vp9_highbd_iht4x4_16_add_c(in, out, stride, tx_type, 12);
|
||||
}
|
||||
|
||||
void iwht4x4_10(const tran_low_t *in, uint8_t *out, int stride) {
|
||||
vpx_highbd_iwht4x4_16_add_c(in, out, stride, 10);
|
||||
}
|
||||
|
||||
void iwht4x4_12(const tran_low_t *in, uint8_t *out, int stride) {
|
||||
vpx_highbd_iwht4x4_16_add_c(in, out, stride, 12);
|
||||
}
|
||||
|
||||
#if HAVE_SSE2
|
||||
void idct4x4_10_sse2(const tran_low_t *in, uint8_t *out, int stride) {
|
||||
vpx_highbd_idct4x4_16_add_sse2(in, out, stride, 10);
|
||||
}
|
||||
|
||||
void idct4x4_12_sse2(const tran_low_t *in, uint8_t *out, int stride) {
|
||||
vpx_highbd_idct4x4_16_add_sse2(in, out, stride, 12);
|
||||
}
|
||||
#endif // HAVE_SSE2
|
||||
#endif // CONFIG_VP9_HIGHBITDEPTH
|
||||
|
||||
class Trans4x4TestBase {
|
||||
public:
|
||||
virtual ~Trans4x4TestBase() {}
|
||||
|
||||
protected:
|
||||
virtual void RunFwdTxfm(const int16_t *in, tran_low_t *out, int stride) = 0;
|
||||
|
||||
virtual void RunInvTxfm(const tran_low_t *out, uint8_t *dst, int stride) = 0;
|
||||
|
||||
void RunAccuracyCheck(int limit) {
|
||||
ACMRandom rnd(ACMRandom::DeterministicSeed());
|
||||
uint32_t max_error = 0;
|
||||
int64_t total_error = 0;
|
||||
const int count_test_block = 10000;
|
||||
for (int i = 0; i < count_test_block; ++i) {
|
||||
DECLARE_ALIGNED(16, int16_t, test_input_block[kNumCoeffs]);
|
||||
DECLARE_ALIGNED(16, tran_low_t, test_temp_block[kNumCoeffs]);
|
||||
DECLARE_ALIGNED(16, uint8_t, dst[kNumCoeffs]);
|
||||
DECLARE_ALIGNED(16, uint8_t, src[kNumCoeffs]);
|
||||
#if CONFIG_VP9_HIGHBITDEPTH
|
||||
DECLARE_ALIGNED(16, uint16_t, dst16[kNumCoeffs]);
|
||||
DECLARE_ALIGNED(16, uint16_t, src16[kNumCoeffs]);
|
||||
#endif
|
||||
|
||||
// Initialize a test block with input range [-255, 255].
|
||||
for (int j = 0; j < kNumCoeffs; ++j) {
|
||||
if (bit_depth_ == VPX_BITS_8) {
|
||||
src[j] = rnd.Rand8();
|
||||
dst[j] = rnd.Rand8();
|
||||
test_input_block[j] = src[j] - dst[j];
|
||||
#if CONFIG_VP9_HIGHBITDEPTH
|
||||
} else {
|
||||
src16[j] = rnd.Rand16() & mask_;
|
||||
dst16[j] = rnd.Rand16() & mask_;
|
||||
test_input_block[j] = src16[j] - dst16[j];
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
ASM_REGISTER_STATE_CHECK(
|
||||
RunFwdTxfm(test_input_block, test_temp_block, pitch_));
|
||||
if (bit_depth_ == VPX_BITS_8) {
|
||||
ASM_REGISTER_STATE_CHECK(RunInvTxfm(test_temp_block, dst, pitch_));
|
||||
#if CONFIG_VP9_HIGHBITDEPTH
|
||||
} else {
|
||||
ASM_REGISTER_STATE_CHECK(
|
||||
RunInvTxfm(test_temp_block, CONVERT_TO_BYTEPTR(dst16), pitch_));
|
||||
#endif
|
||||
}
|
||||
|
||||
for (int j = 0; j < kNumCoeffs; ++j) {
|
||||
#if CONFIG_VP9_HIGHBITDEPTH
|
||||
const int diff =
|
||||
bit_depth_ == VPX_BITS_8 ? dst[j] - src[j] : dst16[j] - src16[j];
|
||||
#else
|
||||
ASSERT_EQ(VPX_BITS_8, bit_depth_);
|
||||
const int diff = dst[j] - src[j];
|
||||
#endif
|
||||
const uint32_t error = diff * diff;
|
||||
if (max_error < error) max_error = error;
|
||||
total_error += error;
|
||||
}
|
||||
}
|
||||
|
||||
EXPECT_GE(static_cast<uint32_t>(limit), max_error)
|
||||
<< "Error: 4x4 FHT/IHT has an individual round trip error > " << limit;
|
||||
|
||||
EXPECT_GE(count_test_block * limit, total_error)
|
||||
<< "Error: 4x4 FHT/IHT has average round trip error > " << limit
|
||||
<< " per block";
|
||||
}
|
||||
|
||||
void RunCoeffCheck() {
|
||||
ACMRandom rnd(ACMRandom::DeterministicSeed());
|
||||
const int count_test_block = 5000;
|
||||
DECLARE_ALIGNED(16, int16_t, input_block[kNumCoeffs]);
|
||||
DECLARE_ALIGNED(16, tran_low_t, output_ref_block[kNumCoeffs]);
|
||||
DECLARE_ALIGNED(16, tran_low_t, output_block[kNumCoeffs]);
|
||||
|
||||
for (int i = 0; i < count_test_block; ++i) {
|
||||
// Initialize a test block with input range [-mask_, mask_].
|
||||
for (int j = 0; j < kNumCoeffs; ++j) {
|
||||
input_block[j] = (rnd.Rand16() & mask_) - (rnd.Rand16() & mask_);
|
||||
}
|
||||
|
||||
fwd_txfm_ref(input_block, output_ref_block, pitch_, tx_type_);
|
||||
ASM_REGISTER_STATE_CHECK(RunFwdTxfm(input_block, output_block, pitch_));
|
||||
|
||||
// The minimum quant value is 4.
|
||||
for (int j = 0; j < kNumCoeffs; ++j)
|
||||
EXPECT_EQ(output_block[j], output_ref_block[j]);
|
||||
}
|
||||
}
|
||||
|
||||
void RunMemCheck() {
|
||||
ACMRandom rnd(ACMRandom::DeterministicSeed());
|
||||
const int count_test_block = 5000;
|
||||
DECLARE_ALIGNED(16, int16_t, input_extreme_block[kNumCoeffs]);
|
||||
DECLARE_ALIGNED(16, tran_low_t, output_ref_block[kNumCoeffs]);
|
||||
DECLARE_ALIGNED(16, tran_low_t, output_block[kNumCoeffs]);
|
||||
|
||||
for (int i = 0; i < count_test_block; ++i) {
|
||||
// Initialize a test block with input range [-mask_, mask_].
|
||||
for (int j = 0; j < kNumCoeffs; ++j) {
|
||||
input_extreme_block[j] = rnd.Rand8() % 2 ? mask_ : -mask_;
|
||||
}
|
||||
if (i == 0) {
|
||||
for (int j = 0; j < kNumCoeffs; ++j) input_extreme_block[j] = mask_;
|
||||
} else if (i == 1) {
|
||||
for (int j = 0; j < kNumCoeffs; ++j) input_extreme_block[j] = -mask_;
|
||||
}
|
||||
|
||||
fwd_txfm_ref(input_extreme_block, output_ref_block, pitch_, tx_type_);
|
||||
ASM_REGISTER_STATE_CHECK(
|
||||
RunFwdTxfm(input_extreme_block, output_block, pitch_));
|
||||
|
||||
// The minimum quant value is 4.
|
||||
for (int j = 0; j < kNumCoeffs; ++j) {
|
||||
EXPECT_EQ(output_block[j], output_ref_block[j]);
|
||||
EXPECT_GE(4 * DCT_MAX_VALUE << (bit_depth_ - 8), abs(output_block[j]))
|
||||
<< "Error: 4x4 FDCT has coefficient larger than 4*DCT_MAX_VALUE";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void RunInvAccuracyCheck(int limit) {
|
||||
ACMRandom rnd(ACMRandom::DeterministicSeed());
|
||||
const int count_test_block = 1000;
|
||||
DECLARE_ALIGNED(16, int16_t, in[kNumCoeffs]);
|
||||
DECLARE_ALIGNED(16, tran_low_t, coeff[kNumCoeffs]);
|
||||
DECLARE_ALIGNED(16, uint8_t, dst[kNumCoeffs]);
|
||||
DECLARE_ALIGNED(16, uint8_t, src[kNumCoeffs]);
|
||||
#if CONFIG_VP9_HIGHBITDEPTH
|
||||
DECLARE_ALIGNED(16, uint16_t, dst16[kNumCoeffs]);
|
||||
DECLARE_ALIGNED(16, uint16_t, src16[kNumCoeffs]);
|
||||
#endif
|
||||
|
||||
for (int i = 0; i < count_test_block; ++i) {
|
||||
// Initialize a test block with input range [-mask_, mask_].
|
||||
for (int j = 0; j < kNumCoeffs; ++j) {
|
||||
if (bit_depth_ == VPX_BITS_8) {
|
||||
src[j] = rnd.Rand8();
|
||||
dst[j] = rnd.Rand8();
|
||||
in[j] = src[j] - dst[j];
|
||||
#if CONFIG_VP9_HIGHBITDEPTH
|
||||
} else {
|
||||
src16[j] = rnd.Rand16() & mask_;
|
||||
dst16[j] = rnd.Rand16() & mask_;
|
||||
in[j] = src16[j] - dst16[j];
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
fwd_txfm_ref(in, coeff, pitch_, tx_type_);
|
||||
|
||||
if (bit_depth_ == VPX_BITS_8) {
|
||||
ASM_REGISTER_STATE_CHECK(RunInvTxfm(coeff, dst, pitch_));
|
||||
#if CONFIG_VP9_HIGHBITDEPTH
|
||||
} else {
|
||||
ASM_REGISTER_STATE_CHECK(
|
||||
RunInvTxfm(coeff, CONVERT_TO_BYTEPTR(dst16), pitch_));
|
||||
#endif
|
||||
}
|
||||
|
||||
for (int j = 0; j < kNumCoeffs; ++j) {
|
||||
#if CONFIG_VP9_HIGHBITDEPTH
|
||||
const int diff =
|
||||
bit_depth_ == VPX_BITS_8 ? dst[j] - src[j] : dst16[j] - src16[j];
|
||||
#else
|
||||
const int diff = dst[j] - src[j];
|
||||
#endif
|
||||
const uint32_t error = diff * diff;
|
||||
EXPECT_GE(static_cast<uint32_t>(limit), error)
|
||||
<< "Error: 4x4 IDCT has error " << error << " at index " << j;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int pitch_;
|
||||
int tx_type_;
|
||||
FhtFunc fwd_txfm_ref;
|
||||
vpx_bit_depth_t bit_depth_;
|
||||
int mask_;
|
||||
};
|
||||
|
||||
class Trans4x4DCT : public Trans4x4TestBase,
|
||||
public ::testing::TestWithParam<Dct4x4Param> {
|
||||
public:
|
||||
virtual ~Trans4x4DCT() {}
|
||||
|
||||
virtual void SetUp() {
|
||||
fwd_txfm_ = GET_PARAM(0);
|
||||
inv_txfm_ = GET_PARAM(1);
|
||||
tx_type_ = GET_PARAM(2);
|
||||
pitch_ = 4;
|
||||
fwd_txfm_ref = fdct4x4_ref;
|
||||
bit_depth_ = GET_PARAM(3);
|
||||
mask_ = (1 << bit_depth_) - 1;
|
||||
}
|
||||
virtual void TearDown() { libvpx_test::ClearSystemState(); }
|
||||
|
||||
protected:
|
||||
void RunFwdTxfm(const int16_t *in, tran_low_t *out, int stride) {
|
||||
fwd_txfm_(in, out, stride);
|
||||
}
|
||||
void RunInvTxfm(const tran_low_t *out, uint8_t *dst, int stride) {
|
||||
inv_txfm_(out, dst, stride);
|
||||
}
|
||||
|
||||
FdctFunc fwd_txfm_;
|
||||
IdctFunc inv_txfm_;
|
||||
};
|
||||
|
||||
TEST_P(Trans4x4DCT, AccuracyCheck) { RunAccuracyCheck(1); }
|
||||
|
||||
TEST_P(Trans4x4DCT, CoeffCheck) { RunCoeffCheck(); }
|
||||
|
||||
TEST_P(Trans4x4DCT, MemCheck) { RunMemCheck(); }
|
||||
|
||||
TEST_P(Trans4x4DCT, InvAccuracyCheck) { RunInvAccuracyCheck(1); }
|
||||
|
||||
class Trans4x4HT : public Trans4x4TestBase,
|
||||
public ::testing::TestWithParam<Ht4x4Param> {
|
||||
public:
|
||||
virtual ~Trans4x4HT() {}
|
||||
|
||||
virtual void SetUp() {
|
||||
fwd_txfm_ = GET_PARAM(0);
|
||||
inv_txfm_ = GET_PARAM(1);
|
||||
tx_type_ = GET_PARAM(2);
|
||||
pitch_ = 4;
|
||||
fwd_txfm_ref = fht4x4_ref;
|
||||
bit_depth_ = GET_PARAM(3);
|
||||
mask_ = (1 << bit_depth_) - 1;
|
||||
}
|
||||
virtual void TearDown() { libvpx_test::ClearSystemState(); }
|
||||
|
||||
protected:
|
||||
void RunFwdTxfm(const int16_t *in, tran_low_t *out, int stride) {
|
||||
fwd_txfm_(in, out, stride, tx_type_);
|
||||
}
|
||||
|
||||
void RunInvTxfm(const tran_low_t *out, uint8_t *dst, int stride) {
|
||||
inv_txfm_(out, dst, stride, tx_type_);
|
||||
}
|
||||
|
||||
FhtFunc fwd_txfm_;
|
||||
IhtFunc inv_txfm_;
|
||||
};
|
||||
|
||||
TEST_P(Trans4x4HT, AccuracyCheck) { RunAccuracyCheck(1); }
|
||||
|
||||
TEST_P(Trans4x4HT, CoeffCheck) { RunCoeffCheck(); }
|
||||
|
||||
TEST_P(Trans4x4HT, MemCheck) { RunMemCheck(); }
|
||||
|
||||
TEST_P(Trans4x4HT, InvAccuracyCheck) { RunInvAccuracyCheck(1); }
|
||||
|
||||
class Trans4x4WHT : public Trans4x4TestBase,
|
||||
public ::testing::TestWithParam<Dct4x4Param> {
|
||||
public:
|
||||
virtual ~Trans4x4WHT() {}
|
||||
|
||||
virtual void SetUp() {
|
||||
fwd_txfm_ = GET_PARAM(0);
|
||||
inv_txfm_ = GET_PARAM(1);
|
||||
tx_type_ = GET_PARAM(2);
|
||||
pitch_ = 4;
|
||||
fwd_txfm_ref = fwht4x4_ref;
|
||||
bit_depth_ = GET_PARAM(3);
|
||||
mask_ = (1 << bit_depth_) - 1;
|
||||
}
|
||||
virtual void TearDown() { libvpx_test::ClearSystemState(); }
|
||||
|
||||
protected:
|
||||
void RunFwdTxfm(const int16_t *in, tran_low_t *out, int stride) {
|
||||
fwd_txfm_(in, out, stride);
|
||||
}
|
||||
void RunInvTxfm(const tran_low_t *out, uint8_t *dst, int stride) {
|
||||
inv_txfm_(out, dst, stride);
|
||||
}
|
||||
|
||||
FdctFunc fwd_txfm_;
|
||||
IdctFunc inv_txfm_;
|
||||
};
|
||||
|
||||
TEST_P(Trans4x4WHT, AccuracyCheck) { RunAccuracyCheck(0); }
|
||||
|
||||
TEST_P(Trans4x4WHT, CoeffCheck) { RunCoeffCheck(); }
|
||||
|
||||
TEST_P(Trans4x4WHT, MemCheck) { RunMemCheck(); }
|
||||
|
||||
TEST_P(Trans4x4WHT, InvAccuracyCheck) { RunInvAccuracyCheck(0); }
|
||||
using std::tr1::make_tuple;
|
||||
|
||||
#if CONFIG_VP9_HIGHBITDEPTH
|
||||
INSTANTIATE_TEST_CASE_P(
|
||||
C, Trans4x4DCT,
|
||||
::testing::Values(
|
||||
make_tuple(&vpx_highbd_fdct4x4_c, &idct4x4_10, 0, VPX_BITS_10),
|
||||
make_tuple(&vpx_highbd_fdct4x4_c, &idct4x4_12, 0, VPX_BITS_12),
|
||||
make_tuple(&vpx_fdct4x4_c, &vpx_idct4x4_16_add_c, 0, VPX_BITS_8)));
|
||||
#else
|
||||
INSTANTIATE_TEST_CASE_P(C, Trans4x4DCT,
|
||||
::testing::Values(make_tuple(&vpx_fdct4x4_c,
|
||||
&vpx_idct4x4_16_add_c, 0,
|
||||
VPX_BITS_8)));
|
||||
#endif // CONFIG_VP9_HIGHBITDEPTH
|
||||
|
||||
#if CONFIG_VP9_HIGHBITDEPTH
|
||||
INSTANTIATE_TEST_CASE_P(
|
||||
C, Trans4x4HT,
|
||||
::testing::Values(
|
||||
make_tuple(&vp9_highbd_fht4x4_c, &iht4x4_10, 0, VPX_BITS_10),
|
||||
make_tuple(&vp9_highbd_fht4x4_c, &iht4x4_10, 1, VPX_BITS_10),
|
||||
make_tuple(&vp9_highbd_fht4x4_c, &iht4x4_10, 2, VPX_BITS_10),
|
||||
make_tuple(&vp9_highbd_fht4x4_c, &iht4x4_10, 3, VPX_BITS_10),
|
||||
make_tuple(&vp9_highbd_fht4x4_c, &iht4x4_12, 0, VPX_BITS_12),
|
||||
make_tuple(&vp9_highbd_fht4x4_c, &iht4x4_12, 1, VPX_BITS_12),
|
||||
make_tuple(&vp9_highbd_fht4x4_c, &iht4x4_12, 2, VPX_BITS_12),
|
||||
make_tuple(&vp9_highbd_fht4x4_c, &iht4x4_12, 3, VPX_BITS_12),
|
||||
make_tuple(&vp9_fht4x4_c, &vp9_iht4x4_16_add_c, 0, VPX_BITS_8),
|
||||
make_tuple(&vp9_fht4x4_c, &vp9_iht4x4_16_add_c, 1, VPX_BITS_8),
|
||||
make_tuple(&vp9_fht4x4_c, &vp9_iht4x4_16_add_c, 2, VPX_BITS_8),
|
||||
make_tuple(&vp9_fht4x4_c, &vp9_iht4x4_16_add_c, 3, VPX_BITS_8)));
|
||||
#else
|
||||
INSTANTIATE_TEST_CASE_P(
|
||||
C, Trans4x4HT,
|
||||
::testing::Values(
|
||||
make_tuple(&vp9_fht4x4_c, &vp9_iht4x4_16_add_c, 0, VPX_BITS_8),
|
||||
make_tuple(&vp9_fht4x4_c, &vp9_iht4x4_16_add_c, 1, VPX_BITS_8),
|
||||
make_tuple(&vp9_fht4x4_c, &vp9_iht4x4_16_add_c, 2, VPX_BITS_8),
|
||||
make_tuple(&vp9_fht4x4_c, &vp9_iht4x4_16_add_c, 3, VPX_BITS_8)));
|
||||
#endif // CONFIG_VP9_HIGHBITDEPTH
|
||||
|
||||
#if CONFIG_VP9_HIGHBITDEPTH
|
||||
INSTANTIATE_TEST_CASE_P(
|
||||
C, Trans4x4WHT,
|
||||
::testing::Values(
|
||||
make_tuple(&vp9_highbd_fwht4x4_c, &iwht4x4_10, 0, VPX_BITS_10),
|
||||
make_tuple(&vp9_highbd_fwht4x4_c, &iwht4x4_12, 0, VPX_BITS_12),
|
||||
make_tuple(&vp9_fwht4x4_c, &vpx_iwht4x4_16_add_c, 0, VPX_BITS_8)));
|
||||
#else
|
||||
INSTANTIATE_TEST_CASE_P(C, Trans4x4WHT,
|
||||
::testing::Values(make_tuple(&vp9_fwht4x4_c,
|
||||
&vpx_iwht4x4_16_add_c, 0,
|
||||
VPX_BITS_8)));
|
||||
#endif // CONFIG_VP9_HIGHBITDEPTH
|
||||
|
||||
#if HAVE_NEON && !CONFIG_EMULATE_HARDWARE
|
||||
INSTANTIATE_TEST_CASE_P(NEON, Trans4x4DCT,
|
||||
::testing::Values(make_tuple(&vpx_fdct4x4_c,
|
||||
&vpx_idct4x4_16_add_neon,
|
||||
0, VPX_BITS_8)));
|
||||
#if !CONFIG_VP9_HIGHBITDEPTH
|
||||
INSTANTIATE_TEST_CASE_P(
|
||||
NEON, Trans4x4HT,
|
||||
::testing::Values(
|
||||
make_tuple(&vp9_fht4x4_c, &vp9_iht4x4_16_add_neon, 0, VPX_BITS_8),
|
||||
make_tuple(&vp9_fht4x4_c, &vp9_iht4x4_16_add_neon, 1, VPX_BITS_8),
|
||||
make_tuple(&vp9_fht4x4_c, &vp9_iht4x4_16_add_neon, 2, VPX_BITS_8),
|
||||
make_tuple(&vp9_fht4x4_c, &vp9_iht4x4_16_add_neon, 3, VPX_BITS_8)));
|
||||
#endif // !CONFIG_VP9_HIGHBITDEPTH
|
||||
#endif // HAVE_NEON && !CONFIG_EMULATE_HARDWARE
|
||||
|
||||
#if HAVE_SSE2 && !CONFIG_EMULATE_HARDWARE
|
||||
INSTANTIATE_TEST_CASE_P(
|
||||
SSE2, Trans4x4WHT,
|
||||
::testing::Values(
|
||||
make_tuple(&vp9_fwht4x4_sse2, &vpx_iwht4x4_16_add_c, 0, VPX_BITS_8),
|
||||
make_tuple(&vp9_fwht4x4_c, &vpx_iwht4x4_16_add_sse2, 0, VPX_BITS_8)));
|
||||
#endif
|
||||
|
||||
#if HAVE_SSE2 && !CONFIG_VP9_HIGHBITDEPTH && !CONFIG_EMULATE_HARDWARE
|
||||
INSTANTIATE_TEST_CASE_P(SSE2, Trans4x4DCT,
|
||||
::testing::Values(make_tuple(&vpx_fdct4x4_sse2,
|
||||
&vpx_idct4x4_16_add_sse2,
|
||||
0, VPX_BITS_8)));
|
||||
INSTANTIATE_TEST_CASE_P(
|
||||
SSE2, Trans4x4HT,
|
||||
::testing::Values(
|
||||
make_tuple(&vp9_fht4x4_sse2, &vp9_iht4x4_16_add_sse2, 0, VPX_BITS_8),
|
||||
make_tuple(&vp9_fht4x4_sse2, &vp9_iht4x4_16_add_sse2, 1, VPX_BITS_8),
|
||||
make_tuple(&vp9_fht4x4_sse2, &vp9_iht4x4_16_add_sse2, 2, VPX_BITS_8),
|
||||
make_tuple(&vp9_fht4x4_sse2, &vp9_iht4x4_16_add_sse2, 3, VPX_BITS_8)));
|
||||
#endif // HAVE_SSE2 && !CONFIG_VP9_HIGHBITDEPTH && !CONFIG_EMULATE_HARDWARE
|
||||
|
||||
#if HAVE_SSE2 && CONFIG_VP9_HIGHBITDEPTH && !CONFIG_EMULATE_HARDWARE
|
||||
INSTANTIATE_TEST_CASE_P(
|
||||
SSE2, Trans4x4DCT,
|
||||
::testing::Values(
|
||||
make_tuple(&vpx_highbd_fdct4x4_c, &idct4x4_10_sse2, 0, VPX_BITS_10),
|
||||
make_tuple(&vpx_highbd_fdct4x4_sse2, &idct4x4_10_sse2, 0, VPX_BITS_10),
|
||||
make_tuple(&vpx_highbd_fdct4x4_c, &idct4x4_12_sse2, 0, VPX_BITS_12),
|
||||
make_tuple(&vpx_highbd_fdct4x4_sse2, &idct4x4_12_sse2, 0, VPX_BITS_12),
|
||||
make_tuple(&vpx_fdct4x4_sse2, &vpx_idct4x4_16_add_c, 0, VPX_BITS_8)));
|
||||
|
||||
INSTANTIATE_TEST_CASE_P(
|
||||
SSE2, Trans4x4HT,
|
||||
::testing::Values(
|
||||
make_tuple(&vp9_fht4x4_sse2, &vp9_iht4x4_16_add_c, 0, VPX_BITS_8),
|
||||
make_tuple(&vp9_fht4x4_sse2, &vp9_iht4x4_16_add_c, 1, VPX_BITS_8),
|
||||
make_tuple(&vp9_fht4x4_sse2, &vp9_iht4x4_16_add_c, 2, VPX_BITS_8),
|
||||
make_tuple(&vp9_fht4x4_sse2, &vp9_iht4x4_16_add_c, 3, VPX_BITS_8)));
|
||||
#endif // HAVE_SSE2 && CONFIG_VP9_HIGHBITDEPTH && !CONFIG_EMULATE_HARDWARE
|
||||
|
||||
#if HAVE_MSA && !CONFIG_VP9_HIGHBITDEPTH && !CONFIG_EMULATE_HARDWARE
|
||||
INSTANTIATE_TEST_CASE_P(MSA, Trans4x4DCT,
|
||||
::testing::Values(make_tuple(&vpx_fdct4x4_msa,
|
||||
&vpx_idct4x4_16_add_msa, 0,
|
||||
VPX_BITS_8)));
|
||||
INSTANTIATE_TEST_CASE_P(
|
||||
MSA, Trans4x4HT,
|
||||
::testing::Values(
|
||||
make_tuple(&vp9_fht4x4_msa, &vp9_iht4x4_16_add_msa, 0, VPX_BITS_8),
|
||||
make_tuple(&vp9_fht4x4_msa, &vp9_iht4x4_16_add_msa, 1, VPX_BITS_8),
|
||||
make_tuple(&vp9_fht4x4_msa, &vp9_iht4x4_16_add_msa, 2, VPX_BITS_8),
|
||||
make_tuple(&vp9_fht4x4_msa, &vp9_iht4x4_16_add_msa, 3, VPX_BITS_8)));
|
||||
#endif // HAVE_MSA && !CONFIG_VP9_HIGHBITDEPTH && !CONFIG_EMULATE_HARDWARE
|
||||
} // namespace
|
||||
@@ -88,45 +88,45 @@ void fht8x8_ref(const int16_t *in, tran_low_t *out, int stride, int tx_type) {
|
||||
|
||||
#if CONFIG_VP9_HIGHBITDEPTH
|
||||
void idct8x8_10(const tran_low_t *in, uint8_t *out, int stride) {
|
||||
vpx_highbd_idct8x8_64_add_c(in, out, stride, 10);
|
||||
vpx_highbd_idct8x8_64_add_c(in, CAST_TO_SHORTPTR(out), stride, 10);
|
||||
}
|
||||
|
||||
void idct8x8_12(const tran_low_t *in, uint8_t *out, int stride) {
|
||||
vpx_highbd_idct8x8_64_add_c(in, out, stride, 12);
|
||||
vpx_highbd_idct8x8_64_add_c(in, CAST_TO_SHORTPTR(out), stride, 12);
|
||||
}
|
||||
|
||||
void iht8x8_10(const tran_low_t *in, uint8_t *out, int stride, int tx_type) {
|
||||
vp9_highbd_iht8x8_64_add_c(in, out, stride, tx_type, 10);
|
||||
vp9_highbd_iht8x8_64_add_c(in, CAST_TO_SHORTPTR(out), stride, tx_type, 10);
|
||||
}
|
||||
|
||||
void iht8x8_12(const tran_low_t *in, uint8_t *out, int stride, int tx_type) {
|
||||
vp9_highbd_iht8x8_64_add_c(in, out, stride, tx_type, 12);
|
||||
vp9_highbd_iht8x8_64_add_c(in, CAST_TO_SHORTPTR(out), stride, tx_type, 12);
|
||||
}
|
||||
|
||||
#if HAVE_SSE2
|
||||
|
||||
void idct8x8_12_add_10_c(const tran_low_t *in, uint8_t *out, int stride) {
|
||||
vpx_highbd_idct8x8_12_add_c(in, out, stride, 10);
|
||||
vpx_highbd_idct8x8_12_add_c(in, CAST_TO_SHORTPTR(out), stride, 10);
|
||||
}
|
||||
|
||||
void idct8x8_12_add_12_c(const tran_low_t *in, uint8_t *out, int stride) {
|
||||
vpx_highbd_idct8x8_12_add_c(in, out, stride, 12);
|
||||
vpx_highbd_idct8x8_12_add_c(in, CAST_TO_SHORTPTR(out), stride, 12);
|
||||
}
|
||||
|
||||
void idct8x8_12_add_10_sse2(const tran_low_t *in, uint8_t *out, int stride) {
|
||||
vpx_highbd_idct8x8_12_add_sse2(in, out, stride, 10);
|
||||
vpx_highbd_idct8x8_12_add_sse2(in, CAST_TO_SHORTPTR(out), stride, 10);
|
||||
}
|
||||
|
||||
void idct8x8_12_add_12_sse2(const tran_low_t *in, uint8_t *out, int stride) {
|
||||
vpx_highbd_idct8x8_12_add_sse2(in, out, stride, 12);
|
||||
vpx_highbd_idct8x8_12_add_sse2(in, CAST_TO_SHORTPTR(out), stride, 12);
|
||||
}
|
||||
|
||||
void idct8x8_64_add_10_sse2(const tran_low_t *in, uint8_t *out, int stride) {
|
||||
vpx_highbd_idct8x8_64_add_sse2(in, out, stride, 10);
|
||||
vpx_highbd_idct8x8_64_add_sse2(in, CAST_TO_SHORTPTR(out), stride, 10);
|
||||
}
|
||||
|
||||
void idct8x8_64_add_12_sse2(const tran_low_t *in, uint8_t *out, int stride) {
|
||||
vpx_highbd_idct8x8_64_add_sse2(in, out, stride, 12);
|
||||
vpx_highbd_idct8x8_64_add_sse2(in, CAST_TO_SHORTPTR(out), stride, 12);
|
||||
}
|
||||
#endif // HAVE_SSE2
|
||||
#endif // CONFIG_VP9_HIGHBITDEPTH
|
||||
@@ -257,7 +257,7 @@ class FwdTrans8x8TestBase {
|
||||
#if CONFIG_VP9_HIGHBITDEPTH
|
||||
} else {
|
||||
ASM_REGISTER_STATE_CHECK(
|
||||
RunInvTxfm(test_temp_block, CONVERT_TO_BYTEPTR(dst16), pitch_));
|
||||
RunInvTxfm(test_temp_block, CAST_TO_BYTEPTR(dst16), pitch_));
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -340,7 +340,7 @@ class FwdTrans8x8TestBase {
|
||||
#if CONFIG_VP9_HIGHBITDEPTH
|
||||
} else {
|
||||
ASM_REGISTER_STATE_CHECK(
|
||||
RunInvTxfm(test_temp_block, CONVERT_TO_BYTEPTR(dst16), pitch_));
|
||||
RunInvTxfm(test_temp_block, CAST_TO_BYTEPTR(dst16), pitch_));
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -413,7 +413,7 @@ class FwdTrans8x8TestBase {
|
||||
#if CONFIG_VP9_HIGHBITDEPTH
|
||||
} else {
|
||||
ASM_REGISTER_STATE_CHECK(
|
||||
RunInvTxfm(coeff, CONVERT_TO_BYTEPTR(dst16), pitch_));
|
||||
RunInvTxfm(coeff, CAST_TO_BYTEPTR(dst16), pitch_));
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -497,9 +497,9 @@ class FwdTrans8x8TestBase {
|
||||
ASM_REGISTER_STATE_CHECK(RunInvTxfm(coeff, dst, pitch_));
|
||||
#if CONFIG_VP9_HIGHBITDEPTH
|
||||
} else {
|
||||
ref_txfm(coeff, CONVERT_TO_BYTEPTR(ref16), pitch_);
|
||||
ref_txfm(coeff, CAST_TO_BYTEPTR(ref16), pitch_);
|
||||
ASM_REGISTER_STATE_CHECK(
|
||||
RunInvTxfm(coeff, CONVERT_TO_BYTEPTR(dst16), pitch_));
|
||||
RunInvTxfm(coeff, CAST_TO_BYTEPTR(dst16), pitch_));
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -511,8 +511,8 @@ class FwdTrans8x8TestBase {
|
||||
const int diff = dst[j] - ref[j];
|
||||
#endif
|
||||
const uint32_t error = diff * diff;
|
||||
EXPECT_EQ(0u, error) << "Error: 8x8 IDCT has error " << error
|
||||
<< " at index " << j;
|
||||
EXPECT_EQ(0u, error)
|
||||
<< "Error: 8x8 IDCT has error " << error << " at index " << j;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -671,16 +671,11 @@ INSTANTIATE_TEST_CASE_P(
|
||||
#endif // CONFIG_VP9_HIGHBITDEPTH
|
||||
|
||||
#if HAVE_NEON && !CONFIG_EMULATE_HARDWARE
|
||||
#if CONFIG_VP9_HIGHBITDEPTH
|
||||
INSTANTIATE_TEST_CASE_P(NEON, FwdTrans8x8DCT,
|
||||
::testing::Values(make_tuple(&vpx_fdct8x8_c,
|
||||
&vpx_idct8x8_64_add_neon,
|
||||
0, VPX_BITS_8)));
|
||||
#else // !CONFIG_VP9_HIGHBITDEPTH
|
||||
INSTANTIATE_TEST_CASE_P(NEON, FwdTrans8x8DCT,
|
||||
::testing::Values(make_tuple(&vpx_fdct8x8_neon,
|
||||
&vpx_idct8x8_64_add_neon,
|
||||
0, VPX_BITS_8)));
|
||||
#if !CONFIG_VP9_HIGHBITDEPTH
|
||||
INSTANTIATE_TEST_CASE_P(
|
||||
NEON, FwdTrans8x8HT,
|
||||
::testing::Values(
|
||||
@@ -688,8 +683,8 @@ INSTANTIATE_TEST_CASE_P(
|
||||
make_tuple(&vp9_fht8x8_c, &vp9_iht8x8_64_add_neon, 1, VPX_BITS_8),
|
||||
make_tuple(&vp9_fht8x8_c, &vp9_iht8x8_64_add_neon, 2, VPX_BITS_8),
|
||||
make_tuple(&vp9_fht8x8_c, &vp9_iht8x8_64_add_neon, 3, VPX_BITS_8)));
|
||||
#endif // CONFIG_VP9_HIGHBITDEPTH
|
||||
#endif // HAVE_NEON && !CONFIG_VP9_HIGHBITDEPTH && !CONFIG_EMULATE_HARDWARE
|
||||
#endif // !CONFIG_VP9_HIGHBITDEPTH
|
||||
#endif // HAVE_NEON && !CONFIG_EMULATE_HARDWARE
|
||||
|
||||
#if HAVE_SSE2 && !CONFIG_VP9_HIGHBITDEPTH && !CONFIG_EMULATE_HARDWARE
|
||||
INSTANTIATE_TEST_CASE_P(SSE2, FwdTrans8x8DCT,
|
||||
@@ -744,7 +739,7 @@ INSTANTIATE_TEST_CASE_P(
|
||||
!CONFIG_EMULATE_HARDWARE
|
||||
INSTANTIATE_TEST_CASE_P(SSSE3, FwdTrans8x8DCT,
|
||||
::testing::Values(make_tuple(&vpx_fdct8x8_ssse3,
|
||||
&vpx_idct8x8_64_add_ssse3,
|
||||
&vpx_idct8x8_64_add_sse2,
|
||||
0, VPX_BITS_8)));
|
||||
#endif
|
||||
|
||||
@@ -761,4 +756,11 @@ INSTANTIATE_TEST_CASE_P(
|
||||
make_tuple(&vp9_fht8x8_msa, &vp9_iht8x8_64_add_msa, 2, VPX_BITS_8),
|
||||
make_tuple(&vp9_fht8x8_msa, &vp9_iht8x8_64_add_msa, 3, VPX_BITS_8)));
|
||||
#endif // HAVE_MSA && !CONFIG_VP9_HIGHBITDEPTH && !CONFIG_EMULATE_HARDWARE
|
||||
|
||||
#if HAVE_VSX && !CONFIG_VP9_HIGHBITDEPTH && !CONFIG_EMULATE_HARDWARE
|
||||
INSTANTIATE_TEST_CASE_P(VSX, FwdTrans8x8DCT,
|
||||
::testing::Values(make_tuple(&vpx_fdct8x8_c,
|
||||
&vpx_idct8x8_64_add_vsx, 0,
|
||||
VPX_BITS_8)));
|
||||
#endif // HAVE_VSX && !CONFIG_VP9_HIGHBITDEPTH && !CONFIG_EMULATE_HARDWARE
|
||||
} // namespace
|
||||
|
||||
@@ -13,6 +13,7 @@
|
||||
#include "third_party/googletest/src/include/gtest/gtest.h"
|
||||
|
||||
#include "./vpx_dsp_rtcd.h"
|
||||
#include "vpx_ports/vpx_timer.h"
|
||||
|
||||
#include "test/acm_random.h"
|
||||
#include "test/register_state_check.h"
|
||||
@@ -21,7 +22,8 @@ namespace {
|
||||
|
||||
using ::libvpx_test::ACMRandom;
|
||||
|
||||
typedef void (*HadamardFunc)(const int16_t *a, int a_stride, int16_t *b);
|
||||
typedef void (*HadamardFunc)(const int16_t *a, ptrdiff_t a_stride,
|
||||
tran_low_t *b);
|
||||
|
||||
void hadamard_loop(const int16_t *a, int a_stride, int16_t *out) {
|
||||
int16_t b[8];
|
||||
@@ -46,18 +48,16 @@ void hadamard_loop(const int16_t *a, int a_stride, int16_t *out) {
|
||||
out[5] = c[3] - c[7];
|
||||
}
|
||||
|
||||
void reference_hadamard8x8(const int16_t *a, int a_stride, int16_t *b) {
|
||||
void reference_hadamard8x8(const int16_t *a, int a_stride, tran_low_t *b) {
|
||||
int16_t buf[64];
|
||||
for (int i = 0; i < 8; ++i) {
|
||||
hadamard_loop(a + i, a_stride, buf + i * 8);
|
||||
}
|
||||
int16_t buf2[64];
|
||||
for (int i = 0; i < 8; ++i) hadamard_loop(a + i, a_stride, buf + i * 8);
|
||||
for (int i = 0; i < 8; ++i) hadamard_loop(buf + i, 8, buf2 + i * 8);
|
||||
|
||||
for (int i = 0; i < 8; ++i) {
|
||||
hadamard_loop(buf + i, 8, b + i * 8);
|
||||
}
|
||||
for (int i = 0; i < 64; ++i) b[i] = (tran_low_t)buf2[i];
|
||||
}
|
||||
|
||||
void reference_hadamard16x16(const int16_t *a, int a_stride, int16_t *b) {
|
||||
void reference_hadamard16x16(const int16_t *a, int a_stride, tran_low_t *b) {
|
||||
/* The source is a 16x16 block. The destination is rearranged to 8x32.
|
||||
* Input is 9 bit. */
|
||||
reference_hadamard8x8(a + 0 + 0 * a_stride, a_stride, b + 0);
|
||||
@@ -68,16 +68,16 @@ void reference_hadamard16x16(const int16_t *a, int a_stride, int16_t *b) {
|
||||
/* Overlay the 8x8 blocks and combine. */
|
||||
for (int i = 0; i < 64; ++i) {
|
||||
/* 8x8 steps the range up to 15 bits. */
|
||||
const int16_t a0 = b[0];
|
||||
const int16_t a1 = b[64];
|
||||
const int16_t a2 = b[128];
|
||||
const int16_t a3 = b[192];
|
||||
const tran_low_t a0 = b[0];
|
||||
const tran_low_t a1 = b[64];
|
||||
const tran_low_t a2 = b[128];
|
||||
const tran_low_t a3 = b[192];
|
||||
|
||||
/* Prevent the result from escaping int16_t. */
|
||||
const int16_t b0 = (a0 + a1) >> 1;
|
||||
const int16_t b1 = (a0 - a1) >> 1;
|
||||
const int16_t b2 = (a2 + a3) >> 1;
|
||||
const int16_t b3 = (a2 - a3) >> 1;
|
||||
const tran_low_t b0 = (a0 + a1) >> 1;
|
||||
const tran_low_t b1 = (a0 - a1) >> 1;
|
||||
const tran_low_t b2 = (a2 + a3) >> 1;
|
||||
const tran_low_t b3 = (a2 - a3) >> 1;
|
||||
|
||||
/* Store a 16 bit value. */
|
||||
b[0] = b0 + b2;
|
||||
@@ -101,12 +101,35 @@ class HadamardTestBase : public ::testing::TestWithParam<HadamardFunc> {
|
||||
ACMRandom rnd_;
|
||||
};
|
||||
|
||||
void HadamardSpeedTest(const char *name, HadamardFunc const func,
|
||||
const int16_t *input, int stride, tran_low_t *output,
|
||||
int times) {
|
||||
int i;
|
||||
vpx_usec_timer timer;
|
||||
|
||||
vpx_usec_timer_start(&timer);
|
||||
for (i = 0; i < times; ++i) {
|
||||
func(input, stride, output);
|
||||
}
|
||||
vpx_usec_timer_mark(&timer);
|
||||
|
||||
const int elapsed_time = static_cast<int>(vpx_usec_timer_elapsed(&timer));
|
||||
printf("%s[%12d runs]: %d us\n", name, times, elapsed_time);
|
||||
}
|
||||
|
||||
class Hadamard8x8Test : public HadamardTestBase {};
|
||||
|
||||
void HadamardSpeedTest8x8(HadamardFunc const func, int times) {
|
||||
DECLARE_ALIGNED(16, int16_t, input[64]);
|
||||
DECLARE_ALIGNED(16, tran_low_t, output[64]);
|
||||
memset(input, 1, sizeof(input));
|
||||
HadamardSpeedTest("Hadamard8x8", func, input, 8, output, times);
|
||||
}
|
||||
|
||||
TEST_P(Hadamard8x8Test, CompareReferenceRandom) {
|
||||
DECLARE_ALIGNED(16, int16_t, a[64]);
|
||||
DECLARE_ALIGNED(16, int16_t, b[64]);
|
||||
int16_t b_ref[64];
|
||||
DECLARE_ALIGNED(16, tran_low_t, b[64]);
|
||||
tran_low_t b_ref[64];
|
||||
for (int i = 0; i < 64; ++i) {
|
||||
a[i] = rnd_.Rand9Signed();
|
||||
}
|
||||
@@ -124,8 +147,8 @@ TEST_P(Hadamard8x8Test, CompareReferenceRandom) {
|
||||
|
||||
TEST_P(Hadamard8x8Test, VaryStride) {
|
||||
DECLARE_ALIGNED(16, int16_t, a[64 * 8]);
|
||||
DECLARE_ALIGNED(16, int16_t, b[64]);
|
||||
int16_t b_ref[64];
|
||||
DECLARE_ALIGNED(16, tran_low_t, b[64]);
|
||||
tran_low_t b_ref[64];
|
||||
for (int i = 0; i < 64 * 8; ++i) {
|
||||
a[i] = rnd_.Rand9Signed();
|
||||
}
|
||||
@@ -144,6 +167,12 @@ TEST_P(Hadamard8x8Test, VaryStride) {
|
||||
}
|
||||
}
|
||||
|
||||
TEST_P(Hadamard8x8Test, DISABLED_Speed) {
|
||||
HadamardSpeedTest8x8(h_func_, 10);
|
||||
HadamardSpeedTest8x8(h_func_, 10000);
|
||||
HadamardSpeedTest8x8(h_func_, 10000000);
|
||||
}
|
||||
|
||||
INSTANTIATE_TEST_CASE_P(C, Hadamard8x8Test,
|
||||
::testing::Values(&vpx_hadamard_8x8_c));
|
||||
|
||||
@@ -162,12 +191,33 @@ INSTANTIATE_TEST_CASE_P(NEON, Hadamard8x8Test,
|
||||
::testing::Values(&vpx_hadamard_8x8_neon));
|
||||
#endif // HAVE_NEON
|
||||
|
||||
// TODO(jingning): Remove highbitdepth flag when the SIMD functions are
|
||||
// in place and turn on the unit test.
|
||||
#if !CONFIG_VP9_HIGHBITDEPTH
|
||||
#if HAVE_MSA
|
||||
INSTANTIATE_TEST_CASE_P(MSA, Hadamard8x8Test,
|
||||
::testing::Values(&vpx_hadamard_8x8_msa));
|
||||
#endif // HAVE_MSA
|
||||
#endif // !CONFIG_VP9_HIGHBITDEPTH
|
||||
|
||||
#if HAVE_VSX
|
||||
INSTANTIATE_TEST_CASE_P(VSX, Hadamard8x8Test,
|
||||
::testing::Values(&vpx_hadamard_8x8_vsx));
|
||||
#endif // HAVE_VSX
|
||||
|
||||
class Hadamard16x16Test : public HadamardTestBase {};
|
||||
|
||||
void HadamardSpeedTest16x16(HadamardFunc const func, int times) {
|
||||
DECLARE_ALIGNED(16, int16_t, input[256]);
|
||||
DECLARE_ALIGNED(16, tran_low_t, output[256]);
|
||||
memset(input, 1, sizeof(input));
|
||||
HadamardSpeedTest("Hadamard16x16", func, input, 16, output, times);
|
||||
}
|
||||
|
||||
TEST_P(Hadamard16x16Test, CompareReferenceRandom) {
|
||||
DECLARE_ALIGNED(16, int16_t, a[16 * 16]);
|
||||
DECLARE_ALIGNED(16, int16_t, b[16 * 16]);
|
||||
int16_t b_ref[16 * 16];
|
||||
DECLARE_ALIGNED(16, tran_low_t, b[16 * 16]);
|
||||
tran_low_t b_ref[16 * 16];
|
||||
for (int i = 0; i < 16 * 16; ++i) {
|
||||
a[i] = rnd_.Rand9Signed();
|
||||
}
|
||||
@@ -185,8 +235,8 @@ TEST_P(Hadamard16x16Test, CompareReferenceRandom) {
|
||||
|
||||
TEST_P(Hadamard16x16Test, VaryStride) {
|
||||
DECLARE_ALIGNED(16, int16_t, a[16 * 16 * 8]);
|
||||
DECLARE_ALIGNED(16, int16_t, b[16 * 16]);
|
||||
int16_t b_ref[16 * 16];
|
||||
DECLARE_ALIGNED(16, tran_low_t, b[16 * 16]);
|
||||
tran_low_t b_ref[16 * 16];
|
||||
for (int i = 0; i < 16 * 16 * 8; ++i) {
|
||||
a[i] = rnd_.Rand9Signed();
|
||||
}
|
||||
@@ -205,6 +255,12 @@ TEST_P(Hadamard16x16Test, VaryStride) {
|
||||
}
|
||||
}
|
||||
|
||||
TEST_P(Hadamard16x16Test, DISABLED_Speed) {
|
||||
HadamardSpeedTest16x16(h_func_, 10);
|
||||
HadamardSpeedTest16x16(h_func_, 10000);
|
||||
HadamardSpeedTest16x16(h_func_, 10000000);
|
||||
}
|
||||
|
||||
INSTANTIATE_TEST_CASE_P(C, Hadamard16x16Test,
|
||||
::testing::Values(&vpx_hadamard_16x16_c));
|
||||
|
||||
@@ -213,8 +269,25 @@ INSTANTIATE_TEST_CASE_P(SSE2, Hadamard16x16Test,
|
||||
::testing::Values(&vpx_hadamard_16x16_sse2));
|
||||
#endif // HAVE_SSE2
|
||||
|
||||
#if HAVE_AVX2
|
||||
INSTANTIATE_TEST_CASE_P(AVX2, Hadamard16x16Test,
|
||||
::testing::Values(&vpx_hadamard_16x16_avx2));
|
||||
#endif // HAVE_AVX2
|
||||
|
||||
#if HAVE_VSX
|
||||
INSTANTIATE_TEST_CASE_P(VSX, Hadamard16x16Test,
|
||||
::testing::Values(&vpx_hadamard_16x16_vsx));
|
||||
#endif // HAVE_VSX
|
||||
|
||||
#if HAVE_NEON
|
||||
INSTANTIATE_TEST_CASE_P(NEON, Hadamard16x16Test,
|
||||
::testing::Values(&vpx_hadamard_16x16_neon));
|
||||
#endif // HAVE_NEON
|
||||
|
||||
#if !CONFIG_VP9_HIGHBITDEPTH
|
||||
#if HAVE_MSA
|
||||
INSTANTIATE_TEST_CASE_P(MSA, Hadamard16x16Test,
|
||||
::testing::Values(&vpx_hadamard_16x16_msa));
|
||||
#endif // HAVE_MSA
|
||||
#endif // !CONFIG_VP9_HIGHBITDEPTH
|
||||
} // namespace
|
||||
|
||||
@@ -13,6 +13,7 @@
|
||||
|
||||
#include "third_party/googletest/src/include/gtest/gtest.h"
|
||||
|
||||
#include "test/buffer.h"
|
||||
#include "test/clear_system_state.h"
|
||||
#include "test/register_state_check.h"
|
||||
#include "vpx/vpx_integer.h"
|
||||
@@ -21,110 +22,156 @@ typedef void (*IdctFunc)(int16_t *input, unsigned char *pred_ptr,
|
||||
int pred_stride, unsigned char *dst_ptr,
|
||||
int dst_stride);
|
||||
namespace {
|
||||
|
||||
using libvpx_test::Buffer;
|
||||
|
||||
class IDCTTest : public ::testing::TestWithParam<IdctFunc> {
|
||||
protected:
|
||||
virtual void SetUp() {
|
||||
int i;
|
||||
|
||||
UUT = GetParam();
|
||||
memset(input, 0, sizeof(input));
|
||||
/* Set up guard blocks */
|
||||
for (i = 0; i < 256; i++) output[i] = ((i & 0xF) < 4 && (i < 64)) ? 0 : -1;
|
||||
|
||||
input = new Buffer<int16_t>(4, 4, 0);
|
||||
ASSERT_TRUE(input != NULL);
|
||||
ASSERT_TRUE(input->Init());
|
||||
predict = new Buffer<uint8_t>(4, 4, 3);
|
||||
ASSERT_TRUE(predict != NULL);
|
||||
ASSERT_TRUE(predict->Init());
|
||||
output = new Buffer<uint8_t>(4, 4, 3);
|
||||
ASSERT_TRUE(output != NULL);
|
||||
ASSERT_TRUE(output->Init());
|
||||
}
|
||||
|
||||
virtual void TearDown() { libvpx_test::ClearSystemState(); }
|
||||
virtual void TearDown() {
|
||||
delete input;
|
||||
delete predict;
|
||||
delete output;
|
||||
libvpx_test::ClearSystemState();
|
||||
}
|
||||
|
||||
IdctFunc UUT;
|
||||
int16_t input[16];
|
||||
unsigned char output[256];
|
||||
unsigned char predict[256];
|
||||
Buffer<int16_t> *input;
|
||||
Buffer<uint8_t> *predict;
|
||||
Buffer<uint8_t> *output;
|
||||
};
|
||||
|
||||
TEST_P(IDCTTest, TestGuardBlocks) {
|
||||
int i;
|
||||
|
||||
for (i = 0; i < 256; i++) {
|
||||
if ((i & 0xF) < 4 && i < 64)
|
||||
EXPECT_EQ(0, output[i]) << i;
|
||||
else
|
||||
EXPECT_EQ(255, output[i]);
|
||||
}
|
||||
}
|
||||
|
||||
TEST_P(IDCTTest, TestAllZeros) {
|
||||
int i;
|
||||
// When the input is '0' the output will be '0'.
|
||||
input->Set(0);
|
||||
predict->Set(0);
|
||||
output->Set(0);
|
||||
|
||||
ASM_REGISTER_STATE_CHECK(UUT(input, output, 16, output, 16));
|
||||
ASM_REGISTER_STATE_CHECK(UUT(input->TopLeftPixel(), predict->TopLeftPixel(),
|
||||
predict->stride(), output->TopLeftPixel(),
|
||||
output->stride()));
|
||||
|
||||
for (i = 0; i < 256; i++) {
|
||||
if ((i & 0xF) < 4 && i < 64)
|
||||
EXPECT_EQ(0, output[i]) << "i==" << i;
|
||||
else
|
||||
EXPECT_EQ(255, output[i]) << "i==" << i;
|
||||
}
|
||||
ASSERT_TRUE(input->CheckValues(0));
|
||||
ASSERT_TRUE(input->CheckPadding());
|
||||
ASSERT_TRUE(output->CheckValues(0));
|
||||
ASSERT_TRUE(output->CheckPadding());
|
||||
}
|
||||
|
||||
TEST_P(IDCTTest, TestAllOnes) {
|
||||
int i;
|
||||
input->Set(0);
|
||||
// When the first element is '4' it will fill the output buffer with '1'.
|
||||
input->TopLeftPixel()[0] = 4;
|
||||
predict->Set(0);
|
||||
output->Set(0);
|
||||
|
||||
input[0] = 4;
|
||||
ASM_REGISTER_STATE_CHECK(UUT(input, output, 16, output, 16));
|
||||
ASM_REGISTER_STATE_CHECK(UUT(input->TopLeftPixel(), predict->TopLeftPixel(),
|
||||
predict->stride(), output->TopLeftPixel(),
|
||||
output->stride()));
|
||||
|
||||
for (i = 0; i < 256; i++) {
|
||||
if ((i & 0xF) < 4 && i < 64)
|
||||
EXPECT_EQ(1, output[i]) << "i==" << i;
|
||||
else
|
||||
EXPECT_EQ(255, output[i]) << "i==" << i;
|
||||
}
|
||||
ASSERT_TRUE(output->CheckValues(1));
|
||||
ASSERT_TRUE(output->CheckPadding());
|
||||
}
|
||||
|
||||
TEST_P(IDCTTest, TestAddOne) {
|
||||
int i;
|
||||
// Set the transform output to '1' and make sure it gets added to the
|
||||
// prediction buffer.
|
||||
input->Set(0);
|
||||
input->TopLeftPixel()[0] = 4;
|
||||
output->Set(0);
|
||||
|
||||
for (i = 0; i < 256; i++) predict[i] = i;
|
||||
input[0] = 4;
|
||||
ASM_REGISTER_STATE_CHECK(UUT(input, predict, 16, output, 16));
|
||||
|
||||
for (i = 0; i < 256; i++) {
|
||||
if ((i & 0xF) < 4 && i < 64)
|
||||
EXPECT_EQ(i + 1, output[i]) << "i==" << i;
|
||||
else
|
||||
EXPECT_EQ(255, output[i]) << "i==" << i;
|
||||
uint8_t *pred = predict->TopLeftPixel();
|
||||
for (int y = 0; y < 4; ++y) {
|
||||
for (int x = 0; x < 4; ++x) {
|
||||
pred[y * predict->stride() + x] = y * 4 + x;
|
||||
}
|
||||
}
|
||||
|
||||
ASM_REGISTER_STATE_CHECK(UUT(input->TopLeftPixel(), predict->TopLeftPixel(),
|
||||
predict->stride(), output->TopLeftPixel(),
|
||||
output->stride()));
|
||||
|
||||
uint8_t const *out = output->TopLeftPixel();
|
||||
for (int y = 0; y < 4; ++y) {
|
||||
for (int x = 0; x < 4; ++x) {
|
||||
EXPECT_EQ(1 + y * 4 + x, out[y * output->stride() + x]);
|
||||
}
|
||||
}
|
||||
|
||||
if (HasFailure()) {
|
||||
output->DumpBuffer();
|
||||
}
|
||||
|
||||
ASSERT_TRUE(output->CheckPadding());
|
||||
}
|
||||
|
||||
TEST_P(IDCTTest, TestWithData) {
|
||||
int i;
|
||||
// Test a single known input.
|
||||
predict->Set(0);
|
||||
|
||||
for (i = 0; i < 16; i++) input[i] = i;
|
||||
|
||||
ASM_REGISTER_STATE_CHECK(UUT(input, output, 16, output, 16));
|
||||
|
||||
for (i = 0; i < 256; i++) {
|
||||
if ((i & 0xF) > 3 || i > 63)
|
||||
EXPECT_EQ(255, output[i]) << "i==" << i;
|
||||
else if (i == 0)
|
||||
EXPECT_EQ(11, output[i]) << "i==" << i;
|
||||
else if (i == 34)
|
||||
EXPECT_EQ(1, output[i]) << "i==" << i;
|
||||
else if (i == 2 || i == 17 || i == 32)
|
||||
EXPECT_EQ(3, output[i]) << "i==" << i;
|
||||
else
|
||||
EXPECT_EQ(0, output[i]) << "i==" << i;
|
||||
int16_t *in = input->TopLeftPixel();
|
||||
for (int y = 0; y < 4; ++y) {
|
||||
for (int x = 0; x < 4; ++x) {
|
||||
in[y * input->stride() + x] = y * 4 + x;
|
||||
}
|
||||
}
|
||||
|
||||
ASM_REGISTER_STATE_CHECK(UUT(input->TopLeftPixel(), predict->TopLeftPixel(),
|
||||
predict->stride(), output->TopLeftPixel(),
|
||||
output->stride()));
|
||||
|
||||
uint8_t *out = output->TopLeftPixel();
|
||||
for (int y = 0; y < 4; ++y) {
|
||||
for (int x = 0; x < 4; ++x) {
|
||||
switch (y * 4 + x) {
|
||||
case 0: EXPECT_EQ(11, out[y * output->stride() + x]); break;
|
||||
case 2:
|
||||
case 5:
|
||||
case 8: EXPECT_EQ(3, out[y * output->stride() + x]); break;
|
||||
case 10: EXPECT_EQ(1, out[y * output->stride() + x]); break;
|
||||
default: EXPECT_EQ(0, out[y * output->stride() + x]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (HasFailure()) {
|
||||
output->DumpBuffer();
|
||||
}
|
||||
|
||||
ASSERT_TRUE(output->CheckPadding());
|
||||
}
|
||||
|
||||
INSTANTIATE_TEST_CASE_P(C, IDCTTest, ::testing::Values(vp8_short_idct4x4llm_c));
|
||||
|
||||
#if HAVE_NEON
|
||||
INSTANTIATE_TEST_CASE_P(NEON, IDCTTest,
|
||||
::testing::Values(vp8_short_idct4x4llm_neon));
|
||||
#endif
|
||||
#endif // HAVE_NEON
|
||||
|
||||
#if HAVE_MMX
|
||||
INSTANTIATE_TEST_CASE_P(MMX, IDCTTest,
|
||||
::testing::Values(vp8_short_idct4x4llm_mmx));
|
||||
#endif
|
||||
#endif // HAVE_MMX
|
||||
|
||||
#if HAVE_MSA
|
||||
INSTANTIATE_TEST_CASE_P(MSA, IDCTTest,
|
||||
::testing::Values(vp8_short_idct4x4llm_msa));
|
||||
#endif
|
||||
#endif // HAVE_MSA
|
||||
|
||||
#if HAVE_MMI
|
||||
INSTANTIATE_TEST_CASE_P(MMI, IDCTTest,
|
||||
::testing::Values(vp8_short_idct4x4llm_mmi));
|
||||
#endif // HAVE_MMI
|
||||
}
|
||||
|
||||
@@ -45,8 +45,8 @@ class InvalidFileTest : public ::libvpx_test::DecoderTest,
|
||||
|
||||
void OpenResFile(const std::string &res_file_name_) {
|
||||
res_file_ = libvpx_test::OpenTestDataFile(res_file_name_);
|
||||
ASSERT_TRUE(res_file_ != NULL) << "Result file open failed. Filename: "
|
||||
<< res_file_name_;
|
||||
ASSERT_TRUE(res_file_ != NULL)
|
||||
<< "Result file open failed. Filename: " << res_file_name_;
|
||||
}
|
||||
|
||||
virtual bool HandleDecodeResult(
|
||||
@@ -120,11 +120,23 @@ class InvalidFileTest : public ::libvpx_test::DecoderTest,
|
||||
|
||||
TEST_P(InvalidFileTest, ReturnCode) { RunTest(); }
|
||||
|
||||
#if CONFIG_VP8_DECODER
|
||||
const DecodeParam kVP8InvalidFileTests[] = {
|
||||
{ 1, "invalid-bug-1443.ivf" },
|
||||
};
|
||||
|
||||
VP8_INSTANTIATE_TEST_CASE(InvalidFileTest,
|
||||
::testing::ValuesIn(kVP8InvalidFileTests));
|
||||
#endif // CONFIG_VP8_DECODER
|
||||
|
||||
#if CONFIG_VP9_DECODER
|
||||
const DecodeParam kVP9InvalidFileTests[] = {
|
||||
{ 1, "invalid-vp90-02-v2.webm" },
|
||||
#if CONFIG_VP9_HIGHBITDEPTH
|
||||
{ 1, "invalid-vp90-2-00-quantizer-00.webm.ivf.s5861_r01-05_b6-.v2.ivf" },
|
||||
{ 1,
|
||||
"invalid-vp90-2-21-resize_inter_320x180_5_3-4.webm.ivf.s45551_r01-05_b6-."
|
||||
"ivf" },
|
||||
#endif
|
||||
{ 1, "invalid-vp90-03-v3.webm" },
|
||||
{ 1, "invalid-vp90-2-00-quantizer-11.webm.ivf.s52984_r01-05_b6-.ivf" },
|
||||
@@ -164,12 +176,12 @@ class InvalidFileInvalidPeekTest : public InvalidFileTest {
|
||||
TEST_P(InvalidFileInvalidPeekTest, ReturnCode) { RunTest(); }
|
||||
|
||||
#if CONFIG_VP8_DECODER
|
||||
const DecodeParam kVP8InvalidFileTests[] = {
|
||||
const DecodeParam kVP8InvalidPeekTests[] = {
|
||||
{ 1, "invalid-vp80-00-comprehensive-018.ivf.2kf_0x6.ivf" },
|
||||
};
|
||||
|
||||
VP8_INSTANTIATE_TEST_CASE(InvalidFileInvalidPeekTest,
|
||||
::testing::ValuesIn(kVP8InvalidFileTests));
|
||||
::testing::ValuesIn(kVP8InvalidPeekTests));
|
||||
#endif // CONFIG_VP8_DECODER
|
||||
|
||||
#if CONFIG_VP9_DECODER
|
||||
|
||||
@@ -47,8 +47,8 @@ class IVFVideoSource : public CompressedVideoSource {
|
||||
|
||||
virtual void Begin() {
|
||||
input_file_ = OpenTestDataFile(file_name_);
|
||||
ASSERT_TRUE(input_file_ != NULL) << "Input file open failed. Filename: "
|
||||
<< file_name_;
|
||||
ASSERT_TRUE(input_file_ != NULL)
|
||||
<< "Input file open failed. Filename: " << file_name_;
|
||||
|
||||
// Read file header
|
||||
uint8_t file_hdr[kIvfFileHdrSize];
|
||||
|
||||
@@ -135,8 +135,8 @@ TEST_P(KeyframeTest, TestAutoKeyframe) {
|
||||
for (std::vector<vpx_codec_pts_t>::const_iterator iter = kf_pts_list_.begin();
|
||||
iter != kf_pts_list_.end(); ++iter) {
|
||||
if (deadline_ == VPX_DL_REALTIME && *iter > 0)
|
||||
EXPECT_EQ(0, (*iter - 1) % 30) << "Unexpected keyframe at frame "
|
||||
<< *iter;
|
||||
EXPECT_EQ(0, (*iter - 1) % 30)
|
||||
<< "Unexpected keyframe at frame " << *iter;
|
||||
else
|
||||
EXPECT_EQ(0, *iter % 30) << "Unexpected keyframe at frame " << *iter;
|
||||
}
|
||||
|
||||
@@ -66,34 +66,34 @@ class LevelTest
|
||||
int level_;
|
||||
};
|
||||
|
||||
TEST_P(LevelTest, TestTargetLevel11) {
|
||||
TEST_P(LevelTest, TestTargetLevel11Large) {
|
||||
ASSERT_NE(encoding_mode_, ::libvpx_test::kRealTime);
|
||||
::libvpx_test::I420VideoSource video("hantro_odd.yuv", 208, 144, 30, 1, 0,
|
||||
90);
|
||||
60);
|
||||
target_level_ = 11;
|
||||
cfg_.rc_target_bitrate = 150;
|
||||
ASSERT_NO_FATAL_FAILURE(RunLoop(&video));
|
||||
ASSERT_EQ(target_level_, level_);
|
||||
ASSERT_GE(target_level_, level_);
|
||||
}
|
||||
|
||||
TEST_P(LevelTest, TestTargetLevel20) {
|
||||
TEST_P(LevelTest, TestTargetLevel20Large) {
|
||||
ASSERT_NE(encoding_mode_, ::libvpx_test::kRealTime);
|
||||
::libvpx_test::I420VideoSource video("hantro_collage_w352h288.yuv", 352, 288,
|
||||
30, 1, 0, 90);
|
||||
30, 1, 0, 60);
|
||||
target_level_ = 20;
|
||||
cfg_.rc_target_bitrate = 1200;
|
||||
ASSERT_NO_FATAL_FAILURE(RunLoop(&video));
|
||||
ASSERT_EQ(target_level_, level_);
|
||||
ASSERT_GE(target_level_, level_);
|
||||
}
|
||||
|
||||
TEST_P(LevelTest, TestTargetLevel31) {
|
||||
TEST_P(LevelTest, TestTargetLevel31Large) {
|
||||
ASSERT_NE(encoding_mode_, ::libvpx_test::kRealTime);
|
||||
::libvpx_test::I420VideoSource video("niklas_1280_720_30.y4m", 1280, 720, 30,
|
||||
1, 0, 60);
|
||||
target_level_ = 31;
|
||||
cfg_.rc_target_bitrate = 8000;
|
||||
ASSERT_NO_FATAL_FAILURE(RunLoop(&video));
|
||||
ASSERT_EQ(target_level_, level_);
|
||||
ASSERT_GE(target_level_, level_);
|
||||
}
|
||||
|
||||
// Test for keeping level stats only
|
||||
@@ -103,11 +103,11 @@ TEST_P(LevelTest, TestTargetLevel0) {
|
||||
target_level_ = 0;
|
||||
min_gf_internal_ = 4;
|
||||
ASSERT_NO_FATAL_FAILURE(RunLoop(&video));
|
||||
ASSERT_EQ(11, level_);
|
||||
ASSERT_GE(11, level_);
|
||||
|
||||
cfg_.rc_target_bitrate = 1600;
|
||||
ASSERT_NO_FATAL_FAILURE(RunLoop(&video));
|
||||
ASSERT_EQ(20, level_);
|
||||
ASSERT_GE(20, level_);
|
||||
}
|
||||
|
||||
// Test for level control being turned off
|
||||
@@ -130,7 +130,7 @@ TEST_P(LevelTest, TestTargetLevelApi) {
|
||||
if (level == 10 || level == 11 || level == 20 || level == 21 ||
|
||||
level == 30 || level == 31 || level == 40 || level == 41 ||
|
||||
level == 50 || level == 51 || level == 52 || level == 60 ||
|
||||
level == 61 || level == 62 || level == 0 || level == 255)
|
||||
level == 61 || level == 62 || level == 0 || level == 1 || level == 255)
|
||||
EXPECT_EQ(VPX_CODEC_OK,
|
||||
vpx_codec_control(&enc, VP9E_SET_TARGET_LEVEL, level));
|
||||
else
|
||||
|
||||
@@ -107,10 +107,10 @@ TEST_P(MinMaxTest, CompareReferenceAndVaryStride) {
|
||||
int min_ref, max_ref, min, max;
|
||||
reference_minmax(a, a_stride, b, b_stride, &min_ref, &max_ref);
|
||||
ASM_REGISTER_STATE_CHECK(mm_func_(a, a_stride, b, b_stride, &min, &max));
|
||||
EXPECT_EQ(max_ref, max) << "when a_stride = " << a_stride
|
||||
<< " and b_stride = " << b_stride;
|
||||
EXPECT_EQ(min_ref, min) << "when a_stride = " << a_stride
|
||||
<< " and b_stride = " << b_stride;
|
||||
EXPECT_EQ(max_ref, max)
|
||||
<< "when a_stride = " << a_stride << " and b_stride = " << b_stride;
|
||||
EXPECT_EQ(min_ref, min)
|
||||
<< "when a_stride = " << a_stride << " and b_stride = " << b_stride;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -127,4 +127,9 @@ INSTANTIATE_TEST_CASE_P(NEON, MinMaxTest,
|
||||
::testing::Values(&vpx_minmax_8x8_neon));
|
||||
#endif
|
||||
|
||||
#if HAVE_MSA
|
||||
INSTANTIATE_TEST_CASE_P(MSA, MinMaxTest,
|
||||
::testing::Values(&vpx_minmax_8x8_msa));
|
||||
#endif
|
||||
|
||||
} // namespace
|
||||
|
||||
@@ -43,9 +43,11 @@ void wrapper(const tran_low_t *in, uint8_t *out, int stride, int bd) {
|
||||
}
|
||||
|
||||
#if CONFIG_VP9_HIGHBITDEPTH
|
||||
template <InvTxfmWithBdFunc fn>
|
||||
typedef void (*InvTxfmHighbdFunc)(const tran_low_t *in, uint16_t *out,
|
||||
int stride, int bd);
|
||||
template <InvTxfmHighbdFunc fn>
|
||||
void highbd_wrapper(const tran_low_t *in, uint8_t *out, int stride, int bd) {
|
||||
fn(in, CONVERT_TO_BYTEPTR(out), stride, bd);
|
||||
fn(in, CAST_TO_SHORTPTR(out), stride, bd);
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -55,41 +57,14 @@ typedef std::tr1::tuple<FwdTxfmFunc, InvTxfmWithBdFunc, InvTxfmWithBdFunc,
|
||||
const int kMaxNumCoeffs = 1024;
|
||||
const int kCountTestBlock = 1000;
|
||||
|
||||
// https://bugs.chromium.org/p/webm/issues/detail?id=1332
|
||||
// The functions specified do not pass with INT16_MIN/MAX. They fail at the
|
||||
// value specified, but pass when 1 is added/subtracted.
|
||||
int16_t MaxSupportedCoeff(InvTxfmWithBdFunc a) {
|
||||
#if HAVE_SSSE3 && ARCH_X86_64 && !CONFIG_EMULATE_HARDWARE
|
||||
if (a == &wrapper<vpx_idct8x8_64_add_ssse3> ||
|
||||
a == &wrapper<vpx_idct8x8_12_add_ssse3>) {
|
||||
return 23625 - 1;
|
||||
}
|
||||
#else
|
||||
(void)a;
|
||||
#endif
|
||||
return std::numeric_limits<int16_t>::max();
|
||||
}
|
||||
|
||||
int16_t MinSupportedCoeff(InvTxfmWithBdFunc a) {
|
||||
#if HAVE_SSSE3 && ARCH_X86_64 && !CONFIG_EMULATE_HARDWARE
|
||||
if (a == &wrapper<vpx_idct8x8_64_add_ssse3> ||
|
||||
a == &wrapper<vpx_idct8x8_12_add_ssse3>) {
|
||||
return -23625 + 1;
|
||||
}
|
||||
#else
|
||||
(void)a;
|
||||
#endif
|
||||
return std::numeric_limits<int16_t>::min();
|
||||
}
|
||||
|
||||
class PartialIDctTest : public ::testing::TestWithParam<PartialInvTxfmParam> {
|
||||
public:
|
||||
virtual ~PartialIDctTest() {}
|
||||
virtual void SetUp() {
|
||||
rnd_.Reset(ACMRandom::DeterministicSeed());
|
||||
ftxfm_ = GET_PARAM(0);
|
||||
full_itxfm_ = GET_PARAM(1);
|
||||
partial_itxfm_ = GET_PARAM(2);
|
||||
fwd_txfm_ = GET_PARAM(0);
|
||||
full_inv_txfm_ = GET_PARAM(1);
|
||||
partial_inv_txfm_ = GET_PARAM(2);
|
||||
tx_size_ = GET_PARAM(3);
|
||||
last_nonzero_ = GET_PARAM(4);
|
||||
bit_depth_ = GET_PARAM(5);
|
||||
@@ -153,12 +128,12 @@ class PartialIDctTest : public ::testing::TestWithParam<PartialInvTxfmParam> {
|
||||
}
|
||||
|
||||
void InitInput() {
|
||||
const int max_coeff = 32766 / 4;
|
||||
int max_energy_leftover = max_coeff * max_coeff;
|
||||
const int64_t max_coeff = (32766 << (bit_depth_ - 8)) / 4;
|
||||
int64_t max_energy_leftover = max_coeff * max_coeff;
|
||||
for (int j = 0; j < last_nonzero_; ++j) {
|
||||
int16_t coeff = static_cast<int16_t>(sqrt(1.0 * max_energy_leftover) *
|
||||
(rnd_.Rand16() - 32768) / 65536);
|
||||
max_energy_leftover -= coeff * coeff;
|
||||
tran_low_t coeff = static_cast<tran_low_t>(
|
||||
sqrt(1.0 * max_energy_leftover) * (rnd_.Rand16() - 32768) / 65536);
|
||||
max_energy_leftover -= static_cast<int64_t>(coeff) * coeff;
|
||||
if (max_energy_leftover < 0) {
|
||||
max_energy_leftover = 0;
|
||||
coeff = 0;
|
||||
@@ -167,6 +142,36 @@ class PartialIDctTest : public ::testing::TestWithParam<PartialInvTxfmParam> {
|
||||
}
|
||||
}
|
||||
|
||||
void PrintDiff() {
|
||||
if (memcmp(output_block_ref_, output_block_,
|
||||
pixel_size_ * output_block_size_)) {
|
||||
uint16_t ref, opt;
|
||||
for (int y = 0; y < size_; y++) {
|
||||
for (int x = 0; x < size_; x++) {
|
||||
if (pixel_size_ == 1) {
|
||||
ref = output_block_ref_[y * stride_ + x];
|
||||
opt = output_block_[y * stride_ + x];
|
||||
} else {
|
||||
ref = reinterpret_cast<uint16_t *>(
|
||||
output_block_ref_)[y * stride_ + x];
|
||||
opt = reinterpret_cast<uint16_t *>(output_block_)[y * stride_ + x];
|
||||
}
|
||||
if (ref != opt) {
|
||||
printf("dest[%d][%d] diff:%6d (ref),%6d (opt)\n", y, x, ref, opt);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
printf("\ninput_block_:\n");
|
||||
for (int y = 0; y < size_; y++) {
|
||||
for (int x = 0; x < size_; x++) {
|
||||
printf("%6d,", input_block_[y * size_ + x]);
|
||||
}
|
||||
printf("\n");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected:
|
||||
int last_nonzero_;
|
||||
TX_SIZE tx_size_;
|
||||
@@ -180,34 +185,43 @@ class PartialIDctTest : public ::testing::TestWithParam<PartialInvTxfmParam> {
|
||||
int output_block_size_;
|
||||
int bit_depth_;
|
||||
int mask_;
|
||||
FwdTxfmFunc ftxfm_;
|
||||
InvTxfmWithBdFunc full_itxfm_;
|
||||
InvTxfmWithBdFunc partial_itxfm_;
|
||||
FwdTxfmFunc fwd_txfm_;
|
||||
InvTxfmWithBdFunc full_inv_txfm_;
|
||||
InvTxfmWithBdFunc partial_inv_txfm_;
|
||||
ACMRandom rnd_;
|
||||
};
|
||||
|
||||
TEST_P(PartialIDctTest, RunQuantCheck) {
|
||||
const int count_test_block = (size_ != 4) ? kCountTestBlock : 65536;
|
||||
DECLARE_ALIGNED(16, int16_t, input_extreme_block[kMaxNumCoeffs]);
|
||||
DECLARE_ALIGNED(16, tran_low_t, output_ref_block[kMaxNumCoeffs]);
|
||||
|
||||
InitMem();
|
||||
for (int i = 0; i < kCountTestBlock * kCountTestBlock; ++i) {
|
||||
|
||||
for (int i = 0; i < count_test_block; ++i) {
|
||||
// Initialize a test block with input range [-mask_, mask_].
|
||||
if (i == 0) {
|
||||
for (int k = 0; k < input_block_size_; ++k) {
|
||||
input_extreme_block[k] = mask_;
|
||||
}
|
||||
} else if (i == 1) {
|
||||
for (int k = 0; k < input_block_size_; ++k) {
|
||||
input_extreme_block[k] = -mask_;
|
||||
if (size_ != 4) {
|
||||
if (i == 0) {
|
||||
for (int k = 0; k < input_block_size_; ++k) {
|
||||
input_extreme_block[k] = mask_;
|
||||
}
|
||||
} else if (i == 1) {
|
||||
for (int k = 0; k < input_block_size_; ++k) {
|
||||
input_extreme_block[k] = -mask_;
|
||||
}
|
||||
} else {
|
||||
for (int k = 0; k < input_block_size_; ++k) {
|
||||
input_extreme_block[k] = rnd_.Rand8() % 2 ? mask_ : -mask_;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// Try all possible combinations.
|
||||
for (int k = 0; k < input_block_size_; ++k) {
|
||||
input_extreme_block[k] = rnd_.Rand8() % 2 ? mask_ : -mask_;
|
||||
input_extreme_block[k] = (i & (1 << k)) ? mask_ : -mask_;
|
||||
}
|
||||
}
|
||||
|
||||
ftxfm_(input_extreme_block, output_ref_block, size_);
|
||||
fwd_txfm_(input_extreme_block, output_ref_block, size_);
|
||||
|
||||
// quantization with minimum allowed step sizes
|
||||
input_block_[0] = (output_ref_block[0] / 4) * 4;
|
||||
@@ -217,9 +231,9 @@ TEST_P(PartialIDctTest, RunQuantCheck) {
|
||||
}
|
||||
|
||||
ASM_REGISTER_STATE_CHECK(
|
||||
full_itxfm_(input_block_, output_block_ref_, stride_, bit_depth_));
|
||||
full_inv_txfm_(input_block_, output_block_ref_, stride_, bit_depth_));
|
||||
ASM_REGISTER_STATE_CHECK(
|
||||
partial_itxfm_(input_block_, output_block_, stride_, bit_depth_));
|
||||
partial_inv_txfm_(input_block_, output_block_, stride_, bit_depth_));
|
||||
ASSERT_EQ(0, memcmp(output_block_ref_, output_block_,
|
||||
pixel_size_ * output_block_size_))
|
||||
<< "Error: partial inverse transform produces different results";
|
||||
@@ -232,9 +246,9 @@ TEST_P(PartialIDctTest, ResultsMatch) {
|
||||
InitInput();
|
||||
|
||||
ASM_REGISTER_STATE_CHECK(
|
||||
full_itxfm_(input_block_, output_block_ref_, stride_, bit_depth_));
|
||||
full_inv_txfm_(input_block_, output_block_ref_, stride_, bit_depth_));
|
||||
ASM_REGISTER_STATE_CHECK(
|
||||
partial_itxfm_(input_block_, output_block_, stride_, bit_depth_));
|
||||
partial_inv_txfm_(input_block_, output_block_, stride_, bit_depth_));
|
||||
ASSERT_EQ(0, memcmp(output_block_ref_, output_block_,
|
||||
pixel_size_ * output_block_size_))
|
||||
<< "Error: partial inverse transform produces different results";
|
||||
@@ -249,9 +263,9 @@ TEST_P(PartialIDctTest, AddOutputBlock) {
|
||||
}
|
||||
|
||||
ASM_REGISTER_STATE_CHECK(
|
||||
full_itxfm_(input_block_, output_block_ref_, stride_, bit_depth_));
|
||||
full_inv_txfm_(input_block_, output_block_ref_, stride_, bit_depth_));
|
||||
ASM_REGISTER_STATE_CHECK(
|
||||
partial_itxfm_(input_block_, output_block_, stride_, bit_depth_));
|
||||
partial_inv_txfm_(input_block_, output_block_, stride_, bit_depth_));
|
||||
ASSERT_EQ(0, memcmp(output_block_ref_, output_block_,
|
||||
pixel_size_ * output_block_size_))
|
||||
<< "Error: Transform results are not correctly added to output.";
|
||||
@@ -259,8 +273,8 @@ TEST_P(PartialIDctTest, AddOutputBlock) {
|
||||
}
|
||||
|
||||
TEST_P(PartialIDctTest, SingleExtremeCoeff) {
|
||||
const int16_t max_coeff = MaxSupportedCoeff(partial_itxfm_);
|
||||
const int16_t min_coeff = MinSupportedCoeff(partial_itxfm_);
|
||||
const int16_t max_coeff = std::numeric_limits<int16_t>::max();
|
||||
const int16_t min_coeff = std::numeric_limits<int16_t>::min();
|
||||
for (int i = 0; i < last_nonzero_; ++i) {
|
||||
memset(input_block_, 0, sizeof(*input_block_) * input_block_size_);
|
||||
// Run once for min and once for max.
|
||||
@@ -272,9 +286,9 @@ TEST_P(PartialIDctTest, SingleExtremeCoeff) {
|
||||
input_block_[vp9_default_scan_orders[tx_size_].scan[i]] = coeff;
|
||||
|
||||
ASM_REGISTER_STATE_CHECK(
|
||||
full_itxfm_(input_block_, output_block_ref_, stride_, bit_depth_));
|
||||
full_inv_txfm_(input_block_, output_block_ref_, stride_, bit_depth_));
|
||||
ASM_REGISTER_STATE_CHECK(
|
||||
partial_itxfm_(input_block_, output_block_, stride_, bit_depth_));
|
||||
partial_inv_txfm_(input_block_, output_block_, stride_, bit_depth_));
|
||||
ASSERT_EQ(0, memcmp(output_block_ref_, output_block_,
|
||||
pixel_size_ * output_block_size_))
|
||||
<< "Error: Fails with single coeff of " << coeff << " at " << i
|
||||
@@ -291,20 +305,20 @@ TEST_P(PartialIDctTest, DISABLED_Speed) {
|
||||
|
||||
for (int i = 0; i < kCountSpeedTestBlock; ++i) {
|
||||
ASM_REGISTER_STATE_CHECK(
|
||||
full_itxfm_(input_block_, output_block_ref_, stride_, bit_depth_));
|
||||
full_inv_txfm_(input_block_, output_block_ref_, stride_, bit_depth_));
|
||||
}
|
||||
vpx_usec_timer timer;
|
||||
vpx_usec_timer_start(&timer);
|
||||
for (int i = 0; i < kCountSpeedTestBlock; ++i) {
|
||||
partial_itxfm_(input_block_, output_block_, stride_, bit_depth_);
|
||||
partial_inv_txfm_(input_block_, output_block_, stride_, bit_depth_);
|
||||
}
|
||||
libvpx_test::ClearSystemState();
|
||||
vpx_usec_timer_mark(&timer);
|
||||
const int elapsed_time =
|
||||
static_cast<int>(vpx_usec_timer_elapsed(&timer) / 1000);
|
||||
printf("idct%dx%d_%d (bitdepth %d) time: %5d ms ", size_, size_,
|
||||
last_nonzero_, bit_depth_, elapsed_time);
|
||||
|
||||
printf("idct%dx%d_%d (%s %d) time: %5d ms\n", size_, size_, last_nonzero_,
|
||||
(pixel_size_ == 1) ? "bitdepth" : "high bitdepth", bit_depth_,
|
||||
elapsed_time);
|
||||
ASSERT_EQ(0, memcmp(output_block_ref_, output_block_,
|
||||
pixel_size_ * output_block_size_))
|
||||
<< "Error: partial inverse transform produces different results";
|
||||
@@ -323,6 +337,15 @@ const PartialInvTxfmParam c_partial_idct_tests[] = {
|
||||
make_tuple(
|
||||
&vpx_highbd_fdct32x32_c, &highbd_wrapper<vpx_highbd_idct32x32_1024_add_c>,
|
||||
&highbd_wrapper<vpx_highbd_idct32x32_1024_add_c>, TX_32X32, 1024, 12, 2),
|
||||
make_tuple(
|
||||
&vpx_highbd_fdct32x32_c, &highbd_wrapper<vpx_highbd_idct32x32_1024_add_c>,
|
||||
&highbd_wrapper<vpx_highbd_idct32x32_135_add_c>, TX_32X32, 135, 8, 2),
|
||||
make_tuple(
|
||||
&vpx_highbd_fdct32x32_c, &highbd_wrapper<vpx_highbd_idct32x32_1024_add_c>,
|
||||
&highbd_wrapper<vpx_highbd_idct32x32_135_add_c>, TX_32X32, 135, 10, 2),
|
||||
make_tuple(
|
||||
&vpx_highbd_fdct32x32_c, &highbd_wrapper<vpx_highbd_idct32x32_1024_add_c>,
|
||||
&highbd_wrapper<vpx_highbd_idct32x32_135_add_c>, TX_32X32, 135, 12, 2),
|
||||
make_tuple(
|
||||
&vpx_highbd_fdct32x32_c, &highbd_wrapper<vpx_highbd_idct32x32_1024_add_c>,
|
||||
&highbd_wrapper<vpx_highbd_idct32x32_34_add_c>, TX_32X32, 34, 8, 2),
|
||||
@@ -350,6 +373,15 @@ const PartialInvTxfmParam c_partial_idct_tests[] = {
|
||||
make_tuple(
|
||||
&vpx_highbd_fdct16x16_c, &highbd_wrapper<vpx_highbd_idct16x16_256_add_c>,
|
||||
&highbd_wrapper<vpx_highbd_idct16x16_256_add_c>, TX_16X16, 256, 12, 2),
|
||||
make_tuple(
|
||||
&vpx_highbd_fdct16x16_c, &highbd_wrapper<vpx_highbd_idct16x16_256_add_c>,
|
||||
&highbd_wrapper<vpx_highbd_idct16x16_38_add_c>, TX_16X16, 38, 8, 2),
|
||||
make_tuple(
|
||||
&vpx_highbd_fdct16x16_c, &highbd_wrapper<vpx_highbd_idct16x16_256_add_c>,
|
||||
&highbd_wrapper<vpx_highbd_idct16x16_38_add_c>, TX_16X16, 38, 10, 2),
|
||||
make_tuple(
|
||||
&vpx_highbd_fdct16x16_c, &highbd_wrapper<vpx_highbd_idct16x16_256_add_c>,
|
||||
&highbd_wrapper<vpx_highbd_idct16x16_38_add_c>, TX_16X16, 38, 12, 2),
|
||||
make_tuple(
|
||||
&vpx_highbd_fdct16x16_c, &highbd_wrapper<vpx_highbd_idct16x16_256_add_c>,
|
||||
&highbd_wrapper<vpx_highbd_idct16x16_10_add_c>, TX_16X16, 10, 8, 2),
|
||||
@@ -424,6 +456,8 @@ const PartialInvTxfmParam c_partial_idct_tests[] = {
|
||||
&wrapper<vpx_idct32x32_1_add_c>, TX_32X32, 1, 8, 1),
|
||||
make_tuple(&vpx_fdct16x16_c, &wrapper<vpx_idct16x16_256_add_c>,
|
||||
&wrapper<vpx_idct16x16_256_add_c>, TX_16X16, 256, 8, 1),
|
||||
make_tuple(&vpx_fdct16x16_c, &wrapper<vpx_idct16x16_256_add_c>,
|
||||
&wrapper<vpx_idct16x16_38_add_c>, TX_16X16, 38, 8, 1),
|
||||
make_tuple(&vpx_fdct16x16_c, &wrapper<vpx_idct16x16_256_add_c>,
|
||||
&wrapper<vpx_idct16x16_10_add_c>, TX_16X16, 10, 8, 1),
|
||||
make_tuple(&vpx_fdct16x16_c, &wrapper<vpx_idct16x16_256_add_c>,
|
||||
@@ -443,9 +477,86 @@ const PartialInvTxfmParam c_partial_idct_tests[] = {
|
||||
INSTANTIATE_TEST_CASE_P(C, PartialIDctTest,
|
||||
::testing::ValuesIn(c_partial_idct_tests));
|
||||
|
||||
#if HAVE_NEON && !CONFIG_EMULATE_HARDWARE
|
||||
#if !CONFIG_EMULATE_HARDWARE
|
||||
|
||||
#if HAVE_NEON
|
||||
const PartialInvTxfmParam neon_partial_idct_tests[] = {
|
||||
#if CONFIG_VP9_HIGHBITDEPTH
|
||||
make_tuple(&vpx_highbd_fdct32x32_c,
|
||||
&highbd_wrapper<vpx_highbd_idct32x32_1024_add_c>,
|
||||
&highbd_wrapper<vpx_highbd_idct32x32_1024_add_neon>, TX_32X32,
|
||||
1024, 8, 2),
|
||||
make_tuple(&vpx_highbd_fdct32x32_c,
|
||||
&highbd_wrapper<vpx_highbd_idct32x32_1024_add_c>,
|
||||
&highbd_wrapper<vpx_highbd_idct32x32_1024_add_neon>, TX_32X32,
|
||||
1024, 10, 2),
|
||||
make_tuple(&vpx_highbd_fdct32x32_c,
|
||||
&highbd_wrapper<vpx_highbd_idct32x32_1024_add_c>,
|
||||
&highbd_wrapper<vpx_highbd_idct32x32_1024_add_neon>, TX_32X32,
|
||||
1024, 12, 2),
|
||||
make_tuple(
|
||||
&vpx_highbd_fdct32x32_c, &highbd_wrapper<vpx_highbd_idct32x32_135_add_c>,
|
||||
&highbd_wrapper<vpx_highbd_idct32x32_135_add_neon>, TX_32X32, 135, 8, 2),
|
||||
make_tuple(
|
||||
&vpx_highbd_fdct32x32_c, &highbd_wrapper<vpx_highbd_idct32x32_135_add_c>,
|
||||
&highbd_wrapper<vpx_highbd_idct32x32_135_add_neon>, TX_32X32, 135, 10, 2),
|
||||
make_tuple(
|
||||
&vpx_highbd_fdct32x32_c, &highbd_wrapper<vpx_highbd_idct32x32_135_add_c>,
|
||||
&highbd_wrapper<vpx_highbd_idct32x32_135_add_neon>, TX_32X32, 135, 12, 2),
|
||||
make_tuple(
|
||||
&vpx_highbd_fdct32x32_c, &highbd_wrapper<vpx_highbd_idct32x32_34_add_c>,
|
||||
&highbd_wrapper<vpx_highbd_idct32x32_34_add_neon>, TX_32X32, 34, 8, 2),
|
||||
make_tuple(
|
||||
&vpx_highbd_fdct32x32_c, &highbd_wrapper<vpx_highbd_idct32x32_34_add_c>,
|
||||
&highbd_wrapper<vpx_highbd_idct32x32_34_add_neon>, TX_32X32, 34, 10, 2),
|
||||
make_tuple(
|
||||
&vpx_highbd_fdct32x32_c, &highbd_wrapper<vpx_highbd_idct32x32_34_add_c>,
|
||||
&highbd_wrapper<vpx_highbd_idct32x32_34_add_neon>, TX_32X32, 34, 12, 2),
|
||||
make_tuple(
|
||||
&vpx_highbd_fdct32x32_c, &highbd_wrapper<vpx_highbd_idct32x32_1_add_c>,
|
||||
&highbd_wrapper<vpx_highbd_idct32x32_1_add_neon>, TX_32X32, 1, 8, 2),
|
||||
make_tuple(
|
||||
&vpx_highbd_fdct32x32_c, &highbd_wrapper<vpx_highbd_idct32x32_1_add_c>,
|
||||
&highbd_wrapper<vpx_highbd_idct32x32_1_add_neon>, TX_32X32, 1, 10, 2),
|
||||
make_tuple(
|
||||
&vpx_highbd_fdct32x32_c, &highbd_wrapper<vpx_highbd_idct32x32_1_add_c>,
|
||||
&highbd_wrapper<vpx_highbd_idct32x32_1_add_neon>, TX_32X32, 1, 12, 2),
|
||||
make_tuple(
|
||||
&vpx_highbd_fdct16x16_c, &highbd_wrapper<vpx_highbd_idct16x16_256_add_c>,
|
||||
&highbd_wrapper<vpx_highbd_idct16x16_256_add_neon>, TX_16X16, 256, 8, 2),
|
||||
make_tuple(
|
||||
&vpx_highbd_fdct16x16_c, &highbd_wrapper<vpx_highbd_idct16x16_256_add_c>,
|
||||
&highbd_wrapper<vpx_highbd_idct16x16_256_add_neon>, TX_16X16, 256, 10, 2),
|
||||
make_tuple(
|
||||
&vpx_highbd_fdct16x16_c, &highbd_wrapper<vpx_highbd_idct16x16_256_add_c>,
|
||||
&highbd_wrapper<vpx_highbd_idct16x16_256_add_neon>, TX_16X16, 256, 12, 2),
|
||||
make_tuple(
|
||||
&vpx_highbd_fdct16x16_c, &highbd_wrapper<vpx_highbd_idct16x16_38_add_c>,
|
||||
&highbd_wrapper<vpx_highbd_idct16x16_38_add_neon>, TX_16X16, 38, 8, 2),
|
||||
make_tuple(
|
||||
&vpx_highbd_fdct16x16_c, &highbd_wrapper<vpx_highbd_idct16x16_38_add_c>,
|
||||
&highbd_wrapper<vpx_highbd_idct16x16_38_add_neon>, TX_16X16, 38, 10, 2),
|
||||
make_tuple(
|
||||
&vpx_highbd_fdct16x16_c, &highbd_wrapper<vpx_highbd_idct16x16_38_add_c>,
|
||||
&highbd_wrapper<vpx_highbd_idct16x16_38_add_neon>, TX_16X16, 38, 12, 2),
|
||||
make_tuple(
|
||||
&vpx_highbd_fdct16x16_c, &highbd_wrapper<vpx_highbd_idct16x16_10_add_c>,
|
||||
&highbd_wrapper<vpx_highbd_idct16x16_10_add_neon>, TX_16X16, 10, 8, 2),
|
||||
make_tuple(
|
||||
&vpx_highbd_fdct16x16_c, &highbd_wrapper<vpx_highbd_idct16x16_10_add_c>,
|
||||
&highbd_wrapper<vpx_highbd_idct16x16_10_add_neon>, TX_16X16, 10, 10, 2),
|
||||
make_tuple(
|
||||
&vpx_highbd_fdct16x16_c, &highbd_wrapper<vpx_highbd_idct16x16_10_add_c>,
|
||||
&highbd_wrapper<vpx_highbd_idct16x16_10_add_neon>, TX_16X16, 10, 12, 2),
|
||||
make_tuple(
|
||||
&vpx_highbd_fdct16x16_c, &highbd_wrapper<vpx_highbd_idct16x16_1_add_c>,
|
||||
&highbd_wrapper<vpx_highbd_idct16x16_1_add_neon>, TX_16X16, 1, 8, 2),
|
||||
make_tuple(
|
||||
&vpx_highbd_fdct16x16_c, &highbd_wrapper<vpx_highbd_idct16x16_1_add_c>,
|
||||
&highbd_wrapper<vpx_highbd_idct16x16_1_add_neon>, TX_16X16, 1, 10, 2),
|
||||
make_tuple(
|
||||
&vpx_highbd_fdct16x16_c, &highbd_wrapper<vpx_highbd_idct16x16_1_add_c>,
|
||||
&highbd_wrapper<vpx_highbd_idct16x16_1_add_neon>, TX_16X16, 1, 12, 2),
|
||||
make_tuple(&vpx_highbd_fdct8x8_c,
|
||||
&highbd_wrapper<vpx_highbd_idct8x8_64_add_c>,
|
||||
&highbd_wrapper<vpx_highbd_idct8x8_64_add_neon>, TX_8X8, 64, 8, 2),
|
||||
@@ -488,46 +599,78 @@ const PartialInvTxfmParam neon_partial_idct_tests[] = {
|
||||
#endif // CONFIG_VP9_HIGHBITDEPTH
|
||||
make_tuple(&vpx_fdct32x32_c, &wrapper<vpx_idct32x32_1024_add_c>,
|
||||
&wrapper<vpx_idct32x32_1024_add_neon>, TX_32X32, 1024, 8, 1),
|
||||
make_tuple(&vpx_fdct32x32_c, &wrapper<vpx_idct32x32_1024_add_c>,
|
||||
make_tuple(&vpx_fdct32x32_c, &wrapper<vpx_idct32x32_135_add_c>,
|
||||
&wrapper<vpx_idct32x32_135_add_neon>, TX_32X32, 135, 8, 1),
|
||||
make_tuple(&vpx_fdct32x32_c, &wrapper<vpx_idct32x32_1024_add_c>,
|
||||
make_tuple(&vpx_fdct32x32_c, &wrapper<vpx_idct32x32_34_add_c>,
|
||||
&wrapper<vpx_idct32x32_34_add_neon>, TX_32X32, 34, 8, 1),
|
||||
make_tuple(&vpx_fdct32x32_c, &wrapper<vpx_idct32x32_1024_add_c>,
|
||||
make_tuple(&vpx_fdct32x32_c, &wrapper<vpx_idct32x32_1_add_c>,
|
||||
&wrapper<vpx_idct32x32_1_add_neon>, TX_32X32, 1, 8, 1),
|
||||
make_tuple(&vpx_fdct16x16_c, &wrapper<vpx_idct16x16_256_add_c>,
|
||||
&wrapper<vpx_idct16x16_256_add_neon>, TX_16X16, 256, 8, 1),
|
||||
make_tuple(&vpx_fdct16x16_c, &wrapper<vpx_idct16x16_256_add_c>,
|
||||
make_tuple(&vpx_fdct16x16_c, &wrapper<vpx_idct16x16_38_add_c>,
|
||||
&wrapper<vpx_idct16x16_38_add_neon>, TX_16X16, 38, 8, 1),
|
||||
make_tuple(&vpx_fdct16x16_c, &wrapper<vpx_idct16x16_10_add_c>,
|
||||
&wrapper<vpx_idct16x16_10_add_neon>, TX_16X16, 10, 8, 1),
|
||||
make_tuple(&vpx_fdct16x16_c, &wrapper<vpx_idct16x16_256_add_c>,
|
||||
make_tuple(&vpx_fdct16x16_c, &wrapper<vpx_idct16x16_1_add_c>,
|
||||
&wrapper<vpx_idct16x16_1_add_neon>, TX_16X16, 1, 8, 1),
|
||||
make_tuple(&vpx_fdct8x8_c, &wrapper<vpx_idct8x8_64_add_c>,
|
||||
&wrapper<vpx_idct8x8_64_add_neon>, TX_8X8, 64, 8, 1),
|
||||
make_tuple(&vpx_fdct8x8_c, &wrapper<vpx_idct8x8_64_add_c>,
|
||||
make_tuple(&vpx_fdct8x8_c, &wrapper<vpx_idct8x8_12_add_c>,
|
||||
&wrapper<vpx_idct8x8_12_add_neon>, TX_8X8, 12, 8, 1),
|
||||
make_tuple(&vpx_fdct8x8_c, &wrapper<vpx_idct8x8_64_add_c>,
|
||||
make_tuple(&vpx_fdct8x8_c, &wrapper<vpx_idct8x8_1_add_c>,
|
||||
&wrapper<vpx_idct8x8_1_add_neon>, TX_8X8, 1, 8, 1),
|
||||
make_tuple(&vpx_fdct4x4_c, &wrapper<vpx_idct4x4_16_add_c>,
|
||||
&wrapper<vpx_idct4x4_16_add_neon>, TX_4X4, 16, 8, 1),
|
||||
make_tuple(&vpx_fdct4x4_c, &wrapper<vpx_idct4x4_16_add_c>,
|
||||
make_tuple(&vpx_fdct4x4_c, &wrapper<vpx_idct4x4_1_add_c>,
|
||||
&wrapper<vpx_idct4x4_1_add_neon>, TX_4X4, 1, 8, 1)
|
||||
};
|
||||
|
||||
INSTANTIATE_TEST_CASE_P(NEON, PartialIDctTest,
|
||||
::testing::ValuesIn(neon_partial_idct_tests));
|
||||
#endif // HAVE_NEON && !CONFIG_EMULATE_HARDWARE
|
||||
#endif // HAVE_NEON
|
||||
|
||||
#if HAVE_SSE2 && !CONFIG_EMULATE_HARDWARE
|
||||
#if HAVE_SSE2
|
||||
// 32x32_135_ is implemented using the 1024 version.
|
||||
const PartialInvTxfmParam sse2_partial_idct_tests[] = {
|
||||
#if CONFIG_VP9_HIGHBITDEPTH
|
||||
make_tuple(&vpx_highbd_fdct32x32_c,
|
||||
&highbd_wrapper<vpx_highbd_idct32x32_1024_add_c>,
|
||||
&highbd_wrapper<vpx_highbd_idct32x32_1024_add_sse2>, TX_32X32,
|
||||
1024, 8, 2),
|
||||
make_tuple(&vpx_highbd_fdct32x32_c,
|
||||
&highbd_wrapper<vpx_highbd_idct32x32_1024_add_c>,
|
||||
&highbd_wrapper<vpx_highbd_idct32x32_1024_add_sse2>, TX_32X32,
|
||||
1024, 10, 2),
|
||||
make_tuple(&vpx_highbd_fdct32x32_c,
|
||||
&highbd_wrapper<vpx_highbd_idct32x32_1024_add_c>,
|
||||
&highbd_wrapper<vpx_highbd_idct32x32_1024_add_sse2>, TX_32X32,
|
||||
1024, 12, 2),
|
||||
make_tuple(
|
||||
&vpx_highbd_fdct32x32_c, &highbd_wrapper<vpx_highbd_idct32x32_1024_add_c>,
|
||||
&vpx_highbd_fdct32x32_c, &highbd_wrapper<vpx_highbd_idct32x32_135_add_c>,
|
||||
&highbd_wrapper<vpx_highbd_idct32x32_135_add_sse2>, TX_32X32, 135, 8, 2),
|
||||
make_tuple(
|
||||
&vpx_highbd_fdct32x32_c, &highbd_wrapper<vpx_highbd_idct32x32_135_add_c>,
|
||||
&highbd_wrapper<vpx_highbd_idct32x32_135_add_sse2>, TX_32X32, 135, 10, 2),
|
||||
make_tuple(
|
||||
&vpx_highbd_fdct32x32_c, &highbd_wrapper<vpx_highbd_idct32x32_135_add_c>,
|
||||
&highbd_wrapper<vpx_highbd_idct32x32_135_add_sse2>, TX_32X32, 135, 12, 2),
|
||||
make_tuple(
|
||||
&vpx_highbd_fdct32x32_c, &highbd_wrapper<vpx_highbd_idct32x32_34_add_c>,
|
||||
&highbd_wrapper<vpx_highbd_idct32x32_34_add_sse2>, TX_32X32, 34, 8, 2),
|
||||
make_tuple(
|
||||
&vpx_highbd_fdct32x32_c, &highbd_wrapper<vpx_highbd_idct32x32_34_add_c>,
|
||||
&highbd_wrapper<vpx_highbd_idct32x32_34_add_sse2>, TX_32X32, 34, 10, 2),
|
||||
make_tuple(
|
||||
&vpx_highbd_fdct32x32_c, &highbd_wrapper<vpx_highbd_idct32x32_34_add_c>,
|
||||
&highbd_wrapper<vpx_highbd_idct32x32_34_add_sse2>, TX_32X32, 34, 12, 2),
|
||||
make_tuple(
|
||||
&vpx_highbd_fdct32x32_c, &highbd_wrapper<vpx_highbd_idct32x32_1_add_c>,
|
||||
&highbd_wrapper<vpx_highbd_idct32x32_1_add_sse2>, TX_32X32, 1, 8, 2),
|
||||
make_tuple(
|
||||
&vpx_highbd_fdct32x32_c, &highbd_wrapper<vpx_highbd_idct32x32_1024_add_c>,
|
||||
&vpx_highbd_fdct32x32_c, &highbd_wrapper<vpx_highbd_idct32x32_1_add_c>,
|
||||
&highbd_wrapper<vpx_highbd_idct32x32_1_add_sse2>, TX_32X32, 1, 10, 2),
|
||||
make_tuple(
|
||||
&vpx_highbd_fdct32x32_c, &highbd_wrapper<vpx_highbd_idct32x32_1024_add_c>,
|
||||
&vpx_highbd_fdct32x32_c, &highbd_wrapper<vpx_highbd_idct32x32_1_add_c>,
|
||||
&highbd_wrapper<vpx_highbd_idct32x32_1_add_sse2>, TX_32X32, 1, 12, 2),
|
||||
make_tuple(
|
||||
&vpx_highbd_fdct16x16_c, &highbd_wrapper<vpx_highbd_idct16x16_256_add_c>,
|
||||
@@ -539,14 +682,32 @@ const PartialInvTxfmParam sse2_partial_idct_tests[] = {
|
||||
&vpx_highbd_fdct16x16_c, &highbd_wrapper<vpx_highbd_idct16x16_256_add_c>,
|
||||
&highbd_wrapper<vpx_highbd_idct16x16_256_add_sse2>, TX_16X16, 256, 12, 2),
|
||||
make_tuple(
|
||||
&vpx_highbd_fdct16x16_c, &highbd_wrapper<vpx_highbd_idct16x16_256_add_c>,
|
||||
&vpx_highbd_fdct16x16_c, &highbd_wrapper<vpx_highbd_idct16x16_38_add_c>,
|
||||
&highbd_wrapper<vpx_highbd_idct16x16_38_add_sse2>, TX_16X16, 38, 8, 2),
|
||||
make_tuple(
|
||||
&vpx_highbd_fdct16x16_c, &highbd_wrapper<vpx_highbd_idct16x16_38_add_c>,
|
||||
&highbd_wrapper<vpx_highbd_idct16x16_38_add_sse2>, TX_16X16, 38, 10, 2),
|
||||
make_tuple(
|
||||
&vpx_highbd_fdct16x16_c, &highbd_wrapper<vpx_highbd_idct16x16_38_add_c>,
|
||||
&highbd_wrapper<vpx_highbd_idct16x16_38_add_sse2>, TX_16X16, 38, 12, 2),
|
||||
make_tuple(
|
||||
&vpx_highbd_fdct16x16_c, &highbd_wrapper<vpx_highbd_idct16x16_10_add_c>,
|
||||
&highbd_wrapper<vpx_highbd_idct16x16_10_add_sse2>, TX_16X16, 10, 8, 2),
|
||||
make_tuple(
|
||||
&vpx_highbd_fdct16x16_c, &highbd_wrapper<vpx_highbd_idct16x16_256_add_c>,
|
||||
&vpx_highbd_fdct16x16_c, &highbd_wrapper<vpx_highbd_idct16x16_10_add_c>,
|
||||
&highbd_wrapper<vpx_highbd_idct16x16_10_add_sse2>, TX_16X16, 10, 10, 2),
|
||||
make_tuple(
|
||||
&vpx_highbd_fdct16x16_c, &highbd_wrapper<vpx_highbd_idct16x16_256_add_c>,
|
||||
&vpx_highbd_fdct16x16_c, &highbd_wrapper<vpx_highbd_idct16x16_10_add_c>,
|
||||
&highbd_wrapper<vpx_highbd_idct16x16_10_add_sse2>, TX_16X16, 10, 12, 2),
|
||||
make_tuple(
|
||||
&vpx_highbd_fdct16x16_c, &highbd_wrapper<vpx_highbd_idct16x16_1_add_c>,
|
||||
&highbd_wrapper<vpx_highbd_idct16x16_1_add_sse2>, TX_16X16, 1, 8, 2),
|
||||
make_tuple(
|
||||
&vpx_highbd_fdct16x16_c, &highbd_wrapper<vpx_highbd_idct16x16_1_add_c>,
|
||||
&highbd_wrapper<vpx_highbd_idct16x16_1_add_sse2>, TX_16X16, 1, 10, 2),
|
||||
make_tuple(
|
||||
&vpx_highbd_fdct16x16_c, &highbd_wrapper<vpx_highbd_idct16x16_1_add_c>,
|
||||
&highbd_wrapper<vpx_highbd_idct16x16_1_add_sse2>, TX_16X16, 1, 12, 2),
|
||||
make_tuple(&vpx_highbd_fdct8x8_c,
|
||||
&highbd_wrapper<vpx_highbd_idct8x8_64_add_c>,
|
||||
&highbd_wrapper<vpx_highbd_idct8x8_64_add_sse2>, TX_8X8, 64, 8, 2),
|
||||
@@ -557,14 +718,20 @@ const PartialInvTxfmParam sse2_partial_idct_tests[] = {
|
||||
&vpx_highbd_fdct8x8_c, &highbd_wrapper<vpx_highbd_idct8x8_64_add_c>,
|
||||
&highbd_wrapper<vpx_highbd_idct8x8_64_add_sse2>, TX_8X8, 64, 12, 2),
|
||||
make_tuple(&vpx_highbd_fdct8x8_c,
|
||||
&highbd_wrapper<vpx_highbd_idct8x8_64_add_c>,
|
||||
&highbd_wrapper<vpx_highbd_idct8x8_12_add_c>,
|
||||
&highbd_wrapper<vpx_highbd_idct8x8_12_add_sse2>, TX_8X8, 12, 8, 2),
|
||||
make_tuple(
|
||||
&vpx_highbd_fdct8x8_c, &highbd_wrapper<vpx_highbd_idct8x8_64_add_c>,
|
||||
&vpx_highbd_fdct8x8_c, &highbd_wrapper<vpx_highbd_idct8x8_12_add_c>,
|
||||
&highbd_wrapper<vpx_highbd_idct8x8_12_add_sse2>, TX_8X8, 12, 10, 2),
|
||||
make_tuple(
|
||||
&vpx_highbd_fdct8x8_c, &highbd_wrapper<vpx_highbd_idct8x8_64_add_c>,
|
||||
&vpx_highbd_fdct8x8_c, &highbd_wrapper<vpx_highbd_idct8x8_12_add_c>,
|
||||
&highbd_wrapper<vpx_highbd_idct8x8_12_add_sse2>, TX_8X8, 12, 12, 2),
|
||||
make_tuple(&vpx_highbd_fdct8x8_c, &highbd_wrapper<vpx_highbd_idct8x8_1_add_c>,
|
||||
&highbd_wrapper<vpx_highbd_idct8x8_1_add_sse2>, TX_8X8, 1, 8, 2),
|
||||
make_tuple(&vpx_highbd_fdct8x8_c, &highbd_wrapper<vpx_highbd_idct8x8_1_add_c>,
|
||||
&highbd_wrapper<vpx_highbd_idct8x8_1_add_sse2>, TX_8X8, 1, 10, 2),
|
||||
make_tuple(&vpx_highbd_fdct8x8_c, &highbd_wrapper<vpx_highbd_idct8x8_1_add_c>,
|
||||
&highbd_wrapper<vpx_highbd_idct8x8_1_add_sse2>, TX_8X8, 1, 12, 2),
|
||||
make_tuple(&vpx_highbd_fdct4x4_c,
|
||||
&highbd_wrapper<vpx_highbd_idct4x4_16_add_c>,
|
||||
&highbd_wrapper<vpx_highbd_idct4x4_16_add_sse2>, TX_4X4, 16, 8, 2),
|
||||
@@ -574,119 +741,219 @@ const PartialInvTxfmParam sse2_partial_idct_tests[] = {
|
||||
make_tuple(
|
||||
&vpx_highbd_fdct4x4_c, &highbd_wrapper<vpx_highbd_idct4x4_16_add_c>,
|
||||
&highbd_wrapper<vpx_highbd_idct4x4_16_add_sse2>, TX_4X4, 16, 12, 2),
|
||||
make_tuple(&vpx_highbd_fdct4x4_c, &highbd_wrapper<vpx_highbd_idct4x4_1_add_c>,
|
||||
&highbd_wrapper<vpx_highbd_idct4x4_1_add_sse2>, TX_4X4, 1, 8, 2),
|
||||
make_tuple(&vpx_highbd_fdct4x4_c, &highbd_wrapper<vpx_highbd_idct4x4_1_add_c>,
|
||||
&highbd_wrapper<vpx_highbd_idct4x4_1_add_sse2>, TX_4X4, 1, 10, 2),
|
||||
make_tuple(&vpx_highbd_fdct4x4_c, &highbd_wrapper<vpx_highbd_idct4x4_1_add_c>,
|
||||
&highbd_wrapper<vpx_highbd_idct4x4_1_add_sse2>, TX_4X4, 1, 12, 2),
|
||||
#endif // CONFIG_VP9_HIGHBITDEPTH
|
||||
make_tuple(&vpx_fdct32x32_c, &wrapper<vpx_idct32x32_1024_add_c>,
|
||||
&wrapper<vpx_idct32x32_1024_add_sse2>, TX_32X32, 1024, 8, 1),
|
||||
make_tuple(&vpx_fdct32x32_c, &wrapper<vpx_idct32x32_1024_add_c>,
|
||||
&wrapper<vpx_idct32x32_1024_add_sse2>, TX_32X32, 135, 8, 1),
|
||||
make_tuple(&vpx_fdct32x32_c, &wrapper<vpx_idct32x32_1024_add_c>,
|
||||
make_tuple(&vpx_fdct32x32_c, &wrapper<vpx_idct32x32_135_add_c>,
|
||||
&wrapper<vpx_idct32x32_135_add_sse2>, TX_32X32, 135, 8, 1),
|
||||
make_tuple(&vpx_fdct32x32_c, &wrapper<vpx_idct32x32_34_add_c>,
|
||||
&wrapper<vpx_idct32x32_34_add_sse2>, TX_32X32, 34, 8, 1),
|
||||
make_tuple(&vpx_fdct32x32_c, &wrapper<vpx_idct32x32_1024_add_c>,
|
||||
make_tuple(&vpx_fdct32x32_c, &wrapper<vpx_idct32x32_1_add_c>,
|
||||
&wrapper<vpx_idct32x32_1_add_sse2>, TX_32X32, 1, 8, 1),
|
||||
make_tuple(&vpx_fdct16x16_c, &wrapper<vpx_idct16x16_256_add_c>,
|
||||
&wrapper<vpx_idct16x16_256_add_sse2>, TX_16X16, 256, 8, 1),
|
||||
make_tuple(&vpx_fdct16x16_c, &wrapper<vpx_idct16x16_256_add_c>,
|
||||
make_tuple(&vpx_fdct16x16_c, &wrapper<vpx_idct16x16_38_add_c>,
|
||||
&wrapper<vpx_idct16x16_38_add_sse2>, TX_16X16, 38, 8, 1),
|
||||
make_tuple(&vpx_fdct16x16_c, &wrapper<vpx_idct16x16_10_add_c>,
|
||||
&wrapper<vpx_idct16x16_10_add_sse2>, TX_16X16, 10, 8, 1),
|
||||
make_tuple(&vpx_fdct16x16_c, &wrapper<vpx_idct16x16_256_add_c>,
|
||||
make_tuple(&vpx_fdct16x16_c, &wrapper<vpx_idct16x16_1_add_c>,
|
||||
&wrapper<vpx_idct16x16_1_add_sse2>, TX_16X16, 1, 8, 1),
|
||||
make_tuple(&vpx_fdct8x8_c, &wrapper<vpx_idct8x8_64_add_c>,
|
||||
&wrapper<vpx_idct8x8_64_add_sse2>, TX_8X8, 64, 8, 1),
|
||||
make_tuple(&vpx_fdct8x8_c, &wrapper<vpx_idct8x8_64_add_c>,
|
||||
make_tuple(&vpx_fdct8x8_c, &wrapper<vpx_idct8x8_12_add_c>,
|
||||
&wrapper<vpx_idct8x8_12_add_sse2>, TX_8X8, 12, 8, 1),
|
||||
make_tuple(&vpx_fdct8x8_c, &wrapper<vpx_idct8x8_64_add_c>,
|
||||
make_tuple(&vpx_fdct8x8_c, &wrapper<vpx_idct8x8_1_add_c>,
|
||||
&wrapper<vpx_idct8x8_1_add_sse2>, TX_8X8, 1, 8, 1),
|
||||
make_tuple(&vpx_fdct4x4_c, &wrapper<vpx_idct4x4_16_add_c>,
|
||||
&wrapper<vpx_idct4x4_16_add_sse2>, TX_4X4, 16, 8, 1),
|
||||
make_tuple(&vpx_fdct4x4_c, &wrapper<vpx_idct4x4_16_add_c>,
|
||||
make_tuple(&vpx_fdct4x4_c, &wrapper<vpx_idct4x4_1_add_c>,
|
||||
&wrapper<vpx_idct4x4_1_add_sse2>, TX_4X4, 1, 8, 1)
|
||||
};
|
||||
|
||||
INSTANTIATE_TEST_CASE_P(SSE2, PartialIDctTest,
|
||||
::testing::ValuesIn(sse2_partial_idct_tests));
|
||||
|
||||
#endif // HAVE_SSE2 && !CONFIG_EMULATE_HARDWARE
|
||||
#endif // HAVE_SSE2
|
||||
|
||||
#if HAVE_SSSE3 && ARCH_X86_64 && !CONFIG_EMULATE_HARDWARE
|
||||
#if HAVE_SSSE3
|
||||
const PartialInvTxfmParam ssse3_partial_idct_tests[] = {
|
||||
make_tuple(&vpx_fdct32x32_c, &wrapper<vpx_idct32x32_1024_add_c>,
|
||||
&wrapper<vpx_idct32x32_1024_add_ssse3>, TX_32X32, 1024, 8, 1),
|
||||
make_tuple(&vpx_fdct32x32_c, &wrapper<vpx_idct32x32_1024_add_c>,
|
||||
make_tuple(&vpx_fdct32x32_c, &wrapper<vpx_idct32x32_135_add_c>,
|
||||
&wrapper<vpx_idct32x32_135_add_ssse3>, TX_32X32, 135, 8, 1),
|
||||
make_tuple(&vpx_fdct32x32_c, &wrapper<vpx_idct32x32_1024_add_c>,
|
||||
make_tuple(&vpx_fdct32x32_c, &wrapper<vpx_idct32x32_34_add_c>,
|
||||
&wrapper<vpx_idct32x32_34_add_ssse3>, TX_32X32, 34, 8, 1),
|
||||
make_tuple(&vpx_fdct8x8_c, &wrapper<vpx_idct8x8_64_add_c>,
|
||||
&wrapper<vpx_idct8x8_64_add_ssse3>, TX_8X8, 64, 8, 1),
|
||||
make_tuple(&vpx_fdct8x8_c, &wrapper<vpx_idct8x8_64_add_c>,
|
||||
make_tuple(&vpx_fdct8x8_c, &wrapper<vpx_idct8x8_12_add_c>,
|
||||
&wrapper<vpx_idct8x8_12_add_ssse3>, TX_8X8, 12, 8, 1)
|
||||
};
|
||||
|
||||
INSTANTIATE_TEST_CASE_P(SSSE3, PartialIDctTest,
|
||||
::testing::ValuesIn(ssse3_partial_idct_tests));
|
||||
#endif // HAVE_SSSE3 && ARCH_X86_64 && !CONFIG_EMULATE_HARDWARE
|
||||
#endif // HAVE_SSSE3
|
||||
|
||||
#if HAVE_DSPR2 && !CONFIG_EMULATE_HARDWARE && !CONFIG_VP9_HIGHBITDEPTH
|
||||
#if HAVE_SSE4_1 && CONFIG_VP9_HIGHBITDEPTH
|
||||
const PartialInvTxfmParam sse4_1_partial_idct_tests[] = {
|
||||
make_tuple(&vpx_highbd_fdct32x32_c,
|
||||
&highbd_wrapper<vpx_highbd_idct32x32_1024_add_c>,
|
||||
&highbd_wrapper<vpx_highbd_idct32x32_1024_add_sse4_1>, TX_32X32,
|
||||
1024, 8, 2),
|
||||
make_tuple(&vpx_highbd_fdct32x32_c,
|
||||
&highbd_wrapper<vpx_highbd_idct32x32_1024_add_c>,
|
||||
&highbd_wrapper<vpx_highbd_idct32x32_1024_add_sse4_1>, TX_32X32,
|
||||
1024, 10, 2),
|
||||
make_tuple(&vpx_highbd_fdct32x32_c,
|
||||
&highbd_wrapper<vpx_highbd_idct32x32_1024_add_c>,
|
||||
&highbd_wrapper<vpx_highbd_idct32x32_1024_add_sse4_1>, TX_32X32,
|
||||
1024, 12, 2),
|
||||
make_tuple(&vpx_highbd_fdct32x32_c,
|
||||
&highbd_wrapper<vpx_highbd_idct32x32_135_add_c>,
|
||||
&highbd_wrapper<vpx_highbd_idct32x32_135_add_sse4_1>, TX_32X32,
|
||||
135, 8, 2),
|
||||
make_tuple(&vpx_highbd_fdct32x32_c,
|
||||
&highbd_wrapper<vpx_highbd_idct32x32_135_add_c>,
|
||||
&highbd_wrapper<vpx_highbd_idct32x32_135_add_sse4_1>, TX_32X32,
|
||||
135, 10, 2),
|
||||
make_tuple(&vpx_highbd_fdct32x32_c,
|
||||
&highbd_wrapper<vpx_highbd_idct32x32_135_add_c>,
|
||||
&highbd_wrapper<vpx_highbd_idct32x32_135_add_sse4_1>, TX_32X32,
|
||||
135, 12, 2),
|
||||
make_tuple(
|
||||
&vpx_highbd_fdct32x32_c, &highbd_wrapper<vpx_highbd_idct32x32_34_add_c>,
|
||||
&highbd_wrapper<vpx_highbd_idct32x32_34_add_sse4_1>, TX_32X32, 34, 8, 2),
|
||||
make_tuple(
|
||||
&vpx_highbd_fdct32x32_c, &highbd_wrapper<vpx_highbd_idct32x32_34_add_c>,
|
||||
&highbd_wrapper<vpx_highbd_idct32x32_34_add_sse4_1>, TX_32X32, 34, 10, 2),
|
||||
make_tuple(
|
||||
&vpx_highbd_fdct32x32_c, &highbd_wrapper<vpx_highbd_idct32x32_34_add_c>,
|
||||
&highbd_wrapper<vpx_highbd_idct32x32_34_add_sse4_1>, TX_32X32, 34, 12, 2),
|
||||
make_tuple(&vpx_highbd_fdct16x16_c,
|
||||
&highbd_wrapper<vpx_highbd_idct16x16_256_add_c>,
|
||||
&highbd_wrapper<vpx_highbd_idct16x16_256_add_sse4_1>, TX_16X16,
|
||||
256, 8, 2),
|
||||
make_tuple(&vpx_highbd_fdct16x16_c,
|
||||
&highbd_wrapper<vpx_highbd_idct16x16_256_add_c>,
|
||||
&highbd_wrapper<vpx_highbd_idct16x16_256_add_sse4_1>, TX_16X16,
|
||||
256, 10, 2),
|
||||
make_tuple(&vpx_highbd_fdct16x16_c,
|
||||
&highbd_wrapper<vpx_highbd_idct16x16_256_add_c>,
|
||||
&highbd_wrapper<vpx_highbd_idct16x16_256_add_sse4_1>, TX_16X16,
|
||||
256, 12, 2),
|
||||
make_tuple(
|
||||
&vpx_highbd_fdct16x16_c, &highbd_wrapper<vpx_highbd_idct16x16_38_add_c>,
|
||||
&highbd_wrapper<vpx_highbd_idct16x16_38_add_sse4_1>, TX_16X16, 38, 8, 2),
|
||||
make_tuple(
|
||||
&vpx_highbd_fdct16x16_c, &highbd_wrapper<vpx_highbd_idct16x16_38_add_c>,
|
||||
&highbd_wrapper<vpx_highbd_idct16x16_38_add_sse4_1>, TX_16X16, 38, 10, 2),
|
||||
make_tuple(
|
||||
&vpx_highbd_fdct16x16_c, &highbd_wrapper<vpx_highbd_idct16x16_38_add_c>,
|
||||
&highbd_wrapper<vpx_highbd_idct16x16_38_add_sse4_1>, TX_16X16, 38, 12, 2),
|
||||
make_tuple(
|
||||
&vpx_highbd_fdct16x16_c, &highbd_wrapper<vpx_highbd_idct16x16_10_add_c>,
|
||||
&highbd_wrapper<vpx_highbd_idct16x16_10_add_sse4_1>, TX_16X16, 10, 8, 2),
|
||||
make_tuple(
|
||||
&vpx_highbd_fdct16x16_c, &highbd_wrapper<vpx_highbd_idct16x16_10_add_c>,
|
||||
&highbd_wrapper<vpx_highbd_idct16x16_10_add_sse4_1>, TX_16X16, 10, 10, 2),
|
||||
make_tuple(
|
||||
&vpx_highbd_fdct16x16_c, &highbd_wrapper<vpx_highbd_idct16x16_10_add_c>,
|
||||
&highbd_wrapper<vpx_highbd_idct16x16_10_add_sse4_1>, TX_16X16, 10, 12, 2),
|
||||
make_tuple(
|
||||
&vpx_highbd_fdct8x8_c, &highbd_wrapper<vpx_highbd_idct8x8_64_add_c>,
|
||||
&highbd_wrapper<vpx_highbd_idct8x8_64_add_sse4_1>, TX_8X8, 64, 8, 2),
|
||||
make_tuple(
|
||||
&vpx_highbd_fdct8x8_c, &highbd_wrapper<vpx_highbd_idct8x8_64_add_c>,
|
||||
&highbd_wrapper<vpx_highbd_idct8x8_64_add_sse4_1>, TX_8X8, 64, 10, 2),
|
||||
make_tuple(
|
||||
&vpx_highbd_fdct8x8_c, &highbd_wrapper<vpx_highbd_idct8x8_64_add_c>,
|
||||
&highbd_wrapper<vpx_highbd_idct8x8_64_add_sse4_1>, TX_8X8, 64, 12, 2),
|
||||
make_tuple(
|
||||
&vpx_highbd_fdct8x8_c, &highbd_wrapper<vpx_highbd_idct8x8_12_add_c>,
|
||||
&highbd_wrapper<vpx_highbd_idct8x8_12_add_sse4_1>, TX_8X8, 12, 8, 2),
|
||||
make_tuple(
|
||||
&vpx_highbd_fdct8x8_c, &highbd_wrapper<vpx_highbd_idct8x8_12_add_c>,
|
||||
&highbd_wrapper<vpx_highbd_idct8x8_12_add_sse4_1>, TX_8X8, 12, 10, 2),
|
||||
make_tuple(
|
||||
&vpx_highbd_fdct8x8_c, &highbd_wrapper<vpx_highbd_idct8x8_12_add_c>,
|
||||
&highbd_wrapper<vpx_highbd_idct8x8_12_add_sse4_1>, TX_8X8, 12, 12, 2),
|
||||
make_tuple(
|
||||
&vpx_highbd_fdct4x4_c, &highbd_wrapper<vpx_highbd_idct4x4_16_add_c>,
|
||||
&highbd_wrapper<vpx_highbd_idct4x4_16_add_sse4_1>, TX_4X4, 16, 8, 2),
|
||||
make_tuple(
|
||||
&vpx_highbd_fdct4x4_c, &highbd_wrapper<vpx_highbd_idct4x4_16_add_c>,
|
||||
&highbd_wrapper<vpx_highbd_idct4x4_16_add_sse4_1>, TX_4X4, 16, 10, 2),
|
||||
make_tuple(
|
||||
&vpx_highbd_fdct4x4_c, &highbd_wrapper<vpx_highbd_idct4x4_16_add_c>,
|
||||
&highbd_wrapper<vpx_highbd_idct4x4_16_add_sse4_1>, TX_4X4, 16, 12, 2)
|
||||
};
|
||||
|
||||
INSTANTIATE_TEST_CASE_P(SSE4_1, PartialIDctTest,
|
||||
::testing::ValuesIn(sse4_1_partial_idct_tests));
|
||||
#endif // HAVE_SSE4_1 && CONFIG_VP9_HIGHBITDEPTH
|
||||
|
||||
#if HAVE_DSPR2 && !CONFIG_VP9_HIGHBITDEPTH
|
||||
const PartialInvTxfmParam dspr2_partial_idct_tests[] = {
|
||||
make_tuple(&vpx_fdct32x32_c, &wrapper<vpx_idct32x32_1024_add_c>,
|
||||
&wrapper<vpx_idct32x32_1024_add_dspr2>, TX_32X32, 1024, 8, 1),
|
||||
make_tuple(&vpx_fdct32x32_c, &wrapper<vpx_idct32x32_1024_add_c>,
|
||||
&wrapper<vpx_idct32x32_1024_add_dspr2>, TX_32X32, 135, 8, 1),
|
||||
make_tuple(&vpx_fdct32x32_c, &wrapper<vpx_idct32x32_1024_add_c>,
|
||||
make_tuple(&vpx_fdct32x32_c, &wrapper<vpx_idct32x32_34_add_c>,
|
||||
&wrapper<vpx_idct32x32_34_add_dspr2>, TX_32X32, 34, 8, 1),
|
||||
make_tuple(&vpx_fdct32x32_c, &wrapper<vpx_idct32x32_1024_add_c>,
|
||||
make_tuple(&vpx_fdct32x32_c, &wrapper<vpx_idct32x32_1_add_c>,
|
||||
&wrapper<vpx_idct32x32_1_add_dspr2>, TX_32X32, 1, 8, 1),
|
||||
make_tuple(&vpx_fdct16x16_c, &wrapper<vpx_idct16x16_256_add_c>,
|
||||
&wrapper<vpx_idct16x16_256_add_dspr2>, TX_16X16, 256, 8, 1),
|
||||
make_tuple(&vpx_fdct16x16_c, &wrapper<vpx_idct16x16_256_add_c>,
|
||||
make_tuple(&vpx_fdct16x16_c, &wrapper<vpx_idct16x16_10_add_c>,
|
||||
&wrapper<vpx_idct16x16_10_add_dspr2>, TX_16X16, 10, 8, 1),
|
||||
make_tuple(&vpx_fdct16x16_c, &wrapper<vpx_idct16x16_256_add_c>,
|
||||
make_tuple(&vpx_fdct16x16_c, &wrapper<vpx_idct16x16_1_add_c>,
|
||||
&wrapper<vpx_idct16x16_1_add_dspr2>, TX_16X16, 1, 8, 1),
|
||||
make_tuple(&vpx_fdct8x8_c, &wrapper<vpx_idct8x8_64_add_c>,
|
||||
&wrapper<vpx_idct8x8_64_add_dspr2>, TX_8X8, 64, 8, 1),
|
||||
make_tuple(&vpx_fdct8x8_c, &wrapper<vpx_idct8x8_64_add_c>,
|
||||
make_tuple(&vpx_fdct8x8_c, &wrapper<vpx_idct8x8_12_add_c>,
|
||||
&wrapper<vpx_idct8x8_12_add_dspr2>, TX_8X8, 12, 8, 1),
|
||||
make_tuple(&vpx_fdct8x8_c, &wrapper<vpx_idct8x8_64_add_c>,
|
||||
make_tuple(&vpx_fdct8x8_c, &wrapper<vpx_idct8x8_1_add_c>,
|
||||
&wrapper<vpx_idct8x8_1_add_dspr2>, TX_8X8, 1, 8, 1),
|
||||
make_tuple(&vpx_fdct4x4_c, &wrapper<vpx_idct4x4_16_add_c>,
|
||||
&wrapper<vpx_idct4x4_16_add_dspr2>, TX_4X4, 16, 8, 1),
|
||||
make_tuple(&vpx_fdct4x4_c, &wrapper<vpx_idct4x4_16_add_c>,
|
||||
make_tuple(&vpx_fdct4x4_c, &wrapper<vpx_idct4x4_1_add_c>,
|
||||
&wrapper<vpx_idct4x4_1_add_dspr2>, TX_4X4, 1, 8, 1)
|
||||
};
|
||||
|
||||
INSTANTIATE_TEST_CASE_P(DSPR2, PartialIDctTest,
|
||||
::testing::ValuesIn(dspr2_partial_idct_tests));
|
||||
#endif // HAVE_DSPR2 && !CONFIG_EMULATE_HARDWARE && !CONFIG_VP9_HIGHBITDEPTH
|
||||
#endif // HAVE_DSPR2 && !CONFIG_VP9_HIGHBITDEPTH
|
||||
|
||||
#if HAVE_MSA && !CONFIG_EMULATE_HARDWARE && !CONFIG_VP9_HIGHBITDEPTH
|
||||
#if HAVE_MSA && !CONFIG_VP9_HIGHBITDEPTH
|
||||
// 32x32_135_ is implemented using the 1024 version.
|
||||
const PartialInvTxfmParam msa_partial_idct_tests[] = {
|
||||
make_tuple(&vpx_fdct32x32_c, &wrapper<vpx_idct32x32_1024_add_c>,
|
||||
&wrapper<vpx_idct32x32_1024_add_msa>, TX_32X32, 1024, 8, 1),
|
||||
make_tuple(&vpx_fdct32x32_c, &wrapper<vpx_idct32x32_1024_add_c>,
|
||||
&wrapper<vpx_idct32x32_1024_add_msa>, TX_32X32, 135, 8, 1),
|
||||
make_tuple(&vpx_fdct32x32_c, &wrapper<vpx_idct32x32_1024_add_c>,
|
||||
make_tuple(&vpx_fdct32x32_c, &wrapper<vpx_idct32x32_34_add_c>,
|
||||
&wrapper<vpx_idct32x32_34_add_msa>, TX_32X32, 34, 8, 1),
|
||||
make_tuple(&vpx_fdct32x32_c, &wrapper<vpx_idct32x32_1024_add_c>,
|
||||
make_tuple(&vpx_fdct32x32_c, &wrapper<vpx_idct32x32_1_add_c>,
|
||||
&wrapper<vpx_idct32x32_1_add_msa>, TX_32X32, 1, 8, 1),
|
||||
make_tuple(&vpx_fdct16x16_c, &wrapper<vpx_idct16x16_256_add_c>,
|
||||
&wrapper<vpx_idct16x16_256_add_msa>, TX_16X16, 256, 8, 1),
|
||||
make_tuple(&vpx_fdct16x16_c, &wrapper<vpx_idct16x16_256_add_c>,
|
||||
make_tuple(&vpx_fdct16x16_c, &wrapper<vpx_idct16x16_10_add_c>,
|
||||
&wrapper<vpx_idct16x16_10_add_msa>, TX_16X16, 10, 8, 1),
|
||||
make_tuple(&vpx_fdct16x16_c, &wrapper<vpx_idct16x16_256_add_c>,
|
||||
make_tuple(&vpx_fdct16x16_c, &wrapper<vpx_idct16x16_1_add_c>,
|
||||
&wrapper<vpx_idct16x16_1_add_msa>, TX_16X16, 1, 8, 1),
|
||||
make_tuple(&vpx_fdct8x8_c, &wrapper<vpx_idct8x8_64_add_c>,
|
||||
&wrapper<vpx_idct8x8_64_add_msa>, TX_8X8, 64, 8, 1),
|
||||
make_tuple(&vpx_fdct8x8_c, &wrapper<vpx_idct8x8_64_add_c>,
|
||||
make_tuple(&vpx_fdct8x8_c, &wrapper<vpx_idct8x8_12_add_c>,
|
||||
&wrapper<vpx_idct8x8_12_add_msa>, TX_8X8, 12, 8, 1),
|
||||
make_tuple(&vpx_fdct8x8_c, &wrapper<vpx_idct8x8_64_add_c>,
|
||||
make_tuple(&vpx_fdct8x8_c, &wrapper<vpx_idct8x8_1_add_c>,
|
||||
&wrapper<vpx_idct8x8_1_add_msa>, TX_8X8, 1, 8, 1),
|
||||
make_tuple(&vpx_fdct4x4_c, &wrapper<vpx_idct4x4_16_add_c>,
|
||||
&wrapper<vpx_idct4x4_16_add_msa>, TX_4X4, 16, 8, 1),
|
||||
make_tuple(&vpx_fdct4x4_c, &wrapper<vpx_idct4x4_16_add_c>,
|
||||
make_tuple(&vpx_fdct4x4_c, &wrapper<vpx_idct4x4_1_add_c>,
|
||||
&wrapper<vpx_idct4x4_1_add_msa>, TX_4X4, 1, 8, 1)
|
||||
};
|
||||
|
||||
INSTANTIATE_TEST_CASE_P(MSA, PartialIDctTest,
|
||||
::testing::ValuesIn(msa_partial_idct_tests));
|
||||
#endif // HAVE_MSA && !CONFIG_EMULATE_HARDWARE && !CONFIG_VP9_HIGHBITDEPTH
|
||||
#endif // HAVE_MSA && !CONFIG_VP9_HIGHBITDEPTH
|
||||
|
||||
#endif // !CONFIG_EMULATE_HARDWARE
|
||||
|
||||
} // namespace
|
||||
|
||||
@@ -11,6 +11,7 @@
|
||||
#include "./vpx_config.h"
|
||||
#include "./vpx_dsp_rtcd.h"
|
||||
#include "test/acm_random.h"
|
||||
#include "test/buffer.h"
|
||||
#include "test/clear_system_state.h"
|
||||
#include "test/register_state_check.h"
|
||||
#include "third_party/googletest/src/include/gtest/gtest.h"
|
||||
@@ -18,6 +19,7 @@
|
||||
#include "vpx_mem/vpx_mem.h"
|
||||
|
||||
using libvpx_test::ACMRandom;
|
||||
using libvpx_test::Buffer;
|
||||
|
||||
typedef void (*VpxPostProcDownAndAcrossMbRowFunc)(
|
||||
unsigned char *src_ptr, unsigned char *dst_ptr, int src_pixels_per_line,
|
||||
@@ -54,31 +56,16 @@ TEST_P(VpxPostProcDownAndAcrossMbRowTest, CheckFilterOutput) {
|
||||
const int block_height = 16;
|
||||
|
||||
// 5-tap filter needs 2 padding rows above and below the block in the input.
|
||||
const int input_width = block_width;
|
||||
const int input_height = block_height + 4;
|
||||
const int input_stride = input_width;
|
||||
const int input_size = input_width * input_height;
|
||||
Buffer<uint8_t> src_image = Buffer<uint8_t>(block_width, block_height, 2);
|
||||
ASSERT_TRUE(src_image.Init());
|
||||
|
||||
// Filter extends output block by 8 samples at left and right edges.
|
||||
const int output_width = block_width + 16;
|
||||
const int output_height = block_height;
|
||||
const int output_stride = output_width;
|
||||
const int output_size = output_width * output_height;
|
||||
|
||||
uint8_t *const src_image = new uint8_t[input_size];
|
||||
ASSERT_TRUE(src_image != NULL);
|
||||
|
||||
// Though the left padding is only 8 bytes, the assembly code tries to
|
||||
// read 16 bytes before the pointer.
|
||||
uint8_t *const dst_image = new uint8_t[output_size + 8];
|
||||
ASSERT_TRUE(dst_image != NULL);
|
||||
Buffer<uint8_t> dst_image =
|
||||
Buffer<uint8_t>(block_width, block_height, 8, 16, 8, 8);
|
||||
ASSERT_TRUE(dst_image.Init());
|
||||
|
||||
// Pointers to top-left pixel of block in the input and output images.
|
||||
uint8_t *const src_image_ptr = src_image + (input_stride << 1);
|
||||
|
||||
// The assembly works in increments of 16. The first read may be offset by
|
||||
// this amount.
|
||||
uint8_t *const dst_image_ptr = dst_image + 16;
|
||||
uint8_t *const flimits =
|
||||
reinterpret_cast<uint8_t *>(vpx_memalign(16, block_width));
|
||||
(void)memset(flimits, 255, block_width);
|
||||
@@ -86,37 +73,29 @@ TEST_P(VpxPostProcDownAndAcrossMbRowTest, CheckFilterOutput) {
|
||||
// Initialize pixels in the input:
|
||||
// block pixels to value 1,
|
||||
// border pixels to value 10.
|
||||
(void)memset(src_image, 10, input_size);
|
||||
uint8_t *pixel_ptr = src_image_ptr;
|
||||
for (int i = 0; i < block_height; ++i) {
|
||||
for (int j = 0; j < block_width; ++j) {
|
||||
pixel_ptr[j] = 1;
|
||||
}
|
||||
pixel_ptr += input_stride;
|
||||
}
|
||||
src_image.SetPadding(10);
|
||||
src_image.Set(1);
|
||||
|
||||
// Initialize pixels in the output to 99.
|
||||
(void)memset(dst_image, 99, output_size);
|
||||
dst_image.Set(99);
|
||||
|
||||
ASM_REGISTER_STATE_CHECK(GetParam()(src_image_ptr, dst_image_ptr,
|
||||
input_stride, output_stride, block_width,
|
||||
flimits, 16));
|
||||
ASM_REGISTER_STATE_CHECK(GetParam()(
|
||||
src_image.TopLeftPixel(), dst_image.TopLeftPixel(), src_image.stride(),
|
||||
dst_image.stride(), block_width, flimits, 16));
|
||||
|
||||
static const uint8_t kExpectedOutput[block_height] = {
|
||||
4, 3, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 3, 4
|
||||
};
|
||||
|
||||
pixel_ptr = dst_image_ptr;
|
||||
uint8_t *pixel_ptr = dst_image.TopLeftPixel();
|
||||
for (int i = 0; i < block_height; ++i) {
|
||||
for (int j = 0; j < block_width; ++j) {
|
||||
ASSERT_EQ(kExpectedOutput[i], pixel_ptr[j]) << "at (" << i << ", " << j
|
||||
<< ")";
|
||||
ASSERT_EQ(kExpectedOutput[i], pixel_ptr[j])
|
||||
<< "at (" << i << ", " << j << ")";
|
||||
}
|
||||
pixel_ptr += output_stride;
|
||||
pixel_ptr += dst_image.stride();
|
||||
}
|
||||
|
||||
delete[] src_image;
|
||||
delete[] dst_image;
|
||||
vpx_free(flimits);
|
||||
};
|
||||
|
||||
@@ -129,35 +108,20 @@ TEST_P(VpxPostProcDownAndAcrossMbRowTest, CheckCvsAssembly) {
|
||||
|
||||
// 5-tap filter needs 2 padding rows above and below the block in the input.
|
||||
// SSE2 reads in blocks of 16. Pad an extra 8 in case the width is not %16.
|
||||
const int input_width = block_width;
|
||||
const int input_height = block_height + 4 + 8;
|
||||
const int input_stride = input_width;
|
||||
const int input_size = input_stride * input_height;
|
||||
Buffer<uint8_t> src_image =
|
||||
Buffer<uint8_t>(block_width, block_height, 2, 2, 10, 2);
|
||||
ASSERT_TRUE(src_image.Init());
|
||||
|
||||
// Filter extends output block by 8 samples at left and right edges.
|
||||
// Though the left padding is only 8 bytes, there is 'above' padding as well
|
||||
// so when the assembly code tries to read 16 bytes before the pointer it is
|
||||
// not a problem.
|
||||
// SSE2 reads in blocks of 16. Pad an extra 8 in case the width is not %16.
|
||||
const int output_width = block_width + 24;
|
||||
const int output_height = block_height;
|
||||
const int output_stride = output_width;
|
||||
const int output_size = output_stride * output_height;
|
||||
|
||||
uint8_t *const src_image = new uint8_t[input_size];
|
||||
ASSERT_TRUE(src_image != NULL);
|
||||
|
||||
// Though the left padding is only 8 bytes, the assembly code tries to
|
||||
// read 16 bytes before the pointer.
|
||||
uint8_t *const dst_image = new uint8_t[output_size + 8];
|
||||
ASSERT_TRUE(dst_image != NULL);
|
||||
uint8_t *const dst_image_ref = new uint8_t[output_size + 8];
|
||||
ASSERT_TRUE(dst_image_ref != NULL);
|
||||
|
||||
// Pointers to top-left pixel of block in the input and output images.
|
||||
uint8_t *const src_image_ptr = src_image + (input_stride << 1);
|
||||
|
||||
// The assembly works in increments of 16. The first read may be offset by
|
||||
// this amount.
|
||||
uint8_t *const dst_image_ptr = dst_image + 16;
|
||||
uint8_t *const dst_image_ref_ptr = dst_image + 16;
|
||||
Buffer<uint8_t> dst_image =
|
||||
Buffer<uint8_t>(block_width, block_height, 8, 8, 16, 8);
|
||||
ASSERT_TRUE(dst_image.Init());
|
||||
Buffer<uint8_t> dst_image_ref = Buffer<uint8_t>(block_width, block_height, 8);
|
||||
ASSERT_TRUE(dst_image_ref.Init());
|
||||
|
||||
// Filter values are set in blocks of 16 for Y and 8 for U/V. Each macroblock
|
||||
// can have a different filter. SSE2 assembly reads flimits in blocks of 16 so
|
||||
@@ -171,14 +135,8 @@ TEST_P(VpxPostProcDownAndAcrossMbRowTest, CheckCvsAssembly) {
|
||||
// Initialize pixels in the input:
|
||||
// block pixels to random values.
|
||||
// border pixels to value 10.
|
||||
(void)memset(src_image, 10, input_size);
|
||||
uint8_t *pixel_ptr = src_image_ptr;
|
||||
for (int i = 0; i < block_height; ++i) {
|
||||
for (int j = 0; j < block_width; ++j) {
|
||||
pixel_ptr[j] = rnd.Rand8();
|
||||
}
|
||||
pixel_ptr += input_stride;
|
||||
}
|
||||
src_image.SetPadding(10);
|
||||
src_image.Set(&rnd, &ACMRandom::Rand8);
|
||||
|
||||
for (int blocks = 0; blocks < block_width; blocks += 8) {
|
||||
(void)memset(flimits, 0, sizeof(*flimits) * flimits_width);
|
||||
@@ -186,29 +144,22 @@ TEST_P(VpxPostProcDownAndAcrossMbRowTest, CheckCvsAssembly) {
|
||||
for (int f = 0; f < 255; f++) {
|
||||
(void)memset(flimits + blocks, f, sizeof(*flimits) * 8);
|
||||
|
||||
(void)memset(dst_image, 0, output_size);
|
||||
(void)memset(dst_image_ref, 0, output_size);
|
||||
dst_image.Set(0);
|
||||
dst_image_ref.Set(0);
|
||||
|
||||
vpx_post_proc_down_and_across_mb_row_c(
|
||||
src_image_ptr, dst_image_ref_ptr, input_stride, output_stride,
|
||||
block_width, flimits, block_height);
|
||||
ASM_REGISTER_STATE_CHECK(GetParam()(src_image_ptr, dst_image_ptr,
|
||||
input_stride, output_stride,
|
||||
block_width, flimits, 16));
|
||||
src_image.TopLeftPixel(), dst_image_ref.TopLeftPixel(),
|
||||
src_image.stride(), dst_image_ref.stride(), block_width, flimits,
|
||||
block_height);
|
||||
ASM_REGISTER_STATE_CHECK(
|
||||
GetParam()(src_image.TopLeftPixel(), dst_image.TopLeftPixel(),
|
||||
src_image.stride(), dst_image.stride(), block_width,
|
||||
flimits, block_height));
|
||||
|
||||
for (int i = 0; i < block_height; ++i) {
|
||||
for (int j = 0; j < block_width; ++j) {
|
||||
ASSERT_EQ(dst_image_ref_ptr[j + i * output_stride],
|
||||
dst_image_ptr[j + i * output_stride])
|
||||
<< "at (" << i << ", " << j << ")";
|
||||
}
|
||||
}
|
||||
ASSERT_TRUE(dst_image.CheckValues(dst_image_ref));
|
||||
}
|
||||
}
|
||||
|
||||
delete[] src_image;
|
||||
delete[] dst_image;
|
||||
delete[] dst_image_ref;
|
||||
vpx_free(flimits);
|
||||
}
|
||||
|
||||
@@ -231,8 +182,8 @@ class VpxMbPostProcAcrossIpTest
|
||||
int rows, int cols, int src_pitch) {
|
||||
for (int r = 0; r < rows; r++) {
|
||||
for (int c = 0; c < cols; c++) {
|
||||
ASSERT_EQ(expected_output[c], src_c[c]) << "at (" << r << ", " << c
|
||||
<< ")";
|
||||
ASSERT_EQ(expected_output[c], src_c[c])
|
||||
<< "at (" << r << ", " << c << ")";
|
||||
}
|
||||
src_c += src_pitch;
|
||||
}
|
||||
@@ -249,108 +200,83 @@ class VpxMbPostProcAcrossIpTest
|
||||
TEST_P(VpxMbPostProcAcrossIpTest, CheckLowFilterOutput) {
|
||||
const int rows = 16;
|
||||
const int cols = 16;
|
||||
const int src_left_padding = 8;
|
||||
const int src_right_padding = 17;
|
||||
const int src_width = cols + src_left_padding + src_right_padding;
|
||||
const int src_size = rows * src_width;
|
||||
|
||||
unsigned char *const src = new unsigned char[src_size];
|
||||
ASSERT_TRUE(src != NULL);
|
||||
memset(src, 10, src_size);
|
||||
unsigned char *const s = src + src_left_padding;
|
||||
SetCols(s, rows, cols, src_width);
|
||||
Buffer<uint8_t> src = Buffer<uint8_t>(cols, rows, 8, 8, 17, 8);
|
||||
ASSERT_TRUE(src.Init());
|
||||
src.SetPadding(10);
|
||||
SetCols(src.TopLeftPixel(), rows, cols, src.stride());
|
||||
|
||||
unsigned char *expected_output = new unsigned char[rows * cols];
|
||||
ASSERT_TRUE(expected_output != NULL);
|
||||
SetCols(expected_output, rows, cols, cols);
|
||||
Buffer<uint8_t> expected_output = Buffer<uint8_t>(cols, rows, 0);
|
||||
ASSERT_TRUE(expected_output.Init());
|
||||
SetCols(expected_output.TopLeftPixel(), rows, cols, expected_output.stride());
|
||||
|
||||
RunFilterLevel(s, rows, cols, src_width, q2mbl(0), expected_output);
|
||||
delete[] src;
|
||||
delete[] expected_output;
|
||||
RunFilterLevel(src.TopLeftPixel(), rows, cols, src.stride(), q2mbl(0),
|
||||
expected_output.TopLeftPixel());
|
||||
}
|
||||
|
||||
TEST_P(VpxMbPostProcAcrossIpTest, CheckMediumFilterOutput) {
|
||||
const int rows = 16;
|
||||
const int cols = 16;
|
||||
const int src_left_padding = 8;
|
||||
const int src_right_padding = 17;
|
||||
const int src_width = cols + src_left_padding + src_right_padding;
|
||||
const int src_size = rows * src_width;
|
||||
|
||||
unsigned char *const src = new unsigned char[src_size];
|
||||
ASSERT_TRUE(src != NULL);
|
||||
memset(src, 10, src_size);
|
||||
unsigned char *const s = src + src_left_padding;
|
||||
Buffer<uint8_t> src = Buffer<uint8_t>(cols, rows, 8, 8, 17, 8);
|
||||
ASSERT_TRUE(src.Init());
|
||||
src.SetPadding(10);
|
||||
SetCols(src.TopLeftPixel(), rows, cols, src.stride());
|
||||
|
||||
SetCols(s, rows, cols, src_width);
|
||||
static const unsigned char kExpectedOutput[cols] = {
|
||||
2, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 13
|
||||
};
|
||||
|
||||
RunFilterLevel(s, rows, cols, src_width, q2mbl(70), kExpectedOutput);
|
||||
|
||||
delete[] src;
|
||||
RunFilterLevel(src.TopLeftPixel(), rows, cols, src.stride(), q2mbl(70),
|
||||
kExpectedOutput);
|
||||
}
|
||||
|
||||
TEST_P(VpxMbPostProcAcrossIpTest, CheckHighFilterOutput) {
|
||||
const int rows = 16;
|
||||
const int cols = 16;
|
||||
const int src_left_padding = 8;
|
||||
const int src_right_padding = 17;
|
||||
const int src_width = cols + src_left_padding + src_right_padding;
|
||||
const int src_size = rows * src_width;
|
||||
|
||||
unsigned char *const src = new unsigned char[src_size];
|
||||
ASSERT_TRUE(src != NULL);
|
||||
unsigned char *const s = src + src_left_padding;
|
||||
Buffer<uint8_t> src = Buffer<uint8_t>(cols, rows, 8, 8, 17, 8);
|
||||
ASSERT_TRUE(src.Init());
|
||||
src.SetPadding(10);
|
||||
SetCols(src.TopLeftPixel(), rows, cols, src.stride());
|
||||
|
||||
memset(src, 10, src_size);
|
||||
SetCols(s, rows, cols, src_width);
|
||||
static const unsigned char kExpectedOutput[cols] = {
|
||||
2, 2, 3, 4, 4, 5, 6, 7, 8, 9, 10, 11, 11, 12, 13, 13
|
||||
};
|
||||
|
||||
RunFilterLevel(s, rows, cols, src_width, INT_MAX, kExpectedOutput);
|
||||
RunFilterLevel(src.TopLeftPixel(), rows, cols, src.stride(), INT_MAX,
|
||||
kExpectedOutput);
|
||||
|
||||
memset(src, 10, src_size);
|
||||
SetCols(s, rows, cols, src_width);
|
||||
RunFilterLevel(s, rows, cols, src_width, q2mbl(100), kExpectedOutput);
|
||||
SetCols(src.TopLeftPixel(), rows, cols, src.stride());
|
||||
|
||||
delete[] src;
|
||||
RunFilterLevel(src.TopLeftPixel(), rows, cols, src.stride(), q2mbl(100),
|
||||
kExpectedOutput);
|
||||
}
|
||||
|
||||
TEST_P(VpxMbPostProcAcrossIpTest, CheckCvsAssembly) {
|
||||
const int rows = 16;
|
||||
const int cols = 16;
|
||||
const int src_left_padding = 8;
|
||||
const int src_right_padding = 17;
|
||||
const int src_width = cols + src_left_padding + src_right_padding;
|
||||
const int src_size = rows * src_width;
|
||||
|
||||
unsigned char *const c_mem = new unsigned char[src_size];
|
||||
unsigned char *const asm_mem = new unsigned char[src_size];
|
||||
ASSERT_TRUE(c_mem != NULL);
|
||||
ASSERT_TRUE(asm_mem != NULL);
|
||||
unsigned char *const src_c = c_mem + src_left_padding;
|
||||
unsigned char *const src_asm = asm_mem + src_left_padding;
|
||||
Buffer<uint8_t> c_mem = Buffer<uint8_t>(cols, rows, 8, 8, 17, 8);
|
||||
ASSERT_TRUE(c_mem.Init());
|
||||
Buffer<uint8_t> asm_mem = Buffer<uint8_t>(cols, rows, 8, 8, 17, 8);
|
||||
ASSERT_TRUE(asm_mem.Init());
|
||||
|
||||
// When level >= 100, the filter behaves the same as the level = INT_MAX
|
||||
// When level < 20, it behaves the same as the level = 0
|
||||
for (int level = 0; level < 100; level++) {
|
||||
memset(c_mem, 10, src_size);
|
||||
memset(asm_mem, 10, src_size);
|
||||
SetCols(src_c, rows, cols, src_width);
|
||||
SetCols(src_asm, rows, cols, src_width);
|
||||
c_mem.SetPadding(10);
|
||||
asm_mem.SetPadding(10);
|
||||
SetCols(c_mem.TopLeftPixel(), rows, cols, c_mem.stride());
|
||||
SetCols(asm_mem.TopLeftPixel(), rows, cols, asm_mem.stride());
|
||||
|
||||
vpx_mbpost_proc_across_ip_c(src_c, src_width, rows, cols, q2mbl(level));
|
||||
ASM_REGISTER_STATE_CHECK(
|
||||
GetParam()(src_asm, src_width, rows, cols, q2mbl(level)));
|
||||
vpx_mbpost_proc_across_ip_c(c_mem.TopLeftPixel(), c_mem.stride(), rows,
|
||||
cols, q2mbl(level));
|
||||
ASM_REGISTER_STATE_CHECK(GetParam()(
|
||||
asm_mem.TopLeftPixel(), asm_mem.stride(), rows, cols, q2mbl(level)));
|
||||
|
||||
RunComparison(src_c, src_asm, rows, cols, src_width);
|
||||
ASSERT_TRUE(asm_mem.CheckValues(c_mem));
|
||||
}
|
||||
|
||||
delete[] c_mem;
|
||||
delete[] asm_mem;
|
||||
}
|
||||
|
||||
class VpxMbPostProcDownTest
|
||||
@@ -359,44 +285,10 @@ class VpxMbPostProcDownTest
|
||||
virtual void TearDown() { libvpx_test::ClearSystemState(); }
|
||||
|
||||
protected:
|
||||
void SetRows(unsigned char *src_c, int rows, int cols) {
|
||||
void SetRows(unsigned char *src_c, int rows, int cols, int src_width) {
|
||||
for (int r = 0; r < rows; r++) {
|
||||
memset(src_c, r, cols);
|
||||
src_c += cols;
|
||||
}
|
||||
}
|
||||
|
||||
void SetRandom(unsigned char *src_c, unsigned char *src_asm, int rows,
|
||||
int cols, int src_pitch) {
|
||||
ACMRandom rnd;
|
||||
rnd.Reset(ACMRandom::DeterministicSeed());
|
||||
|
||||
// Add some random noise to the input
|
||||
for (int r = 0; r < rows; r++) {
|
||||
for (int c = 0; c < cols; c++) {
|
||||
const int noise = rnd(4);
|
||||
src_c[c] = r + noise;
|
||||
src_asm[c] = r + noise;
|
||||
}
|
||||
src_c += src_pitch;
|
||||
src_asm += src_pitch;
|
||||
}
|
||||
}
|
||||
|
||||
void SetRandomSaturation(unsigned char *src_c, unsigned char *src_asm,
|
||||
int rows, int cols, int src_pitch) {
|
||||
ACMRandom rnd;
|
||||
rnd.Reset(ACMRandom::DeterministicSeed());
|
||||
|
||||
// Add some random noise to the input
|
||||
for (int r = 0; r < rows; r++) {
|
||||
for (int c = 0; c < cols; c++) {
|
||||
const int noise = 3 * rnd(2);
|
||||
src_c[c] = r + noise;
|
||||
src_asm[c] = r + noise;
|
||||
}
|
||||
src_c += src_pitch;
|
||||
src_asm += src_pitch;
|
||||
src_c += src_width;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -404,24 +296,13 @@ class VpxMbPostProcDownTest
|
||||
int rows, int cols, int src_pitch) {
|
||||
for (int r = 0; r < rows; r++) {
|
||||
for (int c = 0; c < cols; c++) {
|
||||
ASSERT_EQ(expected_output[r * rows + c], src_c[c]) << "at (" << r
|
||||
<< ", " << c << ")";
|
||||
ASSERT_EQ(expected_output[r * rows + c], src_c[c])
|
||||
<< "at (" << r << ", " << c << ")";
|
||||
}
|
||||
src_c += src_pitch;
|
||||
}
|
||||
}
|
||||
|
||||
void RunComparison(unsigned char *src_c, unsigned char *src_asm, int rows,
|
||||
int cols, int src_pitch) {
|
||||
for (int r = 0; r < rows; r++) {
|
||||
for (int c = 0; c < cols; c++) {
|
||||
ASSERT_EQ(src_c[c], src_asm[c]) << "at (" << r << ", " << c << ")";
|
||||
}
|
||||
src_c += src_pitch;
|
||||
src_asm += src_pitch;
|
||||
}
|
||||
}
|
||||
|
||||
void RunFilterLevel(unsigned char *s, int rows, int cols, int src_width,
|
||||
int filter_level, const unsigned char *expected_output) {
|
||||
ASM_REGISTER_STATE_CHECK(
|
||||
@@ -433,17 +314,12 @@ class VpxMbPostProcDownTest
|
||||
TEST_P(VpxMbPostProcDownTest, CheckHighFilterOutput) {
|
||||
const int rows = 16;
|
||||
const int cols = 16;
|
||||
const int src_pitch = cols;
|
||||
const int src_top_padding = 8;
|
||||
const int src_bottom_padding = 17;
|
||||
|
||||
const int src_size = cols * (rows + src_top_padding + src_bottom_padding);
|
||||
unsigned char *const c_mem = new unsigned char[src_size];
|
||||
ASSERT_TRUE(c_mem != NULL);
|
||||
memset(c_mem, 10, src_size);
|
||||
unsigned char *const src_c = c_mem + src_top_padding * src_pitch;
|
||||
Buffer<uint8_t> src_c = Buffer<uint8_t>(cols, rows, 8, 8, 8, 17);
|
||||
ASSERT_TRUE(src_c.Init());
|
||||
src_c.SetPadding(10);
|
||||
|
||||
SetRows(src_c, rows, cols);
|
||||
SetRows(src_c.TopLeftPixel(), rows, cols, src_c.stride());
|
||||
|
||||
static const unsigned char kExpectedOutput[rows * cols] = {
|
||||
2, 2, 1, 1, 2, 2, 2, 2, 2, 2, 1, 1, 2, 2, 2, 2, 2, 2, 2,
|
||||
@@ -462,29 +338,24 @@ TEST_P(VpxMbPostProcDownTest, CheckHighFilterOutput) {
|
||||
13, 13, 13, 13, 14, 13, 13, 13, 13
|
||||
};
|
||||
|
||||
RunFilterLevel(src_c, rows, cols, src_pitch, INT_MAX, kExpectedOutput);
|
||||
RunFilterLevel(src_c.TopLeftPixel(), rows, cols, src_c.stride(), INT_MAX,
|
||||
kExpectedOutput);
|
||||
|
||||
memset(c_mem, 10, src_size);
|
||||
SetRows(src_c, rows, cols);
|
||||
RunFilterLevel(src_c, rows, cols, src_pitch, q2mbl(100), kExpectedOutput);
|
||||
|
||||
delete[] c_mem;
|
||||
src_c.SetPadding(10);
|
||||
SetRows(src_c.TopLeftPixel(), rows, cols, src_c.stride());
|
||||
RunFilterLevel(src_c.TopLeftPixel(), rows, cols, src_c.stride(), q2mbl(100),
|
||||
kExpectedOutput);
|
||||
}
|
||||
|
||||
TEST_P(VpxMbPostProcDownTest, CheckMediumFilterOutput) {
|
||||
const int rows = 16;
|
||||
const int cols = 16;
|
||||
const int src_pitch = cols;
|
||||
const int src_top_padding = 8;
|
||||
const int src_bottom_padding = 17;
|
||||
|
||||
const int src_size = cols * (rows + src_top_padding + src_bottom_padding);
|
||||
unsigned char *const c_mem = new unsigned char[src_size];
|
||||
ASSERT_TRUE(c_mem != NULL);
|
||||
memset(c_mem, 10, src_size);
|
||||
unsigned char *const src_c = c_mem + src_top_padding * src_pitch;
|
||||
Buffer<uint8_t> src_c = Buffer<uint8_t>(cols, rows, 8, 8, 8, 17);
|
||||
ASSERT_TRUE(src_c.Init());
|
||||
src_c.SetPadding(10);
|
||||
|
||||
SetRows(src_c, rows, cols);
|
||||
SetRows(src_c.TopLeftPixel(), rows, cols, src_c.stride());
|
||||
|
||||
static const unsigned char kExpectedOutput[rows * cols] = {
|
||||
2, 2, 1, 1, 2, 2, 2, 2, 2, 2, 1, 1, 2, 2, 2, 2, 2, 2, 2,
|
||||
@@ -503,70 +374,65 @@ TEST_P(VpxMbPostProcDownTest, CheckMediumFilterOutput) {
|
||||
13, 13, 13, 13, 14, 13, 13, 13, 13
|
||||
};
|
||||
|
||||
RunFilterLevel(src_c, rows, cols, src_pitch, q2mbl(70), kExpectedOutput);
|
||||
|
||||
delete[] c_mem;
|
||||
RunFilterLevel(src_c.TopLeftPixel(), rows, cols, src_c.stride(), q2mbl(70),
|
||||
kExpectedOutput);
|
||||
}
|
||||
|
||||
TEST_P(VpxMbPostProcDownTest, CheckLowFilterOutput) {
|
||||
const int rows = 16;
|
||||
const int cols = 16;
|
||||
const int src_pitch = cols;
|
||||
const int src_top_padding = 8;
|
||||
const int src_bottom_padding = 17;
|
||||
|
||||
const int src_size = cols * (rows + src_top_padding + src_bottom_padding);
|
||||
unsigned char *const c_mem = new unsigned char[src_size];
|
||||
ASSERT_TRUE(c_mem != NULL);
|
||||
memset(c_mem, 10, src_size);
|
||||
unsigned char *const src_c = c_mem + src_top_padding * src_pitch;
|
||||
Buffer<uint8_t> src_c = Buffer<uint8_t>(cols, rows, 8, 8, 8, 17);
|
||||
ASSERT_TRUE(src_c.Init());
|
||||
src_c.SetPadding(10);
|
||||
|
||||
SetRows(src_c, rows, cols);
|
||||
SetRows(src_c.TopLeftPixel(), rows, cols, src_c.stride());
|
||||
|
||||
unsigned char *expected_output = new unsigned char[rows * cols];
|
||||
ASSERT_TRUE(expected_output != NULL);
|
||||
SetRows(expected_output, rows, cols);
|
||||
SetRows(expected_output, rows, cols, cols);
|
||||
|
||||
RunFilterLevel(src_c, rows, cols, src_pitch, q2mbl(0), expected_output);
|
||||
RunFilterLevel(src_c.TopLeftPixel(), rows, cols, src_c.stride(), q2mbl(0),
|
||||
expected_output);
|
||||
|
||||
delete[] c_mem;
|
||||
delete[] expected_output;
|
||||
}
|
||||
|
||||
TEST_P(VpxMbPostProcDownTest, CheckCvsAssembly) {
|
||||
const int rows = 16;
|
||||
const int cols = 16;
|
||||
const int src_pitch = cols;
|
||||
const int src_top_padding = 8;
|
||||
const int src_bottom_padding = 17;
|
||||
const int src_size = cols * (rows + src_top_padding + src_bottom_padding);
|
||||
unsigned char *const c_mem = new unsigned char[src_size];
|
||||
unsigned char *const asm_mem = new unsigned char[src_size];
|
||||
ASSERT_TRUE(c_mem != NULL);
|
||||
ASSERT_TRUE(asm_mem != NULL);
|
||||
unsigned char *const src_c = c_mem + src_top_padding * src_pitch;
|
||||
unsigned char *const src_asm = asm_mem + src_top_padding * src_pitch;
|
||||
|
||||
ACMRandom rnd;
|
||||
rnd.Reset(ACMRandom::DeterministicSeed());
|
||||
|
||||
Buffer<uint8_t> src_c = Buffer<uint8_t>(cols, rows, 8, 8, 8, 17);
|
||||
ASSERT_TRUE(src_c.Init());
|
||||
Buffer<uint8_t> src_asm = Buffer<uint8_t>(cols, rows, 8, 8, 8, 17);
|
||||
ASSERT_TRUE(src_asm.Init());
|
||||
|
||||
for (int level = 0; level < 100; level++) {
|
||||
memset(c_mem, 10, src_size);
|
||||
memset(asm_mem, 10, src_size);
|
||||
SetRandom(src_c, src_asm, rows, cols, src_pitch);
|
||||
vpx_mbpost_proc_down_c(src_c, src_pitch, rows, cols, q2mbl(level));
|
||||
ASM_REGISTER_STATE_CHECK(
|
||||
GetParam()(src_asm, src_pitch, rows, cols, q2mbl(level)));
|
||||
RunComparison(src_c, src_asm, rows, cols, src_pitch);
|
||||
src_c.SetPadding(10);
|
||||
src_asm.SetPadding(10);
|
||||
src_c.Set(&rnd, &ACMRandom::Rand8);
|
||||
src_asm.CopyFrom(src_c);
|
||||
|
||||
memset(c_mem, 10, src_size);
|
||||
memset(asm_mem, 10, src_size);
|
||||
SetRandomSaturation(src_c, src_asm, rows, cols, src_pitch);
|
||||
vpx_mbpost_proc_down_c(src_c, src_pitch, rows, cols, q2mbl(level));
|
||||
ASM_REGISTER_STATE_CHECK(
|
||||
GetParam()(src_asm, src_pitch, rows, cols, q2mbl(level)));
|
||||
RunComparison(src_c, src_asm, rows, cols, src_pitch);
|
||||
vpx_mbpost_proc_down_c(src_c.TopLeftPixel(), src_c.stride(), rows, cols,
|
||||
q2mbl(level));
|
||||
ASM_REGISTER_STATE_CHECK(GetParam()(
|
||||
src_asm.TopLeftPixel(), src_asm.stride(), rows, cols, q2mbl(level)));
|
||||
ASSERT_TRUE(src_asm.CheckValues(src_c));
|
||||
|
||||
src_c.SetPadding(10);
|
||||
src_asm.SetPadding(10);
|
||||
src_c.Set(&rnd, &ACMRandom::Rand8Extremes);
|
||||
src_asm.CopyFrom(src_c);
|
||||
|
||||
vpx_mbpost_proc_down_c(src_c.TopLeftPixel(), src_c.stride(), rows, cols,
|
||||
q2mbl(level));
|
||||
ASM_REGISTER_STATE_CHECK(GetParam()(
|
||||
src_asm.TopLeftPixel(), src_asm.stride(), rows, cols, q2mbl(level)));
|
||||
ASSERT_TRUE(src_asm.CheckValues(src_c));
|
||||
}
|
||||
|
||||
delete[] c_mem;
|
||||
delete[] asm_mem;
|
||||
}
|
||||
|
||||
INSTANTIATE_TEST_CASE_P(
|
||||
@@ -598,6 +464,9 @@ INSTANTIATE_TEST_CASE_P(
|
||||
|
||||
INSTANTIATE_TEST_CASE_P(NEON, VpxMbPostProcAcrossIpTest,
|
||||
::testing::Values(vpx_mbpost_proc_across_ip_neon));
|
||||
|
||||
INSTANTIATE_TEST_CASE_P(NEON, VpxMbPostProcDownTest,
|
||||
::testing::Values(vpx_mbpost_proc_down_neon));
|
||||
#endif // HAVE_NEON
|
||||
|
||||
#if HAVE_MSA
|
||||
|
||||
@@ -324,6 +324,15 @@ INSTANTIATE_TEST_CASE_P(
|
||||
make_tuple(4, 4, &vp8_sixtap_predict4x4_msa)));
|
||||
#endif
|
||||
|
||||
#if HAVE_MMI
|
||||
INSTANTIATE_TEST_CASE_P(
|
||||
MMI, SixtapPredictTest,
|
||||
::testing::Values(make_tuple(16, 16, &vp8_sixtap_predict16x16_mmi),
|
||||
make_tuple(8, 8, &vp8_sixtap_predict8x8_mmi),
|
||||
make_tuple(8, 4, &vp8_sixtap_predict8x4_mmi),
|
||||
make_tuple(4, 4, &vp8_sixtap_predict4x4_mmi)));
|
||||
#endif
|
||||
|
||||
class BilinearPredictTest : public PredictTestBase {};
|
||||
|
||||
TEST_P(BilinearPredictTest, TestWithRandomData) {
|
||||
|
||||
@@ -200,4 +200,12 @@ INSTANTIATE_TEST_CASE_P(
|
||||
make_tuple(&vp8_fast_quantize_b_msa, &vp8_fast_quantize_b_c),
|
||||
make_tuple(&vp8_regular_quantize_b_msa, &vp8_regular_quantize_b_c)));
|
||||
#endif // HAVE_MSA
|
||||
|
||||
#if HAVE_MMI
|
||||
INSTANTIATE_TEST_CASE_P(
|
||||
MMI, QuantizeTest,
|
||||
::testing::Values(
|
||||
make_tuple(&vp8_fast_quantize_b_mmi, &vp8_fast_quantize_b_c),
|
||||
make_tuple(&vp8_regular_quantize_b_mmi, &vp8_regular_quantize_b_c)));
|
||||
#endif // HAVE_MMI
|
||||
} // namespace
|
||||
|
||||
@@ -113,8 +113,8 @@ class RegisterStateCheck {
|
||||
int64_t post_store[8];
|
||||
vpx_push_neon(post_store);
|
||||
for (int i = 0; i < 8; ++i) {
|
||||
EXPECT_EQ(pre_store_[i], post_store[i]) << "d" << i + 8
|
||||
<< " has been modified";
|
||||
EXPECT_EQ(pre_store_[i], post_store[i])
|
||||
<< "d" << i + 8 << " has been modified";
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -298,10 +298,10 @@ TEST_P(ResizeTest, TestExternalResizeWorks) {
|
||||
unsigned int expected_h;
|
||||
ScaleForFrameNumber(frame, kInitialWidth, kInitialHeight, &expected_w,
|
||||
&expected_h, 0);
|
||||
EXPECT_EQ(expected_w, info->w) << "Frame " << frame
|
||||
<< " had unexpected width";
|
||||
EXPECT_EQ(expected_h, info->h) << "Frame " << frame
|
||||
<< " had unexpected height";
|
||||
EXPECT_EQ(expected_w, info->w)
|
||||
<< "Frame " << frame << " had unexpected width";
|
||||
EXPECT_EQ(expected_h, info->h)
|
||||
<< "Frame " << frame << " had unexpected height";
|
||||
}
|
||||
}
|
||||
|
||||
@@ -513,10 +513,10 @@ TEST_P(ResizeRealtimeTest, TestExternalResizeWorks) {
|
||||
unsigned int expected_h;
|
||||
ScaleForFrameNumber(frame, kInitialWidth, kInitialHeight, &expected_w,
|
||||
&expected_h, 1);
|
||||
EXPECT_EQ(expected_w, info->w) << "Frame " << frame
|
||||
<< " had unexpected width";
|
||||
EXPECT_EQ(expected_h, info->h) << "Frame " << frame
|
||||
<< " had unexpected height";
|
||||
EXPECT_EQ(expected_w, info->w)
|
||||
<< "Frame " << frame << " had unexpected width";
|
||||
EXPECT_EQ(expected_h, info->h)
|
||||
<< "Frame " << frame << " had unexpected height";
|
||||
EXPECT_EQ(static_cast<unsigned int>(0), GetMismatchFrames());
|
||||
}
|
||||
}
|
||||
|
||||
133
test/sad_test.cc
133
test/sad_test.cc
@@ -644,19 +644,50 @@ INSTANTIATE_TEST_CASE_P(C, SADx4Test, ::testing::ValuesIn(x4d_c_tests));
|
||||
#if HAVE_NEON
|
||||
const SadMxNParam neon_tests[] = {
|
||||
SadMxNParam(64, 64, &vpx_sad64x64_neon),
|
||||
SadMxNParam(64, 32, &vpx_sad64x32_neon),
|
||||
SadMxNParam(32, 32, &vpx_sad32x32_neon),
|
||||
SadMxNParam(16, 32, &vpx_sad16x32_neon),
|
||||
SadMxNParam(16, 16, &vpx_sad16x16_neon),
|
||||
SadMxNParam(16, 8, &vpx_sad16x8_neon),
|
||||
SadMxNParam(8, 16, &vpx_sad8x16_neon),
|
||||
SadMxNParam(8, 8, &vpx_sad8x8_neon),
|
||||
SadMxNParam(8, 4, &vpx_sad8x4_neon),
|
||||
SadMxNParam(4, 8, &vpx_sad4x8_neon),
|
||||
SadMxNParam(4, 4, &vpx_sad4x4_neon),
|
||||
};
|
||||
INSTANTIATE_TEST_CASE_P(NEON, SADTest, ::testing::ValuesIn(neon_tests));
|
||||
|
||||
const SadMxNAvgParam avg_neon_tests[] = {
|
||||
SadMxNAvgParam(64, 64, &vpx_sad64x64_avg_neon),
|
||||
SadMxNAvgParam(64, 32, &vpx_sad64x32_avg_neon),
|
||||
SadMxNAvgParam(32, 64, &vpx_sad32x64_avg_neon),
|
||||
SadMxNAvgParam(32, 32, &vpx_sad32x32_avg_neon),
|
||||
SadMxNAvgParam(32, 16, &vpx_sad32x16_avg_neon),
|
||||
SadMxNAvgParam(16, 32, &vpx_sad16x32_avg_neon),
|
||||
SadMxNAvgParam(16, 16, &vpx_sad16x16_avg_neon),
|
||||
SadMxNAvgParam(16, 8, &vpx_sad16x8_avg_neon),
|
||||
SadMxNAvgParam(8, 16, &vpx_sad8x16_avg_neon),
|
||||
SadMxNAvgParam(8, 8, &vpx_sad8x8_avg_neon),
|
||||
SadMxNAvgParam(8, 4, &vpx_sad8x4_avg_neon),
|
||||
SadMxNAvgParam(4, 8, &vpx_sad4x8_avg_neon),
|
||||
SadMxNAvgParam(4, 4, &vpx_sad4x4_avg_neon),
|
||||
};
|
||||
INSTANTIATE_TEST_CASE_P(NEON, SADavgTest, ::testing::ValuesIn(avg_neon_tests));
|
||||
|
||||
const SadMxNx4Param x4d_neon_tests[] = {
|
||||
SadMxNx4Param(64, 64, &vpx_sad64x64x4d_neon),
|
||||
SadMxNx4Param(64, 32, &vpx_sad64x32x4d_neon),
|
||||
SadMxNx4Param(32, 64, &vpx_sad32x64x4d_neon),
|
||||
SadMxNx4Param(32, 32, &vpx_sad32x32x4d_neon),
|
||||
SadMxNx4Param(32, 16, &vpx_sad32x16x4d_neon),
|
||||
SadMxNx4Param(16, 32, &vpx_sad16x32x4d_neon),
|
||||
SadMxNx4Param(16, 16, &vpx_sad16x16x4d_neon),
|
||||
SadMxNx4Param(16, 8, &vpx_sad16x8x4d_neon),
|
||||
SadMxNx4Param(8, 16, &vpx_sad8x16x4d_neon),
|
||||
SadMxNx4Param(8, 8, &vpx_sad8x8x4d_neon),
|
||||
SadMxNx4Param(8, 4, &vpx_sad8x4x4d_neon),
|
||||
SadMxNx4Param(4, 8, &vpx_sad4x8x4d_neon),
|
||||
SadMxNx4Param(4, 4, &vpx_sad4x4x4d_neon),
|
||||
};
|
||||
INSTANTIATE_TEST_CASE_P(NEON, SADx4Test, ::testing::ValuesIn(x4d_neon_tests));
|
||||
#endif // HAVE_NEON
|
||||
@@ -865,6 +896,14 @@ const SadMxNx4Param x4d_avx2_tests[] = {
|
||||
INSTANTIATE_TEST_CASE_P(AVX2, SADx4Test, ::testing::ValuesIn(x4d_avx2_tests));
|
||||
#endif // HAVE_AVX2
|
||||
|
||||
#if HAVE_AVX512
|
||||
const SadMxNx4Param x4d_avx512_tests[] = {
|
||||
SadMxNx4Param(64, 64, &vpx_sad64x64x4d_avx512),
|
||||
};
|
||||
INSTANTIATE_TEST_CASE_P(AVX512, SADx4Test,
|
||||
::testing::ValuesIn(x4d_avx512_tests));
|
||||
#endif // HAVE_AVX512
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// MIPS functions
|
||||
#if HAVE_MSA
|
||||
@@ -920,4 +959,98 @@ const SadMxNx4Param x4d_msa_tests[] = {
|
||||
INSTANTIATE_TEST_CASE_P(MSA, SADx4Test, ::testing::ValuesIn(x4d_msa_tests));
|
||||
#endif // HAVE_MSA
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// VSX functions
|
||||
#if HAVE_VSX
|
||||
const SadMxNParam vsx_tests[] = {
|
||||
SadMxNParam(64, 64, &vpx_sad64x64_vsx),
|
||||
SadMxNParam(64, 32, &vpx_sad64x32_vsx),
|
||||
SadMxNParam(32, 64, &vpx_sad32x64_vsx),
|
||||
SadMxNParam(32, 32, &vpx_sad32x32_vsx),
|
||||
SadMxNParam(32, 16, &vpx_sad32x16_vsx),
|
||||
SadMxNParam(16, 32, &vpx_sad16x32_vsx),
|
||||
SadMxNParam(16, 16, &vpx_sad16x16_vsx),
|
||||
SadMxNParam(16, 8, &vpx_sad16x8_vsx),
|
||||
};
|
||||
INSTANTIATE_TEST_CASE_P(VSX, SADTest, ::testing::ValuesIn(vsx_tests));
|
||||
|
||||
const SadMxNAvgParam avg_vsx_tests[] = {
|
||||
SadMxNAvgParam(64, 64, &vpx_sad64x64_avg_vsx),
|
||||
SadMxNAvgParam(64, 32, &vpx_sad64x32_avg_vsx),
|
||||
SadMxNAvgParam(32, 64, &vpx_sad32x64_avg_vsx),
|
||||
SadMxNAvgParam(32, 32, &vpx_sad32x32_avg_vsx),
|
||||
SadMxNAvgParam(32, 16, &vpx_sad32x16_avg_vsx),
|
||||
SadMxNAvgParam(16, 32, &vpx_sad16x32_avg_vsx),
|
||||
SadMxNAvgParam(16, 16, &vpx_sad16x16_avg_vsx),
|
||||
SadMxNAvgParam(16, 8, &vpx_sad16x8_avg_vsx),
|
||||
};
|
||||
INSTANTIATE_TEST_CASE_P(VSX, SADavgTest, ::testing::ValuesIn(avg_vsx_tests));
|
||||
|
||||
const SadMxNx4Param x4d_vsx_tests[] = {
|
||||
SadMxNx4Param(64, 64, &vpx_sad64x64x4d_vsx),
|
||||
SadMxNx4Param(64, 32, &vpx_sad64x32x4d_vsx),
|
||||
SadMxNx4Param(32, 64, &vpx_sad32x64x4d_vsx),
|
||||
SadMxNx4Param(32, 32, &vpx_sad32x32x4d_vsx),
|
||||
SadMxNx4Param(32, 16, &vpx_sad32x16x4d_vsx),
|
||||
SadMxNx4Param(16, 32, &vpx_sad16x32x4d_vsx),
|
||||
SadMxNx4Param(16, 16, &vpx_sad16x16x4d_vsx),
|
||||
SadMxNx4Param(16, 8, &vpx_sad16x8x4d_vsx),
|
||||
};
|
||||
INSTANTIATE_TEST_CASE_P(VSX, SADx4Test, ::testing::ValuesIn(x4d_vsx_tests));
|
||||
#endif // HAVE_VSX
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Loongson functions
|
||||
#if HAVE_MMI
|
||||
const SadMxNParam mmi_tests[] = {
|
||||
SadMxNParam(64, 64, &vpx_sad64x64_mmi),
|
||||
SadMxNParam(64, 32, &vpx_sad64x32_mmi),
|
||||
SadMxNParam(32, 64, &vpx_sad32x64_mmi),
|
||||
SadMxNParam(32, 32, &vpx_sad32x32_mmi),
|
||||
SadMxNParam(32, 16, &vpx_sad32x16_mmi),
|
||||
SadMxNParam(16, 32, &vpx_sad16x32_mmi),
|
||||
SadMxNParam(16, 16, &vpx_sad16x16_mmi),
|
||||
SadMxNParam(16, 8, &vpx_sad16x8_mmi),
|
||||
SadMxNParam(8, 16, &vpx_sad8x16_mmi),
|
||||
SadMxNParam(8, 8, &vpx_sad8x8_mmi),
|
||||
SadMxNParam(8, 4, &vpx_sad8x4_mmi),
|
||||
SadMxNParam(4, 8, &vpx_sad4x8_mmi),
|
||||
SadMxNParam(4, 4, &vpx_sad4x4_mmi),
|
||||
};
|
||||
INSTANTIATE_TEST_CASE_P(MMI, SADTest, ::testing::ValuesIn(mmi_tests));
|
||||
|
||||
const SadMxNAvgParam avg_mmi_tests[] = {
|
||||
SadMxNAvgParam(64, 64, &vpx_sad64x64_avg_mmi),
|
||||
SadMxNAvgParam(64, 32, &vpx_sad64x32_avg_mmi),
|
||||
SadMxNAvgParam(32, 64, &vpx_sad32x64_avg_mmi),
|
||||
SadMxNAvgParam(32, 32, &vpx_sad32x32_avg_mmi),
|
||||
SadMxNAvgParam(32, 16, &vpx_sad32x16_avg_mmi),
|
||||
SadMxNAvgParam(16, 32, &vpx_sad16x32_avg_mmi),
|
||||
SadMxNAvgParam(16, 16, &vpx_sad16x16_avg_mmi),
|
||||
SadMxNAvgParam(16, 8, &vpx_sad16x8_avg_mmi),
|
||||
SadMxNAvgParam(8, 16, &vpx_sad8x16_avg_mmi),
|
||||
SadMxNAvgParam(8, 8, &vpx_sad8x8_avg_mmi),
|
||||
SadMxNAvgParam(8, 4, &vpx_sad8x4_avg_mmi),
|
||||
SadMxNAvgParam(4, 8, &vpx_sad4x8_avg_mmi),
|
||||
SadMxNAvgParam(4, 4, &vpx_sad4x4_avg_mmi),
|
||||
};
|
||||
INSTANTIATE_TEST_CASE_P(MMI, SADavgTest, ::testing::ValuesIn(avg_mmi_tests));
|
||||
|
||||
const SadMxNx4Param x4d_mmi_tests[] = {
|
||||
SadMxNx4Param(64, 64, &vpx_sad64x64x4d_mmi),
|
||||
SadMxNx4Param(64, 32, &vpx_sad64x32x4d_mmi),
|
||||
SadMxNx4Param(32, 64, &vpx_sad32x64x4d_mmi),
|
||||
SadMxNx4Param(32, 32, &vpx_sad32x32x4d_mmi),
|
||||
SadMxNx4Param(32, 16, &vpx_sad32x16x4d_mmi),
|
||||
SadMxNx4Param(16, 32, &vpx_sad16x32x4d_mmi),
|
||||
SadMxNx4Param(16, 16, &vpx_sad16x16x4d_mmi),
|
||||
SadMxNx4Param(16, 8, &vpx_sad16x8x4d_mmi),
|
||||
SadMxNx4Param(8, 16, &vpx_sad8x16x4d_mmi),
|
||||
SadMxNx4Param(8, 8, &vpx_sad8x8x4d_mmi),
|
||||
SadMxNx4Param(8, 4, &vpx_sad8x4x4d_mmi),
|
||||
SadMxNx4Param(4, 8, &vpx_sad4x8x4d_mmi),
|
||||
SadMxNx4Param(4, 4, &vpx_sad4x4x4d_mmi),
|
||||
};
|
||||
INSTANTIATE_TEST_CASE_P(MMI, SADx4Test, ::testing::ValuesIn(x4d_mmi_tests));
|
||||
#endif // HAVE_MMI
|
||||
} // namespace
|
||||
|
||||
@@ -146,14 +146,6 @@ TEST(VP8RoiMapTest, ParameterCheck) {
|
||||
if (deltas_valid != roi_retval) break;
|
||||
}
|
||||
|
||||
// Test that we report and error if cyclic refresh is enabled.
|
||||
cpi.cyclic_refresh_mode_enabled = 1;
|
||||
roi_retval =
|
||||
vp8_set_roimap(&cpi, roi_map, cpi.common.mb_rows, cpi.common.mb_cols,
|
||||
delta_q, delta_lf, threshold);
|
||||
EXPECT_EQ(-1, roi_retval) << "cyclic refresh check error";
|
||||
cpi.cyclic_refresh_mode_enabled = 0;
|
||||
|
||||
// Test invalid number of rows or colums.
|
||||
roi_retval =
|
||||
vp8_set_roimap(&cpi, roi_map, cpi.common.mb_rows + 1,
|
||||
|
||||
@@ -8,8 +8,10 @@
|
||||
## in the file PATENTS. All contributing project authors may
|
||||
## be found in the AUTHORS file in the root of the source tree.
|
||||
##
|
||||
## This file performs a stress test. It runs 5 encodes and 30 decodes in
|
||||
## parallel.
|
||||
## This file performs a stress test. It runs (STRESS_ONEPASS_MAX_JOBS,
|
||||
## default=5) one, (STRESS_TWOPASS_MAX_JOBS, default=5) two pass &
|
||||
## (STRESS_RT_MAX_JOBS, default=5) encodes and (STRESS_<codec>_DECODE_MAX_JOBS,
|
||||
## default=30) decodes in parallel.
|
||||
|
||||
. $(dirname $0)/tools_common.sh
|
||||
|
||||
@@ -75,20 +77,33 @@ stress() {
|
||||
local readonly codec="$1"
|
||||
local readonly webm="$2"
|
||||
local readonly decode_count="$3"
|
||||
local readonly threads="$4"
|
||||
local readonly enc_args="$5"
|
||||
local pids=""
|
||||
local rt_max_jobs=${STRESS_RT_MAX_JOBS:-5}
|
||||
local onepass_max_jobs=${STRESS_ONEPASS_MAX_JOBS:-5}
|
||||
local twopass_max_jobs=${STRESS_TWOPASS_MAX_JOBS:-5}
|
||||
|
||||
# Enable job control, so we can run multiple processes.
|
||||
set -m
|
||||
|
||||
# Start $onepass_max_jobs encode jobs in parallel.
|
||||
for i in $(seq ${onepass_max_jobs}); do
|
||||
bitrate=$(($i * 20 + 300))
|
||||
eval "${VPX_TEST_PREFIX}" "${encoder}" "--codec=${codec} -w 1280 -h 720" \
|
||||
"${YUV}" "-t ${threads} --limit=150 --test-decode=fatal --passes=1" \
|
||||
"--target-bitrate=${bitrate} -o ${VPX_TEST_OUTPUT_DIR}/${i}.1pass.webm" \
|
||||
"${enc_args}" ${devnull} &
|
||||
pids="${pids} $!"
|
||||
done
|
||||
|
||||
# Start $twopass_max_jobs encode jobs in parallel.
|
||||
for i in $(seq ${twopass_max_jobs}); do
|
||||
bitrate=$(($i * 20 + 300))
|
||||
eval "${VPX_TEST_PREFIX}" "${encoder}" "--codec=${codec} -w 1280 -h 720" \
|
||||
"${YUV}" "-t 4 --limit=150 --test-decode=fatal " \
|
||||
"--target-bitrate=${bitrate} -o ${VPX_TEST_OUTPUT_DIR}/${i}.webm" \
|
||||
${devnull} &
|
||||
"${YUV}" "-t ${threads} --limit=150 --test-decode=fatal --passes=2" \
|
||||
"--target-bitrate=${bitrate} -o ${VPX_TEST_OUTPUT_DIR}/${i}.2pass.webm" \
|
||||
"${enc_args}" ${devnull} &
|
||||
pids="${pids} $!"
|
||||
done
|
||||
|
||||
@@ -96,7 +111,7 @@ stress() {
|
||||
for i in $(seq ${rt_max_jobs}); do
|
||||
bitrate=$(($i * 20 + 300))
|
||||
eval "${VPX_TEST_PREFIX}" "${encoder}" "--codec=${codec} -w 1280 -h 720" \
|
||||
"${YUV}" "-t 4 --limit=150 --test-decode=fatal " \
|
||||
"${YUV}" "-t ${threads} --limit=150 --test-decode=fatal " \
|
||||
"--target-bitrate=${bitrate} --lag-in-frames=0 --error-resilient=1" \
|
||||
"--kf-min-dist=3000 --kf-max-dist=3000 --cpu-used=-6 --static-thresh=1" \
|
||||
"--end-usage=cbr --min-q=2 --max-q=56 --undershoot-pct=100" \
|
||||
@@ -109,7 +124,7 @@ stress() {
|
||||
|
||||
# Start $decode_count decode jobs in parallel.
|
||||
for i in $(seq "${decode_count}"); do
|
||||
eval "${decoder}" "-t 4" "${webm}" "--noblit" ${devnull} &
|
||||
eval "${decoder}" "-t ${threads}" "${webm}" "--noblit" ${devnull} &
|
||||
pids="${pids} $!"
|
||||
done
|
||||
|
||||
@@ -125,17 +140,30 @@ vp8_stress_test() {
|
||||
local vp8_max_jobs=${STRESS_VP8_DECODE_MAX_JOBS:-40}
|
||||
if [ "$(vp8_decode_available)" = "yes" -a \
|
||||
"$(vp8_encode_available)" = "yes" ]; then
|
||||
stress vp8 "${VP8}" "${vp8_max_jobs}"
|
||||
stress vp8 "${VP8}" "${vp8_max_jobs}" 4
|
||||
fi
|
||||
}
|
||||
|
||||
vp9_stress_test() {
|
||||
vp9_stress() {
|
||||
local vp9_max_jobs=${STRESS_VP9_DECODE_MAX_JOBS:-25}
|
||||
|
||||
if [ "$(vp9_decode_available)" = "yes" -a \
|
||||
"$(vp9_encode_available)" = "yes" ]; then
|
||||
stress vp9 "${VP9}" "${vp9_max_jobs}"
|
||||
stress vp9 "${VP9}" "${vp9_max_jobs}" "$@"
|
||||
fi
|
||||
}
|
||||
|
||||
run_tests stress_verify_environment "vp8_stress_test vp9_stress_test"
|
||||
vp9_stress_test() {
|
||||
for threads in 4 8 100; do
|
||||
vp9_stress "$threads" "--row-mt=0"
|
||||
done
|
||||
}
|
||||
|
||||
vp9_stress_test_row_mt() {
|
||||
for threads in 4 8 100; do
|
||||
vp9_stress "$threads" "--row-mt=1"
|
||||
done
|
||||
}
|
||||
|
||||
run_tests stress_verify_environment \
|
||||
"vp8_stress_test vp9_stress_test vp9_stress_test_row_mt"
|
||||
|
||||
@@ -110,4 +110,10 @@ INSTANTIATE_TEST_CASE_P(
|
||||
::testing::Values(make_tuple(&vpx_sum_squares_2d_i16_c,
|
||||
&vpx_sum_squares_2d_i16_sse2)));
|
||||
#endif // HAVE_SSE2
|
||||
|
||||
#if HAVE_MSA
|
||||
INSTANTIATE_TEST_CASE_P(MSA, SumSquaresTest, ::testing::Values(make_tuple(
|
||||
&vpx_sum_squares_2d_i16_c,
|
||||
&vpx_sum_squares_2d_i16_msa)));
|
||||
#endif // HAVE_MSA
|
||||
} // namespace
|
||||
|
||||
277
test/temporal_filter_test.cc
Normal file
277
test/temporal_filter_test.cc
Normal file
@@ -0,0 +1,277 @@
|
||||
/*
|
||||
* Copyright (c) 2016 The WebM project authors. All Rights Reserved.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license
|
||||
* that can be found in the LICENSE file in the root of the source
|
||||
* tree. An additional intellectual property rights grant can be found
|
||||
* in the file PATENTS. All contributing project authors may
|
||||
* be found in the AUTHORS file in the root of the source tree.
|
||||
*/
|
||||
|
||||
#include <limits>
|
||||
|
||||
#include "third_party/googletest/src/include/gtest/gtest.h"
|
||||
|
||||
#include "./vp9_rtcd.h"
|
||||
#include "test/acm_random.h"
|
||||
#include "test/buffer.h"
|
||||
#include "test/register_state_check.h"
|
||||
#include "vpx_ports/vpx_timer.h"
|
||||
|
||||
namespace {
|
||||
|
||||
using ::libvpx_test::ACMRandom;
|
||||
using ::libvpx_test::Buffer;
|
||||
|
||||
typedef void (*TemporalFilterFunc)(const uint8_t *a, unsigned int stride,
|
||||
const uint8_t *b, unsigned int w,
|
||||
unsigned int h, int filter_strength,
|
||||
int filter_weight, unsigned int *accumulator,
|
||||
uint16_t *count);
|
||||
|
||||
// Calculate the difference between 'a' and 'b', sum in blocks of 9, and apply
|
||||
// filter based on strength and weight. Store the resulting filter amount in
|
||||
// 'count' and apply it to 'b' and store it in 'accumulator'.
|
||||
void reference_filter(const Buffer<uint8_t> &a, const Buffer<uint8_t> &b, int w,
|
||||
int h, int filter_strength, int filter_weight,
|
||||
Buffer<unsigned int> *accumulator,
|
||||
Buffer<uint16_t> *count) {
|
||||
Buffer<int> diff_sq = Buffer<int>(w, h, 0);
|
||||
ASSERT_TRUE(diff_sq.Init());
|
||||
diff_sq.Set(0);
|
||||
|
||||
int rounding = 0;
|
||||
if (filter_strength > 0) {
|
||||
rounding = 1 << (filter_strength - 1);
|
||||
}
|
||||
|
||||
// Calculate all the differences. Avoids re-calculating a bunch of extra
|
||||
// values.
|
||||
for (int height = 0; height < h; ++height) {
|
||||
for (int width = 0; width < w; ++width) {
|
||||
int diff = a.TopLeftPixel()[height * a.stride() + width] -
|
||||
b.TopLeftPixel()[height * b.stride() + width];
|
||||
diff_sq.TopLeftPixel()[height * diff_sq.stride() + width] = diff * diff;
|
||||
}
|
||||
}
|
||||
|
||||
// For any given point, sum the neighboring values and calculate the
|
||||
// modifier.
|
||||
for (int height = 0; height < h; ++height) {
|
||||
for (int width = 0; width < w; ++width) {
|
||||
// Determine how many values are being summed.
|
||||
int summed_values = 9;
|
||||
|
||||
if (height == 0 || height == (h - 1)) {
|
||||
summed_values -= 3;
|
||||
}
|
||||
|
||||
if (width == 0 || width == (w - 1)) {
|
||||
if (summed_values == 6) { // corner
|
||||
summed_values -= 2;
|
||||
} else {
|
||||
summed_values -= 3;
|
||||
}
|
||||
}
|
||||
|
||||
// Sum the diff_sq of the surrounding values.
|
||||
int sum = 0;
|
||||
for (int idy = -1; idy <= 1; ++idy) {
|
||||
for (int idx = -1; idx <= 1; ++idx) {
|
||||
const int y = height + idy;
|
||||
const int x = width + idx;
|
||||
|
||||
// If inside the border.
|
||||
if (y >= 0 && y < h && x >= 0 && x < w) {
|
||||
sum += diff_sq.TopLeftPixel()[y * diff_sq.stride() + x];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
sum *= 3;
|
||||
sum /= summed_values;
|
||||
sum += rounding;
|
||||
sum >>= filter_strength;
|
||||
|
||||
// Clamp the value and invert it.
|
||||
if (sum > 16) sum = 16;
|
||||
sum = 16 - sum;
|
||||
|
||||
sum *= filter_weight;
|
||||
|
||||
count->TopLeftPixel()[height * count->stride() + width] += sum;
|
||||
accumulator->TopLeftPixel()[height * accumulator->stride() + width] +=
|
||||
sum * b.TopLeftPixel()[height * b.stride() + width];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class TemporalFilterTest : public ::testing::TestWithParam<TemporalFilterFunc> {
|
||||
public:
|
||||
virtual void SetUp() {
|
||||
filter_func_ = GetParam();
|
||||
rnd_.Reset(ACMRandom::DeterministicSeed());
|
||||
}
|
||||
|
||||
protected:
|
||||
TemporalFilterFunc filter_func_;
|
||||
ACMRandom rnd_;
|
||||
};
|
||||
|
||||
TEST_P(TemporalFilterTest, SizeCombinations) {
|
||||
// Depending on subsampling this function may be called with values of 8 or 16
|
||||
// for width and height, in any combination.
|
||||
Buffer<uint8_t> a = Buffer<uint8_t>(16, 16, 8);
|
||||
ASSERT_TRUE(a.Init());
|
||||
|
||||
const int filter_weight = 2;
|
||||
const int filter_strength = 6;
|
||||
|
||||
for (int width = 8; width <= 16; width += 8) {
|
||||
for (int height = 8; height <= 16; height += 8) {
|
||||
// The second buffer must not have any border.
|
||||
Buffer<uint8_t> b = Buffer<uint8_t>(width, height, 0);
|
||||
ASSERT_TRUE(b.Init());
|
||||
Buffer<unsigned int> accum_ref = Buffer<unsigned int>(width, height, 0);
|
||||
ASSERT_TRUE(accum_ref.Init());
|
||||
Buffer<unsigned int> accum_chk = Buffer<unsigned int>(width, height, 0);
|
||||
ASSERT_TRUE(accum_chk.Init());
|
||||
Buffer<uint16_t> count_ref = Buffer<uint16_t>(width, height, 0);
|
||||
ASSERT_TRUE(count_ref.Init());
|
||||
Buffer<uint16_t> count_chk = Buffer<uint16_t>(width, height, 0);
|
||||
ASSERT_TRUE(count_chk.Init());
|
||||
|
||||
// The difference between the buffers must be small to pass the threshold
|
||||
// to apply the filter.
|
||||
a.Set(&rnd_, 0, 7);
|
||||
b.Set(&rnd_, 0, 7);
|
||||
|
||||
accum_ref.Set(rnd_.Rand8());
|
||||
accum_chk.CopyFrom(accum_ref);
|
||||
count_ref.Set(rnd_.Rand8());
|
||||
count_chk.CopyFrom(count_ref);
|
||||
reference_filter(a, b, width, height, filter_strength, filter_weight,
|
||||
&accum_ref, &count_ref);
|
||||
ASM_REGISTER_STATE_CHECK(
|
||||
filter_func_(a.TopLeftPixel(), a.stride(), b.TopLeftPixel(), width,
|
||||
height, filter_strength, filter_weight,
|
||||
accum_chk.TopLeftPixel(), count_chk.TopLeftPixel()));
|
||||
EXPECT_TRUE(accum_chk.CheckValues(accum_ref));
|
||||
EXPECT_TRUE(count_chk.CheckValues(count_ref));
|
||||
if (HasFailure()) {
|
||||
printf("Width: %d Height: %d\n", width, height);
|
||||
count_chk.PrintDifference(count_ref);
|
||||
accum_chk.PrintDifference(accum_ref);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
TEST_P(TemporalFilterTest, CompareReferenceRandom) {
|
||||
for (int width = 8; width <= 16; width += 8) {
|
||||
for (int height = 8; height <= 16; height += 8) {
|
||||
Buffer<uint8_t> a = Buffer<uint8_t>(width, height, 8);
|
||||
ASSERT_TRUE(a.Init());
|
||||
// The second buffer must not have any border.
|
||||
Buffer<uint8_t> b = Buffer<uint8_t>(width, height, 0);
|
||||
ASSERT_TRUE(b.Init());
|
||||
Buffer<unsigned int> accum_ref = Buffer<unsigned int>(width, height, 0);
|
||||
ASSERT_TRUE(accum_ref.Init());
|
||||
Buffer<unsigned int> accum_chk = Buffer<unsigned int>(width, height, 0);
|
||||
ASSERT_TRUE(accum_chk.Init());
|
||||
Buffer<uint16_t> count_ref = Buffer<uint16_t>(width, height, 0);
|
||||
ASSERT_TRUE(count_ref.Init());
|
||||
Buffer<uint16_t> count_chk = Buffer<uint16_t>(width, height, 0);
|
||||
ASSERT_TRUE(count_chk.Init());
|
||||
|
||||
for (int filter_strength = 0; filter_strength <= 6; ++filter_strength) {
|
||||
for (int filter_weight = 0; filter_weight <= 2; ++filter_weight) {
|
||||
for (int repeat = 0; repeat < 100; ++repeat) {
|
||||
if (repeat < 50) {
|
||||
a.Set(&rnd_, 0, 7);
|
||||
b.Set(&rnd_, 0, 7);
|
||||
} else {
|
||||
// Check large (but close) values as well.
|
||||
a.Set(&rnd_, std::numeric_limits<uint8_t>::max() - 7,
|
||||
std::numeric_limits<uint8_t>::max());
|
||||
b.Set(&rnd_, std::numeric_limits<uint8_t>::max() - 7,
|
||||
std::numeric_limits<uint8_t>::max());
|
||||
}
|
||||
|
||||
accum_ref.Set(rnd_.Rand8());
|
||||
accum_chk.CopyFrom(accum_ref);
|
||||
count_ref.Set(rnd_.Rand8());
|
||||
count_chk.CopyFrom(count_ref);
|
||||
reference_filter(a, b, width, height, filter_strength,
|
||||
filter_weight, &accum_ref, &count_ref);
|
||||
ASM_REGISTER_STATE_CHECK(filter_func_(
|
||||
a.TopLeftPixel(), a.stride(), b.TopLeftPixel(), width, height,
|
||||
filter_strength, filter_weight, accum_chk.TopLeftPixel(),
|
||||
count_chk.TopLeftPixel()));
|
||||
EXPECT_TRUE(accum_chk.CheckValues(accum_ref));
|
||||
EXPECT_TRUE(count_chk.CheckValues(count_ref));
|
||||
if (HasFailure()) {
|
||||
printf("Weight: %d Strength: %d\n", filter_weight,
|
||||
filter_strength);
|
||||
count_chk.PrintDifference(count_ref);
|
||||
accum_chk.PrintDifference(accum_ref);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
TEST_P(TemporalFilterTest, DISABLED_Speed) {
|
||||
Buffer<uint8_t> a = Buffer<uint8_t>(16, 16, 8);
|
||||
ASSERT_TRUE(a.Init());
|
||||
|
||||
const int filter_weight = 2;
|
||||
const int filter_strength = 6;
|
||||
|
||||
for (int width = 8; width <= 16; width += 8) {
|
||||
for (int height = 8; height <= 16; height += 8) {
|
||||
// The second buffer must not have any border.
|
||||
Buffer<uint8_t> b = Buffer<uint8_t>(width, height, 0);
|
||||
ASSERT_TRUE(b.Init());
|
||||
Buffer<unsigned int> accum_ref = Buffer<unsigned int>(width, height, 0);
|
||||
ASSERT_TRUE(accum_ref.Init());
|
||||
Buffer<unsigned int> accum_chk = Buffer<unsigned int>(width, height, 0);
|
||||
ASSERT_TRUE(accum_chk.Init());
|
||||
Buffer<uint16_t> count_ref = Buffer<uint16_t>(width, height, 0);
|
||||
ASSERT_TRUE(count_ref.Init());
|
||||
Buffer<uint16_t> count_chk = Buffer<uint16_t>(width, height, 0);
|
||||
ASSERT_TRUE(count_chk.Init());
|
||||
|
||||
a.Set(&rnd_, 0, 7);
|
||||
b.Set(&rnd_, 0, 7);
|
||||
|
||||
accum_chk.Set(0);
|
||||
count_chk.Set(0);
|
||||
|
||||
vpx_usec_timer timer;
|
||||
vpx_usec_timer_start(&timer);
|
||||
for (int i = 0; i < 10000; ++i) {
|
||||
filter_func_(a.TopLeftPixel(), a.stride(), b.TopLeftPixel(), width,
|
||||
height, filter_strength, filter_weight,
|
||||
accum_chk.TopLeftPixel(), count_chk.TopLeftPixel());
|
||||
}
|
||||
vpx_usec_timer_mark(&timer);
|
||||
const int elapsed_time = static_cast<int>(vpx_usec_timer_elapsed(&timer));
|
||||
printf("Temporal filter %dx%d time: %5d us\n", width, height,
|
||||
elapsed_time);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
INSTANTIATE_TEST_CASE_P(C, TemporalFilterTest,
|
||||
::testing::Values(&vp9_temporal_filter_apply_c));
|
||||
|
||||
#if HAVE_SSE4_1
|
||||
INSTANTIATE_TEST_CASE_P(SSE4_1, TemporalFilterTest,
|
||||
::testing::Values(&vp9_temporal_filter_apply_sse4_1));
|
||||
#endif // HAVE_SSE4_1
|
||||
} // namespace
|
||||
@@ -23,6 +23,7 @@ LIBVPX_TEST_DATA-$(CONFIG_VP9_ENCODER) += niklas_1280_720_30.y4m
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_ENCODER) += noisy_clip_640_360.y4m
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_ENCODER) += rush_hour_444.y4m
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_ENCODER) += screendata.y4m
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_ENCODER) += niklas_640_480_30.yuv
|
||||
|
||||
# Test vectors
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP8_DECODER) += vp80-00-comprehensive-001.ivf
|
||||
@@ -731,6 +732,8 @@ LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp93-2-20-12bit-yuv444.webm.md5
|
||||
endif # CONFIG_VP9_HIGHBITDEPTH
|
||||
|
||||
# Invalid files for testing libvpx error checking.
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP8_DECODER) += invalid-bug-1443.ivf
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP8_DECODER) += invalid-bug-1443.ivf.res
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP8_DECODER) += invalid-vp80-00-comprehensive-018.ivf.2kf_0x6.ivf
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP8_DECODER) += invalid-vp80-00-comprehensive-018.ivf.2kf_0x6.ivf.res
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += invalid-vp90-01-v3.webm
|
||||
@@ -771,6 +774,8 @@ LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += invalid-vp90-2-12-droppable_1.ivf.s367
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += invalid-vp90-2-12-droppable_1.ivf.s3676_r01-05_b6-.ivf.res
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += invalid-vp90-2-12-droppable_1.ivf.s73804_r01-05_b6-.ivf
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += invalid-vp90-2-12-droppable_1.ivf.s73804_r01-05_b6-.ivf.res
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += invalid-vp90-2-21-resize_inter_320x180_5_3-4.webm.ivf.s45551_r01-05_b6-.ivf
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += invalid-vp90-2-21-resize_inter_320x180_5_3-4.webm.ivf.s45551_r01-05_b6-.ivf.res
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += invalid-vp91-2-mixedrefcsp-444to420.ivf
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += invalid-vp91-2-mixedrefcsp-444to420.ivf.res
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += invalid-vp90-2-07-frame_parallel-1.webm
|
||||
@@ -814,7 +819,6 @@ LIBVPX_TEST_DATA-$(CONFIG_VP9_ENCODER) += kirland_640_480_30.yuv
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_ENCODER) += macmarcomoving_640_480_30.yuv
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_ENCODER) += macmarcostationary_640_480_30.yuv
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_ENCODER) += niklas_1280_720_30.yuv
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_ENCODER) += niklas_640_480_30.yuv
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_ENCODER) += tacomanarrows_640_480_30.yuv
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_ENCODER) += tacomasmallcameramovement_640_480_30.yuv
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_ENCODER) += thaloundeskmtg_640_480_30.yuv
|
||||
@@ -874,3 +878,5 @@ LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-21-resize_inter_1920x1080_7_3-4
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-21-resize_inter_1920x1080_7_3-4.webm.md5
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-22-svc_1280x720_3.ivf
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-22-svc_1280x720_3.ivf.md5
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-22-svc_1280x720_1.webm
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-22-svc_1280x720_1.webm.md5
|
||||
|
||||
@@ -6,6 +6,8 @@ b87815bf86020c592ccc7a846ba2e28ec8043902 *hantro_odd.yuv
|
||||
456d1493e52d32a5c30edf44a27debc1fa6b253a *invalid-vp90-2-00-quantizer-11.webm.ivf.s52984_r01-05_b6-.ivf.res
|
||||
c123d1f9f02fb4143abb5e271916e3a3080de8f6 *invalid-vp90-2-00-quantizer-11.webm.ivf.s52984_r01-05_b6-z.ivf
|
||||
456d1493e52d32a5c30edf44a27debc1fa6b253a *invalid-vp90-2-00-quantizer-11.webm.ivf.s52984_r01-05_b6-z.ivf.res
|
||||
efafb92b7567bc04c3f1432ea6c268c1c31affd5 *invalid-vp90-2-21-resize_inter_320x180_5_3-4.webm.ivf.s45551_r01-05_b6-.ivf
|
||||
5d9474c0309b7ca09a182d888f73b37a8fe1362c *invalid-vp90-2-21-resize_inter_320x180_5_3-4.webm.ivf.s45551_r01-05_b6-.ivf.res
|
||||
fe346136b9b8c1e6f6084cc106485706915795e4 *invalid-vp90-01-v3.webm
|
||||
5d9474c0309b7ca09a182d888f73b37a8fe1362c *invalid-vp90-01-v3.webm.res
|
||||
d78e2fceba5ac942246503ec8366f879c4775ca5 *invalid-vp90-02-v2.webm
|
||||
@@ -848,3 +850,7 @@ a000d568431d07379dd5a8ec066061c07e560b47 *invalid-vp90-2-00-quantizer-63.ivf.kf_
|
||||
6fa3d3ac306a3d9ce1d610b78441dc00d2c2d4b9 *tos_vp8.webm
|
||||
e402cbbf9e550ae017a1e9f1f73931c1d18474e8 *invalid-crbug-667044.webm
|
||||
d3964f9dad9f60363c81b688324d95b4ec7c8038 *invalid-crbug-667044.webm.res
|
||||
fd9df7f3f6992af1d7a9dde975c9a0d6f28c053d *invalid-bug-1443.ivf
|
||||
fd3020fa6e9ca5966206738654c97dec313b0a95 *invalid-bug-1443.ivf.res
|
||||
17696cd21e875f1d6e5d418cbf89feab02c8850a *vp90-2-22-svc_1280x720_1.webm
|
||||
e2f9e1e47a791b4e939a9bdc50bf7a25b3761f77 *vp90-2-22-svc_1280x720_1.webm.md5
|
||||
|
||||
16
test/test.mk
16
test/test.mk
@@ -1,4 +1,5 @@
|
||||
LIBVPX_TEST_SRCS-yes += acm_random.h
|
||||
LIBVPX_TEST_SRCS-yes += buffer.h
|
||||
LIBVPX_TEST_SRCS-yes += clear_system_state.h
|
||||
LIBVPX_TEST_SRCS-yes += codec_factory.h
|
||||
LIBVPX_TEST_SRCS-yes += md5_helper.h
|
||||
@@ -38,7 +39,6 @@ LIBVPX_TEST_SRCS-$(CONFIG_VP9_DECODER) += byte_alignment_test.cc
|
||||
LIBVPX_TEST_SRCS-$(CONFIG_VP9_DECODER) += decode_svc_test.cc
|
||||
LIBVPX_TEST_SRCS-$(CONFIG_VP9_DECODER) += external_frame_buffer_test.cc
|
||||
LIBVPX_TEST_SRCS-$(CONFIG_VP9_DECODER) += user_priv_test.cc
|
||||
LIBVPX_TEST_SRCS-$(CONFIG_VP9_DECODER) += vp9_frame_parallel_test.cc
|
||||
LIBVPX_TEST_SRCS-$(CONFIG_VP9_ENCODER) += active_map_refresh_test.cc
|
||||
LIBVPX_TEST_SRCS-$(CONFIG_VP9_ENCODER) += active_map_test.cc
|
||||
LIBVPX_TEST_SRCS-$(CONFIG_VP9_ENCODER) += borders_test.cc
|
||||
@@ -47,6 +47,7 @@ LIBVPX_TEST_SRCS-$(CONFIG_VP9_ENCODER) += frame_size_tests.cc
|
||||
LIBVPX_TEST_SRCS-$(CONFIG_VP9_ENCODER) += vp9_lossless_test.cc
|
||||
LIBVPX_TEST_SRCS-$(CONFIG_VP9_ENCODER) += vp9_end_to_end_test.cc
|
||||
LIBVPX_TEST_SRCS-$(CONFIG_VP9_ENCODER) += vp9_ethread_test.cc
|
||||
LIBVPX_TEST_SRCS-$(CONFIG_VP9_ENCODER) += vp9_motion_vector_test.cc
|
||||
LIBVPX_TEST_SRCS-$(CONFIG_VP9_ENCODER) += level_test.cc
|
||||
|
||||
LIBVPX_TEST_SRCS-yes += decode_test_driver.cc
|
||||
@@ -122,6 +123,7 @@ LIBVPX_TEST_SRCS-$(CONFIG_VP8_ENCODER) += vp8_fdct4x4_test.cc
|
||||
LIBVPX_TEST_SRCS-yes += idct_test.cc
|
||||
LIBVPX_TEST_SRCS-yes += predict_test.cc
|
||||
LIBVPX_TEST_SRCS-yes += vpx_scale_test.cc
|
||||
LIBVPX_TEST_SRCS-yes += vpx_scale_test.h
|
||||
|
||||
ifeq ($(CONFIG_VP8_ENCODER)$(CONFIG_TEMPORAL_DENOISING),yesyes)
|
||||
LIBVPX_TEST_SRCS-$(HAVE_SSE2) += vp8_denoiser_sse2_test.cc
|
||||
@@ -149,14 +151,20 @@ LIBVPX_TEST_SRCS-yes += vp9_intrapred_test.cc
|
||||
LIBVPX_TEST_SRCS-$(CONFIG_VP9_DECODER) += vp9_decrypt_test.cc
|
||||
LIBVPX_TEST_SRCS-$(CONFIG_VP9_DECODER) += vp9_thread_test.cc
|
||||
LIBVPX_TEST_SRCS-$(CONFIG_VP9_ENCODER) += avg_test.cc
|
||||
LIBVPX_TEST_SRCS-$(CONFIG_VP9_ENCODER) += comp_avg_pred_test.cc
|
||||
LIBVPX_TEST_SRCS-$(CONFIG_VP9_ENCODER) += dct16x16_test.cc
|
||||
LIBVPX_TEST_SRCS-$(CONFIG_VP9_ENCODER) += dct32x32_test.cc
|
||||
LIBVPX_TEST_SRCS-$(CONFIG_VP9_ENCODER) += fdct4x4_test.cc
|
||||
LIBVPX_TEST_SRCS-$(CONFIG_VP9_ENCODER) += dct_partial_test.cc
|
||||
LIBVPX_TEST_SRCS-$(CONFIG_VP9_ENCODER) += dct_test.cc
|
||||
LIBVPX_TEST_SRCS-$(CONFIG_VP9_ENCODER) += fdct8x8_test.cc
|
||||
LIBVPX_TEST_SRCS-$(CONFIG_VP9_ENCODER) += hadamard_test.cc
|
||||
LIBVPX_TEST_SRCS-$(CONFIG_VP9_ENCODER) += minmax_test.cc
|
||||
LIBVPX_TEST_SRCS-$(CONFIG_VP9_ENCODER) += vp9_scale_test.cc
|
||||
ifneq ($(CONFIG_REALTIME_ONLY),yes)
|
||||
LIBVPX_TEST_SRCS-$(CONFIG_VP9_ENCODER) += temporal_filter_test.cc
|
||||
endif
|
||||
LIBVPX_TEST_SRCS-$(CONFIG_VP9_ENCODER) += variance_test.cc
|
||||
LIBVPX_TEST_SRCS-$(CONFIG_VP9_ENCODER) += vp9_error_block_test.cc
|
||||
LIBVPX_TEST_SRCS-$(CONFIG_VP9_ENCODER) += vp9_block_error_test.cc
|
||||
LIBVPX_TEST_SRCS-$(CONFIG_VP9_ENCODER) += vp9_quantize_test.cc
|
||||
LIBVPX_TEST_SRCS-$(CONFIG_VP9_ENCODER) += vp9_subtract_test.cc
|
||||
|
||||
@@ -167,7 +175,7 @@ LIBVPX_TEST_SRCS-$(CONFIG_INTERNAL_STATS) += consistency_test.cc
|
||||
endif
|
||||
|
||||
ifeq ($(CONFIG_VP9_ENCODER)$(CONFIG_VP9_TEMPORAL_DENOISING),yesyes)
|
||||
LIBVPX_TEST_SRCS-$(HAVE_SSE2) += vp9_denoiser_sse2_test.cc
|
||||
LIBVPX_TEST_SRCS-yes += vp9_denoiser_test.cc
|
||||
endif
|
||||
LIBVPX_TEST_SRCS-$(CONFIG_VP9_ENCODER) += vp9_arf_freq_test.cc
|
||||
|
||||
|
||||
@@ -312,6 +312,31 @@ INTRA_PRED_TEST(MSA, TestIntraPred32, vpx_dc_predictor_32x32_msa,
|
||||
vpx_tm_predictor_32x32_msa)
|
||||
#endif // HAVE_MSA
|
||||
|
||||
#if HAVE_VSX
|
||||
INTRA_PRED_TEST(VSX, TestIntraPred4, NULL, NULL, NULL, NULL, NULL,
|
||||
vpx_h_predictor_4x4_vsx, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
vpx_tm_predictor_4x4_vsx)
|
||||
|
||||
INTRA_PRED_TEST(VSX, TestIntraPred8, vpx_dc_predictor_8x8_vsx, NULL, NULL, NULL,
|
||||
NULL, vpx_h_predictor_8x8_vsx, vpx_d45_predictor_8x8_vsx, NULL,
|
||||
NULL, NULL, NULL, vpx_d63_predictor_8x8_vsx,
|
||||
vpx_tm_predictor_8x8_vsx)
|
||||
|
||||
INTRA_PRED_TEST(VSX, TestIntraPred16, vpx_dc_predictor_16x16_vsx,
|
||||
vpx_dc_left_predictor_16x16_vsx, vpx_dc_top_predictor_16x16_vsx,
|
||||
vpx_dc_128_predictor_16x16_vsx, vpx_v_predictor_16x16_vsx,
|
||||
vpx_h_predictor_16x16_vsx, vpx_d45_predictor_16x16_vsx, NULL,
|
||||
NULL, NULL, NULL, vpx_d63_predictor_16x16_vsx,
|
||||
vpx_tm_predictor_16x16_vsx)
|
||||
|
||||
INTRA_PRED_TEST(VSX, TestIntraPred32, vpx_dc_predictor_32x32_vsx,
|
||||
vpx_dc_left_predictor_32x32_vsx, vpx_dc_top_predictor_32x32_vsx,
|
||||
vpx_dc_128_predictor_32x32_vsx, vpx_v_predictor_32x32_vsx,
|
||||
vpx_h_predictor_32x32_vsx, vpx_d45_predictor_32x32_vsx, NULL,
|
||||
NULL, NULL, NULL, vpx_d63_predictor_32x32_vsx,
|
||||
vpx_tm_predictor_32x32_vsx)
|
||||
#endif // HAVE_VSX
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
#if CONFIG_VP9_HIGHBITDEPTH
|
||||
@@ -455,29 +480,70 @@ HIGHBD_INTRA_PRED_TEST(
|
||||
vpx_highbd_d63_predictor_32x32_c, vpx_highbd_tm_predictor_32x32_c)
|
||||
|
||||
#if HAVE_SSE2
|
||||
HIGHBD_INTRA_PRED_TEST(SSE2, TestHighbdIntraPred4,
|
||||
vpx_highbd_dc_predictor_4x4_sse2, NULL, NULL, NULL,
|
||||
vpx_highbd_v_predictor_4x4_sse2, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, vpx_highbd_tm_predictor_4x4_c)
|
||||
HIGHBD_INTRA_PRED_TEST(
|
||||
SSE2, TestHighbdIntraPred4, vpx_highbd_dc_predictor_4x4_sse2,
|
||||
vpx_highbd_dc_left_predictor_4x4_sse2, vpx_highbd_dc_top_predictor_4x4_sse2,
|
||||
vpx_highbd_dc_128_predictor_4x4_sse2, vpx_highbd_v_predictor_4x4_sse2,
|
||||
vpx_highbd_h_predictor_4x4_sse2, NULL, vpx_highbd_d135_predictor_4x4_sse2,
|
||||
vpx_highbd_d117_predictor_4x4_sse2, vpx_highbd_d153_predictor_4x4_sse2,
|
||||
vpx_highbd_d207_predictor_4x4_sse2, vpx_highbd_d63_predictor_4x4_sse2,
|
||||
vpx_highbd_tm_predictor_4x4_c)
|
||||
|
||||
HIGHBD_INTRA_PRED_TEST(SSE2, TestHighbdIntraPred8,
|
||||
vpx_highbd_dc_predictor_8x8_sse2, NULL, NULL, NULL,
|
||||
vpx_highbd_v_predictor_8x8_sse2, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, vpx_highbd_tm_predictor_8x8_sse2)
|
||||
vpx_highbd_dc_predictor_8x8_sse2,
|
||||
vpx_highbd_dc_left_predictor_8x8_sse2,
|
||||
vpx_highbd_dc_top_predictor_8x8_sse2,
|
||||
vpx_highbd_dc_128_predictor_8x8_sse2,
|
||||
vpx_highbd_v_predictor_8x8_sse2,
|
||||
vpx_highbd_h_predictor_8x8_sse2, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, vpx_highbd_tm_predictor_8x8_sse2)
|
||||
|
||||
HIGHBD_INTRA_PRED_TEST(SSE2, TestHighbdIntraPred16,
|
||||
vpx_highbd_dc_predictor_16x16_sse2, NULL, NULL, NULL,
|
||||
vpx_highbd_v_predictor_16x16_sse2, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL,
|
||||
vpx_highbd_tm_predictor_16x16_sse2)
|
||||
vpx_highbd_dc_predictor_16x16_sse2,
|
||||
vpx_highbd_dc_left_predictor_16x16_sse2,
|
||||
vpx_highbd_dc_top_predictor_16x16_sse2,
|
||||
vpx_highbd_dc_128_predictor_16x16_sse2,
|
||||
vpx_highbd_v_predictor_16x16_sse2,
|
||||
vpx_highbd_h_predictor_16x16_sse2, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, vpx_highbd_tm_predictor_16x16_sse2)
|
||||
|
||||
HIGHBD_INTRA_PRED_TEST(SSE2, TestHighbdIntraPred32,
|
||||
vpx_highbd_dc_predictor_32x32_sse2, NULL, NULL, NULL,
|
||||
vpx_highbd_v_predictor_32x32_sse2, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL,
|
||||
vpx_highbd_tm_predictor_32x32_sse2)
|
||||
vpx_highbd_dc_predictor_32x32_sse2,
|
||||
vpx_highbd_dc_left_predictor_32x32_sse2,
|
||||
vpx_highbd_dc_top_predictor_32x32_sse2,
|
||||
vpx_highbd_dc_128_predictor_32x32_sse2,
|
||||
vpx_highbd_v_predictor_32x32_sse2,
|
||||
vpx_highbd_h_predictor_32x32_sse2, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, vpx_highbd_tm_predictor_32x32_sse2)
|
||||
#endif // HAVE_SSE2
|
||||
|
||||
#if HAVE_SSSE3
|
||||
HIGHBD_INTRA_PRED_TEST(SSSE3, TestHighbdIntraPred4, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, vpx_highbd_d45_predictor_4x4_ssse3, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL)
|
||||
HIGHBD_INTRA_PRED_TEST(SSSE3, TestHighbdIntraPred8, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, vpx_highbd_d45_predictor_8x8_ssse3,
|
||||
vpx_highbd_d135_predictor_8x8_ssse3,
|
||||
vpx_highbd_d117_predictor_8x8_ssse3,
|
||||
vpx_highbd_d153_predictor_8x8_ssse3,
|
||||
vpx_highbd_d207_predictor_8x8_ssse3,
|
||||
vpx_highbd_d63_predictor_8x8_ssse3, NULL)
|
||||
HIGHBD_INTRA_PRED_TEST(SSSE3, TestHighbdIntraPred16, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, vpx_highbd_d45_predictor_16x16_ssse3,
|
||||
vpx_highbd_d135_predictor_16x16_ssse3,
|
||||
vpx_highbd_d117_predictor_16x16_ssse3,
|
||||
vpx_highbd_d153_predictor_16x16_ssse3,
|
||||
vpx_highbd_d207_predictor_16x16_ssse3,
|
||||
vpx_highbd_d63_predictor_16x16_ssse3, NULL)
|
||||
HIGHBD_INTRA_PRED_TEST(SSSE3, TestHighbdIntraPred32, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, vpx_highbd_d45_predictor_32x32_ssse3,
|
||||
vpx_highbd_d135_predictor_32x32_ssse3,
|
||||
vpx_highbd_d117_predictor_32x32_ssse3,
|
||||
vpx_highbd_d153_predictor_32x32_ssse3,
|
||||
vpx_highbd_d207_predictor_32x32_ssse3,
|
||||
vpx_highbd_d63_predictor_32x32_ssse3, NULL)
|
||||
#endif // HAVE_SSSE3
|
||||
|
||||
#if HAVE_NEON
|
||||
HIGHBD_INTRA_PRED_TEST(
|
||||
NEON, TestHighbdIntraPred4, vpx_highbd_dc_predictor_4x4_neon,
|
||||
|
||||
@@ -53,6 +53,9 @@ int main(int argc, char **argv) {
|
||||
}
|
||||
if (!(simd_caps & HAS_AVX)) append_negative_gtest_filter(":AVX.*:AVX/*");
|
||||
if (!(simd_caps & HAS_AVX2)) append_negative_gtest_filter(":AVX2.*:AVX2/*");
|
||||
if (!(simd_caps & HAS_AVX512)) {
|
||||
append_negative_gtest_filter(":AVX512.*:AVX512/*");
|
||||
}
|
||||
#endif // ARCH_X86 || ARCH_X86_64
|
||||
|
||||
#if !CONFIG_SHARED
|
||||
|
||||
@@ -28,13 +28,10 @@
|
||||
|
||||
namespace {
|
||||
|
||||
enum DecodeMode { kSerialMode, kFrameParallelMode };
|
||||
const int kThreads = 0;
|
||||
const int kFileName = 1;
|
||||
|
||||
const int kDecodeMode = 0;
|
||||
const int kThreads = 1;
|
||||
const int kFileName = 2;
|
||||
|
||||
typedef std::tr1::tuple<int, int, const char *> DecodeParam;
|
||||
typedef std::tr1::tuple<int, const char *> DecodeParam;
|
||||
|
||||
class TestVectorTest : public ::libvpx_test::DecoderTest,
|
||||
public ::libvpx_test::CodecTestWithParam<DecodeParam> {
|
||||
@@ -53,8 +50,8 @@ class TestVectorTest : public ::libvpx_test::DecoderTest,
|
||||
|
||||
void OpenMD5File(const std::string &md5_file_name_) {
|
||||
md5_file_ = libvpx_test::OpenTestDataFile(md5_file_name_);
|
||||
ASSERT_TRUE(md5_file_ != NULL) << "Md5 file open failed. Filename: "
|
||||
<< md5_file_name_;
|
||||
ASSERT_TRUE(md5_file_ != NULL)
|
||||
<< "Md5 file open failed. Filename: " << md5_file_name_;
|
||||
}
|
||||
|
||||
virtual void DecompressedFrameHook(const vpx_image_t &img,
|
||||
@@ -92,29 +89,14 @@ class TestVectorTest : public ::libvpx_test::DecoderTest,
|
||||
TEST_P(TestVectorTest, MD5Match) {
|
||||
const DecodeParam input = GET_PARAM(1);
|
||||
const std::string filename = std::tr1::get<kFileName>(input);
|
||||
const int threads = std::tr1::get<kThreads>(input);
|
||||
const int mode = std::tr1::get<kDecodeMode>(input);
|
||||
vpx_codec_flags_t flags = 0;
|
||||
vpx_codec_dec_cfg_t cfg = vpx_codec_dec_cfg_t();
|
||||
char str[256];
|
||||
|
||||
if (mode == kFrameParallelMode) {
|
||||
flags |= VPX_CODEC_USE_FRAME_THREADING;
|
||||
#if CONFIG_VP9_DECODER
|
||||
// TODO(hkuang): Fix frame parallel decode bug. See issue 1086.
|
||||
if (resize_clips_.find(filename) != resize_clips_.end()) {
|
||||
printf("Skipping the test file: %s, due to frame parallel decode bug.\n",
|
||||
filename.c_str());
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
cfg.threads = std::tr1::get<kThreads>(input);
|
||||
|
||||
cfg.threads = threads;
|
||||
|
||||
snprintf(str, sizeof(str) / sizeof(str[0]) - 1,
|
||||
"file: %s mode: %s threads: %d", filename.c_str(),
|
||||
mode == 0 ? "Serial" : "Parallel", threads);
|
||||
snprintf(str, sizeof(str) / sizeof(str[0]) - 1, "file: %s threads: %d",
|
||||
filename.c_str(), cfg.threads);
|
||||
SCOPED_TRACE(str);
|
||||
|
||||
// Open compressed video file.
|
||||
@@ -145,13 +127,10 @@ TEST_P(TestVectorTest, MD5Match) {
|
||||
ASSERT_NO_FATAL_FAILURE(RunLoop(video.get(), cfg));
|
||||
}
|
||||
|
||||
// Test VP8 decode in serial mode with single thread.
|
||||
// NOTE: VP8 only support serial mode.
|
||||
#if CONFIG_VP8_DECODER
|
||||
VP8_INSTANTIATE_TEST_CASE(
|
||||
TestVectorTest,
|
||||
::testing::Combine(
|
||||
::testing::Values(0), // Serial Mode.
|
||||
::testing::Values(1), // Single thread.
|
||||
::testing::ValuesIn(libvpx_test::kVP8TestVectors,
|
||||
libvpx_test::kVP8TestVectors +
|
||||
@@ -164,33 +143,28 @@ INSTANTIATE_TEST_CASE_P(
|
||||
::testing::Values(
|
||||
static_cast<const libvpx_test::CodecFactory *>(&libvpx_test::kVP8)),
|
||||
::testing::Combine(
|
||||
::testing::Values(0), // Serial Mode.
|
||||
::testing::Range(1, 8), // With 1 ~ 8 threads.
|
||||
::testing::Range(2, 9), // With 2 ~ 8 threads.
|
||||
::testing::ValuesIn(libvpx_test::kVP8TestVectors,
|
||||
libvpx_test::kVP8TestVectors +
|
||||
libvpx_test::kNumVP8TestVectors))));
|
||||
|
||||
#endif // CONFIG_VP8_DECODER
|
||||
|
||||
// Test VP9 decode in serial mode with single thread.
|
||||
#if CONFIG_VP9_DECODER
|
||||
VP9_INSTANTIATE_TEST_CASE(
|
||||
TestVectorTest,
|
||||
::testing::Combine(
|
||||
::testing::Values(0), // Serial Mode.
|
||||
::testing::Values(1), // Single thread.
|
||||
::testing::ValuesIn(libvpx_test::kVP9TestVectors,
|
||||
libvpx_test::kVP9TestVectors +
|
||||
libvpx_test::kNumVP9TestVectors)));
|
||||
|
||||
// Test VP9 decode in frame parallel mode with different number of threads.
|
||||
INSTANTIATE_TEST_CASE_P(
|
||||
VP9MultiThreadedFrameParallel, TestVectorTest,
|
||||
VP9MultiThreaded, TestVectorTest,
|
||||
::testing::Combine(
|
||||
::testing::Values(
|
||||
static_cast<const libvpx_test::CodecFactory *>(&libvpx_test::kVP9)),
|
||||
::testing::Combine(
|
||||
::testing::Values(1), // Frame Parallel mode.
|
||||
::testing::Range(2, 9), // With 2 ~ 8 threads.
|
||||
::testing::ValuesIn(libvpx_test::kVP9TestVectors,
|
||||
libvpx_test::kVP9TestVectors +
|
||||
|
||||
@@ -371,6 +371,7 @@ const char *const kVP9TestVectors[] = {
|
||||
#endif // CONFIG_VP9_HIGHBITDEPTH
|
||||
"vp90-2-20-big_superframe-01.webm",
|
||||
"vp90-2-20-big_superframe-02.webm",
|
||||
"vp90-2-22-svc_1280x720_1.webm",
|
||||
RESIZE_TEST_VECTORS
|
||||
};
|
||||
const char *const kVP9TestVectorsSvc[] = { "vp90-2-22-svc_1280x720_3.ivf" };
|
||||
|
||||
@@ -54,7 +54,10 @@ twopass_encoder_vp9() {
|
||||
fi
|
||||
}
|
||||
|
||||
twopass_encoder_tests="twopass_encoder_vp8
|
||||
twopass_encoder_vp9"
|
||||
|
||||
run_tests twopass_encoder_verify_environment "${twopass_encoder_tests}"
|
||||
if [ "$(vpx_config_option_enabled CONFIG_REALTIME_ONLY)" != "yes" ]; then
|
||||
twopass_encoder_tests="twopass_encoder_vp8
|
||||
twopass_encoder_vp9"
|
||||
|
||||
run_tests twopass_encoder_verify_environment "${twopass_encoder_tests}"
|
||||
fi
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -17,12 +17,16 @@
|
||||
|
||||
#include "third_party/googletest/src/include/gtest/gtest.h"
|
||||
|
||||
#include "./vpx_config.h"
|
||||
#include "./vp8_rtcd.h"
|
||||
#include "test/acm_random.h"
|
||||
#include "vpx/vpx_integer.h"
|
||||
#include "vpx_ports/mem.h"
|
||||
|
||||
namespace {
|
||||
|
||||
typedef void (*FdctFunc)(int16_t *a, int16_t *b, int a_stride);
|
||||
|
||||
const int cospi8sqrt2minus1 = 20091;
|
||||
const int sinpi8sqrt2 = 35468;
|
||||
|
||||
@@ -68,10 +72,21 @@ void reference_idct4x4(const int16_t *input, int16_t *output) {
|
||||
|
||||
using libvpx_test::ACMRandom;
|
||||
|
||||
TEST(VP8FdctTest, SignBiasCheck) {
|
||||
ACMRandom rnd(ACMRandom::DeterministicSeed());
|
||||
class FdctTest : public ::testing::TestWithParam<FdctFunc> {
|
||||
public:
|
||||
virtual void SetUp() {
|
||||
fdct_func_ = GetParam();
|
||||
rnd_.Reset(ACMRandom::DeterministicSeed());
|
||||
}
|
||||
|
||||
protected:
|
||||
FdctFunc fdct_func_;
|
||||
ACMRandom rnd_;
|
||||
};
|
||||
|
||||
TEST_P(FdctTest, SignBiasCheck) {
|
||||
int16_t test_input_block[16];
|
||||
int16_t test_output_block[16];
|
||||
DECLARE_ALIGNED(16, int16_t, test_output_block[16]);
|
||||
const int pitch = 8;
|
||||
int count_sign_block[16][2];
|
||||
const int count_test_block = 1000000;
|
||||
@@ -81,10 +96,10 @@ TEST(VP8FdctTest, SignBiasCheck) {
|
||||
for (int i = 0; i < count_test_block; ++i) {
|
||||
// Initialize a test block with input range [-255, 255].
|
||||
for (int j = 0; j < 16; ++j) {
|
||||
test_input_block[j] = rnd.Rand8() - rnd.Rand8();
|
||||
test_input_block[j] = rnd_.Rand8() - rnd_.Rand8();
|
||||
}
|
||||
|
||||
vp8_short_fdct4x4_c(test_input_block, test_output_block, pitch);
|
||||
fdct_func_(test_input_block, test_output_block, pitch);
|
||||
|
||||
for (int j = 0; j < 16; ++j) {
|
||||
if (test_output_block[j] < 0) {
|
||||
@@ -110,10 +125,10 @@ TEST(VP8FdctTest, SignBiasCheck) {
|
||||
for (int i = 0; i < count_test_block; ++i) {
|
||||
// Initialize a test block with input range [-15, 15].
|
||||
for (int j = 0; j < 16; ++j) {
|
||||
test_input_block[j] = (rnd.Rand8() >> 4) - (rnd.Rand8() >> 4);
|
||||
test_input_block[j] = (rnd_.Rand8() >> 4) - (rnd_.Rand8() >> 4);
|
||||
}
|
||||
|
||||
vp8_short_fdct4x4_c(test_input_block, test_output_block, pitch);
|
||||
fdct_func_(test_input_block, test_output_block, pitch);
|
||||
|
||||
for (int j = 0; j < 16; ++j) {
|
||||
if (test_output_block[j] < 0) {
|
||||
@@ -135,23 +150,22 @@ TEST(VP8FdctTest, SignBiasCheck) {
|
||||
<< "Error: 4x4 FDCT has a sign bias > 10% for input range [-15, 15]";
|
||||
};
|
||||
|
||||
TEST(VP8FdctTest, RoundTripErrorCheck) {
|
||||
ACMRandom rnd(ACMRandom::DeterministicSeed());
|
||||
TEST_P(FdctTest, RoundTripErrorCheck) {
|
||||
int max_error = 0;
|
||||
double total_error = 0;
|
||||
const int count_test_block = 1000000;
|
||||
for (int i = 0; i < count_test_block; ++i) {
|
||||
int16_t test_input_block[16];
|
||||
int16_t test_temp_block[16];
|
||||
int16_t test_output_block[16];
|
||||
DECLARE_ALIGNED(16, int16_t, test_temp_block[16]);
|
||||
|
||||
// Initialize a test block with input range [-255, 255].
|
||||
for (int j = 0; j < 16; ++j) {
|
||||
test_input_block[j] = rnd.Rand8() - rnd.Rand8();
|
||||
test_input_block[j] = rnd_.Rand8() - rnd_.Rand8();
|
||||
}
|
||||
|
||||
const int pitch = 8;
|
||||
vp8_short_fdct4x4_c(test_input_block, test_temp_block, pitch);
|
||||
fdct_func_(test_input_block, test_temp_block, pitch);
|
||||
reference_idct4x4(test_temp_block, test_output_block);
|
||||
|
||||
for (int j = 0; j < 16; ++j) {
|
||||
@@ -169,4 +183,24 @@ TEST(VP8FdctTest, RoundTripErrorCheck) {
|
||||
<< "Error: FDCT/IDCT has average roundtrip error > 1 per block";
|
||||
};
|
||||
|
||||
INSTANTIATE_TEST_CASE_P(C, FdctTest, ::testing::Values(vp8_short_fdct4x4_c));
|
||||
|
||||
#if HAVE_NEON
|
||||
INSTANTIATE_TEST_CASE_P(NEON, FdctTest,
|
||||
::testing::Values(vp8_short_fdct4x4_neon));
|
||||
#endif // HAVE_NEON
|
||||
|
||||
#if HAVE_SSE2
|
||||
INSTANTIATE_TEST_CASE_P(SSE2, FdctTest,
|
||||
::testing::Values(vp8_short_fdct4x4_sse2));
|
||||
#endif // HAVE_SSE2
|
||||
|
||||
#if HAVE_MSA
|
||||
INSTANTIATE_TEST_CASE_P(MSA, FdctTest,
|
||||
::testing::Values(vp8_short_fdct4x4_msa));
|
||||
#endif // HAVE_MSA
|
||||
#if HAVE_MMI
|
||||
INSTANTIATE_TEST_CASE_P(MMI, FdctTest,
|
||||
::testing::Values(vp8_short_fdct4x4_mmi));
|
||||
#endif // HAVE_MMI
|
||||
} // namespace
|
||||
|
||||
@@ -23,36 +23,36 @@
|
||||
#include "vp9/common/vp9_entropy.h"
|
||||
#include "vpx/vpx_codec.h"
|
||||
#include "vpx/vpx_integer.h"
|
||||
#include "vpx_dsp/vpx_dsp_common.h"
|
||||
|
||||
using libvpx_test::ACMRandom;
|
||||
|
||||
namespace {
|
||||
#if CONFIG_VP9_HIGHBITDEPTH
|
||||
const int kNumIterations = 1000;
|
||||
|
||||
typedef int64_t (*ErrorBlockFunc)(const tran_low_t *coeff,
|
||||
typedef int64_t (*HBDBlockErrorFunc)(const tran_low_t *coeff,
|
||||
const tran_low_t *dqcoeff,
|
||||
intptr_t block_size, int64_t *ssz,
|
||||
int bps);
|
||||
|
||||
typedef std::tr1::tuple<HBDBlockErrorFunc, HBDBlockErrorFunc, vpx_bit_depth_t>
|
||||
BlockErrorParam;
|
||||
|
||||
typedef int64_t (*BlockErrorFunc)(const tran_low_t *coeff,
|
||||
const tran_low_t *dqcoeff,
|
||||
intptr_t block_size, int64_t *ssz, int bps);
|
||||
intptr_t block_size, int64_t *ssz);
|
||||
|
||||
typedef std::tr1::tuple<ErrorBlockFunc, ErrorBlockFunc, vpx_bit_depth_t>
|
||||
ErrorBlockParam;
|
||||
|
||||
// wrapper for 8-bit block error functions without a 'bps' param.
|
||||
typedef int64_t (*HighBdBlockError8bit)(const tran_low_t *coeff,
|
||||
const tran_low_t *dqcoeff,
|
||||
intptr_t block_size, int64_t *ssz);
|
||||
template <HighBdBlockError8bit fn>
|
||||
int64_t HighBdBlockError8bitWrapper(const tran_low_t *coeff,
|
||||
const tran_low_t *dqcoeff,
|
||||
intptr_t block_size, int64_t *ssz,
|
||||
int bps) {
|
||||
EXPECT_EQ(8, bps);
|
||||
template <BlockErrorFunc fn>
|
||||
int64_t BlockError8BitWrapper(const tran_low_t *coeff,
|
||||
const tran_low_t *dqcoeff, intptr_t block_size,
|
||||
int64_t *ssz, int bps) {
|
||||
EXPECT_EQ(bps, 8);
|
||||
return fn(coeff, dqcoeff, block_size, ssz);
|
||||
}
|
||||
|
||||
class ErrorBlockTest : public ::testing::TestWithParam<ErrorBlockParam> {
|
||||
class BlockErrorTest : public ::testing::TestWithParam<BlockErrorParam> {
|
||||
public:
|
||||
virtual ~ErrorBlockTest() {}
|
||||
virtual ~BlockErrorTest() {}
|
||||
virtual void SetUp() {
|
||||
error_block_op_ = GET_PARAM(0);
|
||||
ref_error_block_op_ = GET_PARAM(1);
|
||||
@@ -63,11 +63,11 @@ class ErrorBlockTest : public ::testing::TestWithParam<ErrorBlockParam> {
|
||||
|
||||
protected:
|
||||
vpx_bit_depth_t bit_depth_;
|
||||
ErrorBlockFunc error_block_op_;
|
||||
ErrorBlockFunc ref_error_block_op_;
|
||||
HBDBlockErrorFunc error_block_op_;
|
||||
HBDBlockErrorFunc ref_error_block_op_;
|
||||
};
|
||||
|
||||
TEST_P(ErrorBlockTest, OperationCheck) {
|
||||
TEST_P(BlockErrorTest, OperationCheck) {
|
||||
ACMRandom rnd(ACMRandom::DeterministicSeed());
|
||||
DECLARE_ALIGNED(16, tran_low_t, coeff[4096]);
|
||||
DECLARE_ALIGNED(16, tran_low_t, dqcoeff[4096]);
|
||||
@@ -110,7 +110,7 @@ TEST_P(ErrorBlockTest, OperationCheck) {
|
||||
<< "First failed at test case " << first_failure;
|
||||
}
|
||||
|
||||
TEST_P(ErrorBlockTest, ExtremeValues) {
|
||||
TEST_P(BlockErrorTest, ExtremeValues) {
|
||||
ACMRandom rnd(ACMRandom::DeterministicSeed());
|
||||
DECLARE_ALIGNED(16, tran_low_t, coeff[4096]);
|
||||
DECLARE_ALIGNED(16, tran_low_t, dqcoeff[4096]);
|
||||
@@ -171,29 +171,28 @@ TEST_P(ErrorBlockTest, ExtremeValues) {
|
||||
using std::tr1::make_tuple;
|
||||
|
||||
#if HAVE_SSE2
|
||||
INSTANTIATE_TEST_CASE_P(
|
||||
SSE2, ErrorBlockTest,
|
||||
::testing::Values(
|
||||
make_tuple(&vp9_highbd_block_error_sse2, &vp9_highbd_block_error_c,
|
||||
VPX_BITS_10),
|
||||
make_tuple(&vp9_highbd_block_error_sse2, &vp9_highbd_block_error_c,
|
||||
VPX_BITS_12),
|
||||
make_tuple(&vp9_highbd_block_error_sse2, &vp9_highbd_block_error_c,
|
||||
VPX_BITS_8),
|
||||
make_tuple(
|
||||
&HighBdBlockError8bitWrapper<vp9_highbd_block_error_8bit_sse2>,
|
||||
&HighBdBlockError8bitWrapper<vp9_highbd_block_error_8bit_c>,
|
||||
VPX_BITS_8)));
|
||||
const BlockErrorParam sse2_block_error_tests[] = {
|
||||
#if CONFIG_VP9_HIGHBITDEPTH
|
||||
make_tuple(&vp9_highbd_block_error_sse2, &vp9_highbd_block_error_c,
|
||||
VPX_BITS_10),
|
||||
make_tuple(&vp9_highbd_block_error_sse2, &vp9_highbd_block_error_c,
|
||||
VPX_BITS_12),
|
||||
make_tuple(&vp9_highbd_block_error_sse2, &vp9_highbd_block_error_c,
|
||||
VPX_BITS_8),
|
||||
#endif // CONFIG_VP9_HIGHBITDEPTH
|
||||
make_tuple(&BlockError8BitWrapper<vp9_block_error_sse2>,
|
||||
&BlockError8BitWrapper<vp9_block_error_c>, VPX_BITS_8)
|
||||
};
|
||||
|
||||
INSTANTIATE_TEST_CASE_P(SSE2, BlockErrorTest,
|
||||
::testing::ValuesIn(sse2_block_error_tests));
|
||||
#endif // HAVE_SSE2
|
||||
|
||||
#if HAVE_AVX
|
||||
#if HAVE_AVX2
|
||||
INSTANTIATE_TEST_CASE_P(
|
||||
AVX, ErrorBlockTest,
|
||||
::testing::Values(make_tuple(
|
||||
&HighBdBlockError8bitWrapper<vp9_highbd_block_error_8bit_avx>,
|
||||
&HighBdBlockError8bitWrapper<vp9_highbd_block_error_8bit_c>,
|
||||
VPX_BITS_8)));
|
||||
#endif // HAVE_AVX
|
||||
|
||||
#endif // CONFIG_VP9_HIGHBITDEPTH
|
||||
AVX2, BlockErrorTest,
|
||||
::testing::Values(make_tuple(&BlockError8BitWrapper<vp9_block_error_avx2>,
|
||||
&BlockError8BitWrapper<vp9_block_error_c>,
|
||||
VPX_BITS_8)));
|
||||
#endif // HAVE_AVX2
|
||||
} // namespace
|
||||
@@ -29,11 +29,21 @@ using libvpx_test::ACMRandom;
|
||||
namespace {
|
||||
|
||||
const int kNumPixels = 64 * 64;
|
||||
class VP9DenoiserTest : public ::testing::TestWithParam<BLOCK_SIZE> {
|
||||
|
||||
typedef int (*Vp9DenoiserFilterFunc)(const uint8_t *sig, int sig_stride,
|
||||
const uint8_t *mc_avg, int mc_avg_stride,
|
||||
uint8_t *avg, int avg_stride,
|
||||
int increase_denoising, BLOCK_SIZE bs,
|
||||
int motion_magnitude);
|
||||
typedef std::tr1::tuple<Vp9DenoiserFilterFunc, BLOCK_SIZE> VP9DenoiserTestParam;
|
||||
|
||||
class VP9DenoiserTest
|
||||
: public ::testing::Test,
|
||||
public ::testing::WithParamInterface<VP9DenoiserTestParam> {
|
||||
public:
|
||||
virtual ~VP9DenoiserTest() {}
|
||||
|
||||
virtual void SetUp() { bs_ = GetParam(); }
|
||||
virtual void SetUp() { bs_ = GET_PARAM(1); }
|
||||
|
||||
virtual void TearDown() { libvpx_test::ClearSystemState(); }
|
||||
|
||||
@@ -76,9 +86,9 @@ TEST_P(VP9DenoiserTest, BitexactCheck) {
|
||||
64, avg_block_c, 64, 0, bs_,
|
||||
motion_magnitude_random));
|
||||
|
||||
ASM_REGISTER_STATE_CHECK(vp9_denoiser_filter_sse2(
|
||||
sig_block, 64, mc_avg_block, 64, avg_block_sse2, 64, 0, bs_,
|
||||
motion_magnitude_random));
|
||||
ASM_REGISTER_STATE_CHECK(GET_PARAM(0)(sig_block, 64, mc_avg_block, 64,
|
||||
avg_block_sse2, 64, 0, bs_,
|
||||
motion_magnitude_random));
|
||||
|
||||
// Test bitexactness.
|
||||
for (int h = 0; h < (4 << b_height_log2_lookup[bs_]); ++h) {
|
||||
@@ -89,10 +99,36 @@ TEST_P(VP9DenoiserTest, BitexactCheck) {
|
||||
}
|
||||
}
|
||||
|
||||
using std::tr1::make_tuple;
|
||||
|
||||
// Test for all block size.
|
||||
INSTANTIATE_TEST_CASE_P(SSE2, VP9DenoiserTest,
|
||||
::testing::Values(BLOCK_8X8, BLOCK_8X16, BLOCK_16X8,
|
||||
BLOCK_16X16, BLOCK_16X32, BLOCK_32X16,
|
||||
BLOCK_32X32, BLOCK_32X64, BLOCK_64X32,
|
||||
BLOCK_64X64));
|
||||
#if HAVE_SSE2
|
||||
INSTANTIATE_TEST_CASE_P(
|
||||
SSE2, VP9DenoiserTest,
|
||||
::testing::Values(make_tuple(&vp9_denoiser_filter_sse2, BLOCK_8X8),
|
||||
make_tuple(&vp9_denoiser_filter_sse2, BLOCK_8X16),
|
||||
make_tuple(&vp9_denoiser_filter_sse2, BLOCK_16X8),
|
||||
make_tuple(&vp9_denoiser_filter_sse2, BLOCK_16X16),
|
||||
make_tuple(&vp9_denoiser_filter_sse2, BLOCK_16X32),
|
||||
make_tuple(&vp9_denoiser_filter_sse2, BLOCK_32X16),
|
||||
make_tuple(&vp9_denoiser_filter_sse2, BLOCK_32X32),
|
||||
make_tuple(&vp9_denoiser_filter_sse2, BLOCK_32X64),
|
||||
make_tuple(&vp9_denoiser_filter_sse2, BLOCK_64X32),
|
||||
make_tuple(&vp9_denoiser_filter_sse2, BLOCK_64X64)));
|
||||
#endif // HAVE_SSE2
|
||||
|
||||
#if HAVE_NEON
|
||||
INSTANTIATE_TEST_CASE_P(
|
||||
NEON, VP9DenoiserTest,
|
||||
::testing::Values(make_tuple(&vp9_denoiser_filter_neon, BLOCK_8X8),
|
||||
make_tuple(&vp9_denoiser_filter_neon, BLOCK_8X16),
|
||||
make_tuple(&vp9_denoiser_filter_neon, BLOCK_16X8),
|
||||
make_tuple(&vp9_denoiser_filter_neon, BLOCK_16X16),
|
||||
make_tuple(&vp9_denoiser_filter_neon, BLOCK_16X32),
|
||||
make_tuple(&vp9_denoiser_filter_neon, BLOCK_32X16),
|
||||
make_tuple(&vp9_denoiser_filter_neon, BLOCK_32X32),
|
||||
make_tuple(&vp9_denoiser_filter_neon, BLOCK_32X64),
|
||||
make_tuple(&vp9_denoiser_filter_neon, BLOCK_64X32),
|
||||
make_tuple(&vp9_denoiser_filter_neon, BLOCK_64X64)));
|
||||
#endif
|
||||
} // namespace
|
||||
@@ -99,9 +99,7 @@ class VpxEncoderParmsGetToDecoder
|
||||
vpx_codec_ctx_t *const vp9_decoder = decoder->GetDecoder();
|
||||
vpx_codec_alg_priv_t *const priv =
|
||||
reinterpret_cast<vpx_codec_alg_priv_t *>(vp9_decoder->priv);
|
||||
FrameWorkerData *const worker_data =
|
||||
reinterpret_cast<FrameWorkerData *>(priv->frame_workers[0].data1);
|
||||
VP9_COMMON *const common = &worker_data->pbi->common;
|
||||
VP9_COMMON *const common = &priv->pbi->common;
|
||||
|
||||
if (encode_parms.lossless) {
|
||||
EXPECT_EQ(0, common->base_qindex);
|
||||
|
||||
@@ -16,8 +16,207 @@
|
||||
#include "test/md5_helper.h"
|
||||
#include "test/util.h"
|
||||
#include "test/y4m_video_source.h"
|
||||
#include "vp9/encoder/vp9_firstpass.h"
|
||||
|
||||
namespace {
|
||||
// FIRSTPASS_STATS struct:
|
||||
// {
|
||||
// 25 double members;
|
||||
// 1 int64_t member;
|
||||
// }
|
||||
// Whenever FIRSTPASS_STATS struct is modified, the following constants need to
|
||||
// be revisited.
|
||||
const int kDbl = 25;
|
||||
const int kInt = 1;
|
||||
const size_t kFirstPassStatsSz = kDbl * sizeof(double) + kInt * sizeof(int64_t);
|
||||
|
||||
class VPxFirstPassEncoderThreadTest
|
||||
: public ::libvpx_test::EncoderTest,
|
||||
public ::libvpx_test::CodecTestWith2Params<libvpx_test::TestMode, int> {
|
||||
protected:
|
||||
VPxFirstPassEncoderThreadTest()
|
||||
: EncoderTest(GET_PARAM(0)), encoder_initialized_(false), tiles_(0),
|
||||
encoding_mode_(GET_PARAM(1)), set_cpu_used_(GET_PARAM(2)) {
|
||||
init_flags_ = VPX_CODEC_USE_PSNR;
|
||||
|
||||
row_mt_mode_ = 1;
|
||||
first_pass_only_ = true;
|
||||
firstpass_stats_.buf = NULL;
|
||||
firstpass_stats_.sz = 0;
|
||||
}
|
||||
virtual ~VPxFirstPassEncoderThreadTest() { free(firstpass_stats_.buf); }
|
||||
|
||||
virtual void SetUp() {
|
||||
InitializeConfig();
|
||||
SetMode(encoding_mode_);
|
||||
|
||||
cfg_.rc_end_usage = VPX_VBR;
|
||||
cfg_.rc_2pass_vbr_minsection_pct = 5;
|
||||
cfg_.rc_2pass_vbr_maxsection_pct = 2000;
|
||||
cfg_.rc_max_quantizer = 56;
|
||||
cfg_.rc_min_quantizer = 0;
|
||||
}
|
||||
|
||||
virtual void BeginPassHook(unsigned int /*pass*/) {
|
||||
encoder_initialized_ = false;
|
||||
abort_ = false;
|
||||
}
|
||||
|
||||
virtual void EndPassHook() {
|
||||
// For first pass stats test, only run first pass encoder.
|
||||
if (first_pass_only_ && cfg_.g_pass == VPX_RC_FIRST_PASS)
|
||||
abort_ |= first_pass_only_;
|
||||
}
|
||||
|
||||
virtual void PreEncodeFrameHook(::libvpx_test::VideoSource * /*video*/,
|
||||
::libvpx_test::Encoder *encoder) {
|
||||
if (!encoder_initialized_) {
|
||||
// Encode in 2-pass mode.
|
||||
encoder->Control(VP9E_SET_TILE_COLUMNS, tiles_);
|
||||
encoder->Control(VP8E_SET_CPUUSED, set_cpu_used_);
|
||||
encoder->Control(VP8E_SET_ENABLEAUTOALTREF, 1);
|
||||
encoder->Control(VP8E_SET_ARNR_MAXFRAMES, 7);
|
||||
encoder->Control(VP8E_SET_ARNR_STRENGTH, 5);
|
||||
encoder->Control(VP8E_SET_ARNR_TYPE, 3);
|
||||
encoder->Control(VP9E_SET_FRAME_PARALLEL_DECODING, 0);
|
||||
|
||||
if (encoding_mode_ == ::libvpx_test::kTwoPassGood)
|
||||
encoder->Control(VP9E_SET_ROW_MT, row_mt_mode_);
|
||||
|
||||
encoder_initialized_ = true;
|
||||
}
|
||||
}
|
||||
|
||||
virtual void StatsPktHook(const vpx_codec_cx_pkt_t *pkt) {
|
||||
const uint8_t *const pkt_buf =
|
||||
reinterpret_cast<uint8_t *>(pkt->data.twopass_stats.buf);
|
||||
const size_t pkt_size = pkt->data.twopass_stats.sz;
|
||||
|
||||
// First pass stats size equals sizeof(FIRSTPASS_STATS)
|
||||
EXPECT_EQ(pkt_size, kFirstPassStatsSz)
|
||||
<< "Error: First pass stats size doesn't equal kFirstPassStatsSz";
|
||||
|
||||
firstpass_stats_.buf =
|
||||
realloc(firstpass_stats_.buf, firstpass_stats_.sz + pkt_size);
|
||||
memcpy((uint8_t *)firstpass_stats_.buf + firstpass_stats_.sz, pkt_buf,
|
||||
pkt_size);
|
||||
firstpass_stats_.sz += pkt_size;
|
||||
}
|
||||
|
||||
bool encoder_initialized_;
|
||||
int tiles_;
|
||||
::libvpx_test::TestMode encoding_mode_;
|
||||
int set_cpu_used_;
|
||||
int row_mt_mode_;
|
||||
bool first_pass_only_;
|
||||
vpx_fixed_buf_t firstpass_stats_;
|
||||
};
|
||||
|
||||
static void compare_fp_stats(vpx_fixed_buf_t *fp_stats, double factor) {
|
||||
// fp_stats consists of 2 set of first pass encoding stats. These 2 set of
|
||||
// stats are compared to check if the stats match or at least are very close.
|
||||
FIRSTPASS_STATS *stats1 = reinterpret_cast<FIRSTPASS_STATS *>(fp_stats->buf);
|
||||
int nframes_ = (int)(fp_stats->sz / sizeof(FIRSTPASS_STATS));
|
||||
FIRSTPASS_STATS *stats2 = stats1 + nframes_ / 2;
|
||||
int i, j;
|
||||
|
||||
// The total stats are also output and included in the first pass stats. Here
|
||||
// ignore that in the comparison.
|
||||
for (i = 0; i < (nframes_ / 2 - 1); ++i) {
|
||||
const double *frame_stats1 = reinterpret_cast<double *>(stats1);
|
||||
const double *frame_stats2 = reinterpret_cast<double *>(stats2);
|
||||
|
||||
for (j = 0; j < kDbl; ++j) {
|
||||
ASSERT_LE(fabs(*frame_stats1 - *frame_stats2),
|
||||
fabs(*frame_stats1) / factor)
|
||||
<< "First failure @ frame #" << i << " stat #" << j << " ("
|
||||
<< *frame_stats1 << " vs. " << *frame_stats2 << ")";
|
||||
frame_stats1++;
|
||||
frame_stats2++;
|
||||
}
|
||||
|
||||
stats1++;
|
||||
stats2++;
|
||||
}
|
||||
|
||||
// Reset firstpass_stats_ to 0.
|
||||
memset((uint8_t *)fp_stats->buf, 0, fp_stats->sz);
|
||||
fp_stats->sz = 0;
|
||||
}
|
||||
|
||||
static void compare_fp_stats_md5(vpx_fixed_buf_t *fp_stats) {
|
||||
// fp_stats consists of 2 set of first pass encoding stats. These 2 set of
|
||||
// stats are compared to check if the stats match.
|
||||
uint8_t *stats1 = reinterpret_cast<uint8_t *>(fp_stats->buf);
|
||||
uint8_t *stats2 = stats1 + fp_stats->sz / 2;
|
||||
::libvpx_test::MD5 md5_row_mt_0, md5_row_mt_1;
|
||||
|
||||
md5_row_mt_0.Add(stats1, fp_stats->sz / 2);
|
||||
const char *md5_row_mt_0_str = md5_row_mt_0.Get();
|
||||
|
||||
md5_row_mt_1.Add(stats2, fp_stats->sz / 2);
|
||||
const char *md5_row_mt_1_str = md5_row_mt_1.Get();
|
||||
|
||||
// Check md5 match.
|
||||
ASSERT_STREQ(md5_row_mt_0_str, md5_row_mt_1_str)
|
||||
<< "MD5 checksums don't match";
|
||||
|
||||
// Reset firstpass_stats_ to 0.
|
||||
memset((uint8_t *)fp_stats->buf, 0, fp_stats->sz);
|
||||
fp_stats->sz = 0;
|
||||
}
|
||||
|
||||
TEST_P(VPxFirstPassEncoderThreadTest, FirstPassStatsTest) {
|
||||
::libvpx_test::Y4mVideoSource video("niklas_1280_720_30.y4m", 0, 60);
|
||||
|
||||
first_pass_only_ = true;
|
||||
cfg_.rc_target_bitrate = 1000;
|
||||
|
||||
// Test row_mt_mode: 0 vs 1 at single thread case(threads = 1, tiles_ = 0)
|
||||
tiles_ = 0;
|
||||
cfg_.g_threads = 1;
|
||||
|
||||
row_mt_mode_ = 0;
|
||||
init_flags_ = VPX_CODEC_USE_PSNR;
|
||||
ASSERT_NO_FATAL_FAILURE(RunLoop(&video));
|
||||
|
||||
row_mt_mode_ = 1;
|
||||
ASSERT_NO_FATAL_FAILURE(RunLoop(&video));
|
||||
|
||||
// Compare to check if using or not using row-mt generates close stats.
|
||||
ASSERT_NO_FATAL_FAILURE(compare_fp_stats(&firstpass_stats_, 1000.0));
|
||||
|
||||
// Test single thread vs multiple threads
|
||||
row_mt_mode_ = 1;
|
||||
tiles_ = 0;
|
||||
|
||||
cfg_.g_threads = 1;
|
||||
init_flags_ = VPX_CODEC_USE_PSNR;
|
||||
ASSERT_NO_FATAL_FAILURE(RunLoop(&video));
|
||||
|
||||
cfg_.g_threads = 4;
|
||||
ASSERT_NO_FATAL_FAILURE(RunLoop(&video));
|
||||
|
||||
// Compare to check if single-thread and multi-thread stats are close enough.
|
||||
ASSERT_NO_FATAL_FAILURE(compare_fp_stats(&firstpass_stats_, 1000.0));
|
||||
|
||||
// Bit exact test in row_mt mode.
|
||||
// When row_mt_mode_=1 and using >1 threads, the encoder generates bit exact
|
||||
// result.
|
||||
row_mt_mode_ = 1;
|
||||
tiles_ = 2;
|
||||
|
||||
cfg_.g_threads = 2;
|
||||
init_flags_ = VPX_CODEC_USE_PSNR;
|
||||
ASSERT_NO_FATAL_FAILURE(RunLoop(&video));
|
||||
|
||||
cfg_.g_threads = 8;
|
||||
ASSERT_NO_FATAL_FAILURE(RunLoop(&video));
|
||||
|
||||
// Compare to check if stats match with row-mt=0/1.
|
||||
compare_fp_stats_md5(&firstpass_stats_);
|
||||
}
|
||||
|
||||
class VPxEncoderThreadTest
|
||||
: public ::libvpx_test::EncoderTest,
|
||||
public ::libvpx_test::CodecTestWith4Params<libvpx_test::TestMode, int,
|
||||
@@ -29,6 +228,9 @@ class VPxEncoderThreadTest
|
||||
encoding_mode_(GET_PARAM(1)), set_cpu_used_(GET_PARAM(2)) {
|
||||
init_flags_ = VPX_CODEC_USE_PSNR;
|
||||
md5_.clear();
|
||||
row_mt_mode_ = 1;
|
||||
psnr_ = 0.0;
|
||||
nframes_ = 0;
|
||||
}
|
||||
virtual ~VPxEncoderThreadTest() {}
|
||||
|
||||
@@ -37,7 +239,6 @@ class VPxEncoderThreadTest
|
||||
SetMode(encoding_mode_);
|
||||
|
||||
if (encoding_mode_ != ::libvpx_test::kRealTime) {
|
||||
cfg_.g_lag_in_frames = 3;
|
||||
cfg_.rc_end_usage = VPX_VBR;
|
||||
cfg_.rc_2pass_vbr_minsection_pct = 5;
|
||||
cfg_.rc_2pass_vbr_maxsection_pct = 2000;
|
||||
@@ -52,6 +253,8 @@ class VPxEncoderThreadTest
|
||||
|
||||
virtual void BeginPassHook(unsigned int /*pass*/) {
|
||||
encoder_initialized_ = false;
|
||||
psnr_ = 0.0;
|
||||
nframes_ = 0;
|
||||
}
|
||||
|
||||
virtual void PreEncodeFrameHook(::libvpx_test::VideoSource * /*video*/,
|
||||
@@ -70,10 +273,17 @@ class VPxEncoderThreadTest
|
||||
encoder->Control(VP8E_SET_ENABLEAUTOALTREF, 0);
|
||||
encoder->Control(VP9E_SET_AQ_MODE, 3);
|
||||
}
|
||||
encoder->Control(VP9E_SET_ROW_MT, row_mt_mode_);
|
||||
|
||||
encoder_initialized_ = true;
|
||||
}
|
||||
}
|
||||
|
||||
virtual void PSNRPktHook(const vpx_codec_cx_pkt_t *pkt) {
|
||||
psnr_ += pkt->data.psnr.psnr[0];
|
||||
nframes_++;
|
||||
}
|
||||
|
||||
virtual void DecompressedFrameHook(const vpx_image_t &img,
|
||||
vpx_codec_pts_t /*pts*/) {
|
||||
::libvpx_test::MD5 md5_res;
|
||||
@@ -92,38 +302,102 @@ class VPxEncoderThreadTest
|
||||
return true;
|
||||
}
|
||||
|
||||
double GetAveragePsnr() const { return nframes_ ? (psnr_ / nframes_) : 0.0; }
|
||||
|
||||
bool encoder_initialized_;
|
||||
int tiles_;
|
||||
int threads_;
|
||||
::libvpx_test::TestMode encoding_mode_;
|
||||
int set_cpu_used_;
|
||||
int row_mt_mode_;
|
||||
double psnr_;
|
||||
unsigned int nframes_;
|
||||
std::vector<std::string> md5_;
|
||||
};
|
||||
|
||||
TEST_P(VPxEncoderThreadTest, EncoderResultTest) {
|
||||
std::vector<std::string> single_thr_md5, multi_thr_md5;
|
||||
|
||||
::libvpx_test::Y4mVideoSource video("niklas_1280_720_30.y4m", 15, 20);
|
||||
|
||||
cfg_.rc_target_bitrate = 1000;
|
||||
|
||||
// Part 1: Bit exact test for row_mt_mode_ = 0.
|
||||
// This part keeps original unit tests done before row-mt code is checked in.
|
||||
row_mt_mode_ = 0;
|
||||
|
||||
// Encode using single thread.
|
||||
cfg_.g_threads = 1;
|
||||
init_flags_ = VPX_CODEC_USE_PSNR;
|
||||
ASSERT_NO_FATAL_FAILURE(RunLoop(&video));
|
||||
single_thr_md5 = md5_;
|
||||
const std::vector<std::string> single_thr_md5 = md5_;
|
||||
md5_.clear();
|
||||
|
||||
// Encode using multiple threads.
|
||||
cfg_.g_threads = threads_;
|
||||
ASSERT_NO_FATAL_FAILURE(RunLoop(&video));
|
||||
multi_thr_md5 = md5_;
|
||||
const std::vector<std::string> multi_thr_md5 = md5_;
|
||||
md5_.clear();
|
||||
|
||||
// Compare to check if two vectors are equal.
|
||||
ASSERT_EQ(single_thr_md5, multi_thr_md5);
|
||||
|
||||
// Part 2: row_mt_mode_ = 0 vs row_mt_mode_ = 1 single thread bit exact test.
|
||||
row_mt_mode_ = 1;
|
||||
|
||||
// Encode using single thread
|
||||
cfg_.g_threads = 1;
|
||||
init_flags_ = VPX_CODEC_USE_PSNR;
|
||||
ASSERT_NO_FATAL_FAILURE(RunLoop(&video));
|
||||
std::vector<std::string> row_mt_single_thr_md5 = md5_;
|
||||
md5_.clear();
|
||||
|
||||
ASSERT_EQ(single_thr_md5, row_mt_single_thr_md5);
|
||||
|
||||
// Part 3: Bit exact test with row-mt on
|
||||
// When row_mt_mode_=1 and using >1 threads, the encoder generates bit exact
|
||||
// result.
|
||||
row_mt_mode_ = 1;
|
||||
row_mt_single_thr_md5.clear();
|
||||
|
||||
// Encode using 2 threads.
|
||||
cfg_.g_threads = 2;
|
||||
init_flags_ = VPX_CODEC_USE_PSNR;
|
||||
ASSERT_NO_FATAL_FAILURE(RunLoop(&video));
|
||||
row_mt_single_thr_md5 = md5_;
|
||||
md5_.clear();
|
||||
|
||||
// Encode using multiple threads.
|
||||
cfg_.g_threads = threads_;
|
||||
ASSERT_NO_FATAL_FAILURE(RunLoop(&video));
|
||||
const std::vector<std::string> row_mt_multi_thr_md5 = md5_;
|
||||
md5_.clear();
|
||||
|
||||
// Compare to check if two vectors are equal.
|
||||
ASSERT_EQ(row_mt_single_thr_md5, row_mt_multi_thr_md5);
|
||||
|
||||
// Part 4: PSNR test with bit_match_mode_ = 0
|
||||
row_mt_mode_ = 1;
|
||||
|
||||
// Encode using single thread.
|
||||
cfg_.g_threads = 1;
|
||||
init_flags_ = VPX_CODEC_USE_PSNR;
|
||||
ASSERT_NO_FATAL_FAILURE(RunLoop(&video));
|
||||
const double single_thr_psnr = GetAveragePsnr();
|
||||
|
||||
// Encode using multiple threads.
|
||||
cfg_.g_threads = threads_;
|
||||
ASSERT_NO_FATAL_FAILURE(RunLoop(&video));
|
||||
const double multi_thr_psnr = GetAveragePsnr();
|
||||
|
||||
EXPECT_NEAR(single_thr_psnr, multi_thr_psnr, 0.1);
|
||||
}
|
||||
|
||||
INSTANTIATE_TEST_CASE_P(
|
||||
VP9, VPxFirstPassEncoderThreadTest,
|
||||
::testing::Combine(
|
||||
::testing::Values(
|
||||
static_cast<const libvpx_test::CodecFactory *>(&libvpx_test::kVP9)),
|
||||
::testing::Values(::libvpx_test::kTwoPassGood),
|
||||
::testing::Range(0, 4))); // cpu_used
|
||||
|
||||
// Split this into two instantiations so that we can distinguish
|
||||
// between very slow runs ( ie cpu_speed 0 ) vs ones that can be
|
||||
// run nightly by adding Large to the title.
|
||||
@@ -135,7 +409,7 @@ INSTANTIATE_TEST_CASE_P(
|
||||
::testing::Values(::libvpx_test::kTwoPassGood,
|
||||
::libvpx_test::kOnePassGood,
|
||||
::libvpx_test::kRealTime),
|
||||
::testing::Range(2, 9), // cpu_used
|
||||
::testing::Range(3, 9), // cpu_used
|
||||
::testing::Range(0, 3), // tile_columns
|
||||
::testing::Range(2, 5))); // threads
|
||||
|
||||
@@ -147,7 +421,7 @@ INSTANTIATE_TEST_CASE_P(
|
||||
::testing::Values(::libvpx_test::kTwoPassGood,
|
||||
::libvpx_test::kOnePassGood,
|
||||
::libvpx_test::kRealTime),
|
||||
::testing::Range(0, 2), // cpu_used
|
||||
::testing::Range(0, 3), // cpu_used
|
||||
::testing::Range(0, 3), // tile_columns
|
||||
::testing::Range(2, 5))); // threads
|
||||
|
||||
|
||||
@@ -1,217 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2014 The WebM project authors. All Rights Reserved.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license
|
||||
* that can be found in the LICENSE file in the root of the source
|
||||
* tree. An additional intellectual property rights grant can be found
|
||||
* in the file PATENTS. All contributing project authors may
|
||||
* be found in the AUTHORS file in the root of the source tree.
|
||||
*/
|
||||
|
||||
#include <cstdio>
|
||||
#include <cstdlib>
|
||||
#include <string>
|
||||
#include "third_party/googletest/src/include/gtest/gtest.h"
|
||||
#include "./vpx_config.h"
|
||||
#include "test/codec_factory.h"
|
||||
#include "test/decode_test_driver.h"
|
||||
#include "test/ivf_video_source.h"
|
||||
#include "test/md5_helper.h"
|
||||
#include "test/util.h"
|
||||
#if CONFIG_WEBM_IO
|
||||
#include "test/webm_video_source.h"
|
||||
#endif
|
||||
#include "vpx_mem/vpx_mem.h"
|
||||
|
||||
namespace {
|
||||
|
||||
using std::string;
|
||||
|
||||
#if CONFIG_WEBM_IO
|
||||
|
||||
struct PauseFileList {
|
||||
const char *name;
|
||||
// md5 sum for decoded frames which does not include skipped frames.
|
||||
const char *expected_md5;
|
||||
const int pause_frame_num;
|
||||
};
|
||||
|
||||
// Decodes |filename| with |num_threads|. Pause at the specified frame_num,
|
||||
// seek to next key frame and then continue decoding until the end. Return
|
||||
// the md5 of the decoded frames which does not include skipped frames.
|
||||
string DecodeFileWithPause(const string &filename, int num_threads,
|
||||
int pause_num) {
|
||||
libvpx_test::WebMVideoSource video(filename);
|
||||
video.Init();
|
||||
int in_frames = 0;
|
||||
int out_frames = 0;
|
||||
|
||||
vpx_codec_dec_cfg_t cfg = vpx_codec_dec_cfg_t();
|
||||
cfg.threads = num_threads;
|
||||
vpx_codec_flags_t flags = 0;
|
||||
flags |= VPX_CODEC_USE_FRAME_THREADING;
|
||||
libvpx_test::VP9Decoder decoder(cfg, flags);
|
||||
|
||||
libvpx_test::MD5 md5;
|
||||
video.Begin();
|
||||
|
||||
do {
|
||||
++in_frames;
|
||||
const vpx_codec_err_t res =
|
||||
decoder.DecodeFrame(video.cxdata(), video.frame_size());
|
||||
if (res != VPX_CODEC_OK) {
|
||||
EXPECT_EQ(VPX_CODEC_OK, res) << decoder.DecodeError();
|
||||
break;
|
||||
}
|
||||
|
||||
// Pause at specified frame number.
|
||||
if (in_frames == pause_num) {
|
||||
// Flush the decoder and then seek to next key frame.
|
||||
decoder.DecodeFrame(NULL, 0);
|
||||
video.SeekToNextKeyFrame();
|
||||
} else {
|
||||
video.Next();
|
||||
}
|
||||
|
||||
// Flush the decoder at the end of the video.
|
||||
if (!video.cxdata()) decoder.DecodeFrame(NULL, 0);
|
||||
|
||||
libvpx_test::DxDataIterator dec_iter = decoder.GetDxData();
|
||||
const vpx_image_t *img;
|
||||
|
||||
// Get decompressed data
|
||||
while ((img = dec_iter.Next())) {
|
||||
++out_frames;
|
||||
md5.Add(img);
|
||||
}
|
||||
} while (video.cxdata() != NULL);
|
||||
|
||||
EXPECT_EQ(in_frames, out_frames)
|
||||
<< "Input frame count does not match output frame count";
|
||||
|
||||
return string(md5.Get());
|
||||
}
|
||||
|
||||
void DecodeFilesWithPause(const PauseFileList files[]) {
|
||||
for (const PauseFileList *iter = files; iter->name != NULL; ++iter) {
|
||||
SCOPED_TRACE(iter->name);
|
||||
for (int t = 2; t <= 8; ++t) {
|
||||
EXPECT_EQ(iter->expected_md5,
|
||||
DecodeFileWithPause(iter->name, t, iter->pause_frame_num))
|
||||
<< "threads = " << t;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
TEST(VP9MultiThreadedFrameParallel, PauseSeekResume) {
|
||||
// vp90-2-07-frame_parallel-1.webm is a 40 frame video file with
|
||||
// one key frame for every ten frames.
|
||||
static const PauseFileList files[] = {
|
||||
{ "vp90-2-07-frame_parallel-1.webm", "6ea7c3875d67252e7caf2bc6e75b36b1",
|
||||
6 },
|
||||
{ "vp90-2-07-frame_parallel-1.webm", "4bb634160c7356a8d7d4299b6dc83a45",
|
||||
12 },
|
||||
{ "vp90-2-07-frame_parallel-1.webm", "89772591e6ef461f9fa754f916c78ed8",
|
||||
26 },
|
||||
{ NULL, NULL, 0 },
|
||||
};
|
||||
DecodeFilesWithPause(files);
|
||||
}
|
||||
|
||||
struct FileList {
|
||||
const char *name;
|
||||
// md5 sum for decoded frames which does not include corrupted frames.
|
||||
const char *expected_md5;
|
||||
// Expected number of decoded frames which does not include corrupted frames.
|
||||
const int expected_frame_count;
|
||||
};
|
||||
|
||||
// Decodes |filename| with |num_threads|. Return the md5 of the decoded
|
||||
// frames which does not include corrupted frames.
|
||||
string DecodeFile(const string &filename, int num_threads,
|
||||
int expected_frame_count) {
|
||||
libvpx_test::WebMVideoSource video(filename);
|
||||
video.Init();
|
||||
|
||||
vpx_codec_dec_cfg_t cfg = vpx_codec_dec_cfg_t();
|
||||
cfg.threads = num_threads;
|
||||
const vpx_codec_flags_t flags = VPX_CODEC_USE_FRAME_THREADING;
|
||||
libvpx_test::VP9Decoder decoder(cfg, flags);
|
||||
|
||||
libvpx_test::MD5 md5;
|
||||
video.Begin();
|
||||
|
||||
int out_frames = 0;
|
||||
do {
|
||||
const vpx_codec_err_t res =
|
||||
decoder.DecodeFrame(video.cxdata(), video.frame_size());
|
||||
// TODO(hkuang): frame parallel mode should return an error on corruption.
|
||||
if (res != VPX_CODEC_OK) {
|
||||
EXPECT_EQ(VPX_CODEC_OK, res) << decoder.DecodeError();
|
||||
break;
|
||||
}
|
||||
|
||||
video.Next();
|
||||
|
||||
// Flush the decoder at the end of the video.
|
||||
if (!video.cxdata()) decoder.DecodeFrame(NULL, 0);
|
||||
|
||||
libvpx_test::DxDataIterator dec_iter = decoder.GetDxData();
|
||||
const vpx_image_t *img;
|
||||
|
||||
// Get decompressed data
|
||||
while ((img = dec_iter.Next())) {
|
||||
++out_frames;
|
||||
md5.Add(img);
|
||||
}
|
||||
} while (video.cxdata() != NULL);
|
||||
|
||||
EXPECT_EQ(expected_frame_count, out_frames)
|
||||
<< "Input frame count does not match expected output frame count";
|
||||
|
||||
return string(md5.Get());
|
||||
}
|
||||
|
||||
void DecodeFiles(const FileList files[]) {
|
||||
for (const FileList *iter = files; iter->name != NULL; ++iter) {
|
||||
SCOPED_TRACE(iter->name);
|
||||
for (int t = 2; t <= 8; ++t) {
|
||||
EXPECT_EQ(iter->expected_md5,
|
||||
DecodeFile(iter->name, t, iter->expected_frame_count))
|
||||
<< "threads = " << t;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
TEST(VP9MultiThreadedFrameParallel, InvalidFileTest) {
|
||||
static const FileList files[] = {
|
||||
// invalid-vp90-2-07-frame_parallel-1.webm is a 40 frame video file with
|
||||
// one key frame for every ten frames. The 11th frame has corrupted data.
|
||||
{ "invalid-vp90-2-07-frame_parallel-1.webm",
|
||||
"0549d0f45f60deaef8eb708e6c0eb6cb", 30 },
|
||||
// invalid-vp90-2-07-frame_parallel-2.webm is a 40 frame video file with
|
||||
// one key frame for every ten frames. The 1st and 31st frames have
|
||||
// corrupted data.
|
||||
{ "invalid-vp90-2-07-frame_parallel-2.webm",
|
||||
"6a1f3cf6f9e7a364212fadb9580d525e", 20 },
|
||||
// invalid-vp90-2-07-frame_parallel-3.webm is a 40 frame video file with
|
||||
// one key frame for every ten frames. The 5th and 13th frames have
|
||||
// corrupted data.
|
||||
{ "invalid-vp90-2-07-frame_parallel-3.webm",
|
||||
"8256544308de926b0681e04685b98677", 27 },
|
||||
{ NULL, NULL, 0 },
|
||||
};
|
||||
DecodeFiles(files);
|
||||
}
|
||||
|
||||
TEST(VP9MultiThreadedFrameParallel, ValidFileTest) {
|
||||
static const FileList files[] = {
|
||||
#if CONFIG_VP9_HIGHBITDEPTH
|
||||
{ "vp92-2-20-10bit-yuv420.webm", "a16b99df180c584e8db2ffeda987d293", 10 },
|
||||
#endif
|
||||
{ NULL, NULL, 0 },
|
||||
};
|
||||
DecodeFiles(files);
|
||||
}
|
||||
#endif // CONFIG_WEBM_IO
|
||||
} // namespace
|
||||
@@ -378,6 +378,60 @@ INSTANTIATE_TEST_CASE_P(
|
||||
8)));
|
||||
#endif // HAVE_MSA
|
||||
|
||||
#if HAVE_VSX
|
||||
INSTANTIATE_TEST_CASE_P(
|
||||
VSX, VP9IntraPredTest,
|
||||
::testing::Values(
|
||||
IntraPredParam(&vpx_d45_predictor_8x8_vsx, &vpx_d45_predictor_8x8_c, 8,
|
||||
8),
|
||||
IntraPredParam(&vpx_d45_predictor_16x16_vsx, &vpx_d45_predictor_16x16_c,
|
||||
16, 8),
|
||||
IntraPredParam(&vpx_d45_predictor_32x32_vsx, &vpx_d45_predictor_32x32_c,
|
||||
32, 8),
|
||||
IntraPredParam(&vpx_d63_predictor_8x8_vsx, &vpx_d63_predictor_8x8_c, 8,
|
||||
8),
|
||||
IntraPredParam(&vpx_d63_predictor_16x16_vsx, &vpx_d63_predictor_16x16_c,
|
||||
16, 8),
|
||||
IntraPredParam(&vpx_d63_predictor_32x32_vsx, &vpx_d63_predictor_32x32_c,
|
||||
32, 8),
|
||||
IntraPredParam(&vpx_dc_128_predictor_16x16_vsx,
|
||||
&vpx_dc_128_predictor_16x16_c, 16, 8),
|
||||
IntraPredParam(&vpx_dc_128_predictor_32x32_vsx,
|
||||
&vpx_dc_128_predictor_32x32_c, 32, 8),
|
||||
IntraPredParam(&vpx_dc_left_predictor_16x16_vsx,
|
||||
&vpx_dc_left_predictor_16x16_c, 16, 8),
|
||||
IntraPredParam(&vpx_dc_left_predictor_32x32_vsx,
|
||||
&vpx_dc_left_predictor_32x32_c, 32, 8),
|
||||
IntraPredParam(&vpx_dc_predictor_8x8_vsx, &vpx_dc_predictor_8x8_c, 8,
|
||||
8),
|
||||
IntraPredParam(&vpx_dc_predictor_16x16_vsx, &vpx_dc_predictor_16x16_c,
|
||||
16, 8),
|
||||
IntraPredParam(&vpx_dc_predictor_32x32_vsx, &vpx_dc_predictor_32x32_c,
|
||||
32, 8),
|
||||
IntraPredParam(&vpx_dc_top_predictor_16x16_vsx,
|
||||
&vpx_dc_top_predictor_16x16_c, 16, 8),
|
||||
IntraPredParam(&vpx_dc_top_predictor_32x32_vsx,
|
||||
&vpx_dc_top_predictor_32x32_c, 32, 8),
|
||||
IntraPredParam(&vpx_h_predictor_4x4_vsx, &vpx_h_predictor_4x4_c, 4, 8),
|
||||
IntraPredParam(&vpx_h_predictor_8x8_vsx, &vpx_h_predictor_8x8_c, 8, 8),
|
||||
IntraPredParam(&vpx_h_predictor_16x16_vsx, &vpx_h_predictor_16x16_c, 16,
|
||||
8),
|
||||
IntraPredParam(&vpx_h_predictor_32x32_vsx, &vpx_h_predictor_32x32_c, 32,
|
||||
8),
|
||||
IntraPredParam(&vpx_tm_predictor_4x4_vsx, &vpx_tm_predictor_4x4_c, 4,
|
||||
8),
|
||||
IntraPredParam(&vpx_tm_predictor_8x8_vsx, &vpx_tm_predictor_8x8_c, 8,
|
||||
8),
|
||||
IntraPredParam(&vpx_tm_predictor_16x16_vsx, &vpx_tm_predictor_16x16_c,
|
||||
16, 8),
|
||||
IntraPredParam(&vpx_tm_predictor_32x32_vsx, &vpx_tm_predictor_32x32_c,
|
||||
32, 8),
|
||||
IntraPredParam(&vpx_v_predictor_16x16_vsx, &vpx_v_predictor_16x16_c, 16,
|
||||
8),
|
||||
IntraPredParam(&vpx_v_predictor_32x32_vsx, &vpx_v_predictor_32x32_c, 32,
|
||||
8)));
|
||||
#endif // HAVE_VSX
|
||||
|
||||
#if CONFIG_VP9_HIGHBITDEPTH
|
||||
typedef void (*HighbdIntraPred)(uint16_t *dst, ptrdiff_t stride,
|
||||
const uint16_t *above, const uint16_t *left,
|
||||
@@ -413,10 +467,164 @@ TEST_P(VP9HighbdIntraPredTest, HighbdIntraPredTests) {
|
||||
RunTest(left_col, above_data, dst, ref_dst);
|
||||
}
|
||||
|
||||
#if HAVE_SSSE3
|
||||
INSTANTIATE_TEST_CASE_P(
|
||||
SSSE3_TO_C_8, VP9HighbdIntraPredTest,
|
||||
::testing::Values(
|
||||
HighbdIntraPredParam(&vpx_highbd_d45_predictor_4x4_ssse3,
|
||||
&vpx_highbd_d45_predictor_4x4_c, 4, 8),
|
||||
HighbdIntraPredParam(&vpx_highbd_d45_predictor_8x8_ssse3,
|
||||
&vpx_highbd_d45_predictor_8x8_c, 8, 8),
|
||||
HighbdIntraPredParam(&vpx_highbd_d45_predictor_16x16_ssse3,
|
||||
&vpx_highbd_d45_predictor_16x16_c, 16, 8),
|
||||
HighbdIntraPredParam(&vpx_highbd_d45_predictor_32x32_ssse3,
|
||||
&vpx_highbd_d45_predictor_32x32_c, 32, 8),
|
||||
HighbdIntraPredParam(&vpx_highbd_d63_predictor_8x8_ssse3,
|
||||
&vpx_highbd_d63_predictor_8x8_c, 8, 8),
|
||||
HighbdIntraPredParam(&vpx_highbd_d63_predictor_16x16_ssse3,
|
||||
&vpx_highbd_d63_predictor_16x16_c, 16, 8),
|
||||
HighbdIntraPredParam(&vpx_highbd_d63_predictor_32x32_c,
|
||||
&vpx_highbd_d63_predictor_32x32_ssse3, 32, 8),
|
||||
HighbdIntraPredParam(&vpx_highbd_d117_predictor_8x8_ssse3,
|
||||
&vpx_highbd_d117_predictor_8x8_c, 8, 8),
|
||||
HighbdIntraPredParam(&vpx_highbd_d117_predictor_16x16_ssse3,
|
||||
&vpx_highbd_d117_predictor_16x16_c, 16, 8),
|
||||
HighbdIntraPredParam(&vpx_highbd_d117_predictor_32x32_c,
|
||||
&vpx_highbd_d117_predictor_32x32_ssse3, 32, 8),
|
||||
HighbdIntraPredParam(&vpx_highbd_d135_predictor_8x8_ssse3,
|
||||
&vpx_highbd_d135_predictor_8x8_c, 8, 8),
|
||||
HighbdIntraPredParam(&vpx_highbd_d135_predictor_16x16_ssse3,
|
||||
&vpx_highbd_d135_predictor_16x16_c, 16, 8),
|
||||
HighbdIntraPredParam(&vpx_highbd_d135_predictor_32x32_ssse3,
|
||||
&vpx_highbd_d135_predictor_32x32_c, 32, 8),
|
||||
HighbdIntraPredParam(&vpx_highbd_d153_predictor_8x8_ssse3,
|
||||
&vpx_highbd_d153_predictor_8x8_c, 8, 8),
|
||||
HighbdIntraPredParam(&vpx_highbd_d153_predictor_16x16_ssse3,
|
||||
&vpx_highbd_d153_predictor_16x16_c, 16, 8),
|
||||
HighbdIntraPredParam(&vpx_highbd_d153_predictor_32x32_ssse3,
|
||||
&vpx_highbd_d153_predictor_32x32_c, 32, 8),
|
||||
HighbdIntraPredParam(&vpx_highbd_d207_predictor_8x8_ssse3,
|
||||
&vpx_highbd_d207_predictor_8x8_c, 8, 8),
|
||||
HighbdIntraPredParam(&vpx_highbd_d207_predictor_16x16_ssse3,
|
||||
&vpx_highbd_d207_predictor_16x16_c, 16, 8),
|
||||
HighbdIntraPredParam(&vpx_highbd_d207_predictor_32x32_ssse3,
|
||||
&vpx_highbd_d207_predictor_32x32_c, 32, 8)));
|
||||
|
||||
INSTANTIATE_TEST_CASE_P(
|
||||
SSSE3_TO_C_10, VP9HighbdIntraPredTest,
|
||||
::testing::Values(
|
||||
HighbdIntraPredParam(&vpx_highbd_d45_predictor_4x4_ssse3,
|
||||
&vpx_highbd_d45_predictor_4x4_c, 4, 10),
|
||||
HighbdIntraPredParam(&vpx_highbd_d45_predictor_8x8_ssse3,
|
||||
&vpx_highbd_d45_predictor_8x8_c, 8, 10),
|
||||
HighbdIntraPredParam(&vpx_highbd_d45_predictor_16x16_ssse3,
|
||||
&vpx_highbd_d45_predictor_16x16_c, 16, 10),
|
||||
HighbdIntraPredParam(&vpx_highbd_d45_predictor_32x32_ssse3,
|
||||
&vpx_highbd_d45_predictor_32x32_c, 32, 10),
|
||||
HighbdIntraPredParam(&vpx_highbd_d63_predictor_8x8_ssse3,
|
||||
&vpx_highbd_d63_predictor_8x8_c, 8, 10),
|
||||
HighbdIntraPredParam(&vpx_highbd_d63_predictor_16x16_ssse3,
|
||||
&vpx_highbd_d63_predictor_16x16_c, 16, 10),
|
||||
HighbdIntraPredParam(&vpx_highbd_d63_predictor_32x32_c,
|
||||
&vpx_highbd_d63_predictor_32x32_ssse3, 32, 10),
|
||||
HighbdIntraPredParam(&vpx_highbd_d117_predictor_8x8_ssse3,
|
||||
&vpx_highbd_d117_predictor_8x8_c, 8, 10),
|
||||
HighbdIntraPredParam(&vpx_highbd_d117_predictor_16x16_ssse3,
|
||||
&vpx_highbd_d117_predictor_16x16_c, 16, 10),
|
||||
HighbdIntraPredParam(&vpx_highbd_d117_predictor_32x32_c,
|
||||
&vpx_highbd_d117_predictor_32x32_ssse3, 32, 10),
|
||||
HighbdIntraPredParam(&vpx_highbd_d135_predictor_8x8_ssse3,
|
||||
&vpx_highbd_d135_predictor_8x8_c, 8, 10),
|
||||
HighbdIntraPredParam(&vpx_highbd_d135_predictor_16x16_ssse3,
|
||||
&vpx_highbd_d135_predictor_16x16_c, 16, 10),
|
||||
HighbdIntraPredParam(&vpx_highbd_d135_predictor_32x32_ssse3,
|
||||
&vpx_highbd_d135_predictor_32x32_c, 32, 10),
|
||||
HighbdIntraPredParam(&vpx_highbd_d153_predictor_8x8_ssse3,
|
||||
&vpx_highbd_d153_predictor_8x8_c, 8, 10),
|
||||
HighbdIntraPredParam(&vpx_highbd_d153_predictor_16x16_ssse3,
|
||||
&vpx_highbd_d153_predictor_16x16_c, 16, 10),
|
||||
HighbdIntraPredParam(&vpx_highbd_d153_predictor_32x32_ssse3,
|
||||
&vpx_highbd_d153_predictor_32x32_c, 32, 10),
|
||||
HighbdIntraPredParam(&vpx_highbd_d207_predictor_8x8_ssse3,
|
||||
&vpx_highbd_d207_predictor_8x8_c, 8, 10),
|
||||
HighbdIntraPredParam(&vpx_highbd_d207_predictor_16x16_ssse3,
|
||||
&vpx_highbd_d207_predictor_16x16_c, 16, 10),
|
||||
HighbdIntraPredParam(&vpx_highbd_d207_predictor_32x32_ssse3,
|
||||
&vpx_highbd_d207_predictor_32x32_c, 32, 10)));
|
||||
|
||||
INSTANTIATE_TEST_CASE_P(
|
||||
SSSE3_TO_C_12, VP9HighbdIntraPredTest,
|
||||
::testing::Values(
|
||||
HighbdIntraPredParam(&vpx_highbd_d45_predictor_4x4_ssse3,
|
||||
&vpx_highbd_d45_predictor_4x4_c, 4, 12),
|
||||
HighbdIntraPredParam(&vpx_highbd_d45_predictor_8x8_ssse3,
|
||||
&vpx_highbd_d45_predictor_8x8_c, 8, 12),
|
||||
HighbdIntraPredParam(&vpx_highbd_d45_predictor_16x16_ssse3,
|
||||
&vpx_highbd_d45_predictor_16x16_c, 16, 12),
|
||||
HighbdIntraPredParam(&vpx_highbd_d45_predictor_32x32_ssse3,
|
||||
&vpx_highbd_d45_predictor_32x32_c, 32, 12),
|
||||
HighbdIntraPredParam(&vpx_highbd_d63_predictor_8x8_ssse3,
|
||||
&vpx_highbd_d63_predictor_8x8_c, 8, 12),
|
||||
HighbdIntraPredParam(&vpx_highbd_d63_predictor_16x16_ssse3,
|
||||
&vpx_highbd_d63_predictor_16x16_c, 16, 12),
|
||||
HighbdIntraPredParam(&vpx_highbd_d63_predictor_32x32_c,
|
||||
&vpx_highbd_d63_predictor_32x32_ssse3, 32, 12),
|
||||
HighbdIntraPredParam(&vpx_highbd_d117_predictor_8x8_ssse3,
|
||||
&vpx_highbd_d117_predictor_8x8_c, 8, 12),
|
||||
HighbdIntraPredParam(&vpx_highbd_d117_predictor_16x16_ssse3,
|
||||
&vpx_highbd_d117_predictor_16x16_c, 16, 12),
|
||||
HighbdIntraPredParam(&vpx_highbd_d117_predictor_32x32_c,
|
||||
&vpx_highbd_d117_predictor_32x32_ssse3, 32, 12),
|
||||
HighbdIntraPredParam(&vpx_highbd_d135_predictor_8x8_ssse3,
|
||||
&vpx_highbd_d135_predictor_8x8_c, 8, 12),
|
||||
HighbdIntraPredParam(&vpx_highbd_d135_predictor_16x16_ssse3,
|
||||
&vpx_highbd_d135_predictor_16x16_c, 16, 12),
|
||||
HighbdIntraPredParam(&vpx_highbd_d135_predictor_32x32_ssse3,
|
||||
&vpx_highbd_d135_predictor_32x32_c, 32, 12),
|
||||
HighbdIntraPredParam(&vpx_highbd_d153_predictor_8x8_ssse3,
|
||||
&vpx_highbd_d153_predictor_8x8_c, 8, 12),
|
||||
HighbdIntraPredParam(&vpx_highbd_d153_predictor_16x16_ssse3,
|
||||
&vpx_highbd_d153_predictor_16x16_c, 16, 12),
|
||||
HighbdIntraPredParam(&vpx_highbd_d153_predictor_32x32_ssse3,
|
||||
&vpx_highbd_d153_predictor_32x32_c, 32, 12),
|
||||
HighbdIntraPredParam(&vpx_highbd_d207_predictor_8x8_ssse3,
|
||||
&vpx_highbd_d207_predictor_8x8_c, 8, 12),
|
||||
HighbdIntraPredParam(&vpx_highbd_d207_predictor_16x16_ssse3,
|
||||
&vpx_highbd_d207_predictor_16x16_c, 16, 12),
|
||||
HighbdIntraPredParam(&vpx_highbd_d207_predictor_32x32_ssse3,
|
||||
&vpx_highbd_d207_predictor_32x32_c, 32, 12)));
|
||||
#endif // HAVE_SSSE3
|
||||
|
||||
#if HAVE_SSE2
|
||||
INSTANTIATE_TEST_CASE_P(
|
||||
SSE2_TO_C_8, VP9HighbdIntraPredTest,
|
||||
::testing::Values(
|
||||
HighbdIntraPredParam(&vpx_highbd_dc_128_predictor_4x4_sse2,
|
||||
&vpx_highbd_dc_128_predictor_4x4_c, 4, 8),
|
||||
HighbdIntraPredParam(&vpx_highbd_dc_128_predictor_8x8_sse2,
|
||||
&vpx_highbd_dc_128_predictor_8x8_c, 8, 8),
|
||||
HighbdIntraPredParam(&vpx_highbd_dc_128_predictor_16x16_sse2,
|
||||
&vpx_highbd_dc_128_predictor_16x16_c, 16, 8),
|
||||
HighbdIntraPredParam(&vpx_highbd_dc_128_predictor_32x32_sse2,
|
||||
&vpx_highbd_dc_128_predictor_32x32_c, 32, 8),
|
||||
HighbdIntraPredParam(&vpx_highbd_d63_predictor_4x4_sse2,
|
||||
&vpx_highbd_d63_predictor_4x4_c, 4, 8),
|
||||
HighbdIntraPredParam(&vpx_highbd_d117_predictor_4x4_sse2,
|
||||
&vpx_highbd_d117_predictor_4x4_c, 4, 8),
|
||||
HighbdIntraPredParam(&vpx_highbd_d135_predictor_4x4_sse2,
|
||||
&vpx_highbd_d135_predictor_4x4_c, 4, 8),
|
||||
HighbdIntraPredParam(&vpx_highbd_d153_predictor_4x4_sse2,
|
||||
&vpx_highbd_d153_predictor_4x4_c, 4, 8),
|
||||
HighbdIntraPredParam(&vpx_highbd_d207_predictor_4x4_sse2,
|
||||
&vpx_highbd_d207_predictor_4x4_c, 4, 8),
|
||||
HighbdIntraPredParam(&vpx_highbd_dc_left_predictor_4x4_sse2,
|
||||
&vpx_highbd_dc_left_predictor_4x4_c, 4, 8),
|
||||
HighbdIntraPredParam(&vpx_highbd_dc_left_predictor_8x8_sse2,
|
||||
&vpx_highbd_dc_left_predictor_8x8_c, 8, 8),
|
||||
HighbdIntraPredParam(&vpx_highbd_dc_left_predictor_16x16_sse2,
|
||||
&vpx_highbd_dc_left_predictor_16x16_c, 16, 8),
|
||||
HighbdIntraPredParam(&vpx_highbd_dc_left_predictor_32x32_sse2,
|
||||
&vpx_highbd_dc_left_predictor_32x32_c, 32, 8),
|
||||
HighbdIntraPredParam(&vpx_highbd_dc_predictor_4x4_sse2,
|
||||
&vpx_highbd_dc_predictor_4x4_c, 4, 8),
|
||||
HighbdIntraPredParam(&vpx_highbd_dc_predictor_8x8_sse2,
|
||||
@@ -425,6 +633,14 @@ INSTANTIATE_TEST_CASE_P(
|
||||
&vpx_highbd_dc_predictor_16x16_c, 16, 8),
|
||||
HighbdIntraPredParam(&vpx_highbd_dc_predictor_32x32_sse2,
|
||||
&vpx_highbd_dc_predictor_32x32_c, 32, 8),
|
||||
HighbdIntraPredParam(&vpx_highbd_dc_top_predictor_4x4_sse2,
|
||||
&vpx_highbd_dc_top_predictor_4x4_c, 4, 8),
|
||||
HighbdIntraPredParam(&vpx_highbd_dc_top_predictor_8x8_sse2,
|
||||
&vpx_highbd_dc_top_predictor_8x8_c, 8, 8),
|
||||
HighbdIntraPredParam(&vpx_highbd_dc_top_predictor_16x16_sse2,
|
||||
&vpx_highbd_dc_top_predictor_16x16_c, 16, 8),
|
||||
HighbdIntraPredParam(&vpx_highbd_dc_top_predictor_32x32_sse2,
|
||||
&vpx_highbd_dc_top_predictor_32x32_c, 32, 8),
|
||||
HighbdIntraPredParam(&vpx_highbd_tm_predictor_4x4_sse2,
|
||||
&vpx_highbd_tm_predictor_4x4_c, 4, 8),
|
||||
HighbdIntraPredParam(&vpx_highbd_tm_predictor_8x8_sse2,
|
||||
@@ -433,6 +649,14 @@ INSTANTIATE_TEST_CASE_P(
|
||||
&vpx_highbd_tm_predictor_16x16_c, 16, 8),
|
||||
HighbdIntraPredParam(&vpx_highbd_tm_predictor_32x32_sse2,
|
||||
&vpx_highbd_tm_predictor_32x32_c, 32, 8),
|
||||
HighbdIntraPredParam(&vpx_highbd_h_predictor_4x4_sse2,
|
||||
&vpx_highbd_h_predictor_4x4_c, 4, 8),
|
||||
HighbdIntraPredParam(&vpx_highbd_h_predictor_8x8_sse2,
|
||||
&vpx_highbd_h_predictor_8x8_c, 8, 8),
|
||||
HighbdIntraPredParam(&vpx_highbd_h_predictor_16x16_sse2,
|
||||
&vpx_highbd_h_predictor_16x16_c, 16, 8),
|
||||
HighbdIntraPredParam(&vpx_highbd_h_predictor_32x32_sse2,
|
||||
&vpx_highbd_h_predictor_32x32_c, 32, 8),
|
||||
HighbdIntraPredParam(&vpx_highbd_v_predictor_4x4_sse2,
|
||||
&vpx_highbd_v_predictor_4x4_c, 4, 8),
|
||||
HighbdIntraPredParam(&vpx_highbd_v_predictor_8x8_sse2,
|
||||
@@ -445,6 +669,32 @@ INSTANTIATE_TEST_CASE_P(
|
||||
INSTANTIATE_TEST_CASE_P(
|
||||
SSE2_TO_C_10, VP9HighbdIntraPredTest,
|
||||
::testing::Values(
|
||||
HighbdIntraPredParam(&vpx_highbd_dc_128_predictor_4x4_sse2,
|
||||
&vpx_highbd_dc_128_predictor_4x4_c, 4, 10),
|
||||
HighbdIntraPredParam(&vpx_highbd_dc_128_predictor_8x8_sse2,
|
||||
&vpx_highbd_dc_128_predictor_8x8_c, 8, 10),
|
||||
HighbdIntraPredParam(&vpx_highbd_dc_128_predictor_16x16_sse2,
|
||||
&vpx_highbd_dc_128_predictor_16x16_c, 16, 10),
|
||||
HighbdIntraPredParam(&vpx_highbd_dc_128_predictor_32x32_sse2,
|
||||
&vpx_highbd_dc_128_predictor_32x32_c, 32, 10),
|
||||
HighbdIntraPredParam(&vpx_highbd_d63_predictor_4x4_sse2,
|
||||
&vpx_highbd_d63_predictor_4x4_c, 4, 10),
|
||||
HighbdIntraPredParam(&vpx_highbd_d117_predictor_4x4_sse2,
|
||||
&vpx_highbd_d117_predictor_4x4_c, 4, 10),
|
||||
HighbdIntraPredParam(&vpx_highbd_d135_predictor_4x4_sse2,
|
||||
&vpx_highbd_d135_predictor_4x4_c, 4, 10),
|
||||
HighbdIntraPredParam(&vpx_highbd_d153_predictor_4x4_sse2,
|
||||
&vpx_highbd_d153_predictor_4x4_c, 4, 10),
|
||||
HighbdIntraPredParam(&vpx_highbd_d207_predictor_4x4_sse2,
|
||||
&vpx_highbd_d207_predictor_4x4_c, 4, 10),
|
||||
HighbdIntraPredParam(&vpx_highbd_dc_left_predictor_4x4_sse2,
|
||||
&vpx_highbd_dc_left_predictor_4x4_c, 4, 10),
|
||||
HighbdIntraPredParam(&vpx_highbd_dc_left_predictor_8x8_sse2,
|
||||
&vpx_highbd_dc_left_predictor_8x8_c, 8, 10),
|
||||
HighbdIntraPredParam(&vpx_highbd_dc_left_predictor_16x16_sse2,
|
||||
&vpx_highbd_dc_left_predictor_16x16_c, 16, 10),
|
||||
HighbdIntraPredParam(&vpx_highbd_dc_left_predictor_32x32_sse2,
|
||||
&vpx_highbd_dc_left_predictor_32x32_c, 32, 10),
|
||||
HighbdIntraPredParam(&vpx_highbd_dc_predictor_4x4_sse2,
|
||||
&vpx_highbd_dc_predictor_4x4_c, 4, 10),
|
||||
HighbdIntraPredParam(&vpx_highbd_dc_predictor_8x8_sse2,
|
||||
@@ -453,6 +703,14 @@ INSTANTIATE_TEST_CASE_P(
|
||||
&vpx_highbd_dc_predictor_16x16_c, 16, 10),
|
||||
HighbdIntraPredParam(&vpx_highbd_dc_predictor_32x32_sse2,
|
||||
&vpx_highbd_dc_predictor_32x32_c, 32, 10),
|
||||
HighbdIntraPredParam(&vpx_highbd_dc_top_predictor_4x4_sse2,
|
||||
&vpx_highbd_dc_top_predictor_4x4_c, 4, 10),
|
||||
HighbdIntraPredParam(&vpx_highbd_dc_top_predictor_8x8_sse2,
|
||||
&vpx_highbd_dc_top_predictor_8x8_c, 8, 10),
|
||||
HighbdIntraPredParam(&vpx_highbd_dc_top_predictor_16x16_sse2,
|
||||
&vpx_highbd_dc_top_predictor_16x16_c, 16, 10),
|
||||
HighbdIntraPredParam(&vpx_highbd_dc_top_predictor_32x32_sse2,
|
||||
&vpx_highbd_dc_top_predictor_32x32_c, 32, 10),
|
||||
HighbdIntraPredParam(&vpx_highbd_tm_predictor_4x4_sse2,
|
||||
&vpx_highbd_tm_predictor_4x4_c, 4, 10),
|
||||
HighbdIntraPredParam(&vpx_highbd_tm_predictor_8x8_sse2,
|
||||
@@ -461,6 +719,14 @@ INSTANTIATE_TEST_CASE_P(
|
||||
&vpx_highbd_tm_predictor_16x16_c, 16, 10),
|
||||
HighbdIntraPredParam(&vpx_highbd_tm_predictor_32x32_sse2,
|
||||
&vpx_highbd_tm_predictor_32x32_c, 32, 10),
|
||||
HighbdIntraPredParam(&vpx_highbd_h_predictor_4x4_sse2,
|
||||
&vpx_highbd_h_predictor_4x4_c, 4, 10),
|
||||
HighbdIntraPredParam(&vpx_highbd_h_predictor_8x8_sse2,
|
||||
&vpx_highbd_h_predictor_8x8_c, 8, 10),
|
||||
HighbdIntraPredParam(&vpx_highbd_h_predictor_16x16_sse2,
|
||||
&vpx_highbd_h_predictor_16x16_c, 16, 10),
|
||||
HighbdIntraPredParam(&vpx_highbd_h_predictor_32x32_sse2,
|
||||
&vpx_highbd_h_predictor_32x32_c, 32, 10),
|
||||
HighbdIntraPredParam(&vpx_highbd_v_predictor_4x4_sse2,
|
||||
&vpx_highbd_v_predictor_4x4_c, 4, 10),
|
||||
HighbdIntraPredParam(&vpx_highbd_v_predictor_8x8_sse2,
|
||||
@@ -473,6 +739,32 @@ INSTANTIATE_TEST_CASE_P(
|
||||
INSTANTIATE_TEST_CASE_P(
|
||||
SSE2_TO_C_12, VP9HighbdIntraPredTest,
|
||||
::testing::Values(
|
||||
HighbdIntraPredParam(&vpx_highbd_dc_128_predictor_4x4_sse2,
|
||||
&vpx_highbd_dc_128_predictor_4x4_c, 4, 12),
|
||||
HighbdIntraPredParam(&vpx_highbd_dc_128_predictor_8x8_sse2,
|
||||
&vpx_highbd_dc_128_predictor_8x8_c, 8, 12),
|
||||
HighbdIntraPredParam(&vpx_highbd_dc_128_predictor_16x16_sse2,
|
||||
&vpx_highbd_dc_128_predictor_16x16_c, 16, 12),
|
||||
HighbdIntraPredParam(&vpx_highbd_dc_128_predictor_32x32_sse2,
|
||||
&vpx_highbd_dc_128_predictor_32x32_c, 32, 12),
|
||||
HighbdIntraPredParam(&vpx_highbd_d63_predictor_4x4_sse2,
|
||||
&vpx_highbd_d63_predictor_4x4_c, 4, 12),
|
||||
HighbdIntraPredParam(&vpx_highbd_d117_predictor_4x4_sse2,
|
||||
&vpx_highbd_d117_predictor_4x4_c, 4, 12),
|
||||
HighbdIntraPredParam(&vpx_highbd_d135_predictor_4x4_sse2,
|
||||
&vpx_highbd_d135_predictor_4x4_c, 4, 12),
|
||||
HighbdIntraPredParam(&vpx_highbd_d153_predictor_4x4_sse2,
|
||||
&vpx_highbd_d153_predictor_4x4_c, 4, 12),
|
||||
HighbdIntraPredParam(&vpx_highbd_d207_predictor_4x4_sse2,
|
||||
&vpx_highbd_d207_predictor_4x4_c, 4, 12),
|
||||
HighbdIntraPredParam(&vpx_highbd_dc_left_predictor_4x4_sse2,
|
||||
&vpx_highbd_dc_left_predictor_4x4_c, 4, 12),
|
||||
HighbdIntraPredParam(&vpx_highbd_dc_left_predictor_8x8_sse2,
|
||||
&vpx_highbd_dc_left_predictor_8x8_c, 8, 12),
|
||||
HighbdIntraPredParam(&vpx_highbd_dc_left_predictor_16x16_sse2,
|
||||
&vpx_highbd_dc_left_predictor_16x16_c, 16, 12),
|
||||
HighbdIntraPredParam(&vpx_highbd_dc_left_predictor_32x32_sse2,
|
||||
&vpx_highbd_dc_left_predictor_32x32_c, 32, 12),
|
||||
HighbdIntraPredParam(&vpx_highbd_dc_predictor_4x4_sse2,
|
||||
&vpx_highbd_dc_predictor_4x4_c, 4, 12),
|
||||
HighbdIntraPredParam(&vpx_highbd_dc_predictor_8x8_sse2,
|
||||
@@ -481,6 +773,14 @@ INSTANTIATE_TEST_CASE_P(
|
||||
&vpx_highbd_dc_predictor_16x16_c, 16, 12),
|
||||
HighbdIntraPredParam(&vpx_highbd_dc_predictor_32x32_sse2,
|
||||
&vpx_highbd_dc_predictor_32x32_c, 32, 12),
|
||||
HighbdIntraPredParam(&vpx_highbd_dc_top_predictor_4x4_sse2,
|
||||
&vpx_highbd_dc_top_predictor_4x4_c, 4, 12),
|
||||
HighbdIntraPredParam(&vpx_highbd_dc_top_predictor_8x8_sse2,
|
||||
&vpx_highbd_dc_top_predictor_8x8_c, 8, 12),
|
||||
HighbdIntraPredParam(&vpx_highbd_dc_top_predictor_16x16_sse2,
|
||||
&vpx_highbd_dc_top_predictor_16x16_c, 16, 12),
|
||||
HighbdIntraPredParam(&vpx_highbd_dc_top_predictor_32x32_sse2,
|
||||
&vpx_highbd_dc_top_predictor_32x32_c, 32, 12),
|
||||
HighbdIntraPredParam(&vpx_highbd_tm_predictor_4x4_sse2,
|
||||
&vpx_highbd_tm_predictor_4x4_c, 4, 12),
|
||||
HighbdIntraPredParam(&vpx_highbd_tm_predictor_8x8_sse2,
|
||||
@@ -489,6 +789,14 @@ INSTANTIATE_TEST_CASE_P(
|
||||
&vpx_highbd_tm_predictor_16x16_c, 16, 12),
|
||||
HighbdIntraPredParam(&vpx_highbd_tm_predictor_32x32_sse2,
|
||||
&vpx_highbd_tm_predictor_32x32_c, 32, 12),
|
||||
HighbdIntraPredParam(&vpx_highbd_h_predictor_4x4_sse2,
|
||||
&vpx_highbd_h_predictor_4x4_c, 4, 12),
|
||||
HighbdIntraPredParam(&vpx_highbd_h_predictor_8x8_sse2,
|
||||
&vpx_highbd_h_predictor_8x8_c, 8, 12),
|
||||
HighbdIntraPredParam(&vpx_highbd_h_predictor_16x16_sse2,
|
||||
&vpx_highbd_h_predictor_16x16_c, 16, 12),
|
||||
HighbdIntraPredParam(&vpx_highbd_h_predictor_32x32_sse2,
|
||||
&vpx_highbd_h_predictor_32x32_c, 32, 12),
|
||||
HighbdIntraPredParam(&vpx_highbd_v_predictor_4x4_sse2,
|
||||
&vpx_highbd_v_predictor_4x4_c, 4, 12),
|
||||
HighbdIntraPredParam(&vpx_highbd_v_predictor_8x8_sse2,
|
||||
|
||||
97
test/vp9_motion_vector_test.cc
Normal file
97
test/vp9_motion_vector_test.cc
Normal file
@@ -0,0 +1,97 @@
|
||||
/*
|
||||
* Copyright (c) 2017 The WebM project authors. All Rights Reserved.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license
|
||||
* that can be found in the LICENSE file in the root of the source
|
||||
* tree. An additional intellectual property rights grant can be found
|
||||
* in the file PATENTS. All contributing project authors may
|
||||
* be found in the AUTHORS file in the root of the source tree.
|
||||
*/
|
||||
|
||||
#include "third_party/googletest/src/include/gtest/gtest.h"
|
||||
|
||||
#include "test/codec_factory.h"
|
||||
#include "test/encode_test_driver.h"
|
||||
#include "test/util.h"
|
||||
#include "test/yuv_video_source.h"
|
||||
|
||||
namespace {
|
||||
#define MAX_EXTREME_MV 1
|
||||
#define MIN_EXTREME_MV 2
|
||||
|
||||
// Encoding modes
|
||||
const libvpx_test::TestMode kEncodingModeVectors[] = {
|
||||
::libvpx_test::kTwoPassGood, ::libvpx_test::kOnePassGood,
|
||||
::libvpx_test::kRealTime,
|
||||
};
|
||||
|
||||
// Encoding speeds
|
||||
const int kCpuUsedVectors[] = { 0, 1, 2, 3, 4, 5, 6 };
|
||||
|
||||
// MV test modes: 1 - always use maximum MV; 2 - always use minimum MV.
|
||||
const int kMVTestModes[] = { MAX_EXTREME_MV, MIN_EXTREME_MV };
|
||||
|
||||
class MotionVectorTestLarge
|
||||
: public ::libvpx_test::EncoderTest,
|
||||
public ::libvpx_test::CodecTestWith3Params<libvpx_test::TestMode, int,
|
||||
int> {
|
||||
protected:
|
||||
MotionVectorTestLarge()
|
||||
: EncoderTest(GET_PARAM(0)), encoding_mode_(GET_PARAM(1)),
|
||||
cpu_used_(GET_PARAM(2)), mv_test_mode_(GET_PARAM(3)) {}
|
||||
|
||||
virtual ~MotionVectorTestLarge() {}
|
||||
|
||||
virtual void SetUp() {
|
||||
InitializeConfig();
|
||||
SetMode(encoding_mode_);
|
||||
if (encoding_mode_ != ::libvpx_test::kRealTime) {
|
||||
cfg_.g_lag_in_frames = 3;
|
||||
cfg_.rc_end_usage = VPX_VBR;
|
||||
} else {
|
||||
cfg_.g_lag_in_frames = 0;
|
||||
cfg_.rc_end_usage = VPX_CBR;
|
||||
cfg_.rc_buf_sz = 1000;
|
||||
cfg_.rc_buf_initial_sz = 500;
|
||||
cfg_.rc_buf_optimal_sz = 600;
|
||||
}
|
||||
}
|
||||
|
||||
virtual void PreEncodeFrameHook(::libvpx_test::VideoSource *video,
|
||||
::libvpx_test::Encoder *encoder) {
|
||||
if (video->frame() == 1) {
|
||||
encoder->Control(VP8E_SET_CPUUSED, cpu_used_);
|
||||
encoder->Control(VP9E_ENABLE_MOTION_VECTOR_UNIT_TEST, mv_test_mode_);
|
||||
if (encoding_mode_ != ::libvpx_test::kRealTime) {
|
||||
encoder->Control(VP8E_SET_ENABLEAUTOALTREF, 1);
|
||||
encoder->Control(VP8E_SET_ARNR_MAXFRAMES, 7);
|
||||
encoder->Control(VP8E_SET_ARNR_STRENGTH, 5);
|
||||
encoder->Control(VP8E_SET_ARNR_TYPE, 3);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
libvpx_test::TestMode encoding_mode_;
|
||||
int cpu_used_;
|
||||
int mv_test_mode_;
|
||||
};
|
||||
|
||||
TEST_P(MotionVectorTestLarge, OverallTest) {
|
||||
cfg_.rc_target_bitrate = 24000;
|
||||
cfg_.g_profile = 0;
|
||||
init_flags_ = VPX_CODEC_USE_PSNR;
|
||||
|
||||
testing::internal::scoped_ptr<libvpx_test::VideoSource> video;
|
||||
video.reset(new libvpx_test::YUVVideoSource(
|
||||
"niklas_640_480_30.yuv", VPX_IMG_FMT_I420, 3840, 2160, // 2048, 1080,
|
||||
30, 1, 0, 5));
|
||||
|
||||
ASSERT_TRUE(video.get() != NULL);
|
||||
ASSERT_NO_FATAL_FAILURE(RunLoop(video.get()));
|
||||
}
|
||||
|
||||
VP9_INSTANTIATE_TEST_CASE(MotionVectorTestLarge,
|
||||
::testing::ValuesIn(kEncodingModeVectors),
|
||||
::testing::ValuesIn(kCpuUsedVectors),
|
||||
::testing::ValuesIn(kMVTestModes));
|
||||
} // namespace
|
||||
@@ -16,7 +16,9 @@
|
||||
|
||||
#include "./vpx_config.h"
|
||||
#include "./vpx_dsp_rtcd.h"
|
||||
#include "./vp9_rtcd.h"
|
||||
#include "test/acm_random.h"
|
||||
#include "test/buffer.h"
|
||||
#include "test/clear_system_state.h"
|
||||
#include "test/register_state_check.h"
|
||||
#include "test/util.h"
|
||||
@@ -24,11 +26,12 @@
|
||||
#include "vp9/common/vp9_scan.h"
|
||||
#include "vpx/vpx_codec.h"
|
||||
#include "vpx/vpx_integer.h"
|
||||
#include "vpx_ports/vpx_timer.h"
|
||||
|
||||
using libvpx_test::ACMRandom;
|
||||
using libvpx_test::Buffer;
|
||||
|
||||
namespace {
|
||||
#if CONFIG_VP9_HIGHBITDEPTH
|
||||
const int number_of_iterations = 100;
|
||||
|
||||
typedef void (*QuantizeFunc)(const tran_low_t *coeff, intptr_t count,
|
||||
@@ -38,307 +41,393 @@ typedef void (*QuantizeFunc)(const tran_low_t *coeff, intptr_t count,
|
||||
tran_low_t *dqcoeff, const int16_t *dequant,
|
||||
uint16_t *eob, const int16_t *scan,
|
||||
const int16_t *iscan);
|
||||
typedef std::tr1::tuple<QuantizeFunc, QuantizeFunc, vpx_bit_depth_t>
|
||||
typedef std::tr1::tuple<QuantizeFunc, QuantizeFunc, vpx_bit_depth_t,
|
||||
int /*max_size*/>
|
||||
QuantizeParam;
|
||||
|
||||
class VP9QuantizeTest : public ::testing::TestWithParam<QuantizeParam> {
|
||||
// Wrapper for FP version which does not use zbin or quant_shift.
|
||||
typedef void (*QuantizeFPFunc)(const tran_low_t *coeff, intptr_t count,
|
||||
int skip_block, const int16_t *round,
|
||||
const int16_t *quant, tran_low_t *qcoeff,
|
||||
tran_low_t *dqcoeff, const int16_t *dequant,
|
||||
uint16_t *eob, const int16_t *scan,
|
||||
const int16_t *iscan);
|
||||
|
||||
template <QuantizeFPFunc fn>
|
||||
void QuantFPWrapper(const tran_low_t *coeff, intptr_t count, int skip_block,
|
||||
const int16_t *zbin, const int16_t *round,
|
||||
const int16_t *quant, const int16_t *quant_shift,
|
||||
tran_low_t *qcoeff, tran_low_t *dqcoeff,
|
||||
const int16_t *dequant, uint16_t *eob, const int16_t *scan,
|
||||
const int16_t *iscan) {
|
||||
(void)zbin;
|
||||
(void)quant_shift;
|
||||
|
||||
fn(coeff, count, skip_block, round, quant, qcoeff, dqcoeff, dequant, eob,
|
||||
scan, iscan);
|
||||
}
|
||||
|
||||
class VP9QuantizeBase {
|
||||
public:
|
||||
virtual ~VP9QuantizeTest() {}
|
||||
virtual void SetUp() {
|
||||
quantize_op_ = GET_PARAM(0);
|
||||
ref_quantize_op_ = GET_PARAM(1);
|
||||
bit_depth_ = GET_PARAM(2);
|
||||
mask_ = (1 << bit_depth_) - 1;
|
||||
VP9QuantizeBase(vpx_bit_depth_t bit_depth, int max_size)
|
||||
: bit_depth_(bit_depth), max_size_(max_size) {
|
||||
max_value_ = (1 << bit_depth_) - 1;
|
||||
zbin_ptr_ =
|
||||
reinterpret_cast<int16_t *>(vpx_memalign(16, 8 * sizeof(*zbin_ptr_)));
|
||||
round_ptr_ =
|
||||
reinterpret_cast<int16_t *>(vpx_memalign(16, 8 * sizeof(*round_ptr_)));
|
||||
quant_ptr_ =
|
||||
reinterpret_cast<int16_t *>(vpx_memalign(16, 8 * sizeof(*quant_ptr_)));
|
||||
quant_shift_ptr_ = reinterpret_cast<int16_t *>(
|
||||
vpx_memalign(16, 8 * sizeof(*quant_shift_ptr_)));
|
||||
dequant_ptr_ = reinterpret_cast<int16_t *>(
|
||||
vpx_memalign(16, 8 * sizeof(*dequant_ptr_)));
|
||||
}
|
||||
|
||||
virtual void TearDown() { libvpx_test::ClearSystemState(); }
|
||||
|
||||
protected:
|
||||
vpx_bit_depth_t bit_depth_;
|
||||
int mask_;
|
||||
QuantizeFunc quantize_op_;
|
||||
QuantizeFunc ref_quantize_op_;
|
||||
};
|
||||
|
||||
class VP9Quantize32Test : public ::testing::TestWithParam<QuantizeParam> {
|
||||
public:
|
||||
virtual ~VP9Quantize32Test() {}
|
||||
virtual void SetUp() {
|
||||
quantize_op_ = GET_PARAM(0);
|
||||
ref_quantize_op_ = GET_PARAM(1);
|
||||
bit_depth_ = GET_PARAM(2);
|
||||
mask_ = (1 << bit_depth_) - 1;
|
||||
~VP9QuantizeBase() {
|
||||
vpx_free(zbin_ptr_);
|
||||
vpx_free(round_ptr_);
|
||||
vpx_free(quant_ptr_);
|
||||
vpx_free(quant_shift_ptr_);
|
||||
vpx_free(dequant_ptr_);
|
||||
zbin_ptr_ = NULL;
|
||||
round_ptr_ = NULL;
|
||||
quant_ptr_ = NULL;
|
||||
quant_shift_ptr_ = NULL;
|
||||
dequant_ptr_ = NULL;
|
||||
libvpx_test::ClearSystemState();
|
||||
}
|
||||
|
||||
virtual void TearDown() { libvpx_test::ClearSystemState(); }
|
||||
protected:
|
||||
int16_t *zbin_ptr_;
|
||||
int16_t *round_ptr_;
|
||||
int16_t *quant_ptr_;
|
||||
int16_t *quant_shift_ptr_;
|
||||
int16_t *dequant_ptr_;
|
||||
const vpx_bit_depth_t bit_depth_;
|
||||
int max_value_;
|
||||
const int max_size_;
|
||||
};
|
||||
|
||||
class VP9QuantizeTest : public VP9QuantizeBase,
|
||||
public ::testing::TestWithParam<QuantizeParam> {
|
||||
public:
|
||||
VP9QuantizeTest()
|
||||
: VP9QuantizeBase(GET_PARAM(2), GET_PARAM(3)), quantize_op_(GET_PARAM(0)),
|
||||
ref_quantize_op_(GET_PARAM(1)) {}
|
||||
|
||||
protected:
|
||||
vpx_bit_depth_t bit_depth_;
|
||||
int mask_;
|
||||
QuantizeFunc quantize_op_;
|
||||
QuantizeFunc ref_quantize_op_;
|
||||
const QuantizeFunc quantize_op_;
|
||||
const QuantizeFunc ref_quantize_op_;
|
||||
};
|
||||
|
||||
void GenerateHelperArrays(ACMRandom *rnd, int16_t *zbin, int16_t *round,
|
||||
int16_t *quant, int16_t *quant_shift,
|
||||
int16_t *dequant) {
|
||||
for (int j = 0; j < 2; j++) {
|
||||
// Values determined by deconstructing vp9_init_quantizer().
|
||||
// zbin may be up to 1143 for 8 and 10 bit Y values, or 1200 for 12 bit Y
|
||||
// values or U/V values of any bit depth. This is because y_delta is not
|
||||
// factored into the vp9_ac_quant() call.
|
||||
zbin[j] = rnd->RandRange(1200);
|
||||
// round may be up to 685 for Y values or 914 for U/V.
|
||||
round[j] = rnd->RandRange(914);
|
||||
// quant ranges from 1 to -32703
|
||||
quant[j] = static_cast<int>(rnd->RandRange(32704)) - 32703;
|
||||
// quant_shift goes up to 1 << 16.
|
||||
quant_shift[j] = rnd->RandRange(16384);
|
||||
// dequant maxes out at 1828 for all cases.
|
||||
dequant[j] = rnd->RandRange(1828);
|
||||
}
|
||||
for (int j = 2; j < 8; j++) {
|
||||
zbin[j] = zbin[1];
|
||||
round[j] = round[1];
|
||||
quant[j] = quant[1];
|
||||
quant_shift[j] = quant_shift[1];
|
||||
dequant[j] = dequant[1];
|
||||
}
|
||||
}
|
||||
|
||||
TEST_P(VP9QuantizeTest, OperationCheck) {
|
||||
ACMRandom rnd(ACMRandom::DeterministicSeed());
|
||||
DECLARE_ALIGNED(16, tran_low_t, coeff_ptr[256]);
|
||||
DECLARE_ALIGNED(16, int16_t, zbin_ptr[2]);
|
||||
DECLARE_ALIGNED(16, int16_t, round_ptr[2]);
|
||||
DECLARE_ALIGNED(16, int16_t, quant_ptr[2]);
|
||||
DECLARE_ALIGNED(16, int16_t, quant_shift_ptr[2]);
|
||||
DECLARE_ALIGNED(16, tran_low_t, qcoeff_ptr[256]);
|
||||
DECLARE_ALIGNED(16, tran_low_t, dqcoeff_ptr[256]);
|
||||
DECLARE_ALIGNED(16, tran_low_t, ref_qcoeff_ptr[256]);
|
||||
DECLARE_ALIGNED(16, tran_low_t, ref_dqcoeff_ptr[256]);
|
||||
DECLARE_ALIGNED(16, int16_t, dequant_ptr[2]);
|
||||
DECLARE_ALIGNED(16, uint16_t, eob_ptr[1]);
|
||||
DECLARE_ALIGNED(16, uint16_t, ref_eob_ptr[1]);
|
||||
int err_count_total = 0;
|
||||
int first_failure = -1;
|
||||
for (int i = 0; i < number_of_iterations; ++i) {
|
||||
const int skip_block = i == 0;
|
||||
const TX_SIZE sz = (TX_SIZE)(i % 3); // TX_4X4, TX_8X8 TX_16X16
|
||||
const TX_TYPE tx_type = (TX_TYPE)((i >> 2) % 3);
|
||||
const scan_order *scan_order = &vp9_scan_orders[sz][tx_type];
|
||||
const int count = (4 << sz) * (4 << sz); // 16, 64, 256
|
||||
int err_count = 0;
|
||||
*eob_ptr = rnd.Rand16();
|
||||
*ref_eob_ptr = *eob_ptr;
|
||||
for (int j = 0; j < count; j++) {
|
||||
coeff_ptr[j] = rnd.Rand16() & mask_;
|
||||
}
|
||||
for (int j = 0; j < 2; j++) {
|
||||
zbin_ptr[j] = rnd.Rand16() & mask_;
|
||||
round_ptr[j] = rnd.Rand16();
|
||||
quant_ptr[j] = rnd.Rand16();
|
||||
quant_shift_ptr[j] = rnd.Rand16();
|
||||
dequant_ptr[j] = rnd.Rand16();
|
||||
}
|
||||
ref_quantize_op_(coeff_ptr, count, skip_block, zbin_ptr, round_ptr,
|
||||
quant_ptr, quant_shift_ptr, ref_qcoeff_ptr,
|
||||
ref_dqcoeff_ptr, dequant_ptr, ref_eob_ptr,
|
||||
scan_order->scan, scan_order->iscan);
|
||||
ASM_REGISTER_STATE_CHECK(quantize_op_(
|
||||
coeff_ptr, count, skip_block, zbin_ptr, round_ptr, quant_ptr,
|
||||
quant_shift_ptr, qcoeff_ptr, dqcoeff_ptr, dequant_ptr, eob_ptr,
|
||||
scan_order->scan, scan_order->iscan));
|
||||
for (int j = 0; j < sz; ++j) {
|
||||
err_count += (ref_qcoeff_ptr[j] != qcoeff_ptr[j]) |
|
||||
(ref_dqcoeff_ptr[j] != dqcoeff_ptr[j]);
|
||||
}
|
||||
err_count += (*ref_eob_ptr != *eob_ptr);
|
||||
if (err_count && !err_count_total) {
|
||||
first_failure = i;
|
||||
}
|
||||
err_count_total += err_count;
|
||||
}
|
||||
EXPECT_EQ(0, err_count_total)
|
||||
<< "Error: Quantization Test, C output doesn't match SSE2 output. "
|
||||
<< "First failed at test case " << first_failure;
|
||||
}
|
||||
Buffer<tran_low_t> coeff = Buffer<tran_low_t>(max_size_, max_size_, 0, 16);
|
||||
ASSERT_TRUE(coeff.Init());
|
||||
Buffer<tran_low_t> qcoeff = Buffer<tran_low_t>(max_size_, max_size_, 0, 32);
|
||||
ASSERT_TRUE(qcoeff.Init());
|
||||
Buffer<tran_low_t> dqcoeff = Buffer<tran_low_t>(max_size_, max_size_, 0, 32);
|
||||
ASSERT_TRUE(dqcoeff.Init());
|
||||
Buffer<tran_low_t> ref_qcoeff =
|
||||
Buffer<tran_low_t>(max_size_, max_size_, 0, 32);
|
||||
ASSERT_TRUE(ref_qcoeff.Init());
|
||||
Buffer<tran_low_t> ref_dqcoeff =
|
||||
Buffer<tran_low_t>(max_size_, max_size_, 0, 32);
|
||||
ASSERT_TRUE(ref_dqcoeff.Init());
|
||||
uint16_t eob, ref_eob;
|
||||
|
||||
TEST_P(VP9Quantize32Test, OperationCheck) {
|
||||
ACMRandom rnd(ACMRandom::DeterministicSeed());
|
||||
DECLARE_ALIGNED(16, tran_low_t, coeff_ptr[1024]);
|
||||
DECLARE_ALIGNED(16, int16_t, zbin_ptr[2]);
|
||||
DECLARE_ALIGNED(16, int16_t, round_ptr[2]);
|
||||
DECLARE_ALIGNED(16, int16_t, quant_ptr[2]);
|
||||
DECLARE_ALIGNED(16, int16_t, quant_shift_ptr[2]);
|
||||
DECLARE_ALIGNED(16, tran_low_t, qcoeff_ptr[1024]);
|
||||
DECLARE_ALIGNED(16, tran_low_t, dqcoeff_ptr[1024]);
|
||||
DECLARE_ALIGNED(16, tran_low_t, ref_qcoeff_ptr[1024]);
|
||||
DECLARE_ALIGNED(16, tran_low_t, ref_dqcoeff_ptr[1024]);
|
||||
DECLARE_ALIGNED(16, int16_t, dequant_ptr[2]);
|
||||
DECLARE_ALIGNED(16, uint16_t, eob_ptr[1]);
|
||||
DECLARE_ALIGNED(16, uint16_t, ref_eob_ptr[1]);
|
||||
int err_count_total = 0;
|
||||
int first_failure = -1;
|
||||
for (int i = 0; i < number_of_iterations; ++i) {
|
||||
const int skip_block = i == 0;
|
||||
const TX_SIZE sz = TX_32X32;
|
||||
const TX_TYPE tx_type = (TX_TYPE)(i % 4);
|
||||
// Test skip block for the first three iterations to catch all the different
|
||||
// sizes.
|
||||
const int skip_block = 0;
|
||||
TX_SIZE sz;
|
||||
if (max_size_ == 16) {
|
||||
sz = static_cast<TX_SIZE>(i % 3); // TX_4X4, TX_8X8 TX_16X16
|
||||
} else {
|
||||
sz = TX_32X32;
|
||||
}
|
||||
const TX_TYPE tx_type = static_cast<TX_TYPE>((i >> 2) % 3);
|
||||
const scan_order *scan_order = &vp9_scan_orders[sz][tx_type];
|
||||
const int count = (4 << sz) * (4 << sz); // 1024
|
||||
int err_count = 0;
|
||||
*eob_ptr = rnd.Rand16();
|
||||
*ref_eob_ptr = *eob_ptr;
|
||||
for (int j = 0; j < count; j++) {
|
||||
coeff_ptr[j] = rnd.Rand16() & mask_;
|
||||
const int count = (4 << sz) * (4 << sz);
|
||||
coeff.Set(&rnd, -max_value_, max_value_);
|
||||
GenerateHelperArrays(&rnd, zbin_ptr_, round_ptr_, quant_ptr_,
|
||||
quant_shift_ptr_, dequant_ptr_);
|
||||
|
||||
ref_quantize_op_(coeff.TopLeftPixel(), count, skip_block, zbin_ptr_,
|
||||
round_ptr_, quant_ptr_, quant_shift_ptr_,
|
||||
ref_qcoeff.TopLeftPixel(), ref_dqcoeff.TopLeftPixel(),
|
||||
dequant_ptr_, &ref_eob, scan_order->scan,
|
||||
scan_order->iscan);
|
||||
|
||||
ASM_REGISTER_STATE_CHECK(
|
||||
quantize_op_(coeff.TopLeftPixel(), count, skip_block, zbin_ptr_,
|
||||
round_ptr_, quant_ptr_, quant_shift_ptr_,
|
||||
qcoeff.TopLeftPixel(), dqcoeff.TopLeftPixel(),
|
||||
dequant_ptr_, &eob, scan_order->scan, scan_order->iscan));
|
||||
|
||||
EXPECT_TRUE(qcoeff.CheckValues(ref_qcoeff));
|
||||
EXPECT_TRUE(dqcoeff.CheckValues(ref_dqcoeff));
|
||||
|
||||
EXPECT_EQ(eob, ref_eob);
|
||||
|
||||
if (HasFailure()) {
|
||||
printf("Failure on iteration %d.\n", i);
|
||||
qcoeff.PrintDifference(ref_qcoeff);
|
||||
dqcoeff.PrintDifference(ref_dqcoeff);
|
||||
return;
|
||||
}
|
||||
for (int j = 0; j < 2; j++) {
|
||||
zbin_ptr[j] = rnd.Rand16() & mask_;
|
||||
round_ptr[j] = rnd.Rand16();
|
||||
quant_ptr[j] = rnd.Rand16();
|
||||
quant_shift_ptr[j] = rnd.Rand16();
|
||||
dequant_ptr[j] = rnd.Rand16();
|
||||
}
|
||||
ref_quantize_op_(coeff_ptr, count, skip_block, zbin_ptr, round_ptr,
|
||||
quant_ptr, quant_shift_ptr, ref_qcoeff_ptr,
|
||||
ref_dqcoeff_ptr, dequant_ptr, ref_eob_ptr,
|
||||
scan_order->scan, scan_order->iscan);
|
||||
ASM_REGISTER_STATE_CHECK(quantize_op_(
|
||||
coeff_ptr, count, skip_block, zbin_ptr, round_ptr, quant_ptr,
|
||||
quant_shift_ptr, qcoeff_ptr, dqcoeff_ptr, dequant_ptr, eob_ptr,
|
||||
scan_order->scan, scan_order->iscan));
|
||||
for (int j = 0; j < sz; ++j) {
|
||||
err_count += (ref_qcoeff_ptr[j] != qcoeff_ptr[j]) |
|
||||
(ref_dqcoeff_ptr[j] != dqcoeff_ptr[j]);
|
||||
}
|
||||
err_count += (*ref_eob_ptr != *eob_ptr);
|
||||
if (err_count && !err_count_total) {
|
||||
first_failure = i;
|
||||
}
|
||||
err_count_total += err_count;
|
||||
}
|
||||
EXPECT_EQ(0, err_count_total)
|
||||
<< "Error: Quantization Test, C output doesn't match SSE2 output. "
|
||||
<< "First failed at test case " << first_failure;
|
||||
}
|
||||
|
||||
TEST_P(VP9QuantizeTest, EOBCheck) {
|
||||
ACMRandom rnd(ACMRandom::DeterministicSeed());
|
||||
DECLARE_ALIGNED(16, tran_low_t, coeff_ptr[256]);
|
||||
DECLARE_ALIGNED(16, int16_t, zbin_ptr[2]);
|
||||
DECLARE_ALIGNED(16, int16_t, round_ptr[2]);
|
||||
DECLARE_ALIGNED(16, int16_t, quant_ptr[2]);
|
||||
DECLARE_ALIGNED(16, int16_t, quant_shift_ptr[2]);
|
||||
DECLARE_ALIGNED(16, tran_low_t, qcoeff_ptr[256]);
|
||||
DECLARE_ALIGNED(16, tran_low_t, dqcoeff_ptr[256]);
|
||||
DECLARE_ALIGNED(16, tran_low_t, ref_qcoeff_ptr[256]);
|
||||
DECLARE_ALIGNED(16, tran_low_t, ref_dqcoeff_ptr[256]);
|
||||
DECLARE_ALIGNED(16, int16_t, dequant_ptr[2]);
|
||||
DECLARE_ALIGNED(16, uint16_t, eob_ptr[1]);
|
||||
DECLARE_ALIGNED(16, uint16_t, ref_eob_ptr[1]);
|
||||
int err_count_total = 0;
|
||||
int first_failure = -1;
|
||||
Buffer<tran_low_t> coeff = Buffer<tran_low_t>(max_size_, max_size_, 0, 16);
|
||||
ASSERT_TRUE(coeff.Init());
|
||||
Buffer<tran_low_t> qcoeff = Buffer<tran_low_t>(max_size_, max_size_, 0, 32);
|
||||
ASSERT_TRUE(qcoeff.Init());
|
||||
Buffer<tran_low_t> dqcoeff = Buffer<tran_low_t>(max_size_, max_size_, 0, 32);
|
||||
ASSERT_TRUE(dqcoeff.Init());
|
||||
Buffer<tran_low_t> ref_qcoeff =
|
||||
Buffer<tran_low_t>(max_size_, max_size_, 0, 32);
|
||||
ASSERT_TRUE(ref_qcoeff.Init());
|
||||
Buffer<tran_low_t> ref_dqcoeff =
|
||||
Buffer<tran_low_t>(max_size_, max_size_, 0, 32);
|
||||
ASSERT_TRUE(ref_dqcoeff.Init());
|
||||
uint16_t eob, ref_eob;
|
||||
|
||||
for (int i = 0; i < number_of_iterations; ++i) {
|
||||
int skip_block = i == 0;
|
||||
TX_SIZE sz = (TX_SIZE)(i % 3); // TX_4X4, TX_8X8 TX_16X16
|
||||
TX_TYPE tx_type = (TX_TYPE)((i >> 2) % 3);
|
||||
const int skip_block = 0;
|
||||
TX_SIZE sz;
|
||||
if (max_size_ == 16) {
|
||||
sz = static_cast<TX_SIZE>(i % 3); // TX_4X4, TX_8X8 TX_16X16
|
||||
} else {
|
||||
sz = TX_32X32;
|
||||
}
|
||||
const TX_TYPE tx_type = static_cast<TX_TYPE>((i >> 2) % 3);
|
||||
const scan_order *scan_order = &vp9_scan_orders[sz][tx_type];
|
||||
int count = (4 << sz) * (4 << sz); // 16, 64, 256
|
||||
int err_count = 0;
|
||||
*eob_ptr = rnd.Rand16();
|
||||
*ref_eob_ptr = *eob_ptr;
|
||||
int count = (4 << sz) * (4 << sz);
|
||||
// Two random entries
|
||||
for (int j = 0; j < count; j++) {
|
||||
coeff_ptr[j] = 0;
|
||||
}
|
||||
coeff_ptr[rnd(count)] = rnd.Rand16() & mask_;
|
||||
coeff_ptr[rnd(count)] = rnd.Rand16() & mask_;
|
||||
for (int j = 0; j < 2; j++) {
|
||||
zbin_ptr[j] = rnd.Rand16() & mask_;
|
||||
round_ptr[j] = rnd.Rand16();
|
||||
quant_ptr[j] = rnd.Rand16();
|
||||
quant_shift_ptr[j] = rnd.Rand16();
|
||||
dequant_ptr[j] = rnd.Rand16();
|
||||
}
|
||||
coeff.Set(0);
|
||||
coeff.TopLeftPixel()[rnd(count)] =
|
||||
static_cast<int>(rnd.RandRange(max_value_ * 2)) - max_value_;
|
||||
coeff.TopLeftPixel()[rnd(count)] =
|
||||
static_cast<int>(rnd.RandRange(max_value_ * 2)) - max_value_;
|
||||
GenerateHelperArrays(&rnd, zbin_ptr_, round_ptr_, quant_ptr_,
|
||||
quant_shift_ptr_, dequant_ptr_);
|
||||
|
||||
ref_quantize_op_(coeff_ptr, count, skip_block, zbin_ptr, round_ptr,
|
||||
quant_ptr, quant_shift_ptr, ref_qcoeff_ptr,
|
||||
ref_dqcoeff_ptr, dequant_ptr, ref_eob_ptr,
|
||||
scan_order->scan, scan_order->iscan);
|
||||
ASM_REGISTER_STATE_CHECK(quantize_op_(
|
||||
coeff_ptr, count, skip_block, zbin_ptr, round_ptr, quant_ptr,
|
||||
quant_shift_ptr, qcoeff_ptr, dqcoeff_ptr, dequant_ptr, eob_ptr,
|
||||
scan_order->scan, scan_order->iscan));
|
||||
ref_quantize_op_(coeff.TopLeftPixel(), count, skip_block, zbin_ptr_,
|
||||
round_ptr_, quant_ptr_, quant_shift_ptr_,
|
||||
ref_qcoeff.TopLeftPixel(), ref_dqcoeff.TopLeftPixel(),
|
||||
dequant_ptr_, &ref_eob, scan_order->scan,
|
||||
scan_order->iscan);
|
||||
|
||||
for (int j = 0; j < sz; ++j) {
|
||||
err_count += (ref_qcoeff_ptr[j] != qcoeff_ptr[j]) |
|
||||
(ref_dqcoeff_ptr[j] != dqcoeff_ptr[j]);
|
||||
ASM_REGISTER_STATE_CHECK(
|
||||
quantize_op_(coeff.TopLeftPixel(), count, skip_block, zbin_ptr_,
|
||||
round_ptr_, quant_ptr_, quant_shift_ptr_,
|
||||
qcoeff.TopLeftPixel(), dqcoeff.TopLeftPixel(),
|
||||
dequant_ptr_, &eob, scan_order->scan, scan_order->iscan));
|
||||
|
||||
EXPECT_TRUE(qcoeff.CheckValues(ref_qcoeff));
|
||||
EXPECT_TRUE(dqcoeff.CheckValues(ref_dqcoeff));
|
||||
|
||||
EXPECT_EQ(eob, ref_eob);
|
||||
|
||||
if (HasFailure()) {
|
||||
printf("Failure on iteration %d.\n", i);
|
||||
qcoeff.PrintDifference(ref_qcoeff);
|
||||
dqcoeff.PrintDifference(ref_dqcoeff);
|
||||
return;
|
||||
}
|
||||
err_count += (*ref_eob_ptr != *eob_ptr);
|
||||
if (err_count && !err_count_total) {
|
||||
first_failure = i;
|
||||
}
|
||||
err_count_total += err_count;
|
||||
}
|
||||
EXPECT_EQ(0, err_count_total)
|
||||
<< "Error: Quantization Test, C output doesn't match SSE2 output. "
|
||||
<< "First failed at test case " << first_failure;
|
||||
}
|
||||
|
||||
TEST_P(VP9Quantize32Test, EOBCheck) {
|
||||
TEST_P(VP9QuantizeTest, DISABLED_Speed) {
|
||||
ACMRandom rnd(ACMRandom::DeterministicSeed());
|
||||
DECLARE_ALIGNED(16, tran_low_t, coeff_ptr[1024]);
|
||||
DECLARE_ALIGNED(16, int16_t, zbin_ptr[2]);
|
||||
DECLARE_ALIGNED(16, int16_t, round_ptr[2]);
|
||||
DECLARE_ALIGNED(16, int16_t, quant_ptr[2]);
|
||||
DECLARE_ALIGNED(16, int16_t, quant_shift_ptr[2]);
|
||||
DECLARE_ALIGNED(16, tran_low_t, qcoeff_ptr[1024]);
|
||||
DECLARE_ALIGNED(16, tran_low_t, dqcoeff_ptr[1024]);
|
||||
DECLARE_ALIGNED(16, tran_low_t, ref_qcoeff_ptr[1024]);
|
||||
DECLARE_ALIGNED(16, tran_low_t, ref_dqcoeff_ptr[1024]);
|
||||
DECLARE_ALIGNED(16, int16_t, dequant_ptr[2]);
|
||||
DECLARE_ALIGNED(16, uint16_t, eob_ptr[1]);
|
||||
DECLARE_ALIGNED(16, uint16_t, ref_eob_ptr[1]);
|
||||
int err_count_total = 0;
|
||||
int first_failure = -1;
|
||||
for (int i = 0; i < number_of_iterations; ++i) {
|
||||
int skip_block = i == 0;
|
||||
TX_SIZE sz = TX_32X32;
|
||||
TX_TYPE tx_type = (TX_TYPE)(i % 4);
|
||||
const scan_order *scan_order = &vp9_scan_orders[sz][tx_type];
|
||||
int count = (4 << sz) * (4 << sz); // 1024
|
||||
int err_count = 0;
|
||||
*eob_ptr = rnd.Rand16();
|
||||
*ref_eob_ptr = *eob_ptr;
|
||||
for (int j = 0; j < count; j++) {
|
||||
coeff_ptr[j] = 0;
|
||||
}
|
||||
// Two random entries
|
||||
coeff_ptr[rnd(count)] = rnd.Rand16() & mask_;
|
||||
coeff_ptr[rnd(count)] = rnd.Rand16() & mask_;
|
||||
for (int j = 0; j < 2; j++) {
|
||||
zbin_ptr[j] = rnd.Rand16() & mask_;
|
||||
round_ptr[j] = rnd.Rand16();
|
||||
quant_ptr[j] = rnd.Rand16();
|
||||
quant_shift_ptr[j] = rnd.Rand16();
|
||||
dequant_ptr[j] = rnd.Rand16();
|
||||
}
|
||||
Buffer<tran_low_t> coeff = Buffer<tran_low_t>(max_size_, max_size_, 0, 16);
|
||||
ASSERT_TRUE(coeff.Init());
|
||||
Buffer<tran_low_t> qcoeff = Buffer<tran_low_t>(max_size_, max_size_, 0, 32);
|
||||
ASSERT_TRUE(qcoeff.Init());
|
||||
Buffer<tran_low_t> dqcoeff = Buffer<tran_low_t>(max_size_, max_size_, 0, 32);
|
||||
ASSERT_TRUE(dqcoeff.Init());
|
||||
uint16_t eob;
|
||||
TX_SIZE starting_sz, ending_sz;
|
||||
|
||||
ref_quantize_op_(coeff_ptr, count, skip_block, zbin_ptr, round_ptr,
|
||||
quant_ptr, quant_shift_ptr, ref_qcoeff_ptr,
|
||||
ref_dqcoeff_ptr, dequant_ptr, ref_eob_ptr,
|
||||
scan_order->scan, scan_order->iscan);
|
||||
ASM_REGISTER_STATE_CHECK(quantize_op_(
|
||||
coeff_ptr, count, skip_block, zbin_ptr, round_ptr, quant_ptr,
|
||||
quant_shift_ptr, qcoeff_ptr, dqcoeff_ptr, dequant_ptr, eob_ptr,
|
||||
scan_order->scan, scan_order->iscan));
|
||||
|
||||
for (int j = 0; j < sz; ++j) {
|
||||
err_count += (ref_qcoeff_ptr[j] != qcoeff_ptr[j]) |
|
||||
(ref_dqcoeff_ptr[j] != dqcoeff_ptr[j]);
|
||||
}
|
||||
err_count += (*ref_eob_ptr != *eob_ptr);
|
||||
if (err_count && !err_count_total) {
|
||||
first_failure = i;
|
||||
}
|
||||
err_count_total += err_count;
|
||||
if (max_size_ == 16) {
|
||||
starting_sz = TX_4X4;
|
||||
ending_sz = TX_16X16;
|
||||
} else {
|
||||
starting_sz = TX_32X32;
|
||||
ending_sz = TX_32X32;
|
||||
}
|
||||
|
||||
for (TX_SIZE sz = starting_sz; sz <= ending_sz; ++sz) {
|
||||
// zbin > coeff, zbin < coeff.
|
||||
for (int i = 0; i < 2; ++i) {
|
||||
const int skip_block = 0;
|
||||
// TX_TYPE defines the scan order. That is not relevant to the speed test.
|
||||
// Pick the first one.
|
||||
const TX_TYPE tx_type = DCT_DCT;
|
||||
const scan_order *scan_order = &vp9_scan_orders[sz][tx_type];
|
||||
const int count = (4 << sz) * (4 << sz);
|
||||
|
||||
GenerateHelperArrays(&rnd, zbin_ptr_, round_ptr_, quant_ptr_,
|
||||
quant_shift_ptr_, dequant_ptr_);
|
||||
|
||||
if (i == 0) {
|
||||
// When |coeff values| are less than zbin the results are 0.
|
||||
int threshold = 100;
|
||||
if (max_size_ == 32) {
|
||||
// For 32x32, the threshold is halved. Double it to keep the values
|
||||
// from clearing it.
|
||||
threshold = 200;
|
||||
}
|
||||
for (int j = 0; j < 8; ++j) zbin_ptr_[j] = threshold;
|
||||
coeff.Set(&rnd, -99, 99);
|
||||
} else if (i == 1) {
|
||||
for (int j = 0; j < 8; ++j) zbin_ptr_[j] = 50;
|
||||
coeff.Set(&rnd, -500, 500);
|
||||
}
|
||||
|
||||
vpx_usec_timer timer;
|
||||
vpx_usec_timer_start(&timer);
|
||||
for (int j = 0; j < 100000000 / count; ++j) {
|
||||
quantize_op_(coeff.TopLeftPixel(), count, skip_block, zbin_ptr_,
|
||||
round_ptr_, quant_ptr_, quant_shift_ptr_,
|
||||
qcoeff.TopLeftPixel(), dqcoeff.TopLeftPixel(),
|
||||
dequant_ptr_, &eob, scan_order->scan, scan_order->iscan);
|
||||
}
|
||||
vpx_usec_timer_mark(&timer);
|
||||
const int elapsed_time = static_cast<int>(vpx_usec_timer_elapsed(&timer));
|
||||
if (i == 0) printf("Bypass calculations.\n");
|
||||
if (i == 1) printf("Full calculations.\n");
|
||||
printf("Quantize %dx%d time: %5d ms\n", 4 << sz, 4 << sz,
|
||||
elapsed_time / 1000);
|
||||
}
|
||||
printf("\n");
|
||||
}
|
||||
EXPECT_EQ(0, err_count_total)
|
||||
<< "Error: Quantization Test, C output doesn't match SSE2 output. "
|
||||
<< "First failed at test case " << first_failure;
|
||||
}
|
||||
|
||||
using std::tr1::make_tuple;
|
||||
|
||||
#if HAVE_SSE2
|
||||
#if CONFIG_VP9_HIGHBITDEPTH
|
||||
// TODO(johannkoenig): Fix vpx_quantize_b_sse2 in highbitdepth builds.
|
||||
// make_tuple(&vpx_quantize_b_sse2, &vpx_highbd_quantize_b_c, VPX_BITS_8),
|
||||
INSTANTIATE_TEST_CASE_P(
|
||||
SSE2, VP9QuantizeTest,
|
||||
::testing::Values(make_tuple(&vpx_highbd_quantize_b_sse2,
|
||||
&vpx_highbd_quantize_b_c, VPX_BITS_8),
|
||||
make_tuple(&vpx_highbd_quantize_b_sse2,
|
||||
&vpx_highbd_quantize_b_c, VPX_BITS_10),
|
||||
make_tuple(&vpx_highbd_quantize_b_sse2,
|
||||
&vpx_highbd_quantize_b_c, VPX_BITS_12)));
|
||||
INSTANTIATE_TEST_CASE_P(
|
||||
SSE2, VP9Quantize32Test,
|
||||
::testing::Values(make_tuple(&vpx_highbd_quantize_b_32x32_sse2,
|
||||
&vpx_highbd_quantize_b_32x32_c, VPX_BITS_8),
|
||||
make_tuple(&vpx_highbd_quantize_b_32x32_sse2,
|
||||
&vpx_highbd_quantize_b_32x32_c, VPX_BITS_10),
|
||||
make_tuple(&vpx_highbd_quantize_b_32x32_sse2,
|
||||
&vpx_highbd_quantize_b_32x32_c, VPX_BITS_12)));
|
||||
#endif // HAVE_SSE2
|
||||
::testing::Values(
|
||||
make_tuple(&vpx_highbd_quantize_b_sse2, &vpx_highbd_quantize_b_c,
|
||||
VPX_BITS_8, 16),
|
||||
make_tuple(&vpx_highbd_quantize_b_sse2, &vpx_highbd_quantize_b_c,
|
||||
VPX_BITS_10, 16),
|
||||
make_tuple(&vpx_highbd_quantize_b_sse2, &vpx_highbd_quantize_b_c,
|
||||
VPX_BITS_12, 16),
|
||||
make_tuple(&vpx_highbd_quantize_b_32x32_sse2,
|
||||
&vpx_highbd_quantize_b_32x32_c, VPX_BITS_8, 32),
|
||||
make_tuple(&vpx_highbd_quantize_b_32x32_sse2,
|
||||
&vpx_highbd_quantize_b_32x32_c, VPX_BITS_10, 32),
|
||||
make_tuple(&vpx_highbd_quantize_b_32x32_sse2,
|
||||
&vpx_highbd_quantize_b_32x32_c, VPX_BITS_12, 32)));
|
||||
|
||||
#else
|
||||
INSTANTIATE_TEST_CASE_P(SSE2, VP9QuantizeTest,
|
||||
::testing::Values(make_tuple(&vpx_quantize_b_sse2,
|
||||
&vpx_quantize_b_c,
|
||||
VPX_BITS_8, 16)));
|
||||
#endif // CONFIG_VP9_HIGHBITDEPTH
|
||||
|
||||
INSTANTIATE_TEST_CASE_P(
|
||||
DISABLED_SSE2, VP9QuantizeTest,
|
||||
::testing::Values(make_tuple(&QuantFPWrapper<vp9_quantize_fp_sse2>,
|
||||
&QuantFPWrapper<vp9_quantize_fp_c>, VPX_BITS_8,
|
||||
16)));
|
||||
#endif // HAVE_SSE2
|
||||
|
||||
#if HAVE_SSSE3 && !CONFIG_VP9_HIGHBITDEPTH
|
||||
INSTANTIATE_TEST_CASE_P(SSSE3, VP9QuantizeTest,
|
||||
::testing::Values(make_tuple(&vpx_quantize_b_ssse3,
|
||||
&vpx_quantize_b_c,
|
||||
VPX_BITS_8, 16)));
|
||||
|
||||
#if ARCH_X86_64
|
||||
// TODO(johannkoenig): SSSE3 optimizations do not yet pass this test.
|
||||
INSTANTIATE_TEST_CASE_P(
|
||||
DISABLED_SSSE3, VP9QuantizeTest,
|
||||
::testing::Values(make_tuple(&vpx_quantize_b_32x32_ssse3,
|
||||
&vpx_quantize_b_32x32_c, VPX_BITS_8, 32),
|
||||
make_tuple(&QuantFPWrapper<vp9_quantize_fp_ssse3>,
|
||||
&QuantFPWrapper<vp9_quantize_fp_c>, VPX_BITS_8,
|
||||
16),
|
||||
make_tuple(&QuantFPWrapper<vp9_quantize_fp_32x32_ssse3>,
|
||||
&QuantFPWrapper<vp9_quantize_fp_32x32_c>,
|
||||
VPX_BITS_8, 32)));
|
||||
#endif // ARCH_X86_64
|
||||
#endif // HAVE_SSSE3 && !CONFIG_VP9_HIGHBITDEPTH
|
||||
|
||||
// TODO(johannkoenig): AVX optimizations do not yet pass the 32x32 test or
|
||||
// highbitdepth configurations.
|
||||
#if HAVE_AVX && !CONFIG_VP9_HIGHBITDEPTH
|
||||
INSTANTIATE_TEST_CASE_P(
|
||||
AVX, VP9QuantizeTest,
|
||||
::testing::Values(make_tuple(&vpx_quantize_b_avx, &vpx_quantize_b_c,
|
||||
VPX_BITS_8, 16),
|
||||
// Even though SSSE3 and AVX do not match the reference
|
||||
// code, we can keep them in sync with each other.
|
||||
make_tuple(&vpx_quantize_b_32x32_avx,
|
||||
&vpx_quantize_b_32x32_ssse3, VPX_BITS_8, 32)));
|
||||
#endif // HAVE_AVX && !CONFIG_VP9_HIGHBITDEPTH
|
||||
|
||||
// TODO(webm:1448): dqcoeff is not handled correctly in HBD builds.
|
||||
#if HAVE_NEON && !CONFIG_VP9_HIGHBITDEPTH
|
||||
INSTANTIATE_TEST_CASE_P(
|
||||
NEON, VP9QuantizeTest,
|
||||
::testing::Values(
|
||||
make_tuple(&vpx_quantize_b_neon, &vpx_quantize_b_c, VPX_BITS_8, 16),
|
||||
make_tuple(&vpx_quantize_b_32x32_neon, &vpx_quantize_b_32x32_c,
|
||||
VPX_BITS_8, 32),
|
||||
make_tuple(&QuantFPWrapper<vp9_quantize_fp_neon>,
|
||||
&QuantFPWrapper<vp9_quantize_fp_c>, VPX_BITS_8, 16),
|
||||
make_tuple(&QuantFPWrapper<vp9_quantize_fp_32x32_neon>,
|
||||
&QuantFPWrapper<vp9_quantize_fp_32x32_c>, VPX_BITS_8, 32)));
|
||||
#endif // HAVE_NEON && !CONFIG_VP9_HIGHBITDEPTH
|
||||
|
||||
// Only useful to compare "Speed" test results.
|
||||
INSTANTIATE_TEST_CASE_P(
|
||||
DISABLED_C, VP9QuantizeTest,
|
||||
::testing::Values(
|
||||
make_tuple(&vpx_quantize_b_c, &vpx_quantize_b_c, VPX_BITS_8, 16),
|
||||
make_tuple(&vpx_quantize_b_32x32_c, &vpx_quantize_b_32x32_c, VPX_BITS_8,
|
||||
32),
|
||||
make_tuple(&QuantFPWrapper<vp9_quantize_fp_c>,
|
||||
&QuantFPWrapper<vp9_quantize_fp_c>, VPX_BITS_8, 16),
|
||||
make_tuple(&QuantFPWrapper<vp9_quantize_fp_32x32_c>,
|
||||
&QuantFPWrapper<vp9_quantize_fp_32x32_c>, VPX_BITS_8, 32)));
|
||||
} // namespace
|
||||
|
||||
214
test/vp9_scale_test.cc
Normal file
214
test/vp9_scale_test.cc
Normal file
@@ -0,0 +1,214 @@
|
||||
/*
|
||||
* Copyright (c) 2017 The WebM project authors. All Rights Reserved.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license
|
||||
* that can be found in the LICENSE file in the root of the source
|
||||
* tree. An additional intellectual property rights grant can be found
|
||||
* in the file PATENTS. All contributing project authors may
|
||||
* be found in the AUTHORS file in the root of the source tree.
|
||||
*/
|
||||
|
||||
#include <assert.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "third_party/googletest/src/include/gtest/gtest.h"
|
||||
|
||||
#include "./vp9_rtcd.h"
|
||||
#include "./vpx_config.h"
|
||||
#include "./vpx_scale_rtcd.h"
|
||||
#include "test/clear_system_state.h"
|
||||
#include "test/register_state_check.h"
|
||||
#include "test/vpx_scale_test.h"
|
||||
#include "vpx_mem/vpx_mem.h"
|
||||
#include "vpx_ports/vpx_timer.h"
|
||||
#include "vpx_scale/yv12config.h"
|
||||
|
||||
namespace libvpx_test {
|
||||
|
||||
typedef void (*ScaleFrameFunc)(const YV12_BUFFER_CONFIG *src,
|
||||
YV12_BUFFER_CONFIG *dst,
|
||||
INTERP_FILTER filter_type, int phase_scaler);
|
||||
|
||||
class ScaleTest : public VpxScaleBase,
|
||||
public ::testing::TestWithParam<ScaleFrameFunc> {
|
||||
public:
|
||||
virtual ~ScaleTest() {}
|
||||
|
||||
protected:
|
||||
virtual void SetUp() { scale_fn_ = GetParam(); }
|
||||
|
||||
void ReferenceScaleFrame(INTERP_FILTER filter_type, int phase_scaler) {
|
||||
vp9_scale_and_extend_frame_c(&img_, &ref_img_, filter_type, phase_scaler);
|
||||
}
|
||||
|
||||
void ScaleFrame(INTERP_FILTER filter_type, int phase_scaler) {
|
||||
ASM_REGISTER_STATE_CHECK(
|
||||
scale_fn_(&img_, &dst_img_, filter_type, phase_scaler));
|
||||
}
|
||||
|
||||
void RunTest() {
|
||||
static const int kNumSizesToTest = 20;
|
||||
static const int kNumScaleFactorsToTest = 4;
|
||||
static const int kSizesToTest[] = {
|
||||
2, 4, 6, 8, 10, 12, 14, 16, 18, 20,
|
||||
22, 24, 26, 28, 30, 32, 34, 68, 128, 134
|
||||
};
|
||||
static const int kScaleFactors[] = { 1, 2, 3, 4 };
|
||||
for (INTERP_FILTER filter_type = 0; filter_type < 4; ++filter_type) {
|
||||
for (int phase_scaler = 0; phase_scaler < 16; ++phase_scaler) {
|
||||
for (int h = 0; h < kNumSizesToTest; ++h) {
|
||||
const int src_height = kSizesToTest[h];
|
||||
for (int w = 0; w < kNumSizesToTest; ++w) {
|
||||
const int src_width = kSizesToTest[w];
|
||||
for (int sf_up_idx = 0; sf_up_idx < kNumScaleFactorsToTest;
|
||||
++sf_up_idx) {
|
||||
const int sf_up = kScaleFactors[sf_up_idx];
|
||||
for (int sf_down_idx = 0; sf_down_idx < kNumScaleFactorsToTest;
|
||||
++sf_down_idx) {
|
||||
const int sf_down = kScaleFactors[sf_down_idx];
|
||||
const int dst_width = src_width * sf_up / sf_down;
|
||||
const int dst_height = src_height * sf_up / sf_down;
|
||||
if (sf_up == sf_down && sf_up != 1) {
|
||||
continue;
|
||||
}
|
||||
// I420 frame width and height must be even.
|
||||
if (!dst_width || !dst_height || dst_width & 1 ||
|
||||
dst_height & 1) {
|
||||
continue;
|
||||
}
|
||||
// vpx_convolve8_c() has restriction on the step which cannot
|
||||
// exceed 64 (ratio 1 to 4).
|
||||
if (src_width > 4 * dst_width || src_height > 4 * dst_height) {
|
||||
continue;
|
||||
}
|
||||
ASSERT_NO_FATAL_FAILURE(ResetScaleImages(
|
||||
src_width, src_height, dst_width, dst_height));
|
||||
ReferenceScaleFrame(filter_type, phase_scaler);
|
||||
ScaleFrame(filter_type, phase_scaler);
|
||||
if (memcmp(dst_img_.buffer_alloc, ref_img_.buffer_alloc,
|
||||
ref_img_.frame_size)) {
|
||||
printf(
|
||||
"filter_type = %d, phase_scaler = %d, src_width = %4d, "
|
||||
"src_height = %4d, dst_width = %4d, dst_height = %4d, "
|
||||
"scale factor = %d:%d\n",
|
||||
filter_type, phase_scaler, src_width, src_height,
|
||||
dst_width, dst_height, sf_down, sf_up);
|
||||
PrintDiff();
|
||||
}
|
||||
CompareImages(dst_img_);
|
||||
DeallocScaleImages();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void PrintDiffComponent(const uint8_t *const ref, const uint8_t *const opt,
|
||||
const int stride, const int width, const int height,
|
||||
const int plane_idx) const {
|
||||
for (int y = 0; y < height; y++) {
|
||||
for (int x = 0; x < width; x++) {
|
||||
if (ref[y * stride + x] != opt[y * stride + x]) {
|
||||
printf("Plane %d pixel[%d][%d] diff:%6d (ref),%6d (opt)\n", plane_idx,
|
||||
y, x, ref[y * stride + x], opt[y * stride + x]);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void PrintDiff() const {
|
||||
assert(ref_img_.y_stride == dst_img_.y_stride);
|
||||
assert(ref_img_.y_width == dst_img_.y_width);
|
||||
assert(ref_img_.y_height == dst_img_.y_height);
|
||||
assert(ref_img_.uv_stride == dst_img_.uv_stride);
|
||||
assert(ref_img_.uv_width == dst_img_.uv_width);
|
||||
assert(ref_img_.uv_height == dst_img_.uv_height);
|
||||
|
||||
if (memcmp(dst_img_.buffer_alloc, ref_img_.buffer_alloc,
|
||||
ref_img_.frame_size)) {
|
||||
PrintDiffComponent(ref_img_.y_buffer, dst_img_.y_buffer,
|
||||
ref_img_.y_stride, ref_img_.y_width, ref_img_.y_height,
|
||||
0);
|
||||
PrintDiffComponent(ref_img_.u_buffer, dst_img_.u_buffer,
|
||||
ref_img_.uv_stride, ref_img_.uv_width,
|
||||
ref_img_.uv_height, 1);
|
||||
PrintDiffComponent(ref_img_.v_buffer, dst_img_.v_buffer,
|
||||
ref_img_.uv_stride, ref_img_.uv_width,
|
||||
ref_img_.uv_height, 2);
|
||||
}
|
||||
}
|
||||
|
||||
ScaleFrameFunc scale_fn_;
|
||||
};
|
||||
|
||||
TEST_P(ScaleTest, ScaleFrame) { ASSERT_NO_FATAL_FAILURE(RunTest()); }
|
||||
|
||||
TEST_P(ScaleTest, DISABLED_Speed) {
|
||||
static const int kCountSpeedTestBlock = 100;
|
||||
static const int kNumScaleFactorsToTest = 4;
|
||||
static const int kScaleFactors[] = { 1, 2, 3, 4 };
|
||||
const int src_width = 1280;
|
||||
const int src_height = 720;
|
||||
for (INTERP_FILTER filter_type = 2; filter_type < 4; ++filter_type) {
|
||||
for (int phase_scaler = 0; phase_scaler < 2; ++phase_scaler) {
|
||||
for (int sf_up_idx = 0; sf_up_idx < kNumScaleFactorsToTest; ++sf_up_idx) {
|
||||
const int sf_up = kScaleFactors[sf_up_idx];
|
||||
for (int sf_down_idx = 0; sf_down_idx < kNumScaleFactorsToTest;
|
||||
++sf_down_idx) {
|
||||
const int sf_down = kScaleFactors[sf_down_idx];
|
||||
const int dst_width = src_width * sf_up / sf_down;
|
||||
const int dst_height = src_height * sf_up / sf_down;
|
||||
if (sf_up == sf_down && sf_up != 1) {
|
||||
continue;
|
||||
}
|
||||
// I420 frame width and height must be even.
|
||||
if (dst_width & 1 || dst_height & 1) {
|
||||
continue;
|
||||
}
|
||||
ASSERT_NO_FATAL_FAILURE(
|
||||
ResetScaleImages(src_width, src_height, dst_width, dst_height));
|
||||
ASM_REGISTER_STATE_CHECK(
|
||||
ReferenceScaleFrame(filter_type, phase_scaler));
|
||||
|
||||
vpx_usec_timer timer;
|
||||
vpx_usec_timer_start(&timer);
|
||||
for (int i = 0; i < kCountSpeedTestBlock; ++i) {
|
||||
ScaleFrame(filter_type, phase_scaler);
|
||||
}
|
||||
libvpx_test::ClearSystemState();
|
||||
vpx_usec_timer_mark(&timer);
|
||||
const int elapsed_time =
|
||||
static_cast<int>(vpx_usec_timer_elapsed(&timer) / 1000);
|
||||
CompareImages(dst_img_);
|
||||
DeallocScaleImages();
|
||||
|
||||
printf(
|
||||
"filter_type = %d, phase_scaler = %d, src_width = %4d, "
|
||||
"src_height = %4d, dst_width = %4d, dst_height = %4d, "
|
||||
"scale factor = %d:%d, scale time: %5d ms\n",
|
||||
filter_type, phase_scaler, src_width, src_height, dst_width,
|
||||
dst_height, sf_down, sf_up, elapsed_time);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
INSTANTIATE_TEST_CASE_P(C, ScaleTest,
|
||||
::testing::Values(vp9_scale_and_extend_frame_c));
|
||||
|
||||
#if HAVE_SSSE3
|
||||
INSTANTIATE_TEST_CASE_P(SSSE3, ScaleTest,
|
||||
::testing::Values(vp9_scale_and_extend_frame_ssse3));
|
||||
#endif // HAVE_SSSE3
|
||||
|
||||
#if HAVE_NEON
|
||||
INSTANTIATE_TEST_CASE_P(NEON, ScaleTest,
|
||||
::testing::Values(vp9_scale_and_extend_frame_neon));
|
||||
#endif // HAVE_NEON
|
||||
|
||||
} // namespace libvpx_test
|
||||
@@ -85,8 +85,8 @@ class SkipLoopFilterTest {
|
||||
// TODO(fgalligan): Move the MD5 testing code into another class.
|
||||
void OpenMd5File(const std::string &md5_file_name) {
|
||||
md5_file_ = libvpx_test::OpenTestDataFile(md5_file_name);
|
||||
ASSERT_TRUE(md5_file_ != NULL) << "MD5 file open failed. Filename: "
|
||||
<< md5_file_name;
|
||||
ASSERT_TRUE(md5_file_ != NULL)
|
||||
<< "MD5 file open failed. Filename: " << md5_file_name;
|
||||
}
|
||||
|
||||
// Reads the next line of the MD5 file.
|
||||
|
||||
@@ -101,4 +101,9 @@ INSTANTIATE_TEST_CASE_P(MSA, VP9SubtractBlockTest,
|
||||
::testing::Values(vpx_subtract_block_msa));
|
||||
#endif
|
||||
|
||||
#if HAVE_MMI
|
||||
INSTANTIATE_TEST_CASE_P(MMI, VP9SubtractBlockTest,
|
||||
::testing::Values(vpx_subtract_block_mmi));
|
||||
#endif
|
||||
|
||||
} // namespace vp9
|
||||
|
||||
@@ -187,8 +187,8 @@ void DecodeFiles(const FileList files[]) {
|
||||
for (const FileList *iter = files; iter->name != NULL; ++iter) {
|
||||
SCOPED_TRACE(iter->name);
|
||||
for (int t = 1; t <= 8; ++t) {
|
||||
EXPECT_EQ(iter->expected_md5, DecodeFile(iter->name, t)) << "threads = "
|
||||
<< t;
|
||||
EXPECT_EQ(iter->expected_md5, DecodeFile(iter->name, t))
|
||||
<< "threads = " << t;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -14,149 +14,17 @@
|
||||
#include "./vpx_scale_rtcd.h"
|
||||
#include "test/clear_system_state.h"
|
||||
#include "test/register_state_check.h"
|
||||
#include "test/vpx_scale_test.h"
|
||||
#include "vpx_mem/vpx_mem.h"
|
||||
#include "vpx_ports/vpx_timer.h"
|
||||
#include "vpx_scale/yv12config.h"
|
||||
|
||||
namespace {
|
||||
namespace libvpx_test {
|
||||
|
||||
typedef void (*ExtendFrameBorderFunc)(YV12_BUFFER_CONFIG *ybf);
|
||||
typedef void (*CopyFrameFunc)(const YV12_BUFFER_CONFIG *src_ybf,
|
||||
YV12_BUFFER_CONFIG *dst_ybf);
|
||||
|
||||
class VpxScaleBase {
|
||||
public:
|
||||
virtual ~VpxScaleBase() { libvpx_test::ClearSystemState(); }
|
||||
|
||||
void ResetImage(int width, int height) {
|
||||
width_ = width;
|
||||
height_ = height;
|
||||
memset(&img_, 0, sizeof(img_));
|
||||
ASSERT_EQ(0, vp8_yv12_alloc_frame_buffer(&img_, width_, height_,
|
||||
VP8BORDERINPIXELS));
|
||||
memset(img_.buffer_alloc, kBufFiller, img_.frame_size);
|
||||
FillPlane(img_.y_buffer, img_.y_crop_width, img_.y_crop_height,
|
||||
img_.y_stride);
|
||||
FillPlane(img_.u_buffer, img_.uv_crop_width, img_.uv_crop_height,
|
||||
img_.uv_stride);
|
||||
FillPlane(img_.v_buffer, img_.uv_crop_width, img_.uv_crop_height,
|
||||
img_.uv_stride);
|
||||
|
||||
memset(&ref_img_, 0, sizeof(ref_img_));
|
||||
ASSERT_EQ(0, vp8_yv12_alloc_frame_buffer(&ref_img_, width_, height_,
|
||||
VP8BORDERINPIXELS));
|
||||
memset(ref_img_.buffer_alloc, kBufFiller, ref_img_.frame_size);
|
||||
|
||||
memset(&cpy_img_, 0, sizeof(cpy_img_));
|
||||
ASSERT_EQ(0, vp8_yv12_alloc_frame_buffer(&cpy_img_, width_, height_,
|
||||
VP8BORDERINPIXELS));
|
||||
memset(cpy_img_.buffer_alloc, kBufFiller, cpy_img_.frame_size);
|
||||
ReferenceCopyFrame();
|
||||
}
|
||||
|
||||
void DeallocImage() {
|
||||
vp8_yv12_de_alloc_frame_buffer(&img_);
|
||||
vp8_yv12_de_alloc_frame_buffer(&ref_img_);
|
||||
vp8_yv12_de_alloc_frame_buffer(&cpy_img_);
|
||||
}
|
||||
|
||||
protected:
|
||||
static const int kBufFiller = 123;
|
||||
static const int kBufMax = kBufFiller - 1;
|
||||
|
||||
static void FillPlane(uint8_t *buf, int width, int height, int stride) {
|
||||
for (int y = 0; y < height; ++y) {
|
||||
for (int x = 0; x < width; ++x) {
|
||||
buf[x + (y * stride)] = (x + (width * y)) % kBufMax;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void ExtendPlane(uint8_t *buf, int crop_width, int crop_height,
|
||||
int width, int height, int stride, int padding) {
|
||||
// Copy the outermost visible pixel to a distance of at least 'padding.'
|
||||
// The buffers are allocated such that there may be excess space outside the
|
||||
// padding. As long as the minimum amount of padding is achieved it is not
|
||||
// necessary to fill this space as well.
|
||||
uint8_t *left = buf - padding;
|
||||
uint8_t *right = buf + crop_width;
|
||||
const int right_extend = padding + (width - crop_width);
|
||||
const int bottom_extend = padding + (height - crop_height);
|
||||
|
||||
// Fill the border pixels from the nearest image pixel.
|
||||
for (int y = 0; y < crop_height; ++y) {
|
||||
memset(left, left[padding], padding);
|
||||
memset(right, right[-1], right_extend);
|
||||
left += stride;
|
||||
right += stride;
|
||||
}
|
||||
|
||||
left = buf - padding;
|
||||
uint8_t *top = left - (stride * padding);
|
||||
// The buffer does not always extend as far as the stride.
|
||||
// Equivalent to padding + width + padding.
|
||||
const int extend_width = padding + crop_width + right_extend;
|
||||
|
||||
// The first row was already extended to the left and right. Copy it up.
|
||||
for (int y = 0; y < padding; ++y) {
|
||||
memcpy(top, left, extend_width);
|
||||
top += stride;
|
||||
}
|
||||
|
||||
uint8_t *bottom = left + (crop_height * stride);
|
||||
for (int y = 0; y < bottom_extend; ++y) {
|
||||
memcpy(bottom, left + (crop_height - 1) * stride, extend_width);
|
||||
bottom += stride;
|
||||
}
|
||||
}
|
||||
|
||||
void ReferenceExtendBorder() {
|
||||
ExtendPlane(ref_img_.y_buffer, ref_img_.y_crop_width,
|
||||
ref_img_.y_crop_height, ref_img_.y_width, ref_img_.y_height,
|
||||
ref_img_.y_stride, ref_img_.border);
|
||||
ExtendPlane(ref_img_.u_buffer, ref_img_.uv_crop_width,
|
||||
ref_img_.uv_crop_height, ref_img_.uv_width, ref_img_.uv_height,
|
||||
ref_img_.uv_stride, ref_img_.border / 2);
|
||||
ExtendPlane(ref_img_.v_buffer, ref_img_.uv_crop_width,
|
||||
ref_img_.uv_crop_height, ref_img_.uv_width, ref_img_.uv_height,
|
||||
ref_img_.uv_stride, ref_img_.border / 2);
|
||||
}
|
||||
|
||||
void ReferenceCopyFrame() {
|
||||
// Copy img_ to ref_img_ and extend frame borders. This will be used for
|
||||
// verifying extend_fn_ as well as copy_frame_fn_.
|
||||
EXPECT_EQ(ref_img_.frame_size, img_.frame_size);
|
||||
for (int y = 0; y < img_.y_crop_height; ++y) {
|
||||
for (int x = 0; x < img_.y_crop_width; ++x) {
|
||||
ref_img_.y_buffer[x + y * ref_img_.y_stride] =
|
||||
img_.y_buffer[x + y * img_.y_stride];
|
||||
}
|
||||
}
|
||||
|
||||
for (int y = 0; y < img_.uv_crop_height; ++y) {
|
||||
for (int x = 0; x < img_.uv_crop_width; ++x) {
|
||||
ref_img_.u_buffer[x + y * ref_img_.uv_stride] =
|
||||
img_.u_buffer[x + y * img_.uv_stride];
|
||||
ref_img_.v_buffer[x + y * ref_img_.uv_stride] =
|
||||
img_.v_buffer[x + y * img_.uv_stride];
|
||||
}
|
||||
}
|
||||
|
||||
ReferenceExtendBorder();
|
||||
}
|
||||
|
||||
void CompareImages(const YV12_BUFFER_CONFIG actual) {
|
||||
EXPECT_EQ(ref_img_.frame_size, actual.frame_size);
|
||||
EXPECT_EQ(0, memcmp(ref_img_.buffer_alloc, actual.buffer_alloc,
|
||||
ref_img_.frame_size));
|
||||
}
|
||||
|
||||
YV12_BUFFER_CONFIG img_;
|
||||
YV12_BUFFER_CONFIG ref_img_;
|
||||
YV12_BUFFER_CONFIG cpy_img_;
|
||||
int width_;
|
||||
int height_;
|
||||
};
|
||||
|
||||
class ExtendBorderTest
|
||||
: public VpxScaleBase,
|
||||
public ::testing::TestWithParam<ExtendFrameBorderFunc> {
|
||||
@@ -178,11 +46,11 @@ class ExtendBorderTest
|
||||
static const int kSizesToTest[] = { 1, 15, 33, 145, 512, 1025, 16383 };
|
||||
for (int h = 0; h < kNumSizesToTest; ++h) {
|
||||
for (int w = 0; w < kNumSizesToTest; ++w) {
|
||||
ResetImage(kSizesToTest[w], kSizesToTest[h]);
|
||||
ASSERT_NO_FATAL_FAILURE(ResetImages(kSizesToTest[w], kSizesToTest[h]));
|
||||
ReferenceCopyFrame();
|
||||
ExtendBorder();
|
||||
ReferenceExtendBorder();
|
||||
CompareImages(img_);
|
||||
DeallocImage();
|
||||
DeallocImages();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -204,7 +72,7 @@ class CopyFrameTest : public VpxScaleBase,
|
||||
virtual void SetUp() { copy_frame_fn_ = GetParam(); }
|
||||
|
||||
void CopyFrame() {
|
||||
ASM_REGISTER_STATE_CHECK(copy_frame_fn_(&img_, &cpy_img_));
|
||||
ASM_REGISTER_STATE_CHECK(copy_frame_fn_(&img_, &dst_img_));
|
||||
}
|
||||
|
||||
void RunTest() {
|
||||
@@ -217,11 +85,11 @@ class CopyFrameTest : public VpxScaleBase,
|
||||
static const int kSizesToTest[] = { 1, 15, 33, 145, 512, 1025, 16383 };
|
||||
for (int h = 0; h < kNumSizesToTest; ++h) {
|
||||
for (int w = 0; w < kNumSizesToTest; ++w) {
|
||||
ResetImage(kSizesToTest[w], kSizesToTest[h]);
|
||||
ASSERT_NO_FATAL_FAILURE(ResetImages(kSizesToTest[w], kSizesToTest[h]));
|
||||
ReferenceCopyFrame();
|
||||
CopyFrame();
|
||||
CompareImages(cpy_img_);
|
||||
DeallocImage();
|
||||
CompareImages(dst_img_);
|
||||
DeallocImages();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -233,4 +101,5 @@ TEST_P(CopyFrameTest, CopyFrame) { ASSERT_NO_FATAL_FAILURE(RunTest()); }
|
||||
|
||||
INSTANTIATE_TEST_CASE_P(C, CopyFrameTest,
|
||||
::testing::Values(vp8_yv12_copy_frame_c));
|
||||
} // namespace
|
||||
|
||||
} // namespace libvpx_test
|
||||
|
||||
200
test/vpx_scale_test.h
Normal file
200
test/vpx_scale_test.h
Normal file
@@ -0,0 +1,200 @@
|
||||
/*
|
||||
* Copyright (c) 2014 The WebM project authors. All Rights Reserved.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license
|
||||
* that can be found in the LICENSE file in the root of the source
|
||||
* tree. An additional intellectual property rights grant can be found
|
||||
* in the file PATENTS. All contributing project authors may
|
||||
* be found in the AUTHORS file in the root of the source tree.
|
||||
*/
|
||||
|
||||
#ifndef TEST_VPX_SCALE_TEST_H_
|
||||
#define TEST_VPX_SCALE_TEST_H_
|
||||
|
||||
#include "third_party/googletest/src/include/gtest/gtest.h"
|
||||
|
||||
#include "./vpx_config.h"
|
||||
#include "./vpx_scale_rtcd.h"
|
||||
#include "test/acm_random.h"
|
||||
#include "test/clear_system_state.h"
|
||||
#include "test/register_state_check.h"
|
||||
#include "vpx_mem/vpx_mem.h"
|
||||
#include "vpx_scale/yv12config.h"
|
||||
|
||||
using libvpx_test::ACMRandom;
|
||||
|
||||
namespace libvpx_test {
|
||||
|
||||
class VpxScaleBase {
|
||||
public:
|
||||
virtual ~VpxScaleBase() { libvpx_test::ClearSystemState(); }
|
||||
|
||||
void ResetImage(YV12_BUFFER_CONFIG *const img, const int width,
|
||||
const int height) {
|
||||
memset(img, 0, sizeof(*img));
|
||||
ASSERT_EQ(
|
||||
0, vp8_yv12_alloc_frame_buffer(img, width, height, VP8BORDERINPIXELS));
|
||||
memset(img->buffer_alloc, kBufFiller, img->frame_size);
|
||||
}
|
||||
|
||||
void ResetImages(const int width, const int height) {
|
||||
ResetImage(&img_, width, height);
|
||||
ResetImage(&ref_img_, width, height);
|
||||
ResetImage(&dst_img_, width, height);
|
||||
|
||||
FillPlane(img_.y_buffer, img_.y_crop_width, img_.y_crop_height,
|
||||
img_.y_stride);
|
||||
FillPlane(img_.u_buffer, img_.uv_crop_width, img_.uv_crop_height,
|
||||
img_.uv_stride);
|
||||
FillPlane(img_.v_buffer, img_.uv_crop_width, img_.uv_crop_height,
|
||||
img_.uv_stride);
|
||||
}
|
||||
|
||||
void ResetScaleImage(YV12_BUFFER_CONFIG *const img, const int width,
|
||||
const int height) {
|
||||
memset(img, 0, sizeof(*img));
|
||||
#if CONFIG_VP9_HIGHBITDEPTH
|
||||
ASSERT_EQ(0, vpx_alloc_frame_buffer(img, width, height, 1, 1, 0,
|
||||
VP9_ENC_BORDER_IN_PIXELS, 0));
|
||||
#else
|
||||
ASSERT_EQ(0, vpx_alloc_frame_buffer(img, width, height, 1, 1,
|
||||
VP9_ENC_BORDER_IN_PIXELS, 0));
|
||||
#endif
|
||||
memset(img->buffer_alloc, kBufFiller, img->frame_size);
|
||||
}
|
||||
|
||||
void ResetScaleImages(const int src_width, const int src_height,
|
||||
const int dst_width, const int dst_height) {
|
||||
ResetScaleImage(&img_, src_width, src_height);
|
||||
ResetScaleImage(&ref_img_, dst_width, dst_height);
|
||||
ResetScaleImage(&dst_img_, dst_width, dst_height);
|
||||
FillPlaneExtreme(img_.y_buffer, img_.y_crop_width, img_.y_crop_height,
|
||||
img_.y_stride);
|
||||
FillPlaneExtreme(img_.u_buffer, img_.uv_crop_width, img_.uv_crop_height,
|
||||
img_.uv_stride);
|
||||
FillPlaneExtreme(img_.v_buffer, img_.uv_crop_width, img_.uv_crop_height,
|
||||
img_.uv_stride);
|
||||
}
|
||||
|
||||
void DeallocImages() {
|
||||
vp8_yv12_de_alloc_frame_buffer(&img_);
|
||||
vp8_yv12_de_alloc_frame_buffer(&ref_img_);
|
||||
vp8_yv12_de_alloc_frame_buffer(&dst_img_);
|
||||
}
|
||||
|
||||
void DeallocScaleImages() {
|
||||
vpx_free_frame_buffer(&img_);
|
||||
vpx_free_frame_buffer(&ref_img_);
|
||||
vpx_free_frame_buffer(&dst_img_);
|
||||
}
|
||||
|
||||
protected:
|
||||
static const int kBufFiller = 123;
|
||||
static const int kBufMax = kBufFiller - 1;
|
||||
|
||||
static void FillPlane(uint8_t *const buf, const int width, const int height,
|
||||
const int stride) {
|
||||
for (int y = 0; y < height; ++y) {
|
||||
for (int x = 0; x < width; ++x) {
|
||||
buf[x + (y * stride)] = (x + (width * y)) % kBufMax;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void FillPlaneExtreme(uint8_t *const buf, const int width,
|
||||
const int height, const int stride) {
|
||||
ACMRandom rnd;
|
||||
for (int y = 0; y < height; ++y) {
|
||||
for (int x = 0; x < width; ++x) {
|
||||
buf[x + (y * stride)] = rnd.Rand8() % 2 ? 255 : 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void ExtendPlane(uint8_t *buf, int crop_width, int crop_height,
|
||||
int width, int height, int stride, int padding) {
|
||||
// Copy the outermost visible pixel to a distance of at least 'padding.'
|
||||
// The buffers are allocated such that there may be excess space outside the
|
||||
// padding. As long as the minimum amount of padding is achieved it is not
|
||||
// necessary to fill this space as well.
|
||||
uint8_t *left = buf - padding;
|
||||
uint8_t *right = buf + crop_width;
|
||||
const int right_extend = padding + (width - crop_width);
|
||||
const int bottom_extend = padding + (height - crop_height);
|
||||
|
||||
// Fill the border pixels from the nearest image pixel.
|
||||
for (int y = 0; y < crop_height; ++y) {
|
||||
memset(left, left[padding], padding);
|
||||
memset(right, right[-1], right_extend);
|
||||
left += stride;
|
||||
right += stride;
|
||||
}
|
||||
|
||||
left = buf - padding;
|
||||
uint8_t *top = left - (stride * padding);
|
||||
// The buffer does not always extend as far as the stride.
|
||||
// Equivalent to padding + width + padding.
|
||||
const int extend_width = padding + crop_width + right_extend;
|
||||
|
||||
// The first row was already extended to the left and right. Copy it up.
|
||||
for (int y = 0; y < padding; ++y) {
|
||||
memcpy(top, left, extend_width);
|
||||
top += stride;
|
||||
}
|
||||
|
||||
uint8_t *bottom = left + (crop_height * stride);
|
||||
for (int y = 0; y < bottom_extend; ++y) {
|
||||
memcpy(bottom, left + (crop_height - 1) * stride, extend_width);
|
||||
bottom += stride;
|
||||
}
|
||||
}
|
||||
|
||||
void ReferenceExtendBorder() {
|
||||
ExtendPlane(ref_img_.y_buffer, ref_img_.y_crop_width,
|
||||
ref_img_.y_crop_height, ref_img_.y_width, ref_img_.y_height,
|
||||
ref_img_.y_stride, ref_img_.border);
|
||||
ExtendPlane(ref_img_.u_buffer, ref_img_.uv_crop_width,
|
||||
ref_img_.uv_crop_height, ref_img_.uv_width, ref_img_.uv_height,
|
||||
ref_img_.uv_stride, ref_img_.border / 2);
|
||||
ExtendPlane(ref_img_.v_buffer, ref_img_.uv_crop_width,
|
||||
ref_img_.uv_crop_height, ref_img_.uv_width, ref_img_.uv_height,
|
||||
ref_img_.uv_stride, ref_img_.border / 2);
|
||||
}
|
||||
|
||||
void ReferenceCopyFrame() {
|
||||
// Copy img_ to ref_img_ and extend frame borders. This will be used for
|
||||
// verifying extend_fn_ as well as copy_frame_fn_.
|
||||
EXPECT_EQ(ref_img_.frame_size, img_.frame_size);
|
||||
for (int y = 0; y < img_.y_crop_height; ++y) {
|
||||
for (int x = 0; x < img_.y_crop_width; ++x) {
|
||||
ref_img_.y_buffer[x + y * ref_img_.y_stride] =
|
||||
img_.y_buffer[x + y * img_.y_stride];
|
||||
}
|
||||
}
|
||||
|
||||
for (int y = 0; y < img_.uv_crop_height; ++y) {
|
||||
for (int x = 0; x < img_.uv_crop_width; ++x) {
|
||||
ref_img_.u_buffer[x + y * ref_img_.uv_stride] =
|
||||
img_.u_buffer[x + y * img_.uv_stride];
|
||||
ref_img_.v_buffer[x + y * ref_img_.uv_stride] =
|
||||
img_.v_buffer[x + y * img_.uv_stride];
|
||||
}
|
||||
}
|
||||
|
||||
ReferenceExtendBorder();
|
||||
}
|
||||
|
||||
void CompareImages(const YV12_BUFFER_CONFIG actual) {
|
||||
EXPECT_EQ(ref_img_.frame_size, actual.frame_size);
|
||||
EXPECT_EQ(0, memcmp(ref_img_.buffer_alloc, actual.buffer_alloc,
|
||||
ref_img_.frame_size));
|
||||
}
|
||||
|
||||
YV12_BUFFER_CONFIG img_;
|
||||
YV12_BUFFER_CONFIG ref_img_;
|
||||
YV12_BUFFER_CONFIG dst_img_;
|
||||
};
|
||||
|
||||
} // namespace libvpx_test
|
||||
|
||||
#endif // TEST_VPX_SCALE_TEST_H_
|
||||
@@ -41,6 +41,7 @@ vpx_tsvc_encoder() {
|
||||
local speed="6"
|
||||
local frame_drop_thresh="30"
|
||||
local max_threads="4"
|
||||
local error_resilient="1"
|
||||
|
||||
shift 2
|
||||
|
||||
@@ -51,11 +52,19 @@ vpx_tsvc_encoder() {
|
||||
|
||||
# TODO(tomfinegan): Verify file output for all thread runs.
|
||||
for threads in $(seq $max_threads); do
|
||||
eval "${VPX_TEST_PREFIX}" "${encoder}" "${YUV_RAW_INPUT}" "${output_file}" \
|
||||
"${codec}" "${YUV_RAW_INPUT_WIDTH}" "${YUV_RAW_INPUT_HEIGHT}" \
|
||||
"${timebase_num}" "${timebase_den}" "${speed}" "${frame_drop_thresh}" \
|
||||
"${threads}" "$@" \
|
||||
${devnull}
|
||||
if [ "$(vpx_config_option_enabled CONFIG_VP9_HIGHBITDEPTH)" != "yes" ]; then
|
||||
eval "${VPX_TEST_PREFIX}" "${encoder}" "${YUV_RAW_INPUT}" \
|
||||
"${output_file}" "${codec}" "${YUV_RAW_INPUT_WIDTH}" \
|
||||
"${YUV_RAW_INPUT_HEIGHT}" "${timebase_num}" "${timebase_den}" \
|
||||
"${speed}" "${frame_drop_thresh}" "${error_resilient}" "${threads}" \
|
||||
"$@" ${devnull}
|
||||
else
|
||||
eval "${VPX_TEST_PREFIX}" "${encoder}" "${YUV_RAW_INPUT}" \
|
||||
"${output_file}" "${codec}" "${YUV_RAW_INPUT_WIDTH}" \
|
||||
"${YUV_RAW_INPUT_HEIGHT}" "${timebase_num}" "${timebase_den}" \
|
||||
"${speed}" "${frame_drop_thresh}" "${error_resilient}" "${threads}" \
|
||||
"$@" "8" ${devnull}
|
||||
fi
|
||||
done
|
||||
}
|
||||
|
||||
@@ -76,193 +85,217 @@ files_exist() {
|
||||
|
||||
vpx_tsvc_encoder_vp8_mode_0() {
|
||||
if [ "$(vp8_encode_available)" = "yes" ]; then
|
||||
vpx_tsvc_encoder vp8 "${FUNCNAME}" 0 200 || return 1
|
||||
local readonly output_basename="vpx_tsvc_encoder_vp8_mode_0"
|
||||
vpx_tsvc_encoder vp8 "${output_basename}" 0 200 || return 1
|
||||
# Mode 0 produces 1 stream
|
||||
files_exist "${FUNCNAME}" 1 || return 1
|
||||
files_exist "${output_basename}" 1 || return 1
|
||||
fi
|
||||
}
|
||||
|
||||
vpx_tsvc_encoder_vp8_mode_1() {
|
||||
if [ "$(vp8_encode_available)" = "yes" ]; then
|
||||
vpx_tsvc_encoder vp8 "${FUNCNAME}" 1 200 400 || return 1
|
||||
local readonly output_basename="vpx_tsvc_encoder_vp8_mode_1"
|
||||
vpx_tsvc_encoder vp8 "${output_basename}" 1 200 400 || return 1
|
||||
# Mode 1 produces 2 streams
|
||||
files_exist "${FUNCNAME}" 2 || return 1
|
||||
files_exist "${output_basename}" 2 || return 1
|
||||
fi
|
||||
}
|
||||
|
||||
vpx_tsvc_encoder_vp8_mode_2() {
|
||||
if [ "$(vp8_encode_available)" = "yes" ]; then
|
||||
vpx_tsvc_encoder vp8 "${FUNCNAME}" 2 200 400 || return 1
|
||||
local readonly output_basename="vpx_tsvc_encoder_vp8_mode_2"
|
||||
vpx_tsvc_encoder vp8 "${output_basename}" 2 200 400 || return 1
|
||||
# Mode 2 produces 2 streams
|
||||
files_exist "${FUNCNAME}" 2 || return 1
|
||||
files_exist "${output_basename}" 2 || return 1
|
||||
fi
|
||||
}
|
||||
|
||||
vpx_tsvc_encoder_vp8_mode_3() {
|
||||
if [ "$(vp8_encode_available)" = "yes" ]; then
|
||||
vpx_tsvc_encoder vp8 "${FUNCNAME}" 3 200 400 600 || return 1
|
||||
local readonly output_basename="vpx_tsvc_encoder_vp8_mode_3"
|
||||
vpx_tsvc_encoder vp8 "${output_basename}" 3 200 400 600 || return 1
|
||||
# Mode 3 produces 3 streams
|
||||
files_exist "${FUNCNAME}" 3 || return 1
|
||||
files_exist "${output_basename}" 3 || return 1
|
||||
fi
|
||||
}
|
||||
|
||||
vpx_tsvc_encoder_vp8_mode_4() {
|
||||
if [ "$(vp8_encode_available)" = "yes" ]; then
|
||||
vpx_tsvc_encoder vp8 "${FUNCNAME}" 4 200 400 600 || return 1
|
||||
local readonly output_basename="vpx_tsvc_encoder_vp8_mode_4"
|
||||
vpx_tsvc_encoder vp8 "${output_basename}" 4 200 400 600 || return 1
|
||||
# Mode 4 produces 3 streams
|
||||
files_exist "${FUNCNAME}" 3 || return 1
|
||||
files_exist "${output_basename}" 3 || return 1
|
||||
fi
|
||||
}
|
||||
|
||||
vpx_tsvc_encoder_vp8_mode_5() {
|
||||
if [ "$(vp8_encode_available)" = "yes" ]; then
|
||||
vpx_tsvc_encoder vp8 "${FUNCNAME}" 5 200 400 600 || return 1
|
||||
local readonly output_basename="vpx_tsvc_encoder_vp8_mode_5"
|
||||
vpx_tsvc_encoder vp8 "${output_basename}" 5 200 400 600 || return 1
|
||||
# Mode 5 produces 3 streams
|
||||
files_exist "${FUNCNAME}" 3 || return 1
|
||||
files_exist "${output_basename}" 3 || return 1
|
||||
fi
|
||||
}
|
||||
|
||||
vpx_tsvc_encoder_vp8_mode_6() {
|
||||
if [ "$(vp8_encode_available)" = "yes" ]; then
|
||||
vpx_tsvc_encoder vp8 "${FUNCNAME}" 6 200 400 600 || return 1
|
||||
local readonly output_basename="vpx_tsvc_encoder_vp8_mode_6"
|
||||
vpx_tsvc_encoder vp8 "${output_basename}" 6 200 400 600 || return 1
|
||||
# Mode 6 produces 3 streams
|
||||
files_exist "${FUNCNAME}" 3 || return 1
|
||||
files_exist "${output_basename}" 3 || return 1
|
||||
fi
|
||||
}
|
||||
|
||||
vpx_tsvc_encoder_vp8_mode_7() {
|
||||
if [ "$(vp8_encode_available)" = "yes" ]; then
|
||||
vpx_tsvc_encoder vp8 "${FUNCNAME}" 7 200 400 600 800 1000 || return 1
|
||||
local readonly output_basename="vpx_tsvc_encoder_vp8_mode_7"
|
||||
vpx_tsvc_encoder vp8 "${output_basename}" 7 200 400 600 800 1000 || return 1
|
||||
# Mode 7 produces 5 streams
|
||||
files_exist "${FUNCNAME}" 5 || return 1
|
||||
files_exist "${output_basename}" 5 || return 1
|
||||
fi
|
||||
}
|
||||
|
||||
vpx_tsvc_encoder_vp8_mode_8() {
|
||||
if [ "$(vp8_encode_available)" = "yes" ]; then
|
||||
vpx_tsvc_encoder vp8 "${FUNCNAME}" 8 200 400 || return 1
|
||||
local readonly output_basename="vpx_tsvc_encoder_vp8_mode_8"
|
||||
vpx_tsvc_encoder vp8 "${output_basename}" 8 200 400 || return 1
|
||||
# Mode 8 produces 2 streams
|
||||
files_exist "${FUNCNAME}" 2 || return 1
|
||||
files_exist "${output_basename}" 2 || return 1
|
||||
fi
|
||||
}
|
||||
|
||||
vpx_tsvc_encoder_vp8_mode_9() {
|
||||
if [ "$(vp8_encode_available)" = "yes" ]; then
|
||||
vpx_tsvc_encoder vp8 "${FUNCNAME}" 9 200 400 600 || return 1
|
||||
local readonly output_basename="vpx_tsvc_encoder_vp8_mode_9"
|
||||
vpx_tsvc_encoder vp8 "${output_basename}" 9 200 400 600 || return 1
|
||||
# Mode 9 produces 3 streams
|
||||
files_exist "${FUNCNAME}" 3 || return 1
|
||||
files_exist "${output_basename}" 3 || return 1
|
||||
fi
|
||||
}
|
||||
|
||||
vpx_tsvc_encoder_vp8_mode_10() {
|
||||
if [ "$(vp8_encode_available)" = "yes" ]; then
|
||||
vpx_tsvc_encoder vp8 "${FUNCNAME}" 10 200 400 600 || return 1
|
||||
local readonly output_basename="vpx_tsvc_encoder_vp8_mode_10"
|
||||
vpx_tsvc_encoder vp8 "${output_basename}" 10 200 400 600 || return 1
|
||||
# Mode 10 produces 3 streams
|
||||
files_exist "${FUNCNAME}" 3 || return 1
|
||||
files_exist "${output_basename}" 3 || return 1
|
||||
fi
|
||||
}
|
||||
|
||||
vpx_tsvc_encoder_vp8_mode_11() {
|
||||
if [ "$(vp8_encode_available)" = "yes" ]; then
|
||||
vpx_tsvc_encoder vp8 "${FUNCNAME}" 11 200 400 600 || return 1
|
||||
local readonly output_basename="vpx_tsvc_encoder_vp8_mode_11"
|
||||
vpx_tsvc_encoder vp8 "${output_basename}" 11 200 400 600 || return 1
|
||||
# Mode 11 produces 3 streams
|
||||
files_exist "${FUNCNAME}" 3 || return 1
|
||||
files_exist "${output_basename}" 3 || return 1
|
||||
fi
|
||||
}
|
||||
|
||||
vpx_tsvc_encoder_vp9_mode_0() {
|
||||
if [ "$(vp9_encode_available)" = "yes" ]; then
|
||||
vpx_tsvc_encoder vp9 "${FUNCNAME}" 0 200 || return 1
|
||||
local readonly output_basename="vpx_tsvc_encoder_vp9_mode_0"
|
||||
vpx_tsvc_encoder vp9 "${output_basename}" 0 200 || return 1
|
||||
# Mode 0 produces 1 stream
|
||||
files_exist "${FUNCNAME}" 1 || return 1
|
||||
files_exist "${output_basename}" 1 || return 1
|
||||
fi
|
||||
}
|
||||
|
||||
vpx_tsvc_encoder_vp9_mode_1() {
|
||||
if [ "$(vp9_encode_available)" = "yes" ]; then
|
||||
vpx_tsvc_encoder vp9 "${FUNCNAME}" 1 200 400 || return 1
|
||||
local readonly output_basename="vpx_tsvc_encoder_vp9_mode_1"
|
||||
vpx_tsvc_encoder vp9 "${output_basename}" 1 200 400 || return 1
|
||||
# Mode 1 produces 2 streams
|
||||
files_exist "${FUNCNAME}" 2 || return 1
|
||||
files_exist "${output_basename}" 2 || return 1
|
||||
fi
|
||||
}
|
||||
|
||||
vpx_tsvc_encoder_vp9_mode_2() {
|
||||
if [ "$(vp9_encode_available)" = "yes" ]; then
|
||||
vpx_tsvc_encoder vp9 "${FUNCNAME}" 2 200 400 || return 1
|
||||
local readonly output_basename="vpx_tsvc_encoder_vp9_mode_2"
|
||||
vpx_tsvc_encoder vp9 "${output_basename}" 2 200 400 || return 1
|
||||
# Mode 2 produces 2 streams
|
||||
files_exist "${FUNCNAME}" 2 || return 1
|
||||
files_exist "${output_basename}" 2 || return 1
|
||||
fi
|
||||
}
|
||||
|
||||
vpx_tsvc_encoder_vp9_mode_3() {
|
||||
if [ "$(vp9_encode_available)" = "yes" ]; then
|
||||
vpx_tsvc_encoder vp9 "${FUNCNAME}" 3 200 400 600 || return 1
|
||||
local readonly output_basename="vpx_tsvc_encoder_vp9_mode_3"
|
||||
vpx_tsvc_encoder vp9 "${output_basename}" 3 200 400 600 || return 1
|
||||
# Mode 3 produces 3 streams
|
||||
files_exist "${FUNCNAME}" 3 || return 1
|
||||
files_exist "${output_basename}" 3 || return 1
|
||||
fi
|
||||
}
|
||||
|
||||
vpx_tsvc_encoder_vp9_mode_4() {
|
||||
if [ "$(vp9_encode_available)" = "yes" ]; then
|
||||
vpx_tsvc_encoder vp9 "${FUNCNAME}" 4 200 400 600 || return 1
|
||||
local readonly output_basename="vpx_tsvc_encoder_vp9_mode_4"
|
||||
vpx_tsvc_encoder vp9 "${output_basename}" 4 200 400 600 || return 1
|
||||
# Mode 4 produces 3 streams
|
||||
files_exist "${FUNCNAME}" 3 || return 1
|
||||
files_exist "${output_basename}" 3 || return 1
|
||||
fi
|
||||
}
|
||||
|
||||
vpx_tsvc_encoder_vp9_mode_5() {
|
||||
if [ "$(vp9_encode_available)" = "yes" ]; then
|
||||
vpx_tsvc_encoder vp9 "${FUNCNAME}" 5 200 400 600 || return 1
|
||||
local readonly output_basename="vpx_tsvc_encoder_vp9_mode_5"
|
||||
vpx_tsvc_encoder vp9 "${output_basename}" 5 200 400 600 || return 1
|
||||
# Mode 5 produces 3 streams
|
||||
files_exist "${FUNCNAME}" 3 || return 1
|
||||
files_exist "${output_basename}" 3 || return 1
|
||||
fi
|
||||
}
|
||||
|
||||
vpx_tsvc_encoder_vp9_mode_6() {
|
||||
if [ "$(vp9_encode_available)" = "yes" ]; then
|
||||
vpx_tsvc_encoder vp9 "${FUNCNAME}" 6 200 400 600 || return 1
|
||||
local readonly output_basename="vpx_tsvc_encoder_vp9_mode_6"
|
||||
vpx_tsvc_encoder vp9 "${output_basename}" 6 200 400 600 || return 1
|
||||
# Mode 6 produces 3 streams
|
||||
files_exist "${FUNCNAME}" 3 || return 1
|
||||
files_exist "${output_basename}" 3 || return 1
|
||||
fi
|
||||
}
|
||||
|
||||
vpx_tsvc_encoder_vp9_mode_7() {
|
||||
if [ "$(vp9_encode_available)" = "yes" ]; then
|
||||
vpx_tsvc_encoder vp9 "${FUNCNAME}" 7 200 400 600 800 1000 || return 1
|
||||
local readonly output_basename="vpx_tsvc_encoder_vp9_mode_7"
|
||||
vpx_tsvc_encoder vp9 "${output_basename}" 7 200 400 600 800 1000 || return 1
|
||||
# Mode 7 produces 5 streams
|
||||
files_exist "${FUNCNAME}" 5 || return 1
|
||||
files_exist "${output_basename}" 5 || return 1
|
||||
fi
|
||||
}
|
||||
|
||||
vpx_tsvc_encoder_vp9_mode_8() {
|
||||
if [ "$(vp9_encode_available)" = "yes" ]; then
|
||||
vpx_tsvc_encoder vp9 "${FUNCNAME}" 8 200 400 || return 1
|
||||
local readonly output_basename="vpx_tsvc_encoder_vp9_mode_8"
|
||||
vpx_tsvc_encoder vp9 "${output_basename}" 8 200 400 || return 1
|
||||
# Mode 8 produces 2 streams
|
||||
files_exist "${FUNCNAME}" 2 || return 1
|
||||
files_exist "${output_basename}" 2 || return 1
|
||||
fi
|
||||
}
|
||||
|
||||
vpx_tsvc_encoder_vp9_mode_9() {
|
||||
if [ "$(vp9_encode_available)" = "yes" ]; then
|
||||
vpx_tsvc_encoder vp9 "${FUNCNAME}" 9 200 400 600 || return 1
|
||||
local readonly output_basename="vpx_tsvc_encoder_vp9_mode_9"
|
||||
vpx_tsvc_encoder vp9 "${output_basename}" 9 200 400 600 || return 1
|
||||
# Mode 9 produces 3 streams
|
||||
files_exist "${FUNCNAME}" 3 || return 1
|
||||
files_exist "${output_basename}" 3 || return 1
|
||||
fi
|
||||
}
|
||||
|
||||
vpx_tsvc_encoder_vp9_mode_10() {
|
||||
if [ "$(vp9_encode_available)" = "yes" ]; then
|
||||
vpx_tsvc_encoder vp9 "${FUNCNAME}" 10 200 400 600 || return 1
|
||||
local readonly output_basename="vpx_tsvc_encoder_vp9_mode_10"
|
||||
vpx_tsvc_encoder vp9 "${output_basename}" 10 200 400 600 || return 1
|
||||
# Mode 10 produces 3 streams
|
||||
files_exist "${FUNCNAME}" 3 || return 1
|
||||
files_exist "${output_basename}" 3 || return 1
|
||||
fi
|
||||
}
|
||||
|
||||
vpx_tsvc_encoder_vp9_mode_11() {
|
||||
if [ "$(vp9_encode_available)" = "yes" ]; then
|
||||
vpx_tsvc_encoder vp9 "${FUNCNAME}" 11 200 400 600 || return 1
|
||||
local readonly output_basename="vpx_tsvc_encoder_vp9_mode_11"
|
||||
vpx_tsvc_encoder vp9 "${output_basename}" 11 200 400 600 || return 1
|
||||
# Mode 11 produces 3 streams
|
||||
files_exist "${FUNCNAME}" 3 || return 1
|
||||
files_exist "${output_basename}" 3 || return 1
|
||||
fi
|
||||
}
|
||||
|
||||
|
||||
@@ -90,6 +90,15 @@ vpxenc_rt_params() {
|
||||
--undershoot-pct=50"
|
||||
}
|
||||
|
||||
# Forces --passes to 1 with CONFIG_REALTIME_ONLY.
|
||||
vpxenc_passes_param() {
|
||||
if [ "$(vpx_config_option_enabled CONFIG_REALTIME_ONLY)" = "yes" ]; then
|
||||
echo "--passes=1"
|
||||
else
|
||||
echo "--passes=2"
|
||||
fi
|
||||
}
|
||||
|
||||
# Wrapper function for running vpxenc with pipe input. Requires that
|
||||
# LIBVPX_BIN_PATH points to the directory containing vpxenc. $1 is used as the
|
||||
# input file path and shifted away. All remaining parameters are passed through
|
||||
@@ -218,9 +227,11 @@ vpxenc_vp8_ivf_piped_input() {
|
||||
vpxenc_vp9_ivf() {
|
||||
if [ "$(vpxenc_can_encode_vp9)" = "yes" ]; then
|
||||
local readonly output="${VPX_TEST_OUTPUT_DIR}/vp9.ivf"
|
||||
local readonly passes=$(vpxenc_passes_param)
|
||||
vpxenc $(yuv_input_hantro_collage) \
|
||||
--codec=vp9 \
|
||||
--limit="${TEST_FRAMES}" \
|
||||
"${passes}" \
|
||||
--ivf \
|
||||
--output="${output}"
|
||||
|
||||
@@ -235,9 +246,11 @@ vpxenc_vp9_webm() {
|
||||
if [ "$(vpxenc_can_encode_vp9)" = "yes" ] && \
|
||||
[ "$(webm_io_available)" = "yes" ]; then
|
||||
local readonly output="${VPX_TEST_OUTPUT_DIR}/vp9.webm"
|
||||
local readonly passes=$(vpxenc_passes_param)
|
||||
vpxenc $(yuv_input_hantro_collage) \
|
||||
--codec=vp9 \
|
||||
--limit="${TEST_FRAMES}" \
|
||||
"${passes}" \
|
||||
--output="${output}"
|
||||
|
||||
if [ ! -e "${output}" ]; then
|
||||
@@ -339,11 +352,13 @@ vpxenc_vp9_webm_2pass() {
|
||||
vpxenc_vp9_ivf_lossless() {
|
||||
if [ "$(vpxenc_can_encode_vp9)" = "yes" ]; then
|
||||
local readonly output="${VPX_TEST_OUTPUT_DIR}/vp9_lossless.ivf"
|
||||
local readonly passes=$(vpxenc_passes_param)
|
||||
vpxenc $(yuv_input_hantro_collage) \
|
||||
--codec=vp9 \
|
||||
--limit="${TEST_FRAMES}" \
|
||||
--ivf \
|
||||
--output="${output}" \
|
||||
"${passes}" \
|
||||
--lossless=1
|
||||
|
||||
if [ ! -e "${output}" ]; then
|
||||
@@ -356,11 +371,13 @@ vpxenc_vp9_ivf_lossless() {
|
||||
vpxenc_vp9_ivf_minq0_maxq0() {
|
||||
if [ "$(vpxenc_can_encode_vp9)" = "yes" ]; then
|
||||
local readonly output="${VPX_TEST_OUTPUT_DIR}/vp9_lossless_minq0_maxq0.ivf"
|
||||
local readonly passes=$(vpxenc_passes_param)
|
||||
vpxenc $(yuv_input_hantro_collage) \
|
||||
--codec=vp9 \
|
||||
--limit="${TEST_FRAMES}" \
|
||||
--ivf \
|
||||
--output="${output}" \
|
||||
"${passes}" \
|
||||
--min-q=0 \
|
||||
--max-q=0
|
||||
|
||||
@@ -377,12 +394,13 @@ vpxenc_vp9_webm_lag10_frames20() {
|
||||
local readonly lag_total_frames=20
|
||||
local readonly lag_frames=10
|
||||
local readonly output="${VPX_TEST_OUTPUT_DIR}/vp9_lag10_frames20.webm"
|
||||
local readonly passes=$(vpxenc_passes_param)
|
||||
vpxenc $(yuv_input_hantro_collage) \
|
||||
--codec=vp9 \
|
||||
--limit="${lag_total_frames}" \
|
||||
--lag-in-frames="${lag_frames}" \
|
||||
--output="${output}" \
|
||||
--passes=2 \
|
||||
"${passes}" \
|
||||
--auto-alt-ref=1
|
||||
|
||||
if [ ! -e "${output}" ]; then
|
||||
@@ -397,9 +415,11 @@ vpxenc_vp9_webm_non_square_par() {
|
||||
if [ "$(vpxenc_can_encode_vp9)" = "yes" ] && \
|
||||
[ "$(webm_io_available)" = "yes" ]; then
|
||||
local readonly output="${VPX_TEST_OUTPUT_DIR}/vp9_non_square_par.webm"
|
||||
local readonly passes=$(vpxenc_passes_param)
|
||||
vpxenc $(y4m_input_non_square_par) \
|
||||
--codec=vp9 \
|
||||
--limit="${TEST_FRAMES}" \
|
||||
"${passes}" \
|
||||
--output="${output}"
|
||||
|
||||
if [ ! -e "${output}" ]; then
|
||||
@@ -412,18 +432,21 @@ vpxenc_vp9_webm_non_square_par() {
|
||||
vpxenc_tests="vpxenc_vp8_ivf
|
||||
vpxenc_vp8_webm
|
||||
vpxenc_vp8_webm_rt
|
||||
vpxenc_vp8_webm_2pass
|
||||
vpxenc_vp8_webm_lag10_frames20
|
||||
vpxenc_vp8_ivf_piped_input
|
||||
vpxenc_vp9_ivf
|
||||
vpxenc_vp9_webm
|
||||
vpxenc_vp9_webm_rt
|
||||
vpxenc_vp9_webm_rt_multithread_tiled
|
||||
vpxenc_vp9_webm_rt_multithread_tiled_frameparallel
|
||||
vpxenc_vp9_webm_2pass
|
||||
vpxenc_vp9_ivf_lossless
|
||||
vpxenc_vp9_ivf_minq0_maxq0
|
||||
vpxenc_vp9_webm_lag10_frames20
|
||||
vpxenc_vp9_webm_non_square_par"
|
||||
if [ "$(vpx_config_option_enabled CONFIG_REALTIME_ONLY)" != "yes" ]; then
|
||||
vpxenc_tests="$vpxenc_tests
|
||||
vpxenc_vp8_webm_2pass
|
||||
vpxenc_vp8_webm_lag10_frames20
|
||||
vpxenc_vp9_webm_2pass"
|
||||
fi
|
||||
|
||||
run_tests vpxenc_verify_environment "${vpxenc_tests}"
|
||||
|
||||
@@ -40,8 +40,8 @@ class WebMVideoSource : public CompressedVideoSource {
|
||||
|
||||
virtual void Begin() {
|
||||
vpx_ctx_->file = OpenTestDataFile(file_name_);
|
||||
ASSERT_TRUE(vpx_ctx_->file != NULL) << "Input file open failed. Filename: "
|
||||
<< file_name_;
|
||||
ASSERT_TRUE(vpx_ctx_->file != NULL)
|
||||
<< "Input file open failed. Filename: " << file_name_;
|
||||
|
||||
ASSERT_EQ(file_is_webm(webm_ctx_, vpx_ctx_), 1) << "file is not WebM";
|
||||
|
||||
|
||||
@@ -34,8 +34,8 @@ class Y4mVideoSource : public VideoSource {
|
||||
virtual void OpenSource() {
|
||||
CloseSource();
|
||||
input_file_ = OpenTestDataFile(file_name_);
|
||||
ASSERT_TRUE(input_file_ != NULL) << "Input file open failed. Filename: "
|
||||
<< file_name_;
|
||||
ASSERT_TRUE(input_file_ != NULL)
|
||||
<< "Input file open failed. Filename: " << file_name_;
|
||||
}
|
||||
|
||||
virtual void ReadSourceToStart() {
|
||||
|
||||
@@ -43,8 +43,8 @@ class YUVVideoSource : public VideoSource {
|
||||
virtual void Begin() {
|
||||
if (input_file_) fclose(input_file_);
|
||||
input_file_ = OpenTestDataFile(file_name_);
|
||||
ASSERT_TRUE(input_file_ != NULL) << "Input file open failed. Filename: "
|
||||
<< file_name_;
|
||||
ASSERT_TRUE(input_file_ != NULL)
|
||||
<< "Input file open failed. Filename: " << file_name_;
|
||||
if (start_) {
|
||||
fseek(input_file_, static_cast<unsigned>(raw_size_) * start_, SEEK_SET);
|
||||
}
|
||||
|
||||
23
third_party/googletest/README.libvpx
vendored
23
third_party/googletest/README.libvpx
vendored
@@ -1,7 +1,7 @@
|
||||
URL: http://code.google.com/p/googletest/
|
||||
Version: 1.7.0
|
||||
URL: https://github.com/google/googletest
|
||||
Version: 1.8.0
|
||||
License: BSD
|
||||
License File: COPYING
|
||||
License File: LICENSE
|
||||
|
||||
Description:
|
||||
Google's framework for writing C++ tests on a variety of platforms
|
||||
@@ -12,10 +12,13 @@ failures, various options for running the tests, and XML test report
|
||||
generation.
|
||||
|
||||
Local Modifications:
|
||||
- Removed unused declarations of kPathSeparatorString to have warning
|
||||
free build.
|
||||
- Added GTEST_ATTRIBUTE_UNUSED_ to test registering dummies in TEST_P
|
||||
and INSTANTIATE_TEST_CASE_P to remove warnings about unused variables
|
||||
under GCC 5.
|
||||
- Only define g_in_fast_death_test_child for non-Windows builds; quiets an
|
||||
unused variable warning.
|
||||
- Remove everything but:
|
||||
googletest-release-1.8.0/googletest/
|
||||
CHANGES
|
||||
CONTRIBUTORS
|
||||
include
|
||||
LICENSE
|
||||
README.md
|
||||
src
|
||||
- Suppress unsigned overflow instrumentation in the LCG
|
||||
https://github.com/google/googletest/pull/1066
|
||||
|
||||
435
third_party/googletest/src/README
vendored
435
third_party/googletest/src/README
vendored
@@ -1,435 +0,0 @@
|
||||
Google C++ Testing Framework
|
||||
============================
|
||||
|
||||
http://code.google.com/p/googletest/
|
||||
|
||||
Overview
|
||||
--------
|
||||
|
||||
Google's framework for writing C++ tests on a variety of platforms
|
||||
(Linux, Mac OS X, Windows, Windows CE, Symbian, etc). Based on the
|
||||
xUnit architecture. Supports automatic test discovery, a rich set of
|
||||
assertions, user-defined assertions, death tests, fatal and non-fatal
|
||||
failures, various options for running the tests, and XML test report
|
||||
generation.
|
||||
|
||||
Please see the project page above for more information as well as the
|
||||
mailing list for questions, discussions, and development. There is
|
||||
also an IRC channel on OFTC (irc.oftc.net) #gtest available. Please
|
||||
join us!
|
||||
|
||||
Requirements for End Users
|
||||
--------------------------
|
||||
|
||||
Google Test is designed to have fairly minimal requirements to build
|
||||
and use with your projects, but there are some. Currently, we support
|
||||
Linux, Windows, Mac OS X, and Cygwin. We will also make our best
|
||||
effort to support other platforms (e.g. Solaris, AIX, and z/OS).
|
||||
However, since core members of the Google Test project have no access
|
||||
to these platforms, Google Test may have outstanding issues there. If
|
||||
you notice any problems on your platform, please notify
|
||||
googletestframework@googlegroups.com. Patches for fixing them are
|
||||
even more welcome!
|
||||
|
||||
### Linux Requirements ###
|
||||
|
||||
These are the base requirements to build and use Google Test from a source
|
||||
package (as described below):
|
||||
* GNU-compatible Make or gmake
|
||||
* POSIX-standard shell
|
||||
* POSIX(-2) Regular Expressions (regex.h)
|
||||
* A C++98-standard-compliant compiler
|
||||
|
||||
### Windows Requirements ###
|
||||
|
||||
* Microsoft Visual C++ 7.1 or newer
|
||||
|
||||
### Cygwin Requirements ###
|
||||
|
||||
* Cygwin 1.5.25-14 or newer
|
||||
|
||||
### Mac OS X Requirements ###
|
||||
|
||||
* Mac OS X 10.4 Tiger or newer
|
||||
* Developer Tools Installed
|
||||
|
||||
Also, you'll need CMake 2.6.4 or higher if you want to build the
|
||||
samples using the provided CMake script, regardless of the platform.
|
||||
|
||||
Requirements for Contributors
|
||||
-----------------------------
|
||||
|
||||
We welcome patches. If you plan to contribute a patch, you need to
|
||||
build Google Test and its own tests from an SVN checkout (described
|
||||
below), which has further requirements:
|
||||
|
||||
* Python version 2.3 or newer (for running some of the tests and
|
||||
re-generating certain source files from templates)
|
||||
* CMake 2.6.4 or newer
|
||||
|
||||
Getting the Source
|
||||
------------------
|
||||
|
||||
There are two primary ways of getting Google Test's source code: you
|
||||
can download a stable source release in your preferred archive format,
|
||||
or directly check out the source from our Subversion (SVN) repositary.
|
||||
The SVN checkout requires a few extra steps and some extra software
|
||||
packages on your system, but lets you track the latest development and
|
||||
make patches much more easily, so we highly encourage it.
|
||||
|
||||
### Source Package ###
|
||||
|
||||
Google Test is released in versioned source packages which can be
|
||||
downloaded from the download page [1]. Several different archive
|
||||
formats are provided, but the only difference is the tools used to
|
||||
manipulate them, and the size of the resulting file. Download
|
||||
whichever you are most comfortable with.
|
||||
|
||||
[1] http://code.google.com/p/googletest/downloads/list
|
||||
|
||||
Once the package is downloaded, expand it using whichever tools you
|
||||
prefer for that type. This will result in a new directory with the
|
||||
name "gtest-X.Y.Z" which contains all of the source code. Here are
|
||||
some examples on Linux:
|
||||
|
||||
tar -xvzf gtest-X.Y.Z.tar.gz
|
||||
tar -xvjf gtest-X.Y.Z.tar.bz2
|
||||
unzip gtest-X.Y.Z.zip
|
||||
|
||||
### SVN Checkout ###
|
||||
|
||||
To check out the main branch (also known as the "trunk") of Google
|
||||
Test, run the following Subversion command:
|
||||
|
||||
svn checkout http://googletest.googlecode.com/svn/trunk/ gtest-svn
|
||||
|
||||
Setting up the Build
|
||||
--------------------
|
||||
|
||||
To build Google Test and your tests that use it, you need to tell your
|
||||
build system where to find its headers and source files. The exact
|
||||
way to do it depends on which build system you use, and is usually
|
||||
straightforward.
|
||||
|
||||
### Generic Build Instructions ###
|
||||
|
||||
Suppose you put Google Test in directory ${GTEST_DIR}. To build it,
|
||||
create a library build target (or a project as called by Visual Studio
|
||||
and Xcode) to compile
|
||||
|
||||
${GTEST_DIR}/src/gtest-all.cc
|
||||
|
||||
with ${GTEST_DIR}/include in the system header search path and ${GTEST_DIR}
|
||||
in the normal header search path. Assuming a Linux-like system and gcc,
|
||||
something like the following will do:
|
||||
|
||||
g++ -isystem ${GTEST_DIR}/include -I${GTEST_DIR} \
|
||||
-pthread -c ${GTEST_DIR}/src/gtest-all.cc
|
||||
ar -rv libgtest.a gtest-all.o
|
||||
|
||||
(We need -pthread as Google Test uses threads.)
|
||||
|
||||
Next, you should compile your test source file with
|
||||
${GTEST_DIR}/include in the system header search path, and link it
|
||||
with gtest and any other necessary libraries:
|
||||
|
||||
g++ -isystem ${GTEST_DIR}/include -pthread path/to/your_test.cc libgtest.a \
|
||||
-o your_test
|
||||
|
||||
As an example, the make/ directory contains a Makefile that you can
|
||||
use to build Google Test on systems where GNU make is available
|
||||
(e.g. Linux, Mac OS X, and Cygwin). It doesn't try to build Google
|
||||
Test's own tests. Instead, it just builds the Google Test library and
|
||||
a sample test. You can use it as a starting point for your own build
|
||||
script.
|
||||
|
||||
If the default settings are correct for your environment, the
|
||||
following commands should succeed:
|
||||
|
||||
cd ${GTEST_DIR}/make
|
||||
make
|
||||
./sample1_unittest
|
||||
|
||||
If you see errors, try to tweak the contents of make/Makefile to make
|
||||
them go away. There are instructions in make/Makefile on how to do
|
||||
it.
|
||||
|
||||
### Using CMake ###
|
||||
|
||||
Google Test comes with a CMake build script (CMakeLists.txt) that can
|
||||
be used on a wide range of platforms ("C" stands for cross-platofrm.).
|
||||
If you don't have CMake installed already, you can download it for
|
||||
free from http://www.cmake.org/.
|
||||
|
||||
CMake works by generating native makefiles or build projects that can
|
||||
be used in the compiler environment of your choice. The typical
|
||||
workflow starts with:
|
||||
|
||||
mkdir mybuild # Create a directory to hold the build output.
|
||||
cd mybuild
|
||||
cmake ${GTEST_DIR} # Generate native build scripts.
|
||||
|
||||
If you want to build Google Test's samples, you should replace the
|
||||
last command with
|
||||
|
||||
cmake -Dgtest_build_samples=ON ${GTEST_DIR}
|
||||
|
||||
If you are on a *nix system, you should now see a Makefile in the
|
||||
current directory. Just type 'make' to build gtest.
|
||||
|
||||
If you use Windows and have Vistual Studio installed, a gtest.sln file
|
||||
and several .vcproj files will be created. You can then build them
|
||||
using Visual Studio.
|
||||
|
||||
On Mac OS X with Xcode installed, a .xcodeproj file will be generated.
|
||||
|
||||
### Legacy Build Scripts ###
|
||||
|
||||
Before settling on CMake, we have been providing hand-maintained build
|
||||
projects/scripts for Visual Studio, Xcode, and Autotools. While we
|
||||
continue to provide them for convenience, they are not actively
|
||||
maintained any more. We highly recommend that you follow the
|
||||
instructions in the previous two sections to integrate Google Test
|
||||
with your existing build system.
|
||||
|
||||
If you still need to use the legacy build scripts, here's how:
|
||||
|
||||
The msvc\ folder contains two solutions with Visual C++ projects.
|
||||
Open the gtest.sln or gtest-md.sln file using Visual Studio, and you
|
||||
are ready to build Google Test the same way you build any Visual
|
||||
Studio project. Files that have names ending with -md use DLL
|
||||
versions of Microsoft runtime libraries (the /MD or the /MDd compiler
|
||||
option). Files without that suffix use static versions of the runtime
|
||||
libraries (the /MT or the /MTd option). Please note that one must use
|
||||
the same option to compile both gtest and the test code. If you use
|
||||
Visual Studio 2005 or above, we recommend the -md version as /MD is
|
||||
the default for new projects in these versions of Visual Studio.
|
||||
|
||||
On Mac OS X, open the gtest.xcodeproj in the xcode/ folder using
|
||||
Xcode. Build the "gtest" target. The universal binary framework will
|
||||
end up in your selected build directory (selected in the Xcode
|
||||
"Preferences..." -> "Building" pane and defaults to xcode/build).
|
||||
Alternatively, at the command line, enter:
|
||||
|
||||
xcodebuild
|
||||
|
||||
This will build the "Release" configuration of gtest.framework in your
|
||||
default build location. See the "xcodebuild" man page for more
|
||||
information about building different configurations and building in
|
||||
different locations.
|
||||
|
||||
If you wish to use the Google Test Xcode project with Xcode 4.x and
|
||||
above, you need to either:
|
||||
* update the SDK configuration options in xcode/Config/General.xconfig.
|
||||
Comment options SDKROOT, MACOS_DEPLOYMENT_TARGET, and GCC_VERSION. If
|
||||
you choose this route you lose the ability to target earlier versions
|
||||
of MacOS X.
|
||||
* Install an SDK for an earlier version. This doesn't appear to be
|
||||
supported by Apple, but has been reported to work
|
||||
(http://stackoverflow.com/questions/5378518).
|
||||
|
||||
Tweaking Google Test
|
||||
--------------------
|
||||
|
||||
Google Test can be used in diverse environments. The default
|
||||
configuration may not work (or may not work well) out of the box in
|
||||
some environments. However, you can easily tweak Google Test by
|
||||
defining control macros on the compiler command line. Generally,
|
||||
these macros are named like GTEST_XYZ and you define them to either 1
|
||||
or 0 to enable or disable a certain feature.
|
||||
|
||||
We list the most frequently used macros below. For a complete list,
|
||||
see file include/gtest/internal/gtest-port.h.
|
||||
|
||||
### Choosing a TR1 Tuple Library ###
|
||||
|
||||
Some Google Test features require the C++ Technical Report 1 (TR1)
|
||||
tuple library, which is not yet available with all compilers. The
|
||||
good news is that Google Test implements a subset of TR1 tuple that's
|
||||
enough for its own need, and will automatically use this when the
|
||||
compiler doesn't provide TR1 tuple.
|
||||
|
||||
Usually you don't need to care about which tuple library Google Test
|
||||
uses. However, if your project already uses TR1 tuple, you need to
|
||||
tell Google Test to use the same TR1 tuple library the rest of your
|
||||
project uses, or the two tuple implementations will clash. To do
|
||||
that, add
|
||||
|
||||
-DGTEST_USE_OWN_TR1_TUPLE=0
|
||||
|
||||
to the compiler flags while compiling Google Test and your tests. If
|
||||
you want to force Google Test to use its own tuple library, just add
|
||||
|
||||
-DGTEST_USE_OWN_TR1_TUPLE=1
|
||||
|
||||
to the compiler flags instead.
|
||||
|
||||
If you don't want Google Test to use tuple at all, add
|
||||
|
||||
-DGTEST_HAS_TR1_TUPLE=0
|
||||
|
||||
and all features using tuple will be disabled.
|
||||
|
||||
### Multi-threaded Tests ###
|
||||
|
||||
Google Test is thread-safe where the pthread library is available.
|
||||
After #include "gtest/gtest.h", you can check the GTEST_IS_THREADSAFE
|
||||
macro to see whether this is the case (yes if the macro is #defined to
|
||||
1, no if it's undefined.).
|
||||
|
||||
If Google Test doesn't correctly detect whether pthread is available
|
||||
in your environment, you can force it with
|
||||
|
||||
-DGTEST_HAS_PTHREAD=1
|
||||
|
||||
or
|
||||
|
||||
-DGTEST_HAS_PTHREAD=0
|
||||
|
||||
When Google Test uses pthread, you may need to add flags to your
|
||||
compiler and/or linker to select the pthread library, or you'll get
|
||||
link errors. If you use the CMake script or the deprecated Autotools
|
||||
script, this is taken care of for you. If you use your own build
|
||||
script, you'll need to read your compiler and linker's manual to
|
||||
figure out what flags to add.
|
||||
|
||||
### As a Shared Library (DLL) ###
|
||||
|
||||
Google Test is compact, so most users can build and link it as a
|
||||
static library for the simplicity. You can choose to use Google Test
|
||||
as a shared library (known as a DLL on Windows) if you prefer.
|
||||
|
||||
To compile *gtest* as a shared library, add
|
||||
|
||||
-DGTEST_CREATE_SHARED_LIBRARY=1
|
||||
|
||||
to the compiler flags. You'll also need to tell the linker to produce
|
||||
a shared library instead - consult your linker's manual for how to do
|
||||
it.
|
||||
|
||||
To compile your *tests* that use the gtest shared library, add
|
||||
|
||||
-DGTEST_LINKED_AS_SHARED_LIBRARY=1
|
||||
|
||||
to the compiler flags.
|
||||
|
||||
Note: while the above steps aren't technically necessary today when
|
||||
using some compilers (e.g. GCC), they may become necessary in the
|
||||
future, if we decide to improve the speed of loading the library (see
|
||||
http://gcc.gnu.org/wiki/Visibility for details). Therefore you are
|
||||
recommended to always add the above flags when using Google Test as a
|
||||
shared library. Otherwise a future release of Google Test may break
|
||||
your build script.
|
||||
|
||||
### Avoiding Macro Name Clashes ###
|
||||
|
||||
In C++, macros don't obey namespaces. Therefore two libraries that
|
||||
both define a macro of the same name will clash if you #include both
|
||||
definitions. In case a Google Test macro clashes with another
|
||||
library, you can force Google Test to rename its macro to avoid the
|
||||
conflict.
|
||||
|
||||
Specifically, if both Google Test and some other code define macro
|
||||
FOO, you can add
|
||||
|
||||
-DGTEST_DONT_DEFINE_FOO=1
|
||||
|
||||
to the compiler flags to tell Google Test to change the macro's name
|
||||
from FOO to GTEST_FOO. Currently FOO can be FAIL, SUCCEED, or TEST.
|
||||
For example, with -DGTEST_DONT_DEFINE_TEST=1, you'll need to write
|
||||
|
||||
GTEST_TEST(SomeTest, DoesThis) { ... }
|
||||
|
||||
instead of
|
||||
|
||||
TEST(SomeTest, DoesThis) { ... }
|
||||
|
||||
in order to define a test.
|
||||
|
||||
Upgrating from an Earlier Version
|
||||
---------------------------------
|
||||
|
||||
We strive to keep Google Test releases backward compatible.
|
||||
Sometimes, though, we have to make some breaking changes for the
|
||||
users' long-term benefits. This section describes what you'll need to
|
||||
do if you are upgrading from an earlier version of Google Test.
|
||||
|
||||
### Upgrading from 1.3.0 or Earlier ###
|
||||
|
||||
You may need to explicitly enable or disable Google Test's own TR1
|
||||
tuple library. See the instructions in section "Choosing a TR1 Tuple
|
||||
Library".
|
||||
|
||||
### Upgrading from 1.4.0 or Earlier ###
|
||||
|
||||
The Autotools build script (configure + make) is no longer officially
|
||||
supportted. You are encouraged to migrate to your own build system or
|
||||
use CMake. If you still need to use Autotools, you can find
|
||||
instructions in the README file from Google Test 1.4.0.
|
||||
|
||||
On platforms where the pthread library is available, Google Test uses
|
||||
it in order to be thread-safe. See the "Multi-threaded Tests" section
|
||||
for what this means to your build script.
|
||||
|
||||
If you use Microsoft Visual C++ 7.1 with exceptions disabled, Google
|
||||
Test will no longer compile. This should affect very few people, as a
|
||||
large portion of STL (including <string>) doesn't compile in this mode
|
||||
anyway. We decided to stop supporting it in order to greatly simplify
|
||||
Google Test's implementation.
|
||||
|
||||
Developing Google Test
|
||||
----------------------
|
||||
|
||||
This section discusses how to make your own changes to Google Test.
|
||||
|
||||
### Testing Google Test Itself ###
|
||||
|
||||
To make sure your changes work as intended and don't break existing
|
||||
functionality, you'll want to compile and run Google Test's own tests.
|
||||
For that you can use CMake:
|
||||
|
||||
mkdir mybuild
|
||||
cd mybuild
|
||||
cmake -Dgtest_build_tests=ON ${GTEST_DIR}
|
||||
|
||||
Make sure you have Python installed, as some of Google Test's tests
|
||||
are written in Python. If the cmake command complains about not being
|
||||
able to find Python ("Could NOT find PythonInterp (missing:
|
||||
PYTHON_EXECUTABLE)"), try telling it explicitly where your Python
|
||||
executable can be found:
|
||||
|
||||
cmake -DPYTHON_EXECUTABLE=path/to/python -Dgtest_build_tests=ON ${GTEST_DIR}
|
||||
|
||||
Next, you can build Google Test and all of its own tests. On *nix,
|
||||
this is usually done by 'make'. To run the tests, do
|
||||
|
||||
make test
|
||||
|
||||
All tests should pass.
|
||||
|
||||
### Regenerating Source Files ###
|
||||
|
||||
Some of Google Test's source files are generated from templates (not
|
||||
in the C++ sense) using a script. A template file is named FOO.pump,
|
||||
where FOO is the name of the file it will generate. For example, the
|
||||
file include/gtest/internal/gtest-type-util.h.pump is used to generate
|
||||
gtest-type-util.h in the same directory.
|
||||
|
||||
Normally you don't need to worry about regenerating the source files,
|
||||
unless you need to modify them. In that case, you should modify the
|
||||
corresponding .pump files instead and run the pump.py Python script to
|
||||
regenerate them. You can find pump.py in the scripts/ directory.
|
||||
Read the Pump manual [2] for how to use it.
|
||||
|
||||
[2] http://code.google.com/p/googletest/wiki/PumpManual
|
||||
|
||||
### Contributing a Patch ###
|
||||
|
||||
We welcome patches. Please read the Google Test developer's guide [3]
|
||||
for how you can contribute. In particular, make sure you have signed
|
||||
the Contributor License Agreement, or we won't be able to accept the
|
||||
patch.
|
||||
|
||||
[3] http://code.google.com/p/googletest/wiki/GoogleTestDevGuide
|
||||
|
||||
Happy testing!
|
||||
280
third_party/googletest/src/README.md
vendored
Normal file
280
third_party/googletest/src/README.md
vendored
Normal file
@@ -0,0 +1,280 @@
|
||||
|
||||
### Generic Build Instructions ###
|
||||
|
||||
#### Setup ####
|
||||
|
||||
To build Google Test and your tests that use it, you need to tell your
|
||||
build system where to find its headers and source files. The exact
|
||||
way to do it depends on which build system you use, and is usually
|
||||
straightforward.
|
||||
|
||||
#### Build ####
|
||||
|
||||
Suppose you put Google Test in directory `${GTEST_DIR}`. To build it,
|
||||
create a library build target (or a project as called by Visual Studio
|
||||
and Xcode) to compile
|
||||
|
||||
${GTEST_DIR}/src/gtest-all.cc
|
||||
|
||||
with `${GTEST_DIR}/include` in the system header search path and `${GTEST_DIR}`
|
||||
in the normal header search path. Assuming a Linux-like system and gcc,
|
||||
something like the following will do:
|
||||
|
||||
g++ -isystem ${GTEST_DIR}/include -I${GTEST_DIR} \
|
||||
-pthread -c ${GTEST_DIR}/src/gtest-all.cc
|
||||
ar -rv libgtest.a gtest-all.o
|
||||
|
||||
(We need `-pthread` as Google Test uses threads.)
|
||||
|
||||
Next, you should compile your test source file with
|
||||
`${GTEST_DIR}/include` in the system header search path, and link it
|
||||
with gtest and any other necessary libraries:
|
||||
|
||||
g++ -isystem ${GTEST_DIR}/include -pthread path/to/your_test.cc libgtest.a \
|
||||
-o your_test
|
||||
|
||||
As an example, the make/ directory contains a Makefile that you can
|
||||
use to build Google Test on systems where GNU make is available
|
||||
(e.g. Linux, Mac OS X, and Cygwin). It doesn't try to build Google
|
||||
Test's own tests. Instead, it just builds the Google Test library and
|
||||
a sample test. You can use it as a starting point for your own build
|
||||
script.
|
||||
|
||||
If the default settings are correct for your environment, the
|
||||
following commands should succeed:
|
||||
|
||||
cd ${GTEST_DIR}/make
|
||||
make
|
||||
./sample1_unittest
|
||||
|
||||
If you see errors, try to tweak the contents of `make/Makefile` to make
|
||||
them go away. There are instructions in `make/Makefile` on how to do
|
||||
it.
|
||||
|
||||
### Using CMake ###
|
||||
|
||||
Google Test comes with a CMake build script (
|
||||
[CMakeLists.txt](CMakeLists.txt)) that can be used on a wide range of platforms ("C" stands for
|
||||
cross-platform.). If you don't have CMake installed already, you can
|
||||
download it for free from <http://www.cmake.org/>.
|
||||
|
||||
CMake works by generating native makefiles or build projects that can
|
||||
be used in the compiler environment of your choice. The typical
|
||||
workflow starts with:
|
||||
|
||||
mkdir mybuild # Create a directory to hold the build output.
|
||||
cd mybuild
|
||||
cmake ${GTEST_DIR} # Generate native build scripts.
|
||||
|
||||
If you want to build Google Test's samples, you should replace the
|
||||
last command with
|
||||
|
||||
cmake -Dgtest_build_samples=ON ${GTEST_DIR}
|
||||
|
||||
If you are on a \*nix system, you should now see a Makefile in the
|
||||
current directory. Just type 'make' to build gtest.
|
||||
|
||||
If you use Windows and have Visual Studio installed, a `gtest.sln` file
|
||||
and several `.vcproj` files will be created. You can then build them
|
||||
using Visual Studio.
|
||||
|
||||
On Mac OS X with Xcode installed, a `.xcodeproj` file will be generated.
|
||||
|
||||
### Legacy Build Scripts ###
|
||||
|
||||
Before settling on CMake, we have been providing hand-maintained build
|
||||
projects/scripts for Visual Studio, Xcode, and Autotools. While we
|
||||
continue to provide them for convenience, they are not actively
|
||||
maintained any more. We highly recommend that you follow the
|
||||
instructions in the previous two sections to integrate Google Test
|
||||
with your existing build system.
|
||||
|
||||
If you still need to use the legacy build scripts, here's how:
|
||||
|
||||
The msvc\ folder contains two solutions with Visual C++ projects.
|
||||
Open the `gtest.sln` or `gtest-md.sln` file using Visual Studio, and you
|
||||
are ready to build Google Test the same way you build any Visual
|
||||
Studio project. Files that have names ending with -md use DLL
|
||||
versions of Microsoft runtime libraries (the /MD or the /MDd compiler
|
||||
option). Files without that suffix use static versions of the runtime
|
||||
libraries (the /MT or the /MTd option). Please note that one must use
|
||||
the same option to compile both gtest and the test code. If you use
|
||||
Visual Studio 2005 or above, we recommend the -md version as /MD is
|
||||
the default for new projects in these versions of Visual Studio.
|
||||
|
||||
On Mac OS X, open the `gtest.xcodeproj` in the `xcode/` folder using
|
||||
Xcode. Build the "gtest" target. The universal binary framework will
|
||||
end up in your selected build directory (selected in the Xcode
|
||||
"Preferences..." -> "Building" pane and defaults to xcode/build).
|
||||
Alternatively, at the command line, enter:
|
||||
|
||||
xcodebuild
|
||||
|
||||
This will build the "Release" configuration of gtest.framework in your
|
||||
default build location. See the "xcodebuild" man page for more
|
||||
information about building different configurations and building in
|
||||
different locations.
|
||||
|
||||
If you wish to use the Google Test Xcode project with Xcode 4.x and
|
||||
above, you need to either:
|
||||
|
||||
* update the SDK configuration options in xcode/Config/General.xconfig.
|
||||
Comment options `SDKROOT`, `MACOS_DEPLOYMENT_TARGET`, and `GCC_VERSION`. If
|
||||
you choose this route you lose the ability to target earlier versions
|
||||
of MacOS X.
|
||||
* Install an SDK for an earlier version. This doesn't appear to be
|
||||
supported by Apple, but has been reported to work
|
||||
(http://stackoverflow.com/questions/5378518).
|
||||
|
||||
### Tweaking Google Test ###
|
||||
|
||||
Google Test can be used in diverse environments. The default
|
||||
configuration may not work (or may not work well) out of the box in
|
||||
some environments. However, you can easily tweak Google Test by
|
||||
defining control macros on the compiler command line. Generally,
|
||||
these macros are named like `GTEST_XYZ` and you define them to either 1
|
||||
or 0 to enable or disable a certain feature.
|
||||
|
||||
We list the most frequently used macros below. For a complete list,
|
||||
see file [include/gtest/internal/gtest-port.h](include/gtest/internal/gtest-port.h).
|
||||
|
||||
### Choosing a TR1 Tuple Library ###
|
||||
|
||||
Some Google Test features require the C++ Technical Report 1 (TR1)
|
||||
tuple library, which is not yet available with all compilers. The
|
||||
good news is that Google Test implements a subset of TR1 tuple that's
|
||||
enough for its own need, and will automatically use this when the
|
||||
compiler doesn't provide TR1 tuple.
|
||||
|
||||
Usually you don't need to care about which tuple library Google Test
|
||||
uses. However, if your project already uses TR1 tuple, you need to
|
||||
tell Google Test to use the same TR1 tuple library the rest of your
|
||||
project uses, or the two tuple implementations will clash. To do
|
||||
that, add
|
||||
|
||||
-DGTEST_USE_OWN_TR1_TUPLE=0
|
||||
|
||||
to the compiler flags while compiling Google Test and your tests. If
|
||||
you want to force Google Test to use its own tuple library, just add
|
||||
|
||||
-DGTEST_USE_OWN_TR1_TUPLE=1
|
||||
|
||||
to the compiler flags instead.
|
||||
|
||||
If you don't want Google Test to use tuple at all, add
|
||||
|
||||
-DGTEST_HAS_TR1_TUPLE=0
|
||||
|
||||
and all features using tuple will be disabled.
|
||||
|
||||
### Multi-threaded Tests ###
|
||||
|
||||
Google Test is thread-safe where the pthread library is available.
|
||||
After `#include "gtest/gtest.h"`, you can check the `GTEST_IS_THREADSAFE`
|
||||
macro to see whether this is the case (yes if the macro is `#defined` to
|
||||
1, no if it's undefined.).
|
||||
|
||||
If Google Test doesn't correctly detect whether pthread is available
|
||||
in your environment, you can force it with
|
||||
|
||||
-DGTEST_HAS_PTHREAD=1
|
||||
|
||||
or
|
||||
|
||||
-DGTEST_HAS_PTHREAD=0
|
||||
|
||||
When Google Test uses pthread, you may need to add flags to your
|
||||
compiler and/or linker to select the pthread library, or you'll get
|
||||
link errors. If you use the CMake script or the deprecated Autotools
|
||||
script, this is taken care of for you. If you use your own build
|
||||
script, you'll need to read your compiler and linker's manual to
|
||||
figure out what flags to add.
|
||||
|
||||
### As a Shared Library (DLL) ###
|
||||
|
||||
Google Test is compact, so most users can build and link it as a
|
||||
static library for the simplicity. You can choose to use Google Test
|
||||
as a shared library (known as a DLL on Windows) if you prefer.
|
||||
|
||||
To compile *gtest* as a shared library, add
|
||||
|
||||
-DGTEST_CREATE_SHARED_LIBRARY=1
|
||||
|
||||
to the compiler flags. You'll also need to tell the linker to produce
|
||||
a shared library instead - consult your linker's manual for how to do
|
||||
it.
|
||||
|
||||
To compile your *tests* that use the gtest shared library, add
|
||||
|
||||
-DGTEST_LINKED_AS_SHARED_LIBRARY=1
|
||||
|
||||
to the compiler flags.
|
||||
|
||||
Note: while the above steps aren't technically necessary today when
|
||||
using some compilers (e.g. GCC), they may become necessary in the
|
||||
future, if we decide to improve the speed of loading the library (see
|
||||
<http://gcc.gnu.org/wiki/Visibility> for details). Therefore you are
|
||||
recommended to always add the above flags when using Google Test as a
|
||||
shared library. Otherwise a future release of Google Test may break
|
||||
your build script.
|
||||
|
||||
### Avoiding Macro Name Clashes ###
|
||||
|
||||
In C++, macros don't obey namespaces. Therefore two libraries that
|
||||
both define a macro of the same name will clash if you `#include` both
|
||||
definitions. In case a Google Test macro clashes with another
|
||||
library, you can force Google Test to rename its macro to avoid the
|
||||
conflict.
|
||||
|
||||
Specifically, if both Google Test and some other code define macro
|
||||
FOO, you can add
|
||||
|
||||
-DGTEST_DONT_DEFINE_FOO=1
|
||||
|
||||
to the compiler flags to tell Google Test to change the macro's name
|
||||
from `FOO` to `GTEST_FOO`. Currently `FOO` can be `FAIL`, `SUCCEED`,
|
||||
or `TEST`. For example, with `-DGTEST_DONT_DEFINE_TEST=1`, you'll
|
||||
need to write
|
||||
|
||||
GTEST_TEST(SomeTest, DoesThis) { ... }
|
||||
|
||||
instead of
|
||||
|
||||
TEST(SomeTest, DoesThis) { ... }
|
||||
|
||||
in order to define a test.
|
||||
|
||||
## Developing Google Test ##
|
||||
|
||||
This section discusses how to make your own changes to Google Test.
|
||||
|
||||
### Testing Google Test Itself ###
|
||||
|
||||
To make sure your changes work as intended and don't break existing
|
||||
functionality, you'll want to compile and run Google Test's own tests.
|
||||
For that you can use CMake:
|
||||
|
||||
mkdir mybuild
|
||||
cd mybuild
|
||||
cmake -Dgtest_build_tests=ON ${GTEST_DIR}
|
||||
|
||||
Make sure you have Python installed, as some of Google Test's tests
|
||||
are written in Python. If the cmake command complains about not being
|
||||
able to find Python (`Could NOT find PythonInterp (missing:
|
||||
PYTHON_EXECUTABLE)`), try telling it explicitly where your Python
|
||||
executable can be found:
|
||||
|
||||
cmake -DPYTHON_EXECUTABLE=path/to/python -Dgtest_build_tests=ON ${GTEST_DIR}
|
||||
|
||||
Next, you can build Google Test and all of its own tests. On \*nix,
|
||||
this is usually done by 'make'. To run the tests, do
|
||||
|
||||
make test
|
||||
|
||||
All tests should pass.
|
||||
|
||||
Normally you don't need to worry about regenerating the source files,
|
||||
unless you need to modify them. In that case, you should modify the
|
||||
corresponding .pump files instead and run the pump.py Python script to
|
||||
regenerate them. You can find pump.py in the [scripts/](scripts/) directory.
|
||||
Read the [Pump manual](docs/PumpManual.md) for how to use it.
|
||||
294
third_party/googletest/src/include/gtest/gtest-death-test.h
vendored
Normal file
294
third_party/googletest/src/include/gtest/gtest-death-test.h
vendored
Normal file
@@ -0,0 +1,294 @@
|
||||
// Copyright 2005, Google Inc.
|
||||
// All rights reserved.
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions are
|
||||
// met:
|
||||
//
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above
|
||||
// copyright notice, this list of conditions and the following disclaimer
|
||||
// in the documentation and/or other materials provided with the
|
||||
// distribution.
|
||||
// * Neither the name of Google Inc. nor the names of its
|
||||
// contributors may be used to endorse or promote products derived from
|
||||
// this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
//
|
||||
// Author: wan@google.com (Zhanyong Wan)
|
||||
//
|
||||
// The Google C++ Testing Framework (Google Test)
|
||||
//
|
||||
// This header file defines the public API for death tests. It is
|
||||
// #included by gtest.h so a user doesn't need to include this
|
||||
// directly.
|
||||
|
||||
#ifndef GTEST_INCLUDE_GTEST_GTEST_DEATH_TEST_H_
|
||||
#define GTEST_INCLUDE_GTEST_GTEST_DEATH_TEST_H_
|
||||
|
||||
#include "gtest/internal/gtest-death-test-internal.h"
|
||||
|
||||
namespace testing {
|
||||
|
||||
// This flag controls the style of death tests. Valid values are "threadsafe",
|
||||
// meaning that the death test child process will re-execute the test binary
|
||||
// from the start, running only a single death test, or "fast",
|
||||
// meaning that the child process will execute the test logic immediately
|
||||
// after forking.
|
||||
GTEST_DECLARE_string_(death_test_style);
|
||||
|
||||
#if GTEST_HAS_DEATH_TEST
|
||||
|
||||
namespace internal {
|
||||
|
||||
// Returns a Boolean value indicating whether the caller is currently
|
||||
// executing in the context of the death test child process. Tools such as
|
||||
// Valgrind heap checkers may need this to modify their behavior in death
|
||||
// tests. IMPORTANT: This is an internal utility. Using it may break the
|
||||
// implementation of death tests. User code MUST NOT use it.
|
||||
GTEST_API_ bool InDeathTestChild();
|
||||
|
||||
} // namespace internal
|
||||
|
||||
// The following macros are useful for writing death tests.
|
||||
|
||||
// Here's what happens when an ASSERT_DEATH* or EXPECT_DEATH* is
|
||||
// executed:
|
||||
//
|
||||
// 1. It generates a warning if there is more than one active
|
||||
// thread. This is because it's safe to fork() or clone() only
|
||||
// when there is a single thread.
|
||||
//
|
||||
// 2. The parent process clone()s a sub-process and runs the death
|
||||
// test in it; the sub-process exits with code 0 at the end of the
|
||||
// death test, if it hasn't exited already.
|
||||
//
|
||||
// 3. The parent process waits for the sub-process to terminate.
|
||||
//
|
||||
// 4. The parent process checks the exit code and error message of
|
||||
// the sub-process.
|
||||
//
|
||||
// Examples:
|
||||
//
|
||||
// ASSERT_DEATH(server.SendMessage(56, "Hello"), "Invalid port number");
|
||||
// for (int i = 0; i < 5; i++) {
|
||||
// EXPECT_DEATH(server.ProcessRequest(i),
|
||||
// "Invalid request .* in ProcessRequest()")
|
||||
// << "Failed to die on request " << i;
|
||||
// }
|
||||
//
|
||||
// ASSERT_EXIT(server.ExitNow(), ::testing::ExitedWithCode(0), "Exiting");
|
||||
//
|
||||
// bool KilledBySIGHUP(int exit_code) {
|
||||
// return WIFSIGNALED(exit_code) && WTERMSIG(exit_code) == SIGHUP;
|
||||
// }
|
||||
//
|
||||
// ASSERT_EXIT(client.HangUpServer(), KilledBySIGHUP, "Hanging up!");
|
||||
//
|
||||
// On the regular expressions used in death tests:
|
||||
//
|
||||
// On POSIX-compliant systems (*nix), we use the <regex.h> library,
|
||||
// which uses the POSIX extended regex syntax.
|
||||
//
|
||||
// On other platforms (e.g. Windows), we only support a simple regex
|
||||
// syntax implemented as part of Google Test. This limited
|
||||
// implementation should be enough most of the time when writing
|
||||
// death tests; though it lacks many features you can find in PCRE
|
||||
// or POSIX extended regex syntax. For example, we don't support
|
||||
// union ("x|y"), grouping ("(xy)"), brackets ("[xy]"), and
|
||||
// repetition count ("x{5,7}"), among others.
|
||||
//
|
||||
// Below is the syntax that we do support. We chose it to be a
|
||||
// subset of both PCRE and POSIX extended regex, so it's easy to
|
||||
// learn wherever you come from. In the following: 'A' denotes a
|
||||
// literal character, period (.), or a single \\ escape sequence;
|
||||
// 'x' and 'y' denote regular expressions; 'm' and 'n' are for
|
||||
// natural numbers.
|
||||
//
|
||||
// c matches any literal character c
|
||||
// \\d matches any decimal digit
|
||||
// \\D matches any character that's not a decimal digit
|
||||
// \\f matches \f
|
||||
// \\n matches \n
|
||||
// \\r matches \r
|
||||
// \\s matches any ASCII whitespace, including \n
|
||||
// \\S matches any character that's not a whitespace
|
||||
// \\t matches \t
|
||||
// \\v matches \v
|
||||
// \\w matches any letter, _, or decimal digit
|
||||
// \\W matches any character that \\w doesn't match
|
||||
// \\c matches any literal character c, which must be a punctuation
|
||||
// . matches any single character except \n
|
||||
// A? matches 0 or 1 occurrences of A
|
||||
// A* matches 0 or many occurrences of A
|
||||
// A+ matches 1 or many occurrences of A
|
||||
// ^ matches the beginning of a string (not that of each line)
|
||||
// $ matches the end of a string (not that of each line)
|
||||
// xy matches x followed by y
|
||||
//
|
||||
// If you accidentally use PCRE or POSIX extended regex features
|
||||
// not implemented by us, you will get a run-time failure. In that
|
||||
// case, please try to rewrite your regular expression within the
|
||||
// above syntax.
|
||||
//
|
||||
// This implementation is *not* meant to be as highly tuned or robust
|
||||
// as a compiled regex library, but should perform well enough for a
|
||||
// death test, which already incurs significant overhead by launching
|
||||
// a child process.
|
||||
//
|
||||
// Known caveats:
|
||||
//
|
||||
// A "threadsafe" style death test obtains the path to the test
|
||||
// program from argv[0] and re-executes it in the sub-process. For
|
||||
// simplicity, the current implementation doesn't search the PATH
|
||||
// when launching the sub-process. This means that the user must
|
||||
// invoke the test program via a path that contains at least one
|
||||
// path separator (e.g. path/to/foo_test and
|
||||
// /absolute/path/to/bar_test are fine, but foo_test is not). This
|
||||
// is rarely a problem as people usually don't put the test binary
|
||||
// directory in PATH.
|
||||
//
|
||||
// TODO(wan@google.com): make thread-safe death tests search the PATH.
|
||||
|
||||
// Asserts that a given statement causes the program to exit, with an
|
||||
// integer exit status that satisfies predicate, and emitting error output
|
||||
// that matches regex.
|
||||
# define ASSERT_EXIT(statement, predicate, regex) \
|
||||
GTEST_DEATH_TEST_(statement, predicate, regex, GTEST_FATAL_FAILURE_)
|
||||
|
||||
// Like ASSERT_EXIT, but continues on to successive tests in the
|
||||
// test case, if any:
|
||||
# define EXPECT_EXIT(statement, predicate, regex) \
|
||||
GTEST_DEATH_TEST_(statement, predicate, regex, GTEST_NONFATAL_FAILURE_)
|
||||
|
||||
// Asserts that a given statement causes the program to exit, either by
|
||||
// explicitly exiting with a nonzero exit code or being killed by a
|
||||
// signal, and emitting error output that matches regex.
|
||||
# define ASSERT_DEATH(statement, regex) \
|
||||
ASSERT_EXIT(statement, ::testing::internal::ExitedUnsuccessfully, regex)
|
||||
|
||||
// Like ASSERT_DEATH, but continues on to successive tests in the
|
||||
// test case, if any:
|
||||
# define EXPECT_DEATH(statement, regex) \
|
||||
EXPECT_EXIT(statement, ::testing::internal::ExitedUnsuccessfully, regex)
|
||||
|
||||
// Two predicate classes that can be used in {ASSERT,EXPECT}_EXIT*:
|
||||
|
||||
// Tests that an exit code describes a normal exit with a given exit code.
|
||||
class GTEST_API_ ExitedWithCode {
|
||||
public:
|
||||
explicit ExitedWithCode(int exit_code);
|
||||
bool operator()(int exit_status) const;
|
||||
private:
|
||||
// No implementation - assignment is unsupported.
|
||||
void operator=(const ExitedWithCode& other);
|
||||
|
||||
const int exit_code_;
|
||||
};
|
||||
|
||||
# if !GTEST_OS_WINDOWS
|
||||
// Tests that an exit code describes an exit due to termination by a
|
||||
// given signal.
|
||||
class GTEST_API_ KilledBySignal {
|
||||
public:
|
||||
explicit KilledBySignal(int signum);
|
||||
bool operator()(int exit_status) const;
|
||||
private:
|
||||
const int signum_;
|
||||
};
|
||||
# endif // !GTEST_OS_WINDOWS
|
||||
|
||||
// EXPECT_DEBUG_DEATH asserts that the given statements die in debug mode.
|
||||
// The death testing framework causes this to have interesting semantics,
|
||||
// since the sideeffects of the call are only visible in opt mode, and not
|
||||
// in debug mode.
|
||||
//
|
||||
// In practice, this can be used to test functions that utilize the
|
||||
// LOG(DFATAL) macro using the following style:
|
||||
//
|
||||
// int DieInDebugOr12(int* sideeffect) {
|
||||
// if (sideeffect) {
|
||||
// *sideeffect = 12;
|
||||
// }
|
||||
// LOG(DFATAL) << "death";
|
||||
// return 12;
|
||||
// }
|
||||
//
|
||||
// TEST(TestCase, TestDieOr12WorksInDgbAndOpt) {
|
||||
// int sideeffect = 0;
|
||||
// // Only asserts in dbg.
|
||||
// EXPECT_DEBUG_DEATH(DieInDebugOr12(&sideeffect), "death");
|
||||
//
|
||||
// #ifdef NDEBUG
|
||||
// // opt-mode has sideeffect visible.
|
||||
// EXPECT_EQ(12, sideeffect);
|
||||
// #else
|
||||
// // dbg-mode no visible sideeffect.
|
||||
// EXPECT_EQ(0, sideeffect);
|
||||
// #endif
|
||||
// }
|
||||
//
|
||||
// This will assert that DieInDebugReturn12InOpt() crashes in debug
|
||||
// mode, usually due to a DCHECK or LOG(DFATAL), but returns the
|
||||
// appropriate fallback value (12 in this case) in opt mode. If you
|
||||
// need to test that a function has appropriate side-effects in opt
|
||||
// mode, include assertions against the side-effects. A general
|
||||
// pattern for this is:
|
||||
//
|
||||
// EXPECT_DEBUG_DEATH({
|
||||
// // Side-effects here will have an effect after this statement in
|
||||
// // opt mode, but none in debug mode.
|
||||
// EXPECT_EQ(12, DieInDebugOr12(&sideeffect));
|
||||
// }, "death");
|
||||
//
|
||||
# ifdef NDEBUG
|
||||
|
||||
# define EXPECT_DEBUG_DEATH(statement, regex) \
|
||||
GTEST_EXECUTE_STATEMENT_(statement, regex)
|
||||
|
||||
# define ASSERT_DEBUG_DEATH(statement, regex) \
|
||||
GTEST_EXECUTE_STATEMENT_(statement, regex)
|
||||
|
||||
# else
|
||||
|
||||
# define EXPECT_DEBUG_DEATH(statement, regex) \
|
||||
EXPECT_DEATH(statement, regex)
|
||||
|
||||
# define ASSERT_DEBUG_DEATH(statement, regex) \
|
||||
ASSERT_DEATH(statement, regex)
|
||||
|
||||
# endif // NDEBUG for EXPECT_DEBUG_DEATH
|
||||
#endif // GTEST_HAS_DEATH_TEST
|
||||
|
||||
// EXPECT_DEATH_IF_SUPPORTED(statement, regex) and
|
||||
// ASSERT_DEATH_IF_SUPPORTED(statement, regex) expand to real death tests if
|
||||
// death tests are supported; otherwise they just issue a warning. This is
|
||||
// useful when you are combining death test assertions with normal test
|
||||
// assertions in one test.
|
||||
#if GTEST_HAS_DEATH_TEST
|
||||
# define EXPECT_DEATH_IF_SUPPORTED(statement, regex) \
|
||||
EXPECT_DEATH(statement, regex)
|
||||
# define ASSERT_DEATH_IF_SUPPORTED(statement, regex) \
|
||||
ASSERT_DEATH(statement, regex)
|
||||
#else
|
||||
# define EXPECT_DEATH_IF_SUPPORTED(statement, regex) \
|
||||
GTEST_UNSUPPORTED_DEATH_TEST_(statement, regex, )
|
||||
# define ASSERT_DEATH_IF_SUPPORTED(statement, regex) \
|
||||
GTEST_UNSUPPORTED_DEATH_TEST_(statement, regex, return)
|
||||
#endif
|
||||
|
||||
} // namespace testing
|
||||
|
||||
#endif // GTEST_INCLUDE_GTEST_GTEST_DEATH_TEST_H_
|
||||
250
third_party/googletest/src/include/gtest/gtest-message.h
vendored
Normal file
250
third_party/googletest/src/include/gtest/gtest-message.h
vendored
Normal file
@@ -0,0 +1,250 @@
|
||||
// Copyright 2005, Google Inc.
|
||||
// All rights reserved.
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions are
|
||||
// met:
|
||||
//
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above
|
||||
// copyright notice, this list of conditions and the following disclaimer
|
||||
// in the documentation and/or other materials provided with the
|
||||
// distribution.
|
||||
// * Neither the name of Google Inc. nor the names of its
|
||||
// contributors may be used to endorse or promote products derived from
|
||||
// this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
//
|
||||
// Author: wan@google.com (Zhanyong Wan)
|
||||
//
|
||||
// The Google C++ Testing Framework (Google Test)
|
||||
//
|
||||
// This header file defines the Message class.
|
||||
//
|
||||
// IMPORTANT NOTE: Due to limitation of the C++ language, we have to
|
||||
// leave some internal implementation details in this header file.
|
||||
// They are clearly marked by comments like this:
|
||||
//
|
||||
// // INTERNAL IMPLEMENTATION - DO NOT USE IN A USER PROGRAM.
|
||||
//
|
||||
// Such code is NOT meant to be used by a user directly, and is subject
|
||||
// to CHANGE WITHOUT NOTICE. Therefore DO NOT DEPEND ON IT in a user
|
||||
// program!
|
||||
|
||||
#ifndef GTEST_INCLUDE_GTEST_GTEST_MESSAGE_H_
|
||||
#define GTEST_INCLUDE_GTEST_GTEST_MESSAGE_H_
|
||||
|
||||
#include <limits>
|
||||
|
||||
#include "gtest/internal/gtest-port.h"
|
||||
|
||||
// Ensures that there is at least one operator<< in the global namespace.
|
||||
// See Message& operator<<(...) below for why.
|
||||
void operator<<(const testing::internal::Secret&, int);
|
||||
|
||||
namespace testing {
|
||||
|
||||
// The Message class works like an ostream repeater.
|
||||
//
|
||||
// Typical usage:
|
||||
//
|
||||
// 1. You stream a bunch of values to a Message object.
|
||||
// It will remember the text in a stringstream.
|
||||
// 2. Then you stream the Message object to an ostream.
|
||||
// This causes the text in the Message to be streamed
|
||||
// to the ostream.
|
||||
//
|
||||
// For example;
|
||||
//
|
||||
// testing::Message foo;
|
||||
// foo << 1 << " != " << 2;
|
||||
// std::cout << foo;
|
||||
//
|
||||
// will print "1 != 2".
|
||||
//
|
||||
// Message is not intended to be inherited from. In particular, its
|
||||
// destructor is not virtual.
|
||||
//
|
||||
// Note that stringstream behaves differently in gcc and in MSVC. You
|
||||
// can stream a NULL char pointer to it in the former, but not in the
|
||||
// latter (it causes an access violation if you do). The Message
|
||||
// class hides this difference by treating a NULL char pointer as
|
||||
// "(null)".
|
||||
class GTEST_API_ Message {
|
||||
private:
|
||||
// The type of basic IO manipulators (endl, ends, and flush) for
|
||||
// narrow streams.
|
||||
typedef std::ostream& (*BasicNarrowIoManip)(std::ostream&);
|
||||
|
||||
public:
|
||||
// Constructs an empty Message.
|
||||
Message();
|
||||
|
||||
// Copy constructor.
|
||||
Message(const Message& msg) : ss_(new ::std::stringstream) { // NOLINT
|
||||
*ss_ << msg.GetString();
|
||||
}
|
||||
|
||||
// Constructs a Message from a C-string.
|
||||
explicit Message(const char* str) : ss_(new ::std::stringstream) {
|
||||
*ss_ << str;
|
||||
}
|
||||
|
||||
#if GTEST_OS_SYMBIAN
|
||||
// Streams a value (either a pointer or not) to this object.
|
||||
template <typename T>
|
||||
inline Message& operator <<(const T& value) {
|
||||
StreamHelper(typename internal::is_pointer<T>::type(), value);
|
||||
return *this;
|
||||
}
|
||||
#else
|
||||
// Streams a non-pointer value to this object.
|
||||
template <typename T>
|
||||
inline Message& operator <<(const T& val) {
|
||||
// Some libraries overload << for STL containers. These
|
||||
// overloads are defined in the global namespace instead of ::std.
|
||||
//
|
||||
// C++'s symbol lookup rule (i.e. Koenig lookup) says that these
|
||||
// overloads are visible in either the std namespace or the global
|
||||
// namespace, but not other namespaces, including the testing
|
||||
// namespace which Google Test's Message class is in.
|
||||
//
|
||||
// To allow STL containers (and other types that has a << operator
|
||||
// defined in the global namespace) to be used in Google Test
|
||||
// assertions, testing::Message must access the custom << operator
|
||||
// from the global namespace. With this using declaration,
|
||||
// overloads of << defined in the global namespace and those
|
||||
// visible via Koenig lookup are both exposed in this function.
|
||||
using ::operator <<;
|
||||
*ss_ << val;
|
||||
return *this;
|
||||
}
|
||||
|
||||
// Streams a pointer value to this object.
|
||||
//
|
||||
// This function is an overload of the previous one. When you
|
||||
// stream a pointer to a Message, this definition will be used as it
|
||||
// is more specialized. (The C++ Standard, section
|
||||
// [temp.func.order].) If you stream a non-pointer, then the
|
||||
// previous definition will be used.
|
||||
//
|
||||
// The reason for this overload is that streaming a NULL pointer to
|
||||
// ostream is undefined behavior. Depending on the compiler, you
|
||||
// may get "0", "(nil)", "(null)", or an access violation. To
|
||||
// ensure consistent result across compilers, we always treat NULL
|
||||
// as "(null)".
|
||||
template <typename T>
|
||||
inline Message& operator <<(T* const& pointer) { // NOLINT
|
||||
if (pointer == NULL) {
|
||||
*ss_ << "(null)";
|
||||
} else {
|
||||
*ss_ << pointer;
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
#endif // GTEST_OS_SYMBIAN
|
||||
|
||||
// Since the basic IO manipulators are overloaded for both narrow
|
||||
// and wide streams, we have to provide this specialized definition
|
||||
// of operator <<, even though its body is the same as the
|
||||
// templatized version above. Without this definition, streaming
|
||||
// endl or other basic IO manipulators to Message will confuse the
|
||||
// compiler.
|
||||
Message& operator <<(BasicNarrowIoManip val) {
|
||||
*ss_ << val;
|
||||
return *this;
|
||||
}
|
||||
|
||||
// Instead of 1/0, we want to see true/false for bool values.
|
||||
Message& operator <<(bool b) {
|
||||
return *this << (b ? "true" : "false");
|
||||
}
|
||||
|
||||
// These two overloads allow streaming a wide C string to a Message
|
||||
// using the UTF-8 encoding.
|
||||
Message& operator <<(const wchar_t* wide_c_str);
|
||||
Message& operator <<(wchar_t* wide_c_str);
|
||||
|
||||
#if GTEST_HAS_STD_WSTRING
|
||||
// Converts the given wide string to a narrow string using the UTF-8
|
||||
// encoding, and streams the result to this Message object.
|
||||
Message& operator <<(const ::std::wstring& wstr);
|
||||
#endif // GTEST_HAS_STD_WSTRING
|
||||
|
||||
#if GTEST_HAS_GLOBAL_WSTRING
|
||||
// Converts the given wide string to a narrow string using the UTF-8
|
||||
// encoding, and streams the result to this Message object.
|
||||
Message& operator <<(const ::wstring& wstr);
|
||||
#endif // GTEST_HAS_GLOBAL_WSTRING
|
||||
|
||||
// Gets the text streamed to this object so far as an std::string.
|
||||
// Each '\0' character in the buffer is replaced with "\\0".
|
||||
//
|
||||
// INTERNAL IMPLEMENTATION - DO NOT USE IN A USER PROGRAM.
|
||||
std::string GetString() const;
|
||||
|
||||
private:
|
||||
|
||||
#if GTEST_OS_SYMBIAN
|
||||
// These are needed as the Nokia Symbian Compiler cannot decide between
|
||||
// const T& and const T* in a function template. The Nokia compiler _can_
|
||||
// decide between class template specializations for T and T*, so a
|
||||
// tr1::type_traits-like is_pointer works, and we can overload on that.
|
||||
template <typename T>
|
||||
inline void StreamHelper(internal::true_type /*is_pointer*/, T* pointer) {
|
||||
if (pointer == NULL) {
|
||||
*ss_ << "(null)";
|
||||
} else {
|
||||
*ss_ << pointer;
|
||||
}
|
||||
}
|
||||
template <typename T>
|
||||
inline void StreamHelper(internal::false_type /*is_pointer*/,
|
||||
const T& value) {
|
||||
// See the comments in Message& operator <<(const T&) above for why
|
||||
// we need this using statement.
|
||||
using ::operator <<;
|
||||
*ss_ << value;
|
||||
}
|
||||
#endif // GTEST_OS_SYMBIAN
|
||||
|
||||
// We'll hold the text streamed to this object here.
|
||||
const internal::scoped_ptr< ::std::stringstream> ss_;
|
||||
|
||||
// We declare (but don't implement) this to prevent the compiler
|
||||
// from implementing the assignment operator.
|
||||
void operator=(const Message&);
|
||||
};
|
||||
|
||||
// Streams a Message to an ostream.
|
||||
inline std::ostream& operator <<(std::ostream& os, const Message& sb) {
|
||||
return os << sb.GetString();
|
||||
}
|
||||
|
||||
namespace internal {
|
||||
|
||||
// Converts a streamable value to an std::string. A NULL pointer is
|
||||
// converted to "(null)". When the input value is a ::string,
|
||||
// ::std::string, ::wstring, or ::std::wstring object, each NUL
|
||||
// character in it is replaced with "\\0".
|
||||
template <typename T>
|
||||
std::string StreamableToString(const T& streamable) {
|
||||
return (Message() << streamable).GetString();
|
||||
}
|
||||
|
||||
} // namespace internal
|
||||
} // namespace testing
|
||||
|
||||
#endif // GTEST_INCLUDE_GTEST_GTEST_MESSAGE_H_
|
||||
1444
third_party/googletest/src/include/gtest/gtest-param-test.h
vendored
Normal file
1444
third_party/googletest/src/include/gtest/gtest-param-test.h
vendored
Normal file
File diff suppressed because it is too large
Load Diff
510
third_party/googletest/src/include/gtest/gtest-param-test.h.pump
vendored
Normal file
510
third_party/googletest/src/include/gtest/gtest-param-test.h.pump
vendored
Normal file
@@ -0,0 +1,510 @@
|
||||
$$ -*- mode: c++; -*-
|
||||
$var n = 50 $$ Maximum length of Values arguments we want to support.
|
||||
$var maxtuple = 10 $$ Maximum number of Combine arguments we want to support.
|
||||
// Copyright 2008, Google Inc.
|
||||
// All rights reserved.
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions are
|
||||
// met:
|
||||
//
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above
|
||||
// copyright notice, this list of conditions and the following disclaimer
|
||||
// in the documentation and/or other materials provided with the
|
||||
// distribution.
|
||||
// * Neither the name of Google Inc. nor the names of its
|
||||
// contributors may be used to endorse or promote products derived from
|
||||
// this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
//
|
||||
// Authors: vladl@google.com (Vlad Losev)
|
||||
//
|
||||
// Macros and functions for implementing parameterized tests
|
||||
// in Google C++ Testing Framework (Google Test)
|
||||
//
|
||||
// This file is generated by a SCRIPT. DO NOT EDIT BY HAND!
|
||||
//
|
||||
#ifndef GTEST_INCLUDE_GTEST_GTEST_PARAM_TEST_H_
|
||||
#define GTEST_INCLUDE_GTEST_GTEST_PARAM_TEST_H_
|
||||
|
||||
|
||||
// Value-parameterized tests allow you to test your code with different
|
||||
// parameters without writing multiple copies of the same test.
|
||||
//
|
||||
// Here is how you use value-parameterized tests:
|
||||
|
||||
#if 0
|
||||
|
||||
// To write value-parameterized tests, first you should define a fixture
|
||||
// class. It is usually derived from testing::TestWithParam<T> (see below for
|
||||
// another inheritance scheme that's sometimes useful in more complicated
|
||||
// class hierarchies), where the type of your parameter values.
|
||||
// TestWithParam<T> is itself derived from testing::Test. T can be any
|
||||
// copyable type. If it's a raw pointer, you are responsible for managing the
|
||||
// lifespan of the pointed values.
|
||||
|
||||
class FooTest : public ::testing::TestWithParam<const char*> {
|
||||
// You can implement all the usual class fixture members here.
|
||||
};
|
||||
|
||||
// Then, use the TEST_P macro to define as many parameterized tests
|
||||
// for this fixture as you want. The _P suffix is for "parameterized"
|
||||
// or "pattern", whichever you prefer to think.
|
||||
|
||||
TEST_P(FooTest, DoesBlah) {
|
||||
// Inside a test, access the test parameter with the GetParam() method
|
||||
// of the TestWithParam<T> class:
|
||||
EXPECT_TRUE(foo.Blah(GetParam()));
|
||||
...
|
||||
}
|
||||
|
||||
TEST_P(FooTest, HasBlahBlah) {
|
||||
...
|
||||
}
|
||||
|
||||
// Finally, you can use INSTANTIATE_TEST_CASE_P to instantiate the test
|
||||
// case with any set of parameters you want. Google Test defines a number
|
||||
// of functions for generating test parameters. They return what we call
|
||||
// (surprise!) parameter generators. Here is a summary of them, which
|
||||
// are all in the testing namespace:
|
||||
//
|
||||
//
|
||||
// Range(begin, end [, step]) - Yields values {begin, begin+step,
|
||||
// begin+step+step, ...}. The values do not
|
||||
// include end. step defaults to 1.
|
||||
// Values(v1, v2, ..., vN) - Yields values {v1, v2, ..., vN}.
|
||||
// ValuesIn(container) - Yields values from a C-style array, an STL
|
||||
// ValuesIn(begin,end) container, or an iterator range [begin, end).
|
||||
// Bool() - Yields sequence {false, true}.
|
||||
// Combine(g1, g2, ..., gN) - Yields all combinations (the Cartesian product
|
||||
// for the math savvy) of the values generated
|
||||
// by the N generators.
|
||||
//
|
||||
// For more details, see comments at the definitions of these functions below
|
||||
// in this file.
|
||||
//
|
||||
// The following statement will instantiate tests from the FooTest test case
|
||||
// each with parameter values "meeny", "miny", and "moe".
|
||||
|
||||
INSTANTIATE_TEST_CASE_P(InstantiationName,
|
||||
FooTest,
|
||||
Values("meeny", "miny", "moe"));
|
||||
|
||||
// To distinguish different instances of the pattern, (yes, you
|
||||
// can instantiate it more then once) the first argument to the
|
||||
// INSTANTIATE_TEST_CASE_P macro is a prefix that will be added to the
|
||||
// actual test case name. Remember to pick unique prefixes for different
|
||||
// instantiations. The tests from the instantiation above will have
|
||||
// these names:
|
||||
//
|
||||
// * InstantiationName/FooTest.DoesBlah/0 for "meeny"
|
||||
// * InstantiationName/FooTest.DoesBlah/1 for "miny"
|
||||
// * InstantiationName/FooTest.DoesBlah/2 for "moe"
|
||||
// * InstantiationName/FooTest.HasBlahBlah/0 for "meeny"
|
||||
// * InstantiationName/FooTest.HasBlahBlah/1 for "miny"
|
||||
// * InstantiationName/FooTest.HasBlahBlah/2 for "moe"
|
||||
//
|
||||
// You can use these names in --gtest_filter.
|
||||
//
|
||||
// This statement will instantiate all tests from FooTest again, each
|
||||
// with parameter values "cat" and "dog":
|
||||
|
||||
const char* pets[] = {"cat", "dog"};
|
||||
INSTANTIATE_TEST_CASE_P(AnotherInstantiationName, FooTest, ValuesIn(pets));
|
||||
|
||||
// The tests from the instantiation above will have these names:
|
||||
//
|
||||
// * AnotherInstantiationName/FooTest.DoesBlah/0 for "cat"
|
||||
// * AnotherInstantiationName/FooTest.DoesBlah/1 for "dog"
|
||||
// * AnotherInstantiationName/FooTest.HasBlahBlah/0 for "cat"
|
||||
// * AnotherInstantiationName/FooTest.HasBlahBlah/1 for "dog"
|
||||
//
|
||||
// Please note that INSTANTIATE_TEST_CASE_P will instantiate all tests
|
||||
// in the given test case, whether their definitions come before or
|
||||
// AFTER the INSTANTIATE_TEST_CASE_P statement.
|
||||
//
|
||||
// Please also note that generator expressions (including parameters to the
|
||||
// generators) are evaluated in InitGoogleTest(), after main() has started.
|
||||
// This allows the user on one hand, to adjust generator parameters in order
|
||||
// to dynamically determine a set of tests to run and on the other hand,
|
||||
// give the user a chance to inspect the generated tests with Google Test
|
||||
// reflection API before RUN_ALL_TESTS() is executed.
|
||||
//
|
||||
// You can see samples/sample7_unittest.cc and samples/sample8_unittest.cc
|
||||
// for more examples.
|
||||
//
|
||||
// In the future, we plan to publish the API for defining new parameter
|
||||
// generators. But for now this interface remains part of the internal
|
||||
// implementation and is subject to change.
|
||||
//
|
||||
//
|
||||
// A parameterized test fixture must be derived from testing::Test and from
|
||||
// testing::WithParamInterface<T>, where T is the type of the parameter
|
||||
// values. Inheriting from TestWithParam<T> satisfies that requirement because
|
||||
// TestWithParam<T> inherits from both Test and WithParamInterface. In more
|
||||
// complicated hierarchies, however, it is occasionally useful to inherit
|
||||
// separately from Test and WithParamInterface. For example:
|
||||
|
||||
class BaseTest : public ::testing::Test {
|
||||
// You can inherit all the usual members for a non-parameterized test
|
||||
// fixture here.
|
||||
};
|
||||
|
||||
class DerivedTest : public BaseTest, public ::testing::WithParamInterface<int> {
|
||||
// The usual test fixture members go here too.
|
||||
};
|
||||
|
||||
TEST_F(BaseTest, HasFoo) {
|
||||
// This is an ordinary non-parameterized test.
|
||||
}
|
||||
|
||||
TEST_P(DerivedTest, DoesBlah) {
|
||||
// GetParam works just the same here as if you inherit from TestWithParam.
|
||||
EXPECT_TRUE(foo.Blah(GetParam()));
|
||||
}
|
||||
|
||||
#endif // 0
|
||||
|
||||
#include "gtest/internal/gtest-port.h"
|
||||
|
||||
#if !GTEST_OS_SYMBIAN
|
||||
# include <utility>
|
||||
#endif
|
||||
|
||||
// scripts/fuse_gtest.py depends on gtest's own header being #included
|
||||
// *unconditionally*. Therefore these #includes cannot be moved
|
||||
// inside #if GTEST_HAS_PARAM_TEST.
|
||||
#include "gtest/internal/gtest-internal.h"
|
||||
#include "gtest/internal/gtest-param-util.h"
|
||||
#include "gtest/internal/gtest-param-util-generated.h"
|
||||
|
||||
#if GTEST_HAS_PARAM_TEST
|
||||
|
||||
namespace testing {
|
||||
|
||||
// Functions producing parameter generators.
|
||||
//
|
||||
// Google Test uses these generators to produce parameters for value-
|
||||
// parameterized tests. When a parameterized test case is instantiated
|
||||
// with a particular generator, Google Test creates and runs tests
|
||||
// for each element in the sequence produced by the generator.
|
||||
//
|
||||
// In the following sample, tests from test case FooTest are instantiated
|
||||
// each three times with parameter values 3, 5, and 8:
|
||||
//
|
||||
// class FooTest : public TestWithParam<int> { ... };
|
||||
//
|
||||
// TEST_P(FooTest, TestThis) {
|
||||
// }
|
||||
// TEST_P(FooTest, TestThat) {
|
||||
// }
|
||||
// INSTANTIATE_TEST_CASE_P(TestSequence, FooTest, Values(3, 5, 8));
|
||||
//
|
||||
|
||||
// Range() returns generators providing sequences of values in a range.
|
||||
//
|
||||
// Synopsis:
|
||||
// Range(start, end)
|
||||
// - returns a generator producing a sequence of values {start, start+1,
|
||||
// start+2, ..., }.
|
||||
// Range(start, end, step)
|
||||
// - returns a generator producing a sequence of values {start, start+step,
|
||||
// start+step+step, ..., }.
|
||||
// Notes:
|
||||
// * The generated sequences never include end. For example, Range(1, 5)
|
||||
// returns a generator producing a sequence {1, 2, 3, 4}. Range(1, 9, 2)
|
||||
// returns a generator producing {1, 3, 5, 7}.
|
||||
// * start and end must have the same type. That type may be any integral or
|
||||
// floating-point type or a user defined type satisfying these conditions:
|
||||
// * It must be assignable (have operator=() defined).
|
||||
// * It must have operator+() (operator+(int-compatible type) for
|
||||
// two-operand version).
|
||||
// * It must have operator<() defined.
|
||||
// Elements in the resulting sequences will also have that type.
|
||||
// * Condition start < end must be satisfied in order for resulting sequences
|
||||
// to contain any elements.
|
||||
//
|
||||
template <typename T, typename IncrementT>
|
||||
internal::ParamGenerator<T> Range(T start, T end, IncrementT step) {
|
||||
return internal::ParamGenerator<T>(
|
||||
new internal::RangeGenerator<T, IncrementT>(start, end, step));
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
internal::ParamGenerator<T> Range(T start, T end) {
|
||||
return Range(start, end, 1);
|
||||
}
|
||||
|
||||
// ValuesIn() function allows generation of tests with parameters coming from
|
||||
// a container.
|
||||
//
|
||||
// Synopsis:
|
||||
// ValuesIn(const T (&array)[N])
|
||||
// - returns a generator producing sequences with elements from
|
||||
// a C-style array.
|
||||
// ValuesIn(const Container& container)
|
||||
// - returns a generator producing sequences with elements from
|
||||
// an STL-style container.
|
||||
// ValuesIn(Iterator begin, Iterator end)
|
||||
// - returns a generator producing sequences with elements from
|
||||
// a range [begin, end) defined by a pair of STL-style iterators. These
|
||||
// iterators can also be plain C pointers.
|
||||
//
|
||||
// Please note that ValuesIn copies the values from the containers
|
||||
// passed in and keeps them to generate tests in RUN_ALL_TESTS().
|
||||
//
|
||||
// Examples:
|
||||
//
|
||||
// This instantiates tests from test case StringTest
|
||||
// each with C-string values of "foo", "bar", and "baz":
|
||||
//
|
||||
// const char* strings[] = {"foo", "bar", "baz"};
|
||||
// INSTANTIATE_TEST_CASE_P(StringSequence, SrtingTest, ValuesIn(strings));
|
||||
//
|
||||
// This instantiates tests from test case StlStringTest
|
||||
// each with STL strings with values "a" and "b":
|
||||
//
|
||||
// ::std::vector< ::std::string> GetParameterStrings() {
|
||||
// ::std::vector< ::std::string> v;
|
||||
// v.push_back("a");
|
||||
// v.push_back("b");
|
||||
// return v;
|
||||
// }
|
||||
//
|
||||
// INSTANTIATE_TEST_CASE_P(CharSequence,
|
||||
// StlStringTest,
|
||||
// ValuesIn(GetParameterStrings()));
|
||||
//
|
||||
//
|
||||
// This will also instantiate tests from CharTest
|
||||
// each with parameter values 'a' and 'b':
|
||||
//
|
||||
// ::std::list<char> GetParameterChars() {
|
||||
// ::std::list<char> list;
|
||||
// list.push_back('a');
|
||||
// list.push_back('b');
|
||||
// return list;
|
||||
// }
|
||||
// ::std::list<char> l = GetParameterChars();
|
||||
// INSTANTIATE_TEST_CASE_P(CharSequence2,
|
||||
// CharTest,
|
||||
// ValuesIn(l.begin(), l.end()));
|
||||
//
|
||||
template <typename ForwardIterator>
|
||||
internal::ParamGenerator<
|
||||
typename ::testing::internal::IteratorTraits<ForwardIterator>::value_type>
|
||||
ValuesIn(ForwardIterator begin, ForwardIterator end) {
|
||||
typedef typename ::testing::internal::IteratorTraits<ForwardIterator>
|
||||
::value_type ParamType;
|
||||
return internal::ParamGenerator<ParamType>(
|
||||
new internal::ValuesInIteratorRangeGenerator<ParamType>(begin, end));
|
||||
}
|
||||
|
||||
template <typename T, size_t N>
|
||||
internal::ParamGenerator<T> ValuesIn(const T (&array)[N]) {
|
||||
return ValuesIn(array, array + N);
|
||||
}
|
||||
|
||||
template <class Container>
|
||||
internal::ParamGenerator<typename Container::value_type> ValuesIn(
|
||||
const Container& container) {
|
||||
return ValuesIn(container.begin(), container.end());
|
||||
}
|
||||
|
||||
// Values() allows generating tests from explicitly specified list of
|
||||
// parameters.
|
||||
//
|
||||
// Synopsis:
|
||||
// Values(T v1, T v2, ..., T vN)
|
||||
// - returns a generator producing sequences with elements v1, v2, ..., vN.
|
||||
//
|
||||
// For example, this instantiates tests from test case BarTest each
|
||||
// with values "one", "two", and "three":
|
||||
//
|
||||
// INSTANTIATE_TEST_CASE_P(NumSequence, BarTest, Values("one", "two", "three"));
|
||||
//
|
||||
// This instantiates tests from test case BazTest each with values 1, 2, 3.5.
|
||||
// The exact type of values will depend on the type of parameter in BazTest.
|
||||
//
|
||||
// INSTANTIATE_TEST_CASE_P(FloatingNumbers, BazTest, Values(1, 2, 3.5));
|
||||
//
|
||||
// Currently, Values() supports from 1 to $n parameters.
|
||||
//
|
||||
$range i 1..n
|
||||
$for i [[
|
||||
$range j 1..i
|
||||
|
||||
template <$for j, [[typename T$j]]>
|
||||
internal::ValueArray$i<$for j, [[T$j]]> Values($for j, [[T$j v$j]]) {
|
||||
return internal::ValueArray$i<$for j, [[T$j]]>($for j, [[v$j]]);
|
||||
}
|
||||
|
||||
]]
|
||||
|
||||
// Bool() allows generating tests with parameters in a set of (false, true).
|
||||
//
|
||||
// Synopsis:
|
||||
// Bool()
|
||||
// - returns a generator producing sequences with elements {false, true}.
|
||||
//
|
||||
// It is useful when testing code that depends on Boolean flags. Combinations
|
||||
// of multiple flags can be tested when several Bool()'s are combined using
|
||||
// Combine() function.
|
||||
//
|
||||
// In the following example all tests in the test case FlagDependentTest
|
||||
// will be instantiated twice with parameters false and true.
|
||||
//
|
||||
// class FlagDependentTest : public testing::TestWithParam<bool> {
|
||||
// virtual void SetUp() {
|
||||
// external_flag = GetParam();
|
||||
// }
|
||||
// }
|
||||
// INSTANTIATE_TEST_CASE_P(BoolSequence, FlagDependentTest, Bool());
|
||||
//
|
||||
inline internal::ParamGenerator<bool> Bool() {
|
||||
return Values(false, true);
|
||||
}
|
||||
|
||||
# if GTEST_HAS_COMBINE
|
||||
// Combine() allows the user to combine two or more sequences to produce
|
||||
// values of a Cartesian product of those sequences' elements.
|
||||
//
|
||||
// Synopsis:
|
||||
// Combine(gen1, gen2, ..., genN)
|
||||
// - returns a generator producing sequences with elements coming from
|
||||
// the Cartesian product of elements from the sequences generated by
|
||||
// gen1, gen2, ..., genN. The sequence elements will have a type of
|
||||
// tuple<T1, T2, ..., TN> where T1, T2, ..., TN are the types
|
||||
// of elements from sequences produces by gen1, gen2, ..., genN.
|
||||
//
|
||||
// Combine can have up to $maxtuple arguments. This number is currently limited
|
||||
// by the maximum number of elements in the tuple implementation used by Google
|
||||
// Test.
|
||||
//
|
||||
// Example:
|
||||
//
|
||||
// This will instantiate tests in test case AnimalTest each one with
|
||||
// the parameter values tuple("cat", BLACK), tuple("cat", WHITE),
|
||||
// tuple("dog", BLACK), and tuple("dog", WHITE):
|
||||
//
|
||||
// enum Color { BLACK, GRAY, WHITE };
|
||||
// class AnimalTest
|
||||
// : public testing::TestWithParam<tuple<const char*, Color> > {...};
|
||||
//
|
||||
// TEST_P(AnimalTest, AnimalLooksNice) {...}
|
||||
//
|
||||
// INSTANTIATE_TEST_CASE_P(AnimalVariations, AnimalTest,
|
||||
// Combine(Values("cat", "dog"),
|
||||
// Values(BLACK, WHITE)));
|
||||
//
|
||||
// This will instantiate tests in FlagDependentTest with all variations of two
|
||||
// Boolean flags:
|
||||
//
|
||||
// class FlagDependentTest
|
||||
// : public testing::TestWithParam<tuple<bool, bool> > {
|
||||
// virtual void SetUp() {
|
||||
// // Assigns external_flag_1 and external_flag_2 values from the tuple.
|
||||
// tie(external_flag_1, external_flag_2) = GetParam();
|
||||
// }
|
||||
// };
|
||||
//
|
||||
// TEST_P(FlagDependentTest, TestFeature1) {
|
||||
// // Test your code using external_flag_1 and external_flag_2 here.
|
||||
// }
|
||||
// INSTANTIATE_TEST_CASE_P(TwoBoolSequence, FlagDependentTest,
|
||||
// Combine(Bool(), Bool()));
|
||||
//
|
||||
$range i 2..maxtuple
|
||||
$for i [[
|
||||
$range j 1..i
|
||||
|
||||
template <$for j, [[typename Generator$j]]>
|
||||
internal::CartesianProductHolder$i<$for j, [[Generator$j]]> Combine(
|
||||
$for j, [[const Generator$j& g$j]]) {
|
||||
return internal::CartesianProductHolder$i<$for j, [[Generator$j]]>(
|
||||
$for j, [[g$j]]);
|
||||
}
|
||||
|
||||
]]
|
||||
# endif // GTEST_HAS_COMBINE
|
||||
|
||||
|
||||
|
||||
# define TEST_P(test_case_name, test_name) \
|
||||
class GTEST_TEST_CLASS_NAME_(test_case_name, test_name) \
|
||||
: public test_case_name { \
|
||||
public: \
|
||||
GTEST_TEST_CLASS_NAME_(test_case_name, test_name)() {} \
|
||||
virtual void TestBody(); \
|
||||
private: \
|
||||
static int AddToRegistry() { \
|
||||
::testing::UnitTest::GetInstance()->parameterized_test_registry(). \
|
||||
GetTestCasePatternHolder<test_case_name>(\
|
||||
#test_case_name, \
|
||||
::testing::internal::CodeLocation(\
|
||||
__FILE__, __LINE__))->AddTestPattern(\
|
||||
#test_case_name, \
|
||||
#test_name, \
|
||||
new ::testing::internal::TestMetaFactory< \
|
||||
GTEST_TEST_CLASS_NAME_(\
|
||||
test_case_name, test_name)>()); \
|
||||
return 0; \
|
||||
} \
|
||||
static int gtest_registering_dummy_ GTEST_ATTRIBUTE_UNUSED_; \
|
||||
GTEST_DISALLOW_COPY_AND_ASSIGN_(\
|
||||
GTEST_TEST_CLASS_NAME_(test_case_name, test_name)); \
|
||||
}; \
|
||||
int GTEST_TEST_CLASS_NAME_(test_case_name, \
|
||||
test_name)::gtest_registering_dummy_ = \
|
||||
GTEST_TEST_CLASS_NAME_(test_case_name, test_name)::AddToRegistry(); \
|
||||
void GTEST_TEST_CLASS_NAME_(test_case_name, test_name)::TestBody()
|
||||
|
||||
// The optional last argument to INSTANTIATE_TEST_CASE_P allows the user
|
||||
// to specify a function or functor that generates custom test name suffixes
|
||||
// based on the test parameters. The function should accept one argument of
|
||||
// type testing::TestParamInfo<class ParamType>, and return std::string.
|
||||
//
|
||||
// testing::PrintToStringParamName is a builtin test suffix generator that
|
||||
// returns the value of testing::PrintToString(GetParam()).
|
||||
//
|
||||
// Note: test names must be non-empty, unique, and may only contain ASCII
|
||||
// alphanumeric characters or underscore. Because PrintToString adds quotes
|
||||
// to std::string and C strings, it won't work for these types.
|
||||
|
||||
# define INSTANTIATE_TEST_CASE_P(prefix, test_case_name, generator, ...) \
|
||||
::testing::internal::ParamGenerator<test_case_name::ParamType> \
|
||||
gtest_##prefix##test_case_name##_EvalGenerator_() { return generator; } \
|
||||
::std::string gtest_##prefix##test_case_name##_EvalGenerateName_( \
|
||||
const ::testing::TestParamInfo<test_case_name::ParamType>& info) { \
|
||||
return ::testing::internal::GetParamNameGen<test_case_name::ParamType> \
|
||||
(__VA_ARGS__)(info); \
|
||||
} \
|
||||
int gtest_##prefix##test_case_name##_dummy_ GTEST_ATTRIBUTE_UNUSED_ = \
|
||||
::testing::UnitTest::GetInstance()->parameterized_test_registry(). \
|
||||
GetTestCasePatternHolder<test_case_name>(\
|
||||
#test_case_name, \
|
||||
::testing::internal::CodeLocation(\
|
||||
__FILE__, __LINE__))->AddTestCaseInstantiation(\
|
||||
#prefix, \
|
||||
>est_##prefix##test_case_name##_EvalGenerator_, \
|
||||
>est_##prefix##test_case_name##_EvalGenerateName_, \
|
||||
__FILE__, __LINE__)
|
||||
|
||||
} // namespace testing
|
||||
|
||||
#endif // GTEST_HAS_PARAM_TEST
|
||||
|
||||
#endif // GTEST_INCLUDE_GTEST_GTEST_PARAM_TEST_H_
|
||||
993
third_party/googletest/src/include/gtest/gtest-printers.h
vendored
Normal file
993
third_party/googletest/src/include/gtest/gtest-printers.h
vendored
Normal file
@@ -0,0 +1,993 @@
|
||||
// Copyright 2007, Google Inc.
|
||||
// All rights reserved.
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions are
|
||||
// met:
|
||||
//
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above
|
||||
// copyright notice, this list of conditions and the following disclaimer
|
||||
// in the documentation and/or other materials provided with the
|
||||
// distribution.
|
||||
// * Neither the name of Google Inc. nor the names of its
|
||||
// contributors may be used to endorse or promote products derived from
|
||||
// this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
//
|
||||
// Author: wan@google.com (Zhanyong Wan)
|
||||
|
||||
// Google Test - The Google C++ Testing Framework
|
||||
//
|
||||
// This file implements a universal value printer that can print a
|
||||
// value of any type T:
|
||||
//
|
||||
// void ::testing::internal::UniversalPrinter<T>::Print(value, ostream_ptr);
|
||||
//
|
||||
// A user can teach this function how to print a class type T by
|
||||
// defining either operator<<() or PrintTo() in the namespace that
|
||||
// defines T. More specifically, the FIRST defined function in the
|
||||
// following list will be used (assuming T is defined in namespace
|
||||
// foo):
|
||||
//
|
||||
// 1. foo::PrintTo(const T&, ostream*)
|
||||
// 2. operator<<(ostream&, const T&) defined in either foo or the
|
||||
// global namespace.
|
||||
//
|
||||
// If none of the above is defined, it will print the debug string of
|
||||
// the value if it is a protocol buffer, or print the raw bytes in the
|
||||
// value otherwise.
|
||||
//
|
||||
// To aid debugging: when T is a reference type, the address of the
|
||||
// value is also printed; when T is a (const) char pointer, both the
|
||||
// pointer value and the NUL-terminated string it points to are
|
||||
// printed.
|
||||
//
|
||||
// We also provide some convenient wrappers:
|
||||
//
|
||||
// // Prints a value to a string. For a (const or not) char
|
||||
// // pointer, the NUL-terminated string (but not the pointer) is
|
||||
// // printed.
|
||||
// std::string ::testing::PrintToString(const T& value);
|
||||
//
|
||||
// // Prints a value tersely: for a reference type, the referenced
|
||||
// // value (but not the address) is printed; for a (const or not) char
|
||||
// // pointer, the NUL-terminated string (but not the pointer) is
|
||||
// // printed.
|
||||
// void ::testing::internal::UniversalTersePrint(const T& value, ostream*);
|
||||
//
|
||||
// // Prints value using the type inferred by the compiler. The difference
|
||||
// // from UniversalTersePrint() is that this function prints both the
|
||||
// // pointer and the NUL-terminated string for a (const or not) char pointer.
|
||||
// void ::testing::internal::UniversalPrint(const T& value, ostream*);
|
||||
//
|
||||
// // Prints the fields of a tuple tersely to a string vector, one
|
||||
// // element for each field. Tuple support must be enabled in
|
||||
// // gtest-port.h.
|
||||
// std::vector<string> UniversalTersePrintTupleFieldsToStrings(
|
||||
// const Tuple& value);
|
||||
//
|
||||
// Known limitation:
|
||||
//
|
||||
// The print primitives print the elements of an STL-style container
|
||||
// using the compiler-inferred type of *iter where iter is a
|
||||
// const_iterator of the container. When const_iterator is an input
|
||||
// iterator but not a forward iterator, this inferred type may not
|
||||
// match value_type, and the print output may be incorrect. In
|
||||
// practice, this is rarely a problem as for most containers
|
||||
// const_iterator is a forward iterator. We'll fix this if there's an
|
||||
// actual need for it. Note that this fix cannot rely on value_type
|
||||
// being defined as many user-defined container types don't have
|
||||
// value_type.
|
||||
|
||||
#ifndef GTEST_INCLUDE_GTEST_GTEST_PRINTERS_H_
|
||||
#define GTEST_INCLUDE_GTEST_GTEST_PRINTERS_H_
|
||||
|
||||
#include <ostream> // NOLINT
|
||||
#include <sstream>
|
||||
#include <string>
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
#include "gtest/internal/gtest-port.h"
|
||||
#include "gtest/internal/gtest-internal.h"
|
||||
|
||||
#if GTEST_HAS_STD_TUPLE_
|
||||
# include <tuple>
|
||||
#endif
|
||||
|
||||
namespace testing {
|
||||
|
||||
// Definitions in the 'internal' and 'internal2' name spaces are
|
||||
// subject to change without notice. DO NOT USE THEM IN USER CODE!
|
||||
namespace internal2 {
|
||||
|
||||
// Prints the given number of bytes in the given object to the given
|
||||
// ostream.
|
||||
GTEST_API_ void PrintBytesInObjectTo(const unsigned char* obj_bytes,
|
||||
size_t count,
|
||||
::std::ostream* os);
|
||||
|
||||
// For selecting which printer to use when a given type has neither <<
|
||||
// nor PrintTo().
|
||||
enum TypeKind {
|
||||
kProtobuf, // a protobuf type
|
||||
kConvertibleToInteger, // a type implicitly convertible to BiggestInt
|
||||
// (e.g. a named or unnamed enum type)
|
||||
kOtherType // anything else
|
||||
};
|
||||
|
||||
// TypeWithoutFormatter<T, kTypeKind>::PrintValue(value, os) is called
|
||||
// by the universal printer to print a value of type T when neither
|
||||
// operator<< nor PrintTo() is defined for T, where kTypeKind is the
|
||||
// "kind" of T as defined by enum TypeKind.
|
||||
template <typename T, TypeKind kTypeKind>
|
||||
class TypeWithoutFormatter {
|
||||
public:
|
||||
// This default version is called when kTypeKind is kOtherType.
|
||||
static void PrintValue(const T& value, ::std::ostream* os) {
|
||||
PrintBytesInObjectTo(reinterpret_cast<const unsigned char*>(&value),
|
||||
sizeof(value), os);
|
||||
}
|
||||
};
|
||||
|
||||
// We print a protobuf using its ShortDebugString() when the string
|
||||
// doesn't exceed this many characters; otherwise we print it using
|
||||
// DebugString() for better readability.
|
||||
const size_t kProtobufOneLinerMaxLength = 50;
|
||||
|
||||
template <typename T>
|
||||
class TypeWithoutFormatter<T, kProtobuf> {
|
||||
public:
|
||||
static void PrintValue(const T& value, ::std::ostream* os) {
|
||||
const ::testing::internal::string short_str = value.ShortDebugString();
|
||||
const ::testing::internal::string pretty_str =
|
||||
short_str.length() <= kProtobufOneLinerMaxLength ?
|
||||
short_str : ("\n" + value.DebugString());
|
||||
*os << ("<" + pretty_str + ">");
|
||||
}
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
class TypeWithoutFormatter<T, kConvertibleToInteger> {
|
||||
public:
|
||||
// Since T has no << operator or PrintTo() but can be implicitly
|
||||
// converted to BiggestInt, we print it as a BiggestInt.
|
||||
//
|
||||
// Most likely T is an enum type (either named or unnamed), in which
|
||||
// case printing it as an integer is the desired behavior. In case
|
||||
// T is not an enum, printing it as an integer is the best we can do
|
||||
// given that it has no user-defined printer.
|
||||
static void PrintValue(const T& value, ::std::ostream* os) {
|
||||
const internal::BiggestInt kBigInt = value;
|
||||
*os << kBigInt;
|
||||
}
|
||||
};
|
||||
|
||||
// Prints the given value to the given ostream. If the value is a
|
||||
// protocol message, its debug string is printed; if it's an enum or
|
||||
// of a type implicitly convertible to BiggestInt, it's printed as an
|
||||
// integer; otherwise the bytes in the value are printed. This is
|
||||
// what UniversalPrinter<T>::Print() does when it knows nothing about
|
||||
// type T and T has neither << operator nor PrintTo().
|
||||
//
|
||||
// A user can override this behavior for a class type Foo by defining
|
||||
// a << operator in the namespace where Foo is defined.
|
||||
//
|
||||
// We put this operator in namespace 'internal2' instead of 'internal'
|
||||
// to simplify the implementation, as much code in 'internal' needs to
|
||||
// use << in STL, which would conflict with our own << were it defined
|
||||
// in 'internal'.
|
||||
//
|
||||
// Note that this operator<< takes a generic std::basic_ostream<Char,
|
||||
// CharTraits> type instead of the more restricted std::ostream. If
|
||||
// we define it to take an std::ostream instead, we'll get an
|
||||
// "ambiguous overloads" compiler error when trying to print a type
|
||||
// Foo that supports streaming to std::basic_ostream<Char,
|
||||
// CharTraits>, as the compiler cannot tell whether
|
||||
// operator<<(std::ostream&, const T&) or
|
||||
// operator<<(std::basic_stream<Char, CharTraits>, const Foo&) is more
|
||||
// specific.
|
||||
template <typename Char, typename CharTraits, typename T>
|
||||
::std::basic_ostream<Char, CharTraits>& operator<<(
|
||||
::std::basic_ostream<Char, CharTraits>& os, const T& x) {
|
||||
TypeWithoutFormatter<T,
|
||||
(internal::IsAProtocolMessage<T>::value ? kProtobuf :
|
||||
internal::ImplicitlyConvertible<const T&, internal::BiggestInt>::value ?
|
||||
kConvertibleToInteger : kOtherType)>::PrintValue(x, &os);
|
||||
return os;
|
||||
}
|
||||
|
||||
} // namespace internal2
|
||||
} // namespace testing
|
||||
|
||||
// This namespace MUST NOT BE NESTED IN ::testing, or the name look-up
|
||||
// magic needed for implementing UniversalPrinter won't work.
|
||||
namespace testing_internal {
|
||||
|
||||
// Used to print a value that is not an STL-style container when the
|
||||
// user doesn't define PrintTo() for it.
|
||||
template <typename T>
|
||||
void DefaultPrintNonContainerTo(const T& value, ::std::ostream* os) {
|
||||
// With the following statement, during unqualified name lookup,
|
||||
// testing::internal2::operator<< appears as if it was declared in
|
||||
// the nearest enclosing namespace that contains both
|
||||
// ::testing_internal and ::testing::internal2, i.e. the global
|
||||
// namespace. For more details, refer to the C++ Standard section
|
||||
// 7.3.4-1 [namespace.udir]. This allows us to fall back onto
|
||||
// testing::internal2::operator<< in case T doesn't come with a <<
|
||||
// operator.
|
||||
//
|
||||
// We cannot write 'using ::testing::internal2::operator<<;', which
|
||||
// gcc 3.3 fails to compile due to a compiler bug.
|
||||
using namespace ::testing::internal2; // NOLINT
|
||||
|
||||
// Assuming T is defined in namespace foo, in the next statement,
|
||||
// the compiler will consider all of:
|
||||
//
|
||||
// 1. foo::operator<< (thanks to Koenig look-up),
|
||||
// 2. ::operator<< (as the current namespace is enclosed in ::),
|
||||
// 3. testing::internal2::operator<< (thanks to the using statement above).
|
||||
//
|
||||
// The operator<< whose type matches T best will be picked.
|
||||
//
|
||||
// We deliberately allow #2 to be a candidate, as sometimes it's
|
||||
// impossible to define #1 (e.g. when foo is ::std, defining
|
||||
// anything in it is undefined behavior unless you are a compiler
|
||||
// vendor.).
|
||||
*os << value;
|
||||
}
|
||||
|
||||
} // namespace testing_internal
|
||||
|
||||
namespace testing {
|
||||
namespace internal {
|
||||
|
||||
// FormatForComparison<ToPrint, OtherOperand>::Format(value) formats a
|
||||
// value of type ToPrint that is an operand of a comparison assertion
|
||||
// (e.g. ASSERT_EQ). OtherOperand is the type of the other operand in
|
||||
// the comparison, and is used to help determine the best way to
|
||||
// format the value. In particular, when the value is a C string
|
||||
// (char pointer) and the other operand is an STL string object, we
|
||||
// want to format the C string as a string, since we know it is
|
||||
// compared by value with the string object. If the value is a char
|
||||
// pointer but the other operand is not an STL string object, we don't
|
||||
// know whether the pointer is supposed to point to a NUL-terminated
|
||||
// string, and thus want to print it as a pointer to be safe.
|
||||
//
|
||||
// INTERNAL IMPLEMENTATION - DO NOT USE IN A USER PROGRAM.
|
||||
|
||||
// The default case.
|
||||
template <typename ToPrint, typename OtherOperand>
|
||||
class FormatForComparison {
|
||||
public:
|
||||
static ::std::string Format(const ToPrint& value) {
|
||||
return ::testing::PrintToString(value);
|
||||
}
|
||||
};
|
||||
|
||||
// Array.
|
||||
template <typename ToPrint, size_t N, typename OtherOperand>
|
||||
class FormatForComparison<ToPrint[N], OtherOperand> {
|
||||
public:
|
||||
static ::std::string Format(const ToPrint* value) {
|
||||
return FormatForComparison<const ToPrint*, OtherOperand>::Format(value);
|
||||
}
|
||||
};
|
||||
|
||||
// By default, print C string as pointers to be safe, as we don't know
|
||||
// whether they actually point to a NUL-terminated string.
|
||||
|
||||
#define GTEST_IMPL_FORMAT_C_STRING_AS_POINTER_(CharType) \
|
||||
template <typename OtherOperand> \
|
||||
class FormatForComparison<CharType*, OtherOperand> { \
|
||||
public: \
|
||||
static ::std::string Format(CharType* value) { \
|
||||
return ::testing::PrintToString(static_cast<const void*>(value)); \
|
||||
} \
|
||||
}
|
||||
|
||||
GTEST_IMPL_FORMAT_C_STRING_AS_POINTER_(char);
|
||||
GTEST_IMPL_FORMAT_C_STRING_AS_POINTER_(const char);
|
||||
GTEST_IMPL_FORMAT_C_STRING_AS_POINTER_(wchar_t);
|
||||
GTEST_IMPL_FORMAT_C_STRING_AS_POINTER_(const wchar_t);
|
||||
|
||||
#undef GTEST_IMPL_FORMAT_C_STRING_AS_POINTER_
|
||||
|
||||
// If a C string is compared with an STL string object, we know it's meant
|
||||
// to point to a NUL-terminated string, and thus can print it as a string.
|
||||
|
||||
#define GTEST_IMPL_FORMAT_C_STRING_AS_STRING_(CharType, OtherStringType) \
|
||||
template <> \
|
||||
class FormatForComparison<CharType*, OtherStringType> { \
|
||||
public: \
|
||||
static ::std::string Format(CharType* value) { \
|
||||
return ::testing::PrintToString(value); \
|
||||
} \
|
||||
}
|
||||
|
||||
GTEST_IMPL_FORMAT_C_STRING_AS_STRING_(char, ::std::string);
|
||||
GTEST_IMPL_FORMAT_C_STRING_AS_STRING_(const char, ::std::string);
|
||||
|
||||
#if GTEST_HAS_GLOBAL_STRING
|
||||
GTEST_IMPL_FORMAT_C_STRING_AS_STRING_(char, ::string);
|
||||
GTEST_IMPL_FORMAT_C_STRING_AS_STRING_(const char, ::string);
|
||||
#endif
|
||||
|
||||
#if GTEST_HAS_GLOBAL_WSTRING
|
||||
GTEST_IMPL_FORMAT_C_STRING_AS_STRING_(wchar_t, ::wstring);
|
||||
GTEST_IMPL_FORMAT_C_STRING_AS_STRING_(const wchar_t, ::wstring);
|
||||
#endif
|
||||
|
||||
#if GTEST_HAS_STD_WSTRING
|
||||
GTEST_IMPL_FORMAT_C_STRING_AS_STRING_(wchar_t, ::std::wstring);
|
||||
GTEST_IMPL_FORMAT_C_STRING_AS_STRING_(const wchar_t, ::std::wstring);
|
||||
#endif
|
||||
|
||||
#undef GTEST_IMPL_FORMAT_C_STRING_AS_STRING_
|
||||
|
||||
// Formats a comparison assertion (e.g. ASSERT_EQ, EXPECT_LT, and etc)
|
||||
// operand to be used in a failure message. The type (but not value)
|
||||
// of the other operand may affect the format. This allows us to
|
||||
// print a char* as a raw pointer when it is compared against another
|
||||
// char* or void*, and print it as a C string when it is compared
|
||||
// against an std::string object, for example.
|
||||
//
|
||||
// INTERNAL IMPLEMENTATION - DO NOT USE IN A USER PROGRAM.
|
||||
template <typename T1, typename T2>
|
||||
std::string FormatForComparisonFailureMessage(
|
||||
const T1& value, const T2& /* other_operand */) {
|
||||
return FormatForComparison<T1, T2>::Format(value);
|
||||
}
|
||||
|
||||
// UniversalPrinter<T>::Print(value, ostream_ptr) prints the given
|
||||
// value to the given ostream. The caller must ensure that
|
||||
// 'ostream_ptr' is not NULL, or the behavior is undefined.
|
||||
//
|
||||
// We define UniversalPrinter as a class template (as opposed to a
|
||||
// function template), as we need to partially specialize it for
|
||||
// reference types, which cannot be done with function templates.
|
||||
template <typename T>
|
||||
class UniversalPrinter;
|
||||
|
||||
template <typename T>
|
||||
void UniversalPrint(const T& value, ::std::ostream* os);
|
||||
|
||||
// Used to print an STL-style container when the user doesn't define
|
||||
// a PrintTo() for it.
|
||||
template <typename C>
|
||||
void DefaultPrintTo(IsContainer /* dummy */,
|
||||
false_type /* is not a pointer */,
|
||||
const C& container, ::std::ostream* os) {
|
||||
const size_t kMaxCount = 32; // The maximum number of elements to print.
|
||||
*os << '{';
|
||||
size_t count = 0;
|
||||
for (typename C::const_iterator it = container.begin();
|
||||
it != container.end(); ++it, ++count) {
|
||||
if (count > 0) {
|
||||
*os << ',';
|
||||
if (count == kMaxCount) { // Enough has been printed.
|
||||
*os << " ...";
|
||||
break;
|
||||
}
|
||||
}
|
||||
*os << ' ';
|
||||
// We cannot call PrintTo(*it, os) here as PrintTo() doesn't
|
||||
// handle *it being a native array.
|
||||
internal::UniversalPrint(*it, os);
|
||||
}
|
||||
|
||||
if (count > 0) {
|
||||
*os << ' ';
|
||||
}
|
||||
*os << '}';
|
||||
}
|
||||
|
||||
// Used to print a pointer that is neither a char pointer nor a member
|
||||
// pointer, when the user doesn't define PrintTo() for it. (A member
|
||||
// variable pointer or member function pointer doesn't really point to
|
||||
// a location in the address space. Their representation is
|
||||
// implementation-defined. Therefore they will be printed as raw
|
||||
// bytes.)
|
||||
template <typename T>
|
||||
void DefaultPrintTo(IsNotContainer /* dummy */,
|
||||
true_type /* is a pointer */,
|
||||
T* p, ::std::ostream* os) {
|
||||
if (p == NULL) {
|
||||
*os << "NULL";
|
||||
} else {
|
||||
// C++ doesn't allow casting from a function pointer to any object
|
||||
// pointer.
|
||||
//
|
||||
// IsTrue() silences warnings: "Condition is always true",
|
||||
// "unreachable code".
|
||||
if (IsTrue(ImplicitlyConvertible<T*, const void*>::value)) {
|
||||
// T is not a function type. We just call << to print p,
|
||||
// relying on ADL to pick up user-defined << for their pointer
|
||||
// types, if any.
|
||||
*os << p;
|
||||
} else {
|
||||
// T is a function type, so '*os << p' doesn't do what we want
|
||||
// (it just prints p as bool). We want to print p as a const
|
||||
// void*. However, we cannot cast it to const void* directly,
|
||||
// even using reinterpret_cast, as earlier versions of gcc
|
||||
// (e.g. 3.4.5) cannot compile the cast when p is a function
|
||||
// pointer. Casting to UInt64 first solves the problem.
|
||||
*os << reinterpret_cast<const void*>(
|
||||
reinterpret_cast<internal::UInt64>(p));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Used to print a non-container, non-pointer value when the user
|
||||
// doesn't define PrintTo() for it.
|
||||
template <typename T>
|
||||
void DefaultPrintTo(IsNotContainer /* dummy */,
|
||||
false_type /* is not a pointer */,
|
||||
const T& value, ::std::ostream* os) {
|
||||
::testing_internal::DefaultPrintNonContainerTo(value, os);
|
||||
}
|
||||
|
||||
// Prints the given value using the << operator if it has one;
|
||||
// otherwise prints the bytes in it. This is what
|
||||
// UniversalPrinter<T>::Print() does when PrintTo() is not specialized
|
||||
// or overloaded for type T.
|
||||
//
|
||||
// A user can override this behavior for a class type Foo by defining
|
||||
// an overload of PrintTo() in the namespace where Foo is defined. We
|
||||
// give the user this option as sometimes defining a << operator for
|
||||
// Foo is not desirable (e.g. the coding style may prevent doing it,
|
||||
// or there is already a << operator but it doesn't do what the user
|
||||
// wants).
|
||||
template <typename T>
|
||||
void PrintTo(const T& value, ::std::ostream* os) {
|
||||
// DefaultPrintTo() is overloaded. The type of its first two
|
||||
// arguments determine which version will be picked. If T is an
|
||||
// STL-style container, the version for container will be called; if
|
||||
// T is a pointer, the pointer version will be called; otherwise the
|
||||
// generic version will be called.
|
||||
//
|
||||
// Note that we check for container types here, prior to we check
|
||||
// for protocol message types in our operator<<. The rationale is:
|
||||
//
|
||||
// For protocol messages, we want to give people a chance to
|
||||
// override Google Mock's format by defining a PrintTo() or
|
||||
// operator<<. For STL containers, other formats can be
|
||||
// incompatible with Google Mock's format for the container
|
||||
// elements; therefore we check for container types here to ensure
|
||||
// that our format is used.
|
||||
//
|
||||
// The second argument of DefaultPrintTo() is needed to bypass a bug
|
||||
// in Symbian's C++ compiler that prevents it from picking the right
|
||||
// overload between:
|
||||
//
|
||||
// PrintTo(const T& x, ...);
|
||||
// PrintTo(T* x, ...);
|
||||
DefaultPrintTo(IsContainerTest<T>(0), is_pointer<T>(), value, os);
|
||||
}
|
||||
|
||||
// The following list of PrintTo() overloads tells
|
||||
// UniversalPrinter<T>::Print() how to print standard types (built-in
|
||||
// types, strings, plain arrays, and pointers).
|
||||
|
||||
// Overloads for various char types.
|
||||
GTEST_API_ void PrintTo(unsigned char c, ::std::ostream* os);
|
||||
GTEST_API_ void PrintTo(signed char c, ::std::ostream* os);
|
||||
inline void PrintTo(char c, ::std::ostream* os) {
|
||||
// When printing a plain char, we always treat it as unsigned. This
|
||||
// way, the output won't be affected by whether the compiler thinks
|
||||
// char is signed or not.
|
||||
PrintTo(static_cast<unsigned char>(c), os);
|
||||
}
|
||||
|
||||
// Overloads for other simple built-in types.
|
||||
inline void PrintTo(bool x, ::std::ostream* os) {
|
||||
*os << (x ? "true" : "false");
|
||||
}
|
||||
|
||||
// Overload for wchar_t type.
|
||||
// Prints a wchar_t as a symbol if it is printable or as its internal
|
||||
// code otherwise and also as its decimal code (except for L'\0').
|
||||
// The L'\0' char is printed as "L'\\0'". The decimal code is printed
|
||||
// as signed integer when wchar_t is implemented by the compiler
|
||||
// as a signed type and is printed as an unsigned integer when wchar_t
|
||||
// is implemented as an unsigned type.
|
||||
GTEST_API_ void PrintTo(wchar_t wc, ::std::ostream* os);
|
||||
|
||||
// Overloads for C strings.
|
||||
GTEST_API_ void PrintTo(const char* s, ::std::ostream* os);
|
||||
inline void PrintTo(char* s, ::std::ostream* os) {
|
||||
PrintTo(ImplicitCast_<const char*>(s), os);
|
||||
}
|
||||
|
||||
// signed/unsigned char is often used for representing binary data, so
|
||||
// we print pointers to it as void* to be safe.
|
||||
inline void PrintTo(const signed char* s, ::std::ostream* os) {
|
||||
PrintTo(ImplicitCast_<const void*>(s), os);
|
||||
}
|
||||
inline void PrintTo(signed char* s, ::std::ostream* os) {
|
||||
PrintTo(ImplicitCast_<const void*>(s), os);
|
||||
}
|
||||
inline void PrintTo(const unsigned char* s, ::std::ostream* os) {
|
||||
PrintTo(ImplicitCast_<const void*>(s), os);
|
||||
}
|
||||
inline void PrintTo(unsigned char* s, ::std::ostream* os) {
|
||||
PrintTo(ImplicitCast_<const void*>(s), os);
|
||||
}
|
||||
|
||||
// MSVC can be configured to define wchar_t as a typedef of unsigned
|
||||
// short. It defines _NATIVE_WCHAR_T_DEFINED when wchar_t is a native
|
||||
// type. When wchar_t is a typedef, defining an overload for const
|
||||
// wchar_t* would cause unsigned short* be printed as a wide string,
|
||||
// possibly causing invalid memory accesses.
|
||||
#if !defined(_MSC_VER) || defined(_NATIVE_WCHAR_T_DEFINED)
|
||||
// Overloads for wide C strings
|
||||
GTEST_API_ void PrintTo(const wchar_t* s, ::std::ostream* os);
|
||||
inline void PrintTo(wchar_t* s, ::std::ostream* os) {
|
||||
PrintTo(ImplicitCast_<const wchar_t*>(s), os);
|
||||
}
|
||||
#endif
|
||||
|
||||
// Overload for C arrays. Multi-dimensional arrays are printed
|
||||
// properly.
|
||||
|
||||
// Prints the given number of elements in an array, without printing
|
||||
// the curly braces.
|
||||
template <typename T>
|
||||
void PrintRawArrayTo(const T a[], size_t count, ::std::ostream* os) {
|
||||
UniversalPrint(a[0], os);
|
||||
for (size_t i = 1; i != count; i++) {
|
||||
*os << ", ";
|
||||
UniversalPrint(a[i], os);
|
||||
}
|
||||
}
|
||||
|
||||
// Overloads for ::string and ::std::string.
|
||||
#if GTEST_HAS_GLOBAL_STRING
|
||||
GTEST_API_ void PrintStringTo(const ::string&s, ::std::ostream* os);
|
||||
inline void PrintTo(const ::string& s, ::std::ostream* os) {
|
||||
PrintStringTo(s, os);
|
||||
}
|
||||
#endif // GTEST_HAS_GLOBAL_STRING
|
||||
|
||||
GTEST_API_ void PrintStringTo(const ::std::string&s, ::std::ostream* os);
|
||||
inline void PrintTo(const ::std::string& s, ::std::ostream* os) {
|
||||
PrintStringTo(s, os);
|
||||
}
|
||||
|
||||
// Overloads for ::wstring and ::std::wstring.
|
||||
#if GTEST_HAS_GLOBAL_WSTRING
|
||||
GTEST_API_ void PrintWideStringTo(const ::wstring&s, ::std::ostream* os);
|
||||
inline void PrintTo(const ::wstring& s, ::std::ostream* os) {
|
||||
PrintWideStringTo(s, os);
|
||||
}
|
||||
#endif // GTEST_HAS_GLOBAL_WSTRING
|
||||
|
||||
#if GTEST_HAS_STD_WSTRING
|
||||
GTEST_API_ void PrintWideStringTo(const ::std::wstring&s, ::std::ostream* os);
|
||||
inline void PrintTo(const ::std::wstring& s, ::std::ostream* os) {
|
||||
PrintWideStringTo(s, os);
|
||||
}
|
||||
#endif // GTEST_HAS_STD_WSTRING
|
||||
|
||||
#if GTEST_HAS_TR1_TUPLE || GTEST_HAS_STD_TUPLE_
|
||||
// Helper function for printing a tuple. T must be instantiated with
|
||||
// a tuple type.
|
||||
template <typename T>
|
||||
void PrintTupleTo(const T& t, ::std::ostream* os);
|
||||
#endif // GTEST_HAS_TR1_TUPLE || GTEST_HAS_STD_TUPLE_
|
||||
|
||||
#if GTEST_HAS_TR1_TUPLE
|
||||
// Overload for ::std::tr1::tuple. Needed for printing function arguments,
|
||||
// which are packed as tuples.
|
||||
|
||||
// Overloaded PrintTo() for tuples of various arities. We support
|
||||
// tuples of up-to 10 fields. The following implementation works
|
||||
// regardless of whether tr1::tuple is implemented using the
|
||||
// non-standard variadic template feature or not.
|
||||
|
||||
inline void PrintTo(const ::std::tr1::tuple<>& t, ::std::ostream* os) {
|
||||
PrintTupleTo(t, os);
|
||||
}
|
||||
|
||||
template <typename T1>
|
||||
void PrintTo(const ::std::tr1::tuple<T1>& t, ::std::ostream* os) {
|
||||
PrintTupleTo(t, os);
|
||||
}
|
||||
|
||||
template <typename T1, typename T2>
|
||||
void PrintTo(const ::std::tr1::tuple<T1, T2>& t, ::std::ostream* os) {
|
||||
PrintTupleTo(t, os);
|
||||
}
|
||||
|
||||
template <typename T1, typename T2, typename T3>
|
||||
void PrintTo(const ::std::tr1::tuple<T1, T2, T3>& t, ::std::ostream* os) {
|
||||
PrintTupleTo(t, os);
|
||||
}
|
||||
|
||||
template <typename T1, typename T2, typename T3, typename T4>
|
||||
void PrintTo(const ::std::tr1::tuple<T1, T2, T3, T4>& t, ::std::ostream* os) {
|
||||
PrintTupleTo(t, os);
|
||||
}
|
||||
|
||||
template <typename T1, typename T2, typename T3, typename T4, typename T5>
|
||||
void PrintTo(const ::std::tr1::tuple<T1, T2, T3, T4, T5>& t,
|
||||
::std::ostream* os) {
|
||||
PrintTupleTo(t, os);
|
||||
}
|
||||
|
||||
template <typename T1, typename T2, typename T3, typename T4, typename T5,
|
||||
typename T6>
|
||||
void PrintTo(const ::std::tr1::tuple<T1, T2, T3, T4, T5, T6>& t,
|
||||
::std::ostream* os) {
|
||||
PrintTupleTo(t, os);
|
||||
}
|
||||
|
||||
template <typename T1, typename T2, typename T3, typename T4, typename T5,
|
||||
typename T6, typename T7>
|
||||
void PrintTo(const ::std::tr1::tuple<T1, T2, T3, T4, T5, T6, T7>& t,
|
||||
::std::ostream* os) {
|
||||
PrintTupleTo(t, os);
|
||||
}
|
||||
|
||||
template <typename T1, typename T2, typename T3, typename T4, typename T5,
|
||||
typename T6, typename T7, typename T8>
|
||||
void PrintTo(const ::std::tr1::tuple<T1, T2, T3, T4, T5, T6, T7, T8>& t,
|
||||
::std::ostream* os) {
|
||||
PrintTupleTo(t, os);
|
||||
}
|
||||
|
||||
template <typename T1, typename T2, typename T3, typename T4, typename T5,
|
||||
typename T6, typename T7, typename T8, typename T9>
|
||||
void PrintTo(const ::std::tr1::tuple<T1, T2, T3, T4, T5, T6, T7, T8, T9>& t,
|
||||
::std::ostream* os) {
|
||||
PrintTupleTo(t, os);
|
||||
}
|
||||
|
||||
template <typename T1, typename T2, typename T3, typename T4, typename T5,
|
||||
typename T6, typename T7, typename T8, typename T9, typename T10>
|
||||
void PrintTo(
|
||||
const ::std::tr1::tuple<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10>& t,
|
||||
::std::ostream* os) {
|
||||
PrintTupleTo(t, os);
|
||||
}
|
||||
#endif // GTEST_HAS_TR1_TUPLE
|
||||
|
||||
#if GTEST_HAS_STD_TUPLE_
|
||||
template <typename... Types>
|
||||
void PrintTo(const ::std::tuple<Types...>& t, ::std::ostream* os) {
|
||||
PrintTupleTo(t, os);
|
||||
}
|
||||
#endif // GTEST_HAS_STD_TUPLE_
|
||||
|
||||
// Overload for std::pair.
|
||||
template <typename T1, typename T2>
|
||||
void PrintTo(const ::std::pair<T1, T2>& value, ::std::ostream* os) {
|
||||
*os << '(';
|
||||
// We cannot use UniversalPrint(value.first, os) here, as T1 may be
|
||||
// a reference type. The same for printing value.second.
|
||||
UniversalPrinter<T1>::Print(value.first, os);
|
||||
*os << ", ";
|
||||
UniversalPrinter<T2>::Print(value.second, os);
|
||||
*os << ')';
|
||||
}
|
||||
|
||||
// Implements printing a non-reference type T by letting the compiler
|
||||
// pick the right overload of PrintTo() for T.
|
||||
template <typename T>
|
||||
class UniversalPrinter {
|
||||
public:
|
||||
// MSVC warns about adding const to a function type, so we want to
|
||||
// disable the warning.
|
||||
GTEST_DISABLE_MSC_WARNINGS_PUSH_(4180)
|
||||
|
||||
// Note: we deliberately don't call this PrintTo(), as that name
|
||||
// conflicts with ::testing::internal::PrintTo in the body of the
|
||||
// function.
|
||||
static void Print(const T& value, ::std::ostream* os) {
|
||||
// By default, ::testing::internal::PrintTo() is used for printing
|
||||
// the value.
|
||||
//
|
||||
// Thanks to Koenig look-up, if T is a class and has its own
|
||||
// PrintTo() function defined in its namespace, that function will
|
||||
// be visible here. Since it is more specific than the generic ones
|
||||
// in ::testing::internal, it will be picked by the compiler in the
|
||||
// following statement - exactly what we want.
|
||||
PrintTo(value, os);
|
||||
}
|
||||
|
||||
GTEST_DISABLE_MSC_WARNINGS_POP_()
|
||||
};
|
||||
|
||||
// UniversalPrintArray(begin, len, os) prints an array of 'len'
|
||||
// elements, starting at address 'begin'.
|
||||
template <typename T>
|
||||
void UniversalPrintArray(const T* begin, size_t len, ::std::ostream* os) {
|
||||
if (len == 0) {
|
||||
*os << "{}";
|
||||
} else {
|
||||
*os << "{ ";
|
||||
const size_t kThreshold = 18;
|
||||
const size_t kChunkSize = 8;
|
||||
// If the array has more than kThreshold elements, we'll have to
|
||||
// omit some details by printing only the first and the last
|
||||
// kChunkSize elements.
|
||||
// TODO(wan@google.com): let the user control the threshold using a flag.
|
||||
if (len <= kThreshold) {
|
||||
PrintRawArrayTo(begin, len, os);
|
||||
} else {
|
||||
PrintRawArrayTo(begin, kChunkSize, os);
|
||||
*os << ", ..., ";
|
||||
PrintRawArrayTo(begin + len - kChunkSize, kChunkSize, os);
|
||||
}
|
||||
*os << " }";
|
||||
}
|
||||
}
|
||||
// This overload prints a (const) char array compactly.
|
||||
GTEST_API_ void UniversalPrintArray(
|
||||
const char* begin, size_t len, ::std::ostream* os);
|
||||
|
||||
// This overload prints a (const) wchar_t array compactly.
|
||||
GTEST_API_ void UniversalPrintArray(
|
||||
const wchar_t* begin, size_t len, ::std::ostream* os);
|
||||
|
||||
// Implements printing an array type T[N].
|
||||
template <typename T, size_t N>
|
||||
class UniversalPrinter<T[N]> {
|
||||
public:
|
||||
// Prints the given array, omitting some elements when there are too
|
||||
// many.
|
||||
static void Print(const T (&a)[N], ::std::ostream* os) {
|
||||
UniversalPrintArray(a, N, os);
|
||||
}
|
||||
};
|
||||
|
||||
// Implements printing a reference type T&.
|
||||
template <typename T>
|
||||
class UniversalPrinter<T&> {
|
||||
public:
|
||||
// MSVC warns about adding const to a function type, so we want to
|
||||
// disable the warning.
|
||||
GTEST_DISABLE_MSC_WARNINGS_PUSH_(4180)
|
||||
|
||||
static void Print(const T& value, ::std::ostream* os) {
|
||||
// Prints the address of the value. We use reinterpret_cast here
|
||||
// as static_cast doesn't compile when T is a function type.
|
||||
*os << "@" << reinterpret_cast<const void*>(&value) << " ";
|
||||
|
||||
// Then prints the value itself.
|
||||
UniversalPrint(value, os);
|
||||
}
|
||||
|
||||
GTEST_DISABLE_MSC_WARNINGS_POP_()
|
||||
};
|
||||
|
||||
// Prints a value tersely: for a reference type, the referenced value
|
||||
// (but not the address) is printed; for a (const) char pointer, the
|
||||
// NUL-terminated string (but not the pointer) is printed.
|
||||
|
||||
template <typename T>
|
||||
class UniversalTersePrinter {
|
||||
public:
|
||||
static void Print(const T& value, ::std::ostream* os) {
|
||||
UniversalPrint(value, os);
|
||||
}
|
||||
};
|
||||
template <typename T>
|
||||
class UniversalTersePrinter<T&> {
|
||||
public:
|
||||
static void Print(const T& value, ::std::ostream* os) {
|
||||
UniversalPrint(value, os);
|
||||
}
|
||||
};
|
||||
template <typename T, size_t N>
|
||||
class UniversalTersePrinter<T[N]> {
|
||||
public:
|
||||
static void Print(const T (&value)[N], ::std::ostream* os) {
|
||||
UniversalPrinter<T[N]>::Print(value, os);
|
||||
}
|
||||
};
|
||||
template <>
|
||||
class UniversalTersePrinter<const char*> {
|
||||
public:
|
||||
static void Print(const char* str, ::std::ostream* os) {
|
||||
if (str == NULL) {
|
||||
*os << "NULL";
|
||||
} else {
|
||||
UniversalPrint(string(str), os);
|
||||
}
|
||||
}
|
||||
};
|
||||
template <>
|
||||
class UniversalTersePrinter<char*> {
|
||||
public:
|
||||
static void Print(char* str, ::std::ostream* os) {
|
||||
UniversalTersePrinter<const char*>::Print(str, os);
|
||||
}
|
||||
};
|
||||
|
||||
#if GTEST_HAS_STD_WSTRING
|
||||
template <>
|
||||
class UniversalTersePrinter<const wchar_t*> {
|
||||
public:
|
||||
static void Print(const wchar_t* str, ::std::ostream* os) {
|
||||
if (str == NULL) {
|
||||
*os << "NULL";
|
||||
} else {
|
||||
UniversalPrint(::std::wstring(str), os);
|
||||
}
|
||||
}
|
||||
};
|
||||
#endif
|
||||
|
||||
template <>
|
||||
class UniversalTersePrinter<wchar_t*> {
|
||||
public:
|
||||
static void Print(wchar_t* str, ::std::ostream* os) {
|
||||
UniversalTersePrinter<const wchar_t*>::Print(str, os);
|
||||
}
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
void UniversalTersePrint(const T& value, ::std::ostream* os) {
|
||||
UniversalTersePrinter<T>::Print(value, os);
|
||||
}
|
||||
|
||||
// Prints a value using the type inferred by the compiler. The
|
||||
// difference between this and UniversalTersePrint() is that for a
|
||||
// (const) char pointer, this prints both the pointer and the
|
||||
// NUL-terminated string.
|
||||
template <typename T>
|
||||
void UniversalPrint(const T& value, ::std::ostream* os) {
|
||||
// A workarond for the bug in VC++ 7.1 that prevents us from instantiating
|
||||
// UniversalPrinter with T directly.
|
||||
typedef T T1;
|
||||
UniversalPrinter<T1>::Print(value, os);
|
||||
}
|
||||
|
||||
typedef ::std::vector<string> Strings;
|
||||
|
||||
// TuplePolicy<TupleT> must provide:
|
||||
// - tuple_size
|
||||
// size of tuple TupleT.
|
||||
// - get<size_t I>(const TupleT& t)
|
||||
// static function extracting element I of tuple TupleT.
|
||||
// - tuple_element<size_t I>::type
|
||||
// type of element I of tuple TupleT.
|
||||
template <typename TupleT>
|
||||
struct TuplePolicy;
|
||||
|
||||
#if GTEST_HAS_TR1_TUPLE
|
||||
template <typename TupleT>
|
||||
struct TuplePolicy {
|
||||
typedef TupleT Tuple;
|
||||
static const size_t tuple_size = ::std::tr1::tuple_size<Tuple>::value;
|
||||
|
||||
template <size_t I>
|
||||
struct tuple_element : ::std::tr1::tuple_element<I, Tuple> {};
|
||||
|
||||
template <size_t I>
|
||||
static typename AddReference<
|
||||
const typename ::std::tr1::tuple_element<I, Tuple>::type>::type get(
|
||||
const Tuple& tuple) {
|
||||
return ::std::tr1::get<I>(tuple);
|
||||
}
|
||||
};
|
||||
template <typename TupleT>
|
||||
const size_t TuplePolicy<TupleT>::tuple_size;
|
||||
#endif // GTEST_HAS_TR1_TUPLE
|
||||
|
||||
#if GTEST_HAS_STD_TUPLE_
|
||||
template <typename... Types>
|
||||
struct TuplePolicy< ::std::tuple<Types...> > {
|
||||
typedef ::std::tuple<Types...> Tuple;
|
||||
static const size_t tuple_size = ::std::tuple_size<Tuple>::value;
|
||||
|
||||
template <size_t I>
|
||||
struct tuple_element : ::std::tuple_element<I, Tuple> {};
|
||||
|
||||
template <size_t I>
|
||||
static const typename ::std::tuple_element<I, Tuple>::type& get(
|
||||
const Tuple& tuple) {
|
||||
return ::std::get<I>(tuple);
|
||||
}
|
||||
};
|
||||
template <typename... Types>
|
||||
const size_t TuplePolicy< ::std::tuple<Types...> >::tuple_size;
|
||||
#endif // GTEST_HAS_STD_TUPLE_
|
||||
|
||||
#if GTEST_HAS_TR1_TUPLE || GTEST_HAS_STD_TUPLE_
|
||||
// This helper template allows PrintTo() for tuples and
|
||||
// UniversalTersePrintTupleFieldsToStrings() to be defined by
|
||||
// induction on the number of tuple fields. The idea is that
|
||||
// TuplePrefixPrinter<N>::PrintPrefixTo(t, os) prints the first N
|
||||
// fields in tuple t, and can be defined in terms of
|
||||
// TuplePrefixPrinter<N - 1>.
|
||||
//
|
||||
// The inductive case.
|
||||
template <size_t N>
|
||||
struct TuplePrefixPrinter {
|
||||
// Prints the first N fields of a tuple.
|
||||
template <typename Tuple>
|
||||
static void PrintPrefixTo(const Tuple& t, ::std::ostream* os) {
|
||||
TuplePrefixPrinter<N - 1>::PrintPrefixTo(t, os);
|
||||
GTEST_INTENTIONAL_CONST_COND_PUSH_()
|
||||
if (N > 1) {
|
||||
GTEST_INTENTIONAL_CONST_COND_POP_()
|
||||
*os << ", ";
|
||||
}
|
||||
UniversalPrinter<
|
||||
typename TuplePolicy<Tuple>::template tuple_element<N - 1>::type>
|
||||
::Print(TuplePolicy<Tuple>::template get<N - 1>(t), os);
|
||||
}
|
||||
|
||||
// Tersely prints the first N fields of a tuple to a string vector,
|
||||
// one element for each field.
|
||||
template <typename Tuple>
|
||||
static void TersePrintPrefixToStrings(const Tuple& t, Strings* strings) {
|
||||
TuplePrefixPrinter<N - 1>::TersePrintPrefixToStrings(t, strings);
|
||||
::std::stringstream ss;
|
||||
UniversalTersePrint(TuplePolicy<Tuple>::template get<N - 1>(t), &ss);
|
||||
strings->push_back(ss.str());
|
||||
}
|
||||
};
|
||||
|
||||
// Base case.
|
||||
template <>
|
||||
struct TuplePrefixPrinter<0> {
|
||||
template <typename Tuple>
|
||||
static void PrintPrefixTo(const Tuple&, ::std::ostream*) {}
|
||||
|
||||
template <typename Tuple>
|
||||
static void TersePrintPrefixToStrings(const Tuple&, Strings*) {}
|
||||
};
|
||||
|
||||
// Helper function for printing a tuple.
|
||||
// Tuple must be either std::tr1::tuple or std::tuple type.
|
||||
template <typename Tuple>
|
||||
void PrintTupleTo(const Tuple& t, ::std::ostream* os) {
|
||||
*os << "(";
|
||||
TuplePrefixPrinter<TuplePolicy<Tuple>::tuple_size>::PrintPrefixTo(t, os);
|
||||
*os << ")";
|
||||
}
|
||||
|
||||
// Prints the fields of a tuple tersely to a string vector, one
|
||||
// element for each field. See the comment before
|
||||
// UniversalTersePrint() for how we define "tersely".
|
||||
template <typename Tuple>
|
||||
Strings UniversalTersePrintTupleFieldsToStrings(const Tuple& value) {
|
||||
Strings result;
|
||||
TuplePrefixPrinter<TuplePolicy<Tuple>::tuple_size>::
|
||||
TersePrintPrefixToStrings(value, &result);
|
||||
return result;
|
||||
}
|
||||
#endif // GTEST_HAS_TR1_TUPLE || GTEST_HAS_STD_TUPLE_
|
||||
|
||||
} // namespace internal
|
||||
|
||||
template <typename T>
|
||||
::std::string PrintToString(const T& value) {
|
||||
::std::stringstream ss;
|
||||
internal::UniversalTersePrinter<T>::Print(value, &ss);
|
||||
return ss.str();
|
||||
}
|
||||
|
||||
} // namespace testing
|
||||
|
||||
// Include any custom printer added by the local installation.
|
||||
// We must include this header at the end to make sure it can use the
|
||||
// declarations from this file.
|
||||
#include "gtest/internal/custom/gtest-printers.h"
|
||||
|
||||
#endif // GTEST_INCLUDE_GTEST_GTEST_PRINTERS_H_
|
||||
232
third_party/googletest/src/include/gtest/gtest-spi.h
vendored
Normal file
232
third_party/googletest/src/include/gtest/gtest-spi.h
vendored
Normal file
@@ -0,0 +1,232 @@
|
||||
// Copyright 2007, Google Inc.
|
||||
// All rights reserved.
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions are
|
||||
// met:
|
||||
//
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above
|
||||
// copyright notice, this list of conditions and the following disclaimer
|
||||
// in the documentation and/or other materials provided with the
|
||||
// distribution.
|
||||
// * Neither the name of Google Inc. nor the names of its
|
||||
// contributors may be used to endorse or promote products derived from
|
||||
// this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
//
|
||||
// Author: wan@google.com (Zhanyong Wan)
|
||||
//
|
||||
// Utilities for testing Google Test itself and code that uses Google Test
|
||||
// (e.g. frameworks built on top of Google Test).
|
||||
|
||||
#ifndef GTEST_INCLUDE_GTEST_GTEST_SPI_H_
|
||||
#define GTEST_INCLUDE_GTEST_GTEST_SPI_H_
|
||||
|
||||
#include "gtest/gtest.h"
|
||||
|
||||
namespace testing {
|
||||
|
||||
// This helper class can be used to mock out Google Test failure reporting
|
||||
// so that we can test Google Test or code that builds on Google Test.
|
||||
//
|
||||
// An object of this class appends a TestPartResult object to the
|
||||
// TestPartResultArray object given in the constructor whenever a Google Test
|
||||
// failure is reported. It can either intercept only failures that are
|
||||
// generated in the same thread that created this object or it can intercept
|
||||
// all generated failures. The scope of this mock object can be controlled with
|
||||
// the second argument to the two arguments constructor.
|
||||
class GTEST_API_ ScopedFakeTestPartResultReporter
|
||||
: public TestPartResultReporterInterface {
|
||||
public:
|
||||
// The two possible mocking modes of this object.
|
||||
enum InterceptMode {
|
||||
INTERCEPT_ONLY_CURRENT_THREAD, // Intercepts only thread local failures.
|
||||
INTERCEPT_ALL_THREADS // Intercepts all failures.
|
||||
};
|
||||
|
||||
// The c'tor sets this object as the test part result reporter used
|
||||
// by Google Test. The 'result' parameter specifies where to report the
|
||||
// results. This reporter will only catch failures generated in the current
|
||||
// thread. DEPRECATED
|
||||
explicit ScopedFakeTestPartResultReporter(TestPartResultArray* result);
|
||||
|
||||
// Same as above, but you can choose the interception scope of this object.
|
||||
ScopedFakeTestPartResultReporter(InterceptMode intercept_mode,
|
||||
TestPartResultArray* result);
|
||||
|
||||
// The d'tor restores the previous test part result reporter.
|
||||
virtual ~ScopedFakeTestPartResultReporter();
|
||||
|
||||
// Appends the TestPartResult object to the TestPartResultArray
|
||||
// received in the constructor.
|
||||
//
|
||||
// This method is from the TestPartResultReporterInterface
|
||||
// interface.
|
||||
virtual void ReportTestPartResult(const TestPartResult& result);
|
||||
private:
|
||||
void Init();
|
||||
|
||||
const InterceptMode intercept_mode_;
|
||||
TestPartResultReporterInterface* old_reporter_;
|
||||
TestPartResultArray* const result_;
|
||||
|
||||
GTEST_DISALLOW_COPY_AND_ASSIGN_(ScopedFakeTestPartResultReporter);
|
||||
};
|
||||
|
||||
namespace internal {
|
||||
|
||||
// A helper class for implementing EXPECT_FATAL_FAILURE() and
|
||||
// EXPECT_NONFATAL_FAILURE(). Its destructor verifies that the given
|
||||
// TestPartResultArray contains exactly one failure that has the given
|
||||
// type and contains the given substring. If that's not the case, a
|
||||
// non-fatal failure will be generated.
|
||||
class GTEST_API_ SingleFailureChecker {
|
||||
public:
|
||||
// The constructor remembers the arguments.
|
||||
SingleFailureChecker(const TestPartResultArray* results,
|
||||
TestPartResult::Type type,
|
||||
const string& substr);
|
||||
~SingleFailureChecker();
|
||||
private:
|
||||
const TestPartResultArray* const results_;
|
||||
const TestPartResult::Type type_;
|
||||
const string substr_;
|
||||
|
||||
GTEST_DISALLOW_COPY_AND_ASSIGN_(SingleFailureChecker);
|
||||
};
|
||||
|
||||
} // namespace internal
|
||||
|
||||
} // namespace testing
|
||||
|
||||
// A set of macros for testing Google Test assertions or code that's expected
|
||||
// to generate Google Test fatal failures. It verifies that the given
|
||||
// statement will cause exactly one fatal Google Test failure with 'substr'
|
||||
// being part of the failure message.
|
||||
//
|
||||
// There are two different versions of this macro. EXPECT_FATAL_FAILURE only
|
||||
// affects and considers failures generated in the current thread and
|
||||
// EXPECT_FATAL_FAILURE_ON_ALL_THREADS does the same but for all threads.
|
||||
//
|
||||
// The verification of the assertion is done correctly even when the statement
|
||||
// throws an exception or aborts the current function.
|
||||
//
|
||||
// Known restrictions:
|
||||
// - 'statement' cannot reference local non-static variables or
|
||||
// non-static members of the current object.
|
||||
// - 'statement' cannot return a value.
|
||||
// - You cannot stream a failure message to this macro.
|
||||
//
|
||||
// Note that even though the implementations of the following two
|
||||
// macros are much alike, we cannot refactor them to use a common
|
||||
// helper macro, due to some peculiarity in how the preprocessor
|
||||
// works. The AcceptsMacroThatExpandsToUnprotectedComma test in
|
||||
// gtest_unittest.cc will fail to compile if we do that.
|
||||
#define EXPECT_FATAL_FAILURE(statement, substr) \
|
||||
do { \
|
||||
class GTestExpectFatalFailureHelper {\
|
||||
public:\
|
||||
static void Execute() { statement; }\
|
||||
};\
|
||||
::testing::TestPartResultArray gtest_failures;\
|
||||
::testing::internal::SingleFailureChecker gtest_checker(\
|
||||
>est_failures, ::testing::TestPartResult::kFatalFailure, (substr));\
|
||||
{\
|
||||
::testing::ScopedFakeTestPartResultReporter gtest_reporter(\
|
||||
::testing::ScopedFakeTestPartResultReporter:: \
|
||||
INTERCEPT_ONLY_CURRENT_THREAD, >est_failures);\
|
||||
GTestExpectFatalFailureHelper::Execute();\
|
||||
}\
|
||||
} while (::testing::internal::AlwaysFalse())
|
||||
|
||||
#define EXPECT_FATAL_FAILURE_ON_ALL_THREADS(statement, substr) \
|
||||
do { \
|
||||
class GTestExpectFatalFailureHelper {\
|
||||
public:\
|
||||
static void Execute() { statement; }\
|
||||
};\
|
||||
::testing::TestPartResultArray gtest_failures;\
|
||||
::testing::internal::SingleFailureChecker gtest_checker(\
|
||||
>est_failures, ::testing::TestPartResult::kFatalFailure, (substr));\
|
||||
{\
|
||||
::testing::ScopedFakeTestPartResultReporter gtest_reporter(\
|
||||
::testing::ScopedFakeTestPartResultReporter:: \
|
||||
INTERCEPT_ALL_THREADS, >est_failures);\
|
||||
GTestExpectFatalFailureHelper::Execute();\
|
||||
}\
|
||||
} while (::testing::internal::AlwaysFalse())
|
||||
|
||||
// A macro for testing Google Test assertions or code that's expected to
|
||||
// generate Google Test non-fatal failures. It asserts that the given
|
||||
// statement will cause exactly one non-fatal Google Test failure with 'substr'
|
||||
// being part of the failure message.
|
||||
//
|
||||
// There are two different versions of this macro. EXPECT_NONFATAL_FAILURE only
|
||||
// affects and considers failures generated in the current thread and
|
||||
// EXPECT_NONFATAL_FAILURE_ON_ALL_THREADS does the same but for all threads.
|
||||
//
|
||||
// 'statement' is allowed to reference local variables and members of
|
||||
// the current object.
|
||||
//
|
||||
// The verification of the assertion is done correctly even when the statement
|
||||
// throws an exception or aborts the current function.
|
||||
//
|
||||
// Known restrictions:
|
||||
// - You cannot stream a failure message to this macro.
|
||||
//
|
||||
// Note that even though the implementations of the following two
|
||||
// macros are much alike, we cannot refactor them to use a common
|
||||
// helper macro, due to some peculiarity in how the preprocessor
|
||||
// works. If we do that, the code won't compile when the user gives
|
||||
// EXPECT_NONFATAL_FAILURE() a statement that contains a macro that
|
||||
// expands to code containing an unprotected comma. The
|
||||
// AcceptsMacroThatExpandsToUnprotectedComma test in gtest_unittest.cc
|
||||
// catches that.
|
||||
//
|
||||
// For the same reason, we have to write
|
||||
// if (::testing::internal::AlwaysTrue()) { statement; }
|
||||
// instead of
|
||||
// GTEST_SUPPRESS_UNREACHABLE_CODE_WARNING_BELOW_(statement)
|
||||
// to avoid an MSVC warning on unreachable code.
|
||||
#define EXPECT_NONFATAL_FAILURE(statement, substr) \
|
||||
do {\
|
||||
::testing::TestPartResultArray gtest_failures;\
|
||||
::testing::internal::SingleFailureChecker gtest_checker(\
|
||||
>est_failures, ::testing::TestPartResult::kNonFatalFailure, \
|
||||
(substr));\
|
||||
{\
|
||||
::testing::ScopedFakeTestPartResultReporter gtest_reporter(\
|
||||
::testing::ScopedFakeTestPartResultReporter:: \
|
||||
INTERCEPT_ONLY_CURRENT_THREAD, >est_failures);\
|
||||
if (::testing::internal::AlwaysTrue()) { statement; }\
|
||||
}\
|
||||
} while (::testing::internal::AlwaysFalse())
|
||||
|
||||
#define EXPECT_NONFATAL_FAILURE_ON_ALL_THREADS(statement, substr) \
|
||||
do {\
|
||||
::testing::TestPartResultArray gtest_failures;\
|
||||
::testing::internal::SingleFailureChecker gtest_checker(\
|
||||
>est_failures, ::testing::TestPartResult::kNonFatalFailure, \
|
||||
(substr));\
|
||||
{\
|
||||
::testing::ScopedFakeTestPartResultReporter gtest_reporter(\
|
||||
::testing::ScopedFakeTestPartResultReporter::INTERCEPT_ALL_THREADS, \
|
||||
>est_failures);\
|
||||
if (::testing::internal::AlwaysTrue()) { statement; }\
|
||||
}\
|
||||
} while (::testing::internal::AlwaysFalse())
|
||||
|
||||
#endif // GTEST_INCLUDE_GTEST_GTEST_SPI_H_
|
||||
179
third_party/googletest/src/include/gtest/gtest-test-part.h
vendored
Normal file
179
third_party/googletest/src/include/gtest/gtest-test-part.h
vendored
Normal file
@@ -0,0 +1,179 @@
|
||||
// Copyright 2008, Google Inc.
|
||||
// All rights reserved.
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions are
|
||||
// met:
|
||||
//
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above
|
||||
// copyright notice, this list of conditions and the following disclaimer
|
||||
// in the documentation and/or other materials provided with the
|
||||
// distribution.
|
||||
// * Neither the name of Google Inc. nor the names of its
|
||||
// contributors may be used to endorse or promote products derived from
|
||||
// this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
//
|
||||
// Author: mheule@google.com (Markus Heule)
|
||||
//
|
||||
|
||||
#ifndef GTEST_INCLUDE_GTEST_GTEST_TEST_PART_H_
|
||||
#define GTEST_INCLUDE_GTEST_GTEST_TEST_PART_H_
|
||||
|
||||
#include <iosfwd>
|
||||
#include <vector>
|
||||
#include "gtest/internal/gtest-internal.h"
|
||||
#include "gtest/internal/gtest-string.h"
|
||||
|
||||
namespace testing {
|
||||
|
||||
// A copyable object representing the result of a test part (i.e. an
|
||||
// assertion or an explicit FAIL(), ADD_FAILURE(), or SUCCESS()).
|
||||
//
|
||||
// Don't inherit from TestPartResult as its destructor is not virtual.
|
||||
class GTEST_API_ TestPartResult {
|
||||
public:
|
||||
// The possible outcomes of a test part (i.e. an assertion or an
|
||||
// explicit SUCCEED(), FAIL(), or ADD_FAILURE()).
|
||||
enum Type {
|
||||
kSuccess, // Succeeded.
|
||||
kNonFatalFailure, // Failed but the test can continue.
|
||||
kFatalFailure // Failed and the test should be terminated.
|
||||
};
|
||||
|
||||
// C'tor. TestPartResult does NOT have a default constructor.
|
||||
// Always use this constructor (with parameters) to create a
|
||||
// TestPartResult object.
|
||||
TestPartResult(Type a_type,
|
||||
const char* a_file_name,
|
||||
int a_line_number,
|
||||
const char* a_message)
|
||||
: type_(a_type),
|
||||
file_name_(a_file_name == NULL ? "" : a_file_name),
|
||||
line_number_(a_line_number),
|
||||
summary_(ExtractSummary(a_message)),
|
||||
message_(a_message) {
|
||||
}
|
||||
|
||||
// Gets the outcome of the test part.
|
||||
Type type() const { return type_; }
|
||||
|
||||
// Gets the name of the source file where the test part took place, or
|
||||
// NULL if it's unknown.
|
||||
const char* file_name() const {
|
||||
return file_name_.empty() ? NULL : file_name_.c_str();
|
||||
}
|
||||
|
||||
// Gets the line in the source file where the test part took place,
|
||||
// or -1 if it's unknown.
|
||||
int line_number() const { return line_number_; }
|
||||
|
||||
// Gets the summary of the failure message.
|
||||
const char* summary() const { return summary_.c_str(); }
|
||||
|
||||
// Gets the message associated with the test part.
|
||||
const char* message() const { return message_.c_str(); }
|
||||
|
||||
// Returns true iff the test part passed.
|
||||
bool passed() const { return type_ == kSuccess; }
|
||||
|
||||
// Returns true iff the test part failed.
|
||||
bool failed() const { return type_ != kSuccess; }
|
||||
|
||||
// Returns true iff the test part non-fatally failed.
|
||||
bool nonfatally_failed() const { return type_ == kNonFatalFailure; }
|
||||
|
||||
// Returns true iff the test part fatally failed.
|
||||
bool fatally_failed() const { return type_ == kFatalFailure; }
|
||||
|
||||
private:
|
||||
Type type_;
|
||||
|
||||
// Gets the summary of the failure message by omitting the stack
|
||||
// trace in it.
|
||||
static std::string ExtractSummary(const char* message);
|
||||
|
||||
// The name of the source file where the test part took place, or
|
||||
// "" if the source file is unknown.
|
||||
std::string file_name_;
|
||||
// The line in the source file where the test part took place, or -1
|
||||
// if the line number is unknown.
|
||||
int line_number_;
|
||||
std::string summary_; // The test failure summary.
|
||||
std::string message_; // The test failure message.
|
||||
};
|
||||
|
||||
// Prints a TestPartResult object.
|
||||
std::ostream& operator<<(std::ostream& os, const TestPartResult& result);
|
||||
|
||||
// An array of TestPartResult objects.
|
||||
//
|
||||
// Don't inherit from TestPartResultArray as its destructor is not
|
||||
// virtual.
|
||||
class GTEST_API_ TestPartResultArray {
|
||||
public:
|
||||
TestPartResultArray() {}
|
||||
|
||||
// Appends the given TestPartResult to the array.
|
||||
void Append(const TestPartResult& result);
|
||||
|
||||
// Returns the TestPartResult at the given index (0-based).
|
||||
const TestPartResult& GetTestPartResult(int index) const;
|
||||
|
||||
// Returns the number of TestPartResult objects in the array.
|
||||
int size() const;
|
||||
|
||||
private:
|
||||
std::vector<TestPartResult> array_;
|
||||
|
||||
GTEST_DISALLOW_COPY_AND_ASSIGN_(TestPartResultArray);
|
||||
};
|
||||
|
||||
// This interface knows how to report a test part result.
|
||||
class TestPartResultReporterInterface {
|
||||
public:
|
||||
virtual ~TestPartResultReporterInterface() {}
|
||||
|
||||
virtual void ReportTestPartResult(const TestPartResult& result) = 0;
|
||||
};
|
||||
|
||||
namespace internal {
|
||||
|
||||
// This helper class is used by {ASSERT|EXPECT}_NO_FATAL_FAILURE to check if a
|
||||
// statement generates new fatal failures. To do so it registers itself as the
|
||||
// current test part result reporter. Besides checking if fatal failures were
|
||||
// reported, it only delegates the reporting to the former result reporter.
|
||||
// The original result reporter is restored in the destructor.
|
||||
// INTERNAL IMPLEMENTATION - DO NOT USE IN A USER PROGRAM.
|
||||
class GTEST_API_ HasNewFatalFailureHelper
|
||||
: public TestPartResultReporterInterface {
|
||||
public:
|
||||
HasNewFatalFailureHelper();
|
||||
virtual ~HasNewFatalFailureHelper();
|
||||
virtual void ReportTestPartResult(const TestPartResult& result);
|
||||
bool has_new_fatal_failure() const { return has_new_fatal_failure_; }
|
||||
private:
|
||||
bool has_new_fatal_failure_;
|
||||
TestPartResultReporterInterface* original_reporter_;
|
||||
|
||||
GTEST_DISALLOW_COPY_AND_ASSIGN_(HasNewFatalFailureHelper);
|
||||
};
|
||||
|
||||
} // namespace internal
|
||||
|
||||
} // namespace testing
|
||||
|
||||
#endif // GTEST_INCLUDE_GTEST_GTEST_TEST_PART_H_
|
||||
263
third_party/googletest/src/include/gtest/gtest-typed-test.h
vendored
Normal file
263
third_party/googletest/src/include/gtest/gtest-typed-test.h
vendored
Normal file
@@ -0,0 +1,263 @@
|
||||
// Copyright 2008 Google Inc.
|
||||
// All Rights Reserved.
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions are
|
||||
// met:
|
||||
//
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above
|
||||
// copyright notice, this list of conditions and the following disclaimer
|
||||
// in the documentation and/or other materials provided with the
|
||||
// distribution.
|
||||
// * Neither the name of Google Inc. nor the names of its
|
||||
// contributors may be used to endorse or promote products derived from
|
||||
// this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
//
|
||||
// Author: wan@google.com (Zhanyong Wan)
|
||||
|
||||
#ifndef GTEST_INCLUDE_GTEST_GTEST_TYPED_TEST_H_
|
||||
#define GTEST_INCLUDE_GTEST_GTEST_TYPED_TEST_H_
|
||||
|
||||
// This header implements typed tests and type-parameterized tests.
|
||||
|
||||
// Typed (aka type-driven) tests repeat the same test for types in a
|
||||
// list. You must know which types you want to test with when writing
|
||||
// typed tests. Here's how you do it:
|
||||
|
||||
#if 0
|
||||
|
||||
// First, define a fixture class template. It should be parameterized
|
||||
// by a type. Remember to derive it from testing::Test.
|
||||
template <typename T>
|
||||
class FooTest : public testing::Test {
|
||||
public:
|
||||
...
|
||||
typedef std::list<T> List;
|
||||
static T shared_;
|
||||
T value_;
|
||||
};
|
||||
|
||||
// Next, associate a list of types with the test case, which will be
|
||||
// repeated for each type in the list. The typedef is necessary for
|
||||
// the macro to parse correctly.
|
||||
typedef testing::Types<char, int, unsigned int> MyTypes;
|
||||
TYPED_TEST_CASE(FooTest, MyTypes);
|
||||
|
||||
// If the type list contains only one type, you can write that type
|
||||
// directly without Types<...>:
|
||||
// TYPED_TEST_CASE(FooTest, int);
|
||||
|
||||
// Then, use TYPED_TEST() instead of TEST_F() to define as many typed
|
||||
// tests for this test case as you want.
|
||||
TYPED_TEST(FooTest, DoesBlah) {
|
||||
// Inside a test, refer to TypeParam to get the type parameter.
|
||||
// Since we are inside a derived class template, C++ requires use to
|
||||
// visit the members of FooTest via 'this'.
|
||||
TypeParam n = this->value_;
|
||||
|
||||
// To visit static members of the fixture, add the TestFixture::
|
||||
// prefix.
|
||||
n += TestFixture::shared_;
|
||||
|
||||
// To refer to typedefs in the fixture, add the "typename
|
||||
// TestFixture::" prefix.
|
||||
typename TestFixture::List values;
|
||||
values.push_back(n);
|
||||
...
|
||||
}
|
||||
|
||||
TYPED_TEST(FooTest, HasPropertyA) { ... }
|
||||
|
||||
#endif // 0
|
||||
|
||||
// Type-parameterized tests are abstract test patterns parameterized
|
||||
// by a type. Compared with typed tests, type-parameterized tests
|
||||
// allow you to define the test pattern without knowing what the type
|
||||
// parameters are. The defined pattern can be instantiated with
|
||||
// different types any number of times, in any number of translation
|
||||
// units.
|
||||
//
|
||||
// If you are designing an interface or concept, you can define a
|
||||
// suite of type-parameterized tests to verify properties that any
|
||||
// valid implementation of the interface/concept should have. Then,
|
||||
// each implementation can easily instantiate the test suite to verify
|
||||
// that it conforms to the requirements, without having to write
|
||||
// similar tests repeatedly. Here's an example:
|
||||
|
||||
#if 0
|
||||
|
||||
// First, define a fixture class template. It should be parameterized
|
||||
// by a type. Remember to derive it from testing::Test.
|
||||
template <typename T>
|
||||
class FooTest : public testing::Test {
|
||||
...
|
||||
};
|
||||
|
||||
// Next, declare that you will define a type-parameterized test case
|
||||
// (the _P suffix is for "parameterized" or "pattern", whichever you
|
||||
// prefer):
|
||||
TYPED_TEST_CASE_P(FooTest);
|
||||
|
||||
// Then, use TYPED_TEST_P() to define as many type-parameterized tests
|
||||
// for this type-parameterized test case as you want.
|
||||
TYPED_TEST_P(FooTest, DoesBlah) {
|
||||
// Inside a test, refer to TypeParam to get the type parameter.
|
||||
TypeParam n = 0;
|
||||
...
|
||||
}
|
||||
|
||||
TYPED_TEST_P(FooTest, HasPropertyA) { ... }
|
||||
|
||||
// Now the tricky part: you need to register all test patterns before
|
||||
// you can instantiate them. The first argument of the macro is the
|
||||
// test case name; the rest are the names of the tests in this test
|
||||
// case.
|
||||
REGISTER_TYPED_TEST_CASE_P(FooTest,
|
||||
DoesBlah, HasPropertyA);
|
||||
|
||||
// Finally, you are free to instantiate the pattern with the types you
|
||||
// want. If you put the above code in a header file, you can #include
|
||||
// it in multiple C++ source files and instantiate it multiple times.
|
||||
//
|
||||
// To distinguish different instances of the pattern, the first
|
||||
// argument to the INSTANTIATE_* macro is a prefix that will be added
|
||||
// to the actual test case name. Remember to pick unique prefixes for
|
||||
// different instances.
|
||||
typedef testing::Types<char, int, unsigned int> MyTypes;
|
||||
INSTANTIATE_TYPED_TEST_CASE_P(My, FooTest, MyTypes);
|
||||
|
||||
// If the type list contains only one type, you can write that type
|
||||
// directly without Types<...>:
|
||||
// INSTANTIATE_TYPED_TEST_CASE_P(My, FooTest, int);
|
||||
|
||||
#endif // 0
|
||||
|
||||
#include "gtest/internal/gtest-port.h"
|
||||
#include "gtest/internal/gtest-type-util.h"
|
||||
|
||||
// Implements typed tests.
|
||||
|
||||
#if GTEST_HAS_TYPED_TEST
|
||||
|
||||
// INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE.
|
||||
//
|
||||
// Expands to the name of the typedef for the type parameters of the
|
||||
// given test case.
|
||||
# define GTEST_TYPE_PARAMS_(TestCaseName) gtest_type_params_##TestCaseName##_
|
||||
|
||||
// The 'Types' template argument below must have spaces around it
|
||||
// since some compilers may choke on '>>' when passing a template
|
||||
// instance (e.g. Types<int>)
|
||||
# define TYPED_TEST_CASE(CaseName, Types) \
|
||||
typedef ::testing::internal::TypeList< Types >::type \
|
||||
GTEST_TYPE_PARAMS_(CaseName)
|
||||
|
||||
# define TYPED_TEST(CaseName, TestName) \
|
||||
template <typename gtest_TypeParam_> \
|
||||
class GTEST_TEST_CLASS_NAME_(CaseName, TestName) \
|
||||
: public CaseName<gtest_TypeParam_> { \
|
||||
private: \
|
||||
typedef CaseName<gtest_TypeParam_> TestFixture; \
|
||||
typedef gtest_TypeParam_ TypeParam; \
|
||||
virtual void TestBody(); \
|
||||
}; \
|
||||
bool gtest_##CaseName##_##TestName##_registered_ GTEST_ATTRIBUTE_UNUSED_ = \
|
||||
::testing::internal::TypeParameterizedTest< \
|
||||
CaseName, \
|
||||
::testing::internal::TemplateSel< \
|
||||
GTEST_TEST_CLASS_NAME_(CaseName, TestName)>, \
|
||||
GTEST_TYPE_PARAMS_(CaseName)>::Register(\
|
||||
"", ::testing::internal::CodeLocation(__FILE__, __LINE__), \
|
||||
#CaseName, #TestName, 0); \
|
||||
template <typename gtest_TypeParam_> \
|
||||
void GTEST_TEST_CLASS_NAME_(CaseName, TestName)<gtest_TypeParam_>::TestBody()
|
||||
|
||||
#endif // GTEST_HAS_TYPED_TEST
|
||||
|
||||
// Implements type-parameterized tests.
|
||||
|
||||
#if GTEST_HAS_TYPED_TEST_P
|
||||
|
||||
// INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE.
|
||||
//
|
||||
// Expands to the namespace name that the type-parameterized tests for
|
||||
// the given type-parameterized test case are defined in. The exact
|
||||
// name of the namespace is subject to change without notice.
|
||||
# define GTEST_CASE_NAMESPACE_(TestCaseName) \
|
||||
gtest_case_##TestCaseName##_
|
||||
|
||||
// INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE.
|
||||
//
|
||||
// Expands to the name of the variable used to remember the names of
|
||||
// the defined tests in the given test case.
|
||||
# define GTEST_TYPED_TEST_CASE_P_STATE_(TestCaseName) \
|
||||
gtest_typed_test_case_p_state_##TestCaseName##_
|
||||
|
||||
// INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE DIRECTLY.
|
||||
//
|
||||
// Expands to the name of the variable used to remember the names of
|
||||
// the registered tests in the given test case.
|
||||
# define GTEST_REGISTERED_TEST_NAMES_(TestCaseName) \
|
||||
gtest_registered_test_names_##TestCaseName##_
|
||||
|
||||
// The variables defined in the type-parameterized test macros are
|
||||
// static as typically these macros are used in a .h file that can be
|
||||
// #included in multiple translation units linked together.
|
||||
# define TYPED_TEST_CASE_P(CaseName) \
|
||||
static ::testing::internal::TypedTestCasePState \
|
||||
GTEST_TYPED_TEST_CASE_P_STATE_(CaseName)
|
||||
|
||||
# define TYPED_TEST_P(CaseName, TestName) \
|
||||
namespace GTEST_CASE_NAMESPACE_(CaseName) { \
|
||||
template <typename gtest_TypeParam_> \
|
||||
class TestName : public CaseName<gtest_TypeParam_> { \
|
||||
private: \
|
||||
typedef CaseName<gtest_TypeParam_> TestFixture; \
|
||||
typedef gtest_TypeParam_ TypeParam; \
|
||||
virtual void TestBody(); \
|
||||
}; \
|
||||
static bool gtest_##TestName##_defined_ GTEST_ATTRIBUTE_UNUSED_ = \
|
||||
GTEST_TYPED_TEST_CASE_P_STATE_(CaseName).AddTestName(\
|
||||
__FILE__, __LINE__, #CaseName, #TestName); \
|
||||
} \
|
||||
template <typename gtest_TypeParam_> \
|
||||
void GTEST_CASE_NAMESPACE_(CaseName)::TestName<gtest_TypeParam_>::TestBody()
|
||||
|
||||
# define REGISTER_TYPED_TEST_CASE_P(CaseName, ...) \
|
||||
namespace GTEST_CASE_NAMESPACE_(CaseName) { \
|
||||
typedef ::testing::internal::Templates<__VA_ARGS__>::type gtest_AllTests_; \
|
||||
} \
|
||||
static const char* const GTEST_REGISTERED_TEST_NAMES_(CaseName) = \
|
||||
GTEST_TYPED_TEST_CASE_P_STATE_(CaseName).VerifyRegisteredTestNames(\
|
||||
__FILE__, __LINE__, #__VA_ARGS__)
|
||||
|
||||
// The 'Types' template argument below must have spaces around it
|
||||
// since some compilers may choke on '>>' when passing a template
|
||||
// instance (e.g. Types<int>)
|
||||
# define INSTANTIATE_TYPED_TEST_CASE_P(Prefix, CaseName, Types) \
|
||||
bool gtest_##Prefix##_##CaseName GTEST_ATTRIBUTE_UNUSED_ = \
|
||||
::testing::internal::TypeParameterizedTestCase<CaseName, \
|
||||
GTEST_CASE_NAMESPACE_(CaseName)::gtest_AllTests_, \
|
||||
::testing::internal::TypeList< Types >::type>::Register(\
|
||||
#Prefix, \
|
||||
::testing::internal::CodeLocation(__FILE__, __LINE__), \
|
||||
>EST_TYPED_TEST_CASE_P_STATE_(CaseName), \
|
||||
#CaseName, GTEST_REGISTERED_TEST_NAMES_(CaseName))
|
||||
|
||||
#endif // GTEST_HAS_TYPED_TEST_P
|
||||
|
||||
#endif // GTEST_INCLUDE_GTEST_GTEST_TYPED_TEST_H_
|
||||
18191
third_party/googletest/src/include/gtest/gtest.h
vendored
18191
third_party/googletest/src/include/gtest/gtest.h
vendored
File diff suppressed because it is too large
Load Diff
358
third_party/googletest/src/include/gtest/gtest_pred_impl.h
vendored
Normal file
358
third_party/googletest/src/include/gtest/gtest_pred_impl.h
vendored
Normal file
@@ -0,0 +1,358 @@
|
||||
// Copyright 2006, Google Inc.
|
||||
// All rights reserved.
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions are
|
||||
// met:
|
||||
//
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above
|
||||
// copyright notice, this list of conditions and the following disclaimer
|
||||
// in the documentation and/or other materials provided with the
|
||||
// distribution.
|
||||
// * Neither the name of Google Inc. nor the names of its
|
||||
// contributors may be used to endorse or promote products derived from
|
||||
// this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
// This file is AUTOMATICALLY GENERATED on 10/31/2011 by command
|
||||
// 'gen_gtest_pred_impl.py 5'. DO NOT EDIT BY HAND!
|
||||
//
|
||||
// Implements a family of generic predicate assertion macros.
|
||||
|
||||
#ifndef GTEST_INCLUDE_GTEST_GTEST_PRED_IMPL_H_
|
||||
#define GTEST_INCLUDE_GTEST_GTEST_PRED_IMPL_H_
|
||||
|
||||
// Makes sure this header is not included before gtest.h.
|
||||
#ifndef GTEST_INCLUDE_GTEST_GTEST_H_
|
||||
# error Do not include gtest_pred_impl.h directly. Include gtest.h instead.
|
||||
#endif // GTEST_INCLUDE_GTEST_GTEST_H_
|
||||
|
||||
// This header implements a family of generic predicate assertion
|
||||
// macros:
|
||||
//
|
||||
// ASSERT_PRED_FORMAT1(pred_format, v1)
|
||||
// ASSERT_PRED_FORMAT2(pred_format, v1, v2)
|
||||
// ...
|
||||
//
|
||||
// where pred_format is a function or functor that takes n (in the
|
||||
// case of ASSERT_PRED_FORMATn) values and their source expression
|
||||
// text, and returns a testing::AssertionResult. See the definition
|
||||
// of ASSERT_EQ in gtest.h for an example.
|
||||
//
|
||||
// If you don't care about formatting, you can use the more
|
||||
// restrictive version:
|
||||
//
|
||||
// ASSERT_PRED1(pred, v1)
|
||||
// ASSERT_PRED2(pred, v1, v2)
|
||||
// ...
|
||||
//
|
||||
// where pred is an n-ary function or functor that returns bool,
|
||||
// and the values v1, v2, ..., must support the << operator for
|
||||
// streaming to std::ostream.
|
||||
//
|
||||
// We also define the EXPECT_* variations.
|
||||
//
|
||||
// For now we only support predicates whose arity is at most 5.
|
||||
// Please email googletestframework@googlegroups.com if you need
|
||||
// support for higher arities.
|
||||
|
||||
// GTEST_ASSERT_ is the basic statement to which all of the assertions
|
||||
// in this file reduce. Don't use this in your code.
|
||||
|
||||
#define GTEST_ASSERT_(expression, on_failure) \
|
||||
GTEST_AMBIGUOUS_ELSE_BLOCKER_ \
|
||||
if (const ::testing::AssertionResult gtest_ar = (expression)) \
|
||||
; \
|
||||
else \
|
||||
on_failure(gtest_ar.failure_message())
|
||||
|
||||
|
||||
// Helper function for implementing {EXPECT|ASSERT}_PRED1. Don't use
|
||||
// this in your code.
|
||||
template <typename Pred,
|
||||
typename T1>
|
||||
AssertionResult AssertPred1Helper(const char* pred_text,
|
||||
const char* e1,
|
||||
Pred pred,
|
||||
const T1& v1) {
|
||||
if (pred(v1)) return AssertionSuccess();
|
||||
|
||||
return AssertionFailure() << pred_text << "("
|
||||
<< e1 << ") evaluates to false, where"
|
||||
<< "\n" << e1 << " evaluates to " << v1;
|
||||
}
|
||||
|
||||
// Internal macro for implementing {EXPECT|ASSERT}_PRED_FORMAT1.
|
||||
// Don't use this in your code.
|
||||
#define GTEST_PRED_FORMAT1_(pred_format, v1, on_failure)\
|
||||
GTEST_ASSERT_(pred_format(#v1, v1), \
|
||||
on_failure)
|
||||
|
||||
// Internal macro for implementing {EXPECT|ASSERT}_PRED1. Don't use
|
||||
// this in your code.
|
||||
#define GTEST_PRED1_(pred, v1, on_failure)\
|
||||
GTEST_ASSERT_(::testing::AssertPred1Helper(#pred, \
|
||||
#v1, \
|
||||
pred, \
|
||||
v1), on_failure)
|
||||
|
||||
// Unary predicate assertion macros.
|
||||
#define EXPECT_PRED_FORMAT1(pred_format, v1) \
|
||||
GTEST_PRED_FORMAT1_(pred_format, v1, GTEST_NONFATAL_FAILURE_)
|
||||
#define EXPECT_PRED1(pred, v1) \
|
||||
GTEST_PRED1_(pred, v1, GTEST_NONFATAL_FAILURE_)
|
||||
#define ASSERT_PRED_FORMAT1(pred_format, v1) \
|
||||
GTEST_PRED_FORMAT1_(pred_format, v1, GTEST_FATAL_FAILURE_)
|
||||
#define ASSERT_PRED1(pred, v1) \
|
||||
GTEST_PRED1_(pred, v1, GTEST_FATAL_FAILURE_)
|
||||
|
||||
|
||||
|
||||
// Helper function for implementing {EXPECT|ASSERT}_PRED2. Don't use
|
||||
// this in your code.
|
||||
template <typename Pred,
|
||||
typename T1,
|
||||
typename T2>
|
||||
AssertionResult AssertPred2Helper(const char* pred_text,
|
||||
const char* e1,
|
||||
const char* e2,
|
||||
Pred pred,
|
||||
const T1& v1,
|
||||
const T2& v2) {
|
||||
if (pred(v1, v2)) return AssertionSuccess();
|
||||
|
||||
return AssertionFailure() << pred_text << "("
|
||||
<< e1 << ", "
|
||||
<< e2 << ") evaluates to false, where"
|
||||
<< "\n" << e1 << " evaluates to " << v1
|
||||
<< "\n" << e2 << " evaluates to " << v2;
|
||||
}
|
||||
|
||||
// Internal macro for implementing {EXPECT|ASSERT}_PRED_FORMAT2.
|
||||
// Don't use this in your code.
|
||||
#define GTEST_PRED_FORMAT2_(pred_format, v1, v2, on_failure)\
|
||||
GTEST_ASSERT_(pred_format(#v1, #v2, v1, v2), \
|
||||
on_failure)
|
||||
|
||||
// Internal macro for implementing {EXPECT|ASSERT}_PRED2. Don't use
|
||||
// this in your code.
|
||||
#define GTEST_PRED2_(pred, v1, v2, on_failure)\
|
||||
GTEST_ASSERT_(::testing::AssertPred2Helper(#pred, \
|
||||
#v1, \
|
||||
#v2, \
|
||||
pred, \
|
||||
v1, \
|
||||
v2), on_failure)
|
||||
|
||||
// Binary predicate assertion macros.
|
||||
#define EXPECT_PRED_FORMAT2(pred_format, v1, v2) \
|
||||
GTEST_PRED_FORMAT2_(pred_format, v1, v2, GTEST_NONFATAL_FAILURE_)
|
||||
#define EXPECT_PRED2(pred, v1, v2) \
|
||||
GTEST_PRED2_(pred, v1, v2, GTEST_NONFATAL_FAILURE_)
|
||||
#define ASSERT_PRED_FORMAT2(pred_format, v1, v2) \
|
||||
GTEST_PRED_FORMAT2_(pred_format, v1, v2, GTEST_FATAL_FAILURE_)
|
||||
#define ASSERT_PRED2(pred, v1, v2) \
|
||||
GTEST_PRED2_(pred, v1, v2, GTEST_FATAL_FAILURE_)
|
||||
|
||||
|
||||
|
||||
// Helper function for implementing {EXPECT|ASSERT}_PRED3. Don't use
|
||||
// this in your code.
|
||||
template <typename Pred,
|
||||
typename T1,
|
||||
typename T2,
|
||||
typename T3>
|
||||
AssertionResult AssertPred3Helper(const char* pred_text,
|
||||
const char* e1,
|
||||
const char* e2,
|
||||
const char* e3,
|
||||
Pred pred,
|
||||
const T1& v1,
|
||||
const T2& v2,
|
||||
const T3& v3) {
|
||||
if (pred(v1, v2, v3)) return AssertionSuccess();
|
||||
|
||||
return AssertionFailure() << pred_text << "("
|
||||
<< e1 << ", "
|
||||
<< e2 << ", "
|
||||
<< e3 << ") evaluates to false, where"
|
||||
<< "\n" << e1 << " evaluates to " << v1
|
||||
<< "\n" << e2 << " evaluates to " << v2
|
||||
<< "\n" << e3 << " evaluates to " << v3;
|
||||
}
|
||||
|
||||
// Internal macro for implementing {EXPECT|ASSERT}_PRED_FORMAT3.
|
||||
// Don't use this in your code.
|
||||
#define GTEST_PRED_FORMAT3_(pred_format, v1, v2, v3, on_failure)\
|
||||
GTEST_ASSERT_(pred_format(#v1, #v2, #v3, v1, v2, v3), \
|
||||
on_failure)
|
||||
|
||||
// Internal macro for implementing {EXPECT|ASSERT}_PRED3. Don't use
|
||||
// this in your code.
|
||||
#define GTEST_PRED3_(pred, v1, v2, v3, on_failure)\
|
||||
GTEST_ASSERT_(::testing::AssertPred3Helper(#pred, \
|
||||
#v1, \
|
||||
#v2, \
|
||||
#v3, \
|
||||
pred, \
|
||||
v1, \
|
||||
v2, \
|
||||
v3), on_failure)
|
||||
|
||||
// Ternary predicate assertion macros.
|
||||
#define EXPECT_PRED_FORMAT3(pred_format, v1, v2, v3) \
|
||||
GTEST_PRED_FORMAT3_(pred_format, v1, v2, v3, GTEST_NONFATAL_FAILURE_)
|
||||
#define EXPECT_PRED3(pred, v1, v2, v3) \
|
||||
GTEST_PRED3_(pred, v1, v2, v3, GTEST_NONFATAL_FAILURE_)
|
||||
#define ASSERT_PRED_FORMAT3(pred_format, v1, v2, v3) \
|
||||
GTEST_PRED_FORMAT3_(pred_format, v1, v2, v3, GTEST_FATAL_FAILURE_)
|
||||
#define ASSERT_PRED3(pred, v1, v2, v3) \
|
||||
GTEST_PRED3_(pred, v1, v2, v3, GTEST_FATAL_FAILURE_)
|
||||
|
||||
|
||||
|
||||
// Helper function for implementing {EXPECT|ASSERT}_PRED4. Don't use
|
||||
// this in your code.
|
||||
template <typename Pred,
|
||||
typename T1,
|
||||
typename T2,
|
||||
typename T3,
|
||||
typename T4>
|
||||
AssertionResult AssertPred4Helper(const char* pred_text,
|
||||
const char* e1,
|
||||
const char* e2,
|
||||
const char* e3,
|
||||
const char* e4,
|
||||
Pred pred,
|
||||
const T1& v1,
|
||||
const T2& v2,
|
||||
const T3& v3,
|
||||
const T4& v4) {
|
||||
if (pred(v1, v2, v3, v4)) return AssertionSuccess();
|
||||
|
||||
return AssertionFailure() << pred_text << "("
|
||||
<< e1 << ", "
|
||||
<< e2 << ", "
|
||||
<< e3 << ", "
|
||||
<< e4 << ") evaluates to false, where"
|
||||
<< "\n" << e1 << " evaluates to " << v1
|
||||
<< "\n" << e2 << " evaluates to " << v2
|
||||
<< "\n" << e3 << " evaluates to " << v3
|
||||
<< "\n" << e4 << " evaluates to " << v4;
|
||||
}
|
||||
|
||||
// Internal macro for implementing {EXPECT|ASSERT}_PRED_FORMAT4.
|
||||
// Don't use this in your code.
|
||||
#define GTEST_PRED_FORMAT4_(pred_format, v1, v2, v3, v4, on_failure)\
|
||||
GTEST_ASSERT_(pred_format(#v1, #v2, #v3, #v4, v1, v2, v3, v4), \
|
||||
on_failure)
|
||||
|
||||
// Internal macro for implementing {EXPECT|ASSERT}_PRED4. Don't use
|
||||
// this in your code.
|
||||
#define GTEST_PRED4_(pred, v1, v2, v3, v4, on_failure)\
|
||||
GTEST_ASSERT_(::testing::AssertPred4Helper(#pred, \
|
||||
#v1, \
|
||||
#v2, \
|
||||
#v3, \
|
||||
#v4, \
|
||||
pred, \
|
||||
v1, \
|
||||
v2, \
|
||||
v3, \
|
||||
v4), on_failure)
|
||||
|
||||
// 4-ary predicate assertion macros.
|
||||
#define EXPECT_PRED_FORMAT4(pred_format, v1, v2, v3, v4) \
|
||||
GTEST_PRED_FORMAT4_(pred_format, v1, v2, v3, v4, GTEST_NONFATAL_FAILURE_)
|
||||
#define EXPECT_PRED4(pred, v1, v2, v3, v4) \
|
||||
GTEST_PRED4_(pred, v1, v2, v3, v4, GTEST_NONFATAL_FAILURE_)
|
||||
#define ASSERT_PRED_FORMAT4(pred_format, v1, v2, v3, v4) \
|
||||
GTEST_PRED_FORMAT4_(pred_format, v1, v2, v3, v4, GTEST_FATAL_FAILURE_)
|
||||
#define ASSERT_PRED4(pred, v1, v2, v3, v4) \
|
||||
GTEST_PRED4_(pred, v1, v2, v3, v4, GTEST_FATAL_FAILURE_)
|
||||
|
||||
|
||||
|
||||
// Helper function for implementing {EXPECT|ASSERT}_PRED5. Don't use
|
||||
// this in your code.
|
||||
template <typename Pred,
|
||||
typename T1,
|
||||
typename T2,
|
||||
typename T3,
|
||||
typename T4,
|
||||
typename T5>
|
||||
AssertionResult AssertPred5Helper(const char* pred_text,
|
||||
const char* e1,
|
||||
const char* e2,
|
||||
const char* e3,
|
||||
const char* e4,
|
||||
const char* e5,
|
||||
Pred pred,
|
||||
const T1& v1,
|
||||
const T2& v2,
|
||||
const T3& v3,
|
||||
const T4& v4,
|
||||
const T5& v5) {
|
||||
if (pred(v1, v2, v3, v4, v5)) return AssertionSuccess();
|
||||
|
||||
return AssertionFailure() << pred_text << "("
|
||||
<< e1 << ", "
|
||||
<< e2 << ", "
|
||||
<< e3 << ", "
|
||||
<< e4 << ", "
|
||||
<< e5 << ") evaluates to false, where"
|
||||
<< "\n" << e1 << " evaluates to " << v1
|
||||
<< "\n" << e2 << " evaluates to " << v2
|
||||
<< "\n" << e3 << " evaluates to " << v3
|
||||
<< "\n" << e4 << " evaluates to " << v4
|
||||
<< "\n" << e5 << " evaluates to " << v5;
|
||||
}
|
||||
|
||||
// Internal macro for implementing {EXPECT|ASSERT}_PRED_FORMAT5.
|
||||
// Don't use this in your code.
|
||||
#define GTEST_PRED_FORMAT5_(pred_format, v1, v2, v3, v4, v5, on_failure)\
|
||||
GTEST_ASSERT_(pred_format(#v1, #v2, #v3, #v4, #v5, v1, v2, v3, v4, v5), \
|
||||
on_failure)
|
||||
|
||||
// Internal macro for implementing {EXPECT|ASSERT}_PRED5. Don't use
|
||||
// this in your code.
|
||||
#define GTEST_PRED5_(pred, v1, v2, v3, v4, v5, on_failure)\
|
||||
GTEST_ASSERT_(::testing::AssertPred5Helper(#pred, \
|
||||
#v1, \
|
||||
#v2, \
|
||||
#v3, \
|
||||
#v4, \
|
||||
#v5, \
|
||||
pred, \
|
||||
v1, \
|
||||
v2, \
|
||||
v3, \
|
||||
v4, \
|
||||
v5), on_failure)
|
||||
|
||||
// 5-ary predicate assertion macros.
|
||||
#define EXPECT_PRED_FORMAT5(pred_format, v1, v2, v3, v4, v5) \
|
||||
GTEST_PRED_FORMAT5_(pred_format, v1, v2, v3, v4, v5, GTEST_NONFATAL_FAILURE_)
|
||||
#define EXPECT_PRED5(pred, v1, v2, v3, v4, v5) \
|
||||
GTEST_PRED5_(pred, v1, v2, v3, v4, v5, GTEST_NONFATAL_FAILURE_)
|
||||
#define ASSERT_PRED_FORMAT5(pred_format, v1, v2, v3, v4, v5) \
|
||||
GTEST_PRED_FORMAT5_(pred_format, v1, v2, v3, v4, v5, GTEST_FATAL_FAILURE_)
|
||||
#define ASSERT_PRED5(pred, v1, v2, v3, v4, v5) \
|
||||
GTEST_PRED5_(pred, v1, v2, v3, v4, v5, GTEST_FATAL_FAILURE_)
|
||||
|
||||
|
||||
|
||||
#endif // GTEST_INCLUDE_GTEST_GTEST_PRED_IMPL_H_
|
||||
58
third_party/googletest/src/include/gtest/gtest_prod.h
vendored
Normal file
58
third_party/googletest/src/include/gtest/gtest_prod.h
vendored
Normal file
@@ -0,0 +1,58 @@
|
||||
// Copyright 2006, Google Inc.
|
||||
// All rights reserved.
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions are
|
||||
// met:
|
||||
//
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above
|
||||
// copyright notice, this list of conditions and the following disclaimer
|
||||
// in the documentation and/or other materials provided with the
|
||||
// distribution.
|
||||
// * Neither the name of Google Inc. nor the names of its
|
||||
// contributors may be used to endorse or promote products derived from
|
||||
// this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
//
|
||||
// Author: wan@google.com (Zhanyong Wan)
|
||||
//
|
||||
// Google C++ Testing Framework definitions useful in production code.
|
||||
|
||||
#ifndef GTEST_INCLUDE_GTEST_GTEST_PROD_H_
|
||||
#define GTEST_INCLUDE_GTEST_GTEST_PROD_H_
|
||||
|
||||
// When you need to test the private or protected members of a class,
|
||||
// use the FRIEND_TEST macro to declare your tests as friends of the
|
||||
// class. For example:
|
||||
//
|
||||
// class MyClass {
|
||||
// private:
|
||||
// void MyMethod();
|
||||
// FRIEND_TEST(MyClassTest, MyMethod);
|
||||
// };
|
||||
//
|
||||
// class MyClassTest : public testing::Test {
|
||||
// // ...
|
||||
// };
|
||||
//
|
||||
// TEST_F(MyClassTest, MyMethod) {
|
||||
// // Can call MyClass::MyMethod() here.
|
||||
// }
|
||||
|
||||
#define FRIEND_TEST(test_case_name, test_name)\
|
||||
friend class test_case_name##_##test_name##_Test
|
||||
|
||||
#endif // GTEST_INCLUDE_GTEST_GTEST_PROD_H_
|
||||
69
third_party/googletest/src/include/gtest/internal/custom/gtest-port.h
vendored
Normal file
69
third_party/googletest/src/include/gtest/internal/custom/gtest-port.h
vendored
Normal file
@@ -0,0 +1,69 @@
|
||||
// Copyright 2015, Google Inc.
|
||||
// All rights reserved.
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions are
|
||||
// met:
|
||||
//
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above
|
||||
// copyright notice, this list of conditions and the following disclaimer
|
||||
// in the documentation and/or other materials provided with the
|
||||
// distribution.
|
||||
// * Neither the name of Google Inc. nor the names of its
|
||||
// contributors may be used to endorse or promote products derived from
|
||||
// this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
//
|
||||
// Injection point for custom user configurations.
|
||||
// The following macros can be defined:
|
||||
//
|
||||
// Flag related macros:
|
||||
// GTEST_FLAG(flag_name)
|
||||
// GTEST_USE_OWN_FLAGFILE_FLAG_ - Define to 0 when the system provides its
|
||||
// own flagfile flag parsing.
|
||||
// GTEST_DECLARE_bool_(name)
|
||||
// GTEST_DECLARE_int32_(name)
|
||||
// GTEST_DECLARE_string_(name)
|
||||
// GTEST_DEFINE_bool_(name, default_val, doc)
|
||||
// GTEST_DEFINE_int32_(name, default_val, doc)
|
||||
// GTEST_DEFINE_string_(name, default_val, doc)
|
||||
//
|
||||
// Test filtering:
|
||||
// GTEST_TEST_FILTER_ENV_VAR_ - The name of an environment variable that
|
||||
// will be used if --GTEST_FLAG(test_filter)
|
||||
// is not provided.
|
||||
//
|
||||
// Logging:
|
||||
// GTEST_LOG_(severity)
|
||||
// GTEST_CHECK_(condition)
|
||||
// Functions LogToStderr() and FlushInfoLog() have to be provided too.
|
||||
//
|
||||
// Threading:
|
||||
// GTEST_HAS_NOTIFICATION_ - Enabled if Notification is already provided.
|
||||
// GTEST_HAS_MUTEX_AND_THREAD_LOCAL_ - Enabled if Mutex and ThreadLocal are
|
||||
// already provided.
|
||||
// Must also provide GTEST_DECLARE_STATIC_MUTEX_(mutex) and
|
||||
// GTEST_DEFINE_STATIC_MUTEX_(mutex)
|
||||
//
|
||||
// GTEST_EXCLUSIVE_LOCK_REQUIRED_(locks)
|
||||
// GTEST_LOCK_EXCLUDED_(locks)
|
||||
//
|
||||
// ** Custom implementation starts here **
|
||||
|
||||
#ifndef GTEST_INCLUDE_GTEST_INTERNAL_CUSTOM_GTEST_PORT_H_
|
||||
#define GTEST_INCLUDE_GTEST_INTERNAL_CUSTOM_GTEST_PORT_H_
|
||||
|
||||
#endif // GTEST_INCLUDE_GTEST_INTERNAL_CUSTOM_GTEST_PORT_H_
|
||||
42
third_party/googletest/src/include/gtest/internal/custom/gtest-printers.h
vendored
Normal file
42
third_party/googletest/src/include/gtest/internal/custom/gtest-printers.h
vendored
Normal file
@@ -0,0 +1,42 @@
|
||||
// Copyright 2015, Google Inc.
|
||||
// All rights reserved.
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions are
|
||||
// met:
|
||||
//
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above
|
||||
// copyright notice, this list of conditions and the following disclaimer
|
||||
// in the documentation and/or other materials provided with the
|
||||
// distribution.
|
||||
// * Neither the name of Google Inc. nor the names of its
|
||||
// contributors may be used to endorse or promote products derived from
|
||||
// this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
//
|
||||
// This file provides an injection point for custom printers in a local
|
||||
// installation of gTest.
|
||||
// It will be included from gtest-printers.h and the overrides in this file
|
||||
// will be visible to everyone.
|
||||
// See documentation at gtest/gtest-printers.h for details on how to define a
|
||||
// custom printer.
|
||||
//
|
||||
// ** Custom implementation starts here **
|
||||
|
||||
#ifndef GTEST_INCLUDE_GTEST_INTERNAL_CUSTOM_GTEST_PRINTERS_H_
|
||||
#define GTEST_INCLUDE_GTEST_INTERNAL_CUSTOM_GTEST_PRINTERS_H_
|
||||
|
||||
#endif // GTEST_INCLUDE_GTEST_INTERNAL_CUSTOM_GTEST_PRINTERS_H_
|
||||
41
third_party/googletest/src/include/gtest/internal/custom/gtest.h
vendored
Normal file
41
third_party/googletest/src/include/gtest/internal/custom/gtest.h
vendored
Normal file
@@ -0,0 +1,41 @@
|
||||
// Copyright 2015, Google Inc.
|
||||
// All rights reserved.
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions are
|
||||
// met:
|
||||
//
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above
|
||||
// copyright notice, this list of conditions and the following disclaimer
|
||||
// in the documentation and/or other materials provided with the
|
||||
// distribution.
|
||||
// * Neither the name of Google Inc. nor the names of its
|
||||
// contributors may be used to endorse or promote products derived from
|
||||
// this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
//
|
||||
// Injection point for custom user configurations.
|
||||
// The following macros can be defined:
|
||||
//
|
||||
// GTEST_OS_STACK_TRACE_GETTER_ - The name of an implementation of
|
||||
// OsStackTraceGetterInterface.
|
||||
//
|
||||
// ** Custom implementation starts here **
|
||||
|
||||
#ifndef GTEST_INCLUDE_GTEST_INTERNAL_CUSTOM_GTEST_H_
|
||||
#define GTEST_INCLUDE_GTEST_INTERNAL_CUSTOM_GTEST_H_
|
||||
|
||||
#endif // GTEST_INCLUDE_GTEST_INTERNAL_CUSTOM_GTEST_H_
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user