Compare commits
1627 Commits
m56-2924
...
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 | ||
|
|
0c0a05046d | ||
|
|
baa4a290eb | ||
|
|
3628975a15 | ||
|
|
70ead526f1 | ||
|
|
6e07bf3634 | ||
|
|
9f27d1f843 | ||
|
|
605ca82e7f | ||
|
|
d98bd7cc5f | ||
|
|
f129e09529 | ||
|
|
68d0f46ec0 | ||
|
|
6886da7547 | ||
|
|
7a0bfa6ec6 | ||
|
|
7e3a82c384 | ||
|
|
9a780fa7db | ||
|
|
91fc730d83 | ||
|
|
299ef2f8eb | ||
|
|
198b834c97 | ||
|
|
5b1a8ca5e8 | ||
|
|
9480da21e8 | ||
|
|
62cce50d55 | ||
|
|
35c4a13eb7 | ||
|
|
bea22782e9 | ||
|
|
371a64bfe7 | ||
|
|
cabc29ba24 | ||
|
|
8a7847c2c9 | ||
|
|
bf168b24f5 | ||
|
|
08d0a7fd0f | ||
|
|
ab20869221 | ||
|
|
7b18202e74 | ||
|
|
c23970ec25 | ||
|
|
9af97fb630 | ||
|
|
ebe0b57c91 | ||
|
|
6377f9d966 | ||
|
|
50dd3eb62c | ||
|
|
c06991fce6 | ||
|
|
24d804f79c | ||
|
|
afd2d797eb | ||
|
|
c6ccd1e939 | ||
|
|
6abdd31555 | ||
|
|
c7e2bd6298 | ||
|
|
4dca923454 | ||
|
|
f1909d26f8 | ||
|
|
316071d79c | ||
|
|
b632626ec0 | ||
|
|
b87ebd7af8 | ||
|
|
bf5cdbdf9d | ||
|
|
267e73446c | ||
|
|
337ad83e58 | ||
|
|
afc8c4836f | ||
|
|
2d12a52ff0 | ||
|
|
90f889a56d | ||
|
|
72746c079d | ||
|
|
1ca1515dd3 | ||
|
|
768b1f7281 | ||
|
|
63a8257fb7 | ||
|
|
d3db846cc5 | ||
|
|
99c573f018 | ||
|
|
b67e1f701f | ||
|
|
ecdb6a00c2 | ||
|
|
c96a8dcb5b | ||
|
|
e6b9609fc0 | ||
|
|
911bb980b1 | ||
|
|
9b187954df | ||
|
|
1d12559b09 | ||
|
|
7cf13826b7 | ||
|
|
3c47a0dc6f | ||
|
|
78a24171a6 | ||
|
|
380a26112c | ||
|
|
36e767c147 | ||
|
|
90ceaba3e4 | ||
|
|
f0b491a524 | ||
|
|
6d5a3fe583 | ||
|
|
e7c453b613 | ||
|
|
b5770a2007 | ||
|
|
9ba77ed45b | ||
|
|
9ba45fa510 | ||
|
|
3fcd595dfb | ||
|
|
f27276f44f | ||
|
|
fce163cd54 | ||
|
|
8a152a55f7 | ||
|
|
1d5ca84df6 | ||
|
|
85aead1790 | ||
|
|
80474bf65e | ||
|
|
c1f5194842 | ||
|
|
0549f5aae9 | ||
|
|
a68b36c752 | ||
|
|
6e8dbc76ad | ||
|
|
61b569b461 | ||
|
|
7e23f895ca | ||
|
|
1f3e079a35 | ||
|
|
9b63cb057a | ||
|
|
d1eca240fb | ||
|
|
4260a7f2b3 | ||
|
|
5993b808f0 | ||
|
|
4781a67737 | ||
|
|
318a1ff5ec | ||
|
|
2b1ec65b5d | ||
|
|
41b0888a84 | ||
|
|
5de798f2b2 | ||
|
|
c8f25fa5c0 | ||
|
|
27e1bacdb3 | ||
|
|
3dd20456ab | ||
|
|
201dcefafe | ||
|
|
3486abd54a | ||
|
|
86e340c76e | ||
|
|
85a541a421 | ||
|
|
5d4aa325a6 | ||
|
|
282f3b3d78 | ||
|
|
817488be47 | ||
|
|
121e161115 | ||
|
|
2c24f7178d | ||
|
|
076d4bd91a | ||
|
|
7ba9d31e3f | ||
|
|
cd6f742980 | ||
|
|
6defef4ab2 | ||
|
|
880adc3355 | ||
|
|
394020383d | ||
|
|
e4c6f8fde7 | ||
|
|
385599b553 | ||
|
|
174528de1e | ||
|
|
5778a7c9cb | ||
|
|
f16a0a1aa4 | ||
|
|
834feffe08 | ||
|
|
17c403d0ab | ||
|
|
018a2adcb1 | ||
|
|
2d3d95f7ac | ||
|
|
228c9940ea | ||
|
|
8befcd0089 | ||
|
|
af9d7aa9fb | ||
|
|
cb339d628f | ||
|
|
360ac89885 | ||
|
|
a8eee97b43 | ||
|
|
a7fa1314da | ||
|
|
17a8cf5cc3 | ||
|
|
264f6e70ec | ||
|
|
c6641782c3 | ||
|
|
12566c3d0f | ||
|
|
33ddc645ce | ||
|
|
68991d7f87 | ||
|
|
27b5cc31e6 | ||
|
|
f68cf8ba19 | ||
|
|
a58e0b2a74 | ||
|
|
120234fa17 | ||
|
|
21a1abd8e3 | ||
|
|
568d4b1d63 | ||
|
|
d757d7e998 | ||
|
|
f63eb66ecd | ||
|
|
95eb505660 | ||
|
|
2c598d0858 | ||
|
|
1136db0db0 | ||
|
|
d793950ec8 | ||
|
|
af290bfe3b | ||
|
|
97ec6291ee | ||
|
|
755fb3d4ec | ||
|
|
8b2cbaefcf | ||
|
|
22f7aca097 | ||
|
|
d7f1d60c51 | ||
|
|
198a046d3e | ||
|
|
cb22359d02 | ||
|
|
05e2b5a59f | ||
|
|
446d1ee624 | ||
|
|
b6597745f9 | ||
|
|
0966757874 | ||
|
|
7d2690e658 | ||
|
|
6cc76ec73f | ||
|
|
4bb01229cd | ||
|
|
974e81d184 | ||
|
|
45876b4550 | ||
|
|
d479c9653e | ||
|
|
719f39f44e | ||
|
|
ecc5998bcf | ||
|
|
0ffbb36ddc | ||
|
|
f473e892f7 | ||
|
|
a38e9f412d | ||
|
|
3d55311062 | ||
|
|
7317ce8bd4 | ||
|
|
cbeae53e76 | ||
|
|
7adeccb33d | ||
|
|
23f1bfbd85 | ||
|
|
de5fd00ec5 | ||
|
|
f6921412d4 | ||
|
|
485a49d0b8 | ||
|
|
c56e5dd620 | ||
|
|
5d48663e04 | ||
|
|
cb1b1b8fef | ||
|
|
2ef2243804 | ||
|
|
f667cc7a4e | ||
|
|
12fe34516e | ||
|
|
f09c687ea9 | ||
|
|
011fdec1e6 | ||
|
|
4ddae8f524 | ||
|
|
85c1ee434d | ||
|
|
360217a233 | ||
|
|
2218a4c292 | ||
|
|
0412193bb9 | ||
|
|
f938ab5e6a | ||
|
|
eff68a3a4d | ||
|
|
44f8ee7258 | ||
|
|
a3128ad33a | ||
|
|
186dc40e8e | ||
|
|
b282048fe4 | ||
|
|
b6f6169348 | ||
|
|
ba016b710a | ||
|
|
80f6b243a7 | ||
|
|
a1c40a2c1a | ||
|
|
40ab0424d4 | ||
|
|
4807f1584c | ||
|
|
cfbb599335 | ||
|
|
c344dee463 | ||
|
|
738c8f23c6 | ||
|
|
18794d8ddc | ||
|
|
f5141ea45f | ||
|
|
50b40f114c | ||
|
|
64a5a8fd6f | ||
|
|
3fdfbcb73d | ||
|
|
40bcb96abd | ||
|
|
1338c71dfb | ||
|
|
1868582e7d | ||
|
|
3b74066b10 |
@@ -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>
|
||||
|
||||
15
AUTHORS
15
AUTHORS
@@ -7,6 +7,8 @@ Adam Xu <adam@xuyaowu.com>
|
||||
Adrian Grange <agrange@google.com>
|
||||
Aℓex Converse <aconverse@google.com>
|
||||
Ahmad Sharif <asharif@google.com>
|
||||
Aleksey Vasenev <margtu-fivt@ya.ru>
|
||||
Alexander Potapenko <glider@google.com>
|
||||
Alexander Voronov <avoronov@graphics.cs.msu.ru>
|
||||
Alexis Ballier <aballier@gentoo.org>
|
||||
Alok Ahuja <waveletcoeff@gmail.com>
|
||||
@@ -27,6 +29,7 @@ Christian Duvivier <cduvivier@google.com>
|
||||
Daniele Castagna <dcastagna@chromium.org>
|
||||
Daniel Kang <ddkang@google.com>
|
||||
Deb Mukherjee <debargha@google.com>
|
||||
Deepa K G <deepa.kg@ittiam.com>
|
||||
Dim Temp <dimtemp0@gmail.com>
|
||||
Dmitry Kovalev <dkovalev@google.com>
|
||||
Dragan Mrdjan <dmrdjan@mips.com>
|
||||
@@ -37,6 +40,7 @@ Fabio Pedretti <fabio.ped@libero.it>
|
||||
Frank Galligan <fgalligan@google.com>
|
||||
Fredrik Söderquist <fs@opera.com>
|
||||
Fritz Koenig <frkoenig@google.com>
|
||||
Gabriel Marin <gmx@chromium.org>
|
||||
Gaute Strokkenes <gaute.strokkenes@broadcom.com>
|
||||
Geza Lore <gezalore@gmail.com>
|
||||
Ghislain MARY <ghislainmary2@gmail.com>
|
||||
@@ -48,6 +52,7 @@ Hangyu Kuang <hkuang@google.com>
|
||||
Hanno Böck <hanno@hboeck.de>
|
||||
Henrik Lundin <hlundin@google.com>
|
||||
Hui Su <huisu@google.com>
|
||||
Ivan Krasin <krasin@chromium.org>
|
||||
Ivan Maltz <ivanmaltz@google.com>
|
||||
Jacek Caban <cjacek@gmail.com>
|
||||
Jacky Chen <jackychen@google.com>
|
||||
@@ -61,6 +66,7 @@ Jean-Yves Avenard <jyavenard@mozilla.com>
|
||||
Jeff Faust <jfaust@google.com>
|
||||
Jeff Muizelaar <jmuizelaar@mozilla.com>
|
||||
Jeff Petkau <jpet@chromium.org>
|
||||
Jerome Jiang <jianj@google.com>
|
||||
Jia Jia <jia.jia@linaro.org>
|
||||
Jian Zhou <zhoujian@google.com>
|
||||
Jim Bankoski <jimbankoski@google.com>
|
||||
@@ -92,8 +98,11 @@ Michael Kohler <michaelkohler@live.com>
|
||||
Mike Frysinger <vapier@chromium.org>
|
||||
Mike Hommey <mhommey@mozilla.com>
|
||||
Mikhal Shemer <mikhal@google.com>
|
||||
Min Chen <chenm003@gmail.com>
|
||||
Minghai Shang <minghai@google.com>
|
||||
Min Ye <yeemmi@google.com>
|
||||
Morton Jonuschat <yabawock@gmail.com>
|
||||
Nathan E. Egge <negge@mozilla.com>
|
||||
Nico Weber <thakis@chromium.org>
|
||||
Parag Salasakar <img.mips1@gmail.com>
|
||||
Pascal Massimino <pascal.massimino@gmail.com>
|
||||
@@ -102,16 +111,19 @@ Paul Wilkins <paulwilkins@google.com>
|
||||
Pavol Rusnak <stick@gk2.sk>
|
||||
Paweł Hajdan <phajdan@google.com>
|
||||
Pengchong Jin <pengchong@google.com>
|
||||
Peter Boström <pbos@google.com>
|
||||
Peter de Rivaz <peter.derivaz@gmail.com>
|
||||
Philip Jägenstedt <philipj@opera.com>
|
||||
Priit Laes <plaes@plaes.org>
|
||||
Rafael Ávila de Espíndola <rafael.espindola@gmail.com>
|
||||
Rafaël Carré <funman@videolan.org>
|
||||
Ralph Giles <giles@xiph.org>
|
||||
Ranjit Kumar Tulabandu <ranjit.tulabandu@ittiam.com>
|
||||
Rob Bradford <rob@linux.intel.com>
|
||||
Ronald S. Bultje <rsbultje@gmail.com>
|
||||
Rui Ueyama <ruiu@google.com>
|
||||
Sami Pietilä <samipietila@google.com>
|
||||
Sarah Parker <sarahparker@google.com>
|
||||
Sasi Inguva <isasi@google.com>
|
||||
Scott Graham <scottmg@chromium.org>
|
||||
Scott LaVarnway <slavarnway@google.com>
|
||||
@@ -119,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>
|
||||
@@ -131,6 +144,8 @@ Thijs Vermeir <thijsvermeir@gmail.com>
|
||||
Tim Kopp <tkopp@google.com>
|
||||
Timothy B. Terriberry <tterribe@xiph.org>
|
||||
Tom Finegan <tomfinegan@google.com>
|
||||
Tristan Matthews <le.businessman@gmail.com>
|
||||
Urvang Joshi <urvang@google.com>
|
||||
Vignesh Venkatasubramanian <vigneshv@google.com>
|
||||
Yaowu Xu <yaowu@google.com>
|
||||
Yi Luo <luoyi@google.com>
|
||||
|
||||
16
CHANGELOG
16
CHANGELOG
@@ -1,3 +1,19 @@
|
||||
2017-01-09 v1.6.1 "Long Tailed Duck"
|
||||
This release improves upon the VP9 encoder and speeds up the encoding and
|
||||
decoding processes.
|
||||
|
||||
- Upgrading:
|
||||
This release is ABI compatible with 1.6.0.
|
||||
|
||||
- Enhancements:
|
||||
Faster VP9 encoding and decoding.
|
||||
High bit depth builds now provide similar speed for 8 bit encode and decode
|
||||
for x86 targets. Other platforms and higher bit depth improvements are in
|
||||
progress.
|
||||
|
||||
- Bug Fixes:
|
||||
A variety of fuzzing issues.
|
||||
|
||||
2016-07-20 v1.6.0 "Khaki Campbell Duck"
|
||||
This release improves upon the VP9 encoder and speeds up the encoding and
|
||||
decoding processes.
|
||||
|
||||
8
README
8
README
@@ -1,4 +1,4 @@
|
||||
README - 20 July 2016
|
||||
README - 26 January 2017
|
||||
|
||||
Welcome to the WebM VP8/VP9 Codec SDK!
|
||||
|
||||
@@ -47,6 +47,7 @@ COMPILING THE APPLICATIONS/LIBRARIES:
|
||||
--help output of the configure script. As of this writing, the list of
|
||||
available targets is:
|
||||
|
||||
arm64-android-gcc
|
||||
arm64-darwin-gcc
|
||||
arm64-linux-gcc
|
||||
armv7-android-gcc
|
||||
@@ -57,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
|
||||
@@ -73,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
|
||||
@@ -83,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
|
||||
@@ -91,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
|
||||
@@ -100,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,
|
||||
|
||||
@@ -64,6 +64,9 @@ CONFIG_DIR := $(LOCAL_PATH)/
|
||||
LIBVPX_PATH := $(LOCAL_PATH)/libvpx
|
||||
ASM_CNV_PATH_LOCAL := $(TARGET_ARCH_ABI)/ads2gas
|
||||
ASM_CNV_PATH := $(LOCAL_PATH)/$(ASM_CNV_PATH_LOCAL)
|
||||
ifneq ($(V),1)
|
||||
qexec := @
|
||||
endif
|
||||
|
||||
# Use the makefiles generated by upstream configure to determine which files to
|
||||
# build. Also set any architecture-specific flags.
|
||||
@@ -103,8 +106,8 @@ LOCAL_ASMFLAGS := -I$(LIBVPX_PATH)
|
||||
|
||||
.PRECIOUS: %.asm.S
|
||||
$(ASM_CNV_PATH)/libvpx/%.asm.S: $(LIBVPX_PATH)/%.asm
|
||||
@mkdir -p $(dir $@)
|
||||
@$(CONFIG_DIR)$(ASM_CONVERSION) <$< > $@
|
||||
$(qexec)mkdir -p $(dir $@)
|
||||
$(qexec)$(CONFIG_DIR)$(ASM_CONVERSION) <$< > $@
|
||||
|
||||
# For building *_rtcd.h, which have rules in libs.mk
|
||||
TGT_ISA:=$(word 1, $(subst -, ,$(TOOLCHAIN)))
|
||||
@@ -150,15 +153,27 @@ CODEC_SRCS_ASM_ADS2GAS = $(patsubst %.S, \
|
||||
LOCAL_SRC_FILES += $(CODEC_SRCS_ASM_ADS2GAS)
|
||||
|
||||
ifeq ($(TARGET_ARCH_ABI),armeabi-v7a)
|
||||
ASM_INCLUDES := vpx_dsp/arm/idct_neon.asm.S
|
||||
CODEC_SRCS_ASM_NEON = $(foreach v, \
|
||||
$(CODEC_SRCS_ASM_ARM_ALL),\
|
||||
$(if $(findstring neon,$(v)),$(v),))
|
||||
CODEC_SRCS_ASM_NEON := $(filter-out $(addprefix %, $(ASM_INCLUDES)), \
|
||||
$(CODEC_SRCS_ASM_NEON))
|
||||
CODEC_SRCS_ASM_NEON_ADS2GAS = $(patsubst %.S, \
|
||||
$(ASM_CNV_PATH_LOCAL)/libvpx/%.S, \
|
||||
$(CODEC_SRCS_ASM_NEON))
|
||||
LOCAL_SRC_FILES += $(patsubst %.S, \
|
||||
%.S.neon, \
|
||||
$(CODEC_SRCS_ASM_NEON_ADS2GAS))
|
||||
|
||||
NEON_ASM_TARGETS = $(patsubst %.S, \
|
||||
$(ASM_CNV_PATH)/libvpx/%.S, \
|
||||
$(CODEC_SRCS_ASM_NEON))
|
||||
# add a dependency to the full path to the ads2gas output to ensure the
|
||||
# includes are converted first.
|
||||
ifneq ($(strip $(NEON_ASM_TARGETS)),)
|
||||
$(NEON_ASM_TARGETS): $(addprefix $(ASM_CNV_PATH)/libvpx/, $(ASM_INCLUDES))
|
||||
endif
|
||||
endif
|
||||
|
||||
LOCAL_CFLAGS += \
|
||||
@@ -187,7 +202,7 @@ $$(rtcd_dep_template_SRCS): vpx_scale_rtcd.h
|
||||
$$(rtcd_dep_template_SRCS): vpx_dsp_rtcd.h
|
||||
|
||||
rtcd_dep_template_CONFIG_ASM_ABIS := x86 x86_64 armeabi-v7a
|
||||
ifneq ($(findstring $(TARGET_ARCH_ABI),$(rtcd_dep_template_CONFIG_ASM_ABIS)),)
|
||||
ifneq ($$(findstring $(TARGET_ARCH_ABI),$$(rtcd_dep_template_CONFIG_ASM_ABIS)),)
|
||||
$$(rtcd_dep_template_SRCS): vpx_config.asm
|
||||
endif
|
||||
endef
|
||||
@@ -197,16 +212,17 @@ $(eval $(call rtcd_dep_template))
|
||||
.PHONY: clean
|
||||
clean:
|
||||
@echo "Clean: ads2gas files [$(TARGET_ARCH_ABI)]"
|
||||
@$(RM) $(CODEC_SRCS_ASM_ADS2GAS) $(CODEC_SRCS_ASM_NEON_ADS2GAS)
|
||||
@$(RM) -r $(ASM_CNV_PATH)
|
||||
@$(RM) $(CLEAN-OBJS)
|
||||
$(qexec)$(RM) $(CODEC_SRCS_ASM_ADS2GAS) $(CODEC_SRCS_ASM_NEON_ADS2GAS)
|
||||
$(qexec)$(RM) -r $(ASM_CNV_PATH)
|
||||
$(qexec)$(RM) $(CLEAN-OBJS)
|
||||
|
||||
ifeq ($(ENABLE_SHARED),1)
|
||||
LOCAL_CFLAGS += -fPIC
|
||||
include $(BUILD_SHARED_LIBRARY)
|
||||
else
|
||||
include $(BUILD_STATIC_LIBRARY)
|
||||
endif
|
||||
|
||||
ifeq ($(CONFIG_RUNTIME_CPU_DETECT),yes)
|
||||
$(call import-module,cpufeatures)
|
||||
$(call import-module,android/cpufeatures)
|
||||
endif
|
||||
|
||||
@@ -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 */
|
||||
@@ -240,9 +240,9 @@ static void set_temporal_layer_pattern(int num_temporal_layers,
|
||||
cfg->ts_layer_id[1] = 2;
|
||||
cfg->ts_layer_id[2] = 1;
|
||||
cfg->ts_layer_id[3] = 2;
|
||||
// Use 40/20/40 bit allocation as example.
|
||||
cfg->ts_target_bitrate[0] = 0.4f * bitrate;
|
||||
cfg->ts_target_bitrate[1] = 0.6f * bitrate;
|
||||
// Use 45/20/35 bit allocation as example.
|
||||
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++) {
|
||||
@@ -460,7 +461,7 @@ int main(int argc, char **argv) {
|
||||
|
||||
// Set the number of threads per encode/spatial layer.
|
||||
// (1, 1, 1) means no encoder threading.
|
||||
cfg[0].g_threads = 2;
|
||||
cfg[0].g_threads = 1;
|
||||
cfg[1].g_threads = 1;
|
||||
cfg[2].g_threads = 1;
|
||||
|
||||
@@ -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;
|
||||
@@ -507,9 +508,11 @@ int main(int argc, char **argv) {
|
||||
|
||||
/* Set NOISE_SENSITIVITY to do TEMPORAL_DENOISING */
|
||||
/* Enable denoising for the highest-resolution encoder. */
|
||||
if (vpx_codec_control(&codec[0], VP8E_SET_NOISE_SENSITIVITY, 4))
|
||||
if (vpx_codec_control(&codec[0], VP8E_SET_NOISE_SENSITIVITY, 1))
|
||||
die_codec(&codec[0], "Failed to set noise_sensitivity");
|
||||
for (i = 1; i < NUM_ENCODERS; i++) {
|
||||
if (vpx_codec_control(&codec[1], VP8E_SET_NOISE_SENSITIVITY, 1))
|
||||
die_codec(&codec[1], "Failed to set noise_sensitivity");
|
||||
for (i = 2; i < NUM_ENCODERS; i++) {
|
||||
if (vpx_codec_control(&codec[i], VP8E_SET_NOISE_SENSITIVITY, 0))
|
||||
die_codec(&codec[i], "Failed to set noise_sensitivity");
|
||||
}
|
||||
@@ -556,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;
|
||||
}
|
||||
}
|
||||
@@ -617,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);
|
||||
}
|
||||
}
|
||||
@@ -661,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);
|
||||
}
|
||||
@@ -679,7 +680,7 @@ int main(int argc, const char **argv) {
|
||||
}
|
||||
#if OUTPUT_RC_STATS
|
||||
// For now, just write temporal layer streams.
|
||||
// TODO(wonkap): do spatial by re-writing superframe.
|
||||
// TODO(marpan): do spatial by re-writing superframe.
|
||||
if (svc_ctx.output_rc_stat) {
|
||||
for (tl = 0; tl < enc_cfg.ts_number_layers; ++tl) {
|
||||
char file_name[PATH_MAX];
|
||||
@@ -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,18 +770,20 @@ 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,
|
||||
cx_pkt->data.frame.sz,
|
||||
cx_pkt->data.frame.pts);
|
||||
#if OUTPUT_RC_STATS
|
||||
// TODO(marpan/wonkap): Put this (to line728) in separate function.
|
||||
// TODO(marpan): Put this (to line728) in separate function.
|
||||
if (svc_ctx.output_rc_stat) {
|
||||
vpx_codec_control(&codec, VP9E_GET_SVC_LAYER_ID, &layer_id);
|
||||
parse_superframe_index(cx_pkt->data.frame.buf,
|
||||
cx_pkt->data.frame.sz, sizes, &count);
|
||||
if (enc_cfg.ss_number_layers == 1)
|
||||
sizes[0] = cx_pkt->data.frame.sz;
|
||||
// Note computing input_layer_frames here won't account for frame
|
||||
// drops in rate control stats.
|
||||
// TODO(marpan): Fix this for non-bypass mode so we can get stats
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -702,16 +757,31 @@ int main(int argc, char **argv) {
|
||||
vpx_codec_control(&codec, VP8E_SET_CPUUSED, -speed);
|
||||
vpx_codec_control(&codec, VP8E_SET_NOISE_SENSITIVITY, kDenoiserOff);
|
||||
vpx_codec_control(&codec, VP8E_SET_STATIC_THRESHOLD, 1);
|
||||
vpx_codec_control(&codec, VP8E_SET_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));
|
||||
vpx_codec_control(&codec, VP8E_SET_CPUUSED, speed);
|
||||
vpx_codec_control(&codec, VP9E_SET_AQ_MODE, 3);
|
||||
vpx_codec_control(&codec, VP9E_SET_GF_CBR_BOOST_PCT, 0);
|
||||
vpx_codec_control(&codec, VP9E_SET_FRAME_PARALLEL_DECODING, 0);
|
||||
vpx_codec_control(&codec, VP9E_SET_FRAME_PERIODIC_BOOST, 0);
|
||||
vpx_codec_control(&codec, VP9E_SET_NOISE_SENSITIVITY, kDenoiserOff);
|
||||
vpx_codec_control(&codec, VP8E_SET_STATIC_THRESHOLD, 1);
|
||||
vpx_codec_control(&codec, VP9E_SET_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) {
|
||||
@@ -730,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);
|
||||
}
|
||||
@@ -740,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) {
|
||||
|
||||
33
libs.mk
33
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,13 +228,13 @@ 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)
|
||||
|
||||
SO_VERSION_MAJOR := 4
|
||||
SO_VERSION_MINOR := 0
|
||||
SO_VERSION_MINOR := 1
|
||||
SO_VERSION_PATCH := 0
|
||||
ifeq ($(filter darwin%,$(TGT_OS)),$(TGT_OS))
|
||||
LIBVPX_SO := libvpx.$(SO_VERSION_MAJOR).dylib
|
||||
@@ -391,7 +392,7 @@ LIBVPX_TEST_SRCS=$(addprefix test/,$(call enabled,LIBVPX_TEST_SRCS))
|
||||
LIBVPX_TEST_BIN=./test_libvpx$(EXE_SFX)
|
||||
LIBVPX_TEST_DATA=$(addprefix $(LIBVPX_TEST_DATA_PATH)/,\
|
||||
$(call enabled,LIBVPX_TEST_DATA))
|
||||
libvpx_test_data_url=http://downloads.webmproject.org/test_data/libvpx/$(1)
|
||||
libvpx_test_data_url=https://storage.googleapis.com/downloads.webmproject.org/test_data/libvpx/$(1)
|
||||
|
||||
TEST_INTRA_PRED_SPEED_BIN=./test_intra_pred_speed$(EXE_SFX)
|
||||
TEST_INTRA_PRED_SPEED_SRCS=$(addprefix test/,$(call enabled,TEST_INTRA_PRED_SPEED_SRCS))
|
||||
@@ -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 -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_;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -954,8 +1074,13 @@ TEST_P(DatarateTestVP9Large, BasicRateTargeting3TemporalLayersFrameDropping) {
|
||||
}
|
||||
|
||||
#if CONFIG_VP9_TEMPORAL_DENOISING
|
||||
class DatarateTestVP9LargeDenoiser : public DatarateTestVP9Large {
|
||||
public:
|
||||
virtual ~DatarateTestVP9LargeDenoiser() {}
|
||||
};
|
||||
|
||||
// Check basic datarate targeting, for a single bitrate, when denoiser is on.
|
||||
TEST_P(DatarateTestVP9Large, DenoiserLevels) {
|
||||
TEST_P(DatarateTestVP9LargeDenoiser, LowNoise) {
|
||||
cfg_.rc_buf_initial_sz = 500;
|
||||
cfg_.rc_buf_optimal_sz = 500;
|
||||
cfg_.rc_buf_sz = 1000;
|
||||
@@ -982,9 +1107,67 @@ TEST_P(DatarateTestVP9Large, DenoiserLevels) {
|
||||
<< " 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 clip with high noise level. Use 2 threads.
|
||||
TEST_P(DatarateTestVP9LargeDenoiser, HighNoise) {
|
||||
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 = 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.
|
||||
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.29)
|
||||
<< " The datarate for the file is greater than target by too much!";
|
||||
}
|
||||
|
||||
// Check basic datarate targeting, for a single bitrate, when denoiser is off
|
||||
// and on.
|
||||
TEST_P(DatarateTestVP9Large, DenoiserOffOn) {
|
||||
TEST_P(DatarateTestVP9LargeDenoiser, DenoiserOffOn) {
|
||||
cfg_.rc_buf_initial_sz = 500;
|
||||
cfg_.rc_buf_optimal_sz = 500;
|
||||
cfg_.rc_buf_sz = 1000;
|
||||
@@ -1040,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,
|
||||
@@ -1050,16 +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] = 7;
|
||||
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;
|
||||
@@ -1073,11 +1264,13 @@ class DatarateOnePassCbrSvc
|
||||
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;
|
||||
// TODO(marpan): This check currently fails for some of the SVC tests,
|
||||
// re-enable when issue (webm:1350) is resolved.
|
||||
// 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;
|
||||
bits_in_buffer_model_ -= frame_size_in_bits;
|
||||
bits_in_buffer_model_ -= static_cast<int64_t>(frame_size_in_bits);
|
||||
bits_total_ += frame_size_in_bits;
|
||||
if (!first_drop_ && duration > 1) first_drop_ = last_pts_ + 1;
|
||||
last_pts_ = pkt->data.frame.pts;
|
||||
@@ -1113,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,
|
||||
@@ -1144,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;
|
||||
@@ -1166,11 +1396,11 @@ 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);
|
||||
// TODO(wonkap/marpan): Check that effective_datarate for each layer hits the
|
||||
// TODO(marpan): Check that effective_datarate for each layer hits the
|
||||
// layer target_bitrate.
|
||||
for (int i = 200; i <= 800; i += 200) {
|
||||
cfg_.rc_target_bitrate = i;
|
||||
@@ -1178,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;
|
||||
@@ -1220,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;
|
||||
@@ -1250,25 +1533,30 @@ TEST_P(DatarateOnePassCbrSvc, OnePassCbrSvc2SpatialLayers4threads) {
|
||||
svc_params_.scaling_factor_den[0] = 288;
|
||||
svc_params_.scaling_factor_num[1] = 288;
|
||||
svc_params_.scaling_factor_den[1] = 288;
|
||||
cfg_.rc_dropframe_thresh = 10;
|
||||
cfg_.rc_dropframe_thresh = 0;
|
||||
cfg_.kf_max_dist = 9999;
|
||||
::libvpx_test::I420VideoSource video("niklas_1280_720_30.y4m", 1280, 720, 30,
|
||||
1, 0, 300);
|
||||
::libvpx_test::Y4mVideoSource video("niklas_1280_720_30.y4m", 0, 300);
|
||||
cfg_.rc_target_bitrate = 800;
|
||||
ResetModel();
|
||||
assign_layer_bitrates(&cfg_, &svc_params_, cfg_.ss_number_layers,
|
||||
cfg_.ts_number_layers, cfg_.temporal_layering_mode);
|
||||
ASSERT_NO_FATAL_FAILURE(RunLoop(&video));
|
||||
ASSERT_GE(cfg_.rc_target_bitrate, file_datarate_ * 0.85)
|
||||
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;
|
||||
@@ -1290,25 +1578,30 @@ 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::I420VideoSource video("niklas_1280_720_30.y4m", 1280, 720, 30,
|
||||
1, 0, 300);
|
||||
::libvpx_test::Y4mVideoSource video("niklas_1280_720_30.y4m", 0, 300);
|
||||
cfg_.rc_target_bitrate = 800;
|
||||
ResetModel();
|
||||
assign_layer_bitrates(&cfg_, &svc_params_, cfg_.ss_number_layers,
|
||||
cfg_.ts_number_layers, cfg_.temporal_layering_mode);
|
||||
ASSERT_NO_FATAL_FAILURE(RunLoop(&video));
|
||||
ASSERT_GE(cfg_.rc_target_bitrate, file_datarate_ * 0.85)
|
||||
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;
|
||||
@@ -1331,8 +1624,7 @@ TEST_P(DatarateOnePassCbrSvc, OnePassCbrSvc3SpatialLayersSmallKf) {
|
||||
svc_params_.scaling_factor_num[2] = 288;
|
||||
svc_params_.scaling_factor_den[2] = 288;
|
||||
cfg_.rc_dropframe_thresh = 10;
|
||||
::libvpx_test::I420VideoSource video("niklas_1280_720_30.y4m", 1280, 720, 30,
|
||||
1, 0, 300);
|
||||
::libvpx_test::Y4mVideoSource video("niklas_1280_720_30.y4m", 0, 300);
|
||||
cfg_.rc_target_bitrate = 800;
|
||||
// For this 3 temporal layer case, pattern repeats every 4 frames, so choose
|
||||
// 4 key neighboring key frame periods (so key frame will land on 0-2-1-2).
|
||||
@@ -1342,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;
|
||||
@@ -1374,19 +1665,58 @@ 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::I420VideoSource video("niklas_1280_720_30.y4m", 1280, 720, 30,
|
||||
1, 0, 300);
|
||||
::libvpx_test::Y4mVideoSource video("niklas_1280_720_30.y4m", 0, 300);
|
||||
cfg_.rc_target_bitrate = 800;
|
||||
ResetModel();
|
||||
assign_layer_bitrates(&cfg_, &svc_params_, cfg_.ss_number_layers,
|
||||
cfg_.ts_number_layers, cfg_.temporal_layering_mode);
|
||||
ASSERT_NO_FATAL_FAILURE(RunLoop(&video));
|
||||
ASSERT_GE(cfg_.rc_target_bitrate, file_datarate_ * 0.85)
|
||||
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!";
|
||||
#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, OnePassCbrSvc2SL1TL5x5MultipleRuns) {
|
||||
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 = 3;
|
||||
cfg_.temporal_layering_mode = 0;
|
||||
svc_params_.scaling_factor_num[0] = 256;
|
||||
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 = 10;
|
||||
cfg_.kf_max_dist = 999999;
|
||||
cfg_.kf_min_dist = 0;
|
||||
cfg_.ss_target_bitrate[0] = 300;
|
||||
cfg_.ss_target_bitrate[1] = 1400;
|
||||
cfg_.layer_target_bitrate[0] = 300;
|
||||
cfg_.layer_target_bitrate[1] = 1400;
|
||||
cfg_.rc_target_bitrate = 1700;
|
||||
::libvpx_test::Y4mVideoSource video("niklas_1280_720_30.y4m", 0, 300);
|
||||
ResetModel();
|
||||
ASSERT_NO_FATAL_FAILURE(RunLoop(&video));
|
||||
EXPECT_EQ(static_cast<unsigned int>(0), GetMismatchFrames());
|
||||
}
|
||||
|
||||
@@ -1399,6 +1729,11 @@ VP9_INSTANTIATE_TEST_CASE(DatarateTestVP9Large,
|
||||
::testing::Values(::libvpx_test::kOnePassGood,
|
||||
::libvpx_test::kRealTime),
|
||||
::testing::Range(2, 9));
|
||||
#if CONFIG_VP9_TEMPORAL_DENOISING
|
||||
VP9_INSTANTIATE_TEST_CASE(DatarateTestVP9LargeDenoiser,
|
||||
::testing::Values(::libvpx_test::kRealTime),
|
||||
::testing::Range(5, 9));
|
||||
#endif
|
||||
VP9_INSTANTIATE_TEST_CASE(DatarateOnePassCbrSvc,
|
||||
::testing::Values(::libvpx_test::kRealTime),
|
||||
::testing::Range(5, 9));
|
||||
|
||||
@@ -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_);
|
||||
|
||||
@@ -15,7 +15,7 @@
|
||||
example_tests=$(ls $(dirname $0)/*.sh)
|
||||
|
||||
# List of script names to exclude.
|
||||
exclude_list="examples tools_common"
|
||||
exclude_list="examples stress tools_common"
|
||||
|
||||
# Filter out the scripts in $exclude_list.
|
||||
for word in ${exclude_list}; do
|
||||
|
||||
@@ -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,512 +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_ASM && !CONFIG_VP9_HIGHBITDEPTH && !CONFIG_EMULATE_HARDWARE
|
||||
INSTANTIATE_TEST_CASE_P(NEON, Trans4x4DCT,
|
||||
::testing::Values(make_tuple(&vpx_fdct4x4_c,
|
||||
&vpx_idct4x4_16_add_neon,
|
||||
0, VPX_BITS_8)));
|
||||
#endif // HAVE_NEON_ASM && !CONFIG_VP9_HIGHBITDEPTH && !CONFIG_EMULATE_HARDWARE
|
||||
|
||||
#if HAVE_NEON && !CONFIG_VP9_HIGHBITDEPTH && !CONFIG_EMULATE_HARDWARE
|
||||
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 // HAVE_NEON && !CONFIG_VP9_HIGHBITDEPTH && !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;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -670,14 +670,12 @@ INSTANTIATE_TEST_CASE_P(
|
||||
make_tuple(&vp9_fht8x8_c, &vp9_iht8x8_64_add_c, 3, VPX_BITS_8)));
|
||||
#endif // CONFIG_VP9_HIGHBITDEPTH
|
||||
|
||||
#if HAVE_NEON_ASM && !CONFIG_VP9_HIGHBITDEPTH && !CONFIG_EMULATE_HARDWARE
|
||||
#if HAVE_NEON && !CONFIG_EMULATE_HARDWARE
|
||||
INSTANTIATE_TEST_CASE_P(NEON, FwdTrans8x8DCT,
|
||||
::testing::Values(make_tuple(&vpx_fdct8x8_neon,
|
||||
&vpx_idct8x8_64_add_neon,
|
||||
0, VPX_BITS_8)));
|
||||
#endif // HAVE_NEON_ASM && !CONFIG_VP9_HIGHBITDEPTH && !CONFIG_EMULATE_HARDWARE
|
||||
|
||||
#if HAVE_NEON && !CONFIG_VP9_HIGHBITDEPTH && !CONFIG_EMULATE_HARDWARE
|
||||
#if !CONFIG_VP9_HIGHBITDEPTH
|
||||
INSTANTIATE_TEST_CASE_P(
|
||||
NEON, FwdTrans8x8HT,
|
||||
::testing::Values(
|
||||
@@ -685,7 +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 // 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,
|
||||
@@ -740,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
|
||||
|
||||
@@ -757,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" },
|
||||
@@ -144,6 +156,7 @@ const DecodeParam kVP9InvalidFileTests[] = {
|
||||
{ 1, "invalid-vp90-2-03-size-202x210.webm.ivf.s113306_r01-05_b6-.ivf" },
|
||||
{ 1,
|
||||
"invalid-vp90-2-10-show-existing-frame.webm.ivf.s180315_r01-05_b6-.ivf" },
|
||||
{ 1, "invalid-crbug-667044.webm" },
|
||||
};
|
||||
|
||||
VP9_INSTANTIATE_TEST_CASE(InvalidFileTest,
|
||||
@@ -163,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,6 +66,36 @@ class LevelTest
|
||||
int level_;
|
||||
};
|
||||
|
||||
TEST_P(LevelTest, TestTargetLevel11Large) {
|
||||
ASSERT_NE(encoding_mode_, ::libvpx_test::kRealTime);
|
||||
::libvpx_test::I420VideoSource video("hantro_odd.yuv", 208, 144, 30, 1, 0,
|
||||
60);
|
||||
target_level_ = 11;
|
||||
cfg_.rc_target_bitrate = 150;
|
||||
ASSERT_NO_FATAL_FAILURE(RunLoop(&video));
|
||||
ASSERT_GE(target_level_, level_);
|
||||
}
|
||||
|
||||
TEST_P(LevelTest, TestTargetLevel20Large) {
|
||||
ASSERT_NE(encoding_mode_, ::libvpx_test::kRealTime);
|
||||
::libvpx_test::I420VideoSource video("hantro_collage_w352h288.yuv", 352, 288,
|
||||
30, 1, 0, 60);
|
||||
target_level_ = 20;
|
||||
cfg_.rc_target_bitrate = 1200;
|
||||
ASSERT_NO_FATAL_FAILURE(RunLoop(&video));
|
||||
ASSERT_GE(target_level_, level_);
|
||||
}
|
||||
|
||||
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_GE(target_level_, level_);
|
||||
}
|
||||
|
||||
// Test for keeping level stats only
|
||||
TEST_P(LevelTest, TestTargetLevel0) {
|
||||
::libvpx_test::I420VideoSource video("hantro_odd.yuv", 208, 144, 30, 1, 0,
|
||||
@@ -73,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
|
||||
@@ -94,12 +124,13 @@ TEST_P(LevelTest, TestTargetLevelApi) {
|
||||
vpx_codec_ctx_t enc;
|
||||
vpx_codec_enc_cfg_t cfg;
|
||||
EXPECT_EQ(VPX_CODEC_OK, vpx_codec_enc_config_default(codec, &cfg, 0));
|
||||
cfg.rc_target_bitrate = 100;
|
||||
EXPECT_EQ(VPX_CODEC_OK, vpx_codec_enc_init(&enc, codec, &cfg, 0));
|
||||
for (int level = 0; level <= 256; ++level) {
|
||||
if (level == 10 || level == 11 || level == 20 || level == 21 ||
|
||||
level == 30 || level == 31 || level == 40 || level == 41 ||
|
||||
level == 50 || level == 51 || level == 52 || level == 60 ||
|
||||
level == 61 || level == 62 || level == 0 || level == 255)
|
||||
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
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -7,21 +7,40 @@
|
||||
* in the file PATENTS. All contributing project authors may
|
||||
* be found in the AUTHORS file in the root of the source tree.
|
||||
*/
|
||||
#include <limits.h>
|
||||
#include "./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"
|
||||
#include "vpx/vpx_integer.h"
|
||||
#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,
|
||||
int dst_pixels_per_line, int cols, unsigned char *flimit, int size);
|
||||
|
||||
typedef void (*VpxMbPostProcAcrossIpFunc)(unsigned char *src, int pitch,
|
||||
int rows, int cols, int flimit);
|
||||
|
||||
typedef void (*VpxMbPostProcDownFunc)(unsigned char *dst, int pitch, int rows,
|
||||
int cols, int flimit);
|
||||
|
||||
namespace {
|
||||
|
||||
// Compute the filter level used in post proc from the loop filter strength
|
||||
int q2mbl(int x) {
|
||||
if (x < 20) x = 20;
|
||||
|
||||
x = 50 + (x - 50) * 10 / 8;
|
||||
return x * x / 3;
|
||||
}
|
||||
|
||||
class VpxPostProcDownAndAcrossMbRowTest
|
||||
: public ::testing::TestWithParam<VpxPostProcDownAndAcrossMbRowFunc> {
|
||||
public:
|
||||
@@ -37,25 +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;
|
||||
// Though the left padding is only 8 bytes, the assembly code tries to
|
||||
// read 16 bytes before the pointer.
|
||||
Buffer<uint8_t> dst_image =
|
||||
Buffer<uint8_t>(block_width, block_height, 8, 16, 8, 8);
|
||||
ASSERT_TRUE(dst_image.Init());
|
||||
|
||||
uint8_t *const src_image =
|
||||
reinterpret_cast<uint8_t *>(vpx_calloc(input_size, 1));
|
||||
uint8_t *const dst_image =
|
||||
reinterpret_cast<uint8_t *>(vpx_calloc(output_size, 1));
|
||||
|
||||
// Pointers to top-left pixel of block in the input and output images.
|
||||
uint8_t *const src_image_ptr = src_image + (input_stride << 1);
|
||||
uint8_t *const dst_image_ptr = dst_image + 8;
|
||||
uint8_t *const flimits =
|
||||
reinterpret_cast<uint8_t *>(vpx_memalign(16, block_width));
|
||||
(void)memset(flimits, 255, block_width);
|
||||
@@ -63,53 +73,412 @@ 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]);
|
||||
ASSERT_EQ(kExpectedOutput[i], pixel_ptr[j])
|
||||
<< "at (" << i << ", " << j << ")";
|
||||
}
|
||||
pixel_ptr += output_stride;
|
||||
pixel_ptr += dst_image.stride();
|
||||
}
|
||||
|
||||
vpx_free(src_image);
|
||||
vpx_free(dst_image);
|
||||
vpx_free(flimits);
|
||||
};
|
||||
|
||||
TEST_P(VpxPostProcDownAndAcrossMbRowTest, CheckCvsAssembly) {
|
||||
// Size of the underlying data block that will be filtered.
|
||||
// Y blocks are always a multiple of 16 wide and exactly 16 high. U and V
|
||||
// blocks are always a multiple of 8 wide and exactly 8 high.
|
||||
const int block_width = 136;
|
||||
const int block_height = 16;
|
||||
|
||||
// 5-tap filter needs 2 padding rows above and below the block in the input.
|
||||
// SSE2 reads in blocks of 16. Pad an extra 8 in case the width is not %16.
|
||||
Buffer<uint8_t> src_image =
|
||||
Buffer<uint8_t>(block_width, block_height, 2, 2, 10, 2);
|
||||
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.
|
||||
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
|
||||
// it must be padded out.
|
||||
const int flimits_width = block_width % 16 ? block_width + 8 : block_width;
|
||||
uint8_t *const flimits =
|
||||
reinterpret_cast<uint8_t *>(vpx_memalign(16, flimits_width));
|
||||
|
||||
ACMRandom rnd;
|
||||
rnd.Reset(ACMRandom::DeterministicSeed());
|
||||
// Initialize pixels in the input:
|
||||
// block pixels to random values.
|
||||
// border pixels to value 10.
|
||||
src_image.SetPadding(10);
|
||||
src_image.Set(&rnd, &ACMRandom::Rand8);
|
||||
|
||||
for (int blocks = 0; blocks < block_width; blocks += 8) {
|
||||
(void)memset(flimits, 0, sizeof(*flimits) * flimits_width);
|
||||
|
||||
for (int f = 0; f < 255; f++) {
|
||||
(void)memset(flimits + blocks, f, sizeof(*flimits) * 8);
|
||||
|
||||
dst_image.Set(0);
|
||||
dst_image_ref.Set(0);
|
||||
|
||||
vpx_post_proc_down_and_across_mb_row_c(
|
||||
src_image.TopLeftPixel(), dst_image_ref.TopLeftPixel(),
|
||||
src_image.stride(), dst_image_ref.stride(), block_width, flimits,
|
||||
block_height);
|
||||
ASM_REGISTER_STATE_CHECK(
|
||||
GetParam()(src_image.TopLeftPixel(), dst_image.TopLeftPixel(),
|
||||
src_image.stride(), dst_image.stride(), block_width,
|
||||
flimits, block_height));
|
||||
|
||||
ASSERT_TRUE(dst_image.CheckValues(dst_image_ref));
|
||||
}
|
||||
}
|
||||
|
||||
vpx_free(flimits);
|
||||
}
|
||||
|
||||
class VpxMbPostProcAcrossIpTest
|
||||
: public ::testing::TestWithParam<VpxMbPostProcAcrossIpFunc> {
|
||||
public:
|
||||
virtual void TearDown() { libvpx_test::ClearSystemState(); }
|
||||
|
||||
protected:
|
||||
void SetCols(unsigned char *s, int rows, int cols, int src_width) {
|
||||
for (int r = 0; r < rows; r++) {
|
||||
for (int c = 0; c < cols; c++) {
|
||||
s[c] = c;
|
||||
}
|
||||
s += src_width;
|
||||
}
|
||||
}
|
||||
|
||||
void RunComparison(const unsigned char *expected_output, unsigned char *src_c,
|
||||
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 << ")";
|
||||
}
|
||||
src_c += 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(
|
||||
GetParam()(s, src_width, rows, cols, filter_level));
|
||||
RunComparison(expected_output, s, rows, cols, src_width);
|
||||
}
|
||||
};
|
||||
|
||||
TEST_P(VpxMbPostProcAcrossIpTest, CheckLowFilterOutput) {
|
||||
const int rows = 16;
|
||||
const int cols = 16;
|
||||
|
||||
Buffer<uint8_t> src = Buffer<uint8_t>(cols, rows, 8, 8, 17, 8);
|
||||
ASSERT_TRUE(src.Init());
|
||||
src.SetPadding(10);
|
||||
SetCols(src.TopLeftPixel(), rows, cols, src.stride());
|
||||
|
||||
Buffer<uint8_t> expected_output = Buffer<uint8_t>(cols, rows, 0);
|
||||
ASSERT_TRUE(expected_output.Init());
|
||||
SetCols(expected_output.TopLeftPixel(), rows, cols, expected_output.stride());
|
||||
|
||||
RunFilterLevel(src.TopLeftPixel(), rows, cols, src.stride(), q2mbl(0),
|
||||
expected_output.TopLeftPixel());
|
||||
}
|
||||
|
||||
TEST_P(VpxMbPostProcAcrossIpTest, CheckMediumFilterOutput) {
|
||||
const int rows = 16;
|
||||
const int cols = 16;
|
||||
|
||||
Buffer<uint8_t> src = Buffer<uint8_t>(cols, rows, 8, 8, 17, 8);
|
||||
ASSERT_TRUE(src.Init());
|
||||
src.SetPadding(10);
|
||||
SetCols(src.TopLeftPixel(), rows, cols, src.stride());
|
||||
|
||||
static const unsigned char kExpectedOutput[cols] = {
|
||||
2, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 13
|
||||
};
|
||||
|
||||
RunFilterLevel(src.TopLeftPixel(), rows, cols, src.stride(), q2mbl(70),
|
||||
kExpectedOutput);
|
||||
}
|
||||
|
||||
TEST_P(VpxMbPostProcAcrossIpTest, CheckHighFilterOutput) {
|
||||
const int rows = 16;
|
||||
const int cols = 16;
|
||||
|
||||
Buffer<uint8_t> src = Buffer<uint8_t>(cols, rows, 8, 8, 17, 8);
|
||||
ASSERT_TRUE(src.Init());
|
||||
src.SetPadding(10);
|
||||
SetCols(src.TopLeftPixel(), rows, cols, src.stride());
|
||||
|
||||
static const unsigned char kExpectedOutput[cols] = {
|
||||
2, 2, 3, 4, 4, 5, 6, 7, 8, 9, 10, 11, 11, 12, 13, 13
|
||||
};
|
||||
|
||||
RunFilterLevel(src.TopLeftPixel(), rows, cols, src.stride(), INT_MAX,
|
||||
kExpectedOutput);
|
||||
|
||||
SetCols(src.TopLeftPixel(), rows, cols, src.stride());
|
||||
|
||||
RunFilterLevel(src.TopLeftPixel(), rows, cols, src.stride(), q2mbl(100),
|
||||
kExpectedOutput);
|
||||
}
|
||||
|
||||
TEST_P(VpxMbPostProcAcrossIpTest, CheckCvsAssembly) {
|
||||
const int rows = 16;
|
||||
const int cols = 16;
|
||||
|
||||
Buffer<uint8_t> c_mem = Buffer<uint8_t>(cols, rows, 8, 8, 17, 8);
|
||||
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++) {
|
||||
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(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)));
|
||||
|
||||
ASSERT_TRUE(asm_mem.CheckValues(c_mem));
|
||||
}
|
||||
}
|
||||
|
||||
class VpxMbPostProcDownTest
|
||||
: public ::testing::TestWithParam<VpxMbPostProcDownFunc> {
|
||||
public:
|
||||
virtual void TearDown() { libvpx_test::ClearSystemState(); }
|
||||
|
||||
protected:
|
||||
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 += src_width;
|
||||
}
|
||||
}
|
||||
|
||||
void RunComparison(const unsigned char *expected_output, unsigned char *src_c,
|
||||
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 << ")";
|
||||
}
|
||||
src_c += 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(
|
||||
GetParam()(s, src_width, rows, cols, filter_level));
|
||||
RunComparison(expected_output, s, rows, cols, src_width);
|
||||
}
|
||||
};
|
||||
|
||||
TEST_P(VpxMbPostProcDownTest, CheckHighFilterOutput) {
|
||||
const int rows = 16;
|
||||
const int cols = 16;
|
||||
|
||||
Buffer<uint8_t> src_c = Buffer<uint8_t>(cols, rows, 8, 8, 8, 17);
|
||||
ASSERT_TRUE(src_c.Init());
|
||||
src_c.SetPadding(10);
|
||||
|
||||
SetRows(src_c.TopLeftPixel(), rows, cols, src_c.stride());
|
||||
|
||||
static const unsigned char kExpectedOutput[rows * cols] = {
|
||||
2, 2, 1, 1, 2, 2, 2, 2, 2, 2, 1, 1, 2, 2, 2, 2, 2, 2, 2,
|
||||
2, 3, 2, 2, 2, 2, 2, 2, 2, 3, 2, 2, 2, 3, 3, 3, 3, 3, 3,
|
||||
3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 4, 4, 3, 4, 4, 3, 3, 3,
|
||||
4, 4, 3, 4, 4, 3, 3, 4, 5, 4, 4, 4, 4, 4, 4, 4, 5, 4, 4,
|
||||
4, 4, 4, 4, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
|
||||
5, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 7, 7,
|
||||
7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 8, 8, 8, 8, 8,
|
||||
8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 9, 8, 9, 9, 8, 8, 8, 9,
|
||||
9, 8, 9, 9, 8, 8, 8, 9, 9, 10, 10, 9, 9, 9, 10, 10, 9, 10, 10,
|
||||
9, 9, 9, 10, 10, 10, 11, 10, 10, 10, 11, 10, 11, 10, 11, 10, 10, 10, 11,
|
||||
10, 11, 11, 11, 11, 11, 11, 11, 12, 11, 11, 11, 11, 11, 11, 11, 12, 11, 12,
|
||||
12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 13, 12,
|
||||
13, 12, 13, 12, 12, 12, 13, 12, 13, 12, 13, 12, 13, 13, 13, 14, 13, 13, 13,
|
||||
13, 13, 13, 13, 14, 13, 13, 13, 13
|
||||
};
|
||||
|
||||
RunFilterLevel(src_c.TopLeftPixel(), rows, cols, src_c.stride(), INT_MAX,
|
||||
kExpectedOutput);
|
||||
|
||||
src_c.SetPadding(10);
|
||||
SetRows(src_c.TopLeftPixel(), rows, cols, src_c.stride());
|
||||
RunFilterLevel(src_c.TopLeftPixel(), rows, cols, src_c.stride(), q2mbl(100),
|
||||
kExpectedOutput);
|
||||
}
|
||||
|
||||
TEST_P(VpxMbPostProcDownTest, CheckMediumFilterOutput) {
|
||||
const int rows = 16;
|
||||
const int cols = 16;
|
||||
|
||||
Buffer<uint8_t> src_c = Buffer<uint8_t>(cols, rows, 8, 8, 8, 17);
|
||||
ASSERT_TRUE(src_c.Init());
|
||||
src_c.SetPadding(10);
|
||||
|
||||
SetRows(src_c.TopLeftPixel(), rows, cols, src_c.stride());
|
||||
|
||||
static const unsigned char kExpectedOutput[rows * cols] = {
|
||||
2, 2, 1, 1, 2, 2, 2, 2, 2, 2, 1, 1, 2, 2, 2, 2, 2, 2, 2,
|
||||
2, 3, 2, 2, 2, 2, 2, 2, 2, 3, 2, 2, 2, 2, 2, 2, 2, 2, 2,
|
||||
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3, 3,
|
||||
3, 3, 3, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
|
||||
4, 4, 4, 4, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
|
||||
5, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 7, 7,
|
||||
7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 8, 8, 8, 8, 8,
|
||||
8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 9, 9, 9, 9, 9, 9, 9, 9,
|
||||
9, 9, 9, 9, 9, 9, 9, 9, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10,
|
||||
10, 10, 10, 10, 10, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11,
|
||||
11, 11, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 13,
|
||||
13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 12, 12, 13, 12,
|
||||
13, 12, 13, 12, 12, 12, 13, 12, 13, 12, 13, 12, 13, 13, 13, 14, 13, 13, 13,
|
||||
13, 13, 13, 13, 14, 13, 13, 13, 13
|
||||
};
|
||||
|
||||
RunFilterLevel(src_c.TopLeftPixel(), rows, cols, src_c.stride(), q2mbl(70),
|
||||
kExpectedOutput);
|
||||
}
|
||||
|
||||
TEST_P(VpxMbPostProcDownTest, CheckLowFilterOutput) {
|
||||
const int rows = 16;
|
||||
const int cols = 16;
|
||||
|
||||
Buffer<uint8_t> src_c = Buffer<uint8_t>(cols, rows, 8, 8, 8, 17);
|
||||
ASSERT_TRUE(src_c.Init());
|
||||
src_c.SetPadding(10);
|
||||
|
||||
SetRows(src_c.TopLeftPixel(), rows, cols, src_c.stride());
|
||||
|
||||
unsigned char *expected_output = new unsigned char[rows * cols];
|
||||
ASSERT_TRUE(expected_output != NULL);
|
||||
SetRows(expected_output, rows, cols, cols);
|
||||
|
||||
RunFilterLevel(src_c.TopLeftPixel(), rows, cols, src_c.stride(), q2mbl(0),
|
||||
expected_output);
|
||||
|
||||
delete[] expected_output;
|
||||
}
|
||||
|
||||
TEST_P(VpxMbPostProcDownTest, CheckCvsAssembly) {
|
||||
const int rows = 16;
|
||||
const int cols = 16;
|
||||
|
||||
ACMRandom rnd;
|
||||
rnd.Reset(ACMRandom::DeterministicSeed());
|
||||
|
||||
Buffer<uint8_t> src_c = Buffer<uint8_t>(cols, rows, 8, 8, 8, 17);
|
||||
ASSERT_TRUE(src_c.Init());
|
||||
Buffer<uint8_t> src_asm = Buffer<uint8_t>(cols, rows, 8, 8, 8, 17);
|
||||
ASSERT_TRUE(src_asm.Init());
|
||||
|
||||
for (int level = 0; level < 100; level++) {
|
||||
src_c.SetPadding(10);
|
||||
src_asm.SetPadding(10);
|
||||
src_c.Set(&rnd, &ACMRandom::Rand8);
|
||||
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));
|
||||
|
||||
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));
|
||||
}
|
||||
}
|
||||
|
||||
INSTANTIATE_TEST_CASE_P(
|
||||
C, VpxPostProcDownAndAcrossMbRowTest,
|
||||
::testing::Values(vpx_post_proc_down_and_across_mb_row_c));
|
||||
|
||||
INSTANTIATE_TEST_CASE_P(C, VpxMbPostProcAcrossIpTest,
|
||||
::testing::Values(vpx_mbpost_proc_across_ip_c));
|
||||
|
||||
INSTANTIATE_TEST_CASE_P(C, VpxMbPostProcDownTest,
|
||||
::testing::Values(vpx_mbpost_proc_down_c));
|
||||
|
||||
#if HAVE_SSE2
|
||||
INSTANTIATE_TEST_CASE_P(
|
||||
SSE2, VpxPostProcDownAndAcrossMbRowTest,
|
||||
::testing::Values(vpx_post_proc_down_and_across_mb_row_sse2));
|
||||
#endif
|
||||
|
||||
INSTANTIATE_TEST_CASE_P(SSE2, VpxMbPostProcAcrossIpTest,
|
||||
::testing::Values(vpx_mbpost_proc_across_ip_sse2));
|
||||
|
||||
INSTANTIATE_TEST_CASE_P(SSE2, VpxMbPostProcDownTest,
|
||||
::testing::Values(vpx_mbpost_proc_down_sse2));
|
||||
#endif // HAVE_SSE2
|
||||
|
||||
#if HAVE_NEON
|
||||
INSTANTIATE_TEST_CASE_P(
|
||||
NEON, VpxPostProcDownAndAcrossMbRowTest,
|
||||
::testing::Values(vpx_post_proc_down_and_across_mb_row_neon));
|
||||
|
||||
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
|
||||
INSTANTIATE_TEST_CASE_P(
|
||||
MSA, VpxPostProcDownAndAcrossMbRowTest,
|
||||
::testing::Values(vpx_post_proc_down_and_across_mb_row_msa));
|
||||
#endif
|
||||
|
||||
INSTANTIATE_TEST_CASE_P(MSA, VpxMbPostProcAcrossIpTest,
|
||||
::testing::Values(vpx_mbpost_proc_across_ip_msa));
|
||||
|
||||
INSTANTIATE_TEST_CASE_P(MSA, VpxMbPostProcDownTest,
|
||||
::testing::Values(vpx_mbpost_proc_down_msa));
|
||||
#endif // HAVE_MSA
|
||||
|
||||
} // namespace
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -32,7 +32,9 @@
|
||||
|
||||
#undef NOMINMAX
|
||||
#define NOMINMAX
|
||||
#ifndef WIN32_LEAN_AND_MEAN
|
||||
#define WIN32_LEAN_AND_MEAN
|
||||
#endif
|
||||
#include <windows.h>
|
||||
#include <winnt.h>
|
||||
|
||||
@@ -111,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,
|
||||
|
||||
169
test/stress.sh
Executable file
169
test/stress.sh
Executable file
@@ -0,0 +1,169 @@
|
||||
#!/bin/sh
|
||||
##
|
||||
## 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.
|
||||
##
|
||||
## 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
|
||||
|
||||
YUV="${LIBVPX_TEST_DATA_PATH}/niklas_1280_720_30.yuv"
|
||||
VP8="${LIBVPX_TEST_DATA_PATH}/tos_vp8.webm"
|
||||
VP9="${LIBVPX_TEST_DATA_PATH}/vp90-2-sintel_1920x818_tile_1x4_fpm_2279kbps.webm"
|
||||
DATA_URL="http://downloads.webmproject.org/test_data/libvpx/"
|
||||
SHA1_FILE="$(dirname $0)/test-data.sha1"
|
||||
|
||||
# Set sha1sum to proper sha program (sha1sum, shasum, sha1). This code is
|
||||
# cribbed from libs.mk.
|
||||
[ -x "$(which sha1sum)" ] && sha1sum=sha1sum
|
||||
[ -x "$(which shasum)" ] && sha1sum=shasum
|
||||
[ -x "$(which sha1)" ] && sha1sum=sha1
|
||||
|
||||
# Download a file from the url and check its sha1sum.
|
||||
download_and_check_file() {
|
||||
# Get the file from the file path.
|
||||
local readonly root="${1#${LIBVPX_TEST_DATA_PATH}/}"
|
||||
|
||||
# Download the file using curl. Trap to insure non partial file.
|
||||
(trap "rm -f $1" INT TERM \
|
||||
&& eval "curl --retry 1 -L -o $1 ${DATA_URL}${root} ${devnull}")
|
||||
|
||||
# Check the sha1 sum of the file.
|
||||
if [ -n "${sha1sum}" ]; then
|
||||
set -e
|
||||
grep ${root} ${SHA1_FILE} \
|
||||
| (cd ${LIBVPX_TEST_DATA_PATH}; ${sha1sum} -c);
|
||||
fi
|
||||
}
|
||||
|
||||
# Environment check: Make sure input is available.
|
||||
stress_verify_environment() {
|
||||
if [ ! -e "${SHA1_FILE}" ] ; then
|
||||
echo "Missing ${SHA1_FILE}"
|
||||
return 1
|
||||
fi
|
||||
for file in "${YUV}" "${VP8}" "${VP9}"; do
|
||||
if [ ! -e "${file}" ] ; then
|
||||
download_and_check_file "${file}"
|
||||
fi
|
||||
done
|
||||
if [ ! -e "${YUV}" ] || [ ! -e "${VP8}" ] || [ ! -e "${VP9}" ] ; then
|
||||
elog "Libvpx test data must exist in LIBVPX_TEST_DATA_PATH."
|
||||
return 1
|
||||
fi
|
||||
if [ -z "$(vpx_tool_path vpxenc)" ]; then
|
||||
elog "vpxenc not found. It must exist in LIBVPX_BIN_PATH or its parent."
|
||||
return 1
|
||||
fi
|
||||
if [ -z "$(vpx_tool_path vpxdec)" ]; then
|
||||
elog "vpxdec not found. It must exist in LIBVPX_BIN_PATH or its parent."
|
||||
return 1
|
||||
fi
|
||||
}
|
||||
|
||||
# This function runs tests on libvpx that run multiple encodes and decodes
|
||||
# in parallel in hopes of catching synchronization and/or threading issues.
|
||||
stress() {
|
||||
local readonly decoder="$(vpx_tool_path vpxdec)"
|
||||
local readonly encoder="$(vpx_tool_path vpxenc)"
|
||||
local readonly codec="$1"
|
||||
local readonly webm="$2"
|
||||
local readonly decode_count="$3"
|
||||
local readonly threads="$4"
|
||||
local readonly enc_args="$5"
|
||||
local 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 ${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
|
||||
|
||||
# Start $rt_max_jobs rt encode jobs in parallel.
|
||||
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 ${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" \
|
||||
"--overshoot-pct=15 --buf-sz=1000 --buf-initial-sz=500" \
|
||||
"--buf-optimal-sz=600 --max-intra-rate=900 --resize-allowed=0" \
|
||||
"--drop-frame=0 --passes=1 --rt --noise-sensitivity=4" \
|
||||
"-o ${VPX_TEST_OUTPUT_DIR}/${i}.rt.webm" ${devnull} &
|
||||
pids="${pids} $!"
|
||||
done
|
||||
|
||||
# Start $decode_count decode jobs in parallel.
|
||||
for i in $(seq "${decode_count}"); do
|
||||
eval "${decoder}" "-t ${threads}" "${webm}" "--noblit" ${devnull} &
|
||||
pids="${pids} $!"
|
||||
done
|
||||
|
||||
# Wait for all parallel jobs to finish.
|
||||
fail=0
|
||||
for job in "${pids}"; do
|
||||
wait $job || fail=$(($fail + 1))
|
||||
done
|
||||
return $fail
|
||||
}
|
||||
|
||||
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}" 4
|
||||
fi
|
||||
}
|
||||
|
||||
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}" "$@"
|
||||
fi
|
||||
}
|
||||
|
||||
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
|
||||
|
||||
@@ -438,7 +438,7 @@ TEST_F(SvcTest, SetAutoAltRefOption) {
|
||||
// Test that decoder can handle an SVC frame as the first frame in a sequence.
|
||||
TEST_F(SvcTest, OnePassEncodeOneFrame) {
|
||||
codec_enc_.g_pass = VPX_RC_ONE_PASS;
|
||||
vpx_fixed_buf output = { 0 };
|
||||
vpx_fixed_buf output = vpx_fixed_buf();
|
||||
Pass2EncodeNFrames(NULL, 1, 2, &output);
|
||||
DecodeNFrames(&output, 1);
|
||||
FreeBitstreamBuffers(&output, 1);
|
||||
|
||||
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
|
||||
@@ -20,8 +20,10 @@ LIBVPX_TEST_DATA-$(CONFIG_ENCODERS) += park_joy_90p_8_440.yuv
|
||||
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_ENCODER) += desktop_credits.y4m
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_ENCODER) += niklas_1280_720_30.y4m
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_ENCODER) += 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
|
||||
@@ -730,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
|
||||
@@ -770,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
|
||||
@@ -777,6 +783,8 @@ LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += invalid-vp90-2-07-frame_parallel-2.web
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += invalid-vp90-2-07-frame_parallel-3.webm
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += invalid-crbug-629481.webm
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += invalid-crbug-629481.webm.res
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += invalid-crbug-667044.webm
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += invalid-crbug-667044.webm.res
|
||||
|
||||
ifeq ($(CONFIG_DECODE_PERF_TESTS),yes)
|
||||
# Encode / Decode test
|
||||
@@ -811,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
|
||||
@@ -871,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
|
||||
@@ -14,6 +16,7 @@ df1a1453feb3c00d7d89746c7003b4163523bff3 *invalid-vp90-03-v3.webm
|
||||
4935c62becc68c13642a03db1e6d3e2331c1c612 *invalid-vp90-03-v3.webm.res
|
||||
d637297561dd904eb2c97a9015deeb31c4a1e8d2 *invalid-vp90-2-08-tile_1x4_frame_parallel_all_key.webm
|
||||
3a204bdbeaa3c6458b77bcebb8366d107267f55d *invalid-vp90-2-08-tile_1x4_frame_parallel_all_key.webm.res
|
||||
9aa21d8b2cb9d39abe8a7bb6032dc66955fb4342 *noisy_clip_640_360.y4m
|
||||
a432f96ff0a787268e2f94a8092ab161a18d1b06 *park_joy_90p_10_420.y4m
|
||||
0b194cc312c3a2e84d156a221b0a5eb615dfddc5 *park_joy_90p_10_422.y4m
|
||||
ff0e0a21dc2adc95b8c1b37902713700655ced17 *park_joy_90p_10_444.y4m
|
||||
@@ -844,3 +847,10 @@ a000d568431d07379dd5a8ec066061c07e560b47 *invalid-vp90-2-00-quantizer-63.ivf.kf_
|
||||
5d9474c0309b7ca09a182d888f73b37a8fe1362c *invalid-crbug-629481.webm.res
|
||||
7602e00378161ca36ae93cc6ee12dd30b5ba1e1d *vp90-2-22-svc_1280x720_3.ivf
|
||||
02e53e3eefbf25ec0929047fe50876acdeb040bd *vp90-2-22-svc_1280x720_3.ivf.md5
|
||||
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
|
||||
|
||||
|
||||
@@ -270,19 +270,22 @@ INTRA_PRED_TEST(NEON, TestIntraPred4, vpx_dc_predictor_4x4_neon,
|
||||
INTRA_PRED_TEST(NEON, TestIntraPred8, vpx_dc_predictor_8x8_neon,
|
||||
vpx_dc_left_predictor_8x8_neon, vpx_dc_top_predictor_8x8_neon,
|
||||
vpx_dc_128_predictor_8x8_neon, vpx_v_predictor_8x8_neon,
|
||||
vpx_h_predictor_8x8_neon, vpx_d45_predictor_8x8_neon, NULL,
|
||||
NULL, NULL, NULL, NULL, vpx_tm_predictor_8x8_neon)
|
||||
vpx_h_predictor_8x8_neon, vpx_d45_predictor_8x8_neon,
|
||||
vpx_d135_predictor_8x8_neon, NULL, NULL, NULL, NULL,
|
||||
vpx_tm_predictor_8x8_neon)
|
||||
INTRA_PRED_TEST(NEON, TestIntraPred16, vpx_dc_predictor_16x16_neon,
|
||||
vpx_dc_left_predictor_16x16_neon,
|
||||
vpx_dc_top_predictor_16x16_neon,
|
||||
vpx_dc_128_predictor_16x16_neon, vpx_v_predictor_16x16_neon,
|
||||
vpx_h_predictor_16x16_neon, vpx_d45_predictor_16x16_neon, NULL,
|
||||
NULL, NULL, NULL, NULL, vpx_tm_predictor_16x16_neon)
|
||||
vpx_h_predictor_16x16_neon, vpx_d45_predictor_16x16_neon,
|
||||
vpx_d135_predictor_16x16_neon, NULL, NULL, NULL, NULL,
|
||||
vpx_tm_predictor_16x16_neon)
|
||||
INTRA_PRED_TEST(NEON, TestIntraPred32, vpx_dc_predictor_32x32_neon,
|
||||
vpx_dc_left_predictor_32x32_neon,
|
||||
vpx_dc_top_predictor_32x32_neon,
|
||||
vpx_dc_128_predictor_32x32_neon, vpx_v_predictor_32x32_neon,
|
||||
vpx_h_predictor_32x32_neon, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
vpx_h_predictor_32x32_neon, vpx_d45_predictor_32x32_neon,
|
||||
vpx_d135_predictor_32x32_neon, NULL, NULL, NULL, NULL,
|
||||
vpx_tm_predictor_32x32_neon)
|
||||
#endif // HAVE_NEON
|
||||
|
||||
@@ -309,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
|
||||
@@ -452,29 +480,107 @@ 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,
|
||||
vpx_highbd_dc_left_predictor_4x4_neon, vpx_highbd_dc_top_predictor_4x4_neon,
|
||||
vpx_highbd_dc_128_predictor_4x4_neon, vpx_highbd_v_predictor_4x4_neon,
|
||||
vpx_highbd_h_predictor_4x4_neon, vpx_highbd_d45_predictor_4x4_neon,
|
||||
vpx_highbd_d135_predictor_4x4_neon, NULL, NULL, NULL, NULL,
|
||||
vpx_highbd_tm_predictor_4x4_neon)
|
||||
HIGHBD_INTRA_PRED_TEST(
|
||||
NEON, TestHighbdIntraPred8, vpx_highbd_dc_predictor_8x8_neon,
|
||||
vpx_highbd_dc_left_predictor_8x8_neon, vpx_highbd_dc_top_predictor_8x8_neon,
|
||||
vpx_highbd_dc_128_predictor_8x8_neon, vpx_highbd_v_predictor_8x8_neon,
|
||||
vpx_highbd_h_predictor_8x8_neon, vpx_highbd_d45_predictor_8x8_neon,
|
||||
vpx_highbd_d135_predictor_8x8_neon, NULL, NULL, NULL, NULL,
|
||||
vpx_highbd_tm_predictor_8x8_neon)
|
||||
HIGHBD_INTRA_PRED_TEST(NEON, TestHighbdIntraPred16,
|
||||
vpx_highbd_dc_predictor_16x16_neon,
|
||||
vpx_highbd_dc_left_predictor_16x16_neon,
|
||||
vpx_highbd_dc_top_predictor_16x16_neon,
|
||||
vpx_highbd_dc_128_predictor_16x16_neon,
|
||||
vpx_highbd_v_predictor_16x16_neon,
|
||||
vpx_highbd_h_predictor_16x16_neon,
|
||||
vpx_highbd_d45_predictor_16x16_neon,
|
||||
vpx_highbd_d135_predictor_16x16_neon, NULL, NULL, NULL,
|
||||
NULL, vpx_highbd_tm_predictor_16x16_neon)
|
||||
HIGHBD_INTRA_PRED_TEST(NEON, TestHighbdIntraPred32,
|
||||
vpx_highbd_dc_predictor_32x32_neon,
|
||||
vpx_highbd_dc_left_predictor_32x32_neon,
|
||||
vpx_highbd_dc_top_predictor_32x32_neon,
|
||||
vpx_highbd_dc_128_predictor_32x32_neon,
|
||||
vpx_highbd_v_predictor_32x32_neon,
|
||||
vpx_highbd_h_predictor_32x32_neon,
|
||||
vpx_highbd_d45_predictor_32x32_neon,
|
||||
vpx_highbd_d135_predictor_32x32_neon, NULL, NULL, NULL,
|
||||
NULL, vpx_highbd_tm_predictor_32x32_neon)
|
||||
#endif // HAVE_NEON
|
||||
|
||||
#endif // CONFIG_VP9_HIGHBITDEPTH
|
||||
|
||||
#include "test/test_libvpx.cc"
|
||||
|
||||
@@ -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,38 +127,44 @@ 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 +
|
||||
libvpx_test::kNumVP8TestVectors)));
|
||||
|
||||
// Test VP8 decode in with different numbers of threads.
|
||||
INSTANTIATE_TEST_CASE_P(
|
||||
VP8MultiThreaded, TestVectorTest,
|
||||
::testing::Combine(
|
||||
::testing::Values(
|
||||
static_cast<const libvpx_test::CodecFactory *>(&libvpx_test::kVP8)),
|
||||
::testing::Combine(
|
||||
::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
@@ -13,7 +13,9 @@
|
||||
#if defined(_WIN32)
|
||||
#undef NOMINMAX
|
||||
#define NOMINMAX
|
||||
#ifndef WIN32_LEAN_AND_MEAN
|
||||
#define WIN32_LEAN_AND_MEAN
|
||||
#endif
|
||||
#include <windows.h>
|
||||
#endif
|
||||
#include <cstdio>
|
||||
|
||||
@@ -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,43 +302,127 @@ 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);
|
||||
}
|
||||
|
||||
VP9_INSTANTIATE_TEST_CASE(VPxEncoderThreadTest,
|
||||
::testing::Values(::libvpx_test::kTwoPassGood,
|
||||
::libvpx_test::kOnePassGood,
|
||||
::libvpx_test::kRealTime),
|
||||
::testing::Range(0, 9), // cpu_used
|
||||
::testing::Range(0, 3), // tile_columns
|
||||
::testing::Range(2, 5)); // threads
|
||||
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.
|
||||
INSTANTIATE_TEST_CASE_P(
|
||||
VP9, VPxEncoderThreadTest,
|
||||
::testing::Combine(
|
||||
::testing::Values(
|
||||
static_cast<const libvpx_test::CodecFactory *>(&libvpx_test::kVP9)),
|
||||
::testing::Values(::libvpx_test::kTwoPassGood,
|
||||
::libvpx_test::kOnePassGood,
|
||||
::libvpx_test::kRealTime),
|
||||
::testing::Range(3, 9), // cpu_used
|
||||
::testing::Range(0, 3), // tile_columns
|
||||
::testing::Range(2, 5))); // threads
|
||||
|
||||
INSTANTIATE_TEST_CASE_P(
|
||||
VP9Large, VPxEncoderThreadTest,
|
||||
::testing::Combine(
|
||||
::testing::Values(
|
||||
static_cast<const libvpx_test::CodecFactory *>(&libvpx_test::kVP9)),
|
||||
::testing::Values(::libvpx_test::kTwoPassGood,
|
||||
::libvpx_test::kOnePassGood,
|
||||
::libvpx_test::kRealTime),
|
||||
::testing::Range(0, 3), // cpu_used
|
||||
::testing::Range(0, 3), // tile_columns
|
||||
::testing::Range(2, 5))); // threads
|
||||
|
||||
} // namespace
|
||||
|
||||
@@ -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
|
||||
@@ -235,8 +235,16 @@ INSTANTIATE_TEST_CASE_P(
|
||||
8),
|
||||
IntraPredParam(&vpx_d45_predictor_16x16_neon,
|
||||
&vpx_d45_predictor_16x16_c, 16, 8),
|
||||
IntraPredParam(&vpx_d45_predictor_32x32_neon,
|
||||
&vpx_d45_predictor_32x32_c, 32, 8),
|
||||
IntraPredParam(&vpx_d135_predictor_4x4_neon, &vpx_d135_predictor_4x4_c,
|
||||
4, 8),
|
||||
IntraPredParam(&vpx_d135_predictor_8x8_neon, &vpx_d135_predictor_8x8_c,
|
||||
8, 8),
|
||||
IntraPredParam(&vpx_d135_predictor_16x16_neon,
|
||||
&vpx_d135_predictor_16x16_c, 16, 8),
|
||||
IntraPredParam(&vpx_d135_predictor_32x32_neon,
|
||||
&vpx_d135_predictor_32x32_c, 32, 8),
|
||||
IntraPredParam(&vpx_dc_128_predictor_4x4_neon,
|
||||
&vpx_dc_128_predictor_4x4_c, 4, 8),
|
||||
IntraPredParam(&vpx_dc_128_predictor_8x8_neon,
|
||||
@@ -291,6 +299,139 @@ INSTANTIATE_TEST_CASE_P(
|
||||
32, 8)));
|
||||
#endif // HAVE_NEON
|
||||
|
||||
#if HAVE_DSPR2
|
||||
INSTANTIATE_TEST_CASE_P(
|
||||
DSPR2, VP9IntraPredTest,
|
||||
::testing::Values(IntraPredParam(&vpx_dc_predictor_4x4_dspr2,
|
||||
&vpx_dc_predictor_4x4_c, 4, 8),
|
||||
IntraPredParam(&vpx_dc_predictor_8x8_dspr2,
|
||||
&vpx_dc_predictor_8x8_c, 8, 8),
|
||||
IntraPredParam(&vpx_dc_predictor_16x16_dspr2,
|
||||
&vpx_dc_predictor_16x16_c, 16, 8),
|
||||
IntraPredParam(&vpx_h_predictor_4x4_dspr2,
|
||||
&vpx_h_predictor_4x4_c, 4, 8),
|
||||
IntraPredParam(&vpx_h_predictor_8x8_dspr2,
|
||||
&vpx_h_predictor_8x8_c, 8, 8),
|
||||
IntraPredParam(&vpx_h_predictor_16x16_dspr2,
|
||||
&vpx_h_predictor_16x16_c, 16, 8),
|
||||
IntraPredParam(&vpx_tm_predictor_4x4_dspr2,
|
||||
&vpx_tm_predictor_4x4_c, 4, 8),
|
||||
IntraPredParam(&vpx_tm_predictor_8x8_dspr2,
|
||||
&vpx_tm_predictor_8x8_c, 8, 8)));
|
||||
#endif // HAVE_DSPR2
|
||||
|
||||
#if HAVE_MSA
|
||||
INSTANTIATE_TEST_CASE_P(
|
||||
MSA, VP9IntraPredTest,
|
||||
::testing::Values(
|
||||
IntraPredParam(&vpx_dc_128_predictor_4x4_msa,
|
||||
&vpx_dc_128_predictor_4x4_c, 4, 8),
|
||||
IntraPredParam(&vpx_dc_128_predictor_8x8_msa,
|
||||
&vpx_dc_128_predictor_8x8_c, 8, 8),
|
||||
IntraPredParam(&vpx_dc_128_predictor_16x16_msa,
|
||||
&vpx_dc_128_predictor_16x16_c, 16, 8),
|
||||
IntraPredParam(&vpx_dc_128_predictor_32x32_msa,
|
||||
&vpx_dc_128_predictor_32x32_c, 32, 8),
|
||||
IntraPredParam(&vpx_dc_left_predictor_4x4_msa,
|
||||
&vpx_dc_left_predictor_4x4_c, 4, 8),
|
||||
IntraPredParam(&vpx_dc_left_predictor_8x8_msa,
|
||||
&vpx_dc_left_predictor_8x8_c, 8, 8),
|
||||
IntraPredParam(&vpx_dc_left_predictor_16x16_msa,
|
||||
&vpx_dc_left_predictor_16x16_c, 16, 8),
|
||||
IntraPredParam(&vpx_dc_left_predictor_32x32_msa,
|
||||
&vpx_dc_left_predictor_32x32_c, 32, 8),
|
||||
IntraPredParam(&vpx_dc_predictor_4x4_msa, &vpx_dc_predictor_4x4_c, 4,
|
||||
8),
|
||||
IntraPredParam(&vpx_dc_predictor_8x8_msa, &vpx_dc_predictor_8x8_c, 8,
|
||||
8),
|
||||
IntraPredParam(&vpx_dc_predictor_16x16_msa, &vpx_dc_predictor_16x16_c,
|
||||
16, 8),
|
||||
IntraPredParam(&vpx_dc_predictor_32x32_msa, &vpx_dc_predictor_32x32_c,
|
||||
32, 8),
|
||||
IntraPredParam(&vpx_dc_top_predictor_4x4_msa,
|
||||
&vpx_dc_top_predictor_4x4_c, 4, 8),
|
||||
IntraPredParam(&vpx_dc_top_predictor_8x8_msa,
|
||||
&vpx_dc_top_predictor_8x8_c, 8, 8),
|
||||
IntraPredParam(&vpx_dc_top_predictor_16x16_msa,
|
||||
&vpx_dc_top_predictor_16x16_c, 16, 8),
|
||||
IntraPredParam(&vpx_dc_top_predictor_32x32_msa,
|
||||
&vpx_dc_top_predictor_32x32_c, 32, 8),
|
||||
IntraPredParam(&vpx_h_predictor_4x4_msa, &vpx_h_predictor_4x4_c, 4, 8),
|
||||
IntraPredParam(&vpx_h_predictor_8x8_msa, &vpx_h_predictor_8x8_c, 8, 8),
|
||||
IntraPredParam(&vpx_h_predictor_16x16_msa, &vpx_h_predictor_16x16_c, 16,
|
||||
8),
|
||||
IntraPredParam(&vpx_h_predictor_32x32_msa, &vpx_h_predictor_32x32_c, 32,
|
||||
8),
|
||||
IntraPredParam(&vpx_tm_predictor_4x4_msa, &vpx_tm_predictor_4x4_c, 4,
|
||||
8),
|
||||
IntraPredParam(&vpx_tm_predictor_8x8_msa, &vpx_tm_predictor_8x8_c, 8,
|
||||
8),
|
||||
IntraPredParam(&vpx_tm_predictor_16x16_msa, &vpx_tm_predictor_16x16_c,
|
||||
16, 8),
|
||||
IntraPredParam(&vpx_tm_predictor_32x32_msa, &vpx_tm_predictor_32x32_c,
|
||||
32, 8),
|
||||
IntraPredParam(&vpx_v_predictor_4x4_msa, &vpx_v_predictor_4x4_c, 4, 8),
|
||||
IntraPredParam(&vpx_v_predictor_8x8_msa, &vpx_v_predictor_8x8_c, 8, 8),
|
||||
IntraPredParam(&vpx_v_predictor_16x16_msa, &vpx_v_predictor_16x16_c, 16,
|
||||
8),
|
||||
IntraPredParam(&vpx_v_predictor_32x32_msa, &vpx_v_predictor_32x32_c, 32,
|
||||
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,
|
||||
@@ -326,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,
|
||||
@@ -338,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,
|
||||
@@ -346,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,
|
||||
@@ -358,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,
|
||||
@@ -366,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,
|
||||
@@ -374,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,
|
||||
@@ -386,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,
|
||||
@@ -394,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,
|
||||
@@ -402,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,
|
||||
@@ -412,5 +807,235 @@ INSTANTIATE_TEST_CASE_P(
|
||||
&vpx_highbd_v_predictor_32x32_c, 32, 12)));
|
||||
#endif // HAVE_SSE2
|
||||
|
||||
#if HAVE_NEON
|
||||
INSTANTIATE_TEST_CASE_P(
|
||||
NEON_TO_C_8, VP9HighbdIntraPredTest,
|
||||
::testing::Values(
|
||||
HighbdIntraPredParam(&vpx_highbd_d45_predictor_4x4_neon,
|
||||
&vpx_highbd_d45_predictor_4x4_c, 4, 8),
|
||||
HighbdIntraPredParam(&vpx_highbd_d45_predictor_8x8_neon,
|
||||
&vpx_highbd_d45_predictor_8x8_c, 8, 8),
|
||||
HighbdIntraPredParam(&vpx_highbd_d45_predictor_16x16_neon,
|
||||
&vpx_highbd_d45_predictor_16x16_c, 16, 8),
|
||||
HighbdIntraPredParam(&vpx_highbd_d45_predictor_32x32_neon,
|
||||
&vpx_highbd_d45_predictor_32x32_c, 32, 8),
|
||||
HighbdIntraPredParam(&vpx_highbd_d135_predictor_4x4_neon,
|
||||
&vpx_highbd_d135_predictor_4x4_c, 4, 8),
|
||||
HighbdIntraPredParam(&vpx_highbd_d135_predictor_8x8_neon,
|
||||
&vpx_highbd_d135_predictor_8x8_c, 8, 8),
|
||||
HighbdIntraPredParam(&vpx_highbd_d135_predictor_16x16_neon,
|
||||
&vpx_highbd_d135_predictor_16x16_c, 16, 8),
|
||||
HighbdIntraPredParam(&vpx_highbd_d135_predictor_32x32_neon,
|
||||
&vpx_highbd_d135_predictor_32x32_c, 32, 8),
|
||||
HighbdIntraPredParam(&vpx_highbd_dc_128_predictor_4x4_neon,
|
||||
&vpx_highbd_dc_128_predictor_4x4_c, 4, 8),
|
||||
HighbdIntraPredParam(&vpx_highbd_dc_128_predictor_8x8_neon,
|
||||
&vpx_highbd_dc_128_predictor_8x8_c, 8, 8),
|
||||
HighbdIntraPredParam(&vpx_highbd_dc_128_predictor_16x16_neon,
|
||||
&vpx_highbd_dc_128_predictor_16x16_c, 16, 8),
|
||||
HighbdIntraPredParam(&vpx_highbd_dc_128_predictor_32x32_neon,
|
||||
&vpx_highbd_dc_128_predictor_32x32_c, 32, 8),
|
||||
HighbdIntraPredParam(&vpx_highbd_dc_left_predictor_4x4_neon,
|
||||
&vpx_highbd_dc_left_predictor_4x4_c, 4, 8),
|
||||
HighbdIntraPredParam(&vpx_highbd_dc_left_predictor_8x8_neon,
|
||||
&vpx_highbd_dc_left_predictor_8x8_c, 8, 8),
|
||||
HighbdIntraPredParam(&vpx_highbd_dc_left_predictor_16x16_neon,
|
||||
&vpx_highbd_dc_left_predictor_16x16_c, 16, 8),
|
||||
HighbdIntraPredParam(&vpx_highbd_dc_left_predictor_32x32_neon,
|
||||
&vpx_highbd_dc_left_predictor_32x32_c, 32, 8),
|
||||
HighbdIntraPredParam(&vpx_highbd_dc_predictor_4x4_neon,
|
||||
&vpx_highbd_dc_predictor_4x4_c, 4, 8),
|
||||
HighbdIntraPredParam(&vpx_highbd_dc_predictor_8x8_neon,
|
||||
&vpx_highbd_dc_predictor_8x8_c, 8, 8),
|
||||
HighbdIntraPredParam(&vpx_highbd_dc_predictor_16x16_neon,
|
||||
&vpx_highbd_dc_predictor_16x16_c, 16, 8),
|
||||
HighbdIntraPredParam(&vpx_highbd_dc_predictor_32x32_neon,
|
||||
&vpx_highbd_dc_predictor_32x32_c, 32, 8),
|
||||
HighbdIntraPredParam(&vpx_highbd_dc_top_predictor_4x4_neon,
|
||||
&vpx_highbd_dc_top_predictor_4x4_c, 4, 8),
|
||||
HighbdIntraPredParam(&vpx_highbd_dc_top_predictor_8x8_neon,
|
||||
&vpx_highbd_dc_top_predictor_8x8_c, 8, 8),
|
||||
HighbdIntraPredParam(&vpx_highbd_dc_top_predictor_16x16_neon,
|
||||
&vpx_highbd_dc_top_predictor_16x16_c, 16, 8),
|
||||
HighbdIntraPredParam(&vpx_highbd_dc_top_predictor_32x32_neon,
|
||||
&vpx_highbd_dc_top_predictor_32x32_c, 32, 8),
|
||||
HighbdIntraPredParam(&vpx_highbd_h_predictor_4x4_neon,
|
||||
&vpx_highbd_h_predictor_4x4_c, 4, 8),
|
||||
HighbdIntraPredParam(&vpx_highbd_h_predictor_8x8_neon,
|
||||
&vpx_highbd_h_predictor_8x8_c, 8, 8),
|
||||
HighbdIntraPredParam(&vpx_highbd_h_predictor_16x16_neon,
|
||||
&vpx_highbd_h_predictor_16x16_c, 16, 8),
|
||||
HighbdIntraPredParam(&vpx_highbd_h_predictor_32x32_neon,
|
||||
&vpx_highbd_h_predictor_32x32_c, 32, 8),
|
||||
HighbdIntraPredParam(&vpx_highbd_tm_predictor_4x4_neon,
|
||||
&vpx_highbd_tm_predictor_4x4_c, 4, 8),
|
||||
HighbdIntraPredParam(&vpx_highbd_tm_predictor_8x8_neon,
|
||||
&vpx_highbd_tm_predictor_8x8_c, 8, 8),
|
||||
HighbdIntraPredParam(&vpx_highbd_tm_predictor_16x16_neon,
|
||||
&vpx_highbd_tm_predictor_16x16_c, 16, 8),
|
||||
HighbdIntraPredParam(&vpx_highbd_tm_predictor_32x32_neon,
|
||||
&vpx_highbd_tm_predictor_32x32_c, 32, 8),
|
||||
HighbdIntraPredParam(&vpx_highbd_v_predictor_4x4_neon,
|
||||
&vpx_highbd_v_predictor_4x4_c, 4, 8),
|
||||
HighbdIntraPredParam(&vpx_highbd_v_predictor_8x8_neon,
|
||||
&vpx_highbd_v_predictor_8x8_c, 8, 8),
|
||||
HighbdIntraPredParam(&vpx_highbd_v_predictor_16x16_neon,
|
||||
&vpx_highbd_v_predictor_16x16_c, 16, 8),
|
||||
HighbdIntraPredParam(&vpx_highbd_v_predictor_32x32_neon,
|
||||
&vpx_highbd_v_predictor_32x32_c, 32, 8)));
|
||||
|
||||
INSTANTIATE_TEST_CASE_P(
|
||||
NEON_TO_C_10, VP9HighbdIntraPredTest,
|
||||
::testing::Values(
|
||||
HighbdIntraPredParam(&vpx_highbd_d45_predictor_4x4_neon,
|
||||
&vpx_highbd_d45_predictor_4x4_c, 4, 10),
|
||||
HighbdIntraPredParam(&vpx_highbd_d45_predictor_8x8_neon,
|
||||
&vpx_highbd_d45_predictor_8x8_c, 8, 10),
|
||||
HighbdIntraPredParam(&vpx_highbd_d45_predictor_16x16_neon,
|
||||
&vpx_highbd_d45_predictor_16x16_c, 16, 10),
|
||||
HighbdIntraPredParam(&vpx_highbd_d45_predictor_32x32_neon,
|
||||
&vpx_highbd_d45_predictor_32x32_c, 32, 10),
|
||||
HighbdIntraPredParam(&vpx_highbd_d135_predictor_4x4_neon,
|
||||
&vpx_highbd_d135_predictor_4x4_c, 4, 10),
|
||||
HighbdIntraPredParam(&vpx_highbd_d135_predictor_8x8_neon,
|
||||
&vpx_highbd_d135_predictor_8x8_c, 8, 10),
|
||||
HighbdIntraPredParam(&vpx_highbd_d135_predictor_16x16_neon,
|
||||
&vpx_highbd_d135_predictor_16x16_c, 16, 10),
|
||||
HighbdIntraPredParam(&vpx_highbd_d135_predictor_32x32_neon,
|
||||
&vpx_highbd_d135_predictor_32x32_c, 32, 10),
|
||||
HighbdIntraPredParam(&vpx_highbd_dc_128_predictor_4x4_neon,
|
||||
&vpx_highbd_dc_128_predictor_4x4_c, 4, 10),
|
||||
HighbdIntraPredParam(&vpx_highbd_dc_128_predictor_8x8_neon,
|
||||
&vpx_highbd_dc_128_predictor_8x8_c, 8, 10),
|
||||
HighbdIntraPredParam(&vpx_highbd_dc_128_predictor_16x16_neon,
|
||||
&vpx_highbd_dc_128_predictor_16x16_c, 16, 10),
|
||||
HighbdIntraPredParam(&vpx_highbd_dc_128_predictor_32x32_neon,
|
||||
&vpx_highbd_dc_128_predictor_32x32_c, 32, 10),
|
||||
HighbdIntraPredParam(&vpx_highbd_dc_left_predictor_4x4_neon,
|
||||
&vpx_highbd_dc_left_predictor_4x4_c, 4, 10),
|
||||
HighbdIntraPredParam(&vpx_highbd_dc_left_predictor_8x8_neon,
|
||||
&vpx_highbd_dc_left_predictor_8x8_c, 8, 10),
|
||||
HighbdIntraPredParam(&vpx_highbd_dc_left_predictor_16x16_neon,
|
||||
&vpx_highbd_dc_left_predictor_16x16_c, 16, 10),
|
||||
HighbdIntraPredParam(&vpx_highbd_dc_left_predictor_32x32_neon,
|
||||
&vpx_highbd_dc_left_predictor_32x32_c, 32, 10),
|
||||
HighbdIntraPredParam(&vpx_highbd_dc_predictor_4x4_neon,
|
||||
&vpx_highbd_dc_predictor_4x4_c, 4, 10),
|
||||
HighbdIntraPredParam(&vpx_highbd_dc_predictor_8x8_neon,
|
||||
&vpx_highbd_dc_predictor_8x8_c, 8, 10),
|
||||
HighbdIntraPredParam(&vpx_highbd_dc_predictor_16x16_neon,
|
||||
&vpx_highbd_dc_predictor_16x16_c, 16, 10),
|
||||
HighbdIntraPredParam(&vpx_highbd_dc_predictor_32x32_neon,
|
||||
&vpx_highbd_dc_predictor_32x32_c, 32, 10),
|
||||
HighbdIntraPredParam(&vpx_highbd_dc_top_predictor_4x4_neon,
|
||||
&vpx_highbd_dc_top_predictor_4x4_c, 4, 10),
|
||||
HighbdIntraPredParam(&vpx_highbd_dc_top_predictor_8x8_neon,
|
||||
&vpx_highbd_dc_top_predictor_8x8_c, 8, 10),
|
||||
HighbdIntraPredParam(&vpx_highbd_dc_top_predictor_16x16_neon,
|
||||
&vpx_highbd_dc_top_predictor_16x16_c, 16, 10),
|
||||
HighbdIntraPredParam(&vpx_highbd_dc_top_predictor_32x32_neon,
|
||||
&vpx_highbd_dc_top_predictor_32x32_c, 32, 10),
|
||||
HighbdIntraPredParam(&vpx_highbd_h_predictor_4x4_neon,
|
||||
&vpx_highbd_h_predictor_4x4_c, 4, 10),
|
||||
HighbdIntraPredParam(&vpx_highbd_h_predictor_8x8_neon,
|
||||
&vpx_highbd_h_predictor_8x8_c, 8, 10),
|
||||
HighbdIntraPredParam(&vpx_highbd_h_predictor_16x16_neon,
|
||||
&vpx_highbd_h_predictor_16x16_c, 16, 10),
|
||||
HighbdIntraPredParam(&vpx_highbd_h_predictor_32x32_neon,
|
||||
&vpx_highbd_h_predictor_32x32_c, 32, 10),
|
||||
HighbdIntraPredParam(&vpx_highbd_tm_predictor_4x4_neon,
|
||||
&vpx_highbd_tm_predictor_4x4_c, 4, 10),
|
||||
HighbdIntraPredParam(&vpx_highbd_tm_predictor_8x8_neon,
|
||||
&vpx_highbd_tm_predictor_8x8_c, 8, 10),
|
||||
HighbdIntraPredParam(&vpx_highbd_tm_predictor_16x16_neon,
|
||||
&vpx_highbd_tm_predictor_16x16_c, 16, 10),
|
||||
HighbdIntraPredParam(&vpx_highbd_tm_predictor_32x32_neon,
|
||||
&vpx_highbd_tm_predictor_32x32_c, 32, 10),
|
||||
HighbdIntraPredParam(&vpx_highbd_v_predictor_4x4_neon,
|
||||
&vpx_highbd_v_predictor_4x4_c, 4, 10),
|
||||
HighbdIntraPredParam(&vpx_highbd_v_predictor_8x8_neon,
|
||||
&vpx_highbd_v_predictor_8x8_c, 8, 10),
|
||||
HighbdIntraPredParam(&vpx_highbd_v_predictor_16x16_neon,
|
||||
&vpx_highbd_v_predictor_16x16_c, 16, 10),
|
||||
HighbdIntraPredParam(&vpx_highbd_v_predictor_32x32_neon,
|
||||
&vpx_highbd_v_predictor_32x32_c, 32, 10)));
|
||||
|
||||
INSTANTIATE_TEST_CASE_P(
|
||||
NEON_TO_C_12, VP9HighbdIntraPredTest,
|
||||
::testing::Values(
|
||||
HighbdIntraPredParam(&vpx_highbd_d45_predictor_4x4_neon,
|
||||
&vpx_highbd_d45_predictor_4x4_c, 4, 12),
|
||||
HighbdIntraPredParam(&vpx_highbd_d45_predictor_8x8_neon,
|
||||
&vpx_highbd_d45_predictor_8x8_c, 8, 12),
|
||||
HighbdIntraPredParam(&vpx_highbd_d45_predictor_16x16_neon,
|
||||
&vpx_highbd_d45_predictor_16x16_c, 16, 12),
|
||||
HighbdIntraPredParam(&vpx_highbd_d45_predictor_32x32_neon,
|
||||
&vpx_highbd_d45_predictor_32x32_c, 32, 12),
|
||||
HighbdIntraPredParam(&vpx_highbd_d135_predictor_4x4_neon,
|
||||
&vpx_highbd_d135_predictor_4x4_c, 4, 12),
|
||||
HighbdIntraPredParam(&vpx_highbd_d135_predictor_8x8_neon,
|
||||
&vpx_highbd_d135_predictor_8x8_c, 8, 12),
|
||||
HighbdIntraPredParam(&vpx_highbd_d135_predictor_16x16_neon,
|
||||
&vpx_highbd_d135_predictor_16x16_c, 16, 12),
|
||||
HighbdIntraPredParam(&vpx_highbd_d135_predictor_32x32_neon,
|
||||
&vpx_highbd_d135_predictor_32x32_c, 32, 12),
|
||||
HighbdIntraPredParam(&vpx_highbd_dc_128_predictor_4x4_neon,
|
||||
&vpx_highbd_dc_128_predictor_4x4_c, 4, 12),
|
||||
HighbdIntraPredParam(&vpx_highbd_dc_128_predictor_8x8_neon,
|
||||
&vpx_highbd_dc_128_predictor_8x8_c, 8, 12),
|
||||
HighbdIntraPredParam(&vpx_highbd_dc_128_predictor_16x16_neon,
|
||||
&vpx_highbd_dc_128_predictor_16x16_c, 16, 12),
|
||||
HighbdIntraPredParam(&vpx_highbd_dc_128_predictor_32x32_neon,
|
||||
&vpx_highbd_dc_128_predictor_32x32_c, 32, 12),
|
||||
HighbdIntraPredParam(&vpx_highbd_dc_left_predictor_4x4_neon,
|
||||
&vpx_highbd_dc_left_predictor_4x4_c, 4, 12),
|
||||
HighbdIntraPredParam(&vpx_highbd_dc_left_predictor_8x8_neon,
|
||||
&vpx_highbd_dc_left_predictor_8x8_c, 8, 12),
|
||||
HighbdIntraPredParam(&vpx_highbd_dc_left_predictor_16x16_neon,
|
||||
&vpx_highbd_dc_left_predictor_16x16_c, 16, 12),
|
||||
HighbdIntraPredParam(&vpx_highbd_dc_left_predictor_32x32_neon,
|
||||
&vpx_highbd_dc_left_predictor_32x32_c, 32, 12),
|
||||
HighbdIntraPredParam(&vpx_highbd_dc_predictor_4x4_neon,
|
||||
&vpx_highbd_dc_predictor_4x4_c, 4, 12),
|
||||
HighbdIntraPredParam(&vpx_highbd_dc_predictor_8x8_neon,
|
||||
&vpx_highbd_dc_predictor_8x8_c, 8, 12),
|
||||
HighbdIntraPredParam(&vpx_highbd_dc_predictor_16x16_neon,
|
||||
&vpx_highbd_dc_predictor_16x16_c, 16, 12),
|
||||
HighbdIntraPredParam(&vpx_highbd_dc_predictor_32x32_neon,
|
||||
&vpx_highbd_dc_predictor_32x32_c, 32, 12),
|
||||
HighbdIntraPredParam(&vpx_highbd_dc_top_predictor_4x4_neon,
|
||||
&vpx_highbd_dc_top_predictor_4x4_c, 4, 12),
|
||||
HighbdIntraPredParam(&vpx_highbd_dc_top_predictor_8x8_neon,
|
||||
&vpx_highbd_dc_top_predictor_8x8_c, 8, 12),
|
||||
HighbdIntraPredParam(&vpx_highbd_dc_top_predictor_16x16_neon,
|
||||
&vpx_highbd_dc_top_predictor_16x16_c, 16, 12),
|
||||
HighbdIntraPredParam(&vpx_highbd_dc_top_predictor_32x32_neon,
|
||||
&vpx_highbd_dc_top_predictor_32x32_c, 32, 12),
|
||||
HighbdIntraPredParam(&vpx_highbd_h_predictor_4x4_neon,
|
||||
&vpx_highbd_h_predictor_4x4_c, 4, 12),
|
||||
HighbdIntraPredParam(&vpx_highbd_h_predictor_8x8_neon,
|
||||
&vpx_highbd_h_predictor_8x8_c, 8, 12),
|
||||
HighbdIntraPredParam(&vpx_highbd_h_predictor_16x16_neon,
|
||||
&vpx_highbd_h_predictor_16x16_c, 16, 12),
|
||||
HighbdIntraPredParam(&vpx_highbd_h_predictor_32x32_neon,
|
||||
&vpx_highbd_h_predictor_32x32_c, 32, 12),
|
||||
HighbdIntraPredParam(&vpx_highbd_tm_predictor_4x4_neon,
|
||||
&vpx_highbd_tm_predictor_4x4_c, 4, 12),
|
||||
HighbdIntraPredParam(&vpx_highbd_tm_predictor_8x8_neon,
|
||||
&vpx_highbd_tm_predictor_8x8_c, 8, 12),
|
||||
HighbdIntraPredParam(&vpx_highbd_tm_predictor_16x16_neon,
|
||||
&vpx_highbd_tm_predictor_16x16_c, 16, 12),
|
||||
HighbdIntraPredParam(&vpx_highbd_tm_predictor_32x32_neon,
|
||||
&vpx_highbd_tm_predictor_32x32_c, 32, 12),
|
||||
HighbdIntraPredParam(&vpx_highbd_v_predictor_4x4_neon,
|
||||
&vpx_highbd_v_predictor_4x4_c, 4, 12),
|
||||
HighbdIntraPredParam(&vpx_highbd_v_predictor_8x8_neon,
|
||||
&vpx_highbd_v_predictor_8x8_c, 8, 12),
|
||||
HighbdIntraPredParam(&vpx_highbd_v_predictor_16x16_neon,
|
||||
&vpx_highbd_v_predictor_16x16_c, 16, 12),
|
||||
HighbdIntraPredParam(&vpx_highbd_v_predictor_32x32_neon,
|
||||
&vpx_highbd_v_predictor_32x32_c, 32, 12)));
|
||||
#endif // HAVE_NEON
|
||||
|
||||
#endif // CONFIG_VP9_HIGHBITDEPTH
|
||||
} // namespace
|
||||
|
||||
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_
|
||||
@@ -40,7 +40,8 @@ vpx_tsvc_encoder() {
|
||||
local timebase_den="1000"
|
||||
local speed="6"
|
||||
local frame_drop_thresh="30"
|
||||
local threads="1"
|
||||
local max_threads="4"
|
||||
local error_resilient="1"
|
||||
|
||||
shift 2
|
||||
|
||||
@@ -49,11 +50,22 @@ vpx_tsvc_encoder() {
|
||||
return 1
|
||||
fi
|
||||
|
||||
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}
|
||||
# TODO(tomfinegan): Verify file output for all thread runs.
|
||||
for threads in $(seq $max_threads); do
|
||||
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
|
||||
}
|
||||
|
||||
# Confirms that all expected output files exist given the output file name
|
||||
@@ -73,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
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user