Compare commits
1157 Commits
m52-2743
...
longtailed
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
0c0a05046d | ||
|
|
cabc29ba24 | ||
|
|
8a7847c2c9 | ||
|
|
bf168b24f5 | ||
|
|
08d0a7fd0f | ||
|
|
ab20869221 | ||
|
|
7b18202e74 | ||
|
|
9af97fb630 | ||
|
|
ebe0b57c91 | ||
|
|
6377f9d966 | ||
|
|
50dd3eb62c | ||
|
|
c06991fce6 | ||
|
|
24d804f79c | ||
|
|
afd2d797eb | ||
|
|
c6ccd1e939 | ||
|
|
c7e2bd6298 | ||
|
|
4dca923454 | ||
|
|
f1909d26f8 | ||
|
|
316071d79c | ||
|
|
b632626ec0 | ||
|
|
b87ebd7af8 | ||
|
|
bf5cdbdf9d | ||
|
|
267e73446c | ||
|
|
337ad83e58 | ||
|
|
afc8c4836f | ||
|
|
2d12a52ff0 | ||
|
|
90f889a56d | ||
|
|
72746c079d | ||
|
|
1ca1515dd3 | ||
|
|
768b1f7281 | ||
|
|
63a8257fb7 | ||
|
|
99c573f018 | ||
|
|
b67e1f701f | ||
|
|
ecdb6a00c2 | ||
|
|
c96a8dcb5b | ||
|
|
e6b9609fc0 | ||
|
|
911bb980b1 | ||
|
|
9b187954df | ||
|
|
1d12559b09 | ||
|
|
7cf13826b7 | ||
|
|
3c47a0dc6f | ||
|
|
78a24171a6 | ||
|
|
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 | ||
|
|
5c64c01c7c | ||
|
|
271de2c9fb | ||
|
|
40bcb96abd | ||
|
|
d545c19afa | ||
|
|
a9874961f0 | ||
|
|
ac495218fb | ||
|
|
a139ecd0c9 | ||
|
|
5d0a271ded | ||
|
|
6e179dacd0 | ||
|
|
e851160642 | ||
|
|
9ad3e14015 | ||
|
|
eefc7d1412 | ||
|
|
e10c95dc83 | ||
|
|
04c3bf3c85 | ||
|
|
32326c2f13 | ||
|
|
900ec31bea | ||
|
|
b68d8107cb | ||
|
|
cf35ffc025 | ||
|
|
232221b83a | ||
|
|
34c35b6fb6 | ||
|
|
c559cc6191 | ||
|
|
90a135854c | ||
|
|
cca774c7df | ||
|
|
86b0042f44 | ||
|
|
da9f762e24 | ||
|
|
f93305aa07 | ||
|
|
cb5a2ac920 | ||
|
|
3e961c09be | ||
|
|
1338c71dfb | ||
|
|
1868582e7d | ||
|
|
5ac7a59a05 | ||
|
|
295cd3b493 | ||
|
|
de76d2e315 | ||
|
|
1961a92a94 | ||
|
|
3b74066b10 | ||
|
|
bf8ab194ee | ||
|
|
1b275ab898 | ||
|
|
9de91855ef | ||
|
|
05ee241493 | ||
|
|
0c88014592 | ||
|
|
cc5f49767a | ||
|
|
84dcfced5b | ||
|
|
7625c803b3 | ||
|
|
2e076ffe50 | ||
|
|
ae32318170 | ||
|
|
1ddb4c0362 | ||
|
|
7cf0c000cf | ||
|
|
41ad80f69d | ||
|
|
410d947c5f | ||
|
|
11b099ea46 | ||
|
|
cde5d5db13 | ||
|
|
39bcb49909 | ||
|
|
702b3e1ee5 | ||
|
|
3ae25974fd | ||
|
|
a347118f3c | ||
|
|
e1cdb50298 | ||
|
|
fb9fef83c7 | ||
|
|
30f3017697 | ||
|
|
086aab7e13 | ||
|
|
ae206924a6 | ||
|
|
5724e8c4c7 | ||
|
|
fd4efde489 | ||
|
|
7042137e60 | ||
|
|
a8fdb3926e | ||
|
|
9205f54744 | ||
|
|
7c75cae74a | ||
|
|
4d305dab34 | ||
|
|
715c65914b | ||
|
|
4f7a59c802 | ||
|
|
4ae9f5c092 | ||
|
|
1cd987d922 | ||
|
|
54e03017b6 | ||
|
|
4555c50ecd | ||
|
|
aadfde4687 | ||
|
|
02deeea447 | ||
|
|
7994dba6c0 | ||
|
|
ed2c240538 | ||
|
|
08e0da30ca | ||
|
|
de859676dd | ||
|
|
ccd6a8e2fa | ||
|
|
9c0680bd43 | ||
|
|
9720b58aac | ||
|
|
98ffc49204 | ||
|
|
4b8b1bae52 | ||
|
|
c327b3f0b0 | ||
|
|
f53d3363ac | ||
|
|
c192def8f3 | ||
|
|
ce88b8f5c5 | ||
|
|
d1c74c149b | ||
|
|
7ef094c02f | ||
|
|
2e6a1976a0 | ||
|
|
5d91752a98 | ||
|
|
9a032fa262 | ||
|
|
5deffa1175 | ||
|
|
ee1b3f34c0 | ||
|
|
9dbb3ad396 | ||
|
|
a7d116aa67 | ||
|
|
32e63efcfb | ||
|
|
83ca63582a | ||
|
|
9fdae93858 | ||
|
|
995a967f19 | ||
|
|
9624964832 | ||
|
|
ff38b8dfae | ||
|
|
7f31bfeddb | ||
|
|
68833c7f85 | ||
|
|
a60dd5c83a | ||
|
|
53d8ff6f14 | ||
|
|
8ff5af773a | ||
|
|
171e2ccf99 | ||
|
|
b7310e2aff | ||
|
|
e084e05484 | ||
|
|
68cd3052ca | ||
|
|
f6980ca68e | ||
|
|
b0cc8d5cc6 | ||
|
|
9c8981c666 | ||
|
|
55a2b67368 | ||
|
|
808a560be6 | ||
|
|
9e8efa5b18 | ||
|
|
4c3d539baa | ||
|
|
acd21e053a | ||
|
|
6c309c1f59 | ||
|
|
e49a02b113 | ||
|
|
3e21d703ce | ||
|
|
f910d14a1a | ||
|
|
f5b8b473db | ||
|
|
1909270f65 | ||
|
|
3e3475321c | ||
|
|
769292017b | ||
|
|
9e75c01353 | ||
|
|
99adf8b22e | ||
|
|
fd270437f0 | ||
|
|
04a6010742 | ||
|
|
d03d1c8cd3 | ||
|
|
b894d95b32 | ||
|
|
f664d3f6d5 | ||
|
|
3b06acd4e2 | ||
|
|
01454ec485 | ||
|
|
27479775c4 | ||
|
|
251cbfbec8 | ||
|
|
56b1be1889 | ||
|
|
356f95b423 | ||
|
|
96c7206ede | ||
|
|
065ba0c486 | ||
|
|
57c6bf291e | ||
|
|
cdbd89197e | ||
|
|
294a734a5f | ||
|
|
57e4cbc632 | ||
|
|
19046d9963 | ||
|
|
3da752fe00 | ||
|
|
d05104b488 | ||
|
|
8b5eddf709 | ||
|
|
3c2f7eb339 | ||
|
|
df66f8e830 | ||
|
|
e83e828998 | ||
|
|
ed50e7710c | ||
|
|
06a6b28d75 | ||
|
|
5e4d2548cf | ||
|
|
49aa9b1f12 | ||
|
|
7aa27bd62f | ||
|
|
ac00db7948 | ||
|
|
c7072ae2f4 | ||
|
|
fd918cf9a3 | ||
|
|
f875267ad0 | ||
|
|
1e1caad165 | ||
|
|
a6be7ba1aa | ||
|
|
efb56ec3ff | ||
|
|
3063c37600 | ||
|
|
a7456144ce | ||
|
|
68f6f6c4cc | ||
|
|
891a87dccd | ||
|
|
955b3b66bd | ||
|
|
8978704970 | ||
|
|
d556d435f3 | ||
|
|
3db06394e7 | ||
|
|
24c0146403 | ||
|
|
5d635365bb | ||
|
|
0a92dd7319 | ||
|
|
5b073c695b | ||
|
|
577221bc87 | ||
|
|
fb020805f9 | ||
|
|
c6bc7499d9 | ||
|
|
6922fc8230 | ||
|
|
7eff8f3b1d | ||
|
|
50b9c467da | ||
|
|
0dc12b4a1c | ||
|
|
fca2196a2e | ||
|
|
c449983c56 | ||
|
|
9255328f27 | ||
|
|
3c00132181 | ||
|
|
da14d23e44 | ||
|
|
edbca72a53 | ||
|
|
0a9f56f146 | ||
|
|
5e908aff34 | ||
|
|
db80c23fd4 | ||
|
|
b6277a47c7 | ||
|
|
1396d12103 | ||
|
|
b51c4df93a | ||
|
|
ca2fe7a8c7 | ||
|
|
4779f5308d | ||
|
|
8c744fd978 | ||
|
|
c435b7fbdd | ||
|
|
bde905cba1 | ||
|
|
ed62d27c71 | ||
|
|
f38616e1a2 | ||
|
|
39ff0de810 | ||
|
|
cb4aa6d589 | ||
|
|
9afe2cf599 | ||
|
|
7f1f35183a | ||
|
|
85a9e48d25 | ||
|
|
2745f94deb | ||
|
|
ad55b1d270 | ||
|
|
7b9c86167e | ||
|
|
721354fe7f | ||
|
|
2663b092ae | ||
|
|
1364cb58b4 | ||
|
|
e765435293 | ||
|
|
d017548be6 | ||
|
|
b3cb065ee4 | ||
|
|
691ef20272 | ||
|
|
7b5a348088 | ||
|
|
c7f9d0719d | ||
|
|
450d89034b | ||
|
|
93c823e24b | ||
|
|
e094e151de | ||
|
|
bb27be0dfe | ||
|
|
63f7e131fe | ||
|
|
7481edb33f | ||
|
|
32c375447c | ||
|
|
240726ac85 | ||
|
|
74f038e6f8 | ||
|
|
06abc1ecd9 | ||
|
|
3a57ce4478 | ||
|
|
e4ddf9db6a | ||
|
|
e61d82bd4f | ||
|
|
348cff040a | ||
|
|
81ff7a065f | ||
|
|
c3a135b5b8 | ||
|
|
02fa245d15 | ||
|
|
097b31c7f0 | ||
|
|
0aa3e2564f | ||
|
|
b3ebea5e8a | ||
|
|
8db503063f | ||
|
|
70240a77b8 | ||
|
|
b165451ad5 | ||
|
|
37798711aa | ||
|
|
d9fc28c0a1 | ||
|
|
b46243d7ff | ||
|
|
0421d8e318 | ||
|
|
60624aa53a | ||
|
|
f8c056a895 | ||
|
|
ab0e7a237a | ||
|
|
1d14e42df7 | ||
|
|
87b689f97a | ||
|
|
ada850786c | ||
|
|
deadda3dea | ||
|
|
a914ffad97 | ||
|
|
7a34f85955 | ||
|
|
fdd1186f97 | ||
|
|
99ef84c65a | ||
|
|
e372bfd5ac | ||
|
|
fcf281b6a1 | ||
|
|
80338b91d3 | ||
|
|
2bed8b6acd | ||
|
|
35ebc1cddf | ||
|
|
3f72509587 | ||
|
|
cec6433e41 | ||
|
|
b6e686b1ea | ||
|
|
c31d02615d | ||
|
|
2351a73531 | ||
|
|
feb4313c5f | ||
|
|
8478f97105 | ||
|
|
18fd69ee91 | ||
|
|
0d2687ef87 | ||
|
|
5841929fde | ||
|
|
08b8b6bb8f | ||
|
|
8281da74b9 | ||
|
|
0ce98b423b | ||
|
|
761e5ec2f6 | ||
|
|
6acd061aad | ||
|
|
0695843a21 | ||
|
|
fad70a358b | ||
|
|
de7f5ce9e5 | ||
|
|
01e2902521 | ||
|
|
aa0eb67bf7 | ||
|
|
5d73639d8f | ||
|
|
112eb54c1b | ||
|
|
8107368000 | ||
|
|
33aef48f29 | ||
|
|
7a9e476072 | ||
|
|
e813c2b416 | ||
|
|
caf9a7841e | ||
|
|
6ae58fd55e | ||
|
|
7795e99296 | ||
|
|
fdbe249991 | ||
|
|
102eae06e9 | ||
|
|
43743b1d3e | ||
|
|
7bc0733c27 | ||
|
|
d5054504a7 | ||
|
|
1d2aaf58dd | ||
|
|
f2be831885 | ||
|
|
c53aacf408 | ||
|
|
4c1a9fb8db | ||
|
|
5f6d143b41 | ||
|
|
30b1abd6e6 | ||
|
|
d9dce2f48e | ||
|
|
284cb5314e | ||
|
|
ee01b78ddd | ||
|
|
a3400f4376 | ||
|
|
4282d29355 | ||
|
|
4c6819d0fc | ||
|
|
75fe2d4409 | ||
|
|
db32581650 | ||
|
|
bce23ab36b | ||
|
|
6eca31be5f | ||
|
|
a22a455899 | ||
|
|
421f376568 | ||
|
|
66241b9579 | ||
|
|
948a1f51d0 | ||
|
|
4b0e78bfda | ||
|
|
bcbc4761fa | ||
|
|
309125b1e7 | ||
|
|
c892521b1d | ||
|
|
4a25b59bbd | ||
|
|
e6f0c26268 | ||
|
|
3d253b0c71 | ||
|
|
d6d3d4ba31 | ||
|
|
4d1540f8ce | ||
|
|
594e53514b | ||
|
|
454139ae13 | ||
|
|
a6bc3dfb0f | ||
|
|
009116cb6f | ||
|
|
3e9e77008c | ||
|
|
4d1c117f5b | ||
|
|
1139f0dbc2 | ||
|
|
18b6691105 | ||
|
|
24f534ac90 | ||
|
|
7b3c2e3269 | ||
|
|
42ccd79b27 | ||
|
|
113f9721d1 | ||
|
|
5399613889 | ||
|
|
bee7d837ab | ||
|
|
e6446b4b60 | ||
|
|
3dfba04dec | ||
|
|
6fc07a217d | ||
|
|
66b2266a22 | ||
|
|
f7cbfed682 | ||
|
|
129814fcb4 | ||
|
|
3a3169be59 | ||
|
|
e66cd132f0 | ||
|
|
4916515511 | ||
|
|
3a98508775 | ||
|
|
19d881290d | ||
|
|
2917737879 | ||
|
|
507d272265 | ||
|
|
a19b9b6185 | ||
|
|
ed11abbc36 | ||
|
|
a70861c435 | ||
|
|
58a497dc29 | ||
|
|
fcc4f3fa21 | ||
|
|
dd2a475e43 | ||
|
|
badd32d914 | ||
|
|
84fccfe475 | ||
|
|
dc42f343ae | ||
|
|
a91fe33c6d | ||
|
|
37e83789f1 | ||
|
|
b6a5f6f740 | ||
|
|
292d221fed | ||
|
|
c018032579 | ||
|
|
635ae8bdc1 | ||
|
|
6d7a9f3e9c | ||
|
|
3ddff4503a | ||
|
|
ce634bbf4d | ||
|
|
4699aca87f | ||
|
|
963291217f | ||
|
|
28c6207bcd | ||
|
|
69c5ba1910 | ||
|
|
dde8004716 | ||
|
|
d7c20079a6 | ||
|
|
5260a6675e | ||
|
|
a6efe6d437 | ||
|
|
13338a481f | ||
|
|
d393885af1 | ||
|
|
0f42d1fa85 | ||
|
|
c325fb748a | ||
|
|
8d4c0ec1f1 | ||
|
|
f6c5410cd4 | ||
|
|
ef98f49cb0 | ||
|
|
bf7a02a4cf | ||
|
|
f5bd76f5c1 | ||
|
|
de075a95e0 | ||
|
|
37169c0bd4 | ||
|
|
fe488cceff | ||
|
|
149d082377 | ||
|
|
8b4c31584e | ||
|
|
52db2b1690 | ||
|
|
33dedd0628 | ||
|
|
8be7e572a7 | ||
|
|
1c07abca18 | ||
|
|
37a39ac138 | ||
|
|
7eb7d6b227 | ||
|
|
1b982cc64f | ||
|
|
af3b0de732 | ||
|
|
ab7cd6d068 | ||
|
|
c2fe9acced | ||
|
|
f9efbad392 | ||
|
|
5d881770e5 | ||
|
|
de3b769524 | ||
|
|
fe4dd4f43f | ||
|
|
fafec95702 | ||
|
|
dfcefe06fa | ||
|
|
bd7cfb46fb | ||
|
|
f09b5a3328 | ||
|
|
a413dbe594 | ||
|
|
f1e12c1bf3 | ||
|
|
656f4a88cf | ||
|
|
343b6b09a1 | ||
|
|
4916a87bfc | ||
|
|
941fe20336 | ||
|
|
475e9d26e0 | ||
|
|
c37d012ada | ||
|
|
9e9722bc79 | ||
|
|
7a730d5901 | ||
|
|
cfd92dab18 | ||
|
|
6554333b59 | ||
|
|
6a8d4631a8 | ||
|
|
2c17d54681 | ||
|
|
9c9d92ae3a | ||
|
|
2d1e63d0c5 | ||
|
|
c12f2f3187 | ||
|
|
19d2e73dea | ||
|
|
ba42ce64b7 | ||
|
|
2fb826c4d5 | ||
|
|
7104833085 | ||
|
|
d772d55704 | ||
|
|
c79665d0ad | ||
|
|
1b1e40c0b2 | ||
|
|
958ae5af9c | ||
|
|
57f49db81f | ||
|
|
17720b60bb | ||
|
|
7f7c888c14 | ||
|
|
0325b95938 | ||
|
|
f4e4ce7549 | ||
|
|
7103b5307d | ||
|
|
8619203ddc | ||
|
|
b757d89ff9 | ||
|
|
4db9bd324d | ||
|
|
70a7885a65 | ||
|
|
caac87b05b | ||
|
|
d55724fae9 | ||
|
|
476e8fc855 | ||
|
|
36608af524 | ||
|
|
377cfa31f0 | ||
|
|
374f0ff4a0 | ||
|
|
3a4002b94d | ||
|
|
df69c751a7 | ||
|
|
bbf4c91f79 | ||
|
|
9fdeeaf411 | ||
|
|
7a79fa1362 | ||
|
|
b51d127c82 | ||
|
|
15f29ef092 | ||
|
|
77f5c3d2e8 | ||
|
|
5ea8712b82 | ||
|
|
068281751c | ||
|
|
a412c004e4 | ||
|
|
a7a8e07a44 | ||
|
|
ff0a87ce38 | ||
|
|
08131055e4 | ||
|
|
85e111b3ba | ||
|
|
8ff40f8bec | ||
|
|
e0cc52db3f | ||
|
|
f7032713af | ||
|
|
d089ac4dda | ||
|
|
3a04c9c9c4 | ||
|
|
039f9e08f0 | ||
|
|
dc5618f3bb | ||
|
|
004eebed31 | ||
|
|
2c3807b89f | ||
|
|
e446ffda45 | ||
|
|
d4ab234869 | ||
|
|
407c2e2974 | ||
|
|
6fbb4c3061 | ||
|
|
462a7c9f0a | ||
|
|
c0241664aa | ||
|
|
4508eb3123 | ||
|
|
956af1d478 | ||
|
|
6b374abc86 | ||
|
|
335cf67d8b | ||
|
|
341919d038 | ||
|
|
33e40cb5db | ||
|
|
47cc64cdf8 | ||
|
|
e4290800b2 | ||
|
|
f4be884466 | ||
|
|
fbf256da41 | ||
|
|
34201e50c1 | ||
|
|
1a3c4f91f6 | ||
|
|
9f9a8d2aaa | ||
|
|
1c85230344 | ||
|
|
7987686397 | ||
|
|
6565c17f24 | ||
|
|
f8c27d164c | ||
|
|
8ce67d714a | ||
|
|
d6c5ef4557 | ||
|
|
580f14b68b | ||
|
|
d7a3b781d3 | ||
|
|
099bd7f07e | ||
|
|
82070ae939 | ||
|
|
5c0f5cdda8 | ||
|
|
91369fd9b7 | ||
|
|
889ed5b158 | ||
|
|
7aa0c748b3 | ||
|
|
511bf49b7e | ||
|
|
ad5fea03e6 | ||
|
|
54b2071bf4 | ||
|
|
f368f86df6 | ||
|
|
c42d54c3a3 | ||
|
|
18e53642b7 | ||
|
|
5cf8eda308 | ||
|
|
256a4af4d1 | ||
|
|
7381e3330f | ||
|
|
0fff2fb34c | ||
|
|
b2542417cd | ||
|
|
3d3f51262c | ||
|
|
5e2791b54d | ||
|
|
9a62ecbd35 | ||
|
|
53db633349 | ||
|
|
325bdddc38 | ||
|
|
c06a4b9df2 | ||
|
|
830fa866a5 | ||
|
|
063e4a2914 | ||
|
|
e3e9fee419 | ||
|
|
4b073bc39a | ||
|
|
930773a1ed | ||
|
|
87c6c5224d | ||
|
|
c969b2b02b | ||
|
|
18c7f46c12 | ||
|
|
92e91bd3a1 | ||
|
|
16e069b8bb | ||
|
|
a6cc74b987 | ||
|
|
042572177b | ||
|
|
71f9cbcfc8 | ||
|
|
297b2a12d6 | ||
|
|
b19f8b1607 | ||
|
|
77a31eb3c5 | ||
|
|
7bb35db872 | ||
|
|
690fcd793b | ||
|
|
fd85664ae6 | ||
|
|
1b048e966a | ||
|
|
b5164f55a0 | ||
|
|
96797e43b4 | ||
|
|
033dab9ca0 | ||
|
|
6e336f6e5f | ||
|
|
7f3e07f1c8 | ||
|
|
5b55bcc564 | ||
|
|
e3f7991f99 | ||
|
|
e4ac882007 | ||
|
|
e90d4f0a03 | ||
|
|
451211cb01 | ||
|
|
ea3d324f13 | ||
|
|
7e4740156f | ||
|
|
ef45540927 | ||
|
|
c69cc4ce1f | ||
|
|
25085a6ac2 | ||
|
|
23d0f73838 | ||
|
|
7d72ebaa5c | ||
|
|
05fe0f20a6 | ||
|
|
1afbd88e81 | ||
|
|
bdfdd7d993 | ||
|
|
3e04114f3d | ||
|
|
106a8a1536 | ||
|
|
3d791194f8 | ||
|
|
090aa88b5a | ||
|
|
f44db1487d | ||
|
|
8d681b36c7 | ||
|
|
5319e83843 | ||
|
|
22c36dd464 | ||
|
|
037a50ed36 | ||
|
|
3fc29ae3ee | ||
|
|
81a6739533 | ||
|
|
65daa41378 | ||
|
|
ce6678fdc9 | ||
|
|
cb957c302a | ||
|
|
0dfede2e79 | ||
|
|
da1bda0fb2 | ||
|
|
302e425453 | ||
|
|
0dc69c70f7 | ||
|
|
60ada7edb4 | ||
|
|
f993ed5c86 | ||
|
|
6d2b79e3a2 | ||
|
|
a07bb84215 | ||
|
|
3386ca7496 | ||
|
|
7eec1f31b5 | ||
|
|
8dd3bef7ef | ||
|
|
8c7751e1c2 | ||
|
|
d6197b621d | ||
|
|
e736691a6d | ||
|
|
ce050afaf3 | ||
|
|
248f6ad771 | ||
|
|
fed14a3e94 | ||
|
|
e93f2fdb83 | ||
|
|
2ca24b0075 | ||
|
|
b24373fec2 | ||
|
|
6f424a768e | ||
|
|
6a3ff0b617 | ||
|
|
98431cde07 | ||
|
|
19c157afe2 | ||
|
|
110a2ddc9b | ||
|
|
efccbc9fb5 | ||
|
|
88e6951465 | ||
|
|
45ed7effed | ||
|
|
2e93fcf893 | ||
|
|
3a986eac57 | ||
|
|
ed7786869a | ||
|
|
5adb43b8be | ||
|
|
20946cdd3b | ||
|
|
dc008cc17d | ||
|
|
cc431ad50a | ||
|
|
a75965fa94 | ||
|
|
2f28f9072e | ||
|
|
44354ee7bf | ||
|
|
62aa642d71 | ||
|
|
541eb78994 | ||
|
|
7c1fdf02cd | ||
|
|
f451b404ea | ||
|
|
9976ff8c79 | ||
|
|
9ef37860cd | ||
|
|
2580e7d63e | ||
|
|
f037cf80c9 | ||
|
|
e357b9efe0 | ||
|
|
884c2ddc48 | ||
|
|
adbad6092f | ||
|
|
aa6108382e | ||
|
|
4b6e4e1813 | ||
|
|
a921444fdb | ||
|
|
2678aefc48 | ||
|
|
ff19cdafdb | ||
|
|
fba5c354ad | ||
|
|
51aad61c8c | ||
|
|
825bb86044 | ||
|
|
14011f037d | ||
|
|
5afa3b9150 | ||
|
|
3197172405 | ||
|
|
3007081a87 | ||
|
|
7954e67bb8 | ||
|
|
a48d42a804 | ||
|
|
8cc525e82b | ||
|
|
d4d6c58e37 | ||
|
|
d2b40894be | ||
|
|
0a075cb39c | ||
|
|
3ef9c0ba03 | ||
|
|
f5a15f270a | ||
|
|
c5372cf077 | ||
|
|
e616012d69 | ||
|
|
fbbd3f0d8d | ||
|
|
ee78c541a4 | ||
|
|
892ebd9760 | ||
|
|
571f00cb95 | ||
|
|
0266e70c52 | ||
|
|
3c41d7358c | ||
|
|
89771f2c2c | ||
|
|
1d3f1983b2 | ||
|
|
f7c2d2a3de | ||
|
|
aa81375d73 | ||
|
|
e25d6252a4 | ||
|
|
f9a3d08f1b | ||
|
|
e85607410e | ||
|
|
f5a6079141 | ||
|
|
1b833d63d9 | ||
|
|
fe96dbda15 | ||
|
|
d11c97e8e2 | ||
|
|
0462263765 | ||
|
|
5fc2d6cb9f | ||
|
|
c8f6ed77b9 | ||
|
|
291033032e | ||
|
|
3a6a81fc9a | ||
|
|
b458f42966 | ||
|
|
0a64929f19 | ||
|
|
c02a4beed8 | ||
|
|
6b350766bd | ||
|
|
63a37d16f3 | ||
|
|
f14c323b4c | ||
|
|
b8f83282f8 | ||
|
|
be013eb396 | ||
|
|
74bb78df82 | ||
|
|
c125f4a594 | ||
|
|
078dff72ca | ||
|
|
6b4463dc1f | ||
|
|
feb7e9a372 | ||
|
|
d004c64013 | ||
|
|
4736e5f9d1 | ||
|
|
43ae6c1e22 | ||
|
|
0afe5e405d | ||
|
|
91038e0eb6 | ||
|
|
b2d690187e | ||
|
|
d34b49d7b9 | ||
|
|
10b4753179 | ||
|
|
f51f67602e | ||
|
|
32ac7cabdf | ||
|
|
7f2628152a | ||
|
|
8cbd4f8701 | ||
|
|
71aacf39c7 | ||
|
|
7676defca9 | ||
|
|
b2fb48cfcf | ||
|
|
7c184c6e1f | ||
|
|
b9ec759bc2 | ||
|
|
913081ab02 | ||
|
|
ca88d22f39 | ||
|
|
1c0a9f36f1 | ||
|
|
cfd5e0221c | ||
|
|
168eea5d60 | ||
|
|
922751e059 | ||
|
|
723e357ead | ||
|
|
0c6caf187c | ||
|
|
b34705f64f | ||
|
|
efad6feb9a | ||
|
|
9e5f355daf | ||
|
|
003a9d20ad | ||
|
|
dd07443f72 | ||
|
|
7991241a50 | ||
|
|
b582cf0ea9 | ||
|
|
67611119b5 | ||
|
|
3b2e2f2f77 | ||
|
|
79436fadfb | ||
|
|
7ed1d54ab4 | ||
|
|
26daa30da4 | ||
|
|
7738bcb350 | ||
|
|
73b11ec876 | ||
|
|
d4596485be | ||
|
|
57adf3d573 | ||
|
|
74a61b5ab9 | ||
|
|
692fe74deb | ||
|
|
bdeb5febe4 | ||
|
|
9eeb1f2fc3 | ||
|
|
424982bc41 | ||
|
|
5e9c5dfdf0 | ||
|
|
aa1c813c43 | ||
|
|
6e4b73125b | ||
|
|
310073868e | ||
|
|
cc1524aa90 | ||
|
|
6c6eb16bb9 | ||
|
|
3b2c3cb366 | ||
|
|
55f3740d76 | ||
|
|
83db21b2fd | ||
|
|
d9c417cb49 | ||
|
|
b2597527a5 | ||
|
|
8496390e73 | ||
|
|
ac27b062b0 | ||
|
|
527a9fea76 | ||
|
|
1517fb74fd | ||
|
|
243029faff | ||
|
|
8c29d332c9 | ||
|
|
5c29ee726e | ||
|
|
ef665996ae | ||
|
|
b3933e2d3c | ||
|
|
87bf1a149c | ||
|
|
b8ec5dcdf8 | ||
|
|
cb1d152719 | ||
|
|
a5af392aae | ||
|
|
b4aa5c9408 | ||
|
|
50d3629c61 | ||
|
|
aee577b691 | ||
|
|
543ea3eb3e | ||
|
|
6929ab0ba6 | ||
|
|
85786a8ddb | ||
|
|
188420f4fd | ||
|
|
7a3d48e56f | ||
|
|
4d9e876b44 | ||
|
|
67edc5e83b | ||
|
|
9e185ed177 | ||
|
|
dba1d1a63d | ||
|
|
40477f1f70 | ||
|
|
1417ed28f3 | ||
|
|
f99f78c7af | ||
|
|
4f367f5cd9 | ||
|
|
1de5ba75be | ||
|
|
9d7a12a0e7 | ||
|
|
7055ca556c | ||
|
|
0146fa95ef | ||
|
|
bfc75f7382 | ||
|
|
c5fae00227 | ||
|
|
cdd83a0bb2 | ||
|
|
5a9f21db54 | ||
|
|
754eb95105 | ||
|
|
a724477d69 | ||
|
|
e9b6172476 | ||
|
|
cf2bfcd9d8 | ||
|
|
b29ebfe91c | ||
|
|
ee30cf1408 | ||
|
|
f5713fefa6 | ||
|
|
6f9982e3c2 | ||
|
|
f4b5330c50 | ||
|
|
bd0c981744 | ||
|
|
73ae3cdeef | ||
|
|
de3a8f23c8 | ||
|
|
e5e998a6eb | ||
|
|
0c1da40ea8 | ||
|
|
3108fbd229 | ||
|
|
db81c34336 | ||
|
|
799ab7c064 | ||
|
|
0cb7f545ad | ||
|
|
c12e61d5a3 | ||
|
|
f180945c18 | ||
|
|
77318b0aec | ||
|
|
8870756ac6 | ||
|
|
159dd0cc39 | ||
|
|
354e70dc78 | ||
|
|
1387f5550f | ||
|
|
25110f2837 | ||
|
|
ff8edd3509 | ||
|
|
bbe5ddfdfb | ||
|
|
7751651ea1 | ||
|
|
8e070558b0 | ||
|
|
55d0ffeb54 | ||
|
|
7abc05c9af | ||
|
|
72d4890caf | ||
|
|
8767999493 | ||
|
|
ace4073090 | ||
|
|
9c90830165 | ||
|
|
7901a051c9 | ||
|
|
221fcdac85 | ||
|
|
17962ab2c0 | ||
|
|
a9936de384 | ||
|
|
c93d30a47f | ||
|
|
95d29675b2 | ||
|
|
4b8b31838b | ||
|
|
c516dd67bc | ||
|
|
63eb2ee056 | ||
|
|
d5be4a17ef | ||
|
|
19a4ce904d | ||
|
|
32ff4906da | ||
|
|
f9c0587200 | ||
|
|
580317160c | ||
|
|
181988d372 | ||
|
|
c1bfa6a846 | ||
|
|
40e3bf8630 | ||
|
|
9b61c709c4 | ||
|
|
2a0e1bcc83 | ||
|
|
e34944ad26 | ||
|
|
697bcef677 | ||
|
|
fba94b8cfd | ||
|
|
5b7960fa82 | ||
|
|
5aeadbb4f6 | ||
|
|
95d2dc8981 | ||
|
|
06c6e4cbf6 | ||
|
|
3fc01f95da | ||
|
|
77ffea92c5 | ||
|
|
d00aaa9c12 | ||
|
|
97b4f8fe92 | ||
|
|
28a93d6588 | ||
|
|
eb09bbe88b | ||
|
|
a554bd8dac | ||
|
|
dd217d3df1 | ||
|
|
01882a9ee8 | ||
|
|
ef1fb6deb4 | ||
|
|
f0b08aa4fa | ||
|
|
3de42ac27b | ||
|
|
c2ebd0e6da | ||
|
|
7982914c37 | ||
|
|
e34e684059 | ||
|
|
4539267916 | ||
|
|
aa90983696 | ||
|
|
03a401c4d9 | ||
|
|
fd38ef4b99 | ||
|
|
a160533e41 | ||
|
|
bfff16af67 | ||
|
|
5ef54c1536 | ||
|
|
7a586cad07 | ||
|
|
304d310975 | ||
|
|
b90166665f | ||
|
|
a8c8bf1c99 | ||
|
|
45a26dd9c8 | ||
|
|
552fd02cf0 | ||
|
|
f9865d1701 | ||
|
|
c7ac2f3864 | ||
|
|
cd700e1ab9 | ||
|
|
4328b08521 | ||
|
|
462e0ff88b | ||
|
|
eea8ea88ab | ||
|
|
7aef9790cf | ||
|
|
891dbe1e52 | ||
|
|
ad0646cb84 | ||
|
|
a32f341539 | ||
|
|
10969dfc6e | ||
|
|
100dfc9eab | ||
|
|
fd500f955f | ||
|
|
bacc67f4a8 | ||
|
|
b26232eb1b | ||
|
|
204809bfb3 | ||
|
|
6382727dc5 | ||
|
|
787b38ebb9 | ||
|
|
e5e2932cb3 | ||
|
|
46ff1072b3 | ||
|
|
bedf1c3af6 | ||
|
|
f80d8011a0 | ||
|
|
f6ac6cf5bd | ||
|
|
2ab7b9a6c9 | ||
|
|
13d48c4267 | ||
|
|
af7fb17c09 | ||
|
|
f1de622617 | ||
|
|
0ba9b299e9 | ||
|
|
4b5e462d08 | ||
|
|
ff6accf936 | ||
|
|
301e345273 | ||
|
|
9d24fe60f1 | ||
|
|
75d551783d | ||
|
|
19e0b406c9 | ||
|
|
e5b7f14ea7 | ||
|
|
ba8651d474 | ||
|
|
75b6cfe1c5 | ||
|
|
7acd0a59ca | ||
|
|
35d7e17b03 | ||
|
|
be12fefa4b | ||
|
|
a4f3751be5 | ||
|
|
72e332f767 | ||
|
|
14e8adea3c | ||
|
|
6f397b8a5b | ||
|
|
4f774ac50e | ||
|
|
e4bdbd3c0b | ||
|
|
3fb55d24e8 | ||
|
|
84e3639454 | ||
|
|
971c5a16a9 | ||
|
|
fa5d54f937 | ||
|
|
af0a9fcf70 | ||
|
|
04fdbdc5ca | ||
|
|
d1f0f4cc63 | ||
|
|
489f8b2d88 | ||
|
|
146ccd304f | ||
|
|
284be1c9e0 | ||
|
|
6dd7f2b50a | ||
|
|
36b610d8c1 | ||
|
|
a564b18d7f | ||
|
|
a5191f3e60 | ||
|
|
4f0e4d6cef | ||
|
|
8b8e296019 | ||
|
|
2468163e07 | ||
|
|
3036fd761a | ||
|
|
2240d83d78 | ||
|
|
bdfbd6325e | ||
|
|
57d30b7b4d | ||
|
|
9b54e812f7 | ||
|
|
cafbf63d30 | ||
|
|
0dfa6b38dc | ||
|
|
8a79769aff | ||
|
|
98726d538b | ||
|
|
9a56a5ea18 | ||
|
|
656f9c4126 | ||
|
|
c1e4f5a80d | ||
|
|
9d7eaf0046 | ||
|
|
992e4b7090 | ||
|
|
10c7ea4be8 | ||
|
|
3c206aca04 | ||
|
|
2f55beb355 | ||
|
|
70bdf643d0 | ||
|
|
8700eed4c6 | ||
|
|
7d6edc3ddd | ||
|
|
9d47341a4c | ||
|
|
0c60db7def | ||
|
|
17fae3ad0a | ||
|
|
ccf4f47b99 | ||
|
|
d0ffae825d | ||
|
|
a45596cff7 | ||
|
|
d0e687bf8c | ||
|
|
5fd142e763 | ||
|
|
45df87ca57 | ||
|
|
65732c36a8 | ||
|
|
6dd5ec7efb | ||
|
|
7764f8af3e | ||
|
|
d7947c37a8 | ||
|
|
be3f0698b0 |
91
.clang-format
Normal file
91
.clang-format
Normal file
@@ -0,0 +1,91 @@
|
|||||||
|
---
|
||||||
|
Language: Cpp
|
||||||
|
# BasedOnStyle: Google
|
||||||
|
# Generated with clang-format 3.8.1
|
||||||
|
AccessModifierOffset: -1
|
||||||
|
AlignAfterOpenBracket: Align
|
||||||
|
AlignConsecutiveAssignments: false
|
||||||
|
AlignConsecutiveDeclarations: false
|
||||||
|
AlignEscapedNewlinesLeft: true
|
||||||
|
AlignOperands: true
|
||||||
|
AlignTrailingComments: true
|
||||||
|
AllowAllParametersOfDeclarationOnNextLine: true
|
||||||
|
AllowShortBlocksOnASingleLine: false
|
||||||
|
AllowShortCaseLabelsOnASingleLine: true
|
||||||
|
AllowShortFunctionsOnASingleLine: All
|
||||||
|
AllowShortIfStatementsOnASingleLine: true
|
||||||
|
AllowShortLoopsOnASingleLine: true
|
||||||
|
AlwaysBreakAfterDefinitionReturnType: None
|
||||||
|
AlwaysBreakAfterReturnType: None
|
||||||
|
AlwaysBreakBeforeMultilineStrings: true
|
||||||
|
AlwaysBreakTemplateDeclarations: true
|
||||||
|
BinPackArguments: true
|
||||||
|
BinPackParameters: true
|
||||||
|
BraceWrapping:
|
||||||
|
AfterClass: false
|
||||||
|
AfterControlStatement: false
|
||||||
|
AfterEnum: false
|
||||||
|
AfterFunction: false
|
||||||
|
AfterNamespace: false
|
||||||
|
AfterObjCDeclaration: false
|
||||||
|
AfterStruct: false
|
||||||
|
AfterUnion: false
|
||||||
|
BeforeCatch: false
|
||||||
|
BeforeElse: false
|
||||||
|
IndentBraces: false
|
||||||
|
BreakBeforeBinaryOperators: None
|
||||||
|
BreakBeforeBraces: Attach
|
||||||
|
BreakBeforeTernaryOperators: true
|
||||||
|
BreakConstructorInitializersBeforeComma: false
|
||||||
|
ColumnLimit: 80
|
||||||
|
CommentPragmas: '^ IWYU pragma:'
|
||||||
|
ConstructorInitializerAllOnOneLineOrOnePerLine: false
|
||||||
|
ConstructorInitializerIndentWidth: 4
|
||||||
|
ContinuationIndentWidth: 4
|
||||||
|
Cpp11BracedListStyle: false
|
||||||
|
DerivePointerAlignment: false
|
||||||
|
DisableFormat: false
|
||||||
|
ExperimentalAutoDetectBinPacking: false
|
||||||
|
ForEachMacros: [ foreach, Q_FOREACH, BOOST_FOREACH ]
|
||||||
|
IncludeCategories:
|
||||||
|
- Regex: '^<.*\.h>'
|
||||||
|
Priority: 1
|
||||||
|
- Regex: '^<.*'
|
||||||
|
Priority: 2
|
||||||
|
- Regex: '.*'
|
||||||
|
Priority: 3
|
||||||
|
IndentCaseLabels: true
|
||||||
|
IndentWidth: 2
|
||||||
|
IndentWrappedFunctionNames: false
|
||||||
|
KeepEmptyLinesAtTheStartOfBlocks: false
|
||||||
|
MacroBlockBegin: ''
|
||||||
|
MacroBlockEnd: ''
|
||||||
|
MaxEmptyLinesToKeep: 1
|
||||||
|
NamespaceIndentation: None
|
||||||
|
ObjCBlockIndentWidth: 2
|
||||||
|
ObjCSpaceAfterProperty: false
|
||||||
|
ObjCSpaceBeforeProtocolList: false
|
||||||
|
PenaltyBreakBeforeFirstCallParameter: 1
|
||||||
|
PenaltyBreakComment: 300
|
||||||
|
PenaltyBreakFirstLessLess: 120
|
||||||
|
PenaltyBreakString: 1000
|
||||||
|
PenaltyExcessCharacter: 1000000
|
||||||
|
PenaltyReturnTypeOnItsOwnLine: 200
|
||||||
|
PointerAlignment: Right
|
||||||
|
ReflowComments: true
|
||||||
|
SortIncludes: false
|
||||||
|
SpaceAfterCStyleCast: false
|
||||||
|
SpaceBeforeAssignmentOperators: true
|
||||||
|
SpaceBeforeParens: ControlStatements
|
||||||
|
SpaceInEmptyParentheses: false
|
||||||
|
SpacesBeforeTrailingComments: 2
|
||||||
|
SpacesInAngles: false
|
||||||
|
SpacesInContainerLiterals: true
|
||||||
|
SpacesInCStyleCastParentheses: false
|
||||||
|
SpacesInParentheses: false
|
||||||
|
SpacesInSquareBrackets: false
|
||||||
|
Standard: Auto
|
||||||
|
TabWidth: 8
|
||||||
|
UseTab: Never
|
||||||
|
...
|
||||||
|
|
||||||
7
.gitignore
vendored
7
.gitignore
vendored
@@ -37,9 +37,9 @@
|
|||||||
/examples/twopass_encoder
|
/examples/twopass_encoder
|
||||||
/examples/vp8_multi_resolution_encoder
|
/examples/vp8_multi_resolution_encoder
|
||||||
/examples/vp8cx_set_ref
|
/examples/vp8cx_set_ref
|
||||||
|
/examples/vp9cx_set_ref
|
||||||
/examples/vp9_lossless_encoder
|
/examples/vp9_lossless_encoder
|
||||||
/examples/vp9_spatial_scalable_encoder
|
/examples/vp9_spatial_svc_encoder
|
||||||
/examples/vpx_temporal_scalable_patterns
|
|
||||||
/examples/vpx_temporal_svc_encoder
|
/examples/vpx_temporal_svc_encoder
|
||||||
/ivfdec
|
/ivfdec
|
||||||
/ivfdec.dox
|
/ivfdec.dox
|
||||||
@@ -50,6 +50,9 @@
|
|||||||
/samples.dox
|
/samples.dox
|
||||||
/test_intra_pred_speed
|
/test_intra_pred_speed
|
||||||
/test_libvpx
|
/test_libvpx
|
||||||
|
/tools.dox
|
||||||
|
/tools/*.dox
|
||||||
|
/tools/tiny_ssim
|
||||||
/vp8_api1_migration.dox
|
/vp8_api1_migration.dox
|
||||||
/vp[89x]_rtcd.h
|
/vp[89x]_rtcd.h
|
||||||
/vpx.pc
|
/vpx.pc
|
||||||
|
|||||||
7
.mailmap
7
.mailmap
@@ -3,6 +3,7 @@ Aℓex Converse <aconverse@google.com>
|
|||||||
Aℓex Converse <aconverse@google.com> <alex.converse@gmail.com>
|
Aℓex Converse <aconverse@google.com> <alex.converse@gmail.com>
|
||||||
Alexis Ballier <aballier@gentoo.org> <alexis.ballier@gmail.com>
|
Alexis Ballier <aballier@gentoo.org> <alexis.ballier@gmail.com>
|
||||||
Alpha Lam <hclam@google.com> <hclam@chromium.org>
|
Alpha Lam <hclam@google.com> <hclam@chromium.org>
|
||||||
|
Daniele Castagna <dcastagna@chromium.org> <dcastagna@google.com>
|
||||||
Deb Mukherjee <debargha@google.com>
|
Deb Mukherjee <debargha@google.com>
|
||||||
Erik Niemeyer <erik.a.niemeyer@intel.com> <erik.a.niemeyer@gmail.com>
|
Erik Niemeyer <erik.a.niemeyer@intel.com> <erik.a.niemeyer@gmail.com>
|
||||||
Guillaume Martres <gmartres@google.com> <smarter3@gmail.com>
|
Guillaume Martres <gmartres@google.com> <smarter3@gmail.com>
|
||||||
@@ -13,12 +14,15 @@ Jim Bankoski <jimbankoski@google.com>
|
|||||||
Johann Koenig <johannkoenig@google.com>
|
Johann Koenig <johannkoenig@google.com>
|
||||||
Johann Koenig <johannkoenig@google.com> <johann.koenig@duck.com>
|
Johann Koenig <johannkoenig@google.com> <johann.koenig@duck.com>
|
||||||
Johann Koenig <johannkoenig@google.com> <johann.koenig@gmail.com>
|
Johann Koenig <johannkoenig@google.com> <johann.koenig@gmail.com>
|
||||||
|
Johann Koenig <johannkoenig@google.com> <johannkoenig@chromium.org>
|
||||||
John Koleszar <jkoleszar@google.com>
|
John Koleszar <jkoleszar@google.com>
|
||||||
Joshua Litt <joshualitt@google.com> <joshualitt@chromium.org>
|
Joshua Litt <joshualitt@google.com> <joshualitt@chromium.org>
|
||||||
Marco Paniconi <marpan@google.com>
|
Marco Paniconi <marpan@google.com>
|
||||||
Marco Paniconi <marpan@google.com> <marpan@chromium.org>
|
Marco Paniconi <marpan@google.com> <marpan@chromium.org>
|
||||||
Pascal Massimino <pascal.massimino@gmail.com>
|
Pascal Massimino <pascal.massimino@gmail.com>
|
||||||
Paul Wilkins <paulwilkins@google.com>
|
Paul Wilkins <paulwilkins@google.com>
|
||||||
|
Peter de Rivaz <peter.derivaz@gmail.com>
|
||||||
|
Peter de Rivaz <peter.derivaz@gmail.com> <peter.derivaz@argondesign.com>
|
||||||
Ralph Giles <giles@xiph.org> <giles@entropywave.com>
|
Ralph Giles <giles@xiph.org> <giles@entropywave.com>
|
||||||
Ralph Giles <giles@xiph.org> <giles@mozilla.com>
|
Ralph Giles <giles@xiph.org> <giles@mozilla.com>
|
||||||
Ronald S. Bultje <rsbultje@gmail.com> <rbultje@google.com>
|
Ronald S. Bultje <rsbultje@gmail.com> <rbultje@google.com>
|
||||||
@@ -26,7 +30,8 @@ Sami Pietilä <samipietila@google.com>
|
|||||||
Tamar Levy <tamar.levy@intel.com>
|
Tamar Levy <tamar.levy@intel.com>
|
||||||
Tamar Levy <tamar.levy@intel.com> <levytamar82@gmail.com>
|
Tamar Levy <tamar.levy@intel.com> <levytamar82@gmail.com>
|
||||||
Tero Rintaluoma <teror@google.com> <tero.rintaluoma@on2.com>
|
Tero Rintaluoma <teror@google.com> <tero.rintaluoma@on2.com>
|
||||||
Timothy B. Terriberry <tterribe@xiph.org> Tim Terriberry <tterriberry@mozilla.com>
|
Timothy B. Terriberry <tterribe@xiph.org> <tterriberry@mozilla.com>
|
||||||
Tom Finegan <tomfinegan@google.com>
|
Tom Finegan <tomfinegan@google.com>
|
||||||
Tom Finegan <tomfinegan@google.com> <tomfinegan@chromium.org>
|
Tom Finegan <tomfinegan@google.com> <tomfinegan@chromium.org>
|
||||||
Yaowu Xu <yaowu@google.com> <yaowu@xuyaowu.com>
|
Yaowu Xu <yaowu@google.com> <yaowu@xuyaowu.com>
|
||||||
|
Yaowu Xu <yaowu@google.com> <Yaowu Xu>
|
||||||
|
|||||||
23
AUTHORS
23
AUTHORS
@@ -7,6 +7,8 @@ Adam Xu <adam@xuyaowu.com>
|
|||||||
Adrian Grange <agrange@google.com>
|
Adrian Grange <agrange@google.com>
|
||||||
Aℓex Converse <aconverse@google.com>
|
Aℓex Converse <aconverse@google.com>
|
||||||
Ahmad Sharif <asharif@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>
|
Alexander Voronov <avoronov@graphics.cs.msu.ru>
|
||||||
Alexis Ballier <aballier@gentoo.org>
|
Alexis Ballier <aballier@gentoo.org>
|
||||||
Alok Ahuja <waveletcoeff@gmail.com>
|
Alok Ahuja <waveletcoeff@gmail.com>
|
||||||
@@ -24,8 +26,10 @@ changjun.yang <changjun.yang@intel.com>
|
|||||||
Charles 'Buck' Krasic <ckrasic@google.com>
|
Charles 'Buck' Krasic <ckrasic@google.com>
|
||||||
chm <chm@rock-chips.com>
|
chm <chm@rock-chips.com>
|
||||||
Christian Duvivier <cduvivier@google.com>
|
Christian Duvivier <cduvivier@google.com>
|
||||||
|
Daniele Castagna <dcastagna@chromium.org>
|
||||||
Daniel Kang <ddkang@google.com>
|
Daniel Kang <ddkang@google.com>
|
||||||
Deb Mukherjee <debargha@google.com>
|
Deb Mukherjee <debargha@google.com>
|
||||||
|
Deepa K G <deepa.kg@ittiam.com>
|
||||||
Dim Temp <dimtemp0@gmail.com>
|
Dim Temp <dimtemp0@gmail.com>
|
||||||
Dmitry Kovalev <dkovalev@google.com>
|
Dmitry Kovalev <dkovalev@google.com>
|
||||||
Dragan Mrdjan <dmrdjan@mips.com>
|
Dragan Mrdjan <dmrdjan@mips.com>
|
||||||
@@ -36,6 +40,7 @@ Fabio Pedretti <fabio.ped@libero.it>
|
|||||||
Frank Galligan <fgalligan@google.com>
|
Frank Galligan <fgalligan@google.com>
|
||||||
Fredrik Söderquist <fs@opera.com>
|
Fredrik Söderquist <fs@opera.com>
|
||||||
Fritz Koenig <frkoenig@google.com>
|
Fritz Koenig <frkoenig@google.com>
|
||||||
|
Gabriel Marin <gmx@chromium.org>
|
||||||
Gaute Strokkenes <gaute.strokkenes@broadcom.com>
|
Gaute Strokkenes <gaute.strokkenes@broadcom.com>
|
||||||
Geza Lore <gezalore@gmail.com>
|
Geza Lore <gezalore@gmail.com>
|
||||||
Ghislain MARY <ghislainmary2@gmail.com>
|
Ghislain MARY <ghislainmary2@gmail.com>
|
||||||
@@ -47,6 +52,7 @@ Hangyu Kuang <hkuang@google.com>
|
|||||||
Hanno Böck <hanno@hboeck.de>
|
Hanno Böck <hanno@hboeck.de>
|
||||||
Henrik Lundin <hlundin@google.com>
|
Henrik Lundin <hlundin@google.com>
|
||||||
Hui Su <huisu@google.com>
|
Hui Su <huisu@google.com>
|
||||||
|
Ivan Krasin <krasin@chromium.org>
|
||||||
Ivan Maltz <ivanmaltz@google.com>
|
Ivan Maltz <ivanmaltz@google.com>
|
||||||
Jacek Caban <cjacek@gmail.com>
|
Jacek Caban <cjacek@gmail.com>
|
||||||
Jacky Chen <jackychen@google.com>
|
Jacky Chen <jackychen@google.com>
|
||||||
@@ -56,10 +62,13 @@ James Zern <jzern@google.com>
|
|||||||
Jan Gerber <j@mailb.org>
|
Jan Gerber <j@mailb.org>
|
||||||
Jan Kratochvil <jan.kratochvil@redhat.com>
|
Jan Kratochvil <jan.kratochvil@redhat.com>
|
||||||
Janne Salonen <jsalonen@google.com>
|
Janne Salonen <jsalonen@google.com>
|
||||||
|
Jean-Yves Avenard <jyavenard@mozilla.com>
|
||||||
Jeff Faust <jfaust@google.com>
|
Jeff Faust <jfaust@google.com>
|
||||||
Jeff Muizelaar <jmuizelaar@mozilla.com>
|
Jeff Muizelaar <jmuizelaar@mozilla.com>
|
||||||
Jeff Petkau <jpet@chromium.org>
|
Jeff Petkau <jpet@chromium.org>
|
||||||
|
Jerome Jiang <jianj@google.com>
|
||||||
Jia Jia <jia.jia@linaro.org>
|
Jia Jia <jia.jia@linaro.org>
|
||||||
|
Jian Zhou <zhoujian@google.com>
|
||||||
Jim Bankoski <jimbankoski@google.com>
|
Jim Bankoski <jimbankoski@google.com>
|
||||||
Jingning Han <jingning@google.com>
|
Jingning Han <jingning@google.com>
|
||||||
Joey Parrish <joeyparrish@google.com>
|
Joey Parrish <joeyparrish@google.com>
|
||||||
@@ -72,8 +81,10 @@ Joshua Litt <joshualitt@google.com>
|
|||||||
Julia Robson <juliamrobson@gmail.com>
|
Julia Robson <juliamrobson@gmail.com>
|
||||||
Justin Clift <justin@salasaga.org>
|
Justin Clift <justin@salasaga.org>
|
||||||
Justin Lebar <justin.lebar@gmail.com>
|
Justin Lebar <justin.lebar@gmail.com>
|
||||||
|
Kaustubh Raste <kaustubh.raste@imgtec.com>
|
||||||
KO Myung-Hun <komh@chollian.net>
|
KO Myung-Hun <komh@chollian.net>
|
||||||
Lawrence Velázquez <larryv@macports.org>
|
Lawrence Velázquez <larryv@macports.org>
|
||||||
|
Linfeng Zhang <linfengz@google.com>
|
||||||
Lou Quillio <louquillio@google.com>
|
Lou Quillio <louquillio@google.com>
|
||||||
Luca Barbato <lu_zero@gentoo.org>
|
Luca Barbato <lu_zero@gentoo.org>
|
||||||
Makoto Kato <makoto.kt@gmail.com>
|
Makoto Kato <makoto.kt@gmail.com>
|
||||||
@@ -87,8 +98,11 @@ Michael Kohler <michaelkohler@live.com>
|
|||||||
Mike Frysinger <vapier@chromium.org>
|
Mike Frysinger <vapier@chromium.org>
|
||||||
Mike Hommey <mhommey@mozilla.com>
|
Mike Hommey <mhommey@mozilla.com>
|
||||||
Mikhal Shemer <mikhal@google.com>
|
Mikhal Shemer <mikhal@google.com>
|
||||||
|
Min Chen <chenm003@gmail.com>
|
||||||
Minghai Shang <minghai@google.com>
|
Minghai Shang <minghai@google.com>
|
||||||
|
Min Ye <yeemmi@google.com>
|
||||||
Morton Jonuschat <yabawock@gmail.com>
|
Morton Jonuschat <yabawock@gmail.com>
|
||||||
|
Nathan E. Egge <negge@mozilla.com>
|
||||||
Nico Weber <thakis@chromium.org>
|
Nico Weber <thakis@chromium.org>
|
||||||
Parag Salasakar <img.mips1@gmail.com>
|
Parag Salasakar <img.mips1@gmail.com>
|
||||||
Pascal Massimino <pascal.massimino@gmail.com>
|
Pascal Massimino <pascal.massimino@gmail.com>
|
||||||
@@ -97,19 +111,24 @@ Paul Wilkins <paulwilkins@google.com>
|
|||||||
Pavol Rusnak <stick@gk2.sk>
|
Pavol Rusnak <stick@gk2.sk>
|
||||||
Paweł Hajdan <phajdan@google.com>
|
Paweł Hajdan <phajdan@google.com>
|
||||||
Pengchong Jin <pengchong@google.com>
|
Pengchong Jin <pengchong@google.com>
|
||||||
|
Peter Boström <pbos@google.com>
|
||||||
Peter de Rivaz <peter.derivaz@gmail.com>
|
Peter de Rivaz <peter.derivaz@gmail.com>
|
||||||
Philip Jägenstedt <philipj@opera.com>
|
Philip Jägenstedt <philipj@opera.com>
|
||||||
Priit Laes <plaes@plaes.org>
|
Priit Laes <plaes@plaes.org>
|
||||||
Rafael Ávila de Espíndola <rafael.espindola@gmail.com>
|
Rafael Ávila de Espíndola <rafael.espindola@gmail.com>
|
||||||
Rafaël Carré <funman@videolan.org>
|
Rafaël Carré <funman@videolan.org>
|
||||||
Ralph Giles <giles@xiph.org>
|
Ralph Giles <giles@xiph.org>
|
||||||
|
Ranjit Kumar Tulabandu <ranjit.tulabandu@ittiam.com>
|
||||||
Rob Bradford <rob@linux.intel.com>
|
Rob Bradford <rob@linux.intel.com>
|
||||||
Ronald S. Bultje <rsbultje@gmail.com>
|
Ronald S. Bultje <rsbultje@gmail.com>
|
||||||
Rui Ueyama <ruiu@google.com>
|
Rui Ueyama <ruiu@google.com>
|
||||||
Sami Pietilä <samipietila@google.com>
|
Sami Pietilä <samipietila@google.com>
|
||||||
|
Sarah Parker <sarahparker@google.com>
|
||||||
|
Sasi Inguva <isasi@google.com>
|
||||||
Scott Graham <scottmg@chromium.org>
|
Scott Graham <scottmg@chromium.org>
|
||||||
Scott LaVarnway <slavarnway@google.com>
|
Scott LaVarnway <slavarnway@google.com>
|
||||||
Sean McGovern <gseanmcg@gmail.com>
|
Sean McGovern <gseanmcg@gmail.com>
|
||||||
|
Sergey Kolomenkin <kolomenkin@gmail.com>
|
||||||
Sergey Ulanov <sergeyu@chromium.org>
|
Sergey Ulanov <sergeyu@chromium.org>
|
||||||
Shimon Doodkin <helpmepro1@gmail.com>
|
Shimon Doodkin <helpmepro1@gmail.com>
|
||||||
Shunyao Li <shunyaoli@google.com>
|
Shunyao Li <shunyaoli@google.com>
|
||||||
@@ -124,10 +143,14 @@ Thijs Vermeir <thijsvermeir@gmail.com>
|
|||||||
Tim Kopp <tkopp@google.com>
|
Tim Kopp <tkopp@google.com>
|
||||||
Timothy B. Terriberry <tterribe@xiph.org>
|
Timothy B. Terriberry <tterribe@xiph.org>
|
||||||
Tom Finegan <tomfinegan@google.com>
|
Tom Finegan <tomfinegan@google.com>
|
||||||
|
Tristan Matthews <le.businessman@gmail.com>
|
||||||
|
Urvang Joshi <urvang@google.com>
|
||||||
Vignesh Venkatasubramanian <vigneshv@google.com>
|
Vignesh Venkatasubramanian <vigneshv@google.com>
|
||||||
Yaowu Xu <yaowu@google.com>
|
Yaowu Xu <yaowu@google.com>
|
||||||
|
Yi Luo <luoyi@google.com>
|
||||||
Yongzhe Wang <yongzhe@google.com>
|
Yongzhe Wang <yongzhe@google.com>
|
||||||
Yunqing Wang <yunqingwang@google.com>
|
Yunqing Wang <yunqingwang@google.com>
|
||||||
|
Yury Gitman <yuryg@google.com>
|
||||||
Zoe Liu <zoeliu@google.com>
|
Zoe Liu <zoeliu@google.com>
|
||||||
Google Inc.
|
Google Inc.
|
||||||
The Mozilla Foundation
|
The Mozilla Foundation
|
||||||
|
|||||||
48
CHANGELOG
48
CHANGELOG
@@ -1,6 +1,48 @@
|
|||||||
Next Release
|
2017-01-09 v1.6.1 "Long Tailed Duck"
|
||||||
- Incompatible changes:
|
This release improves upon the VP9 encoder and speeds up the encoding and
|
||||||
The VP9 encoder's default keyframe interval changed to 128 from 9999.
|
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.
|
||||||
|
|
||||||
|
- Upgrading:
|
||||||
|
This release is ABI incompatible with 1.5.0 due to a new 'color_range' enum
|
||||||
|
in vpx_image and some minor changes to the VP8_COMP structure.
|
||||||
|
|
||||||
|
The default key frame interval for VP9 has changed from 128 to 9999.
|
||||||
|
|
||||||
|
- Enhancement:
|
||||||
|
A core focus has been performance for low end Intel processors. SSSE3
|
||||||
|
instructions such as 'pshufb' have been avoided and instructions have been
|
||||||
|
reordered to better accommodate the more constrained pipelines.
|
||||||
|
|
||||||
|
As a result, devices based on Celeron processors have seen substantial
|
||||||
|
decoding improvements. From Indian Runner Duck to Javan Whistling Duck,
|
||||||
|
decoding speed improved between 10 and 30%. Between Javan Whistling Duck
|
||||||
|
and Khaki Campbell Duck, it improved another 10 to 15%.
|
||||||
|
|
||||||
|
While Celeron benefited most, Core-i5 also improved 5% and 10% between the
|
||||||
|
respective releases.
|
||||||
|
|
||||||
|
Realtime performance for WebRTC for both speed and quality has received a
|
||||||
|
lot of attention.
|
||||||
|
|
||||||
|
- Bug Fixes:
|
||||||
|
A number of fuzzing issues, found variously by Mozilla, Chromium and others,
|
||||||
|
have been fixed and we strongly recommend updating.
|
||||||
|
|
||||||
2015-11-09 v1.5.0 "Javan Whistling Duck"
|
2015-11-09 v1.5.0 "Javan Whistling Duck"
|
||||||
This release improves upon the VP9 encoder and speeds up the encoding and
|
This release improves upon the VP9 encoder and speeds up the encoding and
|
||||||
|
|||||||
32
README
32
README
@@ -1,4 +1,4 @@
|
|||||||
README - 23 March 2015
|
README - 9 January 2017
|
||||||
|
|
||||||
Welcome to the WebM VP8/VP9 Codec SDK!
|
Welcome to the WebM VP8/VP9 Codec SDK!
|
||||||
|
|
||||||
@@ -47,10 +47,9 @@ COMPILING THE APPLICATIONS/LIBRARIES:
|
|||||||
--help output of the configure script. As of this writing, the list of
|
--help output of the configure script. As of this writing, the list of
|
||||||
available targets is:
|
available targets is:
|
||||||
|
|
||||||
armv6-linux-rvct
|
arm64-android-gcc
|
||||||
armv6-linux-gcc
|
|
||||||
armv6-none-rvct
|
|
||||||
arm64-darwin-gcc
|
arm64-darwin-gcc
|
||||||
|
arm64-linux-gcc
|
||||||
armv7-android-gcc
|
armv7-android-gcc
|
||||||
armv7-darwin-gcc
|
armv7-darwin-gcc
|
||||||
armv7-linux-rvct
|
armv7-linux-rvct
|
||||||
@@ -60,6 +59,7 @@ COMPILING THE APPLICATIONS/LIBRARIES:
|
|||||||
armv7-win32-vs12
|
armv7-win32-vs12
|
||||||
armv7-win32-vs14
|
armv7-win32-vs14
|
||||||
armv7s-darwin-gcc
|
armv7s-darwin-gcc
|
||||||
|
armv8-linux-gcc
|
||||||
mips32-linux-gcc
|
mips32-linux-gcc
|
||||||
mips64-linux-gcc
|
mips64-linux-gcc
|
||||||
sparc-solaris-gcc
|
sparc-solaris-gcc
|
||||||
@@ -73,15 +73,13 @@ COMPILING THE APPLICATIONS/LIBRARIES:
|
|||||||
x86-darwin12-gcc
|
x86-darwin12-gcc
|
||||||
x86-darwin13-gcc
|
x86-darwin13-gcc
|
||||||
x86-darwin14-gcc
|
x86-darwin14-gcc
|
||||||
|
x86-darwin15-gcc
|
||||||
x86-iphonesimulator-gcc
|
x86-iphonesimulator-gcc
|
||||||
x86-linux-gcc
|
x86-linux-gcc
|
||||||
x86-linux-icc
|
x86-linux-icc
|
||||||
x86-os2-gcc
|
x86-os2-gcc
|
||||||
x86-solaris-gcc
|
x86-solaris-gcc
|
||||||
x86-win32-gcc
|
x86-win32-gcc
|
||||||
x86-win32-vs7
|
|
||||||
x86-win32-vs8
|
|
||||||
x86-win32-vs9
|
|
||||||
x86-win32-vs10
|
x86-win32-vs10
|
||||||
x86-win32-vs11
|
x86-win32-vs11
|
||||||
x86-win32-vs12
|
x86-win32-vs12
|
||||||
@@ -93,13 +91,12 @@ COMPILING THE APPLICATIONS/LIBRARIES:
|
|||||||
x86_64-darwin12-gcc
|
x86_64-darwin12-gcc
|
||||||
x86_64-darwin13-gcc
|
x86_64-darwin13-gcc
|
||||||
x86_64-darwin14-gcc
|
x86_64-darwin14-gcc
|
||||||
|
x86_64-darwin15-gcc
|
||||||
x86_64-iphonesimulator-gcc
|
x86_64-iphonesimulator-gcc
|
||||||
x86_64-linux-gcc
|
x86_64-linux-gcc
|
||||||
x86_64-linux-icc
|
x86_64-linux-icc
|
||||||
x86_64-solaris-gcc
|
x86_64-solaris-gcc
|
||||||
x86_64-win64-gcc
|
x86_64-win64-gcc
|
||||||
x86_64-win64-vs8
|
|
||||||
x86_64-win64-vs9
|
|
||||||
x86_64-win64-vs10
|
x86_64-win64-vs10
|
||||||
x86_64-win64-vs11
|
x86_64-win64-vs11
|
||||||
x86_64-win64-vs12
|
x86_64-win64-vs12
|
||||||
@@ -132,7 +129,22 @@ VP8/VP9 TEST VECTORS:
|
|||||||
$ ./configure --enable-unit-tests
|
$ ./configure --enable-unit-tests
|
||||||
$ LIBVPX_TEST_DATA_PATH=../libvpx-test-data make testdata
|
$ LIBVPX_TEST_DATA_PATH=../libvpx-test-data make testdata
|
||||||
|
|
||||||
|
CODE STYLE:
|
||||||
|
The coding style used by this project is enforced with clang-format using the
|
||||||
|
configuration contained in the .clang-format file in the root of the
|
||||||
|
repository.
|
||||||
|
|
||||||
|
Before pushing changes for review you can format your code with:
|
||||||
|
# Apply clang-format to modified .c, .h and .cc files
|
||||||
|
$ clang-format -i --style=file \
|
||||||
|
$(git diff --name-only --diff-filter=ACMR '*.[hc]' '*.cc')
|
||||||
|
|
||||||
|
Check the .clang-format file for the version used to generate it if there is
|
||||||
|
any difference between your local formatting and the review system.
|
||||||
|
|
||||||
|
See also: http://clang.llvm.org/docs/ClangFormat.html
|
||||||
|
|
||||||
SUPPORT
|
SUPPORT
|
||||||
This library is an open source project supported by its community. Please
|
This library is an open source project supported by its community. Please
|
||||||
please email webm-discuss@webmproject.org for help.
|
email webm-discuss@webmproject.org for help.
|
||||||
|
|
||||||
|
|||||||
101
args.c
101
args.c
@@ -8,12 +8,12 @@
|
|||||||
* be found in the AUTHORS file in the root of the source tree.
|
* be found in the AUTHORS file in the root of the source tree.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <limits.h>
|
#include <limits.h>
|
||||||
#include "args.h"
|
#include "args.h"
|
||||||
|
|
||||||
|
#include "vpx/vpx_integer.h"
|
||||||
#include "vpx_ports/msvc.h"
|
#include "vpx_ports/msvc.h"
|
||||||
|
|
||||||
#if defined(__GNUC__) && __GNUC__
|
#if defined(__GNUC__) && __GNUC__
|
||||||
@@ -22,7 +22,6 @@ extern void die(const char *fmt, ...) __attribute__((noreturn));
|
|||||||
extern void die(const char *fmt, ...);
|
extern void die(const char *fmt, ...);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
struct arg arg_init(char **argv) {
|
struct arg arg_init(char **argv) {
|
||||||
struct arg a;
|
struct arg a;
|
||||||
|
|
||||||
@@ -37,27 +36,22 @@ struct arg arg_init(char **argv) {
|
|||||||
int arg_match(struct arg *arg_, const struct arg_def *def, char **argv) {
|
int arg_match(struct arg *arg_, const struct arg_def *def, char **argv) {
|
||||||
struct arg arg;
|
struct arg arg;
|
||||||
|
|
||||||
if (!argv[0] || argv[0][0] != '-')
|
if (!argv[0] || argv[0][0] != '-') return 0;
|
||||||
return 0;
|
|
||||||
|
|
||||||
arg = arg_init(argv);
|
arg = arg_init(argv);
|
||||||
|
|
||||||
if (def->short_name
|
if (def->short_name && strlen(arg.argv[0]) == strlen(def->short_name) + 1 &&
|
||||||
&& strlen(arg.argv[0]) == strlen(def->short_name) + 1
|
!strcmp(arg.argv[0] + 1, def->short_name)) {
|
||||||
&& !strcmp(arg.argv[0] + 1, def->short_name)) {
|
|
||||||
|
|
||||||
arg.name = arg.argv[0] + 1;
|
arg.name = arg.argv[0] + 1;
|
||||||
arg.val = def->has_val ? arg.argv[1] : NULL;
|
arg.val = def->has_val ? arg.argv[1] : NULL;
|
||||||
arg.argv_step = def->has_val ? 2 : 1;
|
arg.argv_step = def->has_val ? 2 : 1;
|
||||||
} else if (def->long_name) {
|
} else if (def->long_name) {
|
||||||
const size_t name_len = strlen(def->long_name);
|
const size_t name_len = strlen(def->long_name);
|
||||||
|
|
||||||
if (strlen(arg.argv[0]) >= name_len + 2
|
if (strlen(arg.argv[0]) >= name_len + 2 && arg.argv[0][1] == '-' &&
|
||||||
&& arg.argv[0][1] == '-'
|
!strncmp(arg.argv[0] + 2, def->long_name, name_len) &&
|
||||||
&& !strncmp(arg.argv[0] + 2, def->long_name, name_len)
|
(arg.argv[0][name_len + 2] == '=' ||
|
||||||
&& (arg.argv[0][name_len + 2] == '='
|
arg.argv[0][name_len + 2] == '\0')) {
|
||||||
|| arg.argv[0][name_len + 2] == '\0')) {
|
|
||||||
|
|
||||||
arg.name = arg.argv[0] + 2;
|
arg.name = arg.argv[0] + 2;
|
||||||
arg.val = arg.name[name_len] == '=' ? arg.name + name_len + 1 : NULL;
|
arg.val = arg.name[name_len] == '=' ? arg.name + name_len + 1 : NULL;
|
||||||
arg.argv_step = 1;
|
arg.argv_step = 1;
|
||||||
@@ -70,8 +64,7 @@ int arg_match(struct arg *arg_, const struct arg_def *def, char **argv) {
|
|||||||
if (arg.name && arg.val && !def->has_val)
|
if (arg.name && arg.val && !def->has_val)
|
||||||
die("Error: option %s requires no argument.\n", arg.name);
|
die("Error: option %s requires no argument.\n", arg.name);
|
||||||
|
|
||||||
if (arg.name
|
if (arg.name && (arg.val || !def->has_val)) {
|
||||||
&& (arg.val || !def->has_val)) {
|
|
||||||
arg.def = def;
|
arg.def = def;
|
||||||
*arg_ = arg;
|
*arg_ = arg;
|
||||||
return 1;
|
return 1;
|
||||||
@@ -80,15 +73,12 @@ int arg_match(struct arg *arg_, const struct arg_def *def, char **argv) {
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
const char *arg_next(struct arg *arg) {
|
const char *arg_next(struct arg *arg) {
|
||||||
if (arg->argv[0])
|
if (arg->argv[0]) arg->argv += arg->argv_step;
|
||||||
arg->argv += arg->argv_step;
|
|
||||||
|
|
||||||
return *arg->argv;
|
return *arg->argv;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
char **argv_dup(int argc, const char **argv) {
|
char **argv_dup(int argc, const char **argv) {
|
||||||
char **new_argv = malloc((argc + 1) * sizeof(*argv));
|
char **new_argv = malloc((argc + 1) * sizeof(*argv));
|
||||||
|
|
||||||
@@ -97,7 +87,6 @@ char **argv_dup(int argc, const char **argv) {
|
|||||||
return new_argv;
|
return new_argv;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void arg_show_usage(FILE *fp, const struct arg_def *const *defs) {
|
void arg_show_usage(FILE *fp, const struct arg_def *const *defs) {
|
||||||
char option_text[40] = { 0 };
|
char option_text[40] = { 0 };
|
||||||
|
|
||||||
@@ -109,15 +98,12 @@ void arg_show_usage(FILE *fp, const struct arg_def *const *defs) {
|
|||||||
if (def->short_name && def->long_name) {
|
if (def->short_name && def->long_name) {
|
||||||
char *comma = def->has_val ? "," : ", ";
|
char *comma = def->has_val ? "," : ", ";
|
||||||
|
|
||||||
snprintf(option_text, 37, "-%s%s%s --%s%6s",
|
snprintf(option_text, 37, "-%s%s%s --%s%6s", def->short_name, short_val,
|
||||||
def->short_name, short_val, comma,
|
comma, def->long_name, long_val);
|
||||||
def->long_name, long_val);
|
|
||||||
} else if (def->short_name)
|
} else if (def->short_name)
|
||||||
snprintf(option_text, 37, "-%s%s",
|
snprintf(option_text, 37, "-%s%s", def->short_name, short_val);
|
||||||
def->short_name, short_val);
|
|
||||||
else if (def->long_name)
|
else if (def->long_name)
|
||||||
snprintf(option_text, 37, " --%s%s",
|
snprintf(option_text, 37, " --%s%s", def->long_name, long_val);
|
||||||
def->long_name, long_val);
|
|
||||||
|
|
||||||
fprintf(fp, " %-37s\t%s\n", option_text, def->desc);
|
fprintf(fp, " %-37s\t%s\n", option_text, def->desc);
|
||||||
|
|
||||||
@@ -127,51 +113,45 @@ void arg_show_usage(FILE *fp, const struct arg_def *const *defs) {
|
|||||||
fprintf(fp, " %-37s\t ", "");
|
fprintf(fp, " %-37s\t ", "");
|
||||||
|
|
||||||
for (listptr = def->enums; listptr->name; listptr++)
|
for (listptr = def->enums; listptr->name; listptr++)
|
||||||
fprintf(fp, "%s%s", listptr->name,
|
fprintf(fp, "%s%s", listptr->name, listptr[1].name ? ", " : "\n");
|
||||||
listptr[1].name ? ", " : "\n");
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
unsigned int arg_parse_uint(const struct arg *arg) {
|
unsigned int arg_parse_uint(const struct arg *arg) {
|
||||||
long int rawval;
|
uint32_t rawval;
|
||||||
char *endptr;
|
char *endptr;
|
||||||
|
|
||||||
rawval = strtol(arg->val, &endptr, 10);
|
rawval = (uint32_t)strtoul(arg->val, &endptr, 10);
|
||||||
|
|
||||||
if (arg->val[0] != '\0' && endptr[0] == '\0') {
|
if (arg->val[0] != '\0' && endptr[0] == '\0') {
|
||||||
if (rawval >= 0 && rawval <= UINT_MAX)
|
if (rawval <= UINT_MAX) return rawval;
|
||||||
return rawval;
|
|
||||||
|
|
||||||
die("Option %s: Value %ld out of range for unsigned int\n",
|
die("Option %s: Value %ld out of range for unsigned int\n", arg->name,
|
||||||
arg->name, rawval);
|
rawval);
|
||||||
}
|
}
|
||||||
|
|
||||||
die("Option %s: Invalid character '%c'\n", arg->name, *endptr);
|
die("Option %s: Invalid character '%c'\n", arg->name, *endptr);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
int arg_parse_int(const struct arg *arg) {
|
int arg_parse_int(const struct arg *arg) {
|
||||||
long int rawval;
|
int32_t rawval;
|
||||||
char *endptr;
|
char *endptr;
|
||||||
|
|
||||||
rawval = strtol(arg->val, &endptr, 10);
|
rawval = (int32_t)strtol(arg->val, &endptr, 10);
|
||||||
|
|
||||||
if (arg->val[0] != '\0' && endptr[0] == '\0') {
|
if (arg->val[0] != '\0' && endptr[0] == '\0') {
|
||||||
if (rawval >= INT_MIN && rawval <= INT_MAX)
|
if (rawval >= INT_MIN && rawval <= INT_MAX) return (int)rawval;
|
||||||
return rawval;
|
|
||||||
|
|
||||||
die("Option %s: Value %ld out of range for signed int\n",
|
die("Option %s: Value %ld out of range for signed int\n", arg->name,
|
||||||
arg->name, rawval);
|
rawval);
|
||||||
}
|
}
|
||||||
|
|
||||||
die("Option %s: Invalid character '%c'\n", arg->name, *endptr);
|
die("Option %s: Invalid character '%c'\n", arg->name, *endptr);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
struct vpx_rational {
|
struct vpx_rational {
|
||||||
int num; /**< fraction numerator */
|
int num; /**< fraction numerator */
|
||||||
int den; /**< fraction denominator */
|
int den; /**< fraction denominator */
|
||||||
@@ -186,25 +166,28 @@ struct vpx_rational arg_parse_rational(const struct arg *arg) {
|
|||||||
|
|
||||||
if (arg->val[0] != '\0' && endptr[0] == '/') {
|
if (arg->val[0] != '\0' && endptr[0] == '/') {
|
||||||
if (rawval >= INT_MIN && rawval <= INT_MAX)
|
if (rawval >= INT_MIN && rawval <= INT_MAX)
|
||||||
rat.num = rawval;
|
rat.num = (int)rawval;
|
||||||
else die("Option %s: Value %ld out of range for signed int\n",
|
else
|
||||||
arg->name, rawval);
|
die("Option %s: Value %ld out of range for signed int\n", arg->name,
|
||||||
} else die("Option %s: Expected / at '%c'\n", arg->name, *endptr);
|
rawval);
|
||||||
|
} else
|
||||||
|
die("Option %s: Expected / at '%c'\n", arg->name, *endptr);
|
||||||
|
|
||||||
/* parse denominator */
|
/* parse denominator */
|
||||||
rawval = strtol(endptr + 1, &endptr, 10);
|
rawval = strtol(endptr + 1, &endptr, 10);
|
||||||
|
|
||||||
if (arg->val[0] != '\0' && endptr[0] == '\0') {
|
if (arg->val[0] != '\0' && endptr[0] == '\0') {
|
||||||
if (rawval >= INT_MIN && rawval <= INT_MAX)
|
if (rawval >= INT_MIN && rawval <= INT_MAX)
|
||||||
rat.den = rawval;
|
rat.den = (int)rawval;
|
||||||
else die("Option %s: Value %ld out of range for signed int\n",
|
else
|
||||||
arg->name, rawval);
|
die("Option %s: Value %ld out of range for signed int\n", arg->name,
|
||||||
} else die("Option %s: Invalid character '%c'\n", arg->name, *endptr);
|
rawval);
|
||||||
|
} else
|
||||||
|
die("Option %s: Invalid character '%c'\n", arg->name, *endptr);
|
||||||
|
|
||||||
return rat;
|
return rat;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
int arg_parse_enum(const struct arg *arg) {
|
int arg_parse_enum(const struct arg *arg) {
|
||||||
const struct arg_enum_list *listptr;
|
const struct arg_enum_list *listptr;
|
||||||
long int rawval;
|
long int rawval;
|
||||||
@@ -215,22 +198,18 @@ int arg_parse_enum(const struct arg *arg) {
|
|||||||
if (arg->val[0] != '\0' && endptr[0] == '\0') {
|
if (arg->val[0] != '\0' && endptr[0] == '\0') {
|
||||||
/* Got a raw value, make sure it's valid */
|
/* Got a raw value, make sure it's valid */
|
||||||
for (listptr = arg->def->enums; listptr->name; listptr++)
|
for (listptr = arg->def->enums; listptr->name; listptr++)
|
||||||
if (listptr->val == rawval)
|
if (listptr->val == rawval) return (int)rawval;
|
||||||
return rawval;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Next see if it can be parsed as a string */
|
/* Next see if it can be parsed as a string */
|
||||||
for (listptr = arg->def->enums; listptr->name; listptr++)
|
for (listptr = arg->def->enums; listptr->name; listptr++)
|
||||||
if (!strcmp(arg->val, listptr->name))
|
if (!strcmp(arg->val, listptr->name)) return listptr->val;
|
||||||
return listptr->val;
|
|
||||||
|
|
||||||
die("Option %s: Invalid value '%s'\n", arg->name, arg->val);
|
die("Option %s: Invalid value '%s'\n", arg->name, arg->val);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
int arg_parse_enum_or_int(const struct arg *arg) {
|
int arg_parse_enum_or_int(const struct arg *arg) {
|
||||||
if (arg->def->enums)
|
if (arg->def->enums) return arg_parse_enum(arg);
|
||||||
return arg_parse_enum(arg);
|
|
||||||
return arg_parse_int(arg);
|
return arg_parse_int(arg);
|
||||||
}
|
}
|
||||||
|
|||||||
13
args.h
13
args.h
@@ -8,7 +8,6 @@
|
|||||||
* be found in the AUTHORS file in the root of the source tree.
|
* be found in the AUTHORS file in the root of the source tree.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
#ifndef ARGS_H_
|
#ifndef ARGS_H_
|
||||||
#define ARGS_H_
|
#define ARGS_H_
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
@@ -29,7 +28,8 @@ struct arg_enum_list {
|
|||||||
const char *name;
|
const char *name;
|
||||||
int val;
|
int val;
|
||||||
};
|
};
|
||||||
#define ARG_ENUM_LIST_END {0}
|
#define ARG_ENUM_LIST_END \
|
||||||
|
{ 0 }
|
||||||
|
|
||||||
typedef struct arg_def {
|
typedef struct arg_def {
|
||||||
const char *short_name;
|
const char *short_name;
|
||||||
@@ -38,9 +38,12 @@ typedef struct arg_def {
|
|||||||
const char *desc;
|
const char *desc;
|
||||||
const struct arg_enum_list *enums;
|
const struct arg_enum_list *enums;
|
||||||
} arg_def_t;
|
} arg_def_t;
|
||||||
#define ARG_DEF(s,l,v,d) {s,l,v,d, NULL}
|
#define ARG_DEF(s, l, v, d) \
|
||||||
#define ARG_DEF_ENUM(s,l,v,d,e) {s,l,v,d,e}
|
{ s, l, v, d, NULL }
|
||||||
#define ARG_DEF_LIST_END {0}
|
#define ARG_DEF_ENUM(s, l, v, d, e) \
|
||||||
|
{ s, l, v, d, e }
|
||||||
|
#define ARG_DEF_LIST_END \
|
||||||
|
{ 0 }
|
||||||
|
|
||||||
struct arg arg_init(char **argv);
|
struct arg arg_init(char **argv);
|
||||||
int arg_match(struct arg *arg_, const struct arg_def *def, char **argv);
|
int arg_match(struct arg *arg_, const struct arg_def *def, char **argv);
|
||||||
|
|||||||
@@ -29,11 +29,6 @@
|
|||||||
# include $(CLEAR_VARS)
|
# include $(CLEAR_VARS)
|
||||||
# include jni/libvpx/build/make/Android.mk
|
# include jni/libvpx/build/make/Android.mk
|
||||||
#
|
#
|
||||||
# There are currently two TARGET_ARCH_ABI targets for ARM.
|
|
||||||
# armeabi and armeabi-v7a. armeabi-v7a is selected by creating an
|
|
||||||
# Application.mk in the jni directory that contains:
|
|
||||||
# APP_ABI := armeabi-v7a
|
|
||||||
#
|
|
||||||
# By default libvpx will detect at runtime the existance of NEON extension.
|
# By default libvpx will detect at runtime the existance of NEON extension.
|
||||||
# For this we import the 'cpufeatures' module from the NDK sources.
|
# For this we import the 'cpufeatures' module from the NDK sources.
|
||||||
# libvpx can also be configured without this runtime detection method.
|
# libvpx can also be configured without this runtime detection method.
|
||||||
@@ -42,28 +37,44 @@
|
|||||||
# --disable-neon-asm
|
# --disable-neon-asm
|
||||||
# will remove any NEON dependency.
|
# will remove any NEON dependency.
|
||||||
|
|
||||||
# To change to building armeabi, run ./libvpx/configure again, but with
|
|
||||||
# --target=armv6-android-gcc and modify the Application.mk file to
|
|
||||||
# set APP_ABI := armeabi
|
|
||||||
#
|
#
|
||||||
# Running ndk-build will build libvpx and include it in your project.
|
# Running ndk-build will build libvpx and include it in your project.
|
||||||
#
|
#
|
||||||
|
|
||||||
|
# Alternatively, building the examples and unit tests can be accomplished in the
|
||||||
|
# following way:
|
||||||
|
#
|
||||||
|
# Create a standalone toolchain from the NDK:
|
||||||
|
# https://developer.android.com/ndk/guides/standalone_toolchain.html
|
||||||
|
#
|
||||||
|
# For example - to test on arm64 devices with clang:
|
||||||
|
# $NDK/build/tools/make_standalone_toolchain.py \
|
||||||
|
# --arch arm64 --install-dir=/tmp/my-android-toolchain
|
||||||
|
# export PATH=/tmp/my-android-toolchain/bin:$PATH
|
||||||
|
# CROSS=aarch64-linux-android- CC=clang CXX=clang++ /path/to/libvpx/configure \
|
||||||
|
# --target=arm64-android-gcc
|
||||||
|
#
|
||||||
|
# Push the resulting binaries to a device and run them:
|
||||||
|
# adb push test_libvpx /data/tmp/test_libvpx
|
||||||
|
# adb shell /data/tmp/test_libvpx --gtest_filter=\*Sixtap\*
|
||||||
|
#
|
||||||
|
# Make sure to push the test data as well and set LIBVPX_TEST_DATA
|
||||||
|
|
||||||
CONFIG_DIR := $(LOCAL_PATH)/
|
CONFIG_DIR := $(LOCAL_PATH)/
|
||||||
LIBVPX_PATH := $(LOCAL_PATH)/libvpx
|
LIBVPX_PATH := $(LOCAL_PATH)/libvpx
|
||||||
ASM_CNV_PATH_LOCAL := $(TARGET_ARCH_ABI)/ads2gas
|
ASM_CNV_PATH_LOCAL := $(TARGET_ARCH_ABI)/ads2gas
|
||||||
ASM_CNV_PATH := $(LOCAL_PATH)/$(ASM_CNV_PATH_LOCAL)
|
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
|
# Use the makefiles generated by upstream configure to determine which files to
|
||||||
# build. Also set any architecture-specific flags.
|
# build. Also set any architecture-specific flags.
|
||||||
ifeq ($(TARGET_ARCH_ABI),armeabi-v7a)
|
ifeq ($(TARGET_ARCH_ABI),armeabi-v7a)
|
||||||
include $(CONFIG_DIR)libs-armv7-android-gcc.mk
|
include $(CONFIG_DIR)libs-armv7-android-gcc.mk
|
||||||
LOCAL_ARM_MODE := arm
|
LOCAL_ARM_MODE := arm
|
||||||
else ifeq ($(TARGET_ARCH_ABI),armeabi)
|
|
||||||
include $(CONFIG_DIR)libs-armv6-android-gcc.mk
|
|
||||||
LOCAL_ARM_MODE := arm
|
|
||||||
else ifeq ($(TARGET_ARCH_ABI),arm64-v8a)
|
else ifeq ($(TARGET_ARCH_ABI),arm64-v8a)
|
||||||
include $(CONFIG_DIR)libs-armv8-android-gcc.mk
|
include $(CONFIG_DIR)libs-arm64-android-gcc.mk
|
||||||
LOCAL_ARM_MODE := arm
|
LOCAL_ARM_MODE := arm
|
||||||
else ifeq ($(TARGET_ARCH_ABI),x86)
|
else ifeq ($(TARGET_ARCH_ABI),x86)
|
||||||
include $(CONFIG_DIR)libs-x86-android-gcc.mk
|
include $(CONFIG_DIR)libs-x86-android-gcc.mk
|
||||||
@@ -93,10 +104,10 @@ LOCAL_CFLAGS := -O3
|
|||||||
# like x86inc.asm and x86_abi_support.asm
|
# like x86inc.asm and x86_abi_support.asm
|
||||||
LOCAL_ASMFLAGS := -I$(LIBVPX_PATH)
|
LOCAL_ASMFLAGS := -I$(LIBVPX_PATH)
|
||||||
|
|
||||||
.PRECIOUS: %.asm.s
|
.PRECIOUS: %.asm.S
|
||||||
$(ASM_CNV_PATH)/libvpx/%.asm.s: $(LIBVPX_PATH)/%.asm
|
$(ASM_CNV_PATH)/libvpx/%.asm.S: $(LIBVPX_PATH)/%.asm
|
||||||
@mkdir -p $(dir $@)
|
$(qexec)mkdir -p $(dir $@)
|
||||||
@$(CONFIG_DIR)$(ASM_CONVERSION) <$< > $@
|
$(qexec)$(CONFIG_DIR)$(ASM_CONVERSION) <$< > $@
|
||||||
|
|
||||||
# For building *_rtcd.h, which have rules in libs.mk
|
# For building *_rtcd.h, which have rules in libs.mk
|
||||||
TGT_ISA:=$(word 1, $(subst -, ,$(TOOLCHAIN)))
|
TGT_ISA:=$(word 1, $(subst -, ,$(TOOLCHAIN)))
|
||||||
@@ -124,7 +135,7 @@ endif
|
|||||||
|
|
||||||
# Pull out assembly files, splitting NEON from the rest. This is
|
# Pull out assembly files, splitting NEON from the rest. This is
|
||||||
# done to specify that the NEON assembly files use NEON assembler flags.
|
# done to specify that the NEON assembly files use NEON assembler flags.
|
||||||
# x86 assembly matches %.asm, arm matches %.asm.s
|
# x86 assembly matches %.asm, arm matches %.asm.S
|
||||||
|
|
||||||
# x86:
|
# x86:
|
||||||
|
|
||||||
@@ -132,31 +143,44 @@ CODEC_SRCS_ASM_X86 = $(filter %.asm, $(CODEC_SRCS_UNIQUE))
|
|||||||
LOCAL_SRC_FILES += $(foreach file, $(CODEC_SRCS_ASM_X86), libvpx/$(file))
|
LOCAL_SRC_FILES += $(foreach file, $(CODEC_SRCS_ASM_X86), libvpx/$(file))
|
||||||
|
|
||||||
# arm:
|
# arm:
|
||||||
CODEC_SRCS_ASM_ARM_ALL = $(filter %.asm.s, $(CODEC_SRCS_UNIQUE))
|
CODEC_SRCS_ASM_ARM_ALL = $(filter %.asm.S, $(CODEC_SRCS_UNIQUE))
|
||||||
CODEC_SRCS_ASM_ARM = $(foreach v, \
|
CODEC_SRCS_ASM_ARM = $(foreach v, \
|
||||||
$(CODEC_SRCS_ASM_ARM_ALL), \
|
$(CODEC_SRCS_ASM_ARM_ALL), \
|
||||||
$(if $(findstring neon,$(v)),,$(v)))
|
$(if $(findstring neon,$(v)),,$(v)))
|
||||||
CODEC_SRCS_ASM_ADS2GAS = $(patsubst %.s, \
|
CODEC_SRCS_ASM_ADS2GAS = $(patsubst %.S, \
|
||||||
$(ASM_CNV_PATH_LOCAL)/libvpx/%.s, \
|
$(ASM_CNV_PATH_LOCAL)/libvpx/%.S, \
|
||||||
$(CODEC_SRCS_ASM_ARM))
|
$(CODEC_SRCS_ASM_ARM))
|
||||||
LOCAL_SRC_FILES += $(CODEC_SRCS_ASM_ADS2GAS)
|
LOCAL_SRC_FILES += $(CODEC_SRCS_ASM_ADS2GAS)
|
||||||
|
|
||||||
ifeq ($(TARGET_ARCH_ABI),armeabi-v7a)
|
ifeq ($(TARGET_ARCH_ABI),armeabi-v7a)
|
||||||
|
ASM_INCLUDES := vpx_dsp/arm/idct_neon.asm.S
|
||||||
CODEC_SRCS_ASM_NEON = $(foreach v, \
|
CODEC_SRCS_ASM_NEON = $(foreach v, \
|
||||||
$(CODEC_SRCS_ASM_ARM_ALL),\
|
$(CODEC_SRCS_ASM_ARM_ALL),\
|
||||||
$(if $(findstring neon,$(v)),$(v),))
|
$(if $(findstring neon,$(v)),$(v),))
|
||||||
CODEC_SRCS_ASM_NEON_ADS2GAS = $(patsubst %.s, \
|
CODEC_SRCS_ASM_NEON := $(filter-out $(addprefix %, $(ASM_INCLUDES)), \
|
||||||
$(ASM_CNV_PATH_LOCAL)/libvpx/%.s, \
|
|
||||||
$(CODEC_SRCS_ASM_NEON))
|
$(CODEC_SRCS_ASM_NEON))
|
||||||
LOCAL_SRC_FILES += $(patsubst %.s, \
|
CODEC_SRCS_ASM_NEON_ADS2GAS = $(patsubst %.S, \
|
||||||
%.s.neon, \
|
$(ASM_CNV_PATH_LOCAL)/libvpx/%.S, \
|
||||||
|
$(CODEC_SRCS_ASM_NEON))
|
||||||
|
LOCAL_SRC_FILES += $(patsubst %.S, \
|
||||||
|
%.S.neon, \
|
||||||
$(CODEC_SRCS_ASM_NEON_ADS2GAS))
|
$(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
|
endif
|
||||||
|
|
||||||
LOCAL_CFLAGS += \
|
LOCAL_CFLAGS += \
|
||||||
-DHAVE_CONFIG_H=vpx_config.h \
|
-DHAVE_CONFIG_H=vpx_config.h \
|
||||||
-I$(LIBVPX_PATH) \
|
-I$(LIBVPX_PATH) \
|
||||||
-I$(ASM_CNV_PATH)
|
-I$(ASM_CNV_PATH) \
|
||||||
|
-I$(ASM_CNV_PATH)/libvpx
|
||||||
|
|
||||||
LOCAL_MODULE := libvpx
|
LOCAL_MODULE := libvpx
|
||||||
|
|
||||||
@@ -174,13 +198,11 @@ endif
|
|||||||
ifeq ($(CONFIG_VP9), yes)
|
ifeq ($(CONFIG_VP9), yes)
|
||||||
$$(rtcd_dep_template_SRCS): vp9_rtcd.h
|
$$(rtcd_dep_template_SRCS): vp9_rtcd.h
|
||||||
endif
|
endif
|
||||||
ifeq ($(CONFIG_VP10), yes)
|
|
||||||
$$(rtcd_dep_template_SRCS): vp10_rtcd.h
|
|
||||||
endif
|
|
||||||
$$(rtcd_dep_template_SRCS): vpx_scale_rtcd.h
|
$$(rtcd_dep_template_SRCS): vpx_scale_rtcd.h
|
||||||
$$(rtcd_dep_template_SRCS): vpx_dsp_rtcd.h
|
$$(rtcd_dep_template_SRCS): vpx_dsp_rtcd.h
|
||||||
|
|
||||||
ifneq ($(findstring $(TARGET_ARCH_ABI),x86 x86_64),)
|
rtcd_dep_template_CONFIG_ASM_ABIS := x86 x86_64 armeabi-v7a
|
||||||
|
ifneq ($$(findstring $(TARGET_ARCH_ABI),$$(rtcd_dep_template_CONFIG_ASM_ABIS)),)
|
||||||
$$(rtcd_dep_template_SRCS): vpx_config.asm
|
$$(rtcd_dep_template_SRCS): vpx_config.asm
|
||||||
endif
|
endif
|
||||||
endef
|
endef
|
||||||
@@ -190,16 +212,17 @@ $(eval $(call rtcd_dep_template))
|
|||||||
.PHONY: clean
|
.PHONY: clean
|
||||||
clean:
|
clean:
|
||||||
@echo "Clean: ads2gas files [$(TARGET_ARCH_ABI)]"
|
@echo "Clean: ads2gas files [$(TARGET_ARCH_ABI)]"
|
||||||
@$(RM) $(CODEC_SRCS_ASM_ADS2GAS) $(CODEC_SRCS_ASM_NEON_ADS2GAS)
|
$(qexec)$(RM) $(CODEC_SRCS_ASM_ADS2GAS) $(CODEC_SRCS_ASM_NEON_ADS2GAS)
|
||||||
@$(RM) -r $(ASM_CNV_PATH)
|
$(qexec)$(RM) -r $(ASM_CNV_PATH)
|
||||||
@$(RM) $(CLEAN-OBJS)
|
$(qexec)$(RM) $(CLEAN-OBJS)
|
||||||
|
|
||||||
ifeq ($(ENABLE_SHARED),1)
|
ifeq ($(ENABLE_SHARED),1)
|
||||||
|
LOCAL_CFLAGS += -fPIC
|
||||||
include $(BUILD_SHARED_LIBRARY)
|
include $(BUILD_SHARED_LIBRARY)
|
||||||
else
|
else
|
||||||
include $(BUILD_STATIC_LIBRARY)
|
include $(BUILD_STATIC_LIBRARY)
|
||||||
endif
|
endif
|
||||||
|
|
||||||
ifeq ($(CONFIG_RUNTIME_CPU_DETECT),yes)
|
ifeq ($(CONFIG_RUNTIME_CPU_DETECT),yes)
|
||||||
$(call import-module,cpufeatures)
|
$(call import-module,android/cpufeatures)
|
||||||
endif
|
endif
|
||||||
|
|||||||
@@ -26,7 +26,7 @@ test-no-data-check:: .DEFAULT
|
|||||||
testdata:: .DEFAULT
|
testdata:: .DEFAULT
|
||||||
utiltest: .DEFAULT
|
utiltest: .DEFAULT
|
||||||
exampletest-no-data-check utiltest-no-data-check: .DEFAULT
|
exampletest-no-data-check utiltest-no-data-check: .DEFAULT
|
||||||
|
test_%: .DEFAULT ;
|
||||||
|
|
||||||
# Note: md5sum is not installed on OS X, but openssl is. Openssl may not be
|
# Note: md5sum is not installed on OS X, but openssl is. Openssl may not be
|
||||||
# installed on cygwin, so we need to autodetect here.
|
# installed on cygwin, so we need to autodetect here.
|
||||||
@@ -90,7 +90,7 @@ all:
|
|||||||
|
|
||||||
.PHONY: clean
|
.PHONY: clean
|
||||||
clean::
|
clean::
|
||||||
rm -f $(OBJS-yes) $(OBJS-yes:.o=.d) $(OBJS-yes:.asm.s.o=.asm.s)
|
rm -f $(OBJS-yes) $(OBJS-yes:.o=.d) $(OBJS-yes:.asm.S.o=.asm.S)
|
||||||
rm -f $(CLEAN-OBJS)
|
rm -f $(CLEAN-OBJS)
|
||||||
|
|
||||||
.PHONY: clean
|
.PHONY: clean
|
||||||
@@ -119,29 +119,25 @@ utiltest:
|
|||||||
test-no-data-check::
|
test-no-data-check::
|
||||||
exampletest-no-data-check utiltest-no-data-check:
|
exampletest-no-data-check utiltest-no-data-check:
|
||||||
|
|
||||||
# Add compiler flags for intrinsic files
|
# Force to realign stack always on OS/2
|
||||||
ifeq ($(TOOLCHAIN), x86-os2-gcc)
|
ifeq ($(TOOLCHAIN), x86-os2-gcc)
|
||||||
STACKREALIGN=-mstackrealign
|
CFLAGS += -mstackrealign
|
||||||
else
|
|
||||||
STACKREALIGN=
|
|
||||||
endif
|
endif
|
||||||
|
|
||||||
$(BUILD_PFX)%_mmx.c.d: CFLAGS += -mmmx
|
$(BUILD_PFX)%_mmx.c.d: CFLAGS += -mmmx
|
||||||
$(BUILD_PFX)%_mmx.c.o: CFLAGS += -mmmx
|
$(BUILD_PFX)%_mmx.c.o: CFLAGS += -mmmx
|
||||||
$(BUILD_PFX)%_sse2.c.d: CFLAGS += -msse2 $(STACKREALIGN)
|
$(BUILD_PFX)%_sse2.c.d: CFLAGS += -msse2
|
||||||
$(BUILD_PFX)%_sse2.c.o: CFLAGS += -msse2 $(STACKREALIGN)
|
$(BUILD_PFX)%_sse2.c.o: CFLAGS += -msse2
|
||||||
$(BUILD_PFX)%_sse3.c.d: CFLAGS += -msse3 $(STACKREALIGN)
|
$(BUILD_PFX)%_sse3.c.d: CFLAGS += -msse3
|
||||||
$(BUILD_PFX)%_sse3.c.o: CFLAGS += -msse3 $(STACKREALIGN)
|
$(BUILD_PFX)%_sse3.c.o: CFLAGS += -msse3
|
||||||
$(BUILD_PFX)%_ssse3.c.d: CFLAGS += -mssse3 $(STACKREALIGN)
|
$(BUILD_PFX)%_ssse3.c.d: CFLAGS += -mssse3
|
||||||
$(BUILD_PFX)%_ssse3.c.o: CFLAGS += -mssse3 $(STACKREALIGN)
|
$(BUILD_PFX)%_ssse3.c.o: CFLAGS += -mssse3
|
||||||
$(BUILD_PFX)%_sse4.c.d: CFLAGS += -msse4.1 $(STACKREALIGN)
|
$(BUILD_PFX)%_sse4.c.d: CFLAGS += -msse4.1
|
||||||
$(BUILD_PFX)%_sse4.c.o: CFLAGS += -msse4.1 $(STACKREALIGN)
|
$(BUILD_PFX)%_sse4.c.o: CFLAGS += -msse4.1
|
||||||
$(BUILD_PFX)%_avx.c.d: CFLAGS += -mavx $(STACKREALIGN)
|
$(BUILD_PFX)%_avx.c.d: CFLAGS += -mavx
|
||||||
$(BUILD_PFX)%_avx.c.o: CFLAGS += -mavx $(STACKREALIGN)
|
$(BUILD_PFX)%_avx.c.o: CFLAGS += -mavx
|
||||||
$(BUILD_PFX)%_avx2.c.d: CFLAGS += -mavx2 $(STACKREALIGN)
|
$(BUILD_PFX)%_avx2.c.d: CFLAGS += -mavx2
|
||||||
$(BUILD_PFX)%_avx2.c.o: CFLAGS += -mavx2 $(STACKREALIGN)
|
$(BUILD_PFX)%_avx2.c.o: CFLAGS += -mavx2
|
||||||
$(BUILD_PFX)%vp9_reconintra.c.d: CFLAGS += $(STACKREALIGN)
|
|
||||||
$(BUILD_PFX)%vp9_reconintra.c.o: CFLAGS += $(STACKREALIGN)
|
|
||||||
|
|
||||||
$(BUILD_PFX)%.c.d: %.c
|
$(BUILD_PFX)%.c.d: %.c
|
||||||
$(if $(quiet),@echo " [DEP] $@")
|
$(if $(quiet),@echo " [DEP] $@")
|
||||||
@@ -184,13 +180,13 @@ $(BUILD_PFX)%.asm.o: %.asm
|
|||||||
$(qexec)$(if $(CONFIG_DEPENDENCY_TRACKING),,mkdir -p $(dir $@))
|
$(qexec)$(if $(CONFIG_DEPENDENCY_TRACKING),,mkdir -p $(dir $@))
|
||||||
$(qexec)$(AS) $(ASFLAGS) -o $@ $<
|
$(qexec)$(AS) $(ASFLAGS) -o $@ $<
|
||||||
|
|
||||||
$(BUILD_PFX)%.s.d: %.s
|
$(BUILD_PFX)%.S.d: %.S
|
||||||
$(if $(quiet),@echo " [DEP] $@")
|
$(if $(quiet),@echo " [DEP] $@")
|
||||||
$(qexec)mkdir -p $(dir $@)
|
$(qexec)mkdir -p $(dir $@)
|
||||||
$(qexec)$(SRC_PATH_BARE)/build/make/gen_asm_deps.sh \
|
$(qexec)$(SRC_PATH_BARE)/build/make/gen_asm_deps.sh \
|
||||||
--build-pfx=$(BUILD_PFX) --depfile=$@ $(ASFLAGS) $< > $@
|
--build-pfx=$(BUILD_PFX) --depfile=$@ $(ASFLAGS) $< > $@
|
||||||
|
|
||||||
$(BUILD_PFX)%.s.o: %.s
|
$(BUILD_PFX)%.S.o: %.S
|
||||||
$(if $(quiet),@echo " [AS] $@")
|
$(if $(quiet),@echo " [AS] $@")
|
||||||
$(qexec)$(if $(CONFIG_DEPENDENCY_TRACKING),,mkdir -p $(dir $@))
|
$(qexec)$(if $(CONFIG_DEPENDENCY_TRACKING),,mkdir -p $(dir $@))
|
||||||
$(qexec)$(AS) $(ASFLAGS) -o $@ $<
|
$(qexec)$(AS) $(ASFLAGS) -o $@ $<
|
||||||
@@ -202,8 +198,8 @@ $(BUILD_PFX)%.c.S: %.c
|
|||||||
$(qexec)$(if $(CONFIG_DEPENDENCY_TRACKING),,mkdir -p $(dir $@))
|
$(qexec)$(if $(CONFIG_DEPENDENCY_TRACKING),,mkdir -p $(dir $@))
|
||||||
$(qexec)$(CC) -S $(CFLAGS) -o $@ $<
|
$(qexec)$(CC) -S $(CFLAGS) -o $@ $<
|
||||||
|
|
||||||
.PRECIOUS: %.asm.s
|
.PRECIOUS: %.asm.S
|
||||||
$(BUILD_PFX)%.asm.s: %.asm
|
$(BUILD_PFX)%.asm.S: %.asm
|
||||||
$(if $(quiet),@echo " [ASM CONVERSION] $@")
|
$(if $(quiet),@echo " [ASM CONVERSION] $@")
|
||||||
$(qexec)mkdir -p $(dir $@)
|
$(qexec)mkdir -p $(dir $@)
|
||||||
$(qexec)$(ASM_CONVERSION) <$< >$@
|
$(qexec)$(ASM_CONVERSION) <$< >$@
|
||||||
@@ -422,7 +418,6 @@ ifneq ($(call enabled,DIST-SRCS),)
|
|||||||
DIST-SRCS-yes += build/make/gen_asm_deps.sh
|
DIST-SRCS-yes += build/make/gen_asm_deps.sh
|
||||||
DIST-SRCS-yes += build/make/Makefile
|
DIST-SRCS-yes += build/make/Makefile
|
||||||
DIST-SRCS-$(CONFIG_MSVS) += build/make/gen_msvs_def.sh
|
DIST-SRCS-$(CONFIG_MSVS) += build/make/gen_msvs_def.sh
|
||||||
DIST-SRCS-$(CONFIG_MSVS) += build/make/gen_msvs_proj.sh
|
|
||||||
DIST-SRCS-$(CONFIG_MSVS) += build/make/gen_msvs_sln.sh
|
DIST-SRCS-$(CONFIG_MSVS) += build/make/gen_msvs_sln.sh
|
||||||
DIST-SRCS-$(CONFIG_MSVS) += build/make/gen_msvs_vcxproj.sh
|
DIST-SRCS-$(CONFIG_MSVS) += build/make/gen_msvs_vcxproj.sh
|
||||||
DIST-SRCS-$(CONFIG_MSVS) += build/make/msvs_common.sh
|
DIST-SRCS-$(CONFIG_MSVS) += build/make/msvs_common.sh
|
||||||
@@ -453,3 +448,5 @@ all: $(BUILD_TARGETS)
|
|||||||
install:: $(INSTALL_TARGETS)
|
install:: $(INSTALL_TARGETS)
|
||||||
dist: $(INSTALL_TARGETS)
|
dist: $(INSTALL_TARGETS)
|
||||||
test::
|
test::
|
||||||
|
|
||||||
|
.SUFFIXES: # Delete default suffix rules
|
||||||
|
|||||||
@@ -138,14 +138,6 @@ while (<STDIN>)
|
|||||||
s/DCD(.*)/.long $1/;
|
s/DCD(.*)/.long $1/;
|
||||||
s/DCB(.*)/.byte $1/;
|
s/DCB(.*)/.byte $1/;
|
||||||
|
|
||||||
# RN to .req
|
|
||||||
if (s/RN\s+([Rr]\d+|lr)/.req $1/)
|
|
||||||
{
|
|
||||||
print;
|
|
||||||
print "$comment_sub$comment\n" if defined $comment;
|
|
||||||
next;
|
|
||||||
}
|
|
||||||
|
|
||||||
# Make function visible to linker, and make additional symbol with
|
# Make function visible to linker, and make additional symbol with
|
||||||
# prepended underscore
|
# prepended underscore
|
||||||
s/EXPORT\s+\|([\$\w]*)\|/.global $1 \n\t.type $1, function/;
|
s/EXPORT\s+\|([\$\w]*)\|/.global $1 \n\t.type $1, function/;
|
||||||
|
|||||||
@@ -18,12 +18,6 @@
|
|||||||
# Usage: cat inputfile | perl ads2gas_apple.pl > outputfile
|
# Usage: cat inputfile | perl ads2gas_apple.pl > outputfile
|
||||||
#
|
#
|
||||||
|
|
||||||
my $chromium = 0;
|
|
||||||
|
|
||||||
foreach my $arg (@ARGV) {
|
|
||||||
$chromium = 1 if ($arg eq "-chromium");
|
|
||||||
}
|
|
||||||
|
|
||||||
print "@ This file was created from a .asm file\n";
|
print "@ This file was created from a .asm file\n";
|
||||||
print "@ using the ads2gas_apple.pl script.\n\n";
|
print "@ using the ads2gas_apple.pl script.\n\n";
|
||||||
print "\t.set WIDE_REFERENCE, 0\n";
|
print "\t.set WIDE_REFERENCE, 0\n";
|
||||||
@@ -126,18 +120,6 @@ while (<STDIN>)
|
|||||||
s/DCD(.*)/.long $1/;
|
s/DCD(.*)/.long $1/;
|
||||||
s/DCB(.*)/.byte $1/;
|
s/DCB(.*)/.byte $1/;
|
||||||
|
|
||||||
# Build a hash of all the register - alias pairs.
|
|
||||||
if (s/(.*)RN(.*)/$1 .req $2/g)
|
|
||||||
{
|
|
||||||
$register_aliases{trim($1)} = trim($2);
|
|
||||||
next;
|
|
||||||
}
|
|
||||||
|
|
||||||
while (($key, $value) = each(%register_aliases))
|
|
||||||
{
|
|
||||||
s/\b$key\b/$value/g;
|
|
||||||
}
|
|
||||||
|
|
||||||
# Make function visible to linker, and make additional symbol with
|
# Make function visible to linker, and make additional symbol with
|
||||||
# prepended underscore
|
# prepended underscore
|
||||||
s/EXPORT\s+\|([\$\w]*)\|/.globl _$1\n\t.globl $1/;
|
s/EXPORT\s+\|([\$\w]*)\|/.globl _$1\n\t.globl $1/;
|
||||||
@@ -218,18 +200,5 @@ while (<STDIN>)
|
|||||||
s/\bMEND\b/.endm/; # No need to tell it where to stop assembling
|
s/\bMEND\b/.endm/; # No need to tell it where to stop assembling
|
||||||
next if /^\s*END\s*$/;
|
next if /^\s*END\s*$/;
|
||||||
|
|
||||||
# Clang used by Chromium differs slightly from clang in XCode in what it
|
|
||||||
# will accept in the assembly.
|
|
||||||
if ($chromium) {
|
|
||||||
s/qsubaddx/qsax/i;
|
|
||||||
s/qaddsubx/qasx/i;
|
|
||||||
s/ldrneb/ldrbne/i;
|
|
||||||
s/ldrneh/ldrhne/i;
|
|
||||||
s/(vqshrun\.s16 .*, \#)0$/${1}8/i;
|
|
||||||
|
|
||||||
# http://llvm.org/bugs/show_bug.cgi?id=16022
|
|
||||||
s/\.include/#include/;
|
|
||||||
}
|
|
||||||
|
|
||||||
print;
|
print;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -185,6 +185,7 @@ add_extralibs() {
|
|||||||
#
|
#
|
||||||
# Boolean Manipulation Functions
|
# Boolean Manipulation Functions
|
||||||
#
|
#
|
||||||
|
|
||||||
enable_feature(){
|
enable_feature(){
|
||||||
set_all yes $*
|
set_all yes $*
|
||||||
}
|
}
|
||||||
@@ -201,6 +202,20 @@ disabled(){
|
|||||||
eval test "x\$$1" = "xno"
|
eval test "x\$$1" = "xno"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
enable_codec(){
|
||||||
|
enabled "${1}" || echo " enabling ${1}"
|
||||||
|
enable_feature "${1}"
|
||||||
|
|
||||||
|
is_in "${1}" vp8 vp9 && enable_feature "${1}_encoder" "${1}_decoder"
|
||||||
|
}
|
||||||
|
|
||||||
|
disable_codec(){
|
||||||
|
disabled "${1}" || echo " disabling ${1}"
|
||||||
|
disable_feature "${1}"
|
||||||
|
|
||||||
|
is_in "${1}" vp8 vp9 && disable_feature "${1}_encoder" "${1}_decoder"
|
||||||
|
}
|
||||||
|
|
||||||
# Iterates through positional parameters, checks to confirm the parameter has
|
# Iterates through positional parameters, checks to confirm the parameter has
|
||||||
# not been explicitly (force) disabled, and enables the setting controlled by
|
# not been explicitly (force) disabled, and enables the setting controlled by
|
||||||
# the parameter when the setting is not disabled.
|
# the parameter when the setting is not disabled.
|
||||||
@@ -521,22 +536,20 @@ process_common_cmdline() {
|
|||||||
;;
|
;;
|
||||||
--enable-?*|--disable-?*)
|
--enable-?*|--disable-?*)
|
||||||
eval `echo "$opt" | sed 's/--/action=/;s/-/ option=/;s/-/_/g'`
|
eval `echo "$opt" | sed 's/--/action=/;s/-/ option=/;s/-/_/g'`
|
||||||
if echo "${ARCH_EXT_LIST}" | grep "^ *$option\$" >/dev/null; then
|
if is_in ${option} ${ARCH_EXT_LIST}; then
|
||||||
[ $action = "disable" ] && RTCD_OPTIONS="${RTCD_OPTIONS}--disable-${option} "
|
[ $action = "disable" ] && RTCD_OPTIONS="${RTCD_OPTIONS}--disable-${option} "
|
||||||
elif [ $action = "disable" ] && ! disabled $option ; then
|
elif [ $action = "disable" ] && ! disabled $option ; then
|
||||||
echo "${CMDLINE_SELECT}" | grep "^ *$option\$" >/dev/null ||
|
is_in ${option} ${CMDLINE_SELECT} || die_unknown $opt
|
||||||
die_unknown $opt
|
|
||||||
log_echo " disabling $option"
|
log_echo " disabling $option"
|
||||||
elif [ $action = "enable" ] && ! enabled $option ; then
|
elif [ $action = "enable" ] && ! enabled $option ; then
|
||||||
echo "${CMDLINE_SELECT}" | grep "^ *$option\$" >/dev/null ||
|
is_in ${option} ${CMDLINE_SELECT} || die_unknown $opt
|
||||||
die_unknown $opt
|
|
||||||
log_echo " enabling $option"
|
log_echo " enabling $option"
|
||||||
fi
|
fi
|
||||||
${action}_feature $option
|
${action}_feature $option
|
||||||
;;
|
;;
|
||||||
--require-?*)
|
--require-?*)
|
||||||
eval `echo "$opt" | sed 's/--/action=/;s/-/ option=/;s/-/_/g'`
|
eval `echo "$opt" | sed 's/--/action=/;s/-/ option=/;s/-/_/g'`
|
||||||
if echo "${ARCH_EXT_LIST}" none | grep "^ *$option\$" >/dev/null; then
|
if is_in ${option} ${ARCH_EXT_LIST}; then
|
||||||
RTCD_OPTIONS="${RTCD_OPTIONS}${opt} "
|
RTCD_OPTIONS="${RTCD_OPTIONS}${opt} "
|
||||||
else
|
else
|
||||||
die_unknown $opt
|
die_unknown $opt
|
||||||
@@ -622,7 +635,7 @@ setup_gnu_toolchain() {
|
|||||||
AS=${AS:-${CROSS}as}
|
AS=${AS:-${CROSS}as}
|
||||||
STRIP=${STRIP:-${CROSS}strip}
|
STRIP=${STRIP:-${CROSS}strip}
|
||||||
NM=${NM:-${CROSS}nm}
|
NM=${NM:-${CROSS}nm}
|
||||||
AS_SFX=.s
|
AS_SFX=.S
|
||||||
EXE_SFX=
|
EXE_SFX=
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -638,6 +651,26 @@ show_darwin_sdk_major_version() {
|
|||||||
xcrun --sdk $1 --show-sdk-version 2>/dev/null | cut -d. -f1
|
xcrun --sdk $1 --show-sdk-version 2>/dev/null | cut -d. -f1
|
||||||
}
|
}
|
||||||
|
|
||||||
|
# Print the Xcode version.
|
||||||
|
show_xcode_version() {
|
||||||
|
xcodebuild -version | head -n1 | cut -d' ' -f2
|
||||||
|
}
|
||||||
|
|
||||||
|
# Fails when Xcode version is less than 6.3.
|
||||||
|
check_xcode_minimum_version() {
|
||||||
|
xcode_major=$(show_xcode_version | cut -f1 -d.)
|
||||||
|
xcode_minor=$(show_xcode_version | cut -f2 -d.)
|
||||||
|
xcode_min_major=6
|
||||||
|
xcode_min_minor=3
|
||||||
|
if [ ${xcode_major} -lt ${xcode_min_major} ]; then
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
if [ ${xcode_major} -eq ${xcode_min_major} ] \
|
||||||
|
&& [ ${xcode_minor} -lt ${xcode_min_minor} ]; then
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
process_common_toolchain() {
|
process_common_toolchain() {
|
||||||
if [ -z "$toolchain" ]; then
|
if [ -z "$toolchain" ]; then
|
||||||
gcctarget="${CHOST:-$(gcc -dumpmachine 2> /dev/null)}"
|
gcctarget="${CHOST:-$(gcc -dumpmachine 2> /dev/null)}"
|
||||||
@@ -647,9 +680,6 @@ process_common_toolchain() {
|
|||||||
aarch64*)
|
aarch64*)
|
||||||
tgt_isa=arm64
|
tgt_isa=arm64
|
||||||
;;
|
;;
|
||||||
armv6*)
|
|
||||||
tgt_isa=armv6
|
|
||||||
;;
|
|
||||||
armv7*-hardfloat* | armv7*-gnueabihf | arm-*-gnueabihf)
|
armv7*-hardfloat* | armv7*-gnueabihf | arm-*-gnueabihf)
|
||||||
tgt_isa=armv7
|
tgt_isa=armv7
|
||||||
float_abi=hard
|
float_abi=hard
|
||||||
@@ -751,7 +781,14 @@ process_common_toolchain() {
|
|||||||
enabled shared && soft_enable pic
|
enabled shared && soft_enable pic
|
||||||
|
|
||||||
# Minimum iOS version for all target platforms (darwin and iphonesimulator).
|
# Minimum iOS version for all target platforms (darwin and iphonesimulator).
|
||||||
|
# Shared library framework builds are only possible on iOS 8 and later.
|
||||||
|
if enabled shared; then
|
||||||
|
IOS_VERSION_OPTIONS="--enable-shared"
|
||||||
|
IOS_VERSION_MIN="8.0"
|
||||||
|
else
|
||||||
|
IOS_VERSION_OPTIONS=""
|
||||||
IOS_VERSION_MIN="6.0"
|
IOS_VERSION_MIN="6.0"
|
||||||
|
fi
|
||||||
|
|
||||||
# Handle darwin variants. Newer SDKs allow targeting older
|
# Handle darwin variants. Newer SDKs allow targeting older
|
||||||
# platforms, so use the newest one available.
|
# platforms, so use the newest one available.
|
||||||
@@ -843,36 +880,6 @@ process_common_toolchain() {
|
|||||||
if disabled neon && enabled neon_asm; then
|
if disabled neon && enabled neon_asm; then
|
||||||
die "Disabling neon while keeping neon-asm is not supported"
|
die "Disabling neon while keeping neon-asm is not supported"
|
||||||
fi
|
fi
|
||||||
case ${toolchain} in
|
|
||||||
# Apple iOS SDKs no longer support armv6 as of the version 9
|
|
||||||
# release (coincides with release of Xcode 7). Only enable media
|
|
||||||
# when using earlier SDK releases.
|
|
||||||
*-darwin*)
|
|
||||||
if [ "$(show_darwin_sdk_major_version iphoneos)" -lt 9 ]; then
|
|
||||||
soft_enable media
|
|
||||||
else
|
|
||||||
soft_disable media
|
|
||||||
RTCD_OPTIONS="${RTCD_OPTIONS}--disable-media "
|
|
||||||
fi
|
|
||||||
;;
|
|
||||||
*)
|
|
||||||
soft_enable media
|
|
||||||
;;
|
|
||||||
esac
|
|
||||||
;;
|
|
||||||
armv6)
|
|
||||||
case ${toolchain} in
|
|
||||||
*-darwin*)
|
|
||||||
if [ "$(show_darwin_sdk_major_version iphoneos)" -lt 9 ]; then
|
|
||||||
soft_enable media
|
|
||||||
else
|
|
||||||
die "Your iOS SDK does not support armv6."
|
|
||||||
fi
|
|
||||||
;;
|
|
||||||
*)
|
|
||||||
soft_enable media
|
|
||||||
;;
|
|
||||||
esac
|
|
||||||
;;
|
;;
|
||||||
esac
|
esac
|
||||||
|
|
||||||
@@ -901,6 +908,9 @@ EOF
|
|||||||
check_add_cflags -mfpu=neon #-ftree-vectorize
|
check_add_cflags -mfpu=neon #-ftree-vectorize
|
||||||
check_add_asflags -mfpu=neon
|
check_add_asflags -mfpu=neon
|
||||||
fi
|
fi
|
||||||
|
elif [ ${tgt_isa} = "arm64" ] || [ ${tgt_isa} = "armv8" ]; then
|
||||||
|
check_add_cflags -march=armv8-a
|
||||||
|
check_add_asflags -march=armv8-a
|
||||||
else
|
else
|
||||||
check_add_cflags -march=${tgt_isa}
|
check_add_cflags -march=${tgt_isa}
|
||||||
check_add_asflags -march=${tgt_isa}
|
check_add_asflags -march=${tgt_isa}
|
||||||
@@ -916,7 +926,7 @@ EOF
|
|||||||
;;
|
;;
|
||||||
vs*)
|
vs*)
|
||||||
asm_conversion_cmd="${source_path}/build/make/ads2armasm_ms.pl"
|
asm_conversion_cmd="${source_path}/build/make/ads2armasm_ms.pl"
|
||||||
AS_SFX=.s
|
AS_SFX=.S
|
||||||
msvs_arch_dir=arm-msvs
|
msvs_arch_dir=arm-msvs
|
||||||
disable_feature multithread
|
disable_feature multithread
|
||||||
disable_feature unit_tests
|
disable_feature unit_tests
|
||||||
@@ -926,6 +936,7 @@ EOF
|
|||||||
# only "AppContainerApplication" which requires an AppxManifest.
|
# only "AppContainerApplication" which requires an AppxManifest.
|
||||||
# Therefore disable the examples, just build the library.
|
# Therefore disable the examples, just build the library.
|
||||||
disable_feature examples
|
disable_feature examples
|
||||||
|
disable_feature tools
|
||||||
fi
|
fi
|
||||||
;;
|
;;
|
||||||
rvct)
|
rvct)
|
||||||
@@ -968,6 +979,7 @@ EOF
|
|||||||
;;
|
;;
|
||||||
|
|
||||||
android*)
|
android*)
|
||||||
|
if [ -n "${sdk_path}" ]; then
|
||||||
SDK_PATH=${sdk_path}
|
SDK_PATH=${sdk_path}
|
||||||
COMPILER_LOCATION=`find "${SDK_PATH}" \
|
COMPILER_LOCATION=`find "${SDK_PATH}" \
|
||||||
-name "arm-linux-androideabi-gcc*" -print -quit`
|
-name "arm-linux-androideabi-gcc*" -print -quit`
|
||||||
@@ -1006,6 +1018,12 @@ EOF
|
|||||||
if enabled runtime_cpu_detect; then
|
if enabled runtime_cpu_detect; then
|
||||||
add_cflags "-I${SDK_PATH}/sources/android/cpufeatures"
|
add_cflags "-I${SDK_PATH}/sources/android/cpufeatures"
|
||||||
fi
|
fi
|
||||||
|
else
|
||||||
|
echo "Assuming standalone build with NDK toolchain."
|
||||||
|
echo "See build/make/Android.mk for details."
|
||||||
|
check_add_ldflags -static
|
||||||
|
soft_enable unit_tests
|
||||||
|
fi
|
||||||
;;
|
;;
|
||||||
|
|
||||||
darwin*)
|
darwin*)
|
||||||
@@ -1017,7 +1035,7 @@ EOF
|
|||||||
STRIP="$(${XCRUN_FIND} strip)"
|
STRIP="$(${XCRUN_FIND} strip)"
|
||||||
NM="$(${XCRUN_FIND} nm)"
|
NM="$(${XCRUN_FIND} nm)"
|
||||||
RANLIB="$(${XCRUN_FIND} ranlib)"
|
RANLIB="$(${XCRUN_FIND} ranlib)"
|
||||||
AS_SFX=.s
|
AS_SFX=.S
|
||||||
LD="${CXX:-$(${XCRUN_FIND} ld)}"
|
LD="${CXX:-$(${XCRUN_FIND} ld)}"
|
||||||
|
|
||||||
# ASFLAGS is written here instead of using check_add_asflags
|
# ASFLAGS is written here instead of using check_add_asflags
|
||||||
@@ -1044,6 +1062,19 @@ EOF
|
|||||||
[ -d "${try_dir}" ] && add_ldflags -L"${try_dir}"
|
[ -d "${try_dir}" ] && add_ldflags -L"${try_dir}"
|
||||||
done
|
done
|
||||||
|
|
||||||
|
case ${tgt_isa} in
|
||||||
|
armv7|armv7s|armv8|arm64)
|
||||||
|
if enabled neon && ! check_xcode_minimum_version; then
|
||||||
|
soft_disable neon
|
||||||
|
log_echo " neon disabled: upgrade Xcode (need v6.3+)."
|
||||||
|
if enabled neon_asm; then
|
||||||
|
soft_disable neon_asm
|
||||||
|
log_echo " neon_asm disabled: upgrade Xcode (need v6.3+)."
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
|
||||||
asm_conversion_cmd="${source_path}/build/make/ads2gas_apple.pl"
|
asm_conversion_cmd="${source_path}/build/make/ads2gas_apple.pl"
|
||||||
|
|
||||||
if [ "$(show_darwin_sdk_major_version iphoneos)" -gt 8 ]; then
|
if [ "$(show_darwin_sdk_major_version iphoneos)" -gt 8 ]; then
|
||||||
@@ -1093,13 +1124,13 @@ EOF
|
|||||||
if [ -n "${tune_cpu}" ]; then
|
if [ -n "${tune_cpu}" ]; then
|
||||||
case ${tune_cpu} in
|
case ${tune_cpu} in
|
||||||
p5600)
|
p5600)
|
||||||
check_add_cflags -mips32r5 -funroll-loops -mload-store-pairs
|
check_add_cflags -mips32r5 -mload-store-pairs
|
||||||
check_add_cflags -msched-weight -mhard-float -mfp64
|
check_add_cflags -msched-weight -mhard-float -mfp64
|
||||||
check_add_asflags -mips32r5 -mhard-float -mfp64
|
check_add_asflags -mips32r5 -mhard-float -mfp64
|
||||||
check_add_ldflags -mfp64
|
check_add_ldflags -mfp64
|
||||||
;;
|
;;
|
||||||
i6400)
|
i6400|p6600)
|
||||||
check_add_cflags -mips64r6 -mabi=64 -funroll-loops -msched-weight
|
check_add_cflags -mips64r6 -mabi=64 -msched-weight
|
||||||
check_add_cflags -mload-store-pairs -mhard-float -mfp64
|
check_add_cflags -mload-store-pairs -mhard-float -mfp64
|
||||||
check_add_asflags -mips64r6 -mabi=64 -mhard-float -mfp64
|
check_add_asflags -mips64r6 -mabi=64 -mhard-float -mfp64
|
||||||
check_add_ldflags -mips64r6 -mabi=64 -mfp64
|
check_add_ldflags -mips64r6 -mabi=64 -mfp64
|
||||||
@@ -1336,10 +1367,6 @@ EOF
|
|||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if [ "${tgt_isa}" = "x86_64" ] || [ "${tgt_isa}" = "x86" ]; then
|
|
||||||
soft_enable use_x86inc
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Position Independent Code (PIC) support, for building relocatable
|
# Position Independent Code (PIC) support, for building relocatable
|
||||||
# shared objects
|
# shared objects
|
||||||
enabled gcc && enabled pic && check_add_cflags -fPIC
|
enabled gcc && enabled pic && check_add_cflags -fPIC
|
||||||
@@ -1369,6 +1396,7 @@ EOF
|
|||||||
*-win*-vs*)
|
*-win*-vs*)
|
||||||
;;
|
;;
|
||||||
*-android-gcc)
|
*-android-gcc)
|
||||||
|
# bionic includes basic pthread functionality, obviating -lpthread.
|
||||||
;;
|
;;
|
||||||
*)
|
*)
|
||||||
check_header pthread.h && add_extralibs -lpthread
|
check_header pthread.h && add_extralibs -lpthread
|
||||||
|
|||||||
@@ -1,490 +0,0 @@
|
|||||||
#!/bin/bash
|
|
||||||
##
|
|
||||||
## Copyright (c) 2010 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.
|
|
||||||
##
|
|
||||||
|
|
||||||
self=$0
|
|
||||||
self_basename=${self##*/}
|
|
||||||
self_dirname=$(dirname "$0")
|
|
||||||
|
|
||||||
. "$self_dirname/msvs_common.sh"|| exit 127
|
|
||||||
|
|
||||||
show_help() {
|
|
||||||
cat <<EOF
|
|
||||||
Usage: ${self_basename} --name=projname [options] file1 [file2 ...]
|
|
||||||
|
|
||||||
This script generates a Visual Studio project file from a list of source
|
|
||||||
code files.
|
|
||||||
|
|
||||||
Options:
|
|
||||||
--help Print this message
|
|
||||||
--exe Generate a project for building an Application
|
|
||||||
--lib Generate a project for creating a static library
|
|
||||||
--dll Generate a project for creating a dll
|
|
||||||
--static-crt Use the static C runtime (/MT)
|
|
||||||
--target=isa-os-cc Target specifier (required)
|
|
||||||
--out=filename Write output to a file [stdout]
|
|
||||||
--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 (7,8,9) 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
|
|
||||||
-Lpath/to/lib Additional library search paths
|
|
||||||
-llibname Library to link against
|
|
||||||
EOF
|
|
||||||
exit 1
|
|
||||||
}
|
|
||||||
|
|
||||||
generate_filter() {
|
|
||||||
local var=$1
|
|
||||||
local name=$2
|
|
||||||
local pats=$3
|
|
||||||
local file_list_sz
|
|
||||||
local i
|
|
||||||
local f
|
|
||||||
local saveIFS="$IFS"
|
|
||||||
local pack
|
|
||||||
echo "generating filter '$name' from ${#file_list[@]} files" >&2
|
|
||||||
IFS=*
|
|
||||||
|
|
||||||
open_tag Filter \
|
|
||||||
Name=$name \
|
|
||||||
Filter=$pats \
|
|
||||||
UniqueIdentifier=`generate_uuid` \
|
|
||||||
|
|
||||||
file_list_sz=${#file_list[@]}
|
|
||||||
for i in ${!file_list[@]}; do
|
|
||||||
f=${file_list[i]}
|
|
||||||
for pat in ${pats//;/$IFS}; do
|
|
||||||
if [ "${f##*.}" == "$pat" ]; then
|
|
||||||
unset file_list[i]
|
|
||||||
|
|
||||||
objf=$(echo ${f%.*}.obj \
|
|
||||||
| sed -e "s,$src_path_bare,," \
|
|
||||||
-e 's/^[\./]\+//g' -e 's,[:/ ],_,g')
|
|
||||||
open_tag File RelativePath="$f"
|
|
||||||
|
|
||||||
if [ "$pat" == "asm" ] && $asm_use_custom_step; then
|
|
||||||
# Avoid object file name collisions, i.e. vpx_config.c and
|
|
||||||
# vpx_config.asm produce the same object file without
|
|
||||||
# this additional suffix.
|
|
||||||
objf=${objf%.obj}_asm.obj
|
|
||||||
for plat in "${platforms[@]}"; do
|
|
||||||
for cfg in Debug Release; do
|
|
||||||
open_tag FileConfiguration \
|
|
||||||
Name="${cfg}|${plat}" \
|
|
||||||
|
|
||||||
tag Tool \
|
|
||||||
Name="VCCustomBuildTool" \
|
|
||||||
Description="Assembling \$(InputFileName)" \
|
|
||||||
CommandLine="$(eval echo \$asm_${cfg}_cmdline) -o \$(IntDir)\\$objf" \
|
|
||||||
Outputs="\$(IntDir)\\$objf" \
|
|
||||||
|
|
||||||
close_tag FileConfiguration
|
|
||||||
done
|
|
||||||
done
|
|
||||||
fi
|
|
||||||
if [ "$pat" == "c" ] || \
|
|
||||||
[ "$pat" == "cc" ] || [ "$pat" == "cpp" ]; then
|
|
||||||
for plat in "${platforms[@]}"; do
|
|
||||||
for cfg in Debug Release; do
|
|
||||||
open_tag FileConfiguration \
|
|
||||||
Name="${cfg}|${plat}" \
|
|
||||||
|
|
||||||
tag Tool \
|
|
||||||
Name="VCCLCompilerTool" \
|
|
||||||
ObjectFile="\$(IntDir)\\$objf" \
|
|
||||||
|
|
||||||
close_tag FileConfiguration
|
|
||||||
done
|
|
||||||
done
|
|
||||||
fi
|
|
||||||
close_tag File
|
|
||||||
|
|
||||||
break
|
|
||||||
fi
|
|
||||||
done
|
|
||||||
done
|
|
||||||
|
|
||||||
close_tag Filter
|
|
||||||
IFS="$saveIFS"
|
|
||||||
}
|
|
||||||
|
|
||||||
# Process command line
|
|
||||||
unset target
|
|
||||||
for opt in "$@"; do
|
|
||||||
optval="${opt#*=}"
|
|
||||||
case "$opt" in
|
|
||||||
--help|-h) show_help
|
|
||||||
;;
|
|
||||||
--target=*) target="${optval}"
|
|
||||||
;;
|
|
||||||
--out=*) outfile="$optval"
|
|
||||||
;;
|
|
||||||
--name=*) name="${optval}"
|
|
||||||
;;
|
|
||||||
--proj-guid=*) guid="${optval}"
|
|
||||||
;;
|
|
||||||
--module-def=*) link_opts="${link_opts} ModuleDefinitionFile=${optval}"
|
|
||||||
;;
|
|
||||||
--exe) proj_kind="exe"
|
|
||||||
;;
|
|
||||||
--dll) proj_kind="dll"
|
|
||||||
;;
|
|
||||||
--lib) proj_kind="lib"
|
|
||||||
;;
|
|
||||||
--src-path-bare=*)
|
|
||||||
src_path_bare=$(fix_path "$optval")
|
|
||||||
src_path_bare=${src_path_bare%/}
|
|
||||||
;;
|
|
||||||
--static-crt) use_static_runtime=true
|
|
||||||
;;
|
|
||||||
--ver=*)
|
|
||||||
vs_ver="$optval"
|
|
||||||
case "$optval" in
|
|
||||||
[789])
|
|
||||||
;;
|
|
||||||
*) die Unrecognized Visual Studio Version in $opt
|
|
||||||
;;
|
|
||||||
esac
|
|
||||||
;;
|
|
||||||
-I*)
|
|
||||||
opt=${opt##-I}
|
|
||||||
opt=$(fix_path "$opt")
|
|
||||||
opt="${opt%/}"
|
|
||||||
incs="${incs}${incs:+;}"${opt}""
|
|
||||||
yasmincs="${yasmincs} -I"${opt}""
|
|
||||||
;;
|
|
||||||
-D*) defines="${defines}${defines:+;}${opt##-D}"
|
|
||||||
;;
|
|
||||||
-L*) # fudge . to $(OutDir)
|
|
||||||
if [ "${opt##-L}" == "." ]; then
|
|
||||||
libdirs="${libdirs}${libdirs:+;}"\$(OutDir)""
|
|
||||||
else
|
|
||||||
# Also try directories for this platform/configuration
|
|
||||||
opt=${opt##-L}
|
|
||||||
opt=$(fix_path "$opt")
|
|
||||||
libdirs="${libdirs}${libdirs:+;}"${opt}""
|
|
||||||
libdirs="${libdirs}${libdirs:+;}"${opt}/\$(PlatformName)/\$(ConfigurationName)""
|
|
||||||
libdirs="${libdirs}${libdirs:+;}"${opt}/\$(PlatformName)""
|
|
||||||
fi
|
|
||||||
;;
|
|
||||||
-l*) libs="${libs}${libs:+ }${opt##-l}.lib"
|
|
||||||
;;
|
|
||||||
-*) die_unknown $opt
|
|
||||||
;;
|
|
||||||
*)
|
|
||||||
# The paths in file_list are fixed outside of the loop.
|
|
||||||
file_list[${#file_list[@]}]="$opt"
|
|
||||||
case "$opt" in
|
|
||||||
*.asm) uses_asm=true
|
|
||||||
;;
|
|
||||||
esac
|
|
||||||
;;
|
|
||||||
esac
|
|
||||||
done
|
|
||||||
|
|
||||||
# Make one call to fix_path for file_list to improve performance.
|
|
||||||
fix_file_list file_list
|
|
||||||
|
|
||||||
outfile=${outfile:-/dev/stdout}
|
|
||||||
guid=${guid:-`generate_uuid`}
|
|
||||||
asm_use_custom_step=false
|
|
||||||
uses_asm=${uses_asm:-false}
|
|
||||||
case "${vs_ver:-8}" in
|
|
||||||
7) vs_ver_id="7.10"
|
|
||||||
asm_use_custom_step=$uses_asm
|
|
||||||
warn_64bit='Detect64BitPortabilityProblems=true'
|
|
||||||
;;
|
|
||||||
8) vs_ver_id="8.00"
|
|
||||||
asm_use_custom_step=$uses_asm
|
|
||||||
warn_64bit='Detect64BitPortabilityProblems=true'
|
|
||||||
;;
|
|
||||||
9) vs_ver_id="9.00"
|
|
||||||
asm_use_custom_step=$uses_asm
|
|
||||||
warn_64bit='Detect64BitPortabilityProblems=false'
|
|
||||||
;;
|
|
||||||
esac
|
|
||||||
|
|
||||||
[ -n "$name" ] || die "Project name (--name) must be specified!"
|
|
||||||
[ -n "$target" ] || die "Target (--target) must be specified!"
|
|
||||||
|
|
||||||
if ${use_static_runtime:-false}; then
|
|
||||||
release_runtime=0
|
|
||||||
debug_runtime=1
|
|
||||||
lib_sfx=mt
|
|
||||||
else
|
|
||||||
release_runtime=2
|
|
||||||
debug_runtime=3
|
|
||||||
lib_sfx=md
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Calculate debug lib names: If a lib ends in ${lib_sfx}.lib, then rename
|
|
||||||
# it to ${lib_sfx}d.lib. This precludes linking to release libs from a
|
|
||||||
# debug exe, so this may need to be refactored later.
|
|
||||||
for lib in ${libs}; do
|
|
||||||
if [ "$lib" != "${lib%${lib_sfx}.lib}" ]; then
|
|
||||||
lib=${lib%.lib}d.lib
|
|
||||||
fi
|
|
||||||
debug_libs="${debug_libs}${debug_libs:+ }${lib}"
|
|
||||||
done
|
|
||||||
|
|
||||||
|
|
||||||
# List Keyword for this target
|
|
||||||
case "$target" in
|
|
||||||
x86*) keyword="ManagedCProj"
|
|
||||||
;;
|
|
||||||
*) die "Unsupported target $target!"
|
|
||||||
esac
|
|
||||||
|
|
||||||
# List of all platforms supported for this target
|
|
||||||
case "$target" in
|
|
||||||
x86_64*)
|
|
||||||
platforms[0]="x64"
|
|
||||||
asm_Debug_cmdline="yasm -Xvc -g cv8 -f win64 ${yasmincs} "\$(InputPath)""
|
|
||||||
asm_Release_cmdline="yasm -Xvc -f win64 ${yasmincs} "\$(InputPath)""
|
|
||||||
;;
|
|
||||||
x86*)
|
|
||||||
platforms[0]="Win32"
|
|
||||||
asm_Debug_cmdline="yasm -Xvc -g cv8 -f win32 ${yasmincs} "\$(InputPath)""
|
|
||||||
asm_Release_cmdline="yasm -Xvc -f win32 ${yasmincs} "\$(InputPath)""
|
|
||||||
;;
|
|
||||||
*) die "Unsupported target $target!"
|
|
||||||
;;
|
|
||||||
esac
|
|
||||||
|
|
||||||
generate_vcproj() {
|
|
||||||
case "$proj_kind" in
|
|
||||||
exe) vs_ConfigurationType=1
|
|
||||||
;;
|
|
||||||
dll) vs_ConfigurationType=2
|
|
||||||
;;
|
|
||||||
*) vs_ConfigurationType=4
|
|
||||||
;;
|
|
||||||
esac
|
|
||||||
|
|
||||||
echo "<?xml version=\"1.0\" encoding=\"Windows-1252\"?>"
|
|
||||||
open_tag VisualStudioProject \
|
|
||||||
ProjectType="Visual C++" \
|
|
||||||
Version="${vs_ver_id}" \
|
|
||||||
Name="${name}" \
|
|
||||||
ProjectGUID="{${guid}}" \
|
|
||||||
RootNamespace="${name}" \
|
|
||||||
Keyword="${keyword}" \
|
|
||||||
|
|
||||||
open_tag Platforms
|
|
||||||
for plat in "${platforms[@]}"; do
|
|
||||||
tag Platform Name="$plat"
|
|
||||||
done
|
|
||||||
close_tag Platforms
|
|
||||||
|
|
||||||
open_tag Configurations
|
|
||||||
for plat in "${platforms[@]}"; do
|
|
||||||
plat_no_ws=`echo $plat | sed 's/[^A-Za-z0-9_]/_/g'`
|
|
||||||
open_tag Configuration \
|
|
||||||
Name="Debug|$plat" \
|
|
||||||
OutputDirectory="\$(SolutionDir)$plat_no_ws/\$(ConfigurationName)" \
|
|
||||||
IntermediateDirectory="$plat_no_ws/\$(ConfigurationName)/${name}" \
|
|
||||||
ConfigurationType="$vs_ConfigurationType" \
|
|
||||||
CharacterSet="1" \
|
|
||||||
|
|
||||||
case "$target" in
|
|
||||||
x86*)
|
|
||||||
case "$name" in
|
|
||||||
vpx)
|
|
||||||
tag Tool \
|
|
||||||
Name="VCCLCompilerTool" \
|
|
||||||
Optimization="0" \
|
|
||||||
AdditionalIncludeDirectories="$incs" \
|
|
||||||
PreprocessorDefinitions="WIN32;_DEBUG;_CRT_SECURE_NO_WARNINGS;_CRT_SECURE_NO_DEPRECATE;$defines" \
|
|
||||||
RuntimeLibrary="$debug_runtime" \
|
|
||||||
UsePrecompiledHeader="0" \
|
|
||||||
WarningLevel="3" \
|
|
||||||
DebugInformationFormat="2" \
|
|
||||||
$warn_64bit \
|
|
||||||
|
|
||||||
$uses_asm && tag Tool Name="YASM" IncludePaths="$incs" Debug="true"
|
|
||||||
;;
|
|
||||||
*)
|
|
||||||
tag Tool \
|
|
||||||
Name="VCCLCompilerTool" \
|
|
||||||
Optimization="0" \
|
|
||||||
AdditionalIncludeDirectories="$incs" \
|
|
||||||
PreprocessorDefinitions="WIN32;_DEBUG;_CRT_SECURE_NO_WARNINGS;_CRT_SECURE_NO_DEPRECATE;$defines" \
|
|
||||||
RuntimeLibrary="$debug_runtime" \
|
|
||||||
UsePrecompiledHeader="0" \
|
|
||||||
WarningLevel="3" \
|
|
||||||
DebugInformationFormat="2" \
|
|
||||||
$warn_64bit \
|
|
||||||
|
|
||||||
$uses_asm && tag Tool Name="YASM" IncludePaths="$incs" Debug="true"
|
|
||||||
;;
|
|
||||||
esac
|
|
||||||
;;
|
|
||||||
esac
|
|
||||||
|
|
||||||
case "$proj_kind" in
|
|
||||||
exe)
|
|
||||||
case "$target" in
|
|
||||||
x86*)
|
|
||||||
case "$name" in
|
|
||||||
*)
|
|
||||||
tag Tool \
|
|
||||||
Name="VCLinkerTool" \
|
|
||||||
AdditionalDependencies="$debug_libs \$(NoInherit)" \
|
|
||||||
AdditionalLibraryDirectories="$libdirs" \
|
|
||||||
GenerateDebugInformation="true" \
|
|
||||||
ProgramDatabaseFile="\$(OutDir)/${name}.pdb" \
|
|
||||||
;;
|
|
||||||
esac
|
|
||||||
;;
|
|
||||||
esac
|
|
||||||
;;
|
|
||||||
lib)
|
|
||||||
case "$target" in
|
|
||||||
x86*)
|
|
||||||
tag Tool \
|
|
||||||
Name="VCLibrarianTool" \
|
|
||||||
OutputFile="\$(OutDir)/${name}${lib_sfx}d.lib" \
|
|
||||||
|
|
||||||
;;
|
|
||||||
esac
|
|
||||||
;;
|
|
||||||
dll)
|
|
||||||
tag Tool \
|
|
||||||
Name="VCLinkerTool" \
|
|
||||||
AdditionalDependencies="\$(NoInherit)" \
|
|
||||||
LinkIncremental="2" \
|
|
||||||
GenerateDebugInformation="true" \
|
|
||||||
AssemblyDebug="1" \
|
|
||||||
TargetMachine="1" \
|
|
||||||
$link_opts \
|
|
||||||
|
|
||||||
;;
|
|
||||||
esac
|
|
||||||
|
|
||||||
close_tag Configuration
|
|
||||||
|
|
||||||
open_tag Configuration \
|
|
||||||
Name="Release|$plat" \
|
|
||||||
OutputDirectory="\$(SolutionDir)$plat_no_ws/\$(ConfigurationName)" \
|
|
||||||
IntermediateDirectory="$plat_no_ws/\$(ConfigurationName)/${name}" \
|
|
||||||
ConfigurationType="$vs_ConfigurationType" \
|
|
||||||
CharacterSet="1" \
|
|
||||||
WholeProgramOptimization="0" \
|
|
||||||
|
|
||||||
case "$target" in
|
|
||||||
x86*)
|
|
||||||
case "$name" in
|
|
||||||
vpx)
|
|
||||||
tag Tool \
|
|
||||||
Name="VCCLCompilerTool" \
|
|
||||||
Optimization="2" \
|
|
||||||
FavorSizeorSpeed="1" \
|
|
||||||
AdditionalIncludeDirectories="$incs" \
|
|
||||||
PreprocessorDefinitions="WIN32;NDEBUG;_CRT_SECURE_NO_WARNINGS;_CRT_SECURE_NO_DEPRECATE;$defines" \
|
|
||||||
RuntimeLibrary="$release_runtime" \
|
|
||||||
UsePrecompiledHeader="0" \
|
|
||||||
WarningLevel="3" \
|
|
||||||
DebugInformationFormat="0" \
|
|
||||||
$warn_64bit \
|
|
||||||
|
|
||||||
$uses_asm && tag Tool Name="YASM" IncludePaths="$incs"
|
|
||||||
;;
|
|
||||||
*)
|
|
||||||
tag Tool \
|
|
||||||
Name="VCCLCompilerTool" \
|
|
||||||
AdditionalIncludeDirectories="$incs" \
|
|
||||||
Optimization="2" \
|
|
||||||
FavorSizeorSpeed="1" \
|
|
||||||
PreprocessorDefinitions="WIN32;NDEBUG;_CRT_SECURE_NO_WARNINGS;_CRT_SECURE_NO_DEPRECATE;$defines" \
|
|
||||||
RuntimeLibrary="$release_runtime" \
|
|
||||||
UsePrecompiledHeader="0" \
|
|
||||||
WarningLevel="3" \
|
|
||||||
DebugInformationFormat="0" \
|
|
||||||
$warn_64bit \
|
|
||||||
|
|
||||||
$uses_asm && tag Tool Name="YASM" IncludePaths="$incs"
|
|
||||||
;;
|
|
||||||
esac
|
|
||||||
;;
|
|
||||||
esac
|
|
||||||
|
|
||||||
case "$proj_kind" in
|
|
||||||
exe)
|
|
||||||
case "$target" in
|
|
||||||
x86*)
|
|
||||||
case "$name" in
|
|
||||||
*)
|
|
||||||
tag Tool \
|
|
||||||
Name="VCLinkerTool" \
|
|
||||||
AdditionalDependencies="$libs \$(NoInherit)" \
|
|
||||||
AdditionalLibraryDirectories="$libdirs" \
|
|
||||||
|
|
||||||
;;
|
|
||||||
esac
|
|
||||||
;;
|
|
||||||
esac
|
|
||||||
;;
|
|
||||||
lib)
|
|
||||||
case "$target" in
|
|
||||||
x86*)
|
|
||||||
tag Tool \
|
|
||||||
Name="VCLibrarianTool" \
|
|
||||||
OutputFile="\$(OutDir)/${name}${lib_sfx}.lib" \
|
|
||||||
|
|
||||||
;;
|
|
||||||
esac
|
|
||||||
;;
|
|
||||||
dll) # note differences to debug version: LinkIncremental, AssemblyDebug
|
|
||||||
tag Tool \
|
|
||||||
Name="VCLinkerTool" \
|
|
||||||
AdditionalDependencies="\$(NoInherit)" \
|
|
||||||
LinkIncremental="1" \
|
|
||||||
GenerateDebugInformation="true" \
|
|
||||||
TargetMachine="1" \
|
|
||||||
$link_opts \
|
|
||||||
|
|
||||||
;;
|
|
||||||
esac
|
|
||||||
|
|
||||||
close_tag Configuration
|
|
||||||
done
|
|
||||||
close_tag Configurations
|
|
||||||
|
|
||||||
open_tag Files
|
|
||||||
generate_filter srcs "Source Files" "c;cc;cpp;def;odl;idl;hpj;bat;asm;asmx"
|
|
||||||
generate_filter hdrs "Header Files" "h;hm;inl;inc;xsd"
|
|
||||||
generate_filter resrcs "Resource Files" "rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav"
|
|
||||||
generate_filter resrcs "Build Files" "mk"
|
|
||||||
close_tag Files
|
|
||||||
|
|
||||||
tag Globals
|
|
||||||
close_tag VisualStudioProject
|
|
||||||
|
|
||||||
# This must be done from within the {} subshell
|
|
||||||
echo "Ignored files list (${#file_list[@]} items) is:" >&2
|
|
||||||
for f in "${file_list[@]}"; do
|
|
||||||
echo " $f" >&2
|
|
||||||
done
|
|
||||||
}
|
|
||||||
|
|
||||||
generate_vcproj |
|
|
||||||
sed -e '/"/s;\([^ "]\)/;\1\\;g' > ${outfile}
|
|
||||||
|
|
||||||
exit
|
|
||||||
<!--
|
|
||||||
TODO: Add any files not captured by filters.
|
|
||||||
<File
|
|
||||||
RelativePath=".\ReadMe.txt"
|
|
||||||
>
|
|
||||||
</File>
|
|
||||||
-->
|
|
||||||
@@ -55,16 +55,11 @@ indent_pop() {
|
|||||||
|
|
||||||
parse_project() {
|
parse_project() {
|
||||||
local file=$1
|
local file=$1
|
||||||
if [ "$sfx" = "vcproj" ]; then
|
|
||||||
local name=`grep Name "$file" | awk 'BEGIN {FS="\""}{if (NR==1) print $2}'`
|
|
||||||
local guid=`grep ProjectGUID "$file" | awk 'BEGIN {FS="\""}{if (NR==1) print $2}'`
|
|
||||||
else
|
|
||||||
local name=`grep RootNamespace "$file" | sed 's,.*<.*>\(.*\)</.*>.*,\1,'`
|
local name=`grep RootNamespace "$file" | sed 's,.*<.*>\(.*\)</.*>.*,\1,'`
|
||||||
local guid=`grep ProjectGuid "$file" | sed 's,.*<.*>\(.*\)</.*>.*,\1,'`
|
local guid=`grep ProjectGuid "$file" | sed 's,.*<.*>\(.*\)</.*>.*,\1,'`
|
||||||
fi
|
|
||||||
|
|
||||||
# save the project GUID to a varaible, normalizing to the basename of the
|
# save the project GUID to a varaible, normalizing to the basename of the
|
||||||
# vcproj file without the extension
|
# vcxproj file without the extension
|
||||||
local var
|
local var
|
||||||
var=${file##*/}
|
var=${file##*/}
|
||||||
var=${var%%.${sfx}}
|
var=${var%%.${sfx}}
|
||||||
@@ -72,13 +67,8 @@ parse_project() {
|
|||||||
eval "${var}_name=$name"
|
eval "${var}_name=$name"
|
||||||
eval "${var}_guid=$guid"
|
eval "${var}_guid=$guid"
|
||||||
|
|
||||||
if [ "$sfx" = "vcproj" ]; then
|
|
||||||
cur_config_list=`grep -A1 '<Configuration' $file |
|
|
||||||
grep Name | cut -d\" -f2`
|
|
||||||
else
|
|
||||||
cur_config_list=`grep -B1 'Label="Configuration"' $file |
|
cur_config_list=`grep -B1 'Label="Configuration"' $file |
|
||||||
grep Condition | cut -d\' -f4`
|
grep Condition | cut -d\' -f4`
|
||||||
fi
|
|
||||||
new_config_list=$(for i in $config_list $cur_config_list; do
|
new_config_list=$(for i in $config_list $cur_config_list; do
|
||||||
echo $i
|
echo $i
|
||||||
done | sort | uniq)
|
done | sort | uniq)
|
||||||
@@ -103,25 +93,6 @@ process_project() {
|
|||||||
eval "${var}_guid=$guid"
|
eval "${var}_guid=$guid"
|
||||||
|
|
||||||
echo "Project(\"{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}\") = \"$name\", \"$file\", \"$guid\""
|
echo "Project(\"{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}\") = \"$name\", \"$file\", \"$guid\""
|
||||||
indent_push
|
|
||||||
|
|
||||||
eval "local deps=\"\${${var}_deps}\""
|
|
||||||
if [ -n "$deps" ] && [ "$sfx" = "vcproj" ]; then
|
|
||||||
echo "${indent}ProjectSection(ProjectDependencies) = postProject"
|
|
||||||
indent_push
|
|
||||||
|
|
||||||
for dep in $deps; do
|
|
||||||
eval "local dep_guid=\${${dep}_guid}"
|
|
||||||
[ -z "${dep_guid}" ] && die "Unknown GUID for $dep (dependency of $var)"
|
|
||||||
echo "${indent}$dep_guid = $dep_guid"
|
|
||||||
done
|
|
||||||
|
|
||||||
indent_pop
|
|
||||||
echo "${indent}EndProjectSection"
|
|
||||||
|
|
||||||
fi
|
|
||||||
|
|
||||||
indent_pop
|
|
||||||
echo "EndProject"
|
echo "EndProject"
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -191,11 +162,7 @@ process_makefile() {
|
|||||||
IFS=$'\r'$'\n'
|
IFS=$'\r'$'\n'
|
||||||
local TAB=$'\t'
|
local TAB=$'\t'
|
||||||
cat <<EOF
|
cat <<EOF
|
||||||
ifeq (\$(CONFIG_VS_VERSION),7)
|
|
||||||
MSBUILD_TOOL := devenv.com
|
|
||||||
else
|
|
||||||
MSBUILD_TOOL := msbuild.exe
|
MSBUILD_TOOL := msbuild.exe
|
||||||
endif
|
|
||||||
found_devenv := \$(shell which \$(MSBUILD_TOOL) >/dev/null 2>&1 && echo yes)
|
found_devenv := \$(shell which \$(MSBUILD_TOOL) >/dev/null 2>&1 && echo yes)
|
||||||
.nodevenv.once:
|
.nodevenv.once:
|
||||||
${TAB}@echo " * \$(MSBUILD_TOOL) not found in path."
|
${TAB}@echo " * \$(MSBUILD_TOOL) not found in path."
|
||||||
@@ -204,7 +171,7 @@ ${TAB}@echo " * You will have to build all configurations manually using the"
|
|||||||
${TAB}@echo " * Visual Studio IDE. To allow make to build them automatically,"
|
${TAB}@echo " * Visual Studio IDE. To allow make to build them automatically,"
|
||||||
${TAB}@echo " * add the Common7/IDE directory of your Visual Studio"
|
${TAB}@echo " * add the Common7/IDE directory of your Visual Studio"
|
||||||
${TAB}@echo " * installation to your path, eg:"
|
${TAB}@echo " * installation to your path, eg:"
|
||||||
${TAB}@echo " * C:\Program Files\Microsoft Visual Studio 8\Common7\IDE"
|
${TAB}@echo " * C:\Program Files\Microsoft Visual Studio 10.0\Common7\IDE"
|
||||||
${TAB}@echo " * "
|
${TAB}@echo " * "
|
||||||
${TAB}@touch \$@
|
${TAB}@touch \$@
|
||||||
CLEAN-OBJS += \$(if \$(found_devenv),,.nodevenv.once)
|
CLEAN-OBJS += \$(if \$(found_devenv),,.nodevenv.once)
|
||||||
@@ -221,16 +188,9 @@ clean::
|
|||||||
${TAB}rm -rf "$platform"/"$config"
|
${TAB}rm -rf "$platform"/"$config"
|
||||||
.PHONY: $nows_sln_config
|
.PHONY: $nows_sln_config
|
||||||
ifneq (\$(found_devenv),)
|
ifneq (\$(found_devenv),)
|
||||||
ifeq (\$(CONFIG_VS_VERSION),7)
|
|
||||||
$nows_sln_config: $outfile
|
|
||||||
${TAB}\$(MSBUILD_TOOL) $outfile -build "$config"
|
|
||||||
|
|
||||||
else
|
|
||||||
$nows_sln_config: $outfile
|
$nows_sln_config: $outfile
|
||||||
${TAB}\$(MSBUILD_TOOL) $outfile -m -t:Build \\
|
${TAB}\$(MSBUILD_TOOL) $outfile -m -t:Build \\
|
||||||
${TAB}${TAB}-p:Configuration="$config" -p:Platform="$platform"
|
${TAB}${TAB}-p:Configuration="$config" -p:Platform="$platform"
|
||||||
|
|
||||||
endif
|
|
||||||
else
|
else
|
||||||
$nows_sln_config: $outfile .nodevenv.once
|
$nows_sln_config: $outfile .nodevenv.once
|
||||||
${TAB}@echo " * Skipping build of $sln_config (\$(MSBUILD_TOOL) not in path)."
|
${TAB}@echo " * Skipping build of $sln_config (\$(MSBUILD_TOOL) not in path)."
|
||||||
@@ -255,23 +215,12 @@ for opt in "$@"; do
|
|||||||
;;
|
;;
|
||||||
--ver=*) vs_ver="$optval"
|
--ver=*) vs_ver="$optval"
|
||||||
case $optval in
|
case $optval in
|
||||||
[789]|10|11|12|14)
|
10|11|12|14)
|
||||||
;;
|
;;
|
||||||
*) die Unrecognized Visual Studio Version in $opt
|
*) die Unrecognized Visual Studio Version in $opt
|
||||||
;;
|
;;
|
||||||
esac
|
esac
|
||||||
;;
|
;;
|
||||||
--ver=*) vs_ver="$optval"
|
|
||||||
case $optval in
|
|
||||||
7) sln_vers="8.00"
|
|
||||||
sln_vers_str="Visual Studio .NET 2003"
|
|
||||||
;;
|
|
||||||
[89])
|
|
||||||
;;
|
|
||||||
*) die "Unrecognized Visual Studio Version '$optval' in $opt"
|
|
||||||
;;
|
|
||||||
esac
|
|
||||||
;;
|
|
||||||
--target=*) target="${optval}"
|
--target=*) target="${optval}"
|
||||||
;;
|
;;
|
||||||
-*) die_unknown $opt
|
-*) die_unknown $opt
|
||||||
@@ -281,16 +230,7 @@ for opt in "$@"; do
|
|||||||
done
|
done
|
||||||
outfile=${outfile:-/dev/stdout}
|
outfile=${outfile:-/dev/stdout}
|
||||||
mkoutfile=${mkoutfile:-/dev/stdout}
|
mkoutfile=${mkoutfile:-/dev/stdout}
|
||||||
case "${vs_ver:-8}" in
|
case "${vs_ver:-10}" in
|
||||||
7) sln_vers="8.00"
|
|
||||||
sln_vers_str="Visual Studio .NET 2003"
|
|
||||||
;;
|
|
||||||
8) sln_vers="9.00"
|
|
||||||
sln_vers_str="Visual Studio 2005"
|
|
||||||
;;
|
|
||||||
9) sln_vers="10.00"
|
|
||||||
sln_vers_str="Visual Studio 2008"
|
|
||||||
;;
|
|
||||||
10) sln_vers="11.00"
|
10) sln_vers="11.00"
|
||||||
sln_vers_str="Visual Studio 2010"
|
sln_vers_str="Visual Studio 2010"
|
||||||
;;
|
;;
|
||||||
@@ -304,14 +244,7 @@ case "${vs_ver:-8}" in
|
|||||||
sln_vers_str="Visual Studio 2015"
|
sln_vers_str="Visual Studio 2015"
|
||||||
;;
|
;;
|
||||||
esac
|
esac
|
||||||
case "${vs_ver:-8}" in
|
|
||||||
[789])
|
|
||||||
sfx=vcproj
|
|
||||||
;;
|
|
||||||
10|11|12|14)
|
|
||||||
sfx=vcxproj
|
sfx=vcxproj
|
||||||
;;
|
|
||||||
esac
|
|
||||||
|
|
||||||
for f in "${file_list[@]}"; do
|
for f in "${file_list[@]}"; do
|
||||||
parse_project $f
|
parse_project $f
|
||||||
|
|||||||
@@ -82,7 +82,7 @@ generate_filter() {
|
|||||||
| sed -e "s,$src_path_bare,," \
|
| sed -e "s,$src_path_bare,," \
|
||||||
-e 's/^[\./]\+//g' -e 's,[:/ ],_,g')
|
-e 's/^[\./]\+//g' -e 's,[:/ ],_,g')
|
||||||
|
|
||||||
if ([ "$pat" == "asm" ] || [ "$pat" == "s" ]) && $asm_use_custom_step; then
|
if ([ "$pat" == "asm" ] || [ "$pat" == "s" ] || [ "$pat" == "S" ]) && $asm_use_custom_step; then
|
||||||
# Avoid object file name collisions, i.e. vpx_config.c and
|
# Avoid object file name collisions, i.e. vpx_config.c and
|
||||||
# vpx_config.asm produce the same object file without
|
# vpx_config.asm produce the same object file without
|
||||||
# this additional suffix.
|
# this additional suffix.
|
||||||
@@ -203,7 +203,7 @@ for opt in "$@"; do
|
|||||||
# The paths in file_list are fixed outside of the loop.
|
# The paths in file_list are fixed outside of the loop.
|
||||||
file_list[${#file_list[@]}]="$opt"
|
file_list[${#file_list[@]}]="$opt"
|
||||||
case "$opt" in
|
case "$opt" in
|
||||||
*.asm|*.s) uses_asm=true
|
*.asm|*.[Ss]) uses_asm=true
|
||||||
;;
|
;;
|
||||||
esac
|
esac
|
||||||
;;
|
;;
|
||||||
@@ -452,7 +452,7 @@ generate_vcxproj() {
|
|||||||
done
|
done
|
||||||
|
|
||||||
open_tag ItemGroup
|
open_tag ItemGroup
|
||||||
generate_filter "Source Files" "c;cc;cpp;def;odl;idl;hpj;bat;asm;asmx;s"
|
generate_filter "Source Files" "c;cc;cpp;def;odl;idl;hpj;bat;asm;asmx;s;S"
|
||||||
close_tag ItemGroup
|
close_tag ItemGroup
|
||||||
open_tag ItemGroup
|
open_tag ItemGroup
|
||||||
generate_filter "Header Files" "h;hm;inl;inc;xsd"
|
generate_filter "Header Files" "h;hm;inl;inc;xsd"
|
||||||
|
|||||||
37
build/make/ios-Info.plist
Normal file
37
build/make/ios-Info.plist
Normal file
@@ -0,0 +1,37 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||||
|
<plist version="1.0">
|
||||||
|
<dict>
|
||||||
|
<key>CFBundleDevelopmentRegion</key>
|
||||||
|
<string>en</string>
|
||||||
|
<key>CFBundleExecutable</key>
|
||||||
|
<string>VPX</string>
|
||||||
|
<key>CFBundleIdentifier</key>
|
||||||
|
<string>org.webmproject.VPX</string>
|
||||||
|
<key>CFBundleInfoDictionaryVersion</key>
|
||||||
|
<string>6.0</string>
|
||||||
|
<key>CFBundleName</key>
|
||||||
|
<string>VPX</string>
|
||||||
|
<key>CFBundlePackageType</key>
|
||||||
|
<string>FMWK</string>
|
||||||
|
<key>CFBundleShortVersionString</key>
|
||||||
|
<string>${VERSION}</string>
|
||||||
|
<key>CFBundleSignature</key>
|
||||||
|
<string>????</string>
|
||||||
|
<key>CFBundleSupportedPlatforms</key>
|
||||||
|
<array>
|
||||||
|
<string>iPhoneOS</string>
|
||||||
|
</array>
|
||||||
|
<key>CFBundleVersion</key>
|
||||||
|
<string>${VERSION}</string>
|
||||||
|
<key>MinimumOSVersion</key>
|
||||||
|
<string>${IOS_VERSION_MIN}</string>
|
||||||
|
<key>UIDeviceFamily</key>
|
||||||
|
<array>
|
||||||
|
<integer>1</integer>
|
||||||
|
<integer>2</integer>
|
||||||
|
</array>
|
||||||
|
<key>VPXFullVersion</key>
|
||||||
|
<string>${FULLVERSION}</string>
|
||||||
|
</dict>
|
||||||
|
</plist>
|
||||||
@@ -196,7 +196,12 @@ build_framework() {
|
|||||||
for target in ${targets}; do
|
for target in ${targets}; do
|
||||||
build_target "${target}"
|
build_target "${target}"
|
||||||
target_dist_dir="${BUILD_ROOT}/${target}/${DIST_DIR}"
|
target_dist_dir="${BUILD_ROOT}/${target}/${DIST_DIR}"
|
||||||
lib_list="${lib_list} ${target_dist_dir}/lib/libvpx.a"
|
if [ "${ENABLE_SHARED}" = "yes" ]; then
|
||||||
|
local suffix="dylib"
|
||||||
|
else
|
||||||
|
local suffix="a"
|
||||||
|
fi
|
||||||
|
lib_list="${lib_list} ${target_dist_dir}/lib/libvpx.${suffix}"
|
||||||
done
|
done
|
||||||
|
|
||||||
cd "${ORIG_PWD}"
|
cd "${ORIG_PWD}"
|
||||||
@@ -215,6 +220,18 @@ build_framework() {
|
|||||||
# Copy in vpx_version.h.
|
# Copy in vpx_version.h.
|
||||||
cp -p "${BUILD_ROOT}/${target}/vpx_version.h" "${HEADER_DIR}"
|
cp -p "${BUILD_ROOT}/${target}/vpx_version.h" "${HEADER_DIR}"
|
||||||
|
|
||||||
|
if [ "${ENABLE_SHARED}" = "yes" ]; then
|
||||||
|
# Adjust the dylib's name so dynamic linking in apps works as expected.
|
||||||
|
install_name_tool -id '@rpath/VPX.framework/VPX' ${FRAMEWORK_DIR}/VPX
|
||||||
|
|
||||||
|
# Copy in Info.plist.
|
||||||
|
cat "${SCRIPT_DIR}/ios-Info.plist" \
|
||||||
|
| sed "s/\${FULLVERSION}/${FULLVERSION}/g" \
|
||||||
|
| sed "s/\${VERSION}/${VERSION}/g" \
|
||||||
|
| sed "s/\${IOS_VERSION_MIN}/${IOS_VERSION_MIN}/g" \
|
||||||
|
> "${FRAMEWORK_DIR}/Info.plist"
|
||||||
|
fi
|
||||||
|
|
||||||
# Confirm VPX.framework/VPX contains the targets requested.
|
# Confirm VPX.framework/VPX contains the targets requested.
|
||||||
verify_framework_targets ${targets}
|
verify_framework_targets ${targets}
|
||||||
|
|
||||||
@@ -252,6 +269,7 @@ iosbuild_usage() {
|
|||||||
cat << EOF
|
cat << EOF
|
||||||
Usage: ${0##*/} [arguments]
|
Usage: ${0##*/} [arguments]
|
||||||
--help: Display this message and exit.
|
--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.
|
--extra-configure-args <args>: Extra args to pass when configuring libvpx.
|
||||||
--macosx: Uses darwin15 targets instead of iphonesimulator targets for x86
|
--macosx: Uses darwin15 targets instead of iphonesimulator targets for x86
|
||||||
and x86_64. Allows linking to framework when builds target MacOSX
|
and x86_64. Allows linking to framework when builds target MacOSX
|
||||||
@@ -290,6 +308,9 @@ while [ -n "$1" ]; do
|
|||||||
iosbuild_usage
|
iosbuild_usage
|
||||||
exit
|
exit
|
||||||
;;
|
;;
|
||||||
|
--enable-shared)
|
||||||
|
ENABLE_SHARED=yes
|
||||||
|
;;
|
||||||
--preserve-build-output)
|
--preserve-build-output)
|
||||||
PRESERVE_BUILD_OUTPUT=yes
|
PRESERVE_BUILD_OUTPUT=yes
|
||||||
;;
|
;;
|
||||||
@@ -317,6 +338,21 @@ while [ -n "$1" ]; do
|
|||||||
shift
|
shift
|
||||||
done
|
done
|
||||||
|
|
||||||
|
if [ "${ENABLE_SHARED}" = "yes" ]; then
|
||||||
|
CONFIGURE_ARGS="--enable-shared ${CONFIGURE_ARGS}"
|
||||||
|
fi
|
||||||
|
|
||||||
|
FULLVERSION=$("${SCRIPT_DIR}"/version.sh --bare "${LIBVPX_SOURCE_DIR}")
|
||||||
|
VERSION=$(echo "${FULLVERSION}" | sed -E 's/^v([0-9]+\.[0-9]+\.[0-9]+).*$/\1/')
|
||||||
|
|
||||||
|
if [ "$ENABLE_SHARED" = "yes" ]; then
|
||||||
|
IOS_VERSION_OPTIONS="--enable-shared"
|
||||||
|
IOS_VERSION_MIN="8.0"
|
||||||
|
else
|
||||||
|
IOS_VERSION_OPTIONS=""
|
||||||
|
IOS_VERSION_MIN="6.0"
|
||||||
|
fi
|
||||||
|
|
||||||
if [ "${VERBOSE}" = "yes" ]; then
|
if [ "${VERBOSE}" = "yes" ]; then
|
||||||
cat << EOF
|
cat << EOF
|
||||||
BUILD_ROOT=${BUILD_ROOT}
|
BUILD_ROOT=${BUILD_ROOT}
|
||||||
@@ -332,8 +368,13 @@ cat << EOF
|
|||||||
ORIG_PWD=${ORIG_PWD}
|
ORIG_PWD=${ORIG_PWD}
|
||||||
PRESERVE_BUILD_OUTPUT=${PRESERVE_BUILD_OUTPUT}
|
PRESERVE_BUILD_OUTPUT=${PRESERVE_BUILD_OUTPUT}
|
||||||
TARGETS="$(print_list "" ${TARGETS})"
|
TARGETS="$(print_list "" ${TARGETS})"
|
||||||
|
ENABLE_SHARED=${ENABLE_SHARED}
|
||||||
OSX_TARGETS="${OSX_TARGETS}"
|
OSX_TARGETS="${OSX_TARGETS}"
|
||||||
SIM_TARGETS="${SIM_TARGETS}"
|
SIM_TARGETS="${SIM_TARGETS}"
|
||||||
|
SCRIPT_DIR="${SCRIPT_DIR}"
|
||||||
|
FULLVERSION="${FULLVERSION}"
|
||||||
|
VERSION="${VERSION}"
|
||||||
|
IOS_VERSION_MIN="${IOS_VERSION_MIN}"
|
||||||
EOF
|
EOF
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
|||||||
@@ -384,13 +384,8 @@ if ($opts{arch} eq 'x86') {
|
|||||||
}
|
}
|
||||||
close CONFIG_FILE;
|
close CONFIG_FILE;
|
||||||
mips;
|
mips;
|
||||||
} elsif ($opts{arch} eq 'armv6') {
|
|
||||||
@ALL_ARCHS = filter(qw/media/);
|
|
||||||
arm;
|
|
||||||
} elsif ($opts{arch} =~ /armv7\w?/) {
|
} elsif ($opts{arch} =~ /armv7\w?/) {
|
||||||
@ALL_ARCHS = filter(qw/media neon_asm neon/);
|
@ALL_ARCHS = filter(qw/neon_asm neon/);
|
||||||
@REQUIRES = filter(keys %required ? keys %required : qw/media/);
|
|
||||||
&require(@REQUIRES);
|
|
||||||
arm;
|
arm;
|
||||||
} elsif ($opts{arch} eq 'armv8' || $opts{arch} eq 'arm64' ) {
|
} elsif ($opts{arch} eq 'armv8' || $opts{arch} eq 'arm64' ) {
|
||||||
@ALL_ARCHS = filter(qw/neon/);
|
@ALL_ARCHS = filter(qw/neon/);
|
||||||
|
|||||||
@@ -2,3 +2,4 @@
|
|||||||
GERRIT_HOST: chromium-review.googlesource.com
|
GERRIT_HOST: chromium-review.googlesource.com
|
||||||
GERRIT_PORT: 29418
|
GERRIT_PORT: 29418
|
||||||
CODE_REVIEW_SERVER: chromium-review.googlesource.com
|
CODE_REVIEW_SERVER: chromium-review.googlesource.com
|
||||||
|
GERRIT_SQUASH_UPLOADS: False
|
||||||
|
|||||||
94
configure
vendored
94
configure
vendored
@@ -22,6 +22,7 @@ show_help(){
|
|||||||
Advanced options:
|
Advanced options:
|
||||||
${toggle_libs} libraries
|
${toggle_libs} libraries
|
||||||
${toggle_examples} examples
|
${toggle_examples} examples
|
||||||
|
${toggle_tools} tools
|
||||||
${toggle_docs} documentation
|
${toggle_docs} documentation
|
||||||
${toggle_unit_tests} unit tests
|
${toggle_unit_tests} unit tests
|
||||||
${toggle_decode_perf_tests} build decoder perf tests with unit tests
|
${toggle_decode_perf_tests} build decoder perf tests with unit tests
|
||||||
@@ -40,7 +41,6 @@ Advanced options:
|
|||||||
hardware decoder compatibility
|
hardware decoder compatibility
|
||||||
${toggle_vp8} VP8 codec support
|
${toggle_vp8} VP8 codec support
|
||||||
${toggle_vp9} VP9 codec support
|
${toggle_vp9} VP9 codec support
|
||||||
${toggle_vp10} VP10 codec support
|
|
||||||
${toggle_internal_stats} output of encoder internal stats for debug, if supported (encoders)
|
${toggle_internal_stats} output of encoder internal stats for debug, if supported (encoders)
|
||||||
${toggle_postproc} postprocessing
|
${toggle_postproc} postprocessing
|
||||||
${toggle_vp9_postproc} vp9 specific postprocessing
|
${toggle_vp9_postproc} vp9 specific postprocessing
|
||||||
@@ -98,9 +98,7 @@ EOF
|
|||||||
|
|
||||||
# all_platforms is a list of all supported target platforms. Maintain
|
# all_platforms is a list of all supported target platforms. Maintain
|
||||||
# alphabetically by architecture, generic-gnu last.
|
# alphabetically by architecture, generic-gnu last.
|
||||||
all_platforms="${all_platforms} armv6-linux-rvct"
|
all_platforms="${all_platforms} arm64-android-gcc"
|
||||||
all_platforms="${all_platforms} armv6-linux-gcc"
|
|
||||||
all_platforms="${all_platforms} armv6-none-rvct"
|
|
||||||
all_platforms="${all_platforms} arm64-darwin-gcc"
|
all_platforms="${all_platforms} arm64-darwin-gcc"
|
||||||
all_platforms="${all_platforms} arm64-linux-gcc"
|
all_platforms="${all_platforms} arm64-linux-gcc"
|
||||||
all_platforms="${all_platforms} armv7-android-gcc" #neon Cortex-A8
|
all_platforms="${all_platforms} armv7-android-gcc" #neon Cortex-A8
|
||||||
@@ -112,6 +110,7 @@ all_platforms="${all_platforms} armv7-win32-vs11"
|
|||||||
all_platforms="${all_platforms} armv7-win32-vs12"
|
all_platforms="${all_platforms} armv7-win32-vs12"
|
||||||
all_platforms="${all_platforms} armv7-win32-vs14"
|
all_platforms="${all_platforms} armv7-win32-vs14"
|
||||||
all_platforms="${all_platforms} armv7s-darwin-gcc"
|
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} mips32-linux-gcc"
|
||||||
all_platforms="${all_platforms} mips64-linux-gcc"
|
all_platforms="${all_platforms} mips64-linux-gcc"
|
||||||
all_platforms="${all_platforms} sparc-solaris-gcc"
|
all_platforms="${all_platforms} sparc-solaris-gcc"
|
||||||
@@ -132,9 +131,6 @@ all_platforms="${all_platforms} x86-linux-icc"
|
|||||||
all_platforms="${all_platforms} x86-os2-gcc"
|
all_platforms="${all_platforms} x86-os2-gcc"
|
||||||
all_platforms="${all_platforms} x86-solaris-gcc"
|
all_platforms="${all_platforms} x86-solaris-gcc"
|
||||||
all_platforms="${all_platforms} x86-win32-gcc"
|
all_platforms="${all_platforms} x86-win32-gcc"
|
||||||
all_platforms="${all_platforms} x86-win32-vs7"
|
|
||||||
all_platforms="${all_platforms} x86-win32-vs8"
|
|
||||||
all_platforms="${all_platforms} x86-win32-vs9"
|
|
||||||
all_platforms="${all_platforms} x86-win32-vs10"
|
all_platforms="${all_platforms} x86-win32-vs10"
|
||||||
all_platforms="${all_platforms} x86-win32-vs11"
|
all_platforms="${all_platforms} x86-win32-vs11"
|
||||||
all_platforms="${all_platforms} x86-win32-vs12"
|
all_platforms="${all_platforms} x86-win32-vs12"
|
||||||
@@ -152,8 +148,6 @@ all_platforms="${all_platforms} x86_64-linux-gcc"
|
|||||||
all_platforms="${all_platforms} x86_64-linux-icc"
|
all_platforms="${all_platforms} x86_64-linux-icc"
|
||||||
all_platforms="${all_platforms} x86_64-solaris-gcc"
|
all_platforms="${all_platforms} x86_64-solaris-gcc"
|
||||||
all_platforms="${all_platforms} x86_64-win64-gcc"
|
all_platforms="${all_platforms} x86_64-win64-gcc"
|
||||||
all_platforms="${all_platforms} x86_64-win64-vs8"
|
|
||||||
all_platforms="${all_platforms} x86_64-win64-vs9"
|
|
||||||
all_platforms="${all_platforms} x86_64-win64-vs10"
|
all_platforms="${all_platforms} x86_64-win64-vs10"
|
||||||
all_platforms="${all_platforms} x86_64-win64-vs11"
|
all_platforms="${all_platforms} x86_64-win64-vs11"
|
||||||
all_platforms="${all_platforms} x86_64-win64-vs12"
|
all_platforms="${all_platforms} x86_64-win64-vs12"
|
||||||
@@ -162,7 +156,7 @@ all_platforms="${all_platforms} generic-gnu"
|
|||||||
|
|
||||||
# all_targets is a list of all targets that can be configured
|
# all_targets is a list of all targets that can be configured
|
||||||
# note that these should be in dependency order for now.
|
# note that these should be in dependency order for now.
|
||||||
all_targets="libs examples docs"
|
all_targets="libs examples tools docs"
|
||||||
|
|
||||||
# all targets available are enabled, by default.
|
# all targets available are enabled, by default.
|
||||||
for t in ${all_targets}; do
|
for t in ${all_targets}; do
|
||||||
@@ -195,12 +189,8 @@ if [ ${doxy_major:-0} -ge 1 ]; then
|
|||||||
fi
|
fi
|
||||||
|
|
||||||
# disable codecs when their source directory does not exist
|
# disable codecs when their source directory does not exist
|
||||||
[ -d "${source_path}/vp8" ] || disable_feature vp8
|
[ -d "${source_path}/vp8" ] || disable_codec vp8
|
||||||
[ -d "${source_path}/vp9" ] || disable_feature vp9
|
[ -d "${source_path}/vp9" ] || disable_codec vp9
|
||||||
[ -d "${source_path}/vp10" ] || disable_feature vp10
|
|
||||||
|
|
||||||
# disable vp10 codec by default
|
|
||||||
disable_feature vp10
|
|
||||||
|
|
||||||
# install everything except the sources, by default. sources will have
|
# install everything except the sources, by default. sources will have
|
||||||
# to be enabled when doing dist builds, since that's no longer a common
|
# to be enabled when doing dist builds, since that's no longer a common
|
||||||
@@ -222,13 +212,10 @@ CODECS="
|
|||||||
vp8_decoder
|
vp8_decoder
|
||||||
vp9_encoder
|
vp9_encoder
|
||||||
vp9_decoder
|
vp9_decoder
|
||||||
vp10_encoder
|
|
||||||
vp10_decoder
|
|
||||||
"
|
"
|
||||||
CODEC_FAMILIES="
|
CODEC_FAMILIES="
|
||||||
vp8
|
vp8
|
||||||
vp9
|
vp9
|
||||||
vp10
|
|
||||||
"
|
"
|
||||||
|
|
||||||
ARCH_LIST="
|
ARCH_LIST="
|
||||||
@@ -248,8 +235,6 @@ ARCH_EXT_LIST_X86="
|
|||||||
avx2
|
avx2
|
||||||
"
|
"
|
||||||
ARCH_EXT_LIST="
|
ARCH_EXT_LIST="
|
||||||
edsp
|
|
||||||
media
|
|
||||||
neon
|
neon
|
||||||
neon_asm
|
neon_asm
|
||||||
|
|
||||||
@@ -279,7 +264,6 @@ CONFIG_LIST="
|
|||||||
install_bins
|
install_bins
|
||||||
install_libs
|
install_libs
|
||||||
install_srcs
|
install_srcs
|
||||||
use_x86inc
|
|
||||||
debug
|
debug
|
||||||
gprof
|
gprof
|
||||||
gcov
|
gcov
|
||||||
@@ -341,7 +325,6 @@ CMDLINE_SELECT="
|
|||||||
gprof
|
gprof
|
||||||
gcov
|
gcov
|
||||||
pic
|
pic
|
||||||
use_x86inc
|
|
||||||
optimizations
|
optimizations
|
||||||
ccache
|
ccache
|
||||||
runtime_cpu_detect
|
runtime_cpu_detect
|
||||||
@@ -349,6 +332,7 @@ CMDLINE_SELECT="
|
|||||||
|
|
||||||
libs
|
libs
|
||||||
examples
|
examples
|
||||||
|
tools
|
||||||
docs
|
docs
|
||||||
libc
|
libc
|
||||||
as
|
as
|
||||||
@@ -391,15 +375,19 @@ process_cmdline() {
|
|||||||
for opt do
|
for opt do
|
||||||
optval="${opt#*=}"
|
optval="${opt#*=}"
|
||||||
case "$opt" in
|
case "$opt" in
|
||||||
--disable-codecs) for c in ${CODECS}; do disable_feature $c; done ;;
|
--disable-codecs)
|
||||||
|
for c in ${CODEC_FAMILIES}; do disable_codec $c; done
|
||||||
|
;;
|
||||||
--enable-?*|--disable-?*)
|
--enable-?*|--disable-?*)
|
||||||
eval `echo "$opt" | sed 's/--/action=/;s/-/ option=/;s/-/_/g'`
|
eval `echo "$opt" | sed 's/--/action=/;s/-/ option=/;s/-/_/g'`
|
||||||
if echo "${EXPERIMENT_LIST}" | grep "^ *$option\$" >/dev/null; then
|
if is_in ${option} ${EXPERIMENT_LIST}; then
|
||||||
if enabled experimental; then
|
if enabled experimental; then
|
||||||
${action}_feature $option
|
${action}_feature $option
|
||||||
else
|
else
|
||||||
log_echo "Ignoring $opt -- not in experimental mode."
|
log_echo "Ignoring $opt -- not in experimental mode."
|
||||||
fi
|
fi
|
||||||
|
elif is_in ${option} "${CODECS} ${CODEC_FAMILIES}"; then
|
||||||
|
${action}_codec ${option}
|
||||||
else
|
else
|
||||||
process_common_cmdline $opt
|
process_common_cmdline $opt
|
||||||
fi
|
fi
|
||||||
@@ -413,14 +401,6 @@ process_cmdline() {
|
|||||||
post_process_cmdline() {
|
post_process_cmdline() {
|
||||||
c=""
|
c=""
|
||||||
|
|
||||||
# If the codec family is disabled, disable all components of that family.
|
|
||||||
# If the codec family is enabled, enable all components of that family.
|
|
||||||
log_echo "Configuring selected codecs"
|
|
||||||
for c in ${CODECS}; do
|
|
||||||
disabled ${c%%_*} && disable_feature ${c}
|
|
||||||
enabled ${c%%_*} && enable_feature ${c}
|
|
||||||
done
|
|
||||||
|
|
||||||
# Enable all detected codecs, if they haven't been disabled
|
# Enable all detected codecs, if they haven't been disabled
|
||||||
for c in ${CODECS}; do soft_enable $c; done
|
for c in ${CODECS}; do soft_enable $c; done
|
||||||
|
|
||||||
@@ -498,7 +478,7 @@ EOF
|
|||||||
#
|
#
|
||||||
# Write makefiles for all enabled targets
|
# Write makefiles for all enabled targets
|
||||||
#
|
#
|
||||||
for tgt in libs examples docs solution; do
|
for tgt in libs examples tools docs solution; do
|
||||||
tgt_fn="$tgt-$toolchain.mk"
|
tgt_fn="$tgt-$toolchain.mk"
|
||||||
|
|
||||||
if enabled $tgt; then
|
if enabled $tgt; then
|
||||||
@@ -515,13 +495,18 @@ process_detect() {
|
|||||||
# Can only build shared libs on a subset of platforms. Doing this check
|
# Can only build shared libs on a subset of platforms. Doing this check
|
||||||
# here rather than at option parse time because the target auto-detect
|
# here rather than at option parse time because the target auto-detect
|
||||||
# magic happens after the command line has been parsed.
|
# magic happens after the command line has been parsed.
|
||||||
if ! enabled linux && ! enabled os2; then
|
case "${tgt_os}" in
|
||||||
|
linux|os2|darwin*|iphonesimulator*)
|
||||||
|
# Supported platforms
|
||||||
|
;;
|
||||||
|
*)
|
||||||
if enabled gnu; then
|
if enabled gnu; then
|
||||||
echo "--enable-shared is only supported on ELF; assuming this is OK"
|
echo "--enable-shared is only supported on ELF; assuming this is OK"
|
||||||
else
|
else
|
||||||
die "--enable-shared only supported on ELF and OS/2 for now"
|
die "--enable-shared only supported on ELF, OS/2, and Darwin for now"
|
||||||
fi
|
|
||||||
fi
|
fi
|
||||||
|
;;
|
||||||
|
esac
|
||||||
fi
|
fi
|
||||||
if [ -z "$CC" ] || enabled external_build; then
|
if [ -z "$CC" ] || enabled external_build; then
|
||||||
echo "Bypassing toolchain for environment detection."
|
echo "Bypassing toolchain for environment detection."
|
||||||
@@ -584,26 +569,29 @@ process_toolchain() {
|
|||||||
check_add_cflags -Wall
|
check_add_cflags -Wall
|
||||||
check_add_cflags -Wdeclaration-after-statement
|
check_add_cflags -Wdeclaration-after-statement
|
||||||
check_add_cflags -Wdisabled-optimization
|
check_add_cflags -Wdisabled-optimization
|
||||||
|
check_add_cflags -Wfloat-conversion
|
||||||
check_add_cflags -Wpointer-arith
|
check_add_cflags -Wpointer-arith
|
||||||
check_add_cflags -Wtype-limits
|
check_add_cflags -Wtype-limits
|
||||||
check_add_cflags -Wcast-qual
|
check_add_cflags -Wcast-qual
|
||||||
check_add_cflags -Wvla
|
check_add_cflags -Wvla
|
||||||
check_add_cflags -Wimplicit-function-declaration
|
check_add_cflags -Wimplicit-function-declaration
|
||||||
check_add_cflags -Wuninitialized
|
check_add_cflags -Wuninitialized
|
||||||
check_add_cflags -Wunused-variable
|
check_add_cflags -Wunused
|
||||||
case ${CC} in
|
# -Wextra has some tricky cases. Rather than fix them all now, get the
|
||||||
*clang*)
|
# flag for as many files as possible and fix the remaining issues
|
||||||
# libvpx and/or clang have issues with aliasing:
|
# piecemeal.
|
||||||
# https://code.google.com/p/webm/issues/detail?id=603
|
# https://bugs.chromium.org/p/webm/issues/detail?id=1069
|
||||||
# work around them until they are fixed
|
check_add_cflags -Wextra
|
||||||
check_add_cflags -fno-strict-aliasing
|
# check_add_cflags also adds to cxxflags. gtest does not do well with
|
||||||
;;
|
# -Wundef so add it explicitly to CFLAGS only.
|
||||||
*) check_add_cflags -Wunused-but-set-variable ;;
|
check_cflags -Wundef && add_cflags_only -Wundef
|
||||||
esac
|
|
||||||
if enabled mips || [ -z "${INLINE}" ]; then
|
if enabled mips || [ -z "${INLINE}" ]; then
|
||||||
enabled extra_warnings || check_add_cflags -Wno-unused-function
|
enabled extra_warnings || check_add_cflags -Wno-unused-function
|
||||||
else
|
fi
|
||||||
check_add_cflags -Wunused-function
|
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
|
fi
|
||||||
fi
|
fi
|
||||||
|
|
||||||
@@ -652,17 +640,9 @@ process_toolchain() {
|
|||||||
vs*) enable_feature msvs
|
vs*) enable_feature msvs
|
||||||
enable_feature solution
|
enable_feature solution
|
||||||
vs_version=${tgt_cc##vs}
|
vs_version=${tgt_cc##vs}
|
||||||
case $vs_version in
|
|
||||||
[789])
|
|
||||||
VCPROJ_SFX=vcproj
|
|
||||||
gen_vcproj_cmd=${source_path}/build/make/gen_msvs_proj.sh
|
|
||||||
;;
|
|
||||||
10|11|12|14)
|
|
||||||
VCPROJ_SFX=vcxproj
|
VCPROJ_SFX=vcxproj
|
||||||
gen_vcproj_cmd=${source_path}/build/make/gen_msvs_vcxproj.sh
|
gen_vcproj_cmd=${source_path}/build/make/gen_msvs_vcxproj.sh
|
||||||
enabled werror && gen_vcproj_cmd="${gen_vcproj_cmd} --enable-werror"
|
enabled werror && gen_vcproj_cmd="${gen_vcproj_cmd} --enable-werror"
|
||||||
;;
|
|
||||||
esac
|
|
||||||
all_targets="${all_targets} solution"
|
all_targets="${all_targets} solution"
|
||||||
INLINE="__forceinline"
|
INLINE="__forceinline"
|
||||||
;;
|
;;
|
||||||
|
|||||||
12
examples.mk
12
examples.mk
@@ -76,6 +76,7 @@ vpxdec.SRCS += tools_common.c tools_common.h
|
|||||||
vpxdec.SRCS += y4menc.c y4menc.h
|
vpxdec.SRCS += y4menc.c y4menc.h
|
||||||
ifeq ($(CONFIG_LIBYUV),yes)
|
ifeq ($(CONFIG_LIBYUV),yes)
|
||||||
vpxdec.SRCS += $(LIBYUV_SRCS)
|
vpxdec.SRCS += $(LIBYUV_SRCS)
|
||||||
|
$(BUILD_PFX)third_party/libyuv/%.cc.o: CXXFLAGS += -Wno-unused-parameter
|
||||||
endif
|
endif
|
||||||
ifeq ($(CONFIG_WEBM_IO),yes)
|
ifeq ($(CONFIG_WEBM_IO),yes)
|
||||||
vpxdec.SRCS += $(LIBWEBM_COMMON_SRCS)
|
vpxdec.SRCS += $(LIBWEBM_COMMON_SRCS)
|
||||||
@@ -215,6 +216,17 @@ vp8cx_set_ref.SRCS += vpx_ports/msvc.h
|
|||||||
vp8cx_set_ref.GUID = C5E31F7F-96F6-48BD-BD3E-10EBF6E8057A
|
vp8cx_set_ref.GUID = C5E31F7F-96F6-48BD-BD3E-10EBF6E8057A
|
||||||
vp8cx_set_ref.DESCRIPTION = VP8 set encoder reference frame
|
vp8cx_set_ref.DESCRIPTION = VP8 set encoder reference frame
|
||||||
|
|
||||||
|
ifeq ($(CONFIG_VP9_ENCODER),yes)
|
||||||
|
ifeq ($(CONFIG_DECODERS),yes)
|
||||||
|
EXAMPLES-yes += vp9cx_set_ref.c
|
||||||
|
vp9cx_set_ref.SRCS += ivfenc.h ivfenc.c
|
||||||
|
vp9cx_set_ref.SRCS += tools_common.h tools_common.c
|
||||||
|
vp9cx_set_ref.SRCS += video_common.h
|
||||||
|
vp9cx_set_ref.SRCS += video_writer.h video_writer.c
|
||||||
|
vp9cx_set_ref.GUID = 65D7F14A-2EE6-4293-B958-AB5107A03B55
|
||||||
|
vp9cx_set_ref.DESCRIPTION = VP9 set encoder reference frame
|
||||||
|
endif
|
||||||
|
endif
|
||||||
|
|
||||||
ifeq ($(CONFIG_MULTI_RES_ENCODING),yes)
|
ifeq ($(CONFIG_MULTI_RES_ENCODING),yes)
|
||||||
ifeq ($(CONFIG_LIBYUV),yes)
|
ifeq ($(CONFIG_LIBYUV),yes)
|
||||||
|
|||||||
@@ -65,8 +65,7 @@ static void get_image_md5(const vpx_image_t *img, unsigned char digest[16]) {
|
|||||||
static void print_md5(FILE *stream, unsigned char digest[16]) {
|
static void print_md5(FILE *stream, unsigned char digest[16]) {
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
for (i = 0; i < 16; ++i)
|
for (i = 0; i < 16; ++i) fprintf(stream, "%02x", digest[i]);
|
||||||
fprintf(stream, "%02x", digest[i]);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static const char *exec_name;
|
static const char *exec_name;
|
||||||
@@ -86,12 +85,10 @@ int main(int argc, char **argv) {
|
|||||||
|
|
||||||
exec_name = argv[0];
|
exec_name = argv[0];
|
||||||
|
|
||||||
if (argc != 3)
|
if (argc != 3) die("Invalid number of arguments.");
|
||||||
die("Invalid number of arguments.");
|
|
||||||
|
|
||||||
reader = vpx_video_reader_open(argv[1]);
|
reader = vpx_video_reader_open(argv[1]);
|
||||||
if (!reader)
|
if (!reader) die("Failed to open %s for reading.", argv[1]);
|
||||||
die("Failed to open %s for reading.", argv[1]);
|
|
||||||
|
|
||||||
if (!(outfile = fopen(argv[2], "wb")))
|
if (!(outfile = fopen(argv[2], "wb")))
|
||||||
die("Failed to open %s for writing.", argv[2]);
|
die("Failed to open %s for writing.", argv[2]);
|
||||||
@@ -99,8 +96,7 @@ int main(int argc, char **argv) {
|
|||||||
info = vpx_video_reader_get_info(reader);
|
info = vpx_video_reader_get_info(reader);
|
||||||
|
|
||||||
decoder = get_vpx_decoder_by_fourcc(info->codec_fourcc);
|
decoder = get_vpx_decoder_by_fourcc(info->codec_fourcc);
|
||||||
if (!decoder)
|
if (!decoder) die("Unknown input codec.");
|
||||||
die("Unknown input codec.");
|
|
||||||
|
|
||||||
printf("Using %s\n", vpx_codec_iface_name(decoder->codec_interface()));
|
printf("Using %s\n", vpx_codec_iface_name(decoder->codec_interface()));
|
||||||
|
|
||||||
@@ -111,8 +107,8 @@ int main(int argc, char **argv) {
|
|||||||
vpx_codec_iter_t iter = NULL;
|
vpx_codec_iter_t iter = NULL;
|
||||||
vpx_image_t *img = NULL;
|
vpx_image_t *img = NULL;
|
||||||
size_t frame_size = 0;
|
size_t frame_size = 0;
|
||||||
const unsigned char *frame = vpx_video_reader_get_frame(reader,
|
const unsigned char *frame =
|
||||||
&frame_size);
|
vpx_video_reader_get_frame(reader, &frame_size);
|
||||||
if (vpx_codec_decode(&codec, frame, (unsigned int)frame_size, NULL, 0))
|
if (vpx_codec_decode(&codec, frame, (unsigned int)frame_size, NULL, 0))
|
||||||
die_codec(&codec, "Failed to decode frame");
|
die_codec(&codec, "Failed to decode frame");
|
||||||
|
|
||||||
@@ -121,14 +117,13 @@ int main(int argc, char **argv) {
|
|||||||
|
|
||||||
get_image_md5(img, digest);
|
get_image_md5(img, digest);
|
||||||
print_md5(outfile, digest);
|
print_md5(outfile, digest);
|
||||||
fprintf(outfile, " img-%dx%d-%04d.i420\n",
|
fprintf(outfile, " img-%dx%d-%04d.i420\n", img->d_w, img->d_h,
|
||||||
img->d_w, img->d_h, ++frame_cnt);
|
++frame_cnt);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
printf("Processed %d frames.\n", frame_cnt);
|
printf("Processed %d frames.\n", frame_cnt);
|
||||||
if (vpx_codec_destroy(&codec))
|
if (vpx_codec_destroy(&codec)) die_codec(&codec, "Failed to destroy codec.");
|
||||||
die_codec(&codec, "Failed to destroy codec.");
|
|
||||||
|
|
||||||
vpx_video_reader_close(reader);
|
vpx_video_reader_close(reader);
|
||||||
|
|
||||||
|
|||||||
@@ -84,18 +84,16 @@ int main(int argc, char **argv) {
|
|||||||
|
|
||||||
exec_name = argv[0];
|
exec_name = argv[0];
|
||||||
|
|
||||||
if (argc != 4)
|
if (argc != 4) die("Invalid number of arguments.");
|
||||||
die("Invalid number of arguments.");
|
|
||||||
|
|
||||||
reader = vpx_video_reader_open(argv[1]);
|
reader = vpx_video_reader_open(argv[1]);
|
||||||
if (!reader)
|
if (!reader) die("Failed to open %s for reading.", argv[1]);
|
||||||
die("Failed to open %s for reading.", argv[1]);
|
|
||||||
|
|
||||||
if (!(outfile = fopen(argv[2], "wb")))
|
if (!(outfile = fopen(argv[2], "wb")))
|
||||||
die("Failed to open %s for writing.", argv[2]);
|
die("Failed to open %s for writing.", argv[2]);
|
||||||
|
|
||||||
n = strtol(argv[3], &nptr, 0);
|
n = (int)strtol(argv[3], &nptr, 0);
|
||||||
m = strtol(nptr + 1, NULL, 0);
|
m = (int)strtol(nptr + 1, NULL, 0);
|
||||||
is_range = (*nptr == '-');
|
is_range = (*nptr == '-');
|
||||||
if (!n || !m || (*nptr != '-' && *nptr != '/'))
|
if (!n || !m || (*nptr != '-' && *nptr != '/'))
|
||||||
die("Couldn't parse pattern %s.\n", argv[3]);
|
die("Couldn't parse pattern %s.\n", argv[3]);
|
||||||
@@ -103,8 +101,7 @@ int main(int argc, char **argv) {
|
|||||||
info = vpx_video_reader_get_info(reader);
|
info = vpx_video_reader_get_info(reader);
|
||||||
|
|
||||||
decoder = get_vpx_decoder_by_fourcc(info->codec_fourcc);
|
decoder = get_vpx_decoder_by_fourcc(info->codec_fourcc);
|
||||||
if (!decoder)
|
if (!decoder) die("Unknown input codec.");
|
||||||
die("Unknown input codec.");
|
|
||||||
|
|
||||||
printf("Using %s\n", vpx_codec_iface_name(decoder->codec_interface()));
|
printf("Using %s\n", vpx_codec_iface_name(decoder->codec_interface()));
|
||||||
|
|
||||||
@@ -116,8 +113,8 @@ int main(int argc, char **argv) {
|
|||||||
vpx_image_t *img = NULL;
|
vpx_image_t *img = NULL;
|
||||||
size_t frame_size = 0;
|
size_t frame_size = 0;
|
||||||
int skip;
|
int skip;
|
||||||
const unsigned char *frame = vpx_video_reader_get_frame(reader,
|
const unsigned char *frame =
|
||||||
&frame_size);
|
vpx_video_reader_get_frame(reader, &frame_size);
|
||||||
if (vpx_codec_decode(&codec, frame, (unsigned int)frame_size, NULL, 0))
|
if (vpx_codec_decode(&codec, frame, (unsigned int)frame_size, NULL, 0))
|
||||||
die_codec(&codec, "Failed to decode frame.");
|
die_codec(&codec, "Failed to decode frame.");
|
||||||
|
|
||||||
@@ -139,8 +136,7 @@ int main(int argc, char **argv) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
printf("Processed %d frames.\n", frame_cnt);
|
printf("Processed %d frames.\n", frame_cnt);
|
||||||
if (vpx_codec_destroy(&codec))
|
if (vpx_codec_destroy(&codec)) die_codec(&codec, "Failed to destroy codec.");
|
||||||
die_codec(&codec, "Failed to destroy codec.");
|
|
||||||
|
|
||||||
printf("Play: ffplay -f rawvideo -pix_fmt yuv420p -s %dx%d %s\n",
|
printf("Play: ffplay -f rawvideo -pix_fmt yuv420p -s %dx%d %s\n",
|
||||||
info->frame_width, info->frame_height, argv[2]);
|
info->frame_width, info->frame_height, argv[2]);
|
||||||
|
|||||||
@@ -68,12 +68,10 @@ int main(int argc, char **argv) {
|
|||||||
|
|
||||||
exec_name = argv[0];
|
exec_name = argv[0];
|
||||||
|
|
||||||
if (argc != 3)
|
if (argc != 3) die("Invalid number of arguments.");
|
||||||
die("Invalid number of arguments.");
|
|
||||||
|
|
||||||
reader = vpx_video_reader_open(argv[1]);
|
reader = vpx_video_reader_open(argv[1]);
|
||||||
if (!reader)
|
if (!reader) die("Failed to open %s for reading.", argv[1]);
|
||||||
die("Failed to open %s for reading.", argv[1]);
|
|
||||||
|
|
||||||
if (!(outfile = fopen(argv[2], "wb")))
|
if (!(outfile = fopen(argv[2], "wb")))
|
||||||
die("Failed to open %s for writing", argv[2]);
|
die("Failed to open %s for writing", argv[2]);
|
||||||
@@ -81,8 +79,7 @@ int main(int argc, char **argv) {
|
|||||||
info = vpx_video_reader_get_info(reader);
|
info = vpx_video_reader_get_info(reader);
|
||||||
|
|
||||||
decoder = get_vpx_decoder_by_fourcc(info->codec_fourcc);
|
decoder = get_vpx_decoder_by_fourcc(info->codec_fourcc);
|
||||||
if (!decoder)
|
if (!decoder) die("Unknown input codec.");
|
||||||
die("Unknown input codec.");
|
|
||||||
|
|
||||||
printf("Using %s\n", vpx_codec_iface_name(decoder->codec_interface()));
|
printf("Using %s\n", vpx_codec_iface_name(decoder->codec_interface()));
|
||||||
|
|
||||||
@@ -91,15 +88,14 @@ int main(int argc, char **argv) {
|
|||||||
if (res == VPX_CODEC_INCAPABLE)
|
if (res == VPX_CODEC_INCAPABLE)
|
||||||
die_codec(&codec, "Postproc not supported by this decoder.");
|
die_codec(&codec, "Postproc not supported by this decoder.");
|
||||||
|
|
||||||
if (res)
|
if (res) die_codec(&codec, "Failed to initialize decoder.");
|
||||||
die_codec(&codec, "Failed to initialize decoder.");
|
|
||||||
|
|
||||||
while (vpx_video_reader_read_frame(reader)) {
|
while (vpx_video_reader_read_frame(reader)) {
|
||||||
vpx_codec_iter_t iter = NULL;
|
vpx_codec_iter_t iter = NULL;
|
||||||
vpx_image_t *img = NULL;
|
vpx_image_t *img = NULL;
|
||||||
size_t frame_size = 0;
|
size_t frame_size = 0;
|
||||||
const unsigned char *frame = vpx_video_reader_get_frame(reader,
|
const unsigned char *frame =
|
||||||
&frame_size);
|
vpx_video_reader_get_frame(reader, &frame_size);
|
||||||
|
|
||||||
++frame_cnt;
|
++frame_cnt;
|
||||||
|
|
||||||
@@ -109,8 +105,8 @@ int main(int argc, char **argv) {
|
|||||||
if (vpx_codec_control(&codec, VP8_SET_POSTPROC, &pp))
|
if (vpx_codec_control(&codec, VP8_SET_POSTPROC, &pp))
|
||||||
die_codec(&codec, "Failed to turn off postproc.");
|
die_codec(&codec, "Failed to turn off postproc.");
|
||||||
} else if (frame_cnt % 30 == 16) {
|
} else if (frame_cnt % 30 == 16) {
|
||||||
vp8_postproc_cfg_t pp = {VP8_DEBLOCK | VP8_DEMACROBLOCK | VP8_MFQE,
|
vp8_postproc_cfg_t pp = { VP8_DEBLOCK | VP8_DEMACROBLOCK | VP8_MFQE, 4,
|
||||||
4, 0};
|
0 };
|
||||||
if (vpx_codec_control(&codec, VP8_SET_POSTPROC, &pp))
|
if (vpx_codec_control(&codec, VP8_SET_POSTPROC, &pp))
|
||||||
die_codec(&codec, "Failed to turn on postproc.");
|
die_codec(&codec, "Failed to turn on postproc.");
|
||||||
};
|
};
|
||||||
@@ -125,8 +121,7 @@ int main(int argc, char **argv) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
printf("Processed %d frames.\n", frame_cnt);
|
printf("Processed %d frames.\n", frame_cnt);
|
||||||
if (vpx_codec_destroy(&codec))
|
if (vpx_codec_destroy(&codec)) die_codec(&codec, "Failed to destroy codec");
|
||||||
die_codec(&codec, "Failed to destroy codec");
|
|
||||||
|
|
||||||
printf("Play: ffplay -f rawvideo -pix_fmt yuv420p -s %dx%d %s\n",
|
printf("Play: ffplay -f rawvideo -pix_fmt yuv420p -s %dx%d %s\n",
|
||||||
info->frame_width, info->frame_height, argv[2]);
|
info->frame_width, info->frame_height, argv[2]);
|
||||||
|
|||||||
@@ -34,10 +34,8 @@ void usage_exit(void) {
|
|||||||
|
|
||||||
static int parse_dim(char *v, int *width, int *height) {
|
static int parse_dim(char *v, int *width, int *height) {
|
||||||
char *x = strchr(v, 'x');
|
char *x = strchr(v, 'x');
|
||||||
if (x == NULL)
|
if (x == NULL) x = strchr(v, 'X');
|
||||||
x = strchr(v, 'X');
|
if (x == NULL) return 0;
|
||||||
if (x == NULL)
|
|
||||||
return 0;
|
|
||||||
*width = atoi(v);
|
*width = atoi(v);
|
||||||
*height = atoi(&x[1]);
|
*height = atoi(&x[1]);
|
||||||
if (*width <= 0 || *height <= 0)
|
if (*width <= 0 || *height <= 0)
|
||||||
@@ -93,10 +91,8 @@ int main(int argc, char *argv[]) {
|
|||||||
else
|
else
|
||||||
frames = INT_MAX;
|
frames = INT_MAX;
|
||||||
|
|
||||||
printf("Input size: %dx%d\n",
|
printf("Input size: %dx%d\n", width, height);
|
||||||
width, height);
|
printf("Target size: %dx%d, Frames: ", target_width, target_height);
|
||||||
printf("Target size: %dx%d, Frames: ",
|
|
||||||
target_width, target_height);
|
|
||||||
if (frames == INT_MAX)
|
if (frames == INT_MAX)
|
||||||
printf("All\n");
|
printf("All\n");
|
||||||
else
|
else
|
||||||
@@ -110,13 +106,10 @@ int main(int argc, char *argv[]) {
|
|||||||
outbuf_v = outbuf_u + target_width * target_height / 4;
|
outbuf_v = outbuf_u + target_width * target_height / 4;
|
||||||
f = 0;
|
f = 0;
|
||||||
while (f < frames) {
|
while (f < frames) {
|
||||||
if (fread(inbuf, width * height * 3 / 2, 1, fpin) != 1)
|
if (fread(inbuf, width * height * 3 / 2, 1, fpin) != 1) break;
|
||||||
break;
|
vp9_resize_frame420(inbuf, width, inbuf_u, inbuf_v, width / 2, height,
|
||||||
vp9_resize_frame420(inbuf, width, inbuf_u, inbuf_v, width / 2,
|
width, outbuf, target_width, outbuf_u, outbuf_v,
|
||||||
height, width,
|
target_width / 2, target_height, target_width);
|
||||||
outbuf, target_width, outbuf_u, outbuf_v,
|
|
||||||
target_width / 2,
|
|
||||||
target_height, target_width);
|
|
||||||
fwrite(outbuf, target_width * target_height * 3 / 2, 1, fpout);
|
fwrite(outbuf, target_width * target_height * 3 / 2, 1, fpout);
|
||||||
f++;
|
f++;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -8,7 +8,6 @@
|
|||||||
* be found in the AUTHORS file in the root of the source tree.
|
* be found in the AUTHORS file in the root of the source tree.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
// VP8 Set Active and ROI Maps
|
// VP8 Set Active and ROI Maps
|
||||||
// ===========================
|
// ===========================
|
||||||
//
|
//
|
||||||
@@ -86,8 +85,7 @@ static void set_roi_map(const vpx_codec_enc_cfg_t *cfg,
|
|||||||
roi.static_threshold[3] = 0;
|
roi.static_threshold[3] = 0;
|
||||||
|
|
||||||
roi.roi_map = (uint8_t *)malloc(roi.rows * roi.cols);
|
roi.roi_map = (uint8_t *)malloc(roi.rows * roi.cols);
|
||||||
for (i = 0; i < roi.rows * roi.cols; ++i)
|
for (i = 0; i < roi.rows * roi.cols; ++i) roi.roi_map[i] = i % 4;
|
||||||
roi.roi_map[i] = i % 4;
|
|
||||||
|
|
||||||
if (vpx_codec_control(codec, VP8E_SET_ROI_MAP, &roi))
|
if (vpx_codec_control(codec, VP8E_SET_ROI_MAP, &roi))
|
||||||
die_codec(codec, "Failed to set ROI map");
|
die_codec(codec, "Failed to set ROI map");
|
||||||
@@ -104,8 +102,7 @@ static void set_active_map(const vpx_codec_enc_cfg_t *cfg,
|
|||||||
map.cols = (cfg->g_w + 15) / 16;
|
map.cols = (cfg->g_w + 15) / 16;
|
||||||
|
|
||||||
map.active_map = (uint8_t *)malloc(map.rows * map.cols);
|
map.active_map = (uint8_t *)malloc(map.rows * map.cols);
|
||||||
for (i = 0; i < map.rows * map.cols; ++i)
|
for (i = 0; i < map.rows * map.cols; ++i) map.active_map[i] = i % 2;
|
||||||
map.active_map[i] = i % 2;
|
|
||||||
|
|
||||||
if (vpx_codec_control(codec, VP8E_SET_ACTIVEMAP, &map))
|
if (vpx_codec_control(codec, VP8E_SET_ACTIVEMAP, &map))
|
||||||
die_codec(codec, "Failed to set active map");
|
die_codec(codec, "Failed to set active map");
|
||||||
@@ -125,25 +122,21 @@ static void unset_active_map(const vpx_codec_enc_cfg_t *cfg,
|
|||||||
die_codec(codec, "Failed to set active map");
|
die_codec(codec, "Failed to set active map");
|
||||||
}
|
}
|
||||||
|
|
||||||
static int encode_frame(vpx_codec_ctx_t *codec,
|
static int encode_frame(vpx_codec_ctx_t *codec, vpx_image_t *img,
|
||||||
vpx_image_t *img,
|
int frame_index, VpxVideoWriter *writer) {
|
||||||
int frame_index,
|
|
||||||
VpxVideoWriter *writer) {
|
|
||||||
int got_pkts = 0;
|
int got_pkts = 0;
|
||||||
vpx_codec_iter_t iter = NULL;
|
vpx_codec_iter_t iter = NULL;
|
||||||
const vpx_codec_cx_pkt_t *pkt = NULL;
|
const vpx_codec_cx_pkt_t *pkt = NULL;
|
||||||
const vpx_codec_err_t res = vpx_codec_encode(codec, img, frame_index, 1, 0,
|
const vpx_codec_err_t res =
|
||||||
VPX_DL_GOOD_QUALITY);
|
vpx_codec_encode(codec, img, frame_index, 1, 0, VPX_DL_GOOD_QUALITY);
|
||||||
if (res != VPX_CODEC_OK)
|
if (res != VPX_CODEC_OK) die_codec(codec, "Failed to encode frame");
|
||||||
die_codec(codec, "Failed to encode frame");
|
|
||||||
|
|
||||||
while ((pkt = vpx_codec_get_cx_data(codec, &iter)) != NULL) {
|
while ((pkt = vpx_codec_get_cx_data(codec, &iter)) != NULL) {
|
||||||
got_pkts = 1;
|
got_pkts = 1;
|
||||||
|
|
||||||
if (pkt->kind == VPX_CODEC_CX_FRAME_PKT) {
|
if (pkt->kind == VPX_CODEC_CX_FRAME_PKT) {
|
||||||
const int keyframe = (pkt->data.frame.flags & VPX_FRAME_IS_KEY) != 0;
|
const int keyframe = (pkt->data.frame.flags & VPX_FRAME_IS_KEY) != 0;
|
||||||
if (!vpx_video_writer_write_frame(writer,
|
if (!vpx_video_writer_write_frame(writer, pkt->data.frame.buf,
|
||||||
pkt->data.frame.buf,
|
|
||||||
pkt->data.frame.sz,
|
pkt->data.frame.sz,
|
||||||
pkt->data.frame.pts)) {
|
pkt->data.frame.pts)) {
|
||||||
die_codec(codec, "Failed to write compressed frame");
|
die_codec(codec, "Failed to write compressed frame");
|
||||||
@@ -171,8 +164,7 @@ int main(int argc, char **argv) {
|
|||||||
const double bits_per_pixel_per_frame = 0.067;
|
const double bits_per_pixel_per_frame = 0.067;
|
||||||
|
|
||||||
exec_name = argv[0];
|
exec_name = argv[0];
|
||||||
if (argc != 6)
|
if (argc != 6) die("Invalid number of arguments");
|
||||||
die("Invalid number of arguments");
|
|
||||||
|
|
||||||
memset(&info, 0, sizeof(info));
|
memset(&info, 0, sizeof(info));
|
||||||
|
|
||||||
@@ -182,15 +174,13 @@ int main(int argc, char **argv) {
|
|||||||
}
|
}
|
||||||
assert(encoder != NULL);
|
assert(encoder != NULL);
|
||||||
info.codec_fourcc = encoder->fourcc;
|
info.codec_fourcc = encoder->fourcc;
|
||||||
info.frame_width = strtol(argv[2], NULL, 0);
|
info.frame_width = (int)strtol(argv[2], NULL, 0);
|
||||||
info.frame_height = strtol(argv[3], NULL, 0);
|
info.frame_height = (int)strtol(argv[3], NULL, 0);
|
||||||
info.time_base.numerator = 1;
|
info.time_base.numerator = 1;
|
||||||
info.time_base.denominator = fps;
|
info.time_base.denominator = fps;
|
||||||
|
|
||||||
if (info.frame_width <= 0 ||
|
if (info.frame_width <= 0 || info.frame_height <= 0 ||
|
||||||
info.frame_height <= 0 ||
|
(info.frame_width % 2) != 0 || (info.frame_height % 2) != 0) {
|
||||||
(info.frame_width % 2) != 0 ||
|
|
||||||
(info.frame_height % 2) != 0) {
|
|
||||||
die("Invalid frame size: %dx%d", info.frame_width, info.frame_height);
|
die("Invalid frame size: %dx%d", info.frame_width, info.frame_height);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -202,20 +192,18 @@ int main(int argc, char **argv) {
|
|||||||
printf("Using %s\n", vpx_codec_iface_name(encoder->codec_interface()));
|
printf("Using %s\n", vpx_codec_iface_name(encoder->codec_interface()));
|
||||||
|
|
||||||
res = vpx_codec_enc_config_default(encoder->codec_interface(), &cfg, 0);
|
res = vpx_codec_enc_config_default(encoder->codec_interface(), &cfg, 0);
|
||||||
if (res)
|
if (res) die_codec(&codec, "Failed to get default codec config.");
|
||||||
die_codec(&codec, "Failed to get default codec config.");
|
|
||||||
|
|
||||||
cfg.g_w = info.frame_width;
|
cfg.g_w = info.frame_width;
|
||||||
cfg.g_h = info.frame_height;
|
cfg.g_h = info.frame_height;
|
||||||
cfg.g_timebase.num = info.time_base.numerator;
|
cfg.g_timebase.num = info.time_base.numerator;
|
||||||
cfg.g_timebase.den = info.time_base.denominator;
|
cfg.g_timebase.den = info.time_base.denominator;
|
||||||
cfg.rc_target_bitrate = (unsigned int)(bits_per_pixel_per_frame * cfg.g_w *
|
cfg.rc_target_bitrate =
|
||||||
cfg.g_h * fps / 1000);
|
(unsigned int)(bits_per_pixel_per_frame * cfg.g_w * cfg.g_h * fps / 1000);
|
||||||
cfg.g_lag_in_frames = 0;
|
cfg.g_lag_in_frames = 0;
|
||||||
|
|
||||||
writer = vpx_video_writer_open(argv[5], kContainerIVF, &info);
|
writer = vpx_video_writer_open(argv[5], kContainerIVF, &info);
|
||||||
if (!writer)
|
if (!writer) die("Failed to open %s for writing.", argv[5]);
|
||||||
die("Failed to open %s for writing.", argv[5]);
|
|
||||||
|
|
||||||
if (!(infile = fopen(argv[4], "rb")))
|
if (!(infile = fopen(argv[4], "rb")))
|
||||||
die("Failed to open %s for reading.", argv[4]);
|
die("Failed to open %s for reading.", argv[4]);
|
||||||
@@ -239,15 +227,15 @@ int main(int argc, char **argv) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Flush encoder.
|
// Flush encoder.
|
||||||
while (encode_frame(&codec, NULL, -1, writer)) {}
|
while (encode_frame(&codec, NULL, -1, writer)) {
|
||||||
|
}
|
||||||
|
|
||||||
printf("\n");
|
printf("\n");
|
||||||
fclose(infile);
|
fclose(infile);
|
||||||
printf("Processed %d frames.\n", frame_count);
|
printf("Processed %d frames.\n", frame_count);
|
||||||
|
|
||||||
vpx_img_free(&raw);
|
vpx_img_free(&raw);
|
||||||
if (vpx_codec_destroy(&codec))
|
if (vpx_codec_destroy(&codec)) die_codec(&codec, "Failed to destroy codec.");
|
||||||
die_codec(&codec, "Failed to destroy codec.");
|
|
||||||
|
|
||||||
vpx_video_writer_close(writer);
|
vpx_video_writer_close(writer);
|
||||||
|
|
||||||
|
|||||||
@@ -8,7 +8,6 @@
|
|||||||
* be found in the AUTHORS file in the root of the source tree.
|
* be found in the AUTHORS file in the root of the source tree.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
// Simple Decoder
|
// Simple Decoder
|
||||||
// ==============
|
// ==============
|
||||||
//
|
//
|
||||||
@@ -103,12 +102,10 @@ int main(int argc, char **argv) {
|
|||||||
|
|
||||||
exec_name = argv[0];
|
exec_name = argv[0];
|
||||||
|
|
||||||
if (argc != 3)
|
if (argc != 3) die("Invalid number of arguments.");
|
||||||
die("Invalid number of arguments.");
|
|
||||||
|
|
||||||
reader = vpx_video_reader_open(argv[1]);
|
reader = vpx_video_reader_open(argv[1]);
|
||||||
if (!reader)
|
if (!reader) die("Failed to open %s for reading.", argv[1]);
|
||||||
die("Failed to open %s for reading.", argv[1]);
|
|
||||||
|
|
||||||
if (!(outfile = fopen(argv[2], "wb")))
|
if (!(outfile = fopen(argv[2], "wb")))
|
||||||
die("Failed to open %s for writing.", argv[2]);
|
die("Failed to open %s for writing.", argv[2]);
|
||||||
@@ -116,8 +113,7 @@ int main(int argc, char **argv) {
|
|||||||
info = vpx_video_reader_get_info(reader);
|
info = vpx_video_reader_get_info(reader);
|
||||||
|
|
||||||
decoder = get_vpx_decoder_by_fourcc(info->codec_fourcc);
|
decoder = get_vpx_decoder_by_fourcc(info->codec_fourcc);
|
||||||
if (!decoder)
|
if (!decoder) die("Unknown input codec.");
|
||||||
die("Unknown input codec.");
|
|
||||||
|
|
||||||
printf("Using %s\n", vpx_codec_iface_name(decoder->codec_interface()));
|
printf("Using %s\n", vpx_codec_iface_name(decoder->codec_interface()));
|
||||||
|
|
||||||
@@ -128,8 +124,8 @@ int main(int argc, char **argv) {
|
|||||||
vpx_codec_iter_t iter = NULL;
|
vpx_codec_iter_t iter = NULL;
|
||||||
vpx_image_t *img = NULL;
|
vpx_image_t *img = NULL;
|
||||||
size_t frame_size = 0;
|
size_t frame_size = 0;
|
||||||
const unsigned char *frame = vpx_video_reader_get_frame(reader,
|
const unsigned char *frame =
|
||||||
&frame_size);
|
vpx_video_reader_get_frame(reader, &frame_size);
|
||||||
if (vpx_codec_decode(&codec, frame, (unsigned int)frame_size, NULL, 0))
|
if (vpx_codec_decode(&codec, frame, (unsigned int)frame_size, NULL, 0))
|
||||||
die_codec(&codec, "Failed to decode frame.");
|
die_codec(&codec, "Failed to decode frame.");
|
||||||
|
|
||||||
@@ -140,8 +136,7 @@ int main(int argc, char **argv) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
printf("Processed %d frames.\n", frame_cnt);
|
printf("Processed %d frames.\n", frame_cnt);
|
||||||
if (vpx_codec_destroy(&codec))
|
if (vpx_codec_destroy(&codec)) die_codec(&codec, "Failed to destroy codec");
|
||||||
die_codec(&codec, "Failed to destroy codec");
|
|
||||||
|
|
||||||
printf("Play: ffplay -f rawvideo -pix_fmt yuv420p -s %dx%d %s\n",
|
printf("Play: ffplay -f rawvideo -pix_fmt yuv420p -s %dx%d %s\n",
|
||||||
info->frame_width, info->frame_height, argv[2]);
|
info->frame_width, info->frame_height, argv[2]);
|
||||||
|
|||||||
@@ -109,32 +109,27 @@ static const char *exec_name;
|
|||||||
void usage_exit(void) {
|
void usage_exit(void) {
|
||||||
fprintf(stderr,
|
fprintf(stderr,
|
||||||
"Usage: %s <codec> <width> <height> <infile> <outfile> "
|
"Usage: %s <codec> <width> <height> <infile> <outfile> "
|
||||||
"<keyframe-interval> [<error-resilient>]\nSee comments in "
|
"<keyframe-interval> <error-resilient> <frames to encode>\n"
|
||||||
"simple_encoder.c for more information.\n",
|
"See comments in simple_encoder.c for more information.\n",
|
||||||
exec_name);
|
exec_name);
|
||||||
exit(EXIT_FAILURE);
|
exit(EXIT_FAILURE);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int encode_frame(vpx_codec_ctx_t *codec,
|
static int encode_frame(vpx_codec_ctx_t *codec, vpx_image_t *img,
|
||||||
vpx_image_t *img,
|
int frame_index, int flags, VpxVideoWriter *writer) {
|
||||||
int frame_index,
|
|
||||||
int flags,
|
|
||||||
VpxVideoWriter *writer) {
|
|
||||||
int got_pkts = 0;
|
int got_pkts = 0;
|
||||||
vpx_codec_iter_t iter = NULL;
|
vpx_codec_iter_t iter = NULL;
|
||||||
const vpx_codec_cx_pkt_t *pkt = NULL;
|
const vpx_codec_cx_pkt_t *pkt = NULL;
|
||||||
const vpx_codec_err_t res = vpx_codec_encode(codec, img, frame_index, 1,
|
const vpx_codec_err_t res =
|
||||||
flags, VPX_DL_GOOD_QUALITY);
|
vpx_codec_encode(codec, img, frame_index, 1, flags, VPX_DL_GOOD_QUALITY);
|
||||||
if (res != VPX_CODEC_OK)
|
if (res != VPX_CODEC_OK) die_codec(codec, "Failed to encode frame");
|
||||||
die_codec(codec, "Failed to encode frame");
|
|
||||||
|
|
||||||
while ((pkt = vpx_codec_get_cx_data(codec, &iter)) != NULL) {
|
while ((pkt = vpx_codec_get_cx_data(codec, &iter)) != NULL) {
|
||||||
got_pkts = 1;
|
got_pkts = 1;
|
||||||
|
|
||||||
if (pkt->kind == VPX_CODEC_CX_FRAME_PKT) {
|
if (pkt->kind == VPX_CODEC_CX_FRAME_PKT) {
|
||||||
const int keyframe = (pkt->data.frame.flags & VPX_FRAME_IS_KEY) != 0;
|
const int keyframe = (pkt->data.frame.flags & VPX_FRAME_IS_KEY) != 0;
|
||||||
if (!vpx_video_writer_write_frame(writer,
|
if (!vpx_video_writer_write_frame(writer, pkt->data.frame.buf,
|
||||||
pkt->data.frame.buf,
|
|
||||||
pkt->data.frame.sz,
|
pkt->data.frame.sz,
|
||||||
pkt->data.frame.pts)) {
|
pkt->data.frame.pts)) {
|
||||||
die_codec(codec, "Failed to write compressed frame");
|
die_codec(codec, "Failed to write compressed frame");
|
||||||
@@ -147,6 +142,7 @@ static int encode_frame(vpx_codec_ctx_t *codec,
|
|||||||
return got_pkts;
|
return got_pkts;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TODO(tomfinegan): Improve command line parsing and add args for bitrate/fps.
|
||||||
int main(int argc, char **argv) {
|
int main(int argc, char **argv) {
|
||||||
FILE *infile = NULL;
|
FILE *infile = NULL;
|
||||||
vpx_codec_ctx_t codec;
|
vpx_codec_ctx_t codec;
|
||||||
@@ -154,15 +150,14 @@ int main(int argc, char **argv) {
|
|||||||
int frame_count = 0;
|
int frame_count = 0;
|
||||||
vpx_image_t raw;
|
vpx_image_t raw;
|
||||||
vpx_codec_err_t res;
|
vpx_codec_err_t res;
|
||||||
VpxVideoInfo info = {0};
|
VpxVideoInfo info = { 0, 0, 0, { 0, 0 } };
|
||||||
VpxVideoWriter *writer = NULL;
|
VpxVideoWriter *writer = NULL;
|
||||||
const VpxInterface *encoder = NULL;
|
const VpxInterface *encoder = NULL;
|
||||||
const int fps = 30; // TODO(dkovalev) add command line argument
|
const int fps = 30;
|
||||||
const int bitrate = 200; // kbit/s TODO(dkovalev) add command line argument
|
const int bitrate = 200;
|
||||||
int keyframe_interval = 0;
|
int keyframe_interval = 0;
|
||||||
|
int max_frames = 0;
|
||||||
// TODO(dkovalev): Add some simple command line parsing code to make the
|
int frames_encoded = 0;
|
||||||
// command line more flexible.
|
|
||||||
const char *codec_arg = NULL;
|
const char *codec_arg = NULL;
|
||||||
const char *width_arg = NULL;
|
const char *width_arg = NULL;
|
||||||
const char *height_arg = NULL;
|
const char *height_arg = NULL;
|
||||||
@@ -172,8 +167,7 @@ int main(int argc, char **argv) {
|
|||||||
|
|
||||||
exec_name = argv[0];
|
exec_name = argv[0];
|
||||||
|
|
||||||
if (argc < 7)
|
if (argc != 9) die("Invalid number of arguments");
|
||||||
die("Invalid number of arguments");
|
|
||||||
|
|
||||||
codec_arg = argv[1];
|
codec_arg = argv[1];
|
||||||
width_arg = argv[2];
|
width_arg = argv[2];
|
||||||
@@ -181,21 +175,19 @@ int main(int argc, char **argv) {
|
|||||||
infile_arg = argv[4];
|
infile_arg = argv[4];
|
||||||
outfile_arg = argv[5];
|
outfile_arg = argv[5];
|
||||||
keyframe_interval_arg = argv[6];
|
keyframe_interval_arg = argv[6];
|
||||||
|
max_frames = (int)strtol(argv[8], NULL, 0);
|
||||||
|
|
||||||
encoder = get_vpx_encoder_by_name(codec_arg);
|
encoder = get_vpx_encoder_by_name(codec_arg);
|
||||||
if (!encoder)
|
if (!encoder) die("Unsupported codec.");
|
||||||
die("Unsupported codec.");
|
|
||||||
|
|
||||||
info.codec_fourcc = encoder->fourcc;
|
info.codec_fourcc = encoder->fourcc;
|
||||||
info.frame_width = strtol(width_arg, NULL, 0);
|
info.frame_width = (int)strtol(width_arg, NULL, 0);
|
||||||
info.frame_height = strtol(height_arg, NULL, 0);
|
info.frame_height = (int)strtol(height_arg, NULL, 0);
|
||||||
info.time_base.numerator = 1;
|
info.time_base.numerator = 1;
|
||||||
info.time_base.denominator = fps;
|
info.time_base.denominator = fps;
|
||||||
|
|
||||||
if (info.frame_width <= 0 ||
|
if (info.frame_width <= 0 || info.frame_height <= 0 ||
|
||||||
info.frame_height <= 0 ||
|
(info.frame_width % 2) != 0 || (info.frame_height % 2) != 0) {
|
||||||
(info.frame_width % 2) != 0 ||
|
|
||||||
(info.frame_height % 2) != 0) {
|
|
||||||
die("Invalid frame size: %dx%d", info.frame_width, info.frame_height);
|
die("Invalid frame size: %dx%d", info.frame_width, info.frame_height);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -204,26 +196,23 @@ int main(int argc, char **argv) {
|
|||||||
die("Failed to allocate image.");
|
die("Failed to allocate image.");
|
||||||
}
|
}
|
||||||
|
|
||||||
keyframe_interval = strtol(keyframe_interval_arg, NULL, 0);
|
keyframe_interval = (int)strtol(keyframe_interval_arg, NULL, 0);
|
||||||
if (keyframe_interval < 0)
|
if (keyframe_interval < 0) die("Invalid keyframe interval value.");
|
||||||
die("Invalid keyframe interval value.");
|
|
||||||
|
|
||||||
printf("Using %s\n", vpx_codec_iface_name(encoder->codec_interface()));
|
printf("Using %s\n", vpx_codec_iface_name(encoder->codec_interface()));
|
||||||
|
|
||||||
res = vpx_codec_enc_config_default(encoder->codec_interface(), &cfg, 0);
|
res = vpx_codec_enc_config_default(encoder->codec_interface(), &cfg, 0);
|
||||||
if (res)
|
if (res) die_codec(&codec, "Failed to get default codec config.");
|
||||||
die_codec(&codec, "Failed to get default codec config.");
|
|
||||||
|
|
||||||
cfg.g_w = info.frame_width;
|
cfg.g_w = info.frame_width;
|
||||||
cfg.g_h = info.frame_height;
|
cfg.g_h = info.frame_height;
|
||||||
cfg.g_timebase.num = info.time_base.numerator;
|
cfg.g_timebase.num = info.time_base.numerator;
|
||||||
cfg.g_timebase.den = info.time_base.denominator;
|
cfg.g_timebase.den = info.time_base.denominator;
|
||||||
cfg.rc_target_bitrate = bitrate;
|
cfg.rc_target_bitrate = bitrate;
|
||||||
cfg.g_error_resilient = argc > 7 ? strtol(argv[7], NULL, 0) : 0;
|
cfg.g_error_resilient = (vpx_codec_er_flags_t)strtoul(argv[7], NULL, 0);
|
||||||
|
|
||||||
writer = vpx_video_writer_open(outfile_arg, kContainerIVF, &info);
|
writer = vpx_video_writer_open(outfile_arg, kContainerIVF, &info);
|
||||||
if (!writer)
|
if (!writer) die("Failed to open %s for writing.", outfile_arg);
|
||||||
die("Failed to open %s for writing.", outfile_arg);
|
|
||||||
|
|
||||||
if (!(infile = fopen(infile_arg, "rb")))
|
if (!(infile = fopen(infile_arg, "rb")))
|
||||||
die("Failed to open %s for reading.", infile_arg);
|
die("Failed to open %s for reading.", infile_arg);
|
||||||
@@ -237,18 +226,20 @@ int main(int argc, char **argv) {
|
|||||||
if (keyframe_interval > 0 && frame_count % keyframe_interval == 0)
|
if (keyframe_interval > 0 && frame_count % keyframe_interval == 0)
|
||||||
flags |= VPX_EFLAG_FORCE_KF;
|
flags |= VPX_EFLAG_FORCE_KF;
|
||||||
encode_frame(&codec, &raw, frame_count++, flags, writer);
|
encode_frame(&codec, &raw, frame_count++, flags, writer);
|
||||||
|
frames_encoded++;
|
||||||
|
if (max_frames > 0 && frames_encoded >= max_frames) break;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Flush encoder.
|
// Flush encoder.
|
||||||
while (encode_frame(&codec, NULL, -1, 0, writer)) {};
|
while (encode_frame(&codec, NULL, -1, 0, writer)) {
|
||||||
|
}
|
||||||
|
|
||||||
printf("\n");
|
printf("\n");
|
||||||
fclose(infile);
|
fclose(infile);
|
||||||
printf("Processed %d frames.\n", frame_count);
|
printf("Processed %d frames.\n", frame_count);
|
||||||
|
|
||||||
vpx_img_free(&raw);
|
vpx_img_free(&raw);
|
||||||
if (vpx_codec_destroy(&codec))
|
if (vpx_codec_destroy(&codec)) die_codec(&codec, "Failed to destroy codec.");
|
||||||
die_codec(&codec, "Failed to destroy codec.");
|
|
||||||
|
|
||||||
vpx_video_writer_close(writer);
|
vpx_video_writer_close(writer);
|
||||||
|
|
||||||
|
|||||||
@@ -59,25 +59,23 @@
|
|||||||
static const char *exec_name;
|
static const char *exec_name;
|
||||||
|
|
||||||
void usage_exit(void) {
|
void usage_exit(void) {
|
||||||
fprintf(stderr, "Usage: %s <codec> <width> <height> <infile> <outfile>\n",
|
fprintf(stderr,
|
||||||
|
"Usage: %s <codec> <width> <height> <infile> <outfile> "
|
||||||
|
"<frame limit>\n",
|
||||||
exec_name);
|
exec_name);
|
||||||
exit(EXIT_FAILURE);
|
exit(EXIT_FAILURE);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int get_frame_stats(vpx_codec_ctx_t *ctx,
|
static int get_frame_stats(vpx_codec_ctx_t *ctx, const vpx_image_t *img,
|
||||||
const vpx_image_t *img,
|
vpx_codec_pts_t pts, unsigned int duration,
|
||||||
vpx_codec_pts_t pts,
|
vpx_enc_frame_flags_t flags, unsigned int deadline,
|
||||||
unsigned int duration,
|
|
||||||
vpx_enc_frame_flags_t flags,
|
|
||||||
unsigned int deadline,
|
|
||||||
vpx_fixed_buf_t *stats) {
|
vpx_fixed_buf_t *stats) {
|
||||||
int got_pkts = 0;
|
int got_pkts = 0;
|
||||||
vpx_codec_iter_t iter = NULL;
|
vpx_codec_iter_t iter = NULL;
|
||||||
const vpx_codec_cx_pkt_t *pkt = NULL;
|
const vpx_codec_cx_pkt_t *pkt = NULL;
|
||||||
const vpx_codec_err_t res = vpx_codec_encode(ctx, img, pts, duration, flags,
|
const vpx_codec_err_t res =
|
||||||
deadline);
|
vpx_codec_encode(ctx, img, pts, duration, flags, deadline);
|
||||||
if (res != VPX_CODEC_OK)
|
if (res != VPX_CODEC_OK) die_codec(ctx, "Failed to get frame stats.");
|
||||||
die_codec(ctx, "Failed to get frame stats.");
|
|
||||||
|
|
||||||
while ((pkt = vpx_codec_get_cx_data(ctx, &iter)) != NULL) {
|
while ((pkt = vpx_codec_get_cx_data(ctx, &iter)) != NULL) {
|
||||||
got_pkts = 1;
|
got_pkts = 1;
|
||||||
@@ -94,20 +92,16 @@ static int get_frame_stats(vpx_codec_ctx_t *ctx,
|
|||||||
return got_pkts;
|
return got_pkts;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int encode_frame(vpx_codec_ctx_t *ctx,
|
static int encode_frame(vpx_codec_ctx_t *ctx, const vpx_image_t *img,
|
||||||
const vpx_image_t *img,
|
vpx_codec_pts_t pts, unsigned int duration,
|
||||||
vpx_codec_pts_t pts,
|
vpx_enc_frame_flags_t flags, unsigned int deadline,
|
||||||
unsigned int duration,
|
|
||||||
vpx_enc_frame_flags_t flags,
|
|
||||||
unsigned int deadline,
|
|
||||||
VpxVideoWriter *writer) {
|
VpxVideoWriter *writer) {
|
||||||
int got_pkts = 0;
|
int got_pkts = 0;
|
||||||
vpx_codec_iter_t iter = NULL;
|
vpx_codec_iter_t iter = NULL;
|
||||||
const vpx_codec_cx_pkt_t *pkt = NULL;
|
const vpx_codec_cx_pkt_t *pkt = NULL;
|
||||||
const vpx_codec_err_t res = vpx_codec_encode(ctx, img, pts, duration, flags,
|
const vpx_codec_err_t res =
|
||||||
deadline);
|
vpx_codec_encode(ctx, img, pts, duration, flags, deadline);
|
||||||
if (res != VPX_CODEC_OK)
|
if (res != VPX_CODEC_OK) die_codec(ctx, "Failed to encode frame.");
|
||||||
die_codec(ctx, "Failed to encode frame.");
|
|
||||||
|
|
||||||
while ((pkt = vpx_codec_get_cx_data(ctx, &iter)) != NULL) {
|
while ((pkt = vpx_codec_get_cx_data(ctx, &iter)) != NULL) {
|
||||||
got_pkts = 1;
|
got_pkts = 1;
|
||||||
@@ -126,10 +120,9 @@ static int encode_frame(vpx_codec_ctx_t *ctx,
|
|||||||
return got_pkts;
|
return got_pkts;
|
||||||
}
|
}
|
||||||
|
|
||||||
static vpx_fixed_buf_t pass0(vpx_image_t *raw,
|
static vpx_fixed_buf_t pass0(vpx_image_t *raw, FILE *infile,
|
||||||
FILE *infile,
|
|
||||||
const VpxInterface *encoder,
|
const VpxInterface *encoder,
|
||||||
const vpx_codec_enc_cfg_t *cfg) {
|
const vpx_codec_enc_cfg_t *cfg, int max_frames) {
|
||||||
vpx_codec_ctx_t codec;
|
vpx_codec_ctx_t codec;
|
||||||
int frame_count = 0;
|
int frame_count = 0;
|
||||||
vpx_fixed_buf_t stats = { NULL, 0 };
|
vpx_fixed_buf_t stats = { NULL, 0 };
|
||||||
@@ -142,37 +135,33 @@ static vpx_fixed_buf_t pass0(vpx_image_t *raw,
|
|||||||
++frame_count;
|
++frame_count;
|
||||||
get_frame_stats(&codec, raw, frame_count, 1, 0, VPX_DL_GOOD_QUALITY,
|
get_frame_stats(&codec, raw, frame_count, 1, 0, VPX_DL_GOOD_QUALITY,
|
||||||
&stats);
|
&stats);
|
||||||
|
if (max_frames > 0 && frame_count >= max_frames) break;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Flush encoder.
|
// Flush encoder.
|
||||||
while (get_frame_stats(&codec, NULL, frame_count, 1, 0,
|
while (get_frame_stats(&codec, NULL, frame_count, 1, 0, VPX_DL_GOOD_QUALITY,
|
||||||
VPX_DL_GOOD_QUALITY, &stats)) {}
|
&stats)) {
|
||||||
|
}
|
||||||
|
|
||||||
printf("Pass 0 complete. Processed %d frames.\n", frame_count);
|
printf("Pass 0 complete. Processed %d frames.\n", frame_count);
|
||||||
if (vpx_codec_destroy(&codec))
|
if (vpx_codec_destroy(&codec)) die_codec(&codec, "Failed to destroy codec.");
|
||||||
die_codec(&codec, "Failed to destroy codec.");
|
|
||||||
|
|
||||||
return stats;
|
return stats;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void pass1(vpx_image_t *raw,
|
static void pass1(vpx_image_t *raw, FILE *infile, const char *outfile_name,
|
||||||
FILE *infile,
|
const VpxInterface *encoder, const vpx_codec_enc_cfg_t *cfg,
|
||||||
const char *outfile_name,
|
int max_frames) {
|
||||||
const VpxInterface *encoder,
|
VpxVideoInfo info = { encoder->fourcc,
|
||||||
const vpx_codec_enc_cfg_t *cfg) {
|
|
||||||
VpxVideoInfo info = {
|
|
||||||
encoder->fourcc,
|
|
||||||
cfg->g_w,
|
cfg->g_w,
|
||||||
cfg->g_h,
|
cfg->g_h,
|
||||||
{cfg->g_timebase.num, cfg->g_timebase.den}
|
{ cfg->g_timebase.num, cfg->g_timebase.den } };
|
||||||
};
|
|
||||||
VpxVideoWriter *writer = NULL;
|
VpxVideoWriter *writer = NULL;
|
||||||
vpx_codec_ctx_t codec;
|
vpx_codec_ctx_t codec;
|
||||||
int frame_count = 0;
|
int frame_count = 0;
|
||||||
|
|
||||||
writer = vpx_video_writer_open(outfile_name, kContainerIVF, &info);
|
writer = vpx_video_writer_open(outfile_name, kContainerIVF, &info);
|
||||||
if (!writer)
|
if (!writer) die("Failed to open %s for writing", outfile_name);
|
||||||
die("Failed to open %s for writing", outfile_name);
|
|
||||||
|
|
||||||
if (vpx_codec_enc_init(&codec, encoder->codec_interface(), cfg, 0))
|
if (vpx_codec_enc_init(&codec, encoder->codec_interface(), cfg, 0))
|
||||||
die_codec(&codec, "Failed to initialize encoder");
|
die_codec(&codec, "Failed to initialize encoder");
|
||||||
@@ -181,15 +170,17 @@ static void pass1(vpx_image_t *raw,
|
|||||||
while (vpx_img_read(raw, infile)) {
|
while (vpx_img_read(raw, infile)) {
|
||||||
++frame_count;
|
++frame_count;
|
||||||
encode_frame(&codec, raw, frame_count, 1, 0, VPX_DL_GOOD_QUALITY, writer);
|
encode_frame(&codec, raw, frame_count, 1, 0, VPX_DL_GOOD_QUALITY, writer);
|
||||||
|
|
||||||
|
if (max_frames > 0 && frame_count >= max_frames) break;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Flush encoder.
|
// Flush encoder.
|
||||||
while (encode_frame(&codec, NULL, -1, 1, 0, VPX_DL_GOOD_QUALITY, writer)) {}
|
while (encode_frame(&codec, NULL, -1, 1, 0, VPX_DL_GOOD_QUALITY, writer)) {
|
||||||
|
}
|
||||||
|
|
||||||
printf("\n");
|
printf("\n");
|
||||||
|
|
||||||
if (vpx_codec_destroy(&codec))
|
if (vpx_codec_destroy(&codec)) die_codec(&codec, "Failed to destroy codec.");
|
||||||
die_codec(&codec, "Failed to destroy codec.");
|
|
||||||
|
|
||||||
vpx_video_writer_close(writer);
|
vpx_video_writer_close(writer);
|
||||||
|
|
||||||
@@ -213,17 +204,18 @@ int main(int argc, char **argv) {
|
|||||||
const char *const height_arg = argv[3];
|
const char *const height_arg = argv[3];
|
||||||
const char *const infile_arg = argv[4];
|
const char *const infile_arg = argv[4];
|
||||||
const char *const outfile_arg = argv[5];
|
const char *const outfile_arg = argv[5];
|
||||||
|
int max_frames = 0;
|
||||||
exec_name = argv[0];
|
exec_name = argv[0];
|
||||||
|
|
||||||
if (argc != 6)
|
if (argc != 7) die("Invalid number of arguments.");
|
||||||
die("Invalid number of arguments.");
|
|
||||||
|
max_frames = (int)strtol(argv[6], NULL, 0);
|
||||||
|
|
||||||
encoder = get_vpx_encoder_by_name(codec_arg);
|
encoder = get_vpx_encoder_by_name(codec_arg);
|
||||||
if (!encoder)
|
if (!encoder) die("Unsupported codec.");
|
||||||
die("Unsupported codec.");
|
|
||||||
|
|
||||||
w = strtol(width_arg, NULL, 0);
|
w = (int)strtol(width_arg, NULL, 0);
|
||||||
h = strtol(height_arg, NULL, 0);
|
h = (int)strtol(height_arg, NULL, 0);
|
||||||
|
|
||||||
if (w <= 0 || h <= 0 || (w % 2) != 0 || (h % 2) != 0)
|
if (w <= 0 || h <= 0 || (w % 2) != 0 || (h % 2) != 0)
|
||||||
die("Invalid frame size: %dx%d", w, h);
|
die("Invalid frame size: %dx%d", w, h);
|
||||||
@@ -235,8 +227,7 @@ int main(int argc, char **argv) {
|
|||||||
|
|
||||||
// Configuration
|
// Configuration
|
||||||
res = vpx_codec_enc_config_default(encoder->codec_interface(), &cfg, 0);
|
res = vpx_codec_enc_config_default(encoder->codec_interface(), &cfg, 0);
|
||||||
if (res)
|
if (res) die_codec(&codec, "Failed to get default codec config.");
|
||||||
die_codec(&codec, "Failed to get default codec config.");
|
|
||||||
|
|
||||||
cfg.g_w = w;
|
cfg.g_w = w;
|
||||||
cfg.g_h = h;
|
cfg.g_h = h;
|
||||||
@@ -249,13 +240,13 @@ int main(int argc, char **argv) {
|
|||||||
|
|
||||||
// Pass 0
|
// Pass 0
|
||||||
cfg.g_pass = VPX_RC_FIRST_PASS;
|
cfg.g_pass = VPX_RC_FIRST_PASS;
|
||||||
stats = pass0(&raw, infile, encoder, &cfg);
|
stats = pass0(&raw, infile, encoder, &cfg, max_frames);
|
||||||
|
|
||||||
// Pass 1
|
// Pass 1
|
||||||
rewind(infile);
|
rewind(infile);
|
||||||
cfg.g_pass = VPX_RC_LAST_PASS;
|
cfg.g_pass = VPX_RC_LAST_PASS;
|
||||||
cfg.rc_twopass_stats_in = stats;
|
cfg.rc_twopass_stats_in = stats;
|
||||||
pass1(&raw, infile, outfile_arg, encoder, &cfg);
|
pass1(&raw, infile, outfile_arg, encoder, &cfg, max_frames);
|
||||||
free(stats.buf);
|
free(stats.buf);
|
||||||
|
|
||||||
vpx_img_free(&raw);
|
vpx_img_free(&raw);
|
||||||
|
|||||||
@@ -37,9 +37,7 @@
|
|||||||
#define interface (vpx_codec_vp8_cx())
|
#define interface (vpx_codec_vp8_cx())
|
||||||
#define fourcc 0x30385056
|
#define fourcc 0x30385056
|
||||||
|
|
||||||
void usage_exit(void) {
|
void usage_exit(void) { exit(EXIT_FAILURE); }
|
||||||
exit(EXIT_FAILURE);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* The input video frame is downsampled several times to generate a multi-level
|
* The input video frame is downsampled several times to generate a multi-level
|
||||||
@@ -82,8 +80,7 @@ static int read_frame_by_row(FILE *f, vpx_image_t *img) {
|
|||||||
int res = 1;
|
int res = 1;
|
||||||
int plane;
|
int plane;
|
||||||
|
|
||||||
for (plane = 0; plane < 3; plane++)
|
for (plane = 0; plane < 3; plane++) {
|
||||||
{
|
|
||||||
unsigned char *ptr;
|
unsigned char *ptr;
|
||||||
int w = (plane ? (1 + img->d_w) / 2 : img->d_w);
|
int w = (plane ? (1 + img->d_w) / 2 : img->d_w);
|
||||||
int h = (plane ? (1 + img->d_h) / 2 : img->d_h);
|
int h = (plane ? (1 + img->d_h) / 2 : img->d_h);
|
||||||
@@ -93,20 +90,19 @@ static int read_frame_by_row(FILE *f, vpx_image_t *img) {
|
|||||||
* always counts in Y,U,V order, but this may not match the order of
|
* always counts in Y,U,V order, but this may not match the order of
|
||||||
* the data on disk.
|
* the data on disk.
|
||||||
*/
|
*/
|
||||||
switch (plane)
|
switch (plane) {
|
||||||
{
|
|
||||||
case 1:
|
case 1:
|
||||||
ptr = img->planes[img->fmt==VPX_IMG_FMT_YV12? VPX_PLANE_V : VPX_PLANE_U];
|
ptr = img->planes[img->fmt == VPX_IMG_FMT_YV12 ? VPX_PLANE_V
|
||||||
|
: VPX_PLANE_U];
|
||||||
break;
|
break;
|
||||||
case 2:
|
case 2:
|
||||||
ptr = img->planes[img->fmt==VPX_IMG_FMT_YV12?VPX_PLANE_U : VPX_PLANE_V];
|
ptr = img->planes[img->fmt == VPX_IMG_FMT_YV12 ? VPX_PLANE_U
|
||||||
|
: VPX_PLANE_V];
|
||||||
break;
|
break;
|
||||||
default:
|
default: ptr = img->planes[plane];
|
||||||
ptr = img->planes[plane];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
for (r = 0; r < h; r++)
|
for (r = 0; r < h; r++) {
|
||||||
{
|
|
||||||
to_read = w;
|
to_read = w;
|
||||||
|
|
||||||
nbytes = fread(ptr, 1, to_read, f);
|
nbytes = fread(ptr, 1, to_read, f);
|
||||||
@@ -119,20 +115,17 @@ static int read_frame_by_row(FILE *f, vpx_image_t *img) {
|
|||||||
|
|
||||||
ptr += img->stride[plane];
|
ptr += img->stride[plane];
|
||||||
}
|
}
|
||||||
if (!res)
|
if (!res) break;
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void write_ivf_file_header(FILE *outfile,
|
static void write_ivf_file_header(FILE *outfile, const vpx_codec_enc_cfg_t *cfg,
|
||||||
const vpx_codec_enc_cfg_t *cfg,
|
|
||||||
int frame_cnt) {
|
int frame_cnt) {
|
||||||
char header[32];
|
char header[32];
|
||||||
|
|
||||||
if(cfg->g_pass != VPX_RC_ONE_PASS && cfg->g_pass != VPX_RC_LAST_PASS)
|
if (cfg->g_pass != VPX_RC_ONE_PASS && cfg->g_pass != VPX_RC_LAST_PASS) return;
|
||||||
return;
|
|
||||||
header[0] = 'D';
|
header[0] = 'D';
|
||||||
header[1] = 'K';
|
header[1] = 'K';
|
||||||
header[2] = 'I';
|
header[2] = 'I';
|
||||||
@@ -151,13 +144,11 @@ static void write_ivf_file_header(FILE *outfile,
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void write_ivf_frame_header(FILE *outfile,
|
static void write_ivf_frame_header(FILE *outfile,
|
||||||
const vpx_codec_cx_pkt_t *pkt)
|
const vpx_codec_cx_pkt_t *pkt) {
|
||||||
{
|
|
||||||
char header[12];
|
char header[12];
|
||||||
vpx_codec_pts_t pts;
|
vpx_codec_pts_t pts;
|
||||||
|
|
||||||
if(pkt->kind != VPX_CODEC_CX_FRAME_PKT)
|
if (pkt->kind != VPX_CODEC_CX_FRAME_PKT) return;
|
||||||
return;
|
|
||||||
|
|
||||||
pts = pkt->data.frame.pts;
|
pts = pkt->data.frame.pts;
|
||||||
mem_put_le32(header, pkt->data.frame.sz);
|
mem_put_le32(header, pkt->data.frame.sz);
|
||||||
@@ -173,15 +164,11 @@ static void write_ivf_frame_header(FILE *outfile,
|
|||||||
* parameters will be passed in as user parameters in another version.
|
* parameters will be passed in as user parameters in another version.
|
||||||
*/
|
*/
|
||||||
static void set_temporal_layer_pattern(int num_temporal_layers,
|
static void set_temporal_layer_pattern(int num_temporal_layers,
|
||||||
vpx_codec_enc_cfg_t *cfg,
|
vpx_codec_enc_cfg_t *cfg, int bitrate,
|
||||||
int bitrate,
|
int *layer_flags) {
|
||||||
int *layer_flags)
|
|
||||||
{
|
|
||||||
assert(num_temporal_layers <= MAX_NUM_TEMPORAL_LAYERS);
|
assert(num_temporal_layers <= MAX_NUM_TEMPORAL_LAYERS);
|
||||||
switch (num_temporal_layers)
|
switch (num_temporal_layers) {
|
||||||
{
|
case 1: {
|
||||||
case 1:
|
|
||||||
{
|
|
||||||
/* 1-layer */
|
/* 1-layer */
|
||||||
cfg->ts_number_layers = 1;
|
cfg->ts_number_layers = 1;
|
||||||
cfg->ts_periodicity = 1;
|
cfg->ts_periodicity = 1;
|
||||||
@@ -194,8 +181,7 @@ static void set_temporal_layer_pattern(int num_temporal_layers,
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
case 2:
|
case 2: {
|
||||||
{
|
|
||||||
/* 2-layers, with sync point at first frame of layer 1. */
|
/* 2-layers, with sync point at first frame of layer 1. */
|
||||||
cfg->ts_number_layers = 2;
|
cfg->ts_number_layers = 2;
|
||||||
cfg->ts_periodicity = 2;
|
cfg->ts_periodicity = 2;
|
||||||
@@ -212,22 +198,18 @@ static void set_temporal_layer_pattern(int num_temporal_layers,
|
|||||||
// key frame. Sync point every 8 frames.
|
// key frame. Sync point every 8 frames.
|
||||||
|
|
||||||
// Layer 0: predict from L and ARF, update L and G.
|
// Layer 0: predict from L and ARF, update L and G.
|
||||||
layer_flags[0] = VP8_EFLAG_NO_REF_GF |
|
layer_flags[0] = VP8_EFLAG_NO_REF_GF | VP8_EFLAG_NO_UPD_ARF;
|
||||||
VP8_EFLAG_NO_UPD_ARF;
|
|
||||||
|
|
||||||
// Layer 1: sync point: predict from L and ARF, and update G.
|
// Layer 1: sync point: predict from L and ARF, and update G.
|
||||||
layer_flags[1] = VP8_EFLAG_NO_REF_GF |
|
layer_flags[1] =
|
||||||
VP8_EFLAG_NO_UPD_LAST |
|
VP8_EFLAG_NO_REF_GF | VP8_EFLAG_NO_UPD_LAST | VP8_EFLAG_NO_UPD_ARF;
|
||||||
VP8_EFLAG_NO_UPD_ARF;
|
|
||||||
|
|
||||||
// Layer 0, predict from L and ARF, update L.
|
// Layer 0, predict from L and ARF, update L.
|
||||||
layer_flags[2] = VP8_EFLAG_NO_REF_GF |
|
layer_flags[2] =
|
||||||
VP8_EFLAG_NO_UPD_GF |
|
VP8_EFLAG_NO_REF_GF | VP8_EFLAG_NO_UPD_GF | VP8_EFLAG_NO_UPD_ARF;
|
||||||
VP8_EFLAG_NO_UPD_ARF;
|
|
||||||
|
|
||||||
// Layer 1: predict from L, G and ARF, and update G.
|
// Layer 1: predict from L, G and ARF, and update G.
|
||||||
layer_flags[3] = VP8_EFLAG_NO_UPD_ARF |
|
layer_flags[3] = VP8_EFLAG_NO_UPD_ARF | VP8_EFLAG_NO_UPD_LAST |
|
||||||
VP8_EFLAG_NO_UPD_LAST |
|
|
||||||
VP8_EFLAG_NO_UPD_ENTROPY;
|
VP8_EFLAG_NO_UPD_ENTROPY;
|
||||||
|
|
||||||
// Layer 0
|
// Layer 0
|
||||||
@@ -245,8 +227,7 @@ static void set_temporal_layer_pattern(int num_temporal_layers,
|
|||||||
}
|
}
|
||||||
|
|
||||||
case 3:
|
case 3:
|
||||||
default:
|
default: {
|
||||||
{
|
|
||||||
// 3-layers structure where ARF is used as predictor for all frames,
|
// 3-layers structure where ARF is used as predictor for all frames,
|
||||||
// and is only updated on key frame.
|
// and is only updated on key frame.
|
||||||
// Sync points for layer 1 and 2 every 8 frames.
|
// Sync points for layer 1 and 2 every 8 frames.
|
||||||
@@ -259,46 +240,38 @@ static void set_temporal_layer_pattern(int num_temporal_layers,
|
|||||||
cfg->ts_layer_id[1] = 2;
|
cfg->ts_layer_id[1] = 2;
|
||||||
cfg->ts_layer_id[2] = 1;
|
cfg->ts_layer_id[2] = 1;
|
||||||
cfg->ts_layer_id[3] = 2;
|
cfg->ts_layer_id[3] = 2;
|
||||||
// Use 40/20/40 bit allocation as example.
|
// Use 45/20/35 bit allocation as example.
|
||||||
cfg->ts_target_bitrate[0] = 0.4f * bitrate;
|
cfg->ts_target_bitrate[0] = 0.45f * bitrate;
|
||||||
cfg->ts_target_bitrate[1] = 0.6f * bitrate;
|
cfg->ts_target_bitrate[1] = 0.65f * bitrate;
|
||||||
cfg->ts_target_bitrate[2] = bitrate;
|
cfg->ts_target_bitrate[2] = bitrate;
|
||||||
|
|
||||||
/* 0=L, 1=GF, 2=ARF */
|
/* 0=L, 1=GF, 2=ARF */
|
||||||
|
|
||||||
// Layer 0: predict from L and ARF; update L and G.
|
// Layer 0: predict from L and ARF; update L and G.
|
||||||
layer_flags[0] = VP8_EFLAG_NO_UPD_ARF |
|
layer_flags[0] = VP8_EFLAG_NO_UPD_ARF | VP8_EFLAG_NO_REF_GF;
|
||||||
VP8_EFLAG_NO_REF_GF;
|
|
||||||
|
|
||||||
// Layer 2: sync point: predict from L and ARF; update none.
|
// Layer 2: sync point: predict from L and ARF; update none.
|
||||||
layer_flags[1] = VP8_EFLAG_NO_REF_GF |
|
layer_flags[1] = VP8_EFLAG_NO_REF_GF | VP8_EFLAG_NO_UPD_GF |
|
||||||
VP8_EFLAG_NO_UPD_GF |
|
VP8_EFLAG_NO_UPD_ARF | VP8_EFLAG_NO_UPD_LAST |
|
||||||
VP8_EFLAG_NO_UPD_ARF |
|
|
||||||
VP8_EFLAG_NO_UPD_LAST |
|
|
||||||
VP8_EFLAG_NO_UPD_ENTROPY;
|
VP8_EFLAG_NO_UPD_ENTROPY;
|
||||||
|
|
||||||
// Layer 1: sync point: predict from L and ARF; update G.
|
// Layer 1: sync point: predict from L and ARF; update G.
|
||||||
layer_flags[2] = VP8_EFLAG_NO_REF_GF |
|
layer_flags[2] =
|
||||||
VP8_EFLAG_NO_UPD_ARF |
|
VP8_EFLAG_NO_REF_GF | VP8_EFLAG_NO_UPD_ARF | VP8_EFLAG_NO_UPD_LAST;
|
||||||
VP8_EFLAG_NO_UPD_LAST;
|
|
||||||
|
|
||||||
// Layer 2: predict from L, G, ARF; update none.
|
// Layer 2: predict from L, G, ARF; update none.
|
||||||
layer_flags[3] = VP8_EFLAG_NO_UPD_GF |
|
layer_flags[3] = VP8_EFLAG_NO_UPD_GF | VP8_EFLAG_NO_UPD_ARF |
|
||||||
VP8_EFLAG_NO_UPD_ARF |
|
VP8_EFLAG_NO_UPD_LAST | VP8_EFLAG_NO_UPD_ENTROPY;
|
||||||
VP8_EFLAG_NO_UPD_LAST |
|
|
||||||
VP8_EFLAG_NO_UPD_ENTROPY;
|
|
||||||
|
|
||||||
// Layer 0: predict from L and ARF; update L.
|
// Layer 0: predict from L and ARF; update L.
|
||||||
layer_flags[4] = VP8_EFLAG_NO_UPD_GF |
|
layer_flags[4] =
|
||||||
VP8_EFLAG_NO_UPD_ARF |
|
VP8_EFLAG_NO_UPD_GF | VP8_EFLAG_NO_UPD_ARF | VP8_EFLAG_NO_REF_GF;
|
||||||
VP8_EFLAG_NO_REF_GF;
|
|
||||||
|
|
||||||
// Layer 2: predict from L, G, ARF; update none.
|
// Layer 2: predict from L, G, ARF; update none.
|
||||||
layer_flags[5] = layer_flags[3];
|
layer_flags[5] = layer_flags[3];
|
||||||
|
|
||||||
// Layer 1: predict from L, G, ARF; update G.
|
// Layer 1: predict from L, G, ARF; update G.
|
||||||
layer_flags[6] = VP8_EFLAG_NO_UPD_ARF |
|
layer_flags[6] = VP8_EFLAG_NO_UPD_ARF | VP8_EFLAG_NO_UPD_LAST;
|
||||||
VP8_EFLAG_NO_UPD_LAST;
|
|
||||||
|
|
||||||
// Layer 2: predict from L, G, ARF; update none.
|
// Layer 2: predict from L, G, ARF; update none.
|
||||||
layer_flags[7] = layer_flags[3];
|
layer_flags[7] = layer_flags[3];
|
||||||
@@ -310,8 +283,7 @@ static void set_temporal_layer_pattern(int num_temporal_layers,
|
|||||||
/* The periodicity of the pattern given the number of temporal layers. */
|
/* The periodicity of the pattern given the number of temporal layers. */
|
||||||
static int periodicity_to_num_layers[MAX_NUM_TEMPORAL_LAYERS] = { 1, 8, 8 };
|
static int periodicity_to_num_layers[MAX_NUM_TEMPORAL_LAYERS] = { 1, 8, 8 };
|
||||||
|
|
||||||
int main(int argc, char **argv)
|
int main(int argc, char **argv) {
|
||||||
{
|
|
||||||
FILE *infile, *outfile[NUM_ENCODERS];
|
FILE *infile, *outfile[NUM_ENCODERS];
|
||||||
FILE *downsampled_input[NUM_ENCODERS - 1];
|
FILE *downsampled_input[NUM_ENCODERS - 1];
|
||||||
char filename[50];
|
char filename[50];
|
||||||
@@ -330,8 +302,7 @@ int main(int argc, char **argv)
|
|||||||
int flags = 0;
|
int flags = 0;
|
||||||
int layer_id = 0;
|
int layer_id = 0;
|
||||||
|
|
||||||
int layer_flags[VPX_TS_MAX_PERIODICITY * NUM_ENCODERS]
|
int layer_flags[VPX_TS_MAX_PERIODICITY * NUM_ENCODERS] = { 0 };
|
||||||
= {0};
|
|
||||||
int flag_periodicity;
|
int flag_periodicity;
|
||||||
|
|
||||||
/*Currently, only realtime mode is supported in multi-resolution encoding.*/
|
/*Currently, only realtime mode is supported in multi-resolution encoding.*/
|
||||||
@@ -370,7 +341,8 @@ int main(int argc, char **argv)
|
|||||||
|
|
||||||
if (argc != (7 + 3 * NUM_ENCODERS))
|
if (argc != (7 + 3 * NUM_ENCODERS))
|
||||||
die("Usage: %s <width> <height> <frame_rate> <infile> <outfile(s)> "
|
die("Usage: %s <width> <height> <frame_rate> <infile> <outfile(s)> "
|
||||||
"<rate_encoder(s)> <temporal_layer(s)> <key_frame_insert> <output psnr?> \n",
|
"<rate_encoder(s)> <temporal_layer(s)> <key_frame_insert> <output "
|
||||||
|
"psnr?> \n",
|
||||||
argv[0]);
|
argv[0]);
|
||||||
|
|
||||||
printf("Using %s\n", vpx_codec_iface_name(interface));
|
printf("Using %s\n", vpx_codec_iface_name(interface));
|
||||||
@@ -387,10 +359,8 @@ int main(int argc, char **argv)
|
|||||||
die("Failed to open %s for reading", argv[4]);
|
die("Failed to open %s for reading", argv[4]);
|
||||||
|
|
||||||
/* Open output file for each encoder to output bitstreams */
|
/* Open output file for each encoder to output bitstreams */
|
||||||
for (i=0; i< NUM_ENCODERS; i++)
|
for (i = 0; i < NUM_ENCODERS; i++) {
|
||||||
{
|
if (!target_bitrate[i]) {
|
||||||
if(!target_bitrate[i])
|
|
||||||
{
|
|
||||||
outfile[i] = NULL;
|
outfile[i] = NULL;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@@ -400,14 +370,12 @@ int main(int argc, char **argv)
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Bitrates per spatial layer: overwrite default rates above.
|
// Bitrates per spatial layer: overwrite default rates above.
|
||||||
for (i=0; i< NUM_ENCODERS; i++)
|
for (i = 0; i < NUM_ENCODERS; i++) {
|
||||||
{
|
|
||||||
target_bitrate[i] = strtol(argv[NUM_ENCODERS + 5 + i], NULL, 0);
|
target_bitrate[i] = strtol(argv[NUM_ENCODERS + 5 + i], NULL, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Temporal layers per spatial layers: overwrite default settings above.
|
// Temporal layers per spatial layers: overwrite default settings above.
|
||||||
for (i=0; i< NUM_ENCODERS; i++)
|
for (i = 0; i < NUM_ENCODERS; i++) {
|
||||||
{
|
|
||||||
num_temporal_layers[i] = strtol(argv[2 * NUM_ENCODERS + 5 + i], NULL, 0);
|
num_temporal_layers[i] = strtol(argv[2 * NUM_ENCODERS + 5 + i], NULL, 0);
|
||||||
if (num_temporal_layers[i] < 1 || num_temporal_layers[i] > 3)
|
if (num_temporal_layers[i] < 1 || num_temporal_layers[i] > 3)
|
||||||
die("Invalid temporal layers: %d, Must be 1, 2, or 3. \n",
|
die("Invalid temporal layers: %d, Must be 1, 2, or 3. \n",
|
||||||
@@ -415,11 +383,9 @@ int main(int argc, char **argv)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Open file to write out each spatially downsampled input stream. */
|
/* Open file to write out each spatially downsampled input stream. */
|
||||||
for (i=0; i< NUM_ENCODERS - 1; i++)
|
for (i = 0; i < NUM_ENCODERS - 1; i++) {
|
||||||
{
|
|
||||||
// Highest resoln is encoder 0.
|
// Highest resoln is encoder 0.
|
||||||
if (sprintf(filename,"ds%d.yuv",NUM_ENCODERS - i) < 0)
|
if (sprintf(filename, "ds%d.yuv", NUM_ENCODERS - i) < 0) {
|
||||||
{
|
|
||||||
return EXIT_FAILURE;
|
return EXIT_FAILURE;
|
||||||
}
|
}
|
||||||
downsampled_input[i] = fopen(filename, "wb");
|
downsampled_input[i] = fopen(filename, "wb");
|
||||||
@@ -429,10 +395,8 @@ int main(int argc, char **argv)
|
|||||||
|
|
||||||
show_psnr = strtol(argv[3 * NUM_ENCODERS + 6], NULL, 0);
|
show_psnr = strtol(argv[3 * NUM_ENCODERS + 6], NULL, 0);
|
||||||
|
|
||||||
|
|
||||||
/* Populate default encoder configuration */
|
/* Populate default encoder configuration */
|
||||||
for (i=0; i< NUM_ENCODERS; i++)
|
for (i = 0; i < NUM_ENCODERS; i++) {
|
||||||
{
|
|
||||||
res[i] = vpx_codec_enc_config_default(interface, &cfg[i], 0);
|
res[i] = vpx_codec_enc_config_default(interface, &cfg[i], 0);
|
||||||
if (res[i]) {
|
if (res[i]) {
|
||||||
printf("Failed to get config: %s\n", vpx_codec_err_to_string(res[i]));
|
printf("Failed to get config: %s\n", vpx_codec_err_to_string(res[i]));
|
||||||
@@ -472,8 +436,7 @@ int main(int argc, char **argv)
|
|||||||
cfg[0].g_timebase.den = framerate;
|
cfg[0].g_timebase.den = framerate;
|
||||||
|
|
||||||
/* Other-resolution encoder settings */
|
/* Other-resolution encoder settings */
|
||||||
for (i=1; i< NUM_ENCODERS; i++)
|
for (i = 1; i < NUM_ENCODERS; i++) {
|
||||||
{
|
|
||||||
memcpy(&cfg[i], &cfg[0], sizeof(vpx_codec_enc_cfg_t));
|
memcpy(&cfg[i], &cfg[0], sizeof(vpx_codec_enc_cfg_t));
|
||||||
|
|
||||||
cfg[i].rc_target_bitrate = target_bitrate[i];
|
cfg[i].rc_target_bitrate = target_bitrate[i];
|
||||||
@@ -495,10 +458,9 @@ int main(int argc, char **argv)
|
|||||||
if ((cfg[i].g_h) % 2) cfg[i].g_h++;
|
if ((cfg[i].g_h) % 2) cfg[i].g_h++;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// Set the number of threads per encode/spatial layer.
|
// Set the number of threads per encode/spatial layer.
|
||||||
// (1, 1, 1) means no encoder threading.
|
// (1, 1, 1) means no encoder threading.
|
||||||
cfg[0].g_threads = 2;
|
cfg[0].g_threads = 1;
|
||||||
cfg[1].g_threads = 1;
|
cfg[1].g_threads = 1;
|
||||||
cfg[2].g_threads = 1;
|
cfg[2].g_threads = 1;
|
||||||
|
|
||||||
@@ -513,14 +475,11 @@ int main(int argc, char **argv)
|
|||||||
read_frame_p = read_frame_by_row;
|
read_frame_p = read_frame_by_row;
|
||||||
|
|
||||||
for (i = 0; i < NUM_ENCODERS; i++)
|
for (i = 0; i < NUM_ENCODERS; i++)
|
||||||
if(outfile[i])
|
if (outfile[i]) write_ivf_file_header(outfile[i], &cfg[i], 0);
|
||||||
write_ivf_file_header(outfile[i], &cfg[i], 0);
|
|
||||||
|
|
||||||
/* Temporal layers settings */
|
/* Temporal layers settings */
|
||||||
for ( i=0; i<NUM_ENCODERS; i++)
|
for (i = 0; i < NUM_ENCODERS; i++) {
|
||||||
{
|
set_temporal_layer_pattern(num_temporal_layers[i], &cfg[i],
|
||||||
set_temporal_layer_pattern(num_temporal_layers[i],
|
|
||||||
&cfg[i],
|
|
||||||
cfg[i].rc_target_bitrate,
|
cfg[i].rc_target_bitrate,
|
||||||
&layer_flags[i * VPX_TS_MAX_PERIODICITY]);
|
&layer_flags[i * VPX_TS_MAX_PERIODICITY]);
|
||||||
}
|
}
|
||||||
@@ -532,8 +491,7 @@ int main(int argc, char **argv)
|
|||||||
|
|
||||||
/* The extra encoding configuration parameters can be set as follows. */
|
/* The extra encoding configuration parameters can be set as follows. */
|
||||||
/* Set encoding speed */
|
/* Set encoding speed */
|
||||||
for ( i=0; i<NUM_ENCODERS; i++)
|
for (i = 0; i < NUM_ENCODERS; i++) {
|
||||||
{
|
|
||||||
int speed = -6;
|
int speed = -6;
|
||||||
/* Lower speed for the lowest resolution. */
|
/* Lower speed for the lowest resolution. */
|
||||||
if (i == NUM_ENCODERS - 1) speed = -4;
|
if (i == NUM_ENCODERS - 1) speed = -4;
|
||||||
@@ -542,8 +500,7 @@ int main(int argc, char **argv)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Set static threshold = 1 for all encoders */
|
/* Set static threshold = 1 for all encoders */
|
||||||
for ( i=0; i<NUM_ENCODERS; i++)
|
for (i = 0; i < NUM_ENCODERS; i++) {
|
||||||
{
|
|
||||||
if (vpx_codec_control(&codec[i], VP8E_SET_STATIC_THRESHOLD, 1))
|
if (vpx_codec_control(&codec[i], VP8E_SET_STATIC_THRESHOLD, 1))
|
||||||
die_codec(&codec[i], "Failed to set static threshold");
|
die_codec(&codec[i], "Failed to set static threshold");
|
||||||
}
|
}
|
||||||
@@ -552,22 +509,21 @@ int main(int argc, char **argv)
|
|||||||
/* Enable denoising for the highest-resolution encoder. */
|
/* Enable denoising for the highest-resolution encoder. */
|
||||||
if (vpx_codec_control(&codec[0], VP8E_SET_NOISE_SENSITIVITY, 1))
|
if (vpx_codec_control(&codec[0], VP8E_SET_NOISE_SENSITIVITY, 1))
|
||||||
die_codec(&codec[0], "Failed to set noise_sensitivity");
|
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))
|
if (vpx_codec_control(&codec[i], VP8E_SET_NOISE_SENSITIVITY, 0))
|
||||||
die_codec(&codec[i], "Failed to set noise_sensitivity");
|
die_codec(&codec[i], "Failed to set noise_sensitivity");
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Set the number of token partitions */
|
/* Set the number of token partitions */
|
||||||
for ( i=0; i<NUM_ENCODERS; i++)
|
for (i = 0; i < NUM_ENCODERS; i++) {
|
||||||
{
|
|
||||||
if (vpx_codec_control(&codec[i], VP8E_SET_TOKEN_PARTITIONS, 1))
|
if (vpx_codec_control(&codec[i], VP8E_SET_TOKEN_PARTITIONS, 1))
|
||||||
die_codec(&codec[i], "Failed to set static threshold");
|
die_codec(&codec[i], "Failed to set static threshold");
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Set the max intra target bitrate */
|
/* Set the max intra target bitrate */
|
||||||
for ( i=0; i<NUM_ENCODERS; i++)
|
for (i = 0; i < NUM_ENCODERS; i++) {
|
||||||
{
|
|
||||||
unsigned int max_intra_size_pct =
|
unsigned int max_intra_size_pct =
|
||||||
(int)(((double)cfg[0].rc_buf_optimal_sz * 0.5) * framerate / 10);
|
(int)(((double)cfg[0].rc_buf_optimal_sz * 0.5) * framerate / 10);
|
||||||
if (vpx_codec_control(&codec[i], VP8E_SET_MAX_INTRA_BITRATE_PCT,
|
if (vpx_codec_control(&codec[i], VP8E_SET_MAX_INTRA_BITRATE_PCT,
|
||||||
@@ -579,8 +535,7 @@ int main(int argc, char **argv)
|
|||||||
frame_avail = 1;
|
frame_avail = 1;
|
||||||
got_data = 0;
|
got_data = 0;
|
||||||
|
|
||||||
while(frame_avail || got_data)
|
while (frame_avail || got_data) {
|
||||||
{
|
|
||||||
struct vpx_usec_timer timer;
|
struct vpx_usec_timer timer;
|
||||||
vpx_codec_iter_t iter[NUM_ENCODERS] = { NULL };
|
vpx_codec_iter_t iter[NUM_ENCODERS] = { NULL };
|
||||||
const vpx_codec_cx_pkt_t *pkt[NUM_ENCODERS];
|
const vpx_codec_cx_pkt_t *pkt[NUM_ENCODERS];
|
||||||
@@ -588,47 +543,39 @@ int main(int argc, char **argv)
|
|||||||
flags = 0;
|
flags = 0;
|
||||||
frame_avail = read_frame_p(infile, &raw[0]);
|
frame_avail = read_frame_p(infile, &raw[0]);
|
||||||
|
|
||||||
if(frame_avail)
|
if (frame_avail) {
|
||||||
{
|
for (i = 1; i < NUM_ENCODERS; i++) {
|
||||||
for ( i=1; i<NUM_ENCODERS; i++)
|
|
||||||
{
|
|
||||||
/*Scale the image down a number of times by downsampling factor*/
|
/*Scale the image down a number of times by downsampling factor*/
|
||||||
/* FilterMode 1 or 2 give better psnr than FilterMode 0. */
|
/* FilterMode 1 or 2 give better psnr than FilterMode 0. */
|
||||||
I420Scale(raw[i-1].planes[VPX_PLANE_Y], raw[i-1].stride[VPX_PLANE_Y],
|
I420Scale(
|
||||||
|
raw[i - 1].planes[VPX_PLANE_Y], raw[i - 1].stride[VPX_PLANE_Y],
|
||||||
raw[i - 1].planes[VPX_PLANE_U], raw[i - 1].stride[VPX_PLANE_U],
|
raw[i - 1].planes[VPX_PLANE_U], raw[i - 1].stride[VPX_PLANE_U],
|
||||||
raw[i - 1].planes[VPX_PLANE_V], raw[i - 1].stride[VPX_PLANE_V],
|
raw[i - 1].planes[VPX_PLANE_V], raw[i - 1].stride[VPX_PLANE_V],
|
||||||
raw[i-1].d_w, raw[i-1].d_h,
|
raw[i - 1].d_w, raw[i - 1].d_h, raw[i].planes[VPX_PLANE_Y],
|
||||||
raw[i].planes[VPX_PLANE_Y], raw[i].stride[VPX_PLANE_Y],
|
raw[i].stride[VPX_PLANE_Y], raw[i].planes[VPX_PLANE_U],
|
||||||
raw[i].planes[VPX_PLANE_U], raw[i].stride[VPX_PLANE_U],
|
raw[i].stride[VPX_PLANE_U], raw[i].planes[VPX_PLANE_V],
|
||||||
raw[i].planes[VPX_PLANE_V], raw[i].stride[VPX_PLANE_V],
|
raw[i].stride[VPX_PLANE_V], raw[i].d_w, raw[i].d_h, 1);
|
||||||
raw[i].d_w, raw[i].d_h, 1);
|
|
||||||
/* Write out down-sampled input. */
|
/* Write out down-sampled input. */
|
||||||
length_frame = cfg[i].g_w * cfg[i].g_h * 3 / 2;
|
length_frame = cfg[i].g_w * cfg[i].g_h * 3 / 2;
|
||||||
if (fwrite(raw[i].planes[0], 1, length_frame,
|
if (fwrite(raw[i].planes[0], 1, length_frame,
|
||||||
downsampled_input[NUM_ENCODERS - i - 1]) !=
|
downsampled_input[NUM_ENCODERS - i - 1]) != length_frame) {
|
||||||
length_frame)
|
|
||||||
{
|
|
||||||
return EXIT_FAILURE;
|
return EXIT_FAILURE;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Set the flags (reference and update) for all the encoders.*/
|
/* Set the flags (reference and update) for all the encoders.*/
|
||||||
for ( i=0; i<NUM_ENCODERS; i++)
|
for (i = 0; i < NUM_ENCODERS; i++) {
|
||||||
{
|
|
||||||
layer_id = cfg[i].ts_layer_id[frame_cnt % cfg[i].ts_periodicity];
|
layer_id = cfg[i].ts_layer_id[frame_cnt % cfg[i].ts_periodicity];
|
||||||
flags = 0;
|
flags = 0;
|
||||||
flag_periodicity = periodicity_to_num_layers
|
flag_periodicity = periodicity_to_num_layers[num_temporal_layers[i] - 1];
|
||||||
[num_temporal_layers[i] - 1];
|
|
||||||
flags = layer_flags[i * VPX_TS_MAX_PERIODICITY +
|
flags = layer_flags[i * VPX_TS_MAX_PERIODICITY +
|
||||||
frame_cnt % flag_periodicity];
|
frame_cnt % flag_periodicity];
|
||||||
// Key frame flag for first frame.
|
// Key frame flag for first frame.
|
||||||
if (frame_cnt == 0)
|
if (frame_cnt == 0) {
|
||||||
{
|
|
||||||
flags |= VPX_EFLAG_FORCE_KF;
|
flags |= VPX_EFLAG_FORCE_KF;
|
||||||
}
|
}
|
||||||
if (frame_cnt > 0 && frame_cnt == key_frame_insert)
|
if (frame_cnt > 0 && frame_cnt == key_frame_insert) {
|
||||||
{
|
|
||||||
flags = VPX_EFLAG_FORCE_KF;
|
flags = VPX_EFLAG_FORCE_KF;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -640,46 +587,42 @@ int main(int argc, char **argv)
|
|||||||
/* Note the flags must be set to 0 in the encode call if they are set
|
/* Note the flags must be set to 0 in the encode call if they are set
|
||||||
for each frame with the vpx_codec_control(), as done above. */
|
for each frame with the vpx_codec_control(), as done above. */
|
||||||
vpx_usec_timer_start(&timer);
|
vpx_usec_timer_start(&timer);
|
||||||
if(vpx_codec_encode(&codec[0], frame_avail? &raw[0] : NULL,
|
if (vpx_codec_encode(&codec[0], frame_avail ? &raw[0] : NULL, frame_cnt, 1,
|
||||||
frame_cnt, 1, 0, arg_deadline))
|
0, arg_deadline)) {
|
||||||
{
|
|
||||||
die_codec(&codec[0], "Failed to encode frame");
|
die_codec(&codec[0], "Failed to encode frame");
|
||||||
}
|
}
|
||||||
vpx_usec_timer_mark(&timer);
|
vpx_usec_timer_mark(&timer);
|
||||||
cx_time += vpx_usec_timer_elapsed(&timer);
|
cx_time += vpx_usec_timer_elapsed(&timer);
|
||||||
|
|
||||||
for (i=NUM_ENCODERS-1; i>=0 ; i--)
|
for (i = NUM_ENCODERS - 1; i >= 0; i--) {
|
||||||
{
|
|
||||||
got_data = 0;
|
got_data = 0;
|
||||||
while( (pkt[i] = vpx_codec_get_cx_data(&codec[i], &iter[i])) )
|
while ((pkt[i] = vpx_codec_get_cx_data(&codec[i], &iter[i]))) {
|
||||||
{
|
|
||||||
got_data = 1;
|
got_data = 1;
|
||||||
switch (pkt[i]->kind) {
|
switch (pkt[i]->kind) {
|
||||||
case VPX_CODEC_CX_FRAME_PKT:
|
case VPX_CODEC_CX_FRAME_PKT:
|
||||||
write_ivf_frame_header(outfile[i], pkt[i]);
|
write_ivf_frame_header(outfile[i], pkt[i]);
|
||||||
(void) fwrite(pkt[i]->data.frame.buf, 1,
|
(void)fwrite(pkt[i]->data.frame.buf, 1, pkt[i]->data.frame.sz,
|
||||||
pkt[i]->data.frame.sz, outfile[i]);
|
outfile[i]);
|
||||||
break;
|
break;
|
||||||
case VPX_CODEC_PSNR_PKT:
|
case VPX_CODEC_PSNR_PKT:
|
||||||
if (show_psnr)
|
if (show_psnr) {
|
||||||
{
|
|
||||||
int j;
|
int j;
|
||||||
|
|
||||||
psnr_sse_total[i] += pkt[i]->data.psnr.sse[0];
|
psnr_sse_total[i] += pkt[i]->data.psnr.sse[0];
|
||||||
psnr_samples_total[i] += pkt[i]->data.psnr.samples[0];
|
psnr_samples_total[i] += pkt[i]->data.psnr.samples[0];
|
||||||
for (j = 0; j < 4; j++)
|
for (j = 0; j < 4; j++) {
|
||||||
{
|
|
||||||
psnr_totals[i][j] += pkt[i]->data.psnr.psnr[j];
|
psnr_totals[i][j] += pkt[i]->data.psnr.psnr[j];
|
||||||
}
|
}
|
||||||
psnr_count[i]++;
|
psnr_count[i]++;
|
||||||
}
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
default:
|
default: break;
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
printf(pkt[i]->kind == VPX_CODEC_CX_FRAME_PKT
|
printf(pkt[i]->kind == VPX_CODEC_CX_FRAME_PKT &&
|
||||||
&& (pkt[i]->data.frame.flags & VPX_FRAME_IS_KEY)? "K":"");
|
(pkt[i]->data.frame.flags & VPX_FRAME_IS_KEY)
|
||||||
|
? "K"
|
||||||
|
: "");
|
||||||
fflush(stdout);
|
fflush(stdout);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -687,27 +630,23 @@ int main(int argc, char **argv)
|
|||||||
}
|
}
|
||||||
printf("\n");
|
printf("\n");
|
||||||
printf("Frame cnt and encoding time/FPS stats for encoding: %d %f %f \n",
|
printf("Frame cnt and encoding time/FPS stats for encoding: %d %f %f \n",
|
||||||
frame_cnt,
|
frame_cnt, 1000 * (float)cx_time / (double)(frame_cnt * 1000000),
|
||||||
1000 * (float)cx_time / (double)(frame_cnt * 1000000),
|
|
||||||
1000000 * (double)frame_cnt / (double)cx_time);
|
1000000 * (double)frame_cnt / (double)cx_time);
|
||||||
|
|
||||||
fclose(infile);
|
fclose(infile);
|
||||||
|
|
||||||
printf("Processed %ld frames.\n", (long int)frame_cnt - 1);
|
printf("Processed %ld frames.\n", (long int)frame_cnt - 1);
|
||||||
for (i=0; i< NUM_ENCODERS; i++)
|
for (i = 0; i < NUM_ENCODERS; i++) {
|
||||||
{
|
|
||||||
/* Calculate PSNR and print it out */
|
/* Calculate PSNR and print it out */
|
||||||
if ( (show_psnr) && (psnr_count[i]>0) )
|
if ((show_psnr) && (psnr_count[i] > 0)) {
|
||||||
{
|
|
||||||
int j;
|
int j;
|
||||||
double ovpsnr = sse_to_psnr(psnr_samples_total[i], 255.0,
|
double ovpsnr =
|
||||||
psnr_sse_total[i]);
|
sse_to_psnr(psnr_samples_total[i], 255.0, psnr_sse_total[i]);
|
||||||
|
|
||||||
fprintf(stderr, "\n ENC%d PSNR (Overall/Avg/Y/U/V)", i);
|
fprintf(stderr, "\n ENC%d PSNR (Overall/Avg/Y/U/V)", i);
|
||||||
|
|
||||||
fprintf(stderr, " %.3lf", ovpsnr);
|
fprintf(stderr, " %.3lf", ovpsnr);
|
||||||
for (j = 0; j < 4; j++)
|
for (j = 0; j < 4; j++) {
|
||||||
{
|
|
||||||
fprintf(stderr, " %.3lf", psnr_totals[i][j] / psnr_count[i]);
|
fprintf(stderr, " %.3lf", psnr_totals[i][j] / psnr_count[i]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -717,8 +656,7 @@ int main(int argc, char **argv)
|
|||||||
|
|
||||||
vpx_img_free(&raw[i]);
|
vpx_img_free(&raw[i]);
|
||||||
|
|
||||||
if(!outfile[i])
|
if (!outfile[i]) continue;
|
||||||
continue;
|
|
||||||
|
|
||||||
/* Try to rewrite the file header with the actual frame count */
|
/* Try to rewrite the file header with the actual frame count */
|
||||||
if (!fseek(outfile[i], 0, SEEK_SET))
|
if (!fseek(outfile[i], 0, SEEK_SET))
|
||||||
|
|||||||
@@ -8,7 +8,6 @@
|
|||||||
* be found in the AUTHORS file in the root of the source tree.
|
* be found in the AUTHORS file in the root of the source tree.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
// VP8 Set Reference Frame
|
// VP8 Set Reference Frame
|
||||||
// =======================
|
// =======================
|
||||||
//
|
//
|
||||||
@@ -52,6 +51,7 @@
|
|||||||
|
|
||||||
#include "vpx/vp8cx.h"
|
#include "vpx/vp8cx.h"
|
||||||
#include "vpx/vpx_encoder.h"
|
#include "vpx/vpx_encoder.h"
|
||||||
|
#include "vp8/common/common.h"
|
||||||
|
|
||||||
#include "../tools_common.h"
|
#include "../tools_common.h"
|
||||||
#include "../video_writer.h"
|
#include "../video_writer.h"
|
||||||
@@ -64,25 +64,21 @@ void usage_exit(void) {
|
|||||||
exit(EXIT_FAILURE);
|
exit(EXIT_FAILURE);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int encode_frame(vpx_codec_ctx_t *codec,
|
static int encode_frame(vpx_codec_ctx_t *codec, vpx_image_t *img,
|
||||||
vpx_image_t *img,
|
int frame_index, VpxVideoWriter *writer) {
|
||||||
int frame_index,
|
|
||||||
VpxVideoWriter *writer) {
|
|
||||||
int got_pkts = 0;
|
int got_pkts = 0;
|
||||||
vpx_codec_iter_t iter = NULL;
|
vpx_codec_iter_t iter = NULL;
|
||||||
const vpx_codec_cx_pkt_t *pkt = NULL;
|
const vpx_codec_cx_pkt_t *pkt = NULL;
|
||||||
const vpx_codec_err_t res = vpx_codec_encode(codec, img, frame_index, 1, 0,
|
const vpx_codec_err_t res =
|
||||||
VPX_DL_GOOD_QUALITY);
|
vpx_codec_encode(codec, img, frame_index, 1, 0, VPX_DL_GOOD_QUALITY);
|
||||||
if (res != VPX_CODEC_OK)
|
if (res != VPX_CODEC_OK) die_codec(codec, "Failed to encode frame");
|
||||||
die_codec(codec, "Failed to encode frame");
|
|
||||||
|
|
||||||
while ((pkt = vpx_codec_get_cx_data(codec, &iter)) != NULL) {
|
while ((pkt = vpx_codec_get_cx_data(codec, &iter)) != NULL) {
|
||||||
got_pkts = 1;
|
got_pkts = 1;
|
||||||
|
|
||||||
if (pkt->kind == VPX_CODEC_CX_FRAME_PKT) {
|
if (pkt->kind == VPX_CODEC_CX_FRAME_PKT) {
|
||||||
const int keyframe = (pkt->data.frame.flags & VPX_FRAME_IS_KEY) != 0;
|
const int keyframe = (pkt->data.frame.flags & VPX_FRAME_IS_KEY) != 0;
|
||||||
if (!vpx_video_writer_write_frame(writer,
|
if (!vpx_video_writer_write_frame(writer, pkt->data.frame.buf,
|
||||||
pkt->data.frame.buf,
|
|
||||||
pkt->data.frame.sz,
|
pkt->data.frame.sz,
|
||||||
pkt->data.frame.pts)) {
|
pkt->data.frame.pts)) {
|
||||||
die_codec(codec, "Failed to write compressed frame");
|
die_codec(codec, "Failed to write compressed frame");
|
||||||
@@ -98,42 +94,41 @@ static int encode_frame(vpx_codec_ctx_t *codec,
|
|||||||
|
|
||||||
int main(int argc, char **argv) {
|
int main(int argc, char **argv) {
|
||||||
FILE *infile = NULL;
|
FILE *infile = NULL;
|
||||||
vpx_codec_ctx_t codec = {0};
|
vpx_codec_ctx_t codec;
|
||||||
vpx_codec_enc_cfg_t cfg = {0};
|
vpx_codec_enc_cfg_t cfg;
|
||||||
int frame_count = 0;
|
int frame_count = 0;
|
||||||
vpx_image_t raw;
|
vpx_image_t raw;
|
||||||
vpx_codec_err_t res;
|
vpx_codec_err_t res;
|
||||||
VpxVideoInfo info = {0};
|
VpxVideoInfo info;
|
||||||
VpxVideoWriter *writer = NULL;
|
VpxVideoWriter *writer = NULL;
|
||||||
const VpxInterface *encoder = NULL;
|
const VpxInterface *encoder = NULL;
|
||||||
int update_frame_num = 0;
|
int update_frame_num = 0;
|
||||||
const int fps = 30; // TODO(dkovalev) add command line argument
|
const int fps = 30; // TODO(dkovalev) add command line argument
|
||||||
const int bitrate = 200; // kbit/s TODO(dkovalev) add command line argument
|
const int bitrate = 200; // kbit/s TODO(dkovalev) add command line argument
|
||||||
|
|
||||||
|
vp8_zero(codec);
|
||||||
|
vp8_zero(cfg);
|
||||||
|
vp8_zero(info);
|
||||||
|
|
||||||
exec_name = argv[0];
|
exec_name = argv[0];
|
||||||
|
|
||||||
if (argc != 6)
|
if (argc != 6) die("Invalid number of arguments");
|
||||||
die("Invalid number of arguments");
|
|
||||||
|
|
||||||
// TODO(dkovalev): add vp9 support and rename the file accordingly
|
// TODO(dkovalev): add vp9 support and rename the file accordingly
|
||||||
encoder = get_vpx_encoder_by_name("vp8");
|
encoder = get_vpx_encoder_by_name("vp8");
|
||||||
if (!encoder)
|
if (!encoder) die("Unsupported codec.");
|
||||||
die("Unsupported codec.");
|
|
||||||
|
|
||||||
update_frame_num = atoi(argv[5]);
|
update_frame_num = atoi(argv[5]);
|
||||||
if (!update_frame_num)
|
if (!update_frame_num) die("Couldn't parse frame number '%s'\n", argv[5]);
|
||||||
die("Couldn't parse frame number '%s'\n", argv[5]);
|
|
||||||
|
|
||||||
info.codec_fourcc = encoder->fourcc;
|
info.codec_fourcc = encoder->fourcc;
|
||||||
info.frame_width = strtol(argv[1], NULL, 0);
|
info.frame_width = (int)strtol(argv[1], NULL, 0);
|
||||||
info.frame_height = strtol(argv[2], NULL, 0);
|
info.frame_height = (int)strtol(argv[2], NULL, 0);
|
||||||
info.time_base.numerator = 1;
|
info.time_base.numerator = 1;
|
||||||
info.time_base.denominator = fps;
|
info.time_base.denominator = fps;
|
||||||
|
|
||||||
if (info.frame_width <= 0 ||
|
if (info.frame_width <= 0 || info.frame_height <= 0 ||
|
||||||
info.frame_height <= 0 ||
|
(info.frame_width % 2) != 0 || (info.frame_height % 2) != 0) {
|
||||||
(info.frame_width % 2) != 0 ||
|
|
||||||
(info.frame_height % 2) != 0) {
|
|
||||||
die("Invalid frame size: %dx%d", info.frame_width, info.frame_height);
|
die("Invalid frame size: %dx%d", info.frame_width, info.frame_height);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -145,8 +140,7 @@ int main(int argc, char **argv) {
|
|||||||
printf("Using %s\n", vpx_codec_iface_name(encoder->codec_interface()));
|
printf("Using %s\n", vpx_codec_iface_name(encoder->codec_interface()));
|
||||||
|
|
||||||
res = vpx_codec_enc_config_default(encoder->codec_interface(), &cfg, 0);
|
res = vpx_codec_enc_config_default(encoder->codec_interface(), &cfg, 0);
|
||||||
if (res)
|
if (res) die_codec(&codec, "Failed to get default codec config.");
|
||||||
die_codec(&codec, "Failed to get default codec config.");
|
|
||||||
|
|
||||||
cfg.g_w = info.frame_width;
|
cfg.g_w = info.frame_width;
|
||||||
cfg.g_h = info.frame_height;
|
cfg.g_h = info.frame_height;
|
||||||
@@ -155,8 +149,7 @@ int main(int argc, char **argv) {
|
|||||||
cfg.rc_target_bitrate = bitrate;
|
cfg.rc_target_bitrate = bitrate;
|
||||||
|
|
||||||
writer = vpx_video_writer_open(argv[4], kContainerIVF, &info);
|
writer = vpx_video_writer_open(argv[4], kContainerIVF, &info);
|
||||||
if (!writer)
|
if (!writer) die("Failed to open %s for writing.", argv[4]);
|
||||||
die("Failed to open %s for writing.", argv[4]);
|
|
||||||
|
|
||||||
if (!(infile = fopen(argv[3], "rb")))
|
if (!(infile = fopen(argv[3], "rb")))
|
||||||
die("Failed to open %s for reading.", argv[3]);
|
die("Failed to open %s for reading.", argv[3]);
|
||||||
@@ -178,15 +171,15 @@ int main(int argc, char **argv) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Flush encoder.
|
// Flush encoder.
|
||||||
while (encode_frame(&codec, NULL, -1, writer)) {}
|
while (encode_frame(&codec, NULL, -1, writer)) {
|
||||||
|
}
|
||||||
|
|
||||||
printf("\n");
|
printf("\n");
|
||||||
fclose(infile);
|
fclose(infile);
|
||||||
printf("Processed %d frames.\n", frame_count);
|
printf("Processed %d frames.\n", frame_count);
|
||||||
|
|
||||||
vpx_img_free(&raw);
|
vpx_img_free(&raw);
|
||||||
if (vpx_codec_destroy(&codec))
|
if (vpx_codec_destroy(&codec)) die_codec(&codec, "Failed to destroy codec.");
|
||||||
die_codec(&codec, "Failed to destroy codec.");
|
|
||||||
|
|
||||||
vpx_video_writer_close(writer);
|
vpx_video_writer_close(writer);
|
||||||
|
|
||||||
|
|||||||
@@ -14,6 +14,7 @@
|
|||||||
|
|
||||||
#include "vpx/vpx_encoder.h"
|
#include "vpx/vpx_encoder.h"
|
||||||
#include "vpx/vp8cx.h"
|
#include "vpx/vp8cx.h"
|
||||||
|
#include "vp9/common/vp9_common.h"
|
||||||
|
|
||||||
#include "../tools_common.h"
|
#include "../tools_common.h"
|
||||||
#include "../video_writer.h"
|
#include "../video_writer.h"
|
||||||
@@ -21,32 +22,28 @@
|
|||||||
static const char *exec_name;
|
static const char *exec_name;
|
||||||
|
|
||||||
void usage_exit(void) {
|
void usage_exit(void) {
|
||||||
fprintf(stderr, "vp9_lossless_encoder: Example demonstrating VP9 lossless "
|
fprintf(stderr,
|
||||||
|
"vp9_lossless_encoder: Example demonstrating VP9 lossless "
|
||||||
"encoding feature. Supports raw input only.\n");
|
"encoding feature. Supports raw input only.\n");
|
||||||
fprintf(stderr, "Usage: %s <width> <height> <infile> <outfile>\n", exec_name);
|
fprintf(stderr, "Usage: %s <width> <height> <infile> <outfile>\n", exec_name);
|
||||||
exit(EXIT_FAILURE);
|
exit(EXIT_FAILURE);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int encode_frame(vpx_codec_ctx_t *codec,
|
static int encode_frame(vpx_codec_ctx_t *codec, vpx_image_t *img,
|
||||||
vpx_image_t *img,
|
int frame_index, int flags, VpxVideoWriter *writer) {
|
||||||
int frame_index,
|
|
||||||
int flags,
|
|
||||||
VpxVideoWriter *writer) {
|
|
||||||
int got_pkts = 0;
|
int got_pkts = 0;
|
||||||
vpx_codec_iter_t iter = NULL;
|
vpx_codec_iter_t iter = NULL;
|
||||||
const vpx_codec_cx_pkt_t *pkt = NULL;
|
const vpx_codec_cx_pkt_t *pkt = NULL;
|
||||||
const vpx_codec_err_t res = vpx_codec_encode(codec, img, frame_index, 1,
|
const vpx_codec_err_t res =
|
||||||
flags, VPX_DL_GOOD_QUALITY);
|
vpx_codec_encode(codec, img, frame_index, 1, flags, VPX_DL_GOOD_QUALITY);
|
||||||
if (res != VPX_CODEC_OK)
|
if (res != VPX_CODEC_OK) die_codec(codec, "Failed to encode frame");
|
||||||
die_codec(codec, "Failed to encode frame");
|
|
||||||
|
|
||||||
while ((pkt = vpx_codec_get_cx_data(codec, &iter)) != NULL) {
|
while ((pkt = vpx_codec_get_cx_data(codec, &iter)) != NULL) {
|
||||||
got_pkts = 1;
|
got_pkts = 1;
|
||||||
|
|
||||||
if (pkt->kind == VPX_CODEC_CX_FRAME_PKT) {
|
if (pkt->kind == VPX_CODEC_CX_FRAME_PKT) {
|
||||||
const int keyframe = (pkt->data.frame.flags & VPX_FRAME_IS_KEY) != 0;
|
const int keyframe = (pkt->data.frame.flags & VPX_FRAME_IS_KEY) != 0;
|
||||||
if (!vpx_video_writer_write_frame(writer,
|
if (!vpx_video_writer_write_frame(writer, pkt->data.frame.buf,
|
||||||
pkt->data.frame.buf,
|
|
||||||
pkt->data.frame.sz,
|
pkt->data.frame.sz,
|
||||||
pkt->data.frame.pts)) {
|
pkt->data.frame.pts)) {
|
||||||
die_codec(codec, "Failed to write compressed frame");
|
die_codec(codec, "Failed to write compressed frame");
|
||||||
@@ -66,30 +63,28 @@ int main(int argc, char **argv) {
|
|||||||
int frame_count = 0;
|
int frame_count = 0;
|
||||||
vpx_image_t raw;
|
vpx_image_t raw;
|
||||||
vpx_codec_err_t res;
|
vpx_codec_err_t res;
|
||||||
VpxVideoInfo info = {0};
|
VpxVideoInfo info;
|
||||||
VpxVideoWriter *writer = NULL;
|
VpxVideoWriter *writer = NULL;
|
||||||
const VpxInterface *encoder = NULL;
|
const VpxInterface *encoder = NULL;
|
||||||
const int fps = 30;
|
const int fps = 30;
|
||||||
|
|
||||||
|
vp9_zero(info);
|
||||||
|
|
||||||
exec_name = argv[0];
|
exec_name = argv[0];
|
||||||
|
|
||||||
if (argc < 5)
|
if (argc < 5) die("Invalid number of arguments");
|
||||||
die("Invalid number of arguments");
|
|
||||||
|
|
||||||
encoder = get_vpx_encoder_by_name("vp9");
|
encoder = get_vpx_encoder_by_name("vp9");
|
||||||
if (!encoder)
|
if (!encoder) die("Unsupported codec.");
|
||||||
die("Unsupported codec.");
|
|
||||||
|
|
||||||
info.codec_fourcc = encoder->fourcc;
|
info.codec_fourcc = encoder->fourcc;
|
||||||
info.frame_width = strtol(argv[1], NULL, 0);
|
info.frame_width = (int)strtol(argv[1], NULL, 0);
|
||||||
info.frame_height = strtol(argv[2], NULL, 0);
|
info.frame_height = (int)strtol(argv[2], NULL, 0);
|
||||||
info.time_base.numerator = 1;
|
info.time_base.numerator = 1;
|
||||||
info.time_base.denominator = fps;
|
info.time_base.denominator = fps;
|
||||||
|
|
||||||
if (info.frame_width <= 0 ||
|
if (info.frame_width <= 0 || info.frame_height <= 0 ||
|
||||||
info.frame_height <= 0 ||
|
(info.frame_width % 2) != 0 || (info.frame_height % 2) != 0) {
|
||||||
(info.frame_width % 2) != 0 ||
|
|
||||||
(info.frame_height % 2) != 0) {
|
|
||||||
die("Invalid frame size: %dx%d", info.frame_width, info.frame_height);
|
die("Invalid frame size: %dx%d", info.frame_width, info.frame_height);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -101,8 +96,7 @@ int main(int argc, char **argv) {
|
|||||||
printf("Using %s\n", vpx_codec_iface_name(encoder->codec_interface()));
|
printf("Using %s\n", vpx_codec_iface_name(encoder->codec_interface()));
|
||||||
|
|
||||||
res = vpx_codec_enc_config_default(encoder->codec_interface(), &cfg, 0);
|
res = vpx_codec_enc_config_default(encoder->codec_interface(), &cfg, 0);
|
||||||
if (res)
|
if (res) die_codec(&codec, "Failed to get default codec config.");
|
||||||
die_codec(&codec, "Failed to get default codec config.");
|
|
||||||
|
|
||||||
cfg.g_w = info.frame_width;
|
cfg.g_w = info.frame_width;
|
||||||
cfg.g_h = info.frame_height;
|
cfg.g_h = info.frame_height;
|
||||||
@@ -110,8 +104,7 @@ int main(int argc, char **argv) {
|
|||||||
cfg.g_timebase.den = info.time_base.denominator;
|
cfg.g_timebase.den = info.time_base.denominator;
|
||||||
|
|
||||||
writer = vpx_video_writer_open(argv[4], kContainerIVF, &info);
|
writer = vpx_video_writer_open(argv[4], kContainerIVF, &info);
|
||||||
if (!writer)
|
if (!writer) die("Failed to open %s for writing.", argv[4]);
|
||||||
die("Failed to open %s for writing.", argv[4]);
|
|
||||||
|
|
||||||
if (!(infile = fopen(argv[3], "rb")))
|
if (!(infile = fopen(argv[3], "rb")))
|
||||||
die("Failed to open %s for reading.", argv[3]);
|
die("Failed to open %s for reading.", argv[3]);
|
||||||
@@ -128,15 +121,15 @@ int main(int argc, char **argv) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Flush encoder.
|
// Flush encoder.
|
||||||
while (encode_frame(&codec, NULL, -1, 0, writer)) {}
|
while (encode_frame(&codec, NULL, -1, 0, writer)) {
|
||||||
|
}
|
||||||
|
|
||||||
printf("\n");
|
printf("\n");
|
||||||
fclose(infile);
|
fclose(infile);
|
||||||
printf("Processed %d frames.\n", frame_count);
|
printf("Processed %d frames.\n", frame_count);
|
||||||
|
|
||||||
vpx_img_free(&raw);
|
vpx_img_free(&raw);
|
||||||
if (vpx_codec_destroy(&codec))
|
if (vpx_codec_destroy(&codec)) die_codec(&codec, "Failed to destroy codec.");
|
||||||
die_codec(&codec, "Failed to destroy codec.");
|
|
||||||
|
|
||||||
vpx_video_writer_close(writer);
|
vpx_video_writer_close(writer);
|
||||||
|
|
||||||
|
|||||||
@@ -20,7 +20,6 @@
|
|||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <time.h>
|
#include <time.h>
|
||||||
|
|
||||||
|
|
||||||
#include "../args.h"
|
#include "../args.h"
|
||||||
#include "../tools_common.h"
|
#include "../tools_common.h"
|
||||||
#include "../video_writer.h"
|
#include "../video_writer.h"
|
||||||
@@ -54,7 +53,8 @@ static const arg_def_t spatial_layers_arg =
|
|||||||
static const arg_def_t temporal_layers_arg =
|
static const arg_def_t temporal_layers_arg =
|
||||||
ARG_DEF("tl", "temporal-layers", 1, "number of temporal SVC layers");
|
ARG_DEF("tl", "temporal-layers", 1, "number of temporal SVC layers");
|
||||||
static const arg_def_t temporal_layering_mode_arg =
|
static const arg_def_t temporal_layering_mode_arg =
|
||||||
ARG_DEF("tlm", "temporal-layering-mode", 1, "temporal layering scheme."
|
ARG_DEF("tlm", "temporal-layering-mode", 1,
|
||||||
|
"temporal layering scheme."
|
||||||
"VP9E_TEMPORAL_LAYERING_MODE");
|
"VP9E_TEMPORAL_LAYERING_MODE");
|
||||||
static const arg_def_t kf_dist_arg =
|
static const arg_def_t kf_dist_arg =
|
||||||
ARG_DEF("k", "kf-dist", 1, "number of frames between keyframes");
|
ARG_DEF("k", "kf-dist", 1, "number of frames between keyframes");
|
||||||
@@ -75,7 +75,8 @@ static const arg_def_t min_bitrate_arg =
|
|||||||
static const arg_def_t max_bitrate_arg =
|
static const arg_def_t max_bitrate_arg =
|
||||||
ARG_DEF(NULL, "max-bitrate", 1, "Maximum bitrate");
|
ARG_DEF(NULL, "max-bitrate", 1, "Maximum bitrate");
|
||||||
static const arg_def_t lag_in_frame_arg =
|
static const arg_def_t lag_in_frame_arg =
|
||||||
ARG_DEF(NULL, "lag-in-frames", 1, "Number of frame to input before "
|
ARG_DEF(NULL, "lag-in-frames", 1,
|
||||||
|
"Number of frame to input before "
|
||||||
"generating any outputs");
|
"generating any outputs");
|
||||||
static const arg_def_t rc_end_usage_arg =
|
static const arg_def_t rc_end_usage_arg =
|
||||||
ARG_DEF(NULL, "rc-end-usage", 1, "0 - 3: VBR, CBR, CQ, Q");
|
ARG_DEF(NULL, "rc-end-usage", 1, "0 - 3: VBR, CBR, CQ, Q");
|
||||||
@@ -83,28 +84,39 @@ static const arg_def_t speed_arg =
|
|||||||
ARG_DEF("sp", "speed", 1, "speed configuration");
|
ARG_DEF("sp", "speed", 1, "speed configuration");
|
||||||
static const arg_def_t aqmode_arg =
|
static const arg_def_t aqmode_arg =
|
||||||
ARG_DEF("aq", "aqmode", 1, "aq-mode off/on");
|
ARG_DEF("aq", "aqmode", 1, "aq-mode off/on");
|
||||||
|
static const arg_def_t bitrates_arg =
|
||||||
|
ARG_DEF("bl", "bitrates", 1, "bitrates[sl * num_tl + tl]");
|
||||||
|
|
||||||
#if CONFIG_VP9_HIGHBITDEPTH
|
#if CONFIG_VP9_HIGHBITDEPTH
|
||||||
static const struct arg_enum_list bitdepth_enum[] = {
|
static const struct arg_enum_list bitdepth_enum[] = {
|
||||||
{"8", VPX_BITS_8},
|
{ "8", VPX_BITS_8 }, { "10", VPX_BITS_10 }, { "12", VPX_BITS_12 }, { NULL, 0 }
|
||||||
{"10", VPX_BITS_10},
|
|
||||||
{"12", VPX_BITS_12},
|
|
||||||
{NULL, 0}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
static const arg_def_t bitdepth_arg =
|
static const arg_def_t bitdepth_arg = ARG_DEF_ENUM(
|
||||||
ARG_DEF_ENUM("d", "bit-depth", 1, "Bit depth for codec 8, 10 or 12. ",
|
"d", "bit-depth", 1, "Bit depth for codec 8, 10 or 12. ", bitdepth_enum);
|
||||||
bitdepth_enum);
|
|
||||||
#endif // CONFIG_VP9_HIGHBITDEPTH
|
#endif // CONFIG_VP9_HIGHBITDEPTH
|
||||||
|
|
||||||
|
static const arg_def_t *svc_args[] = { &frames_arg,
|
||||||
static const arg_def_t *svc_args[] = {
|
&width_arg,
|
||||||
&frames_arg, &width_arg, &height_arg,
|
&height_arg,
|
||||||
&timebase_arg, &bitrate_arg, &skip_frames_arg, &spatial_layers_arg,
|
&timebase_arg,
|
||||||
&kf_dist_arg, &scale_factors_arg, &passes_arg, &pass_arg,
|
&bitrate_arg,
|
||||||
&fpf_name_arg, &min_q_arg, &max_q_arg, &min_bitrate_arg,
|
&skip_frames_arg,
|
||||||
&max_bitrate_arg, &temporal_layers_arg, &temporal_layering_mode_arg,
|
&spatial_layers_arg,
|
||||||
&lag_in_frame_arg, &threads_arg, &aqmode_arg,
|
&kf_dist_arg,
|
||||||
|
&scale_factors_arg,
|
||||||
|
&passes_arg,
|
||||||
|
&pass_arg,
|
||||||
|
&fpf_name_arg,
|
||||||
|
&min_q_arg,
|
||||||
|
&max_q_arg,
|
||||||
|
&min_bitrate_arg,
|
||||||
|
&max_bitrate_arg,
|
||||||
|
&temporal_layers_arg,
|
||||||
|
&temporal_layering_mode_arg,
|
||||||
|
&lag_in_frame_arg,
|
||||||
|
&threads_arg,
|
||||||
|
&aqmode_arg,
|
||||||
#if OUTPUT_RC_STATS
|
#if OUTPUT_RC_STATS
|
||||||
&output_rc_stats_arg,
|
&output_rc_stats_arg,
|
||||||
#endif
|
#endif
|
||||||
@@ -113,8 +125,9 @@ static const arg_def_t *svc_args[] = {
|
|||||||
&bitdepth_arg,
|
&bitdepth_arg,
|
||||||
#endif
|
#endif
|
||||||
&speed_arg,
|
&speed_arg,
|
||||||
&rc_end_usage_arg, NULL
|
&rc_end_usage_arg,
|
||||||
};
|
&bitrates_arg,
|
||||||
|
NULL };
|
||||||
|
|
||||||
static const uint32_t default_frames_to_skip = 0;
|
static const uint32_t default_frames_to_skip = 0;
|
||||||
static const uint32_t default_frames_to_code = 60 * 60;
|
static const uint32_t default_frames_to_code = 60 * 60;
|
||||||
@@ -229,8 +242,8 @@ static void parse_command_line(int argc, const char **argv_,
|
|||||||
} else if (arg_match(&arg, &threads_arg, argi)) {
|
} else if (arg_match(&arg, &threads_arg, argi)) {
|
||||||
svc_ctx->threads = arg_parse_uint(&arg);
|
svc_ctx->threads = arg_parse_uint(&arg);
|
||||||
} else if (arg_match(&arg, &temporal_layering_mode_arg, argi)) {
|
} else if (arg_match(&arg, &temporal_layering_mode_arg, argi)) {
|
||||||
svc_ctx->temporal_layering_mode =
|
svc_ctx->temporal_layering_mode = enc_cfg->temporal_layering_mode =
|
||||||
enc_cfg->temporal_layering_mode = arg_parse_int(&arg);
|
arg_parse_int(&arg);
|
||||||
if (svc_ctx->temporal_layering_mode) {
|
if (svc_ctx->temporal_layering_mode) {
|
||||||
enc_cfg->g_error_resilient = 1;
|
enc_cfg->g_error_resilient = 1;
|
||||||
}
|
}
|
||||||
@@ -240,6 +253,9 @@ static void parse_command_line(int argc, const char **argv_,
|
|||||||
} else if (arg_match(&arg, &scale_factors_arg, argi)) {
|
} else if (arg_match(&arg, &scale_factors_arg, argi)) {
|
||||||
snprintf(string_options, sizeof(string_options), "%s scale-factors=%s",
|
snprintf(string_options, sizeof(string_options), "%s scale-factors=%s",
|
||||||
string_options, arg.val);
|
string_options, arg.val);
|
||||||
|
} else if (arg_match(&arg, &bitrates_arg, argi)) {
|
||||||
|
snprintf(string_options, sizeof(string_options), "%s bitrates=%s",
|
||||||
|
string_options, arg.val);
|
||||||
} else if (arg_match(&arg, &passes_arg, argi)) {
|
} else if (arg_match(&arg, &passes_arg, argi)) {
|
||||||
passes = arg_parse_uint(&arg);
|
passes = arg_parse_uint(&arg);
|
||||||
if (passes < 1 || passes > 2) {
|
if (passes < 1 || passes > 2) {
|
||||||
@@ -360,9 +376,8 @@ static void parse_command_line(int argc, const char **argv_,
|
|||||||
"num: %d, den: %d, bitrate: %d,\n"
|
"num: %d, den: %d, bitrate: %d,\n"
|
||||||
"gop size: %d\n",
|
"gop size: %d\n",
|
||||||
vpx_codec_iface_name(vpx_codec_vp9_cx()), app_input->frames_to_code,
|
vpx_codec_iface_name(vpx_codec_vp9_cx()), app_input->frames_to_code,
|
||||||
app_input->frames_to_skip,
|
app_input->frames_to_skip, svc_ctx->spatial_layers, enc_cfg->g_w,
|
||||||
svc_ctx->spatial_layers, enc_cfg->g_w, enc_cfg->g_h,
|
enc_cfg->g_h, enc_cfg->g_timebase.num, enc_cfg->g_timebase.den,
|
||||||
enc_cfg->g_timebase.num, enc_cfg->g_timebase.den,
|
|
||||||
enc_cfg->rc_target_bitrate, enc_cfg->kf_max_dist);
|
enc_cfg->rc_target_bitrate, enc_cfg->kf_max_dist);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -408,22 +423,18 @@ static void set_rate_control_stats(struct RateControlStats *rc,
|
|||||||
for (sl = 0; sl < cfg->ss_number_layers; ++sl) {
|
for (sl = 0; sl < cfg->ss_number_layers; ++sl) {
|
||||||
for (tl = 0; tl < cfg->ts_number_layers; ++tl) {
|
for (tl = 0; tl < cfg->ts_number_layers; ++tl) {
|
||||||
const int layer = sl * cfg->ts_number_layers + tl;
|
const int layer = sl * cfg->ts_number_layers + tl;
|
||||||
const int tlayer0 = sl * cfg->ts_number_layers;
|
|
||||||
if (cfg->ts_number_layers == 1)
|
if (cfg->ts_number_layers == 1)
|
||||||
rc->layer_framerate[layer] = framerate;
|
rc->layer_framerate[layer] = framerate;
|
||||||
else
|
else
|
||||||
rc->layer_framerate[layer] =
|
rc->layer_framerate[layer] = framerate / cfg->ts_rate_decimator[tl];
|
||||||
framerate / cfg->ts_rate_decimator[tl];
|
|
||||||
if (tl > 0) {
|
if (tl > 0) {
|
||||||
rc->layer_pfb[layer] = 1000.0 *
|
rc->layer_pfb[layer] =
|
||||||
(cfg->layer_target_bitrate[layer] -
|
1000.0 * (cfg->layer_target_bitrate[layer] -
|
||||||
cfg->layer_target_bitrate[layer - 1]) /
|
cfg->layer_target_bitrate[layer - 1]) /
|
||||||
(rc->layer_framerate[layer] -
|
(rc->layer_framerate[layer] - rc->layer_framerate[layer - 1]);
|
||||||
rc->layer_framerate[layer - 1]);
|
|
||||||
} else {
|
} else {
|
||||||
rc->layer_pfb[tlayer0] = 1000.0 *
|
rc->layer_pfb[layer] = 1000.0 * cfg->layer_target_bitrate[layer] /
|
||||||
cfg->layer_target_bitrate[tlayer0] /
|
rc->layer_framerate[layer];
|
||||||
rc->layer_framerate[tlayer0];
|
|
||||||
}
|
}
|
||||||
rc->layer_input_frames[layer] = 0;
|
rc->layer_input_frames[layer] = 0;
|
||||||
rc->layer_enc_frames[layer] = 0;
|
rc->layer_enc_frames[layer] = 0;
|
||||||
@@ -443,25 +454,28 @@ static void printout_rate_control_summary(struct RateControlStats *rc,
|
|||||||
vpx_codec_enc_cfg_t *cfg,
|
vpx_codec_enc_cfg_t *cfg,
|
||||||
int frame_cnt) {
|
int frame_cnt) {
|
||||||
unsigned int sl, tl;
|
unsigned int sl, tl;
|
||||||
int tot_num_frames = 0;
|
|
||||||
double perc_fluctuation = 0.0;
|
double perc_fluctuation = 0.0;
|
||||||
|
int tot_num_frames = 0;
|
||||||
printf("Total number of processed frames: %d\n\n", frame_cnt - 1);
|
printf("Total number of processed frames: %d\n\n", frame_cnt - 1);
|
||||||
printf("Rate control layer stats for sl%d tl%d layer(s):\n\n",
|
printf("Rate control layer stats for sl%d tl%d layer(s):\n\n",
|
||||||
cfg->ss_number_layers, cfg->ts_number_layers);
|
cfg->ss_number_layers, cfg->ts_number_layers);
|
||||||
for (sl = 0; sl < cfg->ss_number_layers; ++sl) {
|
for (sl = 0; sl < cfg->ss_number_layers; ++sl) {
|
||||||
|
tot_num_frames = 0;
|
||||||
for (tl = 0; tl < cfg->ts_number_layers; ++tl) {
|
for (tl = 0; tl < cfg->ts_number_layers; ++tl) {
|
||||||
const int layer = sl * cfg->ts_number_layers + tl;
|
const int layer = sl * cfg->ts_number_layers + tl;
|
||||||
const int num_dropped = (tl > 0) ?
|
const int num_dropped =
|
||||||
(rc->layer_input_frames[layer] - rc->layer_enc_frames[layer]) :
|
(tl > 0)
|
||||||
(rc->layer_input_frames[layer] - rc->layer_enc_frames[layer] - 1);
|
? (rc->layer_input_frames[layer] - rc->layer_enc_frames[layer])
|
||||||
if (!sl)
|
: (rc->layer_input_frames[layer] - rc->layer_enc_frames[layer] -
|
||||||
|
1);
|
||||||
tot_num_frames += rc->layer_input_frames[layer];
|
tot_num_frames += rc->layer_input_frames[layer];
|
||||||
rc->layer_encoding_bitrate[layer] = 0.001 * rc->layer_framerate[layer] *
|
rc->layer_encoding_bitrate[layer] = 0.001 * rc->layer_framerate[layer] *
|
||||||
rc->layer_encoding_bitrate[layer] / tot_num_frames;
|
rc->layer_encoding_bitrate[layer] /
|
||||||
rc->layer_avg_frame_size[layer] = rc->layer_avg_frame_size[layer] /
|
tot_num_frames;
|
||||||
rc->layer_enc_frames[layer];
|
rc->layer_avg_frame_size[layer] =
|
||||||
rc->layer_avg_rate_mismatch[layer] =
|
rc->layer_avg_frame_size[layer] / rc->layer_enc_frames[layer];
|
||||||
100.0 * rc->layer_avg_rate_mismatch[layer] /
|
rc->layer_avg_rate_mismatch[layer] = 100.0 *
|
||||||
|
rc->layer_avg_rate_mismatch[layer] /
|
||||||
rc->layer_enc_frames[layer];
|
rc->layer_enc_frames[layer];
|
||||||
printf("For layer#: sl%d tl%d \n", sl, tl);
|
printf("For layer#: sl%d tl%d \n", sl, tl);
|
||||||
printf("Bitrate (target vs actual): %d %f.0 kbps\n",
|
printf("Bitrate (target vs actual): %d %f.0 kbps\n",
|
||||||
@@ -469,9 +483,9 @@ static void printout_rate_control_summary(struct RateControlStats *rc,
|
|||||||
rc->layer_encoding_bitrate[layer]);
|
rc->layer_encoding_bitrate[layer]);
|
||||||
printf("Average frame size (target vs actual): %f %f bits\n",
|
printf("Average frame size (target vs actual): %f %f bits\n",
|
||||||
rc->layer_pfb[layer], rc->layer_avg_frame_size[layer]);
|
rc->layer_pfb[layer], rc->layer_avg_frame_size[layer]);
|
||||||
printf("Average rate_mismatch: %f\n",
|
printf("Average rate_mismatch: %f\n", rc->layer_avg_rate_mismatch[layer]);
|
||||||
rc->layer_avg_rate_mismatch[layer]);
|
printf(
|
||||||
printf("Number of input frames, encoded (non-key) frames, "
|
"Number of input frames, encoded (non-key) frames, "
|
||||||
"and percent dropped frames: %d %d %f.0 \n",
|
"and percent dropped frames: %d %d %f.0 \n",
|
||||||
rc->layer_input_frames[layer], rc->layer_enc_frames[layer],
|
rc->layer_input_frames[layer], rc->layer_enc_frames[layer],
|
||||||
100.0 * num_dropped / rc->layer_input_frames[layer]);
|
100.0 * num_dropped / rc->layer_input_frames[layer]);
|
||||||
@@ -486,16 +500,15 @@ static void printout_rate_control_summary(struct RateControlStats *rc,
|
|||||||
rc->avg_st_encoding_bitrate;
|
rc->avg_st_encoding_bitrate;
|
||||||
printf("Short-time stats, for window of %d frames: \n", rc->window_size);
|
printf("Short-time stats, for window of %d frames: \n", rc->window_size);
|
||||||
printf("Average, rms-variance, and percent-fluct: %f %f %f \n",
|
printf("Average, rms-variance, and percent-fluct: %f %f %f \n",
|
||||||
rc->avg_st_encoding_bitrate,
|
rc->avg_st_encoding_bitrate, sqrt(rc->variance_st_encoding_bitrate),
|
||||||
sqrt(rc->variance_st_encoding_bitrate),
|
|
||||||
perc_fluctuation);
|
perc_fluctuation);
|
||||||
if (frame_cnt != tot_num_frames)
|
if (frame_cnt != tot_num_frames)
|
||||||
die("Error: Number of input frames not equal to output encoded frames != "
|
die("Error: Number of input frames not equal to output encoded frames != "
|
||||||
"%d tot_num_frames = %d\n", frame_cnt, tot_num_frames);
|
"%d tot_num_frames = %d\n",
|
||||||
|
frame_cnt, tot_num_frames);
|
||||||
}
|
}
|
||||||
|
|
||||||
vpx_codec_err_t parse_superframe_index(const uint8_t *data,
|
vpx_codec_err_t parse_superframe_index(const uint8_t *data, size_t data_sz,
|
||||||
size_t data_sz,
|
|
||||||
uint32_t sizes[8], int *count) {
|
uint32_t sizes[8], int *count) {
|
||||||
// A chunk ending with a byte matching 0xc0 is an invalid chunk unless
|
// 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
|
// it is a super frame index. If the last byte of real video compression
|
||||||
@@ -508,7 +521,6 @@ vpx_codec_err_t parse_superframe_index(const uint8_t *data,
|
|||||||
marker = *(data + data_sz - 1);
|
marker = *(data + data_sz - 1);
|
||||||
*count = 0;
|
*count = 0;
|
||||||
|
|
||||||
|
|
||||||
if ((marker & 0xe0) == 0xc0) {
|
if ((marker & 0xe0) == 0xc0) {
|
||||||
const uint32_t frames = (marker & 0x7) + 1;
|
const uint32_t frames = (marker & 0x7) + 1;
|
||||||
const uint32_t mag = ((marker >> 3) & 0x3) + 1;
|
const uint32_t mag = ((marker >> 3) & 0x3) + 1;
|
||||||
@@ -516,8 +528,7 @@ vpx_codec_err_t parse_superframe_index(const uint8_t *data,
|
|||||||
|
|
||||||
// This chunk is marked as having a superframe index but doesn't have
|
// This chunk is marked as having a superframe index but doesn't have
|
||||||
// enough data for it, thus it's an invalid superframe index.
|
// enough data for it, thus it's an invalid superframe index.
|
||||||
if (data_sz < index_sz)
|
if (data_sz < index_sz) return VPX_CODEC_CORRUPT_FRAME;
|
||||||
return VPX_CODEC_CORRUPT_FRAME;
|
|
||||||
|
|
||||||
{
|
{
|
||||||
const uint8_t marker2 = *(data + data_sz - index_sz);
|
const uint8_t marker2 = *(data + data_sz - index_sz);
|
||||||
@@ -525,8 +536,7 @@ vpx_codec_err_t parse_superframe_index(const uint8_t *data,
|
|||||||
// This chunk is marked as having a superframe index but doesn't have
|
// This chunk is marked as having a superframe index but doesn't have
|
||||||
// the matching marker byte at the front of the index therefore it's an
|
// the matching marker byte at the front of the index therefore it's an
|
||||||
// invalid chunk.
|
// invalid chunk.
|
||||||
if (marker != marker2)
|
if (marker != marker2) return VPX_CODEC_CORRUPT_FRAME;
|
||||||
return VPX_CODEC_CORRUPT_FRAME;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
@@ -537,8 +547,7 @@ vpx_codec_err_t parse_superframe_index(const uint8_t *data,
|
|||||||
for (i = 0; i < frames; ++i) {
|
for (i = 0; i < frames; ++i) {
|
||||||
uint32_t this_sz = 0;
|
uint32_t this_sz = 0;
|
||||||
|
|
||||||
for (j = 0; j < mag; ++j)
|
for (j = 0; j < mag; ++j) this_sz |= (*x++) << (j * 8);
|
||||||
this_sz |= (*x++) << (j * 8);
|
|
||||||
sizes[i] = this_sz;
|
sizes[i] = this_sz;
|
||||||
}
|
}
|
||||||
*count = frames;
|
*count = frames;
|
||||||
@@ -558,32 +567,27 @@ void set_frame_flags_bypass_mode(int sl, int tl, int num_spatial_layers,
|
|||||||
for (sl = 0; sl < num_spatial_layers; ++sl) {
|
for (sl = 0; sl < num_spatial_layers; ++sl) {
|
||||||
if (!tl) {
|
if (!tl) {
|
||||||
if (!sl) {
|
if (!sl) {
|
||||||
ref_frame_config->frame_flags[sl] = VP8_EFLAG_NO_REF_GF |
|
ref_frame_config->frame_flags[sl] =
|
||||||
VP8_EFLAG_NO_REF_ARF |
|
VP8_EFLAG_NO_REF_GF | VP8_EFLAG_NO_REF_ARF | VP8_EFLAG_NO_UPD_GF |
|
||||||
VP8_EFLAG_NO_UPD_GF |
|
|
||||||
VP8_EFLAG_NO_UPD_ARF;
|
VP8_EFLAG_NO_UPD_ARF;
|
||||||
} else {
|
} else {
|
||||||
if (is_key_frame) {
|
if (is_key_frame) {
|
||||||
ref_frame_config->frame_flags[sl] = VP8_EFLAG_NO_REF_LAST |
|
ref_frame_config->frame_flags[sl] =
|
||||||
VP8_EFLAG_NO_REF_ARF |
|
VP8_EFLAG_NO_REF_LAST | VP8_EFLAG_NO_REF_ARF |
|
||||||
VP8_EFLAG_NO_UPD_GF |
|
VP8_EFLAG_NO_UPD_GF | VP8_EFLAG_NO_UPD_ARF;
|
||||||
VP8_EFLAG_NO_UPD_ARF;
|
|
||||||
} else {
|
} else {
|
||||||
ref_frame_config->frame_flags[sl] = VP8_EFLAG_NO_REF_ARF |
|
ref_frame_config->frame_flags[sl] =
|
||||||
VP8_EFLAG_NO_UPD_GF |
|
VP8_EFLAG_NO_REF_ARF | VP8_EFLAG_NO_UPD_GF | VP8_EFLAG_NO_UPD_ARF;
|
||||||
VP8_EFLAG_NO_UPD_ARF;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else if (tl == 1) {
|
} else if (tl == 1) {
|
||||||
if (!sl) {
|
if (!sl) {
|
||||||
ref_frame_config->frame_flags[sl] = VP8_EFLAG_NO_REF_GF |
|
ref_frame_config->frame_flags[sl] =
|
||||||
VP8_EFLAG_NO_REF_ARF |
|
VP8_EFLAG_NO_REF_GF | VP8_EFLAG_NO_REF_ARF | VP8_EFLAG_NO_UPD_LAST |
|
||||||
VP8_EFLAG_NO_UPD_LAST |
|
|
||||||
VP8_EFLAG_NO_UPD_GF;
|
VP8_EFLAG_NO_UPD_GF;
|
||||||
} else {
|
} else {
|
||||||
ref_frame_config->frame_flags[sl] = VP8_EFLAG_NO_REF_ARF |
|
ref_frame_config->frame_flags[sl] =
|
||||||
VP8_EFLAG_NO_UPD_LAST |
|
VP8_EFLAG_NO_REF_ARF | VP8_EFLAG_NO_UPD_LAST | VP8_EFLAG_NO_UPD_GF;
|
||||||
VP8_EFLAG_NO_UPD_GF;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (tl == 0) {
|
if (tl == 0) {
|
||||||
@@ -622,7 +626,7 @@ int main(int argc, const char **argv) {
|
|||||||
struct RateControlStats rc;
|
struct RateControlStats rc;
|
||||||
vpx_svc_layer_id_t layer_id;
|
vpx_svc_layer_id_t layer_id;
|
||||||
vpx_svc_ref_frame_config_t ref_frame_config;
|
vpx_svc_ref_frame_config_t ref_frame_config;
|
||||||
int sl, tl;
|
unsigned int sl, tl;
|
||||||
double sum_bitrate = 0.0;
|
double sum_bitrate = 0.0;
|
||||||
double sum_bitrate2 = 0.0;
|
double sum_bitrate2 = 0.0;
|
||||||
double framerate = 30.0;
|
double framerate = 30.0;
|
||||||
@@ -636,8 +640,8 @@ int main(int argc, const char **argv) {
|
|||||||
|
|
||||||
// Allocate image buffer
|
// Allocate image buffer
|
||||||
#if CONFIG_VP9_HIGHBITDEPTH
|
#if CONFIG_VP9_HIGHBITDEPTH
|
||||||
if (!vpx_img_alloc(&raw, enc_cfg.g_input_bit_depth == 8 ?
|
if (!vpx_img_alloc(&raw, enc_cfg.g_input_bit_depth == 8 ? VPX_IMG_FMT_I420
|
||||||
VPX_IMG_FMT_I420 : VPX_IMG_FMT_I42016,
|
: VPX_IMG_FMT_I42016,
|
||||||
enc_cfg.g_w, enc_cfg.g_h, 32)) {
|
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);
|
die("Failed to allocate image %dx%d\n", enc_cfg.g_w, enc_cfg.g_h);
|
||||||
}
|
}
|
||||||
@@ -668,14 +672,14 @@ int main(int argc, const char **argv) {
|
|||||||
|
|
||||||
if (!(app_input.passes == 2 && app_input.pass == 1)) {
|
if (!(app_input.passes == 2 && app_input.pass == 1)) {
|
||||||
// We don't save the bitstream for the 1st pass on two pass rate control
|
// We don't save the bitstream for the 1st pass on two pass rate control
|
||||||
writer = vpx_video_writer_open(app_input.output_filename, kContainerIVF,
|
writer =
|
||||||
&info);
|
vpx_video_writer_open(app_input.output_filename, kContainerIVF, &info);
|
||||||
if (!writer)
|
if (!writer)
|
||||||
die("Failed to open %s for writing\n", app_input.output_filename);
|
die("Failed to open %s for writing\n", app_input.output_filename);
|
||||||
}
|
}
|
||||||
#if OUTPUT_RC_STATS
|
#if OUTPUT_RC_STATS
|
||||||
// For now, just write temporal layer streams.
|
// 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) {
|
if (svc_ctx.output_rc_stat) {
|
||||||
for (tl = 0; tl < enc_cfg.ts_number_layers; ++tl) {
|
for (tl = 0; tl < enc_cfg.ts_number_layers; ++tl) {
|
||||||
char file_name[PATH_MAX];
|
char file_name[PATH_MAX];
|
||||||
@@ -683,15 +687,13 @@ int main(int argc, const char **argv) {
|
|||||||
snprintf(file_name, sizeof(file_name), "%s_t%d.ivf",
|
snprintf(file_name, sizeof(file_name), "%s_t%d.ivf",
|
||||||
app_input.output_filename, tl);
|
app_input.output_filename, tl);
|
||||||
outfile[tl] = vpx_video_writer_open(file_name, kContainerIVF, &info);
|
outfile[tl] = vpx_video_writer_open(file_name, kContainerIVF, &info);
|
||||||
if (!outfile[tl])
|
if (!outfile[tl]) die("Failed to open %s for writing", file_name);
|
||||||
die("Failed to open %s for writing", file_name);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// skip initial frames
|
// skip initial frames
|
||||||
for (i = 0; i < app_input.frames_to_skip; ++i)
|
for (i = 0; i < app_input.frames_to_skip; ++i) vpx_img_read(&raw, infile);
|
||||||
vpx_img_read(&raw, infile);
|
|
||||||
|
|
||||||
if (svc_ctx.speed != -1)
|
if (svc_ctx.speed != -1)
|
||||||
vpx_codec_control(&codec, VP8E_SET_CPUUSED, svc_ctx.speed);
|
vpx_codec_control(&codec, VP8E_SET_CPUUSED, svc_ctx.speed);
|
||||||
@@ -699,7 +701,8 @@ int main(int argc, const char **argv) {
|
|||||||
vpx_codec_control(&codec, VP9E_SET_TILE_COLUMNS, (svc_ctx.threads >> 1));
|
vpx_codec_control(&codec, VP9E_SET_TILE_COLUMNS, (svc_ctx.threads >> 1));
|
||||||
if (svc_ctx.speed >= 5 && svc_ctx.aqmode == 1)
|
if (svc_ctx.speed >= 5 && svc_ctx.aqmode == 1)
|
||||||
vpx_codec_control(&codec, VP9E_SET_AQ_MODE, 3);
|
vpx_codec_control(&codec, VP9E_SET_AQ_MODE, 3);
|
||||||
|
if (svc_ctx.speed >= 5)
|
||||||
|
vpx_codec_control(&codec, VP8E_SET_STATIC_THRESHOLD, 1);
|
||||||
|
|
||||||
// Encode frames
|
// Encode frames
|
||||||
while (!end_of_stream) {
|
while (!end_of_stream) {
|
||||||
@@ -729,23 +732,22 @@ int main(int argc, const char **argv) {
|
|||||||
// over all the spatial layers for the current superframe.
|
// over all the spatial layers for the current superframe.
|
||||||
vpx_codec_control(&codec, VP9E_SET_SVC_LAYER_ID, &layer_id);
|
vpx_codec_control(&codec, VP9E_SET_SVC_LAYER_ID, &layer_id);
|
||||||
set_frame_flags_bypass_mode(sl, layer_id.temporal_layer_id,
|
set_frame_flags_bypass_mode(sl, layer_id.temporal_layer_id,
|
||||||
svc_ctx.spatial_layers,
|
svc_ctx.spatial_layers, frame_cnt == 0,
|
||||||
frame_cnt == 0,
|
|
||||||
&ref_frame_config);
|
&ref_frame_config);
|
||||||
vpx_codec_control(&codec, VP9E_SET_SVC_REF_FRAME_CONFIG,
|
vpx_codec_control(&codec, VP9E_SET_SVC_REF_FRAME_CONFIG,
|
||||||
&ref_frame_config);
|
&ref_frame_config);
|
||||||
// Keep track of input frames, to account for frame drops in rate control
|
// Keep track of input frames, to account for frame drops in rate control
|
||||||
// stats/metrics.
|
// stats/metrics.
|
||||||
for (sl = 0; sl < enc_cfg.ss_number_layers; ++sl) {
|
for (sl = 0; sl < (unsigned int)enc_cfg.ss_number_layers; ++sl) {
|
||||||
++rc.layer_input_frames[sl * enc_cfg.ts_number_layers +
|
++rc.layer_input_frames[sl * enc_cfg.ts_number_layers +
|
||||||
layer_id.temporal_layer_id];
|
layer_id.temporal_layer_id];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
vpx_usec_timer_start(&timer);
|
vpx_usec_timer_start(&timer);
|
||||||
res = vpx_svc_encode(&svc_ctx, &codec, (end_of_stream ? NULL : &raw),
|
res = vpx_svc_encode(
|
||||||
pts, frame_duration, svc_ctx.speed >= 5 ?
|
&svc_ctx, &codec, (end_of_stream ? NULL : &raw), pts, frame_duration,
|
||||||
VPX_DL_REALTIME : VPX_DL_GOOD_QUALITY);
|
svc_ctx.speed >= 5 ? VPX_DL_REALTIME : VPX_DL_GOOD_QUALITY);
|
||||||
vpx_usec_timer_mark(&timer);
|
vpx_usec_timer_mark(&timer);
|
||||||
cx_time += vpx_usec_timer_elapsed(&timer);
|
cx_time += vpx_usec_timer_elapsed(&timer);
|
||||||
|
|
||||||
@@ -764,12 +766,11 @@ int main(int argc, const char **argv) {
|
|||||||
uint32_t sizes[8];
|
uint32_t sizes[8];
|
||||||
int count = 0;
|
int count = 0;
|
||||||
#endif
|
#endif
|
||||||
vpx_video_writer_write_frame(writer,
|
vpx_video_writer_write_frame(writer, cx_pkt->data.frame.buf,
|
||||||
cx_pkt->data.frame.buf,
|
|
||||||
cx_pkt->data.frame.sz,
|
cx_pkt->data.frame.sz,
|
||||||
cx_pkt->data.frame.pts);
|
cx_pkt->data.frame.pts);
|
||||||
#if OUTPUT_RC_STATS
|
#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) {
|
if (svc_ctx.output_rc_stat) {
|
||||||
vpx_codec_control(&codec, VP9E_GET_SVC_LAYER_ID, &layer_id);
|
vpx_codec_control(&codec, VP9E_GET_SVC_LAYER_ID, &layer_id);
|
||||||
parse_superframe_index(cx_pkt->data.frame.buf,
|
parse_superframe_index(cx_pkt->data.frame.buf,
|
||||||
@@ -787,9 +788,8 @@ int main(int argc, const char **argv) {
|
|||||||
}
|
}
|
||||||
for (tl = layer_id.temporal_layer_id;
|
for (tl = layer_id.temporal_layer_id;
|
||||||
tl < enc_cfg.ts_number_layers; ++tl) {
|
tl < enc_cfg.ts_number_layers; ++tl) {
|
||||||
vpx_video_writer_write_frame(outfile[tl],
|
vpx_video_writer_write_frame(
|
||||||
cx_pkt->data.frame.buf,
|
outfile[tl], cx_pkt->data.frame.buf, cx_pkt->data.frame.sz,
|
||||||
cx_pkt->data.frame.sz,
|
|
||||||
cx_pkt->data.frame.pts);
|
cx_pkt->data.frame.pts);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -801,7 +801,7 @@ int main(int argc, const char **argv) {
|
|||||||
rc.layer_encoding_bitrate[layer] += 8.0 * sizes[sl];
|
rc.layer_encoding_bitrate[layer] += 8.0 * sizes[sl];
|
||||||
// Keep count of rate control stats per layer, for non-key
|
// Keep count of rate control stats per layer, for non-key
|
||||||
// frames.
|
// frames.
|
||||||
if (tl == layer_id.temporal_layer_id &&
|
if (tl == (unsigned int)layer_id.temporal_layer_id &&
|
||||||
!(cx_pkt->data.frame.flags & VPX_FRAME_IS_KEY)) {
|
!(cx_pkt->data.frame.flags & VPX_FRAME_IS_KEY)) {
|
||||||
rc.layer_avg_frame_size[layer] += 8.0 * sizes[sl];
|
rc.layer_avg_frame_size[layer] += 8.0 * sizes[sl];
|
||||||
rc.layer_avg_rate_mismatch[layer] +=
|
rc.layer_avg_rate_mismatch[layer] +=
|
||||||
@@ -815,7 +815,7 @@ int main(int argc, const char **argv) {
|
|||||||
// Update for short-time encoding bitrate states, for moving
|
// Update for short-time encoding bitrate states, for moving
|
||||||
// window of size rc->window, shifted by rc->window / 2.
|
// window of size rc->window, shifted by rc->window / 2.
|
||||||
// Ignore first window segment, due to key frame.
|
// Ignore first window segment, due to key frame.
|
||||||
if (frame_cnt > rc.window_size) {
|
if (frame_cnt > (unsigned int)rc.window_size) {
|
||||||
tl = layer_id.temporal_layer_id;
|
tl = layer_id.temporal_layer_id;
|
||||||
for (sl = 0; sl < enc_cfg.ss_number_layers; ++sl) {
|
for (sl = 0; sl < enc_cfg.ss_number_layers; ++sl) {
|
||||||
sum_bitrate += 0.001 * 8.0 * sizes[sl] * framerate;
|
sum_bitrate += 0.001 * 8.0 * sizes[sl] * framerate;
|
||||||
@@ -831,13 +831,14 @@ int main(int argc, const char **argv) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Second shifted window.
|
// Second shifted window.
|
||||||
if (frame_cnt > rc.window_size + rc.window_size / 2) {
|
if (frame_cnt >
|
||||||
|
(unsigned int)(rc.window_size + rc.window_size / 2)) {
|
||||||
tl = layer_id.temporal_layer_id;
|
tl = layer_id.temporal_layer_id;
|
||||||
for (sl = 0; sl < enc_cfg.ss_number_layers; ++sl) {
|
for (sl = 0; sl < enc_cfg.ss_number_layers; ++sl) {
|
||||||
sum_bitrate2 += 0.001 * 8.0 * sizes[sl] * framerate;
|
sum_bitrate2 += 0.001 * 8.0 * sizes[sl] * framerate;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (frame_cnt > 2 * rc.window_size &&
|
if (frame_cnt > (unsigned int)(2 * rc.window_size) &&
|
||||||
frame_cnt % rc.window_size == 0) {
|
frame_cnt % rc.window_size == 0) {
|
||||||
rc.window_count += 1;
|
rc.window_count += 1;
|
||||||
rc.avg_st_encoding_bitrate += sum_bitrate2 / rc.window_size;
|
rc.avg_st_encoding_bitrate += sum_bitrate2 / rc.window_size;
|
||||||
@@ -850,24 +851,22 @@ int main(int argc, const char **argv) {
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
/*
|
||||||
printf("SVC frame: %d, kf: %d, size: %d, pts: %d\n", frames_received,
|
printf("SVC frame: %d, kf: %d, size: %d, pts: %d\n", frames_received,
|
||||||
!!(cx_pkt->data.frame.flags & VPX_FRAME_IS_KEY),
|
!!(cx_pkt->data.frame.flags & VPX_FRAME_IS_KEY),
|
||||||
(int)cx_pkt->data.frame.sz, (int)cx_pkt->data.frame.pts);
|
(int)cx_pkt->data.frame.sz, (int)cx_pkt->data.frame.pts);
|
||||||
|
*/
|
||||||
if (enc_cfg.ss_number_layers == 1 && enc_cfg.ts_number_layers == 1)
|
if (enc_cfg.ss_number_layers == 1 && enc_cfg.ts_number_layers == 1)
|
||||||
si->bytes_sum[0] += (int)cx_pkt->data.frame.sz;
|
si->bytes_sum[0] += (int)cx_pkt->data.frame.sz;
|
||||||
++frames_received;
|
++frames_received;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case VPX_CODEC_STATS_PKT: {
|
case VPX_CODEC_STATS_PKT: {
|
||||||
stats_write(&app_input.rc_stats,
|
stats_write(&app_input.rc_stats, cx_pkt->data.twopass_stats.buf,
|
||||||
cx_pkt->data.twopass_stats.buf,
|
|
||||||
cx_pkt->data.twopass_stats.sz);
|
cx_pkt->data.twopass_stats.sz);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
default: {
|
default: { break; }
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -880,8 +879,8 @@ int main(int argc, const char **argv) {
|
|||||||
// Compensate for the extra frame count for the bypass mode.
|
// Compensate for the extra frame count for the bypass mode.
|
||||||
if (svc_ctx.temporal_layering_mode == VP9E_TEMPORAL_LAYERING_MODE_BYPASS) {
|
if (svc_ctx.temporal_layering_mode == VP9E_TEMPORAL_LAYERING_MODE_BYPASS) {
|
||||||
for (sl = 0; sl < enc_cfg.ss_number_layers; ++sl) {
|
for (sl = 0; sl < enc_cfg.ss_number_layers; ++sl) {
|
||||||
const int layer = sl * enc_cfg.ts_number_layers +
|
const int layer =
|
||||||
layer_id.temporal_layer_id;
|
sl * enc_cfg.ts_number_layers + layer_id.temporal_layer_id;
|
||||||
--rc.layer_input_frames[layer];
|
--rc.layer_input_frames[layer];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -895,8 +894,7 @@ int main(int argc, const char **argv) {
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
if (vpx_codec_destroy(&codec)) die_codec(&codec, "Failed to destroy codec");
|
if (vpx_codec_destroy(&codec)) die_codec(&codec, "Failed to destroy codec");
|
||||||
if (app_input.passes == 2)
|
if (app_input.passes == 2) stats_close(&app_input.rc_stats, 1);
|
||||||
stats_close(&app_input.rc_stats, 1);
|
|
||||||
if (writer) {
|
if (writer) {
|
||||||
vpx_video_writer_close(writer);
|
vpx_video_writer_close(writer);
|
||||||
}
|
}
|
||||||
@@ -908,8 +906,7 @@ int main(int argc, const char **argv) {
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
printf("Frame cnt and encoding time/FPS stats for encoding: %d %f %f \n",
|
printf("Frame cnt and encoding time/FPS stats for encoding: %d %f %f \n",
|
||||||
frame_cnt,
|
frame_cnt, 1000 * (float)cx_time / (double)(frame_cnt * 1000000),
|
||||||
1000 * (float)cx_time / (double)(frame_cnt * 1000000),
|
|
||||||
1000000 * (double)frame_cnt / (double)cx_time);
|
1000000 * (double)frame_cnt / (double)cx_time);
|
||||||
vpx_img_free(&raw);
|
vpx_img_free(&raw);
|
||||||
// display average size, psnr
|
// display average size, psnr
|
||||||
|
|||||||
442
examples/vp9cx_set_ref.c
Normal file
442
examples/vp9cx_set_ref.c
Normal file
@@ -0,0 +1,442 @@
|
|||||||
|
/*
|
||||||
|
* 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
// VP9 Set Reference Frame
|
||||||
|
// ============================
|
||||||
|
//
|
||||||
|
// This is an example demonstrating how to overwrite the VP9 encoder's
|
||||||
|
// internal reference frame. In the sample we set the last frame to the
|
||||||
|
// current frame. This technique could be used to bounce between two cameras.
|
||||||
|
//
|
||||||
|
// The decoder would also have to set the reference frame to the same value
|
||||||
|
// on the same frame, or the video will become corrupt. The 'test_decode'
|
||||||
|
// variable is set to 1 in this example that tests if the encoder and decoder
|
||||||
|
// results are matching.
|
||||||
|
//
|
||||||
|
// Usage
|
||||||
|
// -----
|
||||||
|
// This example encodes a raw video. And the last argument passed in specifies
|
||||||
|
// the frame number to update the reference frame on. For example, run
|
||||||
|
// examples/vp9cx_set_ref 352 288 in.yuv out.ivf 4 30
|
||||||
|
// The parameter is parsed as follows:
|
||||||
|
//
|
||||||
|
//
|
||||||
|
// Extra Variables
|
||||||
|
// ---------------
|
||||||
|
// This example maintains the frame number passed on the command line
|
||||||
|
// in the `update_frame_num` variable.
|
||||||
|
//
|
||||||
|
//
|
||||||
|
// Configuration
|
||||||
|
// -------------
|
||||||
|
//
|
||||||
|
// The reference frame is updated on the frame specified on the command
|
||||||
|
// line.
|
||||||
|
//
|
||||||
|
// Observing The Effects
|
||||||
|
// ---------------------
|
||||||
|
// The encoder and decoder results should be matching when the same reference
|
||||||
|
// frame setting operation is done in both encoder and decoder. Otherwise,
|
||||||
|
// the encoder/decoder mismatch would be seen.
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
#include "vpx/vp8cx.h"
|
||||||
|
#include "vpx/vpx_decoder.h"
|
||||||
|
#include "vpx/vpx_encoder.h"
|
||||||
|
#include "vp9/common/vp9_common.h"
|
||||||
|
|
||||||
|
#include "./tools_common.h"
|
||||||
|
#include "./video_writer.h"
|
||||||
|
|
||||||
|
static const char *exec_name;
|
||||||
|
|
||||||
|
void usage_exit() {
|
||||||
|
fprintf(stderr,
|
||||||
|
"Usage: %s <width> <height> <infile> <outfile> "
|
||||||
|
"<frame> <limit(optional)>\n",
|
||||||
|
exec_name);
|
||||||
|
exit(EXIT_FAILURE);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int compare_img(const vpx_image_t *const img1,
|
||||||
|
const vpx_image_t *const img2) {
|
||||||
|
uint32_t l_w = img1->d_w;
|
||||||
|
uint32_t c_w = (img1->d_w + img1->x_chroma_shift) >> img1->x_chroma_shift;
|
||||||
|
const uint32_t c_h =
|
||||||
|
(img1->d_h + img1->y_chroma_shift) >> img1->y_chroma_shift;
|
||||||
|
uint32_t i;
|
||||||
|
int match = 1;
|
||||||
|
|
||||||
|
match &= (img1->fmt == img2->fmt);
|
||||||
|
match &= (img1->d_w == img2->d_w);
|
||||||
|
match &= (img1->d_h == img2->d_h);
|
||||||
|
|
||||||
|
for (i = 0; i < img1->d_h; ++i)
|
||||||
|
match &= (memcmp(img1->planes[VPX_PLANE_Y] + i * img1->stride[VPX_PLANE_Y],
|
||||||
|
img2->planes[VPX_PLANE_Y] + i * img2->stride[VPX_PLANE_Y],
|
||||||
|
l_w) == 0);
|
||||||
|
|
||||||
|
for (i = 0; i < c_h; ++i)
|
||||||
|
match &= (memcmp(img1->planes[VPX_PLANE_U] + i * img1->stride[VPX_PLANE_U],
|
||||||
|
img2->planes[VPX_PLANE_U] + i * img2->stride[VPX_PLANE_U],
|
||||||
|
c_w) == 0);
|
||||||
|
|
||||||
|
for (i = 0; i < c_h; ++i)
|
||||||
|
match &= (memcmp(img1->planes[VPX_PLANE_V] + i * img1->stride[VPX_PLANE_V],
|
||||||
|
img2->planes[VPX_PLANE_V] + i * img2->stride[VPX_PLANE_V],
|
||||||
|
c_w) == 0);
|
||||||
|
|
||||||
|
return match;
|
||||||
|
}
|
||||||
|
|
||||||
|
#define mmin(a, b) ((a) < (b) ? (a) : (b))
|
||||||
|
static void find_mismatch(const vpx_image_t *const img1,
|
||||||
|
const vpx_image_t *const img2, int yloc[4],
|
||||||
|
int uloc[4], int vloc[4]) {
|
||||||
|
const uint32_t bsize = 64;
|
||||||
|
const uint32_t bsizey = bsize >> img1->y_chroma_shift;
|
||||||
|
const uint32_t bsizex = bsize >> img1->x_chroma_shift;
|
||||||
|
const uint32_t c_w =
|
||||||
|
(img1->d_w + img1->x_chroma_shift) >> img1->x_chroma_shift;
|
||||||
|
const uint32_t c_h =
|
||||||
|
(img1->d_h + img1->y_chroma_shift) >> img1->y_chroma_shift;
|
||||||
|
int match = 1;
|
||||||
|
uint32_t i, j;
|
||||||
|
yloc[0] = yloc[1] = yloc[2] = yloc[3] = -1;
|
||||||
|
for (i = 0, match = 1; match && i < img1->d_h; i += bsize) {
|
||||||
|
for (j = 0; match && j < img1->d_w; j += bsize) {
|
||||||
|
int k, l;
|
||||||
|
const int si = mmin(i + bsize, img1->d_h) - i;
|
||||||
|
const int sj = mmin(j + bsize, img1->d_w) - j;
|
||||||
|
for (k = 0; match && k < si; ++k) {
|
||||||
|
for (l = 0; match && l < sj; ++l) {
|
||||||
|
if (*(img1->planes[VPX_PLANE_Y] +
|
||||||
|
(i + k) * img1->stride[VPX_PLANE_Y] + j + l) !=
|
||||||
|
*(img2->planes[VPX_PLANE_Y] +
|
||||||
|
(i + k) * img2->stride[VPX_PLANE_Y] + j + l)) {
|
||||||
|
yloc[0] = i + k;
|
||||||
|
yloc[1] = j + l;
|
||||||
|
yloc[2] = *(img1->planes[VPX_PLANE_Y] +
|
||||||
|
(i + k) * img1->stride[VPX_PLANE_Y] + j + l);
|
||||||
|
yloc[3] = *(img2->planes[VPX_PLANE_Y] +
|
||||||
|
(i + k) * img2->stride[VPX_PLANE_Y] + j + l);
|
||||||
|
match = 0;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
uloc[0] = uloc[1] = uloc[2] = uloc[3] = -1;
|
||||||
|
for (i = 0, match = 1; match && i < c_h; i += bsizey) {
|
||||||
|
for (j = 0; match && j < c_w; j += bsizex) {
|
||||||
|
int k, l;
|
||||||
|
const int si = mmin(i + bsizey, c_h - i);
|
||||||
|
const int sj = mmin(j + bsizex, c_w - j);
|
||||||
|
for (k = 0; match && k < si; ++k) {
|
||||||
|
for (l = 0; match && l < sj; ++l) {
|
||||||
|
if (*(img1->planes[VPX_PLANE_U] +
|
||||||
|
(i + k) * img1->stride[VPX_PLANE_U] + j + l) !=
|
||||||
|
*(img2->planes[VPX_PLANE_U] +
|
||||||
|
(i + k) * img2->stride[VPX_PLANE_U] + j + l)) {
|
||||||
|
uloc[0] = i + k;
|
||||||
|
uloc[1] = j + l;
|
||||||
|
uloc[2] = *(img1->planes[VPX_PLANE_U] +
|
||||||
|
(i + k) * img1->stride[VPX_PLANE_U] + j + l);
|
||||||
|
uloc[3] = *(img2->planes[VPX_PLANE_U] +
|
||||||
|
(i + k) * img2->stride[VPX_PLANE_U] + j + l);
|
||||||
|
match = 0;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
vloc[0] = vloc[1] = vloc[2] = vloc[3] = -1;
|
||||||
|
for (i = 0, match = 1; match && i < c_h; i += bsizey) {
|
||||||
|
for (j = 0; match && j < c_w; j += bsizex) {
|
||||||
|
int k, l;
|
||||||
|
const int si = mmin(i + bsizey, c_h - i);
|
||||||
|
const int sj = mmin(j + bsizex, c_w - j);
|
||||||
|
for (k = 0; match && k < si; ++k) {
|
||||||
|
for (l = 0; match && l < sj; ++l) {
|
||||||
|
if (*(img1->planes[VPX_PLANE_V] +
|
||||||
|
(i + k) * img1->stride[VPX_PLANE_V] + j + l) !=
|
||||||
|
*(img2->planes[VPX_PLANE_V] +
|
||||||
|
(i + k) * img2->stride[VPX_PLANE_V] + j + l)) {
|
||||||
|
vloc[0] = i + k;
|
||||||
|
vloc[1] = j + l;
|
||||||
|
vloc[2] = *(img1->planes[VPX_PLANE_V] +
|
||||||
|
(i + k) * img1->stride[VPX_PLANE_V] + j + l);
|
||||||
|
vloc[3] = *(img2->planes[VPX_PLANE_V] +
|
||||||
|
(i + k) * img2->stride[VPX_PLANE_V] + j + l);
|
||||||
|
match = 0;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void testing_decode(vpx_codec_ctx_t *encoder, vpx_codec_ctx_t *decoder,
|
||||||
|
unsigned int frame_out, int *mismatch_seen) {
|
||||||
|
vpx_image_t enc_img, dec_img;
|
||||||
|
struct vp9_ref_frame ref_enc, ref_dec;
|
||||||
|
|
||||||
|
if (*mismatch_seen) return;
|
||||||
|
|
||||||
|
ref_enc.idx = 0;
|
||||||
|
ref_dec.idx = 0;
|
||||||
|
if (vpx_codec_control(encoder, VP9_GET_REFERENCE, &ref_enc))
|
||||||
|
die_codec(encoder, "Failed to get encoder reference frame");
|
||||||
|
enc_img = ref_enc.img;
|
||||||
|
if (vpx_codec_control(decoder, VP9_GET_REFERENCE, &ref_dec))
|
||||||
|
die_codec(decoder, "Failed to get decoder reference frame");
|
||||||
|
dec_img = ref_dec.img;
|
||||||
|
|
||||||
|
if (!compare_img(&enc_img, &dec_img)) {
|
||||||
|
int y[4], u[4], v[4];
|
||||||
|
|
||||||
|
*mismatch_seen = 1;
|
||||||
|
|
||||||
|
find_mismatch(&enc_img, &dec_img, y, u, v);
|
||||||
|
printf(
|
||||||
|
"Encode/decode mismatch on frame %d at"
|
||||||
|
" Y[%d, %d] {%d/%d},"
|
||||||
|
" U[%d, %d] {%d/%d},"
|
||||||
|
" V[%d, %d] {%d/%d}",
|
||||||
|
frame_out, y[0], y[1], y[2], y[3], u[0], u[1], u[2], u[3], v[0], v[1],
|
||||||
|
v[2], v[3]);
|
||||||
|
}
|
||||||
|
|
||||||
|
vpx_img_free(&enc_img);
|
||||||
|
vpx_img_free(&dec_img);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int encode_frame(vpx_codec_ctx_t *ecodec, vpx_image_t *img,
|
||||||
|
unsigned int frame_in, VpxVideoWriter *writer,
|
||||||
|
int test_decode, vpx_codec_ctx_t *dcodec,
|
||||||
|
unsigned int *frame_out, int *mismatch_seen) {
|
||||||
|
int got_pkts = 0;
|
||||||
|
vpx_codec_iter_t iter = NULL;
|
||||||
|
const vpx_codec_cx_pkt_t *pkt = NULL;
|
||||||
|
int got_data;
|
||||||
|
const vpx_codec_err_t res =
|
||||||
|
vpx_codec_encode(ecodec, img, frame_in, 1, 0, VPX_DL_GOOD_QUALITY);
|
||||||
|
if (res != VPX_CODEC_OK) die_codec(ecodec, "Failed to encode frame");
|
||||||
|
|
||||||
|
got_data = 0;
|
||||||
|
|
||||||
|
while ((pkt = vpx_codec_get_cx_data(ecodec, &iter)) != NULL) {
|
||||||
|
got_pkts = 1;
|
||||||
|
|
||||||
|
if (pkt->kind == VPX_CODEC_CX_FRAME_PKT) {
|
||||||
|
const int keyframe = (pkt->data.frame.flags & VPX_FRAME_IS_KEY) != 0;
|
||||||
|
|
||||||
|
if (!(pkt->data.frame.flags & VPX_FRAME_IS_FRAGMENT)) {
|
||||||
|
*frame_out += 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!vpx_video_writer_write_frame(writer, pkt->data.frame.buf,
|
||||||
|
pkt->data.frame.sz,
|
||||||
|
pkt->data.frame.pts)) {
|
||||||
|
die_codec(ecodec, "Failed to write compressed frame");
|
||||||
|
}
|
||||||
|
printf(keyframe ? "K" : ".");
|
||||||
|
fflush(stdout);
|
||||||
|
got_data = 1;
|
||||||
|
|
||||||
|
// Decode 1 frame.
|
||||||
|
if (test_decode) {
|
||||||
|
if (vpx_codec_decode(dcodec, pkt->data.frame.buf,
|
||||||
|
(unsigned int)pkt->data.frame.sz, NULL, 0))
|
||||||
|
die_codec(dcodec, "Failed to decode frame.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Mismatch checking
|
||||||
|
if (got_data && test_decode) {
|
||||||
|
testing_decode(ecodec, dcodec, *frame_out, mismatch_seen);
|
||||||
|
}
|
||||||
|
|
||||||
|
return got_pkts;
|
||||||
|
}
|
||||||
|
|
||||||
|
int main(int argc, char **argv) {
|
||||||
|
FILE *infile = NULL;
|
||||||
|
// Encoder
|
||||||
|
vpx_codec_ctx_t ecodec;
|
||||||
|
vpx_codec_enc_cfg_t cfg;
|
||||||
|
unsigned int frame_in = 0;
|
||||||
|
vpx_image_t raw;
|
||||||
|
vpx_codec_err_t res;
|
||||||
|
VpxVideoInfo info;
|
||||||
|
VpxVideoWriter *writer = NULL;
|
||||||
|
const VpxInterface *encoder = NULL;
|
||||||
|
|
||||||
|
// Test encoder/decoder mismatch.
|
||||||
|
int test_decode = 1;
|
||||||
|
// Decoder
|
||||||
|
vpx_codec_ctx_t dcodec;
|
||||||
|
unsigned int frame_out = 0;
|
||||||
|
|
||||||
|
// The frame number to set reference frame on
|
||||||
|
unsigned int update_frame_num = 0;
|
||||||
|
int mismatch_seen = 0;
|
||||||
|
|
||||||
|
const int fps = 30;
|
||||||
|
const int bitrate = 500;
|
||||||
|
|
||||||
|
const char *width_arg = NULL;
|
||||||
|
const char *height_arg = NULL;
|
||||||
|
const char *infile_arg = NULL;
|
||||||
|
const char *outfile_arg = NULL;
|
||||||
|
const char *update_frame_num_arg = NULL;
|
||||||
|
unsigned int limit = 0;
|
||||||
|
|
||||||
|
vp9_zero(ecodec);
|
||||||
|
vp9_zero(cfg);
|
||||||
|
vp9_zero(info);
|
||||||
|
|
||||||
|
exec_name = argv[0];
|
||||||
|
|
||||||
|
if (argc < 6) die("Invalid number of arguments");
|
||||||
|
|
||||||
|
width_arg = argv[1];
|
||||||
|
height_arg = argv[2];
|
||||||
|
infile_arg = argv[3];
|
||||||
|
outfile_arg = argv[4];
|
||||||
|
update_frame_num_arg = argv[5];
|
||||||
|
|
||||||
|
encoder = get_vpx_encoder_by_name("vp9");
|
||||||
|
if (!encoder) die("Unsupported codec.");
|
||||||
|
|
||||||
|
update_frame_num = (unsigned int)strtoul(update_frame_num_arg, NULL, 0);
|
||||||
|
// In VP9, the reference buffers (cm->buffer_pool->frame_bufs[i].buf) are
|
||||||
|
// allocated while calling vpx_codec_encode(), thus, setting reference for
|
||||||
|
// 1st frame isn't supported.
|
||||||
|
if (update_frame_num <= 1) {
|
||||||
|
die("Couldn't parse frame number '%s'\n", update_frame_num_arg);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (argc > 6) {
|
||||||
|
limit = (unsigned int)strtoul(argv[6], NULL, 0);
|
||||||
|
if (update_frame_num > limit)
|
||||||
|
die("Update frame number couldn't larger than limit\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
info.codec_fourcc = encoder->fourcc;
|
||||||
|
info.frame_width = (int)strtol(width_arg, NULL, 0);
|
||||||
|
info.frame_height = (int)strtol(height_arg, NULL, 0);
|
||||||
|
info.time_base.numerator = 1;
|
||||||
|
info.time_base.denominator = fps;
|
||||||
|
|
||||||
|
if (info.frame_width <= 0 || info.frame_height <= 0 ||
|
||||||
|
(info.frame_width % 2) != 0 || (info.frame_height % 2) != 0) {
|
||||||
|
die("Invalid frame size: %dx%d", info.frame_width, info.frame_height);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!vpx_img_alloc(&raw, VPX_IMG_FMT_I420, info.frame_width,
|
||||||
|
info.frame_height, 1)) {
|
||||||
|
die("Failed to allocate image.");
|
||||||
|
}
|
||||||
|
|
||||||
|
printf("Using %s\n", vpx_codec_iface_name(encoder->codec_interface()));
|
||||||
|
|
||||||
|
res = vpx_codec_enc_config_default(encoder->codec_interface(), &cfg, 0);
|
||||||
|
if (res) die_codec(&ecodec, "Failed to get default codec config.");
|
||||||
|
|
||||||
|
cfg.g_w = info.frame_width;
|
||||||
|
cfg.g_h = info.frame_height;
|
||||||
|
cfg.g_timebase.num = info.time_base.numerator;
|
||||||
|
cfg.g_timebase.den = info.time_base.denominator;
|
||||||
|
cfg.rc_target_bitrate = bitrate;
|
||||||
|
cfg.g_lag_in_frames = 3;
|
||||||
|
|
||||||
|
writer = vpx_video_writer_open(outfile_arg, kContainerIVF, &info);
|
||||||
|
if (!writer) die("Failed to open %s for writing.", outfile_arg);
|
||||||
|
|
||||||
|
if (!(infile = fopen(infile_arg, "rb")))
|
||||||
|
die("Failed to open %s for reading.", infile_arg);
|
||||||
|
|
||||||
|
if (vpx_codec_enc_init(&ecodec, encoder->codec_interface(), &cfg, 0))
|
||||||
|
die_codec(&ecodec, "Failed to initialize encoder");
|
||||||
|
|
||||||
|
// Disable alt_ref.
|
||||||
|
if (vpx_codec_control(&ecodec, VP8E_SET_ENABLEAUTOALTREF, 0))
|
||||||
|
die_codec(&ecodec, "Failed to set enable auto alt ref");
|
||||||
|
|
||||||
|
if (test_decode) {
|
||||||
|
const VpxInterface *decoder = get_vpx_decoder_by_name("vp9");
|
||||||
|
if (vpx_codec_dec_init(&dcodec, decoder->codec_interface(), NULL, 0))
|
||||||
|
die_codec(&dcodec, "Failed to initialize decoder.");
|
||||||
|
}
|
||||||
|
|
||||||
|
// Encode frames.
|
||||||
|
while (vpx_img_read(&raw, infile)) {
|
||||||
|
if (limit && frame_in >= limit) break;
|
||||||
|
if (update_frame_num > 1 && frame_out + 1 == update_frame_num) {
|
||||||
|
vpx_ref_frame_t ref;
|
||||||
|
ref.frame_type = VP8_LAST_FRAME;
|
||||||
|
ref.img = raw;
|
||||||
|
// Set reference frame in encoder.
|
||||||
|
if (vpx_codec_control(&ecodec, VP8_SET_REFERENCE, &ref))
|
||||||
|
die_codec(&ecodec, "Failed to set reference frame");
|
||||||
|
printf(" <SET_REF>");
|
||||||
|
|
||||||
|
// If set_reference in decoder is commented out, the enc/dec mismatch
|
||||||
|
// would be seen.
|
||||||
|
if (test_decode) {
|
||||||
|
if (vpx_codec_control(&dcodec, VP8_SET_REFERENCE, &ref))
|
||||||
|
die_codec(&dcodec, "Failed to set reference frame");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
encode_frame(&ecodec, &raw, frame_in, writer, test_decode, &dcodec,
|
||||||
|
&frame_out, &mismatch_seen);
|
||||||
|
frame_in++;
|
||||||
|
if (mismatch_seen) break;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Flush encoder.
|
||||||
|
if (!mismatch_seen)
|
||||||
|
while (encode_frame(&ecodec, NULL, frame_in, writer, test_decode, &dcodec,
|
||||||
|
&frame_out, &mismatch_seen)) {
|
||||||
|
}
|
||||||
|
|
||||||
|
printf("\n");
|
||||||
|
fclose(infile);
|
||||||
|
printf("Processed %d frames.\n", frame_out);
|
||||||
|
|
||||||
|
if (test_decode) {
|
||||||
|
if (!mismatch_seen)
|
||||||
|
printf("Encoder/decoder results are matching.\n");
|
||||||
|
else
|
||||||
|
printf("Encoder/decoder results are NOT matching.\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (test_decode)
|
||||||
|
if (vpx_codec_destroy(&dcodec))
|
||||||
|
die_codec(&dcodec, "Failed to destroy decoder");
|
||||||
|
|
||||||
|
vpx_img_free(&raw);
|
||||||
|
if (vpx_codec_destroy(&ecodec))
|
||||||
|
die_codec(&ecodec, "Failed to destroy encoder.");
|
||||||
|
|
||||||
|
vpx_video_writer_close(writer);
|
||||||
|
|
||||||
|
return EXIT_SUCCESS;
|
||||||
|
}
|
||||||
@@ -28,9 +28,7 @@
|
|||||||
|
|
||||||
static const char *exec_name;
|
static const char *exec_name;
|
||||||
|
|
||||||
void usage_exit(void) {
|
void usage_exit(void) { exit(EXIT_FAILURE); }
|
||||||
exit(EXIT_FAILURE);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Denoiser states, for temporal denoising.
|
// Denoiser states, for temporal denoising.
|
||||||
enum denoiserState {
|
enum denoiserState {
|
||||||
@@ -86,13 +84,13 @@ static void set_rate_control_metrics(struct RateControlMetrics *rc,
|
|||||||
// per-frame-bandwidth, for the rate control encoding stats below.
|
// per-frame-bandwidth, for the rate control encoding stats below.
|
||||||
const double framerate = cfg->g_timebase.den / cfg->g_timebase.num;
|
const double framerate = cfg->g_timebase.den / cfg->g_timebase.num;
|
||||||
rc->layer_framerate[0] = framerate / cfg->ts_rate_decimator[0];
|
rc->layer_framerate[0] = framerate / cfg->ts_rate_decimator[0];
|
||||||
rc->layer_pfb[0] = 1000.0 * rc->layer_target_bitrate[0] /
|
rc->layer_pfb[0] =
|
||||||
rc->layer_framerate[0];
|
1000.0 * rc->layer_target_bitrate[0] / rc->layer_framerate[0];
|
||||||
for (i = 0; i < cfg->ts_number_layers; ++i) {
|
for (i = 0; i < cfg->ts_number_layers; ++i) {
|
||||||
if (i > 0) {
|
if (i > 0) {
|
||||||
rc->layer_framerate[i] = framerate / cfg->ts_rate_decimator[i];
|
rc->layer_framerate[i] = framerate / cfg->ts_rate_decimator[i];
|
||||||
rc->layer_pfb[i] = 1000.0 *
|
rc->layer_pfb[i] = 1000.0 * (rc->layer_target_bitrate[i] -
|
||||||
(rc->layer_target_bitrate[i] - rc->layer_target_bitrate[i - 1]) /
|
rc->layer_target_bitrate[i - 1]) /
|
||||||
(rc->layer_framerate[i] - rc->layer_framerate[i - 1]);
|
(rc->layer_framerate[i] - rc->layer_framerate[i - 1]);
|
||||||
}
|
}
|
||||||
rc->layer_input_frames[i] = 0;
|
rc->layer_input_frames[i] = 0;
|
||||||
@@ -118,25 +116,27 @@ static void printout_rate_control_summary(struct RateControlMetrics *rc,
|
|||||||
printf("Rate control layer stats for %d layer(s):\n\n",
|
printf("Rate control layer stats for %d layer(s):\n\n",
|
||||||
cfg->ts_number_layers);
|
cfg->ts_number_layers);
|
||||||
for (i = 0; i < cfg->ts_number_layers; ++i) {
|
for (i = 0; i < cfg->ts_number_layers; ++i) {
|
||||||
const int num_dropped = (i > 0) ?
|
const int num_dropped =
|
||||||
(rc->layer_input_frames[i] - rc->layer_enc_frames[i]) :
|
(i > 0) ? (rc->layer_input_frames[i] - rc->layer_enc_frames[i])
|
||||||
(rc->layer_input_frames[i] - rc->layer_enc_frames[i] - 1);
|
: (rc->layer_input_frames[i] - rc->layer_enc_frames[i] - 1);
|
||||||
tot_num_frames += rc->layer_input_frames[i];
|
tot_num_frames += rc->layer_input_frames[i];
|
||||||
rc->layer_encoding_bitrate[i] = 0.001 * rc->layer_framerate[i] *
|
rc->layer_encoding_bitrate[i] = 0.001 * rc->layer_framerate[i] *
|
||||||
rc->layer_encoding_bitrate[i] / tot_num_frames;
|
rc->layer_encoding_bitrate[i] /
|
||||||
rc->layer_avg_frame_size[i] = rc->layer_avg_frame_size[i] /
|
tot_num_frames;
|
||||||
rc->layer_enc_frames[i];
|
rc->layer_avg_frame_size[i] =
|
||||||
rc->layer_avg_rate_mismatch[i] = 100.0 * rc->layer_avg_rate_mismatch[i] /
|
rc->layer_avg_frame_size[i] / rc->layer_enc_frames[i];
|
||||||
rc->layer_enc_frames[i];
|
rc->layer_avg_rate_mismatch[i] =
|
||||||
|
100.0 * rc->layer_avg_rate_mismatch[i] / rc->layer_enc_frames[i];
|
||||||
printf("For layer#: %d \n", i);
|
printf("For layer#: %d \n", i);
|
||||||
printf("Bitrate (target vs actual): %d %f \n", rc->layer_target_bitrate[i],
|
printf("Bitrate (target vs actual): %d %f \n", rc->layer_target_bitrate[i],
|
||||||
rc->layer_encoding_bitrate[i]);
|
rc->layer_encoding_bitrate[i]);
|
||||||
printf("Average frame size (target vs actual): %f %f \n", rc->layer_pfb[i],
|
printf("Average frame size (target vs actual): %f %f \n", rc->layer_pfb[i],
|
||||||
rc->layer_avg_frame_size[i]);
|
rc->layer_avg_frame_size[i]);
|
||||||
printf("Average rate_mismatch: %f \n", rc->layer_avg_rate_mismatch[i]);
|
printf("Average rate_mismatch: %f \n", rc->layer_avg_rate_mismatch[i]);
|
||||||
printf("Number of input frames, encoded (non-key) frames, "
|
printf(
|
||||||
"and perc dropped frames: %d %d %f \n", rc->layer_input_frames[i],
|
"Number of input frames, encoded (non-key) frames, "
|
||||||
rc->layer_enc_frames[i],
|
"and perc dropped frames: %d %d %f \n",
|
||||||
|
rc->layer_input_frames[i], rc->layer_enc_frames[i],
|
||||||
100.0 * num_dropped / rc->layer_input_frames[i]);
|
100.0 * num_dropped / rc->layer_input_frames[i]);
|
||||||
printf("\n");
|
printf("\n");
|
||||||
}
|
}
|
||||||
@@ -148,8 +148,7 @@ static void printout_rate_control_summary(struct RateControlMetrics *rc,
|
|||||||
rc->avg_st_encoding_bitrate;
|
rc->avg_st_encoding_bitrate;
|
||||||
printf("Short-time stats, for window of %d frames: \n", rc->window_size);
|
printf("Short-time stats, for window of %d frames: \n", rc->window_size);
|
||||||
printf("Average, rms-variance, and percent-fluct: %f %f %f \n",
|
printf("Average, rms-variance, and percent-fluct: %f %f %f \n",
|
||||||
rc->avg_st_encoding_bitrate,
|
rc->avg_st_encoding_bitrate, sqrt(rc->variance_st_encoding_bitrate),
|
||||||
sqrt(rc->variance_st_encoding_bitrate),
|
|
||||||
perc_fluctuation);
|
perc_fluctuation);
|
||||||
if ((frame_cnt - 1) != tot_num_frames)
|
if ((frame_cnt - 1) != tot_num_frames)
|
||||||
die("Error: Number of input frames not equal to output! \n");
|
die("Error: Number of input frames not equal to output! \n");
|
||||||
@@ -174,8 +173,8 @@ static void set_temporal_layer_pattern(int layering_mode,
|
|||||||
cfg->ts_rate_decimator[0] = 1;
|
cfg->ts_rate_decimator[0] = 1;
|
||||||
memcpy(cfg->ts_layer_id, ids, sizeof(ids));
|
memcpy(cfg->ts_layer_id, ids, sizeof(ids));
|
||||||
// Update L only.
|
// Update L only.
|
||||||
layer_flags[0] = VPX_EFLAG_FORCE_KF | VP8_EFLAG_NO_UPD_GF |
|
layer_flags[0] =
|
||||||
VP8_EFLAG_NO_UPD_ARF;
|
VPX_EFLAG_FORCE_KF | VP8_EFLAG_NO_UPD_GF | VP8_EFLAG_NO_UPD_ARF;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case 1: {
|
case 1: {
|
||||||
@@ -190,13 +189,15 @@ static void set_temporal_layer_pattern(int layering_mode,
|
|||||||
#if 1
|
#if 1
|
||||||
// 0=L, 1=GF, Intra-layer prediction enabled.
|
// 0=L, 1=GF, Intra-layer prediction enabled.
|
||||||
layer_flags[0] = VPX_EFLAG_FORCE_KF | VP8_EFLAG_NO_UPD_GF |
|
layer_flags[0] = VPX_EFLAG_FORCE_KF | VP8_EFLAG_NO_UPD_GF |
|
||||||
VP8_EFLAG_NO_UPD_ARF | VP8_EFLAG_NO_REF_GF | VP8_EFLAG_NO_REF_ARF;
|
VP8_EFLAG_NO_UPD_ARF | VP8_EFLAG_NO_REF_GF |
|
||||||
layer_flags[1] = VP8_EFLAG_NO_UPD_ARF | VP8_EFLAG_NO_UPD_LAST |
|
|
||||||
VP8_EFLAG_NO_REF_ARF;
|
VP8_EFLAG_NO_REF_ARF;
|
||||||
|
layer_flags[1] =
|
||||||
|
VP8_EFLAG_NO_UPD_ARF | VP8_EFLAG_NO_UPD_LAST | VP8_EFLAG_NO_REF_ARF;
|
||||||
#else
|
#else
|
||||||
// 0=L, 1=GF, Intra-layer prediction disabled.
|
// 0=L, 1=GF, Intra-layer prediction disabled.
|
||||||
layer_flags[0] = VPX_EFLAG_FORCE_KF | VP8_EFLAG_NO_UPD_GF |
|
layer_flags[0] = VPX_EFLAG_FORCE_KF | VP8_EFLAG_NO_UPD_GF |
|
||||||
VP8_EFLAG_NO_UPD_ARF | VP8_EFLAG_NO_REF_GF | VP8_EFLAG_NO_REF_ARF;
|
VP8_EFLAG_NO_UPD_ARF | VP8_EFLAG_NO_REF_GF |
|
||||||
|
VP8_EFLAG_NO_REF_ARF;
|
||||||
layer_flags[1] = VP8_EFLAG_NO_UPD_ARF | VP8_EFLAG_NO_UPD_LAST |
|
layer_flags[1] = VP8_EFLAG_NO_UPD_ARF | VP8_EFLAG_NO_UPD_LAST |
|
||||||
VP8_EFLAG_NO_REF_ARF | VP8_EFLAG_NO_REF_LAST;
|
VP8_EFLAG_NO_REF_ARF | VP8_EFLAG_NO_REF_LAST;
|
||||||
#endif
|
#endif
|
||||||
@@ -213,10 +214,11 @@ static void set_temporal_layer_pattern(int layering_mode,
|
|||||||
memcpy(cfg->ts_layer_id, ids, sizeof(ids));
|
memcpy(cfg->ts_layer_id, ids, sizeof(ids));
|
||||||
// 0=L, 1=GF, Intra-layer prediction enabled.
|
// 0=L, 1=GF, Intra-layer prediction enabled.
|
||||||
layer_flags[0] = VPX_EFLAG_FORCE_KF | VP8_EFLAG_NO_REF_GF |
|
layer_flags[0] = VPX_EFLAG_FORCE_KF | VP8_EFLAG_NO_REF_GF |
|
||||||
VP8_EFLAG_NO_REF_ARF | VP8_EFLAG_NO_UPD_GF | VP8_EFLAG_NO_UPD_ARF;
|
VP8_EFLAG_NO_REF_ARF | VP8_EFLAG_NO_UPD_GF |
|
||||||
layer_flags[1] =
|
VP8_EFLAG_NO_UPD_ARF;
|
||||||
layer_flags[2] = VP8_EFLAG_NO_REF_GF | VP8_EFLAG_NO_REF_ARF |
|
layer_flags[1] = layer_flags[2] =
|
||||||
VP8_EFLAG_NO_UPD_ARF | VP8_EFLAG_NO_UPD_LAST;
|
VP8_EFLAG_NO_REF_GF | VP8_EFLAG_NO_REF_ARF | VP8_EFLAG_NO_UPD_ARF |
|
||||||
|
VP8_EFLAG_NO_UPD_LAST;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case 3: {
|
case 3: {
|
||||||
@@ -231,13 +233,12 @@ static void set_temporal_layer_pattern(int layering_mode,
|
|||||||
memcpy(cfg->ts_layer_id, ids, sizeof(ids));
|
memcpy(cfg->ts_layer_id, ids, sizeof(ids));
|
||||||
// 0=L, 1=GF, 2=ARF, Intra-layer prediction enabled.
|
// 0=L, 1=GF, 2=ARF, Intra-layer prediction enabled.
|
||||||
layer_flags[0] = VPX_EFLAG_FORCE_KF | VP8_EFLAG_NO_REF_GF |
|
layer_flags[0] = VPX_EFLAG_FORCE_KF | VP8_EFLAG_NO_REF_GF |
|
||||||
VP8_EFLAG_NO_REF_ARF | VP8_EFLAG_NO_UPD_GF | VP8_EFLAG_NO_UPD_ARF;
|
VP8_EFLAG_NO_REF_ARF | VP8_EFLAG_NO_UPD_GF |
|
||||||
layer_flags[3] = VP8_EFLAG_NO_REF_ARF | VP8_EFLAG_NO_UPD_ARF |
|
VP8_EFLAG_NO_UPD_ARF;
|
||||||
VP8_EFLAG_NO_UPD_LAST;
|
layer_flags[3] =
|
||||||
layer_flags[1] =
|
VP8_EFLAG_NO_REF_ARF | VP8_EFLAG_NO_UPD_ARF | VP8_EFLAG_NO_UPD_LAST;
|
||||||
layer_flags[2] =
|
layer_flags[1] = layer_flags[2] = layer_flags[4] = layer_flags[5] =
|
||||||
layer_flags[4] =
|
VP8_EFLAG_NO_UPD_GF | VP8_EFLAG_NO_UPD_LAST;
|
||||||
layer_flags[5] = VP8_EFLAG_NO_UPD_GF | VP8_EFLAG_NO_UPD_LAST;
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case 4: {
|
case 4: {
|
||||||
@@ -252,12 +253,13 @@ static void set_temporal_layer_pattern(int layering_mode,
|
|||||||
memcpy(cfg->ts_layer_id, ids, sizeof(ids));
|
memcpy(cfg->ts_layer_id, ids, sizeof(ids));
|
||||||
// 0=L, 1=GF, 2=ARF, Intra-layer prediction disabled.
|
// 0=L, 1=GF, 2=ARF, Intra-layer prediction disabled.
|
||||||
layer_flags[0] = VPX_EFLAG_FORCE_KF | VP8_EFLAG_NO_REF_GF |
|
layer_flags[0] = VPX_EFLAG_FORCE_KF | VP8_EFLAG_NO_REF_GF |
|
||||||
VP8_EFLAG_NO_REF_ARF | VP8_EFLAG_NO_UPD_GF | VP8_EFLAG_NO_UPD_ARF;
|
VP8_EFLAG_NO_REF_ARF | VP8_EFLAG_NO_UPD_GF |
|
||||||
|
VP8_EFLAG_NO_UPD_ARF;
|
||||||
layer_flags[2] = VP8_EFLAG_NO_REF_GF | VP8_EFLAG_NO_REF_ARF |
|
layer_flags[2] = VP8_EFLAG_NO_REF_GF | VP8_EFLAG_NO_REF_ARF |
|
||||||
VP8_EFLAG_NO_UPD_ARF | VP8_EFLAG_NO_UPD_LAST;
|
VP8_EFLAG_NO_UPD_ARF | VP8_EFLAG_NO_UPD_LAST;
|
||||||
layer_flags[1] =
|
layer_flags[1] = layer_flags[3] =
|
||||||
layer_flags[3] = VP8_EFLAG_NO_REF_ARF | VP8_EFLAG_NO_UPD_LAST |
|
VP8_EFLAG_NO_REF_ARF | VP8_EFLAG_NO_UPD_LAST | VP8_EFLAG_NO_UPD_GF |
|
||||||
VP8_EFLAG_NO_UPD_GF | VP8_EFLAG_NO_UPD_ARF;
|
VP8_EFLAG_NO_UPD_ARF;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case 5: {
|
case 5: {
|
||||||
@@ -273,12 +275,13 @@ static void set_temporal_layer_pattern(int layering_mode,
|
|||||||
// 0=L, 1=GF, 2=ARF, Intra-layer prediction enabled in layer 1, disabled
|
// 0=L, 1=GF, 2=ARF, Intra-layer prediction enabled in layer 1, disabled
|
||||||
// in layer 2.
|
// in layer 2.
|
||||||
layer_flags[0] = VPX_EFLAG_FORCE_KF | VP8_EFLAG_NO_REF_GF |
|
layer_flags[0] = VPX_EFLAG_FORCE_KF | VP8_EFLAG_NO_REF_GF |
|
||||||
VP8_EFLAG_NO_REF_ARF | VP8_EFLAG_NO_UPD_GF | VP8_EFLAG_NO_UPD_ARF;
|
VP8_EFLAG_NO_REF_ARF | VP8_EFLAG_NO_UPD_GF |
|
||||||
layer_flags[2] = VP8_EFLAG_NO_REF_ARF | VP8_EFLAG_NO_UPD_LAST |
|
VP8_EFLAG_NO_UPD_ARF;
|
||||||
|
layer_flags[2] =
|
||||||
|
VP8_EFLAG_NO_REF_ARF | VP8_EFLAG_NO_UPD_LAST | VP8_EFLAG_NO_UPD_ARF;
|
||||||
|
layer_flags[1] = layer_flags[3] =
|
||||||
|
VP8_EFLAG_NO_REF_ARF | VP8_EFLAG_NO_UPD_LAST | VP8_EFLAG_NO_UPD_GF |
|
||||||
VP8_EFLAG_NO_UPD_ARF;
|
VP8_EFLAG_NO_UPD_ARF;
|
||||||
layer_flags[1] =
|
|
||||||
layer_flags[3] = VP8_EFLAG_NO_REF_ARF | VP8_EFLAG_NO_UPD_LAST |
|
|
||||||
VP8_EFLAG_NO_UPD_GF | VP8_EFLAG_NO_UPD_ARF;
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case 6: {
|
case 6: {
|
||||||
@@ -293,11 +296,12 @@ static void set_temporal_layer_pattern(int layering_mode,
|
|||||||
memcpy(cfg->ts_layer_id, ids, sizeof(ids));
|
memcpy(cfg->ts_layer_id, ids, sizeof(ids));
|
||||||
// 0=L, 1=GF, 2=ARF, Intra-layer prediction enabled.
|
// 0=L, 1=GF, 2=ARF, Intra-layer prediction enabled.
|
||||||
layer_flags[0] = VPX_EFLAG_FORCE_KF | VP8_EFLAG_NO_REF_GF |
|
layer_flags[0] = VPX_EFLAG_FORCE_KF | VP8_EFLAG_NO_REF_GF |
|
||||||
VP8_EFLAG_NO_REF_ARF | VP8_EFLAG_NO_UPD_GF | VP8_EFLAG_NO_UPD_ARF;
|
VP8_EFLAG_NO_REF_ARF | VP8_EFLAG_NO_UPD_GF |
|
||||||
layer_flags[2] = VP8_EFLAG_NO_REF_ARF | VP8_EFLAG_NO_UPD_LAST |
|
|
||||||
VP8_EFLAG_NO_UPD_ARF;
|
VP8_EFLAG_NO_UPD_ARF;
|
||||||
layer_flags[1] =
|
layer_flags[2] =
|
||||||
layer_flags[3] = VP8_EFLAG_NO_UPD_LAST | VP8_EFLAG_NO_UPD_GF;
|
VP8_EFLAG_NO_REF_ARF | VP8_EFLAG_NO_UPD_LAST | VP8_EFLAG_NO_UPD_ARF;
|
||||||
|
layer_flags[1] = layer_flags[3] =
|
||||||
|
VP8_EFLAG_NO_UPD_LAST | VP8_EFLAG_NO_UPD_GF;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case 7: {
|
case 7: {
|
||||||
@@ -314,21 +318,14 @@ static void set_temporal_layer_pattern(int layering_mode,
|
|||||||
cfg->ts_rate_decimator[4] = 1;
|
cfg->ts_rate_decimator[4] = 1;
|
||||||
memcpy(cfg->ts_layer_id, ids, sizeof(ids));
|
memcpy(cfg->ts_layer_id, ids, sizeof(ids));
|
||||||
layer_flags[0] = VPX_EFLAG_FORCE_KF;
|
layer_flags[0] = VPX_EFLAG_FORCE_KF;
|
||||||
layer_flags[1] =
|
layer_flags[1] = layer_flags[3] = layer_flags[5] = layer_flags[7] =
|
||||||
layer_flags[3] =
|
layer_flags[9] = layer_flags[11] = layer_flags[13] = layer_flags[15] =
|
||||||
layer_flags[5] =
|
VP8_EFLAG_NO_UPD_LAST | VP8_EFLAG_NO_UPD_GF |
|
||||||
layer_flags[7] =
|
|
||||||
layer_flags[9] =
|
|
||||||
layer_flags[11] =
|
|
||||||
layer_flags[13] =
|
|
||||||
layer_flags[15] = VP8_EFLAG_NO_UPD_LAST | VP8_EFLAG_NO_UPD_GF |
|
|
||||||
VP8_EFLAG_NO_UPD_ARF;
|
VP8_EFLAG_NO_UPD_ARF;
|
||||||
layer_flags[2] =
|
layer_flags[2] = layer_flags[6] = layer_flags[10] = layer_flags[14] =
|
||||||
layer_flags[6] =
|
VP8_EFLAG_NO_UPD_ARF | VP8_EFLAG_NO_UPD_GF;
|
||||||
layer_flags[10] =
|
layer_flags[4] = layer_flags[12] =
|
||||||
layer_flags[14] = VP8_EFLAG_NO_UPD_ARF | VP8_EFLAG_NO_UPD_GF;
|
VP8_EFLAG_NO_REF_LAST | VP8_EFLAG_NO_UPD_ARF;
|
||||||
layer_flags[4] =
|
|
||||||
layer_flags[12] = VP8_EFLAG_NO_REF_LAST | VP8_EFLAG_NO_UPD_ARF;
|
|
||||||
layer_flags[8] = VP8_EFLAG_NO_REF_LAST | VP8_EFLAG_NO_REF_GF;
|
layer_flags[8] = VP8_EFLAG_NO_REF_LAST | VP8_EFLAG_NO_REF_GF;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -346,14 +343,14 @@ static void set_temporal_layer_pattern(int layering_mode,
|
|||||||
// key frame. Sync point every 8 frames.
|
// key frame. Sync point every 8 frames.
|
||||||
|
|
||||||
// Layer 0: predict from L and ARF, update L and G.
|
// Layer 0: predict from L and ARF, update L and G.
|
||||||
layer_flags[0] = VPX_EFLAG_FORCE_KF | VP8_EFLAG_NO_REF_GF |
|
layer_flags[0] =
|
||||||
VP8_EFLAG_NO_UPD_ARF;
|
VPX_EFLAG_FORCE_KF | VP8_EFLAG_NO_REF_GF | VP8_EFLAG_NO_UPD_ARF;
|
||||||
// Layer 1: sync point: predict from L and ARF, and update G.
|
// Layer 1: sync point: predict from L and ARF, and update G.
|
||||||
layer_flags[1] = VP8_EFLAG_NO_REF_GF | VP8_EFLAG_NO_UPD_LAST |
|
layer_flags[1] =
|
||||||
VP8_EFLAG_NO_UPD_ARF;
|
VP8_EFLAG_NO_REF_GF | VP8_EFLAG_NO_UPD_LAST | VP8_EFLAG_NO_UPD_ARF;
|
||||||
// Layer 0, predict from L and ARF, update L.
|
// Layer 0, predict from L and ARF, update L.
|
||||||
layer_flags[2] = VP8_EFLAG_NO_REF_GF | VP8_EFLAG_NO_UPD_GF |
|
layer_flags[2] =
|
||||||
VP8_EFLAG_NO_UPD_ARF;
|
VP8_EFLAG_NO_REF_GF | VP8_EFLAG_NO_UPD_GF | VP8_EFLAG_NO_UPD_ARF;
|
||||||
// Layer 1: predict from L, G and ARF, and update G.
|
// Layer 1: predict from L, G and ARF, and update G.
|
||||||
layer_flags[3] = VP8_EFLAG_NO_UPD_ARF | VP8_EFLAG_NO_UPD_LAST |
|
layer_flags[3] = VP8_EFLAG_NO_UPD_ARF | VP8_EFLAG_NO_UPD_LAST |
|
||||||
VP8_EFLAG_NO_UPD_ENTROPY;
|
VP8_EFLAG_NO_UPD_ENTROPY;
|
||||||
@@ -379,17 +376,18 @@ static void set_temporal_layer_pattern(int layering_mode,
|
|||||||
memcpy(cfg->ts_layer_id, ids, sizeof(ids));
|
memcpy(cfg->ts_layer_id, ids, sizeof(ids));
|
||||||
// 0=L, 1=GF, 2=ARF.
|
// 0=L, 1=GF, 2=ARF.
|
||||||
layer_flags[0] = VPX_EFLAG_FORCE_KF | VP8_EFLAG_NO_REF_GF |
|
layer_flags[0] = VPX_EFLAG_FORCE_KF | VP8_EFLAG_NO_REF_GF |
|
||||||
VP8_EFLAG_NO_REF_ARF | VP8_EFLAG_NO_UPD_GF | VP8_EFLAG_NO_UPD_ARF;
|
VP8_EFLAG_NO_REF_ARF | VP8_EFLAG_NO_UPD_GF |
|
||||||
|
VP8_EFLAG_NO_UPD_ARF;
|
||||||
layer_flags[1] = VP8_EFLAG_NO_REF_GF | VP8_EFLAG_NO_REF_ARF |
|
layer_flags[1] = VP8_EFLAG_NO_REF_GF | VP8_EFLAG_NO_REF_ARF |
|
||||||
VP8_EFLAG_NO_UPD_LAST | VP8_EFLAG_NO_UPD_GF;
|
VP8_EFLAG_NO_UPD_LAST | VP8_EFLAG_NO_UPD_GF;
|
||||||
layer_flags[2] = VP8_EFLAG_NO_REF_GF | VP8_EFLAG_NO_REF_ARF |
|
layer_flags[2] = VP8_EFLAG_NO_REF_GF | VP8_EFLAG_NO_REF_ARF |
|
||||||
VP8_EFLAG_NO_UPD_LAST | VP8_EFLAG_NO_UPD_ARF;
|
VP8_EFLAG_NO_UPD_LAST | VP8_EFLAG_NO_UPD_ARF;
|
||||||
layer_flags[3] =
|
layer_flags[3] = layer_flags[5] =
|
||||||
layer_flags[5] = VP8_EFLAG_NO_UPD_LAST | VP8_EFLAG_NO_UPD_GF;
|
VP8_EFLAG_NO_UPD_LAST | VP8_EFLAG_NO_UPD_GF;
|
||||||
layer_flags[4] = VP8_EFLAG_NO_REF_GF | VP8_EFLAG_NO_REF_ARF |
|
layer_flags[4] = VP8_EFLAG_NO_REF_GF | VP8_EFLAG_NO_REF_ARF |
|
||||||
VP8_EFLAG_NO_UPD_GF | VP8_EFLAG_NO_UPD_ARF;
|
VP8_EFLAG_NO_UPD_GF | VP8_EFLAG_NO_UPD_ARF;
|
||||||
layer_flags[6] = VP8_EFLAG_NO_REF_ARF | VP8_EFLAG_NO_UPD_LAST |
|
layer_flags[6] =
|
||||||
VP8_EFLAG_NO_UPD_ARF;
|
VP8_EFLAG_NO_REF_ARF | VP8_EFLAG_NO_UPD_LAST | VP8_EFLAG_NO_UPD_ARF;
|
||||||
layer_flags[7] = VP8_EFLAG_NO_UPD_LAST | VP8_EFLAG_NO_UPD_GF |
|
layer_flags[7] = VP8_EFLAG_NO_UPD_LAST | VP8_EFLAG_NO_UPD_GF |
|
||||||
VP8_EFLAG_NO_UPD_ARF | VP8_EFLAG_NO_UPD_ENTROPY;
|
VP8_EFLAG_NO_UPD_ARF | VP8_EFLAG_NO_UPD_ENTROPY;
|
||||||
break;
|
break;
|
||||||
@@ -409,21 +407,21 @@ static void set_temporal_layer_pattern(int layering_mode,
|
|||||||
memcpy(cfg->ts_layer_id, ids, sizeof(ids));
|
memcpy(cfg->ts_layer_id, ids, sizeof(ids));
|
||||||
// 0=L, 1=GF, 2=ARF.
|
// 0=L, 1=GF, 2=ARF.
|
||||||
// Layer 0: predict from L and ARF; update L and G.
|
// Layer 0: predict from L and ARF; update L and G.
|
||||||
layer_flags[0] = VPX_EFLAG_FORCE_KF | VP8_EFLAG_NO_UPD_ARF |
|
layer_flags[0] =
|
||||||
VP8_EFLAG_NO_REF_GF;
|
VPX_EFLAG_FORCE_KF | VP8_EFLAG_NO_UPD_ARF | VP8_EFLAG_NO_REF_GF;
|
||||||
// Layer 2: sync point: predict from L and ARF; update none.
|
// Layer 2: sync point: predict from L and ARF; update none.
|
||||||
layer_flags[1] = VP8_EFLAG_NO_REF_GF | VP8_EFLAG_NO_UPD_GF |
|
layer_flags[1] = VP8_EFLAG_NO_REF_GF | VP8_EFLAG_NO_UPD_GF |
|
||||||
VP8_EFLAG_NO_UPD_ARF | VP8_EFLAG_NO_UPD_LAST |
|
VP8_EFLAG_NO_UPD_ARF | VP8_EFLAG_NO_UPD_LAST |
|
||||||
VP8_EFLAG_NO_UPD_ENTROPY;
|
VP8_EFLAG_NO_UPD_ENTROPY;
|
||||||
// Layer 1: sync point: predict from L and ARF; update G.
|
// Layer 1: sync point: predict from L and ARF; update G.
|
||||||
layer_flags[2] = VP8_EFLAG_NO_REF_GF | VP8_EFLAG_NO_UPD_ARF |
|
layer_flags[2] =
|
||||||
VP8_EFLAG_NO_UPD_LAST;
|
VP8_EFLAG_NO_REF_GF | VP8_EFLAG_NO_UPD_ARF | VP8_EFLAG_NO_UPD_LAST;
|
||||||
// Layer 2: predict from L, G, ARF; update none.
|
// Layer 2: predict from L, G, ARF; update none.
|
||||||
layer_flags[3] = VP8_EFLAG_NO_UPD_GF | VP8_EFLAG_NO_UPD_ARF |
|
layer_flags[3] = VP8_EFLAG_NO_UPD_GF | VP8_EFLAG_NO_UPD_ARF |
|
||||||
VP8_EFLAG_NO_UPD_LAST | VP8_EFLAG_NO_UPD_ENTROPY;
|
VP8_EFLAG_NO_UPD_LAST | VP8_EFLAG_NO_UPD_ENTROPY;
|
||||||
// Layer 0: predict from L and ARF; update L.
|
// Layer 0: predict from L and ARF; update L.
|
||||||
layer_flags[4] = VP8_EFLAG_NO_UPD_GF | VP8_EFLAG_NO_UPD_ARF |
|
layer_flags[4] =
|
||||||
VP8_EFLAG_NO_REF_GF;
|
VP8_EFLAG_NO_UPD_GF | VP8_EFLAG_NO_UPD_ARF | VP8_EFLAG_NO_REF_GF;
|
||||||
// Layer 2: predict from L, G, ARF; update none.
|
// Layer 2: predict from L, G, ARF; update none.
|
||||||
layer_flags[5] = layer_flags[3];
|
layer_flags[5] = layer_flags[3];
|
||||||
// Layer 1: predict from L, G, ARF; update G.
|
// Layer 1: predict from L, G, ARF; update G.
|
||||||
@@ -471,8 +469,8 @@ static void set_temporal_layer_pattern(int layering_mode,
|
|||||||
memcpy(cfg->ts_layer_id, ids, sizeof(ids));
|
memcpy(cfg->ts_layer_id, ids, sizeof(ids));
|
||||||
// 0=L, 1=GF, 2=ARF.
|
// 0=L, 1=GF, 2=ARF.
|
||||||
// Layer 0: predict from L and ARF; update L.
|
// Layer 0: predict from L and ARF; update L.
|
||||||
layer_flags[0] = VP8_EFLAG_NO_UPD_GF | VP8_EFLAG_NO_UPD_ARF |
|
layer_flags[0] =
|
||||||
VP8_EFLAG_NO_REF_GF;
|
VP8_EFLAG_NO_UPD_GF | VP8_EFLAG_NO_UPD_ARF | VP8_EFLAG_NO_REF_GF;
|
||||||
layer_flags[4] = layer_flags[0];
|
layer_flags[4] = layer_flags[0];
|
||||||
// Layer 1: predict from L, G, ARF; update G.
|
// Layer 1: predict from L, G, ARF; update G.
|
||||||
layer_flags[2] = VP8_EFLAG_NO_UPD_ARF | VP8_EFLAG_NO_UPD_LAST;
|
layer_flags[2] = VP8_EFLAG_NO_UPD_ARF | VP8_EFLAG_NO_UPD_LAST;
|
||||||
@@ -516,7 +514,7 @@ int main(int argc, char **argv) {
|
|||||||
FILE *infile = NULL;
|
FILE *infile = NULL;
|
||||||
struct RateControlMetrics rc;
|
struct RateControlMetrics rc;
|
||||||
int64_t cx_time = 0;
|
int64_t cx_time = 0;
|
||||||
const int min_args_base = 11;
|
const int min_args_base = 12;
|
||||||
#if CONFIG_VP9_HIGHBITDEPTH
|
#if CONFIG_VP9_HIGHBITDEPTH
|
||||||
vpx_bit_depth_t bit_depth = VPX_BITS_8;
|
vpx_bit_depth_t bit_depth = VPX_BITS_8;
|
||||||
int input_bit_depth = 8;
|
int input_bit_depth = 8;
|
||||||
@@ -533,30 +531,31 @@ int main(int argc, char **argv) {
|
|||||||
if (argc < min_args) {
|
if (argc < min_args) {
|
||||||
#if CONFIG_VP9_HIGHBITDEPTH
|
#if CONFIG_VP9_HIGHBITDEPTH
|
||||||
die("Usage: %s <infile> <outfile> <codec_type(vp8/vp9)> <width> <height> "
|
die("Usage: %s <infile> <outfile> <codec_type(vp8/vp9)> <width> <height> "
|
||||||
"<rate_num> <rate_den> <speed> <frame_drop_threshold> <mode> "
|
"<rate_num> <rate_den> <speed> <frame_drop_threshold> <threads> <mode> "
|
||||||
"<Rate_0> ... <Rate_nlayers-1> <bit-depth> \n", argv[0]);
|
"<Rate_0> ... <Rate_nlayers-1> <bit-depth> \n",
|
||||||
|
argv[0]);
|
||||||
#else
|
#else
|
||||||
die("Usage: %s <infile> <outfile> <codec_type(vp8/vp9)> <width> <height> "
|
die("Usage: %s <infile> <outfile> <codec_type(vp8/vp9)> <width> <height> "
|
||||||
"<rate_num> <rate_den> <speed> <frame_drop_threshold> <mode> "
|
"<rate_num> <rate_den> <speed> <frame_drop_threshold> <threads> <mode> "
|
||||||
"<Rate_0> ... <Rate_nlayers-1> \n", argv[0]);
|
"<Rate_0> ... <Rate_nlayers-1> \n",
|
||||||
|
argv[0]);
|
||||||
#endif // CONFIG_VP9_HIGHBITDEPTH
|
#endif // CONFIG_VP9_HIGHBITDEPTH
|
||||||
}
|
}
|
||||||
|
|
||||||
encoder = get_vpx_encoder_by_name(argv[3]);
|
encoder = get_vpx_encoder_by_name(argv[3]);
|
||||||
if (!encoder)
|
if (!encoder) die("Unsupported codec.");
|
||||||
die("Unsupported codec.");
|
|
||||||
|
|
||||||
printf("Using %s\n", vpx_codec_iface_name(encoder->codec_interface()));
|
printf("Using %s\n", vpx_codec_iface_name(encoder->codec_interface()));
|
||||||
|
|
||||||
width = strtol(argv[4], NULL, 0);
|
width = (unsigned int)strtoul(argv[4], NULL, 0);
|
||||||
height = strtol(argv[5], NULL, 0);
|
height = (unsigned int)strtoul(argv[5], NULL, 0);
|
||||||
if (width < 16 || width % 2 || height < 16 || height % 2) {
|
if (width < 16 || width % 2 || height < 16 || height % 2) {
|
||||||
die("Invalid resolution: %d x %d", width, height);
|
die("Invalid resolution: %d x %d", width, height);
|
||||||
}
|
}
|
||||||
|
|
||||||
layering_mode = strtol(argv[10], NULL, 0);
|
layering_mode = (int)strtol(argv[11], NULL, 0);
|
||||||
if (layering_mode < 0 || layering_mode > 13) {
|
if (layering_mode < 0 || layering_mode > 13) {
|
||||||
die("Invalid layering mode (0..12) %s", argv[10]);
|
die("Invalid layering mode (0..12) %s", argv[11]);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (argc != min_args + mode_to_num_layers[layering_mode]) {
|
if (argc != min_args + mode_to_num_layers[layering_mode]) {
|
||||||
@@ -577,12 +576,10 @@ int main(int argc, char **argv) {
|
|||||||
bit_depth = VPX_BITS_12;
|
bit_depth = VPX_BITS_12;
|
||||||
input_bit_depth = 12;
|
input_bit_depth = 12;
|
||||||
break;
|
break;
|
||||||
default:
|
default: die("Invalid bit depth (8, 10, 12) %s", argv[argc - 1]);
|
||||||
die("Invalid bit depth (8, 10, 12) %s", argv[argc-1]);
|
|
||||||
}
|
}
|
||||||
if (!vpx_img_alloc(&raw,
|
if (!vpx_img_alloc(
|
||||||
bit_depth == VPX_BITS_8 ? VPX_IMG_FMT_I420 :
|
&raw, bit_depth == VPX_BITS_8 ? VPX_IMG_FMT_I420 : VPX_IMG_FMT_I42016,
|
||||||
VPX_IMG_FMT_I42016,
|
|
||||||
width, height, 32)) {
|
width, height, 32)) {
|
||||||
die("Failed to allocate image", width, height);
|
die("Failed to allocate image", width, height);
|
||||||
}
|
}
|
||||||
@@ -612,31 +609,29 @@ int main(int argc, char **argv) {
|
|||||||
#endif // CONFIG_VP9_HIGHBITDEPTH
|
#endif // CONFIG_VP9_HIGHBITDEPTH
|
||||||
|
|
||||||
// Timebase format e.g. 30fps: numerator=1, demoninator = 30.
|
// Timebase format e.g. 30fps: numerator=1, demoninator = 30.
|
||||||
cfg.g_timebase.num = strtol(argv[6], NULL, 0);
|
cfg.g_timebase.num = (int)strtol(argv[6], NULL, 0);
|
||||||
cfg.g_timebase.den = strtol(argv[7], NULL, 0);
|
cfg.g_timebase.den = (int)strtol(argv[7], NULL, 0);
|
||||||
|
|
||||||
speed = strtol(argv[8], NULL, 0);
|
speed = (int)strtol(argv[8], NULL, 0);
|
||||||
if (speed < 0) {
|
if (speed < 0) {
|
||||||
die("Invalid speed setting: must be positive");
|
die("Invalid speed setting: must be positive");
|
||||||
}
|
}
|
||||||
|
|
||||||
for (i = min_args_base;
|
for (i = min_args_base;
|
||||||
(int)i < min_args_base + mode_to_num_layers[layering_mode];
|
(int)i < min_args_base + mode_to_num_layers[layering_mode]; ++i) {
|
||||||
++i) {
|
rc.layer_target_bitrate[i - 12] = (int)strtol(argv[i], NULL, 0);
|
||||||
rc.layer_target_bitrate[i - 11] = strtol(argv[i], NULL, 0);
|
|
||||||
if (strncmp(encoder->name, "vp8", 3) == 0)
|
if (strncmp(encoder->name, "vp8", 3) == 0)
|
||||||
cfg.ts_target_bitrate[i - 11] = rc.layer_target_bitrate[i - 11];
|
cfg.ts_target_bitrate[i - 12] = rc.layer_target_bitrate[i - 12];
|
||||||
else if (strncmp(encoder->name, "vp9", 3) == 0)
|
else if (strncmp(encoder->name, "vp9", 3) == 0)
|
||||||
cfg.layer_target_bitrate[i - 11] = rc.layer_target_bitrate[i - 11];
|
cfg.layer_target_bitrate[i - 12] = rc.layer_target_bitrate[i - 12];
|
||||||
}
|
}
|
||||||
|
|
||||||
// Real time parameters.
|
// Real time parameters.
|
||||||
cfg.rc_dropframe_thresh = strtol(argv[9], NULL, 0);
|
cfg.rc_dropframe_thresh = (unsigned int)strtoul(argv[9], NULL, 0);
|
||||||
cfg.rc_end_usage = VPX_CBR;
|
cfg.rc_end_usage = VPX_CBR;
|
||||||
cfg.rc_min_quantizer = 2;
|
cfg.rc_min_quantizer = 2;
|
||||||
cfg.rc_max_quantizer = 56;
|
cfg.rc_max_quantizer = 56;
|
||||||
if (strncmp(encoder->name, "vp9", 3) == 0)
|
if (strncmp(encoder->name, "vp9", 3) == 0) cfg.rc_max_quantizer = 52;
|
||||||
cfg.rc_max_quantizer = 52;
|
|
||||||
cfg.rc_undershoot_pct = 50;
|
cfg.rc_undershoot_pct = 50;
|
||||||
cfg.rc_overshoot_pct = 50;
|
cfg.rc_overshoot_pct = 50;
|
||||||
cfg.rc_buf_initial_sz = 500;
|
cfg.rc_buf_initial_sz = 500;
|
||||||
@@ -647,7 +642,7 @@ int main(int argc, char **argv) {
|
|||||||
cfg.rc_resize_allowed = 0;
|
cfg.rc_resize_allowed = 0;
|
||||||
|
|
||||||
// Use 1 thread as default.
|
// Use 1 thread as default.
|
||||||
cfg.g_threads = 1;
|
cfg.g_threads = (unsigned int)strtoul(argv[10], NULL, 0);
|
||||||
|
|
||||||
// Enable error resilient mode.
|
// Enable error resilient mode.
|
||||||
cfg.g_error_resilient = 1;
|
cfg.g_error_resilient = 1;
|
||||||
@@ -659,9 +654,7 @@ int main(int argc, char **argv) {
|
|||||||
|
|
||||||
cfg.temporal_layering_mode = VP9E_TEMPORAL_LAYERING_MODE_BYPASS;
|
cfg.temporal_layering_mode = VP9E_TEMPORAL_LAYERING_MODE_BYPASS;
|
||||||
|
|
||||||
set_temporal_layer_pattern(layering_mode,
|
set_temporal_layer_pattern(layering_mode, &cfg, layer_flags,
|
||||||
&cfg,
|
|
||||||
layer_flags,
|
|
||||||
&flag_periodicity);
|
&flag_periodicity);
|
||||||
|
|
||||||
set_rate_control_metrics(&rc, &cfg);
|
set_rate_control_metrics(&rc, &cfg);
|
||||||
@@ -688,8 +681,7 @@ int main(int argc, char **argv) {
|
|||||||
|
|
||||||
snprintf(file_name, sizeof(file_name), "%s_%d.ivf", argv[2], i);
|
snprintf(file_name, sizeof(file_name), "%s_%d.ivf", argv[2], i);
|
||||||
outfile[i] = vpx_video_writer_open(file_name, kContainerIVF, &info);
|
outfile[i] = vpx_video_writer_open(file_name, kContainerIVF, &info);
|
||||||
if (!outfile[i])
|
if (!outfile[i]) die("Failed to open %s for writing", file_name);
|
||||||
die("Failed to open %s for writing", file_name);
|
|
||||||
|
|
||||||
assert(outfile[i] != NULL);
|
assert(outfile[i] != NULL);
|
||||||
}
|
}
|
||||||
@@ -710,10 +702,14 @@ int main(int argc, char **argv) {
|
|||||||
vpx_codec_control(&codec, VP8E_SET_CPUUSED, -speed);
|
vpx_codec_control(&codec, VP8E_SET_CPUUSED, -speed);
|
||||||
vpx_codec_control(&codec, VP8E_SET_NOISE_SENSITIVITY, kDenoiserOff);
|
vpx_codec_control(&codec, VP8E_SET_NOISE_SENSITIVITY, kDenoiserOff);
|
||||||
vpx_codec_control(&codec, VP8E_SET_STATIC_THRESHOLD, 1);
|
vpx_codec_control(&codec, VP8E_SET_STATIC_THRESHOLD, 1);
|
||||||
|
vpx_codec_control(&codec, VP8E_SET_GF_CBR_BOOST_PCT, 0);
|
||||||
} else if (strncmp(encoder->name, "vp9", 3) == 0) {
|
} else if (strncmp(encoder->name, "vp9", 3) == 0) {
|
||||||
vpx_svc_extra_cfg_t svc_params;
|
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, VP8E_SET_CPUUSED, speed);
|
||||||
vpx_codec_control(&codec, VP9E_SET_AQ_MODE, 3);
|
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_FRAME_PERIODIC_BOOST, 0);
|
||||||
vpx_codec_control(&codec, VP9E_SET_NOISE_SENSITIVITY, kDenoiserOff);
|
vpx_codec_control(&codec, VP9E_SET_NOISE_SENSITIVITY, kDenoiserOff);
|
||||||
vpx_codec_control(&codec, VP8E_SET_STATIC_THRESHOLD, 1);
|
vpx_codec_control(&codec, VP8E_SET_STATIC_THRESHOLD, 1);
|
||||||
@@ -760,11 +756,9 @@ int main(int argc, char **argv) {
|
|||||||
layer_id.temporal_layer_id);
|
layer_id.temporal_layer_id);
|
||||||
}
|
}
|
||||||
flags = layer_flags[frame_cnt % flag_periodicity];
|
flags = layer_flags[frame_cnt % flag_periodicity];
|
||||||
if (layering_mode == 0)
|
if (layering_mode == 0) flags = 0;
|
||||||
flags = 0;
|
|
||||||
frame_avail = vpx_img_read(&raw, infile);
|
frame_avail = vpx_img_read(&raw, infile);
|
||||||
if (frame_avail)
|
if (frame_avail) ++rc.layer_input_frames[layer_id.temporal_layer_id];
|
||||||
++rc.layer_input_frames[layer_id.temporal_layer_id];
|
|
||||||
vpx_usec_timer_start(&timer);
|
vpx_usec_timer_start(&timer);
|
||||||
if (vpx_codec_encode(&codec, frame_avail ? &raw : NULL, pts, 1, flags,
|
if (vpx_codec_encode(&codec, frame_avail ? &raw : NULL, pts, 1, flags,
|
||||||
VPX_DL_REALTIME)) {
|
VPX_DL_REALTIME)) {
|
||||||
@@ -825,8 +819,7 @@ int main(int argc, char **argv) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
default:
|
default: break;
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
++frame_cnt;
|
++frame_cnt;
|
||||||
@@ -836,16 +829,13 @@ int main(int argc, char **argv) {
|
|||||||
printout_rate_control_summary(&rc, &cfg, frame_cnt);
|
printout_rate_control_summary(&rc, &cfg, frame_cnt);
|
||||||
printf("\n");
|
printf("\n");
|
||||||
printf("Frame cnt and encoding time/FPS stats for encoding: %d %f %f \n",
|
printf("Frame cnt and encoding time/FPS stats for encoding: %d %f %f \n",
|
||||||
frame_cnt,
|
frame_cnt, 1000 * (float)cx_time / (double)(frame_cnt * 1000000),
|
||||||
1000 * (float)cx_time / (double)(frame_cnt * 1000000),
|
|
||||||
1000000 * (double)frame_cnt / (double)cx_time);
|
1000000 * (double)frame_cnt / (double)cx_time);
|
||||||
|
|
||||||
if (vpx_codec_destroy(&codec))
|
if (vpx_codec_destroy(&codec)) die_codec(&codec, "Failed to destroy codec");
|
||||||
die_codec(&codec, "Failed to destroy codec");
|
|
||||||
|
|
||||||
// Try to rewrite the output file headers with the actual frame count.
|
// Try to rewrite the output file headers with the actual frame count.
|
||||||
for (i = 0; i < cfg.ts_number_layers; ++i)
|
for (i = 0; i < cfg.ts_number_layers; ++i) vpx_video_writer_close(outfile[i]);
|
||||||
vpx_video_writer_close(outfile[i]);
|
|
||||||
|
|
||||||
vpx_img_free(&raw);
|
vpx_img_free(&raw);
|
||||||
return EXIT_SUCCESS;
|
return EXIT_SUCCESS;
|
||||||
|
|||||||
12
ivfdec.c
12
ivfdec.c
@@ -23,7 +23,7 @@ static void fix_framerate(int *num, int *den) {
|
|||||||
// we can guess the framerate using only the timebase in this
|
// we can guess the framerate using only the timebase in this
|
||||||
// case. Other files would require reading ahead to guess the
|
// case. Other files would require reading ahead to guess the
|
||||||
// timebase, like we do for webm.
|
// timebase, like we do for webm.
|
||||||
if (*num < 1000) {
|
if (*den > 0 && *den < 1000000000 && *num > 0 && *num < 1000) {
|
||||||
// Correct for the factor of 2 applied to the timebase in the encoder.
|
// Correct for the factor of 2 applied to the timebase in the encoder.
|
||||||
if (*num & 1)
|
if (*num & 1)
|
||||||
*den *= 2;
|
*den *= 2;
|
||||||
@@ -46,7 +46,8 @@ int file_is_ivf(struct VpxInputContext *input_ctx) {
|
|||||||
is_ivf = 1;
|
is_ivf = 1;
|
||||||
|
|
||||||
if (mem_get_le16(raw_hdr + 4) != 0) {
|
if (mem_get_le16(raw_hdr + 4) != 0) {
|
||||||
fprintf(stderr, "Error: Unrecognized IVF version! This file may not"
|
fprintf(stderr,
|
||||||
|
"Error: Unrecognized IVF version! This file may not"
|
||||||
" decode properly.");
|
" decode properly.");
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -69,14 +70,13 @@ int file_is_ivf(struct VpxInputContext *input_ctx) {
|
|||||||
return is_ivf;
|
return is_ivf;
|
||||||
}
|
}
|
||||||
|
|
||||||
int ivf_read_frame(FILE *infile, uint8_t **buffer,
|
int ivf_read_frame(FILE *infile, uint8_t **buffer, size_t *bytes_read,
|
||||||
size_t *bytes_read, size_t *buffer_size) {
|
size_t *buffer_size) {
|
||||||
char raw_header[IVF_FRAME_HDR_SZ] = { 0 };
|
char raw_header[IVF_FRAME_HDR_SZ] = { 0 };
|
||||||
size_t frame_size = 0;
|
size_t frame_size = 0;
|
||||||
|
|
||||||
if (fread(raw_header, IVF_FRAME_HDR_SZ, 1, infile) != 1) {
|
if (fread(raw_header, IVF_FRAME_HDR_SZ, 1, infile) != 1) {
|
||||||
if (!feof(infile))
|
if (!feof(infile)) warn("Failed to read frame size\n");
|
||||||
warn("Failed to read frame size\n");
|
|
||||||
} else {
|
} else {
|
||||||
frame_size = mem_get_le32(raw_header);
|
frame_size = mem_get_le32(raw_header);
|
||||||
|
|
||||||
|
|||||||
4
ivfdec.h
4
ivfdec.h
@@ -18,8 +18,8 @@ extern "C" {
|
|||||||
|
|
||||||
int file_is_ivf(struct VpxInputContext *input);
|
int file_is_ivf(struct VpxInputContext *input);
|
||||||
|
|
||||||
int ivf_read_frame(FILE *infile, uint8_t **buffer,
|
int ivf_read_frame(FILE *infile, uint8_t **buffer, size_t *bytes_read,
|
||||||
size_t *bytes_read, size_t *buffer_size);
|
size_t *buffer_size);
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
} /* extern "C" */
|
} /* extern "C" */
|
||||||
|
|||||||
6
ivfenc.c
6
ivfenc.c
@@ -13,10 +13,8 @@
|
|||||||
#include "vpx/vpx_encoder.h"
|
#include "vpx/vpx_encoder.h"
|
||||||
#include "vpx_ports/mem_ops.h"
|
#include "vpx_ports/mem_ops.h"
|
||||||
|
|
||||||
void ivf_write_file_header(FILE *outfile,
|
void ivf_write_file_header(FILE *outfile, const struct vpx_codec_enc_cfg *cfg,
|
||||||
const struct vpx_codec_enc_cfg *cfg,
|
unsigned int fourcc, int frame_cnt) {
|
||||||
unsigned int fourcc,
|
|
||||||
int frame_cnt) {
|
|
||||||
char header[32];
|
char header[32];
|
||||||
|
|
||||||
header[0] = 'D';
|
header[0] = 'D';
|
||||||
|
|||||||
6
ivfenc.h
6
ivfenc.h
@@ -19,10 +19,8 @@ struct vpx_codec_cx_pkt;
|
|||||||
extern "C" {
|
extern "C" {
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
void ivf_write_file_header(FILE *outfile,
|
void ivf_write_file_header(FILE *outfile, const struct vpx_codec_enc_cfg *cfg,
|
||||||
const struct vpx_codec_enc_cfg *cfg,
|
uint32_t fourcc, int frame_cnt);
|
||||||
uint32_t fourcc,
|
|
||||||
int frame_cnt);
|
|
||||||
|
|
||||||
void ivf_write_frame_header(FILE *outfile, int64_t pts, size_t frame_size);
|
void ivf_write_frame_header(FILE *outfile, int64_t pts, size_t frame_size);
|
||||||
|
|
||||||
|
|||||||
62
libs.mk
62
libs.mk
@@ -12,7 +12,7 @@
|
|||||||
# ARM assembly files are written in RVCT-style. We use some make magic to
|
# ARM assembly files are written in RVCT-style. We use some make magic to
|
||||||
# filter those files to allow GCC compilation
|
# filter those files to allow GCC compilation
|
||||||
ifeq ($(ARCH_ARM),yes)
|
ifeq ($(ARCH_ARM),yes)
|
||||||
ASM:=$(if $(filter yes,$(CONFIG_GCC)$(CONFIG_MSVS)),.asm.s,.asm)
|
ASM:=$(if $(filter yes,$(CONFIG_GCC)$(CONFIG_MSVS)),.asm.S,.asm)
|
||||||
else
|
else
|
||||||
ASM:=.asm
|
ASM:=.asm
|
||||||
endif
|
endif
|
||||||
@@ -106,43 +106,6 @@ ifeq ($(CONFIG_VP9_DECODER),yes)
|
|||||||
CODEC_DOC_SECTIONS += vp9 vp9_decoder
|
CODEC_DOC_SECTIONS += vp9 vp9_decoder
|
||||||
endif
|
endif
|
||||||
|
|
||||||
VP9_PREFIX=vp9/
|
|
||||||
$(BUILD_PFX)$(VP9_PREFIX)%.c.o: CFLAGS += -Wextra
|
|
||||||
|
|
||||||
# VP10 make file
|
|
||||||
ifeq ($(CONFIG_VP10),yes)
|
|
||||||
VP10_PREFIX=vp10/
|
|
||||||
include $(SRC_PATH_BARE)/$(VP10_PREFIX)vp10_common.mk
|
|
||||||
endif
|
|
||||||
|
|
||||||
ifeq ($(CONFIG_VP10_ENCODER),yes)
|
|
||||||
VP10_PREFIX=vp10/
|
|
||||||
include $(SRC_PATH_BARE)/$(VP10_PREFIX)vp10cx.mk
|
|
||||||
CODEC_SRCS-yes += $(addprefix $(VP10_PREFIX),$(call enabled,VP10_CX_SRCS))
|
|
||||||
CODEC_EXPORTS-yes += $(addprefix $(VP10_PREFIX),$(VP10_CX_EXPORTS))
|
|
||||||
CODEC_SRCS-yes += $(VP10_PREFIX)vp10cx.mk vpx/vp8.h vpx/vp8cx.h
|
|
||||||
INSTALL-LIBS-yes += include/vpx/vp8.h include/vpx/vp8cx.h
|
|
||||||
INSTALL-LIBS-$(CONFIG_SPATIAL_SVC) += include/vpx/svc_context.h
|
|
||||||
INSTALL_MAPS += include/vpx/% $(SRC_PATH_BARE)/$(VP10_PREFIX)/%
|
|
||||||
CODEC_DOC_SRCS += vpx/vp8.h vpx/vp8cx.h
|
|
||||||
CODEC_DOC_SECTIONS += vp9 vp9_encoder
|
|
||||||
endif
|
|
||||||
|
|
||||||
ifeq ($(CONFIG_VP10_DECODER),yes)
|
|
||||||
VP10_PREFIX=vp10/
|
|
||||||
include $(SRC_PATH_BARE)/$(VP10_PREFIX)vp10dx.mk
|
|
||||||
CODEC_SRCS-yes += $(addprefix $(VP10_PREFIX),$(call enabled,VP10_DX_SRCS))
|
|
||||||
CODEC_EXPORTS-yes += $(addprefix $(VP10_PREFIX),$(VP10_DX_EXPORTS))
|
|
||||||
CODEC_SRCS-yes += $(VP10_PREFIX)vp10dx.mk vpx/vp8.h vpx/vp8dx.h
|
|
||||||
INSTALL-LIBS-yes += include/vpx/vp8.h include/vpx/vp8dx.h
|
|
||||||
INSTALL_MAPS += include/vpx/% $(SRC_PATH_BARE)/$(VP10_PREFIX)/%
|
|
||||||
CODEC_DOC_SRCS += vpx/vp8.h vpx/vp8dx.h
|
|
||||||
CODEC_DOC_SECTIONS += vp9 vp9_decoder
|
|
||||||
endif
|
|
||||||
|
|
||||||
VP10_PREFIX=vp10/
|
|
||||||
$(BUILD_PFX)$(VP10_PREFIX)%.c.o: CFLAGS += -Wextra
|
|
||||||
|
|
||||||
ifeq ($(CONFIG_ENCODERS),yes)
|
ifeq ($(CONFIG_ENCODERS),yes)
|
||||||
CODEC_DOC_SECTIONS += encoder
|
CODEC_DOC_SECTIONS += encoder
|
||||||
endif
|
endif
|
||||||
@@ -150,6 +113,12 @@ ifeq ($(CONFIG_DECODERS),yes)
|
|||||||
CODEC_DOC_SECTIONS += decoder
|
CODEC_DOC_SECTIONS += decoder
|
||||||
endif
|
endif
|
||||||
|
|
||||||
|
# Suppress -Wextra warnings in third party code.
|
||||||
|
$(BUILD_PFX)third_party/googletest/%.cc.o: CXXFLAGS += -Wno-missing-field-initializers
|
||||||
|
# Suppress -Wextra warnings in first party code pending investigation.
|
||||||
|
# https://bugs.chromium.org/p/webm/issues/detail?id=1069
|
||||||
|
$(BUILD_PFX)vp8/encoder/onyx_if.c.o: CFLAGS += -Wno-unknown-warning-option -Wno-clobbered
|
||||||
|
$(BUILD_PFX)vp8/decoder/onyxd_if.c.o: CFLAGS += -Wno-unknown-warning-option -Wno-clobbered
|
||||||
|
|
||||||
ifeq ($(CONFIG_MSVS),yes)
|
ifeq ($(CONFIG_MSVS),yes)
|
||||||
CODEC_LIB=$(if $(CONFIG_STATIC_MSVCRT),vpxmt,vpxmd)
|
CODEC_LIB=$(if $(CONFIG_STATIC_MSVCRT),vpxmt,vpxmd)
|
||||||
@@ -263,8 +232,8 @@ OBJS-yes += $(LIBVPX_OBJS)
|
|||||||
LIBS-$(if yes,$(CONFIG_STATIC)) += $(BUILD_PFX)libvpx.a $(BUILD_PFX)libvpx_g.a
|
LIBS-$(if yes,$(CONFIG_STATIC)) += $(BUILD_PFX)libvpx.a $(BUILD_PFX)libvpx_g.a
|
||||||
$(BUILD_PFX)libvpx_g.a: $(LIBVPX_OBJS)
|
$(BUILD_PFX)libvpx_g.a: $(LIBVPX_OBJS)
|
||||||
|
|
||||||
SO_VERSION_MAJOR := 3
|
SO_VERSION_MAJOR := 4
|
||||||
SO_VERSION_MINOR := 0
|
SO_VERSION_MINOR := 1
|
||||||
SO_VERSION_PATCH := 0
|
SO_VERSION_PATCH := 0
|
||||||
ifeq ($(filter darwin%,$(TGT_OS)),$(TGT_OS))
|
ifeq ($(filter darwin%,$(TGT_OS)),$(TGT_OS))
|
||||||
LIBVPX_SO := libvpx.$(SO_VERSION_MAJOR).dylib
|
LIBVPX_SO := libvpx.$(SO_VERSION_MAJOR).dylib
|
||||||
@@ -273,6 +242,12 @@ EXPORT_FILE := libvpx.syms
|
|||||||
LIBVPX_SO_SYMLINKS := $(addprefix $(LIBSUBDIR)/, \
|
LIBVPX_SO_SYMLINKS := $(addprefix $(LIBSUBDIR)/, \
|
||||||
libvpx.dylib )
|
libvpx.dylib )
|
||||||
else
|
else
|
||||||
|
ifeq ($(filter iphonesimulator%,$(TGT_OS)),$(TGT_OS))
|
||||||
|
LIBVPX_SO := libvpx.$(SO_VERSION_MAJOR).dylib
|
||||||
|
SHARED_LIB_SUF := .dylib
|
||||||
|
EXPORT_FILE := libvpx.syms
|
||||||
|
LIBVPX_SO_SYMLINKS := $(addprefix $(LIBSUBDIR)/, libvpx.dylib)
|
||||||
|
else
|
||||||
ifeq ($(filter os2%,$(TGT_OS)),$(TGT_OS))
|
ifeq ($(filter os2%,$(TGT_OS)),$(TGT_OS))
|
||||||
LIBVPX_SO := libvpx$(SO_VERSION_MAJOR).dll
|
LIBVPX_SO := libvpx$(SO_VERSION_MAJOR).dll
|
||||||
SHARED_LIB_SUF := _dll.a
|
SHARED_LIB_SUF := _dll.a
|
||||||
@@ -288,6 +263,7 @@ LIBVPX_SO_SYMLINKS := $(addprefix $(LIBSUBDIR)/, \
|
|||||||
libvpx.so.$(SO_VERSION_MAJOR).$(SO_VERSION_MINOR))
|
libvpx.so.$(SO_VERSION_MAJOR).$(SO_VERSION_MINOR))
|
||||||
endif
|
endif
|
||||||
endif
|
endif
|
||||||
|
endif
|
||||||
|
|
||||||
LIBS-$(CONFIG_SHARED) += $(BUILD_PFX)$(LIBVPX_SO)\
|
LIBS-$(CONFIG_SHARED) += $(BUILD_PFX)$(LIBVPX_SO)\
|
||||||
$(notdir $(LIBVPX_SO_SYMLINKS)) \
|
$(notdir $(LIBVPX_SO_SYMLINKS)) \
|
||||||
@@ -390,7 +366,7 @@ endif
|
|||||||
#
|
#
|
||||||
# Add assembler dependencies for configuration.
|
# Add assembler dependencies for configuration.
|
||||||
#
|
#
|
||||||
$(filter %.s.o,$(OBJS-yes)): $(BUILD_PFX)vpx_config.asm
|
$(filter %.S.o,$(OBJS-yes)): $(BUILD_PFX)vpx_config.asm
|
||||||
$(filter %$(ASM).o,$(OBJS-yes)): $(BUILD_PFX)vpx_config.asm
|
$(filter %$(ASM).o,$(OBJS-yes)): $(BUILD_PFX)vpx_config.asm
|
||||||
|
|
||||||
|
|
||||||
@@ -415,7 +391,7 @@ LIBVPX_TEST_SRCS=$(addprefix test/,$(call enabled,LIBVPX_TEST_SRCS))
|
|||||||
LIBVPX_TEST_BIN=./test_libvpx$(EXE_SFX)
|
LIBVPX_TEST_BIN=./test_libvpx$(EXE_SFX)
|
||||||
LIBVPX_TEST_DATA=$(addprefix $(LIBVPX_TEST_DATA_PATH)/,\
|
LIBVPX_TEST_DATA=$(addprefix $(LIBVPX_TEST_DATA_PATH)/,\
|
||||||
$(call enabled,LIBVPX_TEST_DATA))
|
$(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_BIN=./test_intra_pred_speed$(EXE_SFX)
|
||||||
TEST_INTRA_PRED_SPEED_SRCS=$(addprefix test/,$(call enabled,TEST_INTRA_PRED_SPEED_SRCS))
|
TEST_INTRA_PRED_SPEED_SRCS=$(addprefix test/,$(call enabled,TEST_INTRA_PRED_SPEED_SRCS))
|
||||||
@@ -429,7 +405,7 @@ CLEAN-OBJS += libvpx_test_srcs.txt
|
|||||||
$(LIBVPX_TEST_DATA): $(SRC_PATH_BARE)/test/test-data.sha1
|
$(LIBVPX_TEST_DATA): $(SRC_PATH_BARE)/test/test-data.sha1
|
||||||
@echo " [DOWNLOAD] $@"
|
@echo " [DOWNLOAD] $@"
|
||||||
$(qexec)trap 'rm -f $@' INT TERM &&\
|
$(qexec)trap 'rm -f $@' INT TERM &&\
|
||||||
curl -L -o $@ $(call libvpx_test_data_url,$(@F))
|
curl --retry 1 -L -o $@ $(call libvpx_test_data_url,$(@F))
|
||||||
|
|
||||||
testdata:: $(LIBVPX_TEST_DATA)
|
testdata:: $(LIBVPX_TEST_DATA)
|
||||||
$(qexec)[ -x "$$(which sha1sum)" ] && sha1sum=sha1sum;\
|
$(qexec)[ -x "$$(which sha1sum)" ] && sha1sum=sha1sum;\
|
||||||
|
|||||||
19
md5_utils.c
19
md5_utils.c
@@ -24,15 +24,13 @@
|
|||||||
|
|
||||||
#include "md5_utils.h"
|
#include "md5_utils.h"
|
||||||
|
|
||||||
static void
|
static void byteSwap(UWORD32 *buf, unsigned words) {
|
||||||
byteSwap(UWORD32 *buf, unsigned words) {
|
|
||||||
md5byte *p;
|
md5byte *p;
|
||||||
|
|
||||||
/* Only swap bytes for big endian machines */
|
/* Only swap bytes for big endian machines */
|
||||||
int i = 1;
|
int i = 1;
|
||||||
|
|
||||||
if (*(char *)&i == 1)
|
if (*(char *)&i == 1) return;
|
||||||
return;
|
|
||||||
|
|
||||||
p = (md5byte *)buf;
|
p = (md5byte *)buf;
|
||||||
|
|
||||||
@@ -47,8 +45,7 @@ byteSwap(UWORD32 *buf, unsigned words) {
|
|||||||
* Start MD5 accumulation. Set bit count to 0 and buffer to mysterious
|
* Start MD5 accumulation. Set bit count to 0 and buffer to mysterious
|
||||||
* initialization constants.
|
* initialization constants.
|
||||||
*/
|
*/
|
||||||
void
|
void MD5Init(struct MD5Context *ctx) {
|
||||||
MD5Init(struct MD5Context *ctx) {
|
|
||||||
ctx->buf[0] = 0x67452301;
|
ctx->buf[0] = 0x67452301;
|
||||||
ctx->buf[1] = 0xefcdab89;
|
ctx->buf[1] = 0xefcdab89;
|
||||||
ctx->buf[2] = 0x98badcfe;
|
ctx->buf[2] = 0x98badcfe;
|
||||||
@@ -62,8 +59,7 @@ MD5Init(struct MD5Context *ctx) {
|
|||||||
* Update context to reflect the concatenation of another buffer full
|
* Update context to reflect the concatenation of another buffer full
|
||||||
* of bytes.
|
* of bytes.
|
||||||
*/
|
*/
|
||||||
void
|
void MD5Update(struct MD5Context *ctx, md5byte const *buf, unsigned len) {
|
||||||
MD5Update(struct MD5Context *ctx, md5byte const *buf, unsigned len) {
|
|
||||||
UWORD32 t;
|
UWORD32 t;
|
||||||
|
|
||||||
/* Update byte count */
|
/* Update byte count */
|
||||||
@@ -104,8 +100,7 @@ MD5Update(struct MD5Context *ctx, md5byte const *buf, unsigned len) {
|
|||||||
* Final wrapup - pad to 64-byte boundary with the bit pattern
|
* Final wrapup - pad to 64-byte boundary with the bit pattern
|
||||||
* 1 0* (64-bit count of bits processed, MSB-first)
|
* 1 0* (64-bit count of bits processed, MSB-first)
|
||||||
*/
|
*/
|
||||||
void
|
void MD5Final(md5byte digest[16], struct MD5Context *ctx) {
|
||||||
MD5Final(md5byte digest[16], struct MD5Context *ctx) {
|
|
||||||
int count = ctx->bytes[0] & 0x3f; /* Number of bytes in ctx->in */
|
int count = ctx->bytes[0] & 0x3f; /* Number of bytes in ctx->in */
|
||||||
md5byte *p = (md5byte *)ctx->in + count;
|
md5byte *p = (md5byte *)ctx->in + count;
|
||||||
|
|
||||||
@@ -166,8 +161,8 @@ MD5Final(md5byte digest[16], struct MD5Context *ctx) {
|
|||||||
* reflect the addition of 16 longwords of new data. MD5Update blocks
|
* reflect the addition of 16 longwords of new data. MD5Update blocks
|
||||||
* the data and converts bytes into longwords for this routine.
|
* the data and converts bytes into longwords for this routine.
|
||||||
*/
|
*/
|
||||||
VPX_NO_UNSIGNED_OVERFLOW_CHECK void
|
VPX_NO_UNSIGNED_OVERFLOW_CHECK void MD5Transform(UWORD32 buf[4],
|
||||||
MD5Transform(UWORD32 buf[4], UWORD32 const in[16]) {
|
UWORD32 const in[16]) {
|
||||||
register UWORD32 a, b, c, d;
|
register UWORD32 a, b, c, d;
|
||||||
|
|
||||||
a = buf[0];
|
a = buf[0];
|
||||||
|
|||||||
57
rate_hist.c
57
rate_hist.c
@@ -45,8 +45,7 @@ struct rate_hist *init_rate_histogram(const vpx_codec_enc_cfg_t *cfg,
|
|||||||
hist->samples = cfg->rc_buf_sz * 5 / 4 * fps->num / fps->den / 1000;
|
hist->samples = cfg->rc_buf_sz * 5 / 4 * fps->num / fps->den / 1000;
|
||||||
|
|
||||||
// prevent division by zero
|
// prevent division by zero
|
||||||
if (hist->samples == 0)
|
if (hist->samples == 0) hist->samples = 1;
|
||||||
hist->samples = 1;
|
|
||||||
|
|
||||||
hist->frames = 0;
|
hist->frames = 0;
|
||||||
hist->total = 0;
|
hist->total = 0;
|
||||||
@@ -85,11 +84,9 @@ void update_rate_histogram(struct rate_hist *hist,
|
|||||||
hist->pts[idx] = now;
|
hist->pts[idx] = now;
|
||||||
hist->sz[idx] = (int)pkt->data.frame.sz;
|
hist->sz[idx] = (int)pkt->data.frame.sz;
|
||||||
|
|
||||||
if (now < cfg->rc_buf_initial_sz)
|
if (now < cfg->rc_buf_initial_sz) return;
|
||||||
return;
|
|
||||||
|
|
||||||
if (!cfg->rc_target_bitrate)
|
if (!cfg->rc_target_bitrate) return;
|
||||||
return;
|
|
||||||
|
|
||||||
then = now;
|
then = now;
|
||||||
|
|
||||||
@@ -98,20 +95,16 @@ void update_rate_histogram(struct rate_hist *hist,
|
|||||||
const int i_idx = (i - 1) % hist->samples;
|
const int i_idx = (i - 1) % hist->samples;
|
||||||
|
|
||||||
then = hist->pts[i_idx];
|
then = hist->pts[i_idx];
|
||||||
if (now - then > cfg->rc_buf_sz)
|
if (now - then > cfg->rc_buf_sz) break;
|
||||||
break;
|
|
||||||
sum_sz += hist->sz[i_idx];
|
sum_sz += hist->sz[i_idx];
|
||||||
}
|
}
|
||||||
|
|
||||||
if (now == then)
|
if (now == then) return;
|
||||||
return;
|
|
||||||
|
|
||||||
avg_bitrate = sum_sz * 8 * 1000 / (now - then);
|
avg_bitrate = sum_sz * 8 * 1000 / (now - then);
|
||||||
idx = (int)(avg_bitrate * (RATE_BINS / 2) / (cfg->rc_target_bitrate * 1000));
|
idx = (int)(avg_bitrate * (RATE_BINS / 2) / (cfg->rc_target_bitrate * 1000));
|
||||||
if (idx < 0)
|
if (idx < 0) idx = 0;
|
||||||
idx = 0;
|
if (idx > RATE_BINS - 1) idx = RATE_BINS - 1;
|
||||||
if (idx > RATE_BINS - 1)
|
|
||||||
idx = RATE_BINS - 1;
|
|
||||||
if (hist->bucket[idx].low > avg_bitrate)
|
if (hist->bucket[idx].low > avg_bitrate)
|
||||||
hist->bucket[idx].low = (int)avg_bitrate;
|
hist->bucket[idx].low = (int)avg_bitrate;
|
||||||
if (hist->bucket[idx].high < avg_bitrate)
|
if (hist->bucket[idx].high < avg_bitrate)
|
||||||
@@ -120,8 +113,8 @@ void update_rate_histogram(struct rate_hist *hist,
|
|||||||
hist->total++;
|
hist->total++;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int merge_hist_buckets(struct hist_bucket *bucket,
|
static int merge_hist_buckets(struct hist_bucket *bucket, int max_buckets,
|
||||||
int max_buckets, int *num_buckets) {
|
int *num_buckets) {
|
||||||
int small_bucket = 0, merge_bucket = INT_MAX, big_bucket = 0;
|
int small_bucket = 0, merge_bucket = INT_MAX, big_bucket = 0;
|
||||||
int buckets = *num_buckets;
|
int buckets = *num_buckets;
|
||||||
int i;
|
int i;
|
||||||
@@ -129,10 +122,8 @@ static int merge_hist_buckets(struct hist_bucket *bucket,
|
|||||||
/* Find the extrema for this list of buckets */
|
/* Find the extrema for this list of buckets */
|
||||||
big_bucket = small_bucket = 0;
|
big_bucket = small_bucket = 0;
|
||||||
for (i = 0; i < buckets; i++) {
|
for (i = 0; i < buckets; i++) {
|
||||||
if (bucket[i].count < bucket[small_bucket].count)
|
if (bucket[i].count < bucket[small_bucket].count) small_bucket = i;
|
||||||
small_bucket = i;
|
if (bucket[i].count > bucket[big_bucket].count) big_bucket = i;
|
||||||
if (bucket[i].count > bucket[big_bucket].count)
|
|
||||||
big_bucket = i;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* If we have too many buckets, merge the smallest with an adjacent
|
/* If we have too many buckets, merge the smallest with an adjacent
|
||||||
@@ -174,13 +165,10 @@ static int merge_hist_buckets(struct hist_bucket *bucket,
|
|||||||
*/
|
*/
|
||||||
big_bucket = small_bucket = 0;
|
big_bucket = small_bucket = 0;
|
||||||
for (i = 0; i < buckets; i++) {
|
for (i = 0; i < buckets; i++) {
|
||||||
if (i > merge_bucket)
|
if (i > merge_bucket) bucket[i] = bucket[i + 1];
|
||||||
bucket[i] = bucket[i + 1];
|
|
||||||
|
|
||||||
if (bucket[i].count < bucket[small_bucket].count)
|
if (bucket[i].count < bucket[small_bucket].count) small_bucket = i;
|
||||||
small_bucket = i;
|
if (bucket[i].count > bucket[big_bucket].count) big_bucket = i;
|
||||||
if (bucket[i].count > bucket[big_bucket].count)
|
|
||||||
big_bucket = i;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -188,8 +176,8 @@ static int merge_hist_buckets(struct hist_bucket *bucket,
|
|||||||
return bucket[big_bucket].count;
|
return bucket[big_bucket].count;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void show_histogram(const struct hist_bucket *bucket,
|
static void show_histogram(const struct hist_bucket *bucket, int buckets,
|
||||||
int buckets, int total, int scale) {
|
int total, int scale) {
|
||||||
const char *pat1, *pat2;
|
const char *pat1, *pat2;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
@@ -232,8 +220,7 @@ static void show_histogram(const struct hist_bucket *bucket,
|
|||||||
|
|
||||||
pct = (float)(100.0 * bucket[i].count / total);
|
pct = (float)(100.0 * bucket[i].count / total);
|
||||||
len = HIST_BAR_MAX * bucket[i].count / scale;
|
len = HIST_BAR_MAX * bucket[i].count / scale;
|
||||||
if (len < 1)
|
if (len < 1) len = 1;
|
||||||
len = 1;
|
|
||||||
assert(len <= HIST_BAR_MAX);
|
assert(len <= HIST_BAR_MAX);
|
||||||
|
|
||||||
if (bucket[i].low == bucket[i].high)
|
if (bucket[i].low == bucket[i].high)
|
||||||
@@ -241,8 +228,7 @@ static void show_histogram(const struct hist_bucket *bucket,
|
|||||||
else
|
else
|
||||||
fprintf(stderr, pat2, bucket[i].low, bucket[i].high);
|
fprintf(stderr, pat2, bucket[i].low, bucket[i].high);
|
||||||
|
|
||||||
for (j = 0; j < HIST_BAR_MAX; j++)
|
for (j = 0; j < HIST_BAR_MAX; j++) fprintf(stderr, j < len ? "=" : " ");
|
||||||
fprintf(stderr, j < len ? "=" : " ");
|
|
||||||
fprintf(stderr, "\t%5d (%6.2f%%)\n", bucket[i].count, pct);
|
fprintf(stderr, "\t%5d (%6.2f%%)\n", bucket[i].count, pct);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -268,14 +254,13 @@ void show_q_histogram(const int counts[64], int max_buckets) {
|
|||||||
show_histogram(bucket, buckets, total, scale);
|
show_histogram(bucket, buckets, total, scale);
|
||||||
}
|
}
|
||||||
|
|
||||||
void show_rate_histogram(struct rate_hist *hist,
|
void show_rate_histogram(struct rate_hist *hist, const vpx_codec_enc_cfg_t *cfg,
|
||||||
const vpx_codec_enc_cfg_t *cfg, int max_buckets) {
|
int max_buckets) {
|
||||||
int i, scale;
|
int i, scale;
|
||||||
int buckets = 0;
|
int buckets = 0;
|
||||||
|
|
||||||
for (i = 0; i < RATE_BINS; i++) {
|
for (i = 0; i < RATE_BINS; i++) {
|
||||||
if (hist->bucket[i].low == INT_MAX)
|
if (hist->bucket[i].low == INT_MAX) continue;
|
||||||
continue;
|
|
||||||
hist->bucket[buckets++] = hist->bucket[i];
|
hist->bucket[buckets++] = hist->bucket[i];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -23,9 +23,7 @@ class ACMRandom {
|
|||||||
|
|
||||||
explicit ACMRandom(int seed) : random_(seed) {}
|
explicit ACMRandom(int seed) : random_(seed) {}
|
||||||
|
|
||||||
void Reset(int seed) {
|
void Reset(int seed) { random_.Reseed(seed); }
|
||||||
random_.Reseed(seed);
|
|
||||||
}
|
|
||||||
uint16_t Rand16(void) {
|
uint16_t Rand16(void) {
|
||||||
const uint32_t value =
|
const uint32_t value =
|
||||||
random_.Generate(testing::internal::Random::kMaxRange);
|
random_.Generate(testing::internal::Random::kMaxRange);
|
||||||
@@ -35,7 +33,7 @@ class ACMRandom {
|
|||||||
int16_t Rand9Signed(void) {
|
int16_t Rand9Signed(void) {
|
||||||
// Use 9 bits: values between 255 (0x0FF) and -256 (0x100).
|
// Use 9 bits: values between 255 (0x0FF) and -256 (0x100).
|
||||||
const uint32_t value = random_.Generate(512);
|
const uint32_t value = random_.Generate(512);
|
||||||
return static_cast<int16_t>(value - 256);
|
return static_cast<int16_t>(value) - 256;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint8_t Rand8(void) {
|
uint8_t Rand8(void) {
|
||||||
@@ -52,17 +50,11 @@ class ACMRandom {
|
|||||||
return r < 128 ? r << 4 : r >> 4;
|
return r < 128 ? r << 4 : r >> 4;
|
||||||
}
|
}
|
||||||
|
|
||||||
int PseudoUniform(int range) {
|
int PseudoUniform(int range) { return random_.Generate(range); }
|
||||||
return random_.Generate(range);
|
|
||||||
}
|
|
||||||
|
|
||||||
int operator()(int n) {
|
int operator()(int n) { return PseudoUniform(n); }
|
||||||
return PseudoUniform(n);
|
|
||||||
}
|
|
||||||
|
|
||||||
static int DeterministicSeed(void) {
|
static int DeterministicSeed(void) { return 0xbaba; }
|
||||||
return 0xbaba;
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
testing::internal::Random random_;
|
testing::internal::Random random_;
|
||||||
|
|||||||
@@ -17,8 +17,8 @@
|
|||||||
namespace {
|
namespace {
|
||||||
|
|
||||||
// Check if any pixel in a 16x16 macroblock varies between frames.
|
// Check if any pixel in a 16x16 macroblock varies between frames.
|
||||||
int CheckMb(const vpx_image_t ¤t, const vpx_image_t &previous,
|
int CheckMb(const vpx_image_t ¤t, const vpx_image_t &previous, int mb_r,
|
||||||
int mb_r, int mb_c) {
|
int mb_c) {
|
||||||
for (int plane = 0; plane < 3; plane++) {
|
for (int plane = 0; plane < 3; plane++) {
|
||||||
int r = 16 * mb_r;
|
int r = 16 * mb_r;
|
||||||
int c0 = 16 * mb_c;
|
int c0 = 16 * mb_c;
|
||||||
@@ -37,11 +37,12 @@ int CheckMb(const vpx_image_t ¤t, const vpx_image_t &previous,
|
|||||||
for (; r < r_top; ++r) {
|
for (; r < r_top; ++r) {
|
||||||
for (int c = c0; c < c_top; ++c) {
|
for (int c = c0; c < c_top; ++c) {
|
||||||
if (current.planes[plane][current.stride[plane] * r + c] !=
|
if (current.planes[plane][current.stride[plane] * r + c] !=
|
||||||
previous.planes[plane][previous.stride[plane] * r + c])
|
previous.planes[plane][previous.stride[plane] * r + c]) {
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -39,6 +39,7 @@ class ActiveMapTest
|
|||||||
encoder->Control(VP8E_SET_CPUUSED, cpu_used_);
|
encoder->Control(VP8E_SET_CPUUSED, cpu_used_);
|
||||||
} else if (video->frame() == 3) {
|
} else if (video->frame() == 3) {
|
||||||
vpx_active_map_t map = vpx_active_map_t();
|
vpx_active_map_t map = vpx_active_map_t();
|
||||||
|
/* clang-format off */
|
||||||
uint8_t active_map[9 * 13] = {
|
uint8_t active_map[9 * 13] = {
|
||||||
1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 0, 0, 0,
|
1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 0, 0, 0,
|
||||||
1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 0, 0, 0,
|
1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 0, 0, 0,
|
||||||
@@ -50,6 +51,7 @@ class ActiveMapTest
|
|||||||
0, 0, 0, 0, 0, 0, 1, 1, 0, 1, 0, 1, 1,
|
0, 0, 0, 0, 0, 0, 1, 1, 0, 1, 0, 1, 1,
|
||||||
1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 0,
|
1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 0,
|
||||||
};
|
};
|
||||||
|
/* clang-format on */
|
||||||
map.cols = (kWidth + 15) / 16;
|
map.cols = (kWidth + 15) / 16;
|
||||||
map.rows = (kHeight + 15) / 16;
|
map.rows = (kHeight + 15) / 16;
|
||||||
ASSERT_EQ(map.cols, 13u);
|
ASSERT_EQ(map.cols, 13u);
|
||||||
@@ -77,8 +79,8 @@ TEST_P(ActiveMapTest, Test) {
|
|||||||
cfg_.rc_end_usage = VPX_CBR;
|
cfg_.rc_end_usage = VPX_CBR;
|
||||||
cfg_.kf_max_dist = 90000;
|
cfg_.kf_max_dist = 90000;
|
||||||
|
|
||||||
::libvpx_test::I420VideoSource video("hantro_odd.yuv", kWidth, kHeight, 30,
|
::libvpx_test::I420VideoSource video("hantro_odd.yuv", kWidth, kHeight, 30, 1,
|
||||||
1, 0, 20);
|
0, 20);
|
||||||
|
|
||||||
ASSERT_NO_FATAL_FAILURE(RunLoop(&video));
|
ASSERT_NO_FATAL_FAILURE(RunLoop(&video));
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -13,22 +13,21 @@
|
|||||||
#include "third_party/googletest/src/include/gtest/gtest.h"
|
#include "third_party/googletest/src/include/gtest/gtest.h"
|
||||||
#include "./vpx_dsp_rtcd.h"
|
#include "./vpx_dsp_rtcd.h"
|
||||||
#include "vpx/vpx_integer.h"
|
#include "vpx/vpx_integer.h"
|
||||||
|
#include "vpx_dsp/postproc.h"
|
||||||
#include "vpx_mem/vpx_mem.h"
|
#include "vpx_mem/vpx_mem.h"
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
|
|
||||||
// TODO(jimbankoski): make width and height integers not unsigned.
|
static const int kNoiseSize = 3072;
|
||||||
typedef void (*AddNoiseFunc)(unsigned char *start, char *noise,
|
|
||||||
char blackclamp[16], char whiteclamp[16],
|
|
||||||
char bothclamp[16], unsigned int width,
|
|
||||||
unsigned int height, int pitch);
|
|
||||||
|
|
||||||
class AddNoiseTest
|
// TODO(jimbankoski): make width and height integers not unsigned.
|
||||||
: public ::testing::TestWithParam<AddNoiseFunc> {
|
typedef void (*AddNoiseFunc)(uint8_t *start, const int8_t *noise,
|
||||||
|
int blackclamp, int whiteclamp, int width,
|
||||||
|
int height, int pitch);
|
||||||
|
|
||||||
|
class AddNoiseTest : public ::testing::TestWithParam<AddNoiseFunc> {
|
||||||
public:
|
public:
|
||||||
virtual void TearDown() {
|
virtual void TearDown() { libvpx_test::ClearSystemState(); }
|
||||||
libvpx_test::ClearSystemState();
|
|
||||||
}
|
|
||||||
virtual ~AddNoiseTest() {}
|
virtual ~AddNoiseTest() {}
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -40,71 +39,19 @@ double stddev6(char a, char b, char c, char d, char e, char f) {
|
|||||||
return sqrt(v);
|
return sqrt(v);
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO(jimbankoski): The following 2 functions are duplicated in each codec.
|
|
||||||
// For now the vp9 one has been copied into the test as is. We should normalize
|
|
||||||
// these in vpx_dsp and not have 3 copies of these unless there is different
|
|
||||||
// noise we add for each codec.
|
|
||||||
|
|
||||||
double gaussian(double sigma, double mu, double x) {
|
|
||||||
return 1 / (sigma * sqrt(2.0 * 3.14159265)) *
|
|
||||||
(exp(-(x - mu) * (x - mu) / (2 * sigma * sigma)));
|
|
||||||
}
|
|
||||||
|
|
||||||
int setup_noise(int size_noise, char *noise) {
|
|
||||||
char char_dist[300];
|
|
||||||
const int ai = 4;
|
|
||||||
const int qi = 24;
|
|
||||||
const double sigma = ai + .5 + .6 * (63 - qi) / 63.0;
|
|
||||||
|
|
||||||
/* set up a lookup table of 256 entries that matches
|
|
||||||
* a gaussian distribution with sigma determined by q.
|
|
||||||
*/
|
|
||||||
int next = 0;
|
|
||||||
|
|
||||||
for (int i = -32; i < 32; i++) {
|
|
||||||
int a_i = (int) (0.5 + 256 * gaussian(sigma, 0, i));
|
|
||||||
|
|
||||||
if (a_i) {
|
|
||||||
for (int j = 0; j < a_i; j++) {
|
|
||||||
char_dist[next + j] = (char)(i);
|
|
||||||
}
|
|
||||||
|
|
||||||
next = next + a_i;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
for (; next < 256; next++)
|
|
||||||
char_dist[next] = 0;
|
|
||||||
|
|
||||||
for (int i = 0; i < size_noise; i++) {
|
|
||||||
noise[i] = char_dist[rand() & 0xff]; // NOLINT
|
|
||||||
}
|
|
||||||
|
|
||||||
// Returns the most negative value in distribution.
|
|
||||||
return char_dist[0];
|
|
||||||
}
|
|
||||||
|
|
||||||
TEST_P(AddNoiseTest, CheckNoiseAdded) {
|
TEST_P(AddNoiseTest, CheckNoiseAdded) {
|
||||||
DECLARE_ALIGNED(16, char, blackclamp[16]);
|
|
||||||
DECLARE_ALIGNED(16, char, whiteclamp[16]);
|
|
||||||
DECLARE_ALIGNED(16, char, bothclamp[16]);
|
|
||||||
const int width = 64;
|
const int width = 64;
|
||||||
const int height = 64;
|
const int height = 64;
|
||||||
const int image_size = width * height;
|
const int image_size = width * height;
|
||||||
char noise[3072];
|
int8_t noise[kNoiseSize];
|
||||||
|
const int clamp = vpx_setup_noise(4.4, noise, kNoiseSize);
|
||||||
|
uint8_t *const s =
|
||||||
|
reinterpret_cast<uint8_t *>(vpx_calloc(image_size, sizeof(*s)));
|
||||||
|
ASSERT_TRUE(s != NULL);
|
||||||
|
memset(s, 99, image_size * sizeof(*s));
|
||||||
|
|
||||||
const int clamp = setup_noise(3072, noise);
|
ASM_REGISTER_STATE_CHECK(
|
||||||
for (int i = 0; i < 16; i++) {
|
GetParam()(s, noise, clamp, clamp, width, height, width));
|
||||||
blackclamp[i] = -clamp;
|
|
||||||
whiteclamp[i] = -clamp;
|
|
||||||
bothclamp[i] = -2 * clamp;
|
|
||||||
}
|
|
||||||
|
|
||||||
uint8_t *const s = reinterpret_cast<uint8_t *>(vpx_calloc(image_size, 1));
|
|
||||||
memset(s, 99, image_size);
|
|
||||||
|
|
||||||
ASM_REGISTER_STATE_CHECK(GetParam()(s, noise, blackclamp, whiteclamp,
|
|
||||||
bothclamp, width, height, width));
|
|
||||||
|
|
||||||
// Check to make sure we don't end up having either the same or no added
|
// Check to make sure we don't end up having either the same or no added
|
||||||
// noise either vertically or horizontally.
|
// noise either vertically or horizontally.
|
||||||
@@ -122,60 +69,52 @@ TEST_P(AddNoiseTest, CheckNoiseAdded) {
|
|||||||
// Initialize pixels in the image to 255 and check for roll over.
|
// Initialize pixels in the image to 255 and check for roll over.
|
||||||
memset(s, 255, image_size);
|
memset(s, 255, image_size);
|
||||||
|
|
||||||
ASM_REGISTER_STATE_CHECK(GetParam()(s, noise, blackclamp, whiteclamp,
|
ASM_REGISTER_STATE_CHECK(
|
||||||
bothclamp, width, height, width));
|
GetParam()(s, noise, clamp, clamp, width, height, width));
|
||||||
|
|
||||||
// Check to make sure don't roll over.
|
// Check to make sure don't roll over.
|
||||||
for (int i = 0; i < image_size; ++i) {
|
for (int i = 0; i < image_size; ++i) {
|
||||||
EXPECT_GT((int)s[i], 10) << "i = " << i;
|
EXPECT_GT(static_cast<int>(s[i]), clamp) << "i = " << i;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Initialize pixels in the image to 0 and check for roll under.
|
// Initialize pixels in the image to 0 and check for roll under.
|
||||||
memset(s, 0, image_size);
|
memset(s, 0, image_size);
|
||||||
|
|
||||||
ASM_REGISTER_STATE_CHECK(GetParam()(s, noise, blackclamp, whiteclamp,
|
ASM_REGISTER_STATE_CHECK(
|
||||||
bothclamp, width, height, width));
|
GetParam()(s, noise, clamp, clamp, width, height, width));
|
||||||
|
|
||||||
// Check to make sure don't roll under.
|
// Check to make sure don't roll under.
|
||||||
for (int i = 0; i < image_size; ++i) {
|
for (int i = 0; i < image_size; ++i) {
|
||||||
EXPECT_LT((int)s[i], 245) << "i = " << i;
|
EXPECT_LT(static_cast<int>(s[i]), 255 - clamp) << "i = " << i;
|
||||||
}
|
}
|
||||||
|
|
||||||
vpx_free(s);
|
vpx_free(s);
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_P(AddNoiseTest, CheckCvsAssembly) {
|
TEST_P(AddNoiseTest, CheckCvsAssembly) {
|
||||||
DECLARE_ALIGNED(16, char, blackclamp[16]);
|
|
||||||
DECLARE_ALIGNED(16, char, whiteclamp[16]);
|
|
||||||
DECLARE_ALIGNED(16, char, bothclamp[16]);
|
|
||||||
const int width = 64;
|
const int width = 64;
|
||||||
const int height = 64;
|
const int height = 64;
|
||||||
const int image_size = width * height;
|
const int image_size = width * height;
|
||||||
char noise[3072];
|
int8_t noise[kNoiseSize];
|
||||||
|
const int clamp = vpx_setup_noise(4.4, noise, kNoiseSize);
|
||||||
const int clamp = setup_noise(3072, noise);
|
|
||||||
for (int i = 0; i < 16; i++) {
|
|
||||||
blackclamp[i] = -clamp;
|
|
||||||
whiteclamp[i] = -clamp;
|
|
||||||
bothclamp[i] = -2 * clamp;
|
|
||||||
}
|
|
||||||
|
|
||||||
uint8_t *const s = reinterpret_cast<uint8_t *>(vpx_calloc(image_size, 1));
|
uint8_t *const s = reinterpret_cast<uint8_t *>(vpx_calloc(image_size, 1));
|
||||||
uint8_t *const d = reinterpret_cast<uint8_t *>(vpx_calloc(image_size, 1));
|
uint8_t *const d = reinterpret_cast<uint8_t *>(vpx_calloc(image_size, 1));
|
||||||
|
ASSERT_TRUE(s != NULL);
|
||||||
|
ASSERT_TRUE(d != NULL);
|
||||||
|
|
||||||
memset(s, 99, image_size);
|
memset(s, 99, image_size);
|
||||||
memset(d, 99, image_size);
|
memset(d, 99, image_size);
|
||||||
|
|
||||||
srand(0);
|
srand(0);
|
||||||
ASM_REGISTER_STATE_CHECK(GetParam()(s, noise, blackclamp, whiteclamp,
|
ASM_REGISTER_STATE_CHECK(
|
||||||
bothclamp, width, height, width));
|
GetParam()(s, noise, clamp, clamp, width, height, width));
|
||||||
srand(0);
|
srand(0);
|
||||||
ASM_REGISTER_STATE_CHECK(vpx_plane_add_noise_c(d, noise, blackclamp,
|
ASM_REGISTER_STATE_CHECK(
|
||||||
whiteclamp, bothclamp,
|
vpx_plane_add_noise_c(d, noise, clamp, clamp, width, height, width));
|
||||||
width, height, width));
|
|
||||||
|
|
||||||
for (int i = 0; i < image_size; ++i) {
|
for (int i = 0; i < image_size; ++i) {
|
||||||
EXPECT_EQ((int)s[i], (int)d[i]) << "i = " << i;
|
EXPECT_EQ(static_cast<int>(s[i]), static_cast<int>(d[i])) << "i = " << i;
|
||||||
}
|
}
|
||||||
|
|
||||||
vpx_free(d);
|
vpx_free(d);
|
||||||
@@ -185,11 +124,6 @@ TEST_P(AddNoiseTest, CheckCvsAssembly) {
|
|||||||
INSTANTIATE_TEST_CASE_P(C, AddNoiseTest,
|
INSTANTIATE_TEST_CASE_P(C, AddNoiseTest,
|
||||||
::testing::Values(vpx_plane_add_noise_c));
|
::testing::Values(vpx_plane_add_noise_c));
|
||||||
|
|
||||||
#if HAVE_MMX
|
|
||||||
INSTANTIATE_TEST_CASE_P(MMX, AddNoiseTest,
|
|
||||||
::testing::Values(vpx_plane_add_noise_mmx));
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if HAVE_SSE2
|
#if HAVE_SSE2
|
||||||
INSTANTIATE_TEST_CASE_P(SSE2, AddNoiseTest,
|
INSTANTIATE_TEST_CASE_P(SSE2, AddNoiseTest,
|
||||||
::testing::Values(vpx_plane_add_noise_sse2));
|
::testing::Values(vpx_plane_add_noise_sse2));
|
||||||
|
|||||||
157
test/alt_ref_aq_segment_test.cc
Normal file
157
test/alt_ref_aq_segment_test.cc
Normal file
@@ -0,0 +1,157 @@
|
|||||||
|
/*
|
||||||
|
* 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 "third_party/googletest/src/include/gtest/gtest.h"
|
||||||
|
#include "test/codec_factory.h"
|
||||||
|
#include "test/encode_test_driver.h"
|
||||||
|
#include "test/i420_video_source.h"
|
||||||
|
#include "test/util.h"
|
||||||
|
|
||||||
|
namespace {
|
||||||
|
|
||||||
|
class AltRefAqSegmentTest
|
||||||
|
: public ::libvpx_test::EncoderTest,
|
||||||
|
public ::libvpx_test::CodecTestWith2Params<libvpx_test::TestMode, int> {
|
||||||
|
protected:
|
||||||
|
AltRefAqSegmentTest() : EncoderTest(GET_PARAM(0)) {}
|
||||||
|
virtual ~AltRefAqSegmentTest() {}
|
||||||
|
|
||||||
|
virtual void SetUp() {
|
||||||
|
InitializeConfig();
|
||||||
|
SetMode(GET_PARAM(1));
|
||||||
|
set_cpu_used_ = GET_PARAM(2);
|
||||||
|
aq_mode_ = 0;
|
||||||
|
alt_ref_aq_mode_ = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual void PreEncodeFrameHook(::libvpx_test::VideoSource *video,
|
||||||
|
::libvpx_test::Encoder *encoder) {
|
||||||
|
if (video->frame() == 1) {
|
||||||
|
encoder->Control(VP8E_SET_CPUUSED, set_cpu_used_);
|
||||||
|
encoder->Control(VP9E_SET_ALT_REF_AQ, alt_ref_aq_mode_);
|
||||||
|
encoder->Control(VP9E_SET_AQ_MODE, aq_mode_);
|
||||||
|
encoder->Control(VP8E_SET_MAX_INTRA_BITRATE_PCT, 100);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int set_cpu_used_;
|
||||||
|
int aq_mode_;
|
||||||
|
int alt_ref_aq_mode_;
|
||||||
|
};
|
||||||
|
|
||||||
|
// Validate that this ALT_REF_AQ/AQ segmentation mode
|
||||||
|
// (ALT_REF_AQ=0, AQ=0/no_aq)
|
||||||
|
// encodes and decodes without a mismatch.
|
||||||
|
TEST_P(AltRefAqSegmentTest, TestNoMisMatchAltRefAQ0) {
|
||||||
|
cfg_.rc_min_quantizer = 8;
|
||||||
|
cfg_.rc_max_quantizer = 56;
|
||||||
|
cfg_.rc_end_usage = VPX_VBR;
|
||||||
|
cfg_.rc_buf_initial_sz = 500;
|
||||||
|
cfg_.rc_buf_optimal_sz = 500;
|
||||||
|
cfg_.rc_buf_sz = 1000;
|
||||||
|
cfg_.rc_target_bitrate = 300;
|
||||||
|
|
||||||
|
aq_mode_ = 0;
|
||||||
|
alt_ref_aq_mode_ = 1;
|
||||||
|
|
||||||
|
::libvpx_test::I420VideoSource video("hantro_collage_w352h288.yuv", 352, 288,
|
||||||
|
30, 1, 0, 100);
|
||||||
|
|
||||||
|
ASSERT_NO_FATAL_FAILURE(RunLoop(&video));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Validate that this ALT_REF_AQ/AQ segmentation mode
|
||||||
|
// (ALT_REF_AQ=0, AQ=1/variance_aq)
|
||||||
|
// encodes and decodes without a mismatch.
|
||||||
|
TEST_P(AltRefAqSegmentTest, TestNoMisMatchAltRefAQ1) {
|
||||||
|
cfg_.rc_min_quantizer = 8;
|
||||||
|
cfg_.rc_max_quantizer = 56;
|
||||||
|
cfg_.rc_end_usage = VPX_VBR;
|
||||||
|
cfg_.rc_buf_initial_sz = 500;
|
||||||
|
cfg_.rc_buf_optimal_sz = 500;
|
||||||
|
cfg_.rc_buf_sz = 1000;
|
||||||
|
cfg_.rc_target_bitrate = 300;
|
||||||
|
|
||||||
|
aq_mode_ = 1;
|
||||||
|
alt_ref_aq_mode_ = 1;
|
||||||
|
|
||||||
|
::libvpx_test::I420VideoSource video("hantro_collage_w352h288.yuv", 352, 288,
|
||||||
|
30, 1, 0, 100);
|
||||||
|
|
||||||
|
ASSERT_NO_FATAL_FAILURE(RunLoop(&video));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Validate that this ALT_REF_AQ/AQ segmentation mode
|
||||||
|
// (ALT_REF_AQ=0, AQ=2/complexity_aq)
|
||||||
|
// encodes and decodes without a mismatch.
|
||||||
|
TEST_P(AltRefAqSegmentTest, TestNoMisMatchAltRefAQ2) {
|
||||||
|
cfg_.rc_min_quantizer = 8;
|
||||||
|
cfg_.rc_max_quantizer = 56;
|
||||||
|
cfg_.rc_end_usage = VPX_VBR;
|
||||||
|
cfg_.rc_buf_initial_sz = 500;
|
||||||
|
cfg_.rc_buf_optimal_sz = 500;
|
||||||
|
cfg_.rc_buf_sz = 1000;
|
||||||
|
cfg_.rc_target_bitrate = 300;
|
||||||
|
|
||||||
|
aq_mode_ = 2;
|
||||||
|
alt_ref_aq_mode_ = 1;
|
||||||
|
|
||||||
|
::libvpx_test::I420VideoSource video("hantro_collage_w352h288.yuv", 352, 288,
|
||||||
|
30, 1, 0, 100);
|
||||||
|
|
||||||
|
ASSERT_NO_FATAL_FAILURE(RunLoop(&video));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Validate that this ALT_REF_AQ/AQ segmentation mode
|
||||||
|
// (ALT_REF_AQ=0, AQ=3/cyclicrefresh_aq)
|
||||||
|
// encodes and decodes without a mismatch.
|
||||||
|
TEST_P(AltRefAqSegmentTest, TestNoMisMatchAltRefAQ3) {
|
||||||
|
cfg_.rc_min_quantizer = 8;
|
||||||
|
cfg_.rc_max_quantizer = 56;
|
||||||
|
cfg_.rc_end_usage = VPX_VBR;
|
||||||
|
cfg_.rc_buf_initial_sz = 500;
|
||||||
|
cfg_.rc_buf_optimal_sz = 500;
|
||||||
|
cfg_.rc_buf_sz = 1000;
|
||||||
|
cfg_.rc_target_bitrate = 300;
|
||||||
|
|
||||||
|
aq_mode_ = 3;
|
||||||
|
alt_ref_aq_mode_ = 1;
|
||||||
|
|
||||||
|
::libvpx_test::I420VideoSource video("hantro_collage_w352h288.yuv", 352, 288,
|
||||||
|
30, 1, 0, 100);
|
||||||
|
|
||||||
|
ASSERT_NO_FATAL_FAILURE(RunLoop(&video));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Validate that this ALT_REF_AQ/AQ segmentation mode
|
||||||
|
// (ALT_REF_AQ=0, AQ=4/equator360_aq)
|
||||||
|
// encodes and decodes without a mismatch.
|
||||||
|
TEST_P(AltRefAqSegmentTest, TestNoMisMatchAltRefAQ4) {
|
||||||
|
cfg_.rc_min_quantizer = 8;
|
||||||
|
cfg_.rc_max_quantizer = 56;
|
||||||
|
cfg_.rc_end_usage = VPX_VBR;
|
||||||
|
cfg_.rc_buf_initial_sz = 500;
|
||||||
|
cfg_.rc_buf_optimal_sz = 500;
|
||||||
|
cfg_.rc_buf_sz = 1000;
|
||||||
|
cfg_.rc_target_bitrate = 300;
|
||||||
|
|
||||||
|
aq_mode_ = 4;
|
||||||
|
alt_ref_aq_mode_ = 1;
|
||||||
|
|
||||||
|
::libvpx_test::I420VideoSource video("hantro_collage_w352h288.yuv", 352, 288,
|
||||||
|
30, 1, 0, 100);
|
||||||
|
|
||||||
|
ASSERT_NO_FATAL_FAILURE(RunLoop(&video));
|
||||||
|
}
|
||||||
|
|
||||||
|
VP9_INSTANTIATE_TEST_CASE(AltRefAqSegmentTest,
|
||||||
|
::testing::Values(::libvpx_test::kOnePassGood,
|
||||||
|
::libvpx_test::kTwoPassGood),
|
||||||
|
::testing::Range(2, 5));
|
||||||
|
} // namespace
|
||||||
@@ -31,9 +31,7 @@ class AltRefTest : public ::libvpx_test::EncoderTest,
|
|||||||
SetMode(libvpx_test::kTwoPassGood);
|
SetMode(libvpx_test::kTwoPassGood);
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual void BeginPassHook(unsigned int pass) {
|
virtual void BeginPassHook(unsigned int /*pass*/) { altref_count_ = 0; }
|
||||||
altref_count_ = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
virtual void PreEncodeFrameHook(libvpx_test::VideoSource *video,
|
virtual void PreEncodeFrameHook(libvpx_test::VideoSource *video,
|
||||||
libvpx_test::Encoder *encoder) {
|
libvpx_test::Encoder *encoder) {
|
||||||
@@ -75,11 +73,8 @@ class AltRefForcedKeyTestLarge
|
|||||||
public ::libvpx_test::CodecTestWith2Params<libvpx_test::TestMode, int> {
|
public ::libvpx_test::CodecTestWith2Params<libvpx_test::TestMode, int> {
|
||||||
protected:
|
protected:
|
||||||
AltRefForcedKeyTestLarge()
|
AltRefForcedKeyTestLarge()
|
||||||
: EncoderTest(GET_PARAM(0)),
|
: EncoderTest(GET_PARAM(0)), encoding_mode_(GET_PARAM(1)),
|
||||||
encoding_mode_(GET_PARAM(1)),
|
cpu_used_(GET_PARAM(2)), forced_kf_frame_num_(1), frame_num_(0) {}
|
||||||
cpu_used_(GET_PARAM(2)),
|
|
||||||
forced_kf_frame_num_(1),
|
|
||||||
frame_num_(0) {}
|
|
||||||
virtual ~AltRefForcedKeyTestLarge() {}
|
virtual ~AltRefForcedKeyTestLarge() {}
|
||||||
|
|
||||||
virtual void SetUp() {
|
virtual void SetUp() {
|
||||||
@@ -94,16 +89,11 @@ class AltRefForcedKeyTestLarge
|
|||||||
if (video->frame() == 0) {
|
if (video->frame() == 0) {
|
||||||
encoder->Control(VP8E_SET_CPUUSED, cpu_used_);
|
encoder->Control(VP8E_SET_CPUUSED, cpu_used_);
|
||||||
encoder->Control(VP8E_SET_ENABLEAUTOALTREF, 1);
|
encoder->Control(VP8E_SET_ENABLEAUTOALTREF, 1);
|
||||||
// override test default for tile columns if necessary.
|
|
||||||
#if CONFIG_VP9_ENCODER
|
#if CONFIG_VP9_ENCODER
|
||||||
|
// override test default for tile columns if necessary.
|
||||||
if (GET_PARAM(0) == &libvpx_test::kVP9) {
|
if (GET_PARAM(0) == &libvpx_test::kVP9) {
|
||||||
encoder->Control(VP9E_SET_TILE_COLUMNS, 6);
|
encoder->Control(VP9E_SET_TILE_COLUMNS, 6);
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
#if CONFIG_VP10_ENCODER
|
|
||||||
if (GET_PARAM(0) == &libvpx_test::kVP10) {
|
|
||||||
encoder->Control(VP9E_SET_TILE_COLUMNS, 6);
|
|
||||||
}
|
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
frame_flags_ =
|
frame_flags_ =
|
||||||
@@ -152,19 +142,11 @@ TEST_P(AltRefForcedKeyTestLarge, ForcedFrameIsKey) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
VP8_INSTANTIATE_TEST_CASE(
|
VP8_INSTANTIATE_TEST_CASE(AltRefForcedKeyTestLarge,
|
||||||
AltRefForcedKeyTestLarge,
|
|
||||||
::testing::Values(::libvpx_test::kOnePassGood),
|
::testing::Values(::libvpx_test::kOnePassGood),
|
||||||
::testing::Range(0, 9));
|
::testing::Range(0, 9));
|
||||||
|
|
||||||
VP9_INSTANTIATE_TEST_CASE(
|
VP9_INSTANTIATE_TEST_CASE(AltRefForcedKeyTestLarge,
|
||||||
AltRefForcedKeyTestLarge,
|
|
||||||
::testing::Values(::libvpx_test::kOnePassGood),
|
::testing::Values(::libvpx_test::kOnePassGood),
|
||||||
::testing::Range(0, 9));
|
::testing::Range(0, 9));
|
||||||
|
|
||||||
VP10_INSTANTIATE_TEST_CASE(
|
|
||||||
AltRefForcedKeyTestLarge,
|
|
||||||
::testing::Values(::libvpx_test::kOnePassGood),
|
|
||||||
::testing::Range(0, 9));
|
|
||||||
|
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|||||||
116
test/avg_test.cc
116
test/avg_test.cc
@@ -40,9 +40,7 @@ class AverageTestBase : public ::testing::Test {
|
|||||||
source_data_ = NULL;
|
source_data_ = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual void TearDown() {
|
virtual void TearDown() { libvpx_test::ClearSystemState(); }
|
||||||
libvpx_test::ClearSystemState();
|
|
||||||
}
|
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
// Handle blocks up to 4 blocks 64x64 with stride up to 128
|
// Handle blocks up to 4 blocks 64x64 with stride up to 128
|
||||||
@@ -55,19 +53,19 @@ class AverageTestBase : public ::testing::Test {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Sum Pixels
|
// Sum Pixels
|
||||||
unsigned int ReferenceAverage8x8(const uint8_t* source, int pitch) {
|
static unsigned int ReferenceAverage8x8(const uint8_t *source, int pitch) {
|
||||||
unsigned int average = 0;
|
unsigned int average = 0;
|
||||||
for (int h = 0; h < 8; ++h)
|
for (int h = 0; h < 8; ++h) {
|
||||||
for (int w = 0; w < 8; ++w)
|
for (int w = 0; w < 8; ++w) average += source[h * pitch + w];
|
||||||
average += source[h * pitch + w];
|
}
|
||||||
return ((average + 32) >> 6);
|
return ((average + 32) >> 6);
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned int ReferenceAverage4x4(const uint8_t* source, int pitch) {
|
static unsigned int ReferenceAverage4x4(const uint8_t *source, int pitch) {
|
||||||
unsigned int average = 0;
|
unsigned int average = 0;
|
||||||
for (int h = 0; h < 4; ++h)
|
for (int h = 0; h < 4; ++h) {
|
||||||
for (int w = 0; w < 4; ++w)
|
for (int w = 0; w < 4; ++w) average += source[h * pitch + w];
|
||||||
average += source[h * pitch + w];
|
}
|
||||||
return ((average + 8) >> 4);
|
return ((average + 8) >> 4);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -93,27 +91,27 @@ typedef unsigned int (*AverageFunction)(const uint8_t* s, int pitch);
|
|||||||
|
|
||||||
typedef std::tr1::tuple<int, int, int, int, AverageFunction> AvgFunc;
|
typedef std::tr1::tuple<int, int, int, int, AverageFunction> AvgFunc;
|
||||||
|
|
||||||
class AverageTest
|
class AverageTest : public AverageTestBase,
|
||||||
: public AverageTestBase,
|
|
||||||
public ::testing::WithParamInterface<AvgFunc> {
|
public ::testing::WithParamInterface<AvgFunc> {
|
||||||
public:
|
public:
|
||||||
AverageTest() : AverageTestBase(GET_PARAM(0), GET_PARAM(1)) {}
|
AverageTest() : AverageTestBase(GET_PARAM(0), GET_PARAM(1)) {}
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
void CheckAverages() {
|
void CheckAverages() {
|
||||||
|
const int block_size = GET_PARAM(3);
|
||||||
unsigned int expected = 0;
|
unsigned int expected = 0;
|
||||||
if (GET_PARAM(3) == 8) {
|
if (block_size == 8) {
|
||||||
expected = ReferenceAverage8x8(source_data_+ GET_PARAM(2),
|
expected =
|
||||||
source_stride_);
|
ReferenceAverage8x8(source_data_ + GET_PARAM(2), source_stride_);
|
||||||
} else if (GET_PARAM(3) == 4) {
|
} else if (block_size == 4) {
|
||||||
expected = ReferenceAverage4x4(source_data_+ GET_PARAM(2),
|
expected =
|
||||||
source_stride_);
|
ReferenceAverage4x4(source_data_ + GET_PARAM(2), source_stride_);
|
||||||
}
|
}
|
||||||
|
|
||||||
ASM_REGISTER_STATE_CHECK(GET_PARAM(4)(source_data_+ GET_PARAM(2),
|
ASM_REGISTER_STATE_CHECK(
|
||||||
source_stride_));
|
GET_PARAM(4)(source_data_ + GET_PARAM(2), source_stride_));
|
||||||
unsigned int actual = GET_PARAM(4)(source_data_+ GET_PARAM(2),
|
unsigned int actual =
|
||||||
source_stride_);
|
GET_PARAM(4)(source_data_ + GET_PARAM(2), source_stride_);
|
||||||
|
|
||||||
EXPECT_EQ(expected, actual);
|
EXPECT_EQ(expected, actual);
|
||||||
}
|
}
|
||||||
@@ -124,14 +122,11 @@ typedef void (*IntProRowFunc)(int16_t hbuf[16], uint8_t const *ref,
|
|||||||
|
|
||||||
typedef std::tr1::tuple<int, IntProRowFunc, IntProRowFunc> IntProRowParam;
|
typedef std::tr1::tuple<int, IntProRowFunc, IntProRowFunc> IntProRowParam;
|
||||||
|
|
||||||
class IntProRowTest
|
class IntProRowTest : public AverageTestBase,
|
||||||
: public AverageTestBase,
|
|
||||||
public ::testing::WithParamInterface<IntProRowParam> {
|
public ::testing::WithParamInterface<IntProRowParam> {
|
||||||
public:
|
public:
|
||||||
IntProRowTest()
|
IntProRowTest()
|
||||||
: AverageTestBase(16, GET_PARAM(0)),
|
: AverageTestBase(16, GET_PARAM(0)), hbuf_asm_(NULL), hbuf_c_(NULL) {
|
||||||
hbuf_asm_(NULL),
|
|
||||||
hbuf_c_(NULL) {
|
|
||||||
asm_func_ = GET_PARAM(1);
|
asm_func_ = GET_PARAM(1);
|
||||||
c_func_ = GET_PARAM(2);
|
c_func_ = GET_PARAM(2);
|
||||||
}
|
}
|
||||||
@@ -169,8 +164,7 @@ typedef int16_t (*IntProColFunc)(uint8_t const *ref, const int width);
|
|||||||
|
|
||||||
typedef std::tr1::tuple<int, IntProColFunc, IntProColFunc> IntProColParam;
|
typedef std::tr1::tuple<int, IntProColFunc, IntProColFunc> IntProColParam;
|
||||||
|
|
||||||
class IntProColTest
|
class IntProColTest : public AverageTestBase,
|
||||||
: public AverageTestBase,
|
|
||||||
public ::testing::WithParamInterface<IntProColParam> {
|
public ::testing::WithParamInterface<IntProColParam> {
|
||||||
public:
|
public:
|
||||||
IntProColTest() : AverageTestBase(GET_PARAM(0), 1), sum_asm_(0), sum_c_(0) {
|
IntProColTest() : AverageTestBase(GET_PARAM(0), 1), sum_asm_(0), sum_c_(0) {
|
||||||
@@ -195,8 +189,7 @@ class IntProColTest
|
|||||||
typedef int (*SatdFunc)(const int16_t *coeffs, int length);
|
typedef int (*SatdFunc)(const int16_t *coeffs, int length);
|
||||||
typedef std::tr1::tuple<int, SatdFunc> SatdTestParam;
|
typedef std::tr1::tuple<int, SatdFunc> SatdTestParam;
|
||||||
|
|
||||||
class SatdTest
|
class SatdTest : public ::testing::Test,
|
||||||
: public ::testing::Test,
|
|
||||||
public ::testing::WithParamInterface<SatdTestParam> {
|
public ::testing::WithParamInterface<SatdTestParam> {
|
||||||
protected:
|
protected:
|
||||||
virtual void SetUp() {
|
virtual void SetUp() {
|
||||||
@@ -286,7 +279,6 @@ TEST_P(IntProColTest, Random) {
|
|||||||
RunComparison();
|
RunComparison();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
TEST_P(SatdTest, MinValue) {
|
TEST_P(SatdTest, MinValue) {
|
||||||
const int kMin = -32640;
|
const int kMin = -32640;
|
||||||
const int expected = -kMin * satd_size_;
|
const int expected = -kMin * satd_size_;
|
||||||
@@ -320,14 +312,11 @@ using std::tr1::make_tuple;
|
|||||||
|
|
||||||
INSTANTIATE_TEST_CASE_P(
|
INSTANTIATE_TEST_CASE_P(
|
||||||
C, AverageTest,
|
C, AverageTest,
|
||||||
::testing::Values(
|
::testing::Values(make_tuple(16, 16, 1, 8, &vpx_avg_8x8_c),
|
||||||
make_tuple(16, 16, 1, 8, &vpx_avg_8x8_c),
|
|
||||||
make_tuple(16, 16, 1, 4, &vpx_avg_4x4_c)));
|
make_tuple(16, 16, 1, 4, &vpx_avg_4x4_c)));
|
||||||
|
|
||||||
INSTANTIATE_TEST_CASE_P(
|
INSTANTIATE_TEST_CASE_P(C, SatdTest,
|
||||||
C, SatdTest,
|
::testing::Values(make_tuple(16, &vpx_satd_c),
|
||||||
::testing::Values(
|
|
||||||
make_tuple(16, &vpx_satd_c),
|
|
||||||
make_tuple(64, &vpx_satd_c),
|
make_tuple(64, &vpx_satd_c),
|
||||||
make_tuple(256, &vpx_satd_c),
|
make_tuple(256, &vpx_satd_c),
|
||||||
make_tuple(1024, &vpx_satd_c)));
|
make_tuple(1024, &vpx_satd_c)));
|
||||||
@@ -335,8 +324,7 @@ INSTANTIATE_TEST_CASE_P(
|
|||||||
#if HAVE_SSE2
|
#if HAVE_SSE2
|
||||||
INSTANTIATE_TEST_CASE_P(
|
INSTANTIATE_TEST_CASE_P(
|
||||||
SSE2, AverageTest,
|
SSE2, AverageTest,
|
||||||
::testing::Values(
|
::testing::Values(make_tuple(16, 16, 0, 8, &vpx_avg_8x8_sse2),
|
||||||
make_tuple(16, 16, 0, 8, &vpx_avg_8x8_sse2),
|
|
||||||
make_tuple(16, 16, 5, 8, &vpx_avg_8x8_sse2),
|
make_tuple(16, 16, 5, 8, &vpx_avg_8x8_sse2),
|
||||||
make_tuple(32, 32, 15, 8, &vpx_avg_8x8_sse2),
|
make_tuple(32, 32, 15, 8, &vpx_avg_8x8_sse2),
|
||||||
make_tuple(16, 16, 0, 4, &vpx_avg_4x4_sse2),
|
make_tuple(16, 16, 0, 4, &vpx_avg_4x4_sse2),
|
||||||
@@ -344,21 +332,21 @@ INSTANTIATE_TEST_CASE_P(
|
|||||||
make_tuple(32, 32, 15, 4, &vpx_avg_4x4_sse2)));
|
make_tuple(32, 32, 15, 4, &vpx_avg_4x4_sse2)));
|
||||||
|
|
||||||
INSTANTIATE_TEST_CASE_P(
|
INSTANTIATE_TEST_CASE_P(
|
||||||
SSE2, IntProRowTest, ::testing::Values(
|
SSE2, IntProRowTest,
|
||||||
make_tuple(16, &vpx_int_pro_row_sse2, &vpx_int_pro_row_c),
|
::testing::Values(make_tuple(16, &vpx_int_pro_row_sse2, &vpx_int_pro_row_c),
|
||||||
make_tuple(32, &vpx_int_pro_row_sse2, &vpx_int_pro_row_c),
|
make_tuple(32, &vpx_int_pro_row_sse2, &vpx_int_pro_row_c),
|
||||||
make_tuple(64, &vpx_int_pro_row_sse2, &vpx_int_pro_row_c)));
|
make_tuple(64, &vpx_int_pro_row_sse2,
|
||||||
|
&vpx_int_pro_row_c)));
|
||||||
|
|
||||||
INSTANTIATE_TEST_CASE_P(
|
INSTANTIATE_TEST_CASE_P(
|
||||||
SSE2, IntProColTest, ::testing::Values(
|
SSE2, IntProColTest,
|
||||||
make_tuple(16, &vpx_int_pro_col_sse2, &vpx_int_pro_col_c),
|
::testing::Values(make_tuple(16, &vpx_int_pro_col_sse2, &vpx_int_pro_col_c),
|
||||||
make_tuple(32, &vpx_int_pro_col_sse2, &vpx_int_pro_col_c),
|
make_tuple(32, &vpx_int_pro_col_sse2, &vpx_int_pro_col_c),
|
||||||
make_tuple(64, &vpx_int_pro_col_sse2, &vpx_int_pro_col_c)));
|
make_tuple(64, &vpx_int_pro_col_sse2,
|
||||||
|
&vpx_int_pro_col_c)));
|
||||||
|
|
||||||
INSTANTIATE_TEST_CASE_P(
|
INSTANTIATE_TEST_CASE_P(SSE2, SatdTest,
|
||||||
SSE2, SatdTest,
|
::testing::Values(make_tuple(16, &vpx_satd_sse2),
|
||||||
::testing::Values(
|
|
||||||
make_tuple(16, &vpx_satd_sse2),
|
|
||||||
make_tuple(64, &vpx_satd_sse2),
|
make_tuple(64, &vpx_satd_sse2),
|
||||||
make_tuple(256, &vpx_satd_sse2),
|
make_tuple(256, &vpx_satd_sse2),
|
||||||
make_tuple(1024, &vpx_satd_sse2)));
|
make_tuple(1024, &vpx_satd_sse2)));
|
||||||
@@ -367,8 +355,7 @@ INSTANTIATE_TEST_CASE_P(
|
|||||||
#if HAVE_NEON
|
#if HAVE_NEON
|
||||||
INSTANTIATE_TEST_CASE_P(
|
INSTANTIATE_TEST_CASE_P(
|
||||||
NEON, AverageTest,
|
NEON, AverageTest,
|
||||||
::testing::Values(
|
::testing::Values(make_tuple(16, 16, 0, 8, &vpx_avg_8x8_neon),
|
||||||
make_tuple(16, 16, 0, 8, &vpx_avg_8x8_neon),
|
|
||||||
make_tuple(16, 16, 5, 8, &vpx_avg_8x8_neon),
|
make_tuple(16, 16, 5, 8, &vpx_avg_8x8_neon),
|
||||||
make_tuple(32, 32, 15, 8, &vpx_avg_8x8_neon),
|
make_tuple(32, 32, 15, 8, &vpx_avg_8x8_neon),
|
||||||
make_tuple(16, 16, 0, 4, &vpx_avg_4x4_neon),
|
make_tuple(16, 16, 0, 4, &vpx_avg_4x4_neon),
|
||||||
@@ -376,21 +363,21 @@ INSTANTIATE_TEST_CASE_P(
|
|||||||
make_tuple(32, 32, 15, 4, &vpx_avg_4x4_neon)));
|
make_tuple(32, 32, 15, 4, &vpx_avg_4x4_neon)));
|
||||||
|
|
||||||
INSTANTIATE_TEST_CASE_P(
|
INSTANTIATE_TEST_CASE_P(
|
||||||
NEON, IntProRowTest, ::testing::Values(
|
NEON, IntProRowTest,
|
||||||
make_tuple(16, &vpx_int_pro_row_neon, &vpx_int_pro_row_c),
|
::testing::Values(make_tuple(16, &vpx_int_pro_row_neon, &vpx_int_pro_row_c),
|
||||||
make_tuple(32, &vpx_int_pro_row_neon, &vpx_int_pro_row_c),
|
make_tuple(32, &vpx_int_pro_row_neon, &vpx_int_pro_row_c),
|
||||||
make_tuple(64, &vpx_int_pro_row_neon, &vpx_int_pro_row_c)));
|
make_tuple(64, &vpx_int_pro_row_neon,
|
||||||
|
&vpx_int_pro_row_c)));
|
||||||
|
|
||||||
INSTANTIATE_TEST_CASE_P(
|
INSTANTIATE_TEST_CASE_P(
|
||||||
NEON, IntProColTest, ::testing::Values(
|
NEON, IntProColTest,
|
||||||
make_tuple(16, &vpx_int_pro_col_neon, &vpx_int_pro_col_c),
|
::testing::Values(make_tuple(16, &vpx_int_pro_col_neon, &vpx_int_pro_col_c),
|
||||||
make_tuple(32, &vpx_int_pro_col_neon, &vpx_int_pro_col_c),
|
make_tuple(32, &vpx_int_pro_col_neon, &vpx_int_pro_col_c),
|
||||||
make_tuple(64, &vpx_int_pro_col_neon, &vpx_int_pro_col_c)));
|
make_tuple(64, &vpx_int_pro_col_neon,
|
||||||
|
&vpx_int_pro_col_c)));
|
||||||
|
|
||||||
INSTANTIATE_TEST_CASE_P(
|
INSTANTIATE_TEST_CASE_P(NEON, SatdTest,
|
||||||
NEON, SatdTest,
|
::testing::Values(make_tuple(16, &vpx_satd_neon),
|
||||||
::testing::Values(
|
|
||||||
make_tuple(16, &vpx_satd_neon),
|
|
||||||
make_tuple(64, &vpx_satd_neon),
|
make_tuple(64, &vpx_satd_neon),
|
||||||
make_tuple(256, &vpx_satd_neon),
|
make_tuple(256, &vpx_satd_neon),
|
||||||
make_tuple(1024, &vpx_satd_neon)));
|
make_tuple(1024, &vpx_satd_neon)));
|
||||||
@@ -399,8 +386,7 @@ INSTANTIATE_TEST_CASE_P(
|
|||||||
#if HAVE_MSA
|
#if HAVE_MSA
|
||||||
INSTANTIATE_TEST_CASE_P(
|
INSTANTIATE_TEST_CASE_P(
|
||||||
MSA, AverageTest,
|
MSA, AverageTest,
|
||||||
::testing::Values(
|
::testing::Values(make_tuple(16, 16, 0, 8, &vpx_avg_8x8_msa),
|
||||||
make_tuple(16, 16, 0, 8, &vpx_avg_8x8_msa),
|
|
||||||
make_tuple(16, 16, 5, 8, &vpx_avg_8x8_msa),
|
make_tuple(16, 16, 5, 8, &vpx_avg_8x8_msa),
|
||||||
make_tuple(32, 32, 15, 8, &vpx_avg_8x8_msa),
|
make_tuple(32, 32, 15, 8, &vpx_avg_8x8_msa),
|
||||||
make_tuple(16, 16, 0, 4, &vpx_avg_4x4_msa),
|
make_tuple(16, 16, 0, 4, &vpx_avg_4x4_msa),
|
||||||
|
|||||||
@@ -26,9 +26,7 @@
|
|||||||
|
|
||||||
#include "vpx_mem/vpx_mem.h"
|
#include "vpx_mem/vpx_mem.h"
|
||||||
|
|
||||||
|
extern "C" double vp9_get_blockiness(const unsigned char *img1, int img1_pitch,
|
||||||
extern "C"
|
|
||||||
double vp9_get_blockiness(const unsigned char *img1, int img1_pitch,
|
|
||||||
const unsigned char *img2, int img2_pitch,
|
const unsigned char *img2, int img2_pitch,
|
||||||
int width, int height);
|
int width, int height);
|
||||||
|
|
||||||
@@ -53,9 +51,7 @@ class BlockinessTestBase : public ::testing::Test {
|
|||||||
reference_data_ = NULL;
|
reference_data_ = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual void TearDown() {
|
virtual void TearDown() { libvpx_test::ClearSystemState(); }
|
||||||
libvpx_test::ClearSystemState();
|
|
||||||
}
|
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
// Handle frames up to 640x480
|
// Handle frames up to 640x480
|
||||||
@@ -68,8 +64,8 @@ class BlockinessTestBase : public ::testing::Test {
|
|||||||
rnd_.Reset(ACMRandom::DeterministicSeed());
|
rnd_.Reset(ACMRandom::DeterministicSeed());
|
||||||
}
|
}
|
||||||
|
|
||||||
void FillConstant(uint8_t *data, int stride, uint8_t fill_constant,
|
void FillConstant(uint8_t *data, int stride, uint8_t fill_constant, int width,
|
||||||
int width, int height) {
|
int height) {
|
||||||
for (int h = 0; h < height; ++h) {
|
for (int h = 0; h < height; ++h) {
|
||||||
for (int w = 0; w < width; ++w) {
|
for (int w = 0; w < width; ++w) {
|
||||||
data[h * stride + w] = fill_constant;
|
data[h * stride + w] = fill_constant;
|
||||||
@@ -104,13 +100,14 @@ class BlockinessTestBase : public ::testing::Test {
|
|||||||
void FillCheckerboard(uint8_t *data, int stride) {
|
void FillCheckerboard(uint8_t *data, int stride) {
|
||||||
for (int h = 0; h < height_; h += 4) {
|
for (int h = 0; h < height_; h += 4) {
|
||||||
for (int w = 0; w < width_; w += 4) {
|
for (int w = 0; w < width_; w += 4) {
|
||||||
if (((h/4) ^ (w/4)) & 1)
|
if (((h / 4) ^ (w / 4)) & 1) {
|
||||||
FillConstant(data + h * stride + w, stride, 255, 4, 4);
|
FillConstant(data + h * stride + w, stride, 255, 4, 4);
|
||||||
else
|
} else {
|
||||||
FillConstant(data + h * stride + w, stride, 0, 4, 4);
|
FillConstant(data + h * stride + w, stride, 0, 4, 4);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void Blur(uint8_t *data, int stride, int taps) {
|
void Blur(uint8_t *data, int stride, int taps) {
|
||||||
int sum = 0;
|
int sum = 0;
|
||||||
@@ -152,10 +149,9 @@ class BlockinessVP9Test
|
|||||||
BlockinessVP9Test() : BlockinessTestBase(GET_PARAM(0), GET_PARAM(1)) {}
|
BlockinessVP9Test() : BlockinessTestBase(GET_PARAM(0), GET_PARAM(1)) {}
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
int CheckBlockiness() {
|
double GetBlockiness() const {
|
||||||
return vp9_get_blockiness(source_data_, source_stride_,
|
return vp9_get_blockiness(source_data_, source_stride_, reference_data_,
|
||||||
reference_data_, reference_stride_,
|
reference_stride_, width_, height_);
|
||||||
width_, height_);
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
#endif // CONFIG_VP9_ENCODER
|
#endif // CONFIG_VP9_ENCODER
|
||||||
@@ -168,16 +164,17 @@ TEST_P(BlockinessVP9Test, SourceBlockierThanReference) {
|
|||||||
// Source is blockier than reference.
|
// Source is blockier than reference.
|
||||||
FillRandomBlocky(source_data_, source_stride_);
|
FillRandomBlocky(source_data_, source_stride_);
|
||||||
FillConstant(reference_data_, reference_stride_, 128);
|
FillConstant(reference_data_, reference_stride_, 128);
|
||||||
int super_blocky = CheckBlockiness();
|
const double super_blocky = GetBlockiness();
|
||||||
|
|
||||||
EXPECT_EQ(0, super_blocky) << "Blocky source should produce 0 blockiness.";
|
EXPECT_DOUBLE_EQ(0.0, super_blocky)
|
||||||
|
<< "Blocky source should produce 0 blockiness.";
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_P(BlockinessVP9Test, ReferenceBlockierThanSource) {
|
TEST_P(BlockinessVP9Test, ReferenceBlockierThanSource) {
|
||||||
// Source is blockier than reference.
|
// Source is blockier than reference.
|
||||||
FillConstant(source_data_, source_stride_, 128);
|
FillConstant(source_data_, source_stride_, 128);
|
||||||
FillRandomBlocky(reference_data_, reference_stride_);
|
FillRandomBlocky(reference_data_, reference_stride_);
|
||||||
int super_blocky = CheckBlockiness();
|
const double super_blocky = GetBlockiness();
|
||||||
|
|
||||||
EXPECT_GT(super_blocky, 0.0)
|
EXPECT_GT(super_blocky, 0.0)
|
||||||
<< "Blocky reference should score high for blockiness.";
|
<< "Blocky reference should score high for blockiness.";
|
||||||
@@ -187,10 +184,10 @@ TEST_P(BlockinessVP9Test, BlurringDecreasesBlockiness) {
|
|||||||
// Source is blockier than reference.
|
// Source is blockier than reference.
|
||||||
FillConstant(source_data_, source_stride_, 128);
|
FillConstant(source_data_, source_stride_, 128);
|
||||||
FillRandomBlocky(reference_data_, reference_stride_);
|
FillRandomBlocky(reference_data_, reference_stride_);
|
||||||
int super_blocky = CheckBlockiness();
|
const double super_blocky = GetBlockiness();
|
||||||
|
|
||||||
Blur(reference_data_, reference_stride_, 4);
|
Blur(reference_data_, reference_stride_, 4);
|
||||||
int less_blocky = CheckBlockiness();
|
const double less_blocky = GetBlockiness();
|
||||||
|
|
||||||
EXPECT_GT(super_blocky, less_blocky)
|
EXPECT_GT(super_blocky, less_blocky)
|
||||||
<< "A straight blur should decrease blockiness.";
|
<< "A straight blur should decrease blockiness.";
|
||||||
@@ -201,17 +198,16 @@ TEST_P(BlockinessVP9Test, WorstCaseBlockiness) {
|
|||||||
FillConstant(source_data_, source_stride_, 128);
|
FillConstant(source_data_, source_stride_, 128);
|
||||||
FillCheckerboard(reference_data_, reference_stride_);
|
FillCheckerboard(reference_data_, reference_stride_);
|
||||||
|
|
||||||
int super_blocky = CheckBlockiness();
|
const double super_blocky = GetBlockiness();
|
||||||
|
|
||||||
Blur(reference_data_, reference_stride_, 4);
|
Blur(reference_data_, reference_stride_, 4);
|
||||||
int less_blocky = CheckBlockiness();
|
const double less_blocky = GetBlockiness();
|
||||||
|
|
||||||
EXPECT_GT(super_blocky, less_blocky)
|
EXPECT_GT(super_blocky, less_blocky)
|
||||||
<< "A straight blur should decrease blockiness.";
|
<< "A straight blur should decrease blockiness.";
|
||||||
}
|
}
|
||||||
#endif // CONFIG_VP9_ENCODER
|
#endif // CONFIG_VP9_ENCODER
|
||||||
|
|
||||||
|
|
||||||
using std::tr1::make_tuple;
|
using std::tr1::make_tuple;
|
||||||
|
|
||||||
//------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------
|
||||||
@@ -219,9 +215,7 @@ using std::tr1::make_tuple;
|
|||||||
|
|
||||||
#if CONFIG_VP9_ENCODER
|
#if CONFIG_VP9_ENCODER
|
||||||
const BlockinessParam c_vp9_tests[] = {
|
const BlockinessParam c_vp9_tests[] = {
|
||||||
make_tuple(320, 240),
|
make_tuple(320, 240), make_tuple(318, 242), make_tuple(318, 238),
|
||||||
make_tuple(318, 242),
|
|
||||||
make_tuple(318, 238),
|
|
||||||
};
|
};
|
||||||
INSTANTIATE_TEST_CASE_P(C, BlockinessVP9Test, ::testing::ValuesIn(c_vp9_tests));
|
INSTANTIATE_TEST_CASE_P(C, BlockinessVP9Test, ::testing::ValuesIn(c_vp9_tests));
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -17,7 +17,8 @@
|
|||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
|
|
||||||
class BordersTest : public ::libvpx_test::EncoderTest,
|
class BordersTest
|
||||||
|
: public ::libvpx_test::EncoderTest,
|
||||||
public ::libvpx_test::CodecTestWithParam<libvpx_test::TestMode> {
|
public ::libvpx_test::CodecTestWithParam<libvpx_test::TestMode> {
|
||||||
protected:
|
protected:
|
||||||
BordersTest() : EncoderTest(GET_PARAM(0)) {}
|
BordersTest() : EncoderTest(GET_PARAM(0)) {}
|
||||||
@@ -78,9 +79,6 @@ TEST_P(BordersTest, TestLowBitrate) {
|
|||||||
ASSERT_NO_FATAL_FAILURE(RunLoop(&video));
|
ASSERT_NO_FATAL_FAILURE(RunLoop(&video));
|
||||||
}
|
}
|
||||||
|
|
||||||
VP9_INSTANTIATE_TEST_CASE(BordersTest, ::testing::Values(
|
VP9_INSTANTIATE_TEST_CASE(BordersTest,
|
||||||
::libvpx_test::kTwoPassGood));
|
::testing::Values(::libvpx_test::kTwoPassGood));
|
||||||
|
|
||||||
VP10_INSTANTIATE_TEST_CASE(BordersTest, ::testing::Values(
|
|
||||||
::libvpx_test::kTwoPassGood));
|
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|||||||
@@ -55,10 +55,7 @@ const ByteAlignmentTestParam kBaTestParams[] = {
|
|||||||
class ByteAlignmentTest
|
class ByteAlignmentTest
|
||||||
: public ::testing::TestWithParam<ByteAlignmentTestParam> {
|
: public ::testing::TestWithParam<ByteAlignmentTestParam> {
|
||||||
protected:
|
protected:
|
||||||
ByteAlignmentTest()
|
ByteAlignmentTest() : video_(NULL), decoder_(NULL), md5_file_(NULL) {}
|
||||||
: video_(NULL),
|
|
||||||
decoder_(NULL),
|
|
||||||
md5_file_(NULL) {}
|
|
||||||
|
|
||||||
virtual void SetUp() {
|
virtual void SetUp() {
|
||||||
video_ = new libvpx_test::WebMVideoSource(kVP9TestFile);
|
video_ = new libvpx_test::WebMVideoSource(kVP9TestFile);
|
||||||
@@ -74,8 +71,7 @@ class ByteAlignmentTest
|
|||||||
}
|
}
|
||||||
|
|
||||||
virtual void TearDown() {
|
virtual void TearDown() {
|
||||||
if (md5_file_ != NULL)
|
if (md5_file_ != NULL) fclose(md5_file_);
|
||||||
fclose(md5_file_);
|
|
||||||
|
|
||||||
delete decoder_;
|
delete decoder_;
|
||||||
delete video_;
|
delete video_;
|
||||||
@@ -89,8 +85,7 @@ class ByteAlignmentTest
|
|||||||
const vpx_codec_err_t res =
|
const vpx_codec_err_t res =
|
||||||
decoder_->DecodeFrame(video_->cxdata(), video_->frame_size());
|
decoder_->DecodeFrame(video_->cxdata(), video_->frame_size());
|
||||||
CheckDecodedFrames(byte_alignment_to_check);
|
CheckDecodedFrames(byte_alignment_to_check);
|
||||||
if (res == VPX_CODEC_OK)
|
if (res == VPX_CODEC_OK) video_->Next();
|
||||||
video_->Next();
|
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -98,8 +93,7 @@ class ByteAlignmentTest
|
|||||||
for (; video_->cxdata() != NULL; video_->Next()) {
|
for (; video_->cxdata() != NULL; video_->Next()) {
|
||||||
const vpx_codec_err_t res =
|
const vpx_codec_err_t res =
|
||||||
decoder_->DecodeFrame(video_->cxdata(), video_->frame_size());
|
decoder_->DecodeFrame(video_->cxdata(), video_->frame_size());
|
||||||
if (res != VPX_CODEC_OK)
|
if (res != VPX_CODEC_OK) return res;
|
||||||
return res;
|
|
||||||
CheckDecodedFrames(byte_alignment_to_check);
|
CheckDecodedFrames(byte_alignment_to_check);
|
||||||
}
|
}
|
||||||
return VPX_CODEC_OK;
|
return VPX_CODEC_OK;
|
||||||
|
|||||||
@@ -13,10 +13,10 @@
|
|||||||
#include "./vpx_config.h"
|
#include "./vpx_config.h"
|
||||||
#include "vpx/vpx_decoder.h"
|
#include "vpx/vpx_decoder.h"
|
||||||
#include "vpx/vpx_encoder.h"
|
#include "vpx/vpx_encoder.h"
|
||||||
#if CONFIG_VP8_ENCODER || CONFIG_VP9_ENCODER || CONFIG_VP10_ENCODER
|
#if CONFIG_VP8_ENCODER || CONFIG_VP9_ENCODER
|
||||||
#include "vpx/vp8cx.h"
|
#include "vpx/vp8cx.h"
|
||||||
#endif
|
#endif
|
||||||
#if CONFIG_VP8_DECODER || CONFIG_VP9_DECODER || CONFIG_VP10_DECODER
|
#if CONFIG_VP8_DECODER || CONFIG_VP9_DECODER
|
||||||
#include "vpx/vp8dx.h"
|
#include "vpx/vp8dx.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@@ -32,13 +32,10 @@ class CodecFactory {
|
|||||||
|
|
||||||
virtual ~CodecFactory() {}
|
virtual ~CodecFactory() {}
|
||||||
|
|
||||||
virtual Decoder* CreateDecoder(vpx_codec_dec_cfg_t cfg,
|
virtual Decoder *CreateDecoder(vpx_codec_dec_cfg_t cfg) const = 0;
|
||||||
unsigned long deadline) const = 0;
|
|
||||||
|
|
||||||
virtual Decoder *CreateDecoder(vpx_codec_dec_cfg_t cfg,
|
virtual Decoder *CreateDecoder(vpx_codec_dec_cfg_t cfg,
|
||||||
const vpx_codec_flags_t flags,
|
const vpx_codec_flags_t flags) const = 0;
|
||||||
unsigned long deadline) // NOLINT(runtime/int)
|
|
||||||
const = 0;
|
|
||||||
|
|
||||||
virtual Encoder *CreateEncoder(vpx_codec_enc_cfg_t cfg,
|
virtual Encoder *CreateEncoder(vpx_codec_enc_cfg_t cfg,
|
||||||
unsigned long deadline,
|
unsigned long deadline,
|
||||||
@@ -54,18 +51,24 @@ class CodecFactory {
|
|||||||
* definition.
|
* definition.
|
||||||
*/
|
*/
|
||||||
template <class T1>
|
template <class T1>
|
||||||
class CodecTestWithParam : public ::testing::TestWithParam<
|
class CodecTestWithParam
|
||||||
std::tr1::tuple< const libvpx_test::CodecFactory*, T1 > > {
|
: public ::testing::TestWithParam<
|
||||||
};
|
std::tr1::tuple<const libvpx_test::CodecFactory *, T1> > {};
|
||||||
|
|
||||||
template <class T1, class T2>
|
template <class T1, class T2>
|
||||||
class CodecTestWith2Params : public ::testing::TestWithParam<
|
class CodecTestWith2Params
|
||||||
std::tr1::tuple< const libvpx_test::CodecFactory*, T1, T2 > > {
|
: public ::testing::TestWithParam<
|
||||||
};
|
std::tr1::tuple<const libvpx_test::CodecFactory *, T1, T2> > {};
|
||||||
|
|
||||||
template <class T1, class T2, class T3>
|
template <class T1, class T2, class T3>
|
||||||
class CodecTestWith3Params : public ::testing::TestWithParam<
|
class CodecTestWith3Params
|
||||||
std::tr1::tuple< const libvpx_test::CodecFactory*, T1, T2, T3 > > {
|
: public ::testing::TestWithParam<
|
||||||
|
std::tr1::tuple<const libvpx_test::CodecFactory *, T1, T2, T3> > {};
|
||||||
|
|
||||||
|
template <class T1, class T2, class T3, class T4>
|
||||||
|
class CodecTestWith4Params
|
||||||
|
: public ::testing::TestWithParam<
|
||||||
|
std::tr1::tuple<const libvpx_test::CodecFactory *, T1, T2, T3, T4> > {
|
||||||
};
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -74,12 +77,10 @@ class CodecTestWith3Params : public ::testing::TestWithParam<
|
|||||||
#if CONFIG_VP8
|
#if CONFIG_VP8
|
||||||
class VP8Decoder : public Decoder {
|
class VP8Decoder : public Decoder {
|
||||||
public:
|
public:
|
||||||
VP8Decoder(vpx_codec_dec_cfg_t cfg, unsigned long deadline)
|
explicit VP8Decoder(vpx_codec_dec_cfg_t cfg) : Decoder(cfg) {}
|
||||||
: Decoder(cfg, deadline) {}
|
|
||||||
|
|
||||||
VP8Decoder(vpx_codec_dec_cfg_t cfg, const vpx_codec_flags_t flag,
|
VP8Decoder(vpx_codec_dec_cfg_t cfg, const vpx_codec_flags_t flag)
|
||||||
unsigned long deadline) // NOLINT
|
: Decoder(cfg, flag) {}
|
||||||
: Decoder(cfg, flag, deadline) {}
|
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
virtual vpx_codec_iface_t *CodecInterface() const {
|
virtual vpx_codec_iface_t *CodecInterface() const {
|
||||||
@@ -111,17 +112,17 @@ class VP8CodecFactory : public CodecFactory {
|
|||||||
public:
|
public:
|
||||||
VP8CodecFactory() : CodecFactory() {}
|
VP8CodecFactory() : CodecFactory() {}
|
||||||
|
|
||||||
virtual Decoder* CreateDecoder(vpx_codec_dec_cfg_t cfg,
|
virtual Decoder *CreateDecoder(vpx_codec_dec_cfg_t cfg) const {
|
||||||
unsigned long deadline) const {
|
return CreateDecoder(cfg, 0);
|
||||||
return CreateDecoder(cfg, 0, deadline);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual Decoder *CreateDecoder(vpx_codec_dec_cfg_t cfg,
|
virtual Decoder *CreateDecoder(vpx_codec_dec_cfg_t cfg,
|
||||||
const vpx_codec_flags_t flags,
|
const vpx_codec_flags_t flags) const {
|
||||||
unsigned long deadline) const { // NOLINT
|
|
||||||
#if CONFIG_VP8_DECODER
|
#if CONFIG_VP8_DECODER
|
||||||
return new VP8Decoder(cfg, flags, deadline);
|
return new VP8Decoder(cfg, flags);
|
||||||
#else
|
#else
|
||||||
|
(void)cfg;
|
||||||
|
(void)flags;
|
||||||
return NULL;
|
return NULL;
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
@@ -133,6 +134,10 @@ class VP8CodecFactory : public CodecFactory {
|
|||||||
#if CONFIG_VP8_ENCODER
|
#if CONFIG_VP8_ENCODER
|
||||||
return new VP8Encoder(cfg, deadline, init_flags, stats);
|
return new VP8Encoder(cfg, deadline, init_flags, stats);
|
||||||
#else
|
#else
|
||||||
|
(void)cfg;
|
||||||
|
(void)deadline;
|
||||||
|
(void)init_flags;
|
||||||
|
(void)stats;
|
||||||
return NULL;
|
return NULL;
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
@@ -142,6 +147,8 @@ class VP8CodecFactory : public CodecFactory {
|
|||||||
#if CONFIG_VP8_ENCODER
|
#if CONFIG_VP8_ENCODER
|
||||||
return vpx_codec_enc_config_default(&vpx_codec_vp8_cx_algo, cfg, usage);
|
return vpx_codec_enc_config_default(&vpx_codec_vp8_cx_algo, cfg, usage);
|
||||||
#else
|
#else
|
||||||
|
(void)cfg;
|
||||||
|
(void)usage;
|
||||||
return VPX_CODEC_INCAPABLE;
|
return VPX_CODEC_INCAPABLE;
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
@@ -150,7 +157,8 @@ class VP8CodecFactory : public CodecFactory {
|
|||||||
const libvpx_test::VP8CodecFactory kVP8;
|
const libvpx_test::VP8CodecFactory kVP8;
|
||||||
|
|
||||||
#define VP8_INSTANTIATE_TEST_CASE(test, ...) \
|
#define VP8_INSTANTIATE_TEST_CASE(test, ...) \
|
||||||
INSTANTIATE_TEST_CASE_P(VP8, test, \
|
INSTANTIATE_TEST_CASE_P( \
|
||||||
|
VP8, test, \
|
||||||
::testing::Combine( \
|
::testing::Combine( \
|
||||||
::testing::Values(static_cast<const libvpx_test::CodecFactory *>( \
|
::testing::Values(static_cast<const libvpx_test::CodecFactory *>( \
|
||||||
&libvpx_test::kVP8)), \
|
&libvpx_test::kVP8)), \
|
||||||
@@ -159,19 +167,16 @@ const libvpx_test::VP8CodecFactory kVP8;
|
|||||||
#define VP8_INSTANTIATE_TEST_CASE(test, ...)
|
#define VP8_INSTANTIATE_TEST_CASE(test, ...)
|
||||||
#endif // CONFIG_VP8
|
#endif // CONFIG_VP8
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* VP9 Codec Definitions
|
* VP9 Codec Definitions
|
||||||
*/
|
*/
|
||||||
#if CONFIG_VP9
|
#if CONFIG_VP9
|
||||||
class VP9Decoder : public Decoder {
|
class VP9Decoder : public Decoder {
|
||||||
public:
|
public:
|
||||||
VP9Decoder(vpx_codec_dec_cfg_t cfg, unsigned long deadline)
|
explicit VP9Decoder(vpx_codec_dec_cfg_t cfg) : Decoder(cfg) {}
|
||||||
: Decoder(cfg, deadline) {}
|
|
||||||
|
|
||||||
VP9Decoder(vpx_codec_dec_cfg_t cfg, const vpx_codec_flags_t flag,
|
VP9Decoder(vpx_codec_dec_cfg_t cfg, const vpx_codec_flags_t flag)
|
||||||
unsigned long deadline) // NOLINT
|
: Decoder(cfg, flag) {}
|
||||||
: Decoder(cfg, flag, deadline) {}
|
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
virtual vpx_codec_iface_t *CodecInterface() const {
|
virtual vpx_codec_iface_t *CodecInterface() const {
|
||||||
@@ -203,17 +208,17 @@ class VP9CodecFactory : public CodecFactory {
|
|||||||
public:
|
public:
|
||||||
VP9CodecFactory() : CodecFactory() {}
|
VP9CodecFactory() : CodecFactory() {}
|
||||||
|
|
||||||
virtual Decoder* CreateDecoder(vpx_codec_dec_cfg_t cfg,
|
virtual Decoder *CreateDecoder(vpx_codec_dec_cfg_t cfg) const {
|
||||||
unsigned long deadline) const {
|
return CreateDecoder(cfg, 0);
|
||||||
return CreateDecoder(cfg, 0, deadline);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual Decoder *CreateDecoder(vpx_codec_dec_cfg_t cfg,
|
virtual Decoder *CreateDecoder(vpx_codec_dec_cfg_t cfg,
|
||||||
const vpx_codec_flags_t flags,
|
const vpx_codec_flags_t flags) const {
|
||||||
unsigned long deadline) const { // NOLINT
|
|
||||||
#if CONFIG_VP9_DECODER
|
#if CONFIG_VP9_DECODER
|
||||||
return new VP9Decoder(cfg, flags, deadline);
|
return new VP9Decoder(cfg, flags);
|
||||||
#else
|
#else
|
||||||
|
(void)cfg;
|
||||||
|
(void)flags;
|
||||||
return NULL;
|
return NULL;
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
@@ -225,6 +230,10 @@ class VP9CodecFactory : public CodecFactory {
|
|||||||
#if CONFIG_VP9_ENCODER
|
#if CONFIG_VP9_ENCODER
|
||||||
return new VP9Encoder(cfg, deadline, init_flags, stats);
|
return new VP9Encoder(cfg, deadline, init_flags, stats);
|
||||||
#else
|
#else
|
||||||
|
(void)cfg;
|
||||||
|
(void)deadline;
|
||||||
|
(void)init_flags;
|
||||||
|
(void)stats;
|
||||||
return NULL;
|
return NULL;
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
@@ -233,9 +242,9 @@ class VP9CodecFactory : public CodecFactory {
|
|||||||
int usage) const {
|
int usage) const {
|
||||||
#if CONFIG_VP9_ENCODER
|
#if CONFIG_VP9_ENCODER
|
||||||
return vpx_codec_enc_config_default(&vpx_codec_vp9_cx_algo, cfg, usage);
|
return vpx_codec_enc_config_default(&vpx_codec_vp9_cx_algo, cfg, usage);
|
||||||
#elif CONFIG_VP10_ENCODER
|
|
||||||
return vpx_codec_enc_config_default(&vpx_codec_vp10_cx_algo, cfg, usage);
|
|
||||||
#else
|
#else
|
||||||
|
(void)cfg;
|
||||||
|
(void)usage;
|
||||||
return VPX_CODEC_INCAPABLE;
|
return VPX_CODEC_INCAPABLE;
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
@@ -244,7 +253,8 @@ class VP9CodecFactory : public CodecFactory {
|
|||||||
const libvpx_test::VP9CodecFactory kVP9;
|
const libvpx_test::VP9CodecFactory kVP9;
|
||||||
|
|
||||||
#define VP9_INSTANTIATE_TEST_CASE(test, ...) \
|
#define VP9_INSTANTIATE_TEST_CASE(test, ...) \
|
||||||
INSTANTIATE_TEST_CASE_P(VP9, test, \
|
INSTANTIATE_TEST_CASE_P( \
|
||||||
|
VP9, test, \
|
||||||
::testing::Combine( \
|
::testing::Combine( \
|
||||||
::testing::Values(static_cast<const libvpx_test::CodecFactory *>( \
|
::testing::Values(static_cast<const libvpx_test::CodecFactory *>( \
|
||||||
&libvpx_test::kVP9)), \
|
&libvpx_test::kVP9)), \
|
||||||
@@ -253,96 +263,5 @@ const libvpx_test::VP9CodecFactory kVP9;
|
|||||||
#define VP9_INSTANTIATE_TEST_CASE(test, ...)
|
#define VP9_INSTANTIATE_TEST_CASE(test, ...)
|
||||||
#endif // CONFIG_VP9
|
#endif // CONFIG_VP9
|
||||||
|
|
||||||
/*
|
|
||||||
* VP10 Codec Definitions
|
|
||||||
*/
|
|
||||||
#if CONFIG_VP10
|
|
||||||
class VP10Decoder : public Decoder {
|
|
||||||
public:
|
|
||||||
VP10Decoder(vpx_codec_dec_cfg_t cfg, unsigned long deadline)
|
|
||||||
: Decoder(cfg, deadline) {}
|
|
||||||
|
|
||||||
VP10Decoder(vpx_codec_dec_cfg_t cfg, const vpx_codec_flags_t flag,
|
|
||||||
unsigned long deadline) // NOLINT
|
|
||||||
: Decoder(cfg, flag, deadline) {}
|
|
||||||
|
|
||||||
protected:
|
|
||||||
virtual vpx_codec_iface_t* CodecInterface() const {
|
|
||||||
#if CONFIG_VP10_DECODER
|
|
||||||
return &vpx_codec_vp10_dx_algo;
|
|
||||||
#else
|
|
||||||
return NULL;
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
class VP10Encoder : public Encoder {
|
|
||||||
public:
|
|
||||||
VP10Encoder(vpx_codec_enc_cfg_t cfg, unsigned long deadline,
|
|
||||||
const unsigned long init_flags, TwopassStatsStore *stats)
|
|
||||||
: Encoder(cfg, deadline, init_flags, stats) {}
|
|
||||||
|
|
||||||
protected:
|
|
||||||
virtual vpx_codec_iface_t* CodecInterface() const {
|
|
||||||
#if CONFIG_VP10_ENCODER
|
|
||||||
return &vpx_codec_vp10_cx_algo;
|
|
||||||
#else
|
|
||||||
return NULL;
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
class VP10CodecFactory : public CodecFactory {
|
|
||||||
public:
|
|
||||||
VP10CodecFactory() : CodecFactory() {}
|
|
||||||
|
|
||||||
virtual Decoder* CreateDecoder(vpx_codec_dec_cfg_t cfg,
|
|
||||||
unsigned long deadline) const {
|
|
||||||
return CreateDecoder(cfg, 0, deadline);
|
|
||||||
}
|
|
||||||
|
|
||||||
virtual Decoder* CreateDecoder(vpx_codec_dec_cfg_t cfg,
|
|
||||||
const vpx_codec_flags_t flags,
|
|
||||||
unsigned long deadline) const { // NOLINT
|
|
||||||
#if CONFIG_VP10_DECODER
|
|
||||||
return new VP10Decoder(cfg, flags, deadline);
|
|
||||||
#else
|
|
||||||
return NULL;
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
virtual Encoder* CreateEncoder(vpx_codec_enc_cfg_t cfg,
|
|
||||||
unsigned long deadline,
|
|
||||||
const unsigned long init_flags,
|
|
||||||
TwopassStatsStore *stats) const {
|
|
||||||
#if CONFIG_VP10_ENCODER
|
|
||||||
return new VP10Encoder(cfg, deadline, init_flags, stats);
|
|
||||||
#else
|
|
||||||
return NULL;
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
virtual vpx_codec_err_t DefaultEncoderConfig(vpx_codec_enc_cfg_t *cfg,
|
|
||||||
int usage) const {
|
|
||||||
#if CONFIG_VP10_ENCODER
|
|
||||||
return vpx_codec_enc_config_default(&vpx_codec_vp10_cx_algo, cfg, usage);
|
|
||||||
#else
|
|
||||||
return VPX_CODEC_INCAPABLE;
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
const libvpx_test::VP10CodecFactory kVP10;
|
|
||||||
|
|
||||||
#define VP10_INSTANTIATE_TEST_CASE(test, ...)\
|
|
||||||
INSTANTIATE_TEST_CASE_P(VP10, test, \
|
|
||||||
::testing::Combine( \
|
|
||||||
::testing::Values(static_cast<const libvpx_test::CodecFactory*>( \
|
|
||||||
&libvpx_test::kVP10)), \
|
|
||||||
__VA_ARGS__))
|
|
||||||
#else
|
|
||||||
#define VP10_INSTANTIATE_TEST_CASE(test, ...)
|
|
||||||
#endif // CONFIG_VP10
|
|
||||||
|
|
||||||
} // namespace libvpx_test
|
} // namespace libvpx_test
|
||||||
#endif // TEST_CODEC_FACTORY_H_
|
#endif // TEST_CODEC_FACTORY_H_
|
||||||
|
|||||||
@@ -15,11 +15,13 @@
|
|||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
|
|
||||||
class ConfigTest : public ::libvpx_test::EncoderTest,
|
class ConfigTest
|
||||||
|
: public ::libvpx_test::EncoderTest,
|
||||||
public ::libvpx_test::CodecTestWithParam<libvpx_test::TestMode> {
|
public ::libvpx_test::CodecTestWithParam<libvpx_test::TestMode> {
|
||||||
protected:
|
protected:
|
||||||
ConfigTest() : EncoderTest(GET_PARAM(0)),
|
ConfigTest()
|
||||||
frame_count_in_(0), frame_count_out_(0), frame_count_max_(0) {}
|
: EncoderTest(GET_PARAM(0)), frame_count_in_(0), frame_count_out_(0),
|
||||||
|
frame_count_max_(0) {}
|
||||||
virtual ~ConfigTest() {}
|
virtual ~ConfigTest() {}
|
||||||
|
|
||||||
virtual void SetUp() {
|
virtual void SetUp() {
|
||||||
|
|||||||
@@ -26,11 +26,9 @@
|
|||||||
#include "vpx_dsp/ssim.h"
|
#include "vpx_dsp/ssim.h"
|
||||||
#include "vpx_mem/vpx_mem.h"
|
#include "vpx_mem/vpx_mem.h"
|
||||||
|
|
||||||
extern "C"
|
extern "C" double vpx_get_ssim_metrics(uint8_t *img1, int img1_pitch,
|
||||||
double vpx_get_ssim_metrics(uint8_t *img1, int img1_pitch,
|
uint8_t *img2, int img2_pitch, int width,
|
||||||
uint8_t *img2, int img2_pitch,
|
int height, Ssimv *sv2, Metrics *m,
|
||||||
int width, int height,
|
|
||||||
Ssimv *sv2, Metrics *m,
|
|
||||||
int do_inconsistency);
|
int do_inconsistency);
|
||||||
|
|
||||||
using libvpx_test::ACMRandom;
|
using libvpx_test::ACMRandom;
|
||||||
@@ -52,9 +50,7 @@ class ConsistencyTestBase : public ::testing::Test {
|
|||||||
ssim_array_ = new Ssimv[kDataBufferSize / 16];
|
ssim_array_ = new Ssimv[kDataBufferSize / 16];
|
||||||
}
|
}
|
||||||
|
|
||||||
static void ClearSsim() {
|
static void ClearSsim() { memset(ssim_array_, 0, kDataBufferSize / 16); }
|
||||||
memset(ssim_array_, 0, kDataBufferSize / 16);
|
|
||||||
}
|
|
||||||
static void TearDownTestCase() {
|
static void TearDownTestCase() {
|
||||||
vpx_free(source_data_[0]);
|
vpx_free(source_data_[0]);
|
||||||
source_data_[0] = NULL;
|
source_data_[0] = NULL;
|
||||||
@@ -68,9 +64,7 @@ class ConsistencyTestBase : public ::testing::Test {
|
|||||||
delete[] ssim_array_;
|
delete[] ssim_array_;
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual void TearDown() {
|
virtual void TearDown() { libvpx_test::ClearSystemState(); }
|
||||||
libvpx_test::ClearSystemState();
|
|
||||||
}
|
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
// Handle frames up to 640x480
|
// Handle frames up to 640x480
|
||||||
@@ -143,8 +137,7 @@ class ConsistencyVP9Test
|
|||||||
protected:
|
protected:
|
||||||
double CheckConsistency(int frame) {
|
double CheckConsistency(int frame) {
|
||||||
EXPECT_LT(frame, 2) << "Frame to check has to be less than 2.";
|
EXPECT_LT(frame, 2) << "Frame to check has to be less than 2.";
|
||||||
return
|
return vpx_get_ssim_metrics(source_data_[frame], source_stride_,
|
||||||
vpx_get_ssim_metrics(source_data_[frame], source_stride_,
|
|
||||||
reference_data_[frame], reference_stride_,
|
reference_data_[frame], reference_stride_,
|
||||||
width_, height_, ssim_array_, &metrics_, 1);
|
width_, height_, ssim_array_, &metrics_, 1);
|
||||||
}
|
}
|
||||||
@@ -205,7 +198,6 @@ TEST_P(ConsistencyVP9Test, ConsistencyIsZero) {
|
|||||||
}
|
}
|
||||||
#endif // CONFIG_VP9_ENCODER
|
#endif // CONFIG_VP9_ENCODER
|
||||||
|
|
||||||
|
|
||||||
using std::tr1::make_tuple;
|
using std::tr1::make_tuple;
|
||||||
|
|
||||||
//------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------
|
||||||
@@ -213,9 +205,7 @@ using std::tr1::make_tuple;
|
|||||||
|
|
||||||
#if CONFIG_VP9_ENCODER
|
#if CONFIG_VP9_ENCODER
|
||||||
const ConsistencyParam c_vp9_tests[] = {
|
const ConsistencyParam c_vp9_tests[] = {
|
||||||
make_tuple(320, 240),
|
make_tuple(320, 240), make_tuple(318, 242), make_tuple(318, 238),
|
||||||
make_tuple(318, 242),
|
|
||||||
make_tuple(318, 238),
|
|
||||||
};
|
};
|
||||||
INSTANTIATE_TEST_CASE_P(C, ConsistencyVP9Test,
|
INSTANTIATE_TEST_CASE_P(C, ConsistencyVP9Test,
|
||||||
::testing::ValuesIn(c_vp9_tests));
|
::testing::ValuesIn(c_vp9_tests));
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@@ -23,10 +23,8 @@ class CpuSpeedTest
|
|||||||
public ::libvpx_test::CodecTestWith2Params<libvpx_test::TestMode, int> {
|
public ::libvpx_test::CodecTestWith2Params<libvpx_test::TestMode, int> {
|
||||||
protected:
|
protected:
|
||||||
CpuSpeedTest()
|
CpuSpeedTest()
|
||||||
: EncoderTest(GET_PARAM(0)),
|
: EncoderTest(GET_PARAM(0)), encoding_mode_(GET_PARAM(1)),
|
||||||
encoding_mode_(GET_PARAM(1)),
|
set_cpu_used_(GET_PARAM(2)), min_psnr_(kMaxPSNR),
|
||||||
set_cpu_used_(GET_PARAM(2)),
|
|
||||||
min_psnr_(kMaxPSNR),
|
|
||||||
tune_content_(VP9E_CONTENT_DEFAULT) {}
|
tune_content_(VP9E_CONTENT_DEFAULT) {}
|
||||||
virtual ~CpuSpeedTest() {}
|
virtual ~CpuSpeedTest() {}
|
||||||
|
|
||||||
@@ -42,9 +40,7 @@ class CpuSpeedTest
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual void BeginPassHook(unsigned int /*pass*/) {
|
virtual void BeginPassHook(unsigned int /*pass*/) { min_psnr_ = kMaxPSNR; }
|
||||||
min_psnr_ = kMaxPSNR;
|
|
||||||
}
|
|
||||||
|
|
||||||
virtual void PreEncodeFrameHook(::libvpx_test::VideoSource *video,
|
virtual void PreEncodeFrameHook(::libvpx_test::VideoSource *video,
|
||||||
::libvpx_test::Encoder *encoder) {
|
::libvpx_test::Encoder *encoder) {
|
||||||
@@ -61,8 +57,7 @@ class CpuSpeedTest
|
|||||||
}
|
}
|
||||||
|
|
||||||
virtual void PSNRPktHook(const vpx_codec_cx_pkt_t *pkt) {
|
virtual void PSNRPktHook(const vpx_codec_cx_pkt_t *pkt) {
|
||||||
if (pkt->data.psnr.psnr[0] < min_psnr_)
|
if (pkt->data.psnr.psnr[0] < min_psnr_) min_psnr_ = pkt->data.psnr.psnr[0];
|
||||||
min_psnr_ = pkt->data.psnr.psnr[0];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
::libvpx_test::TestMode encoding_mode_;
|
::libvpx_test::TestMode encoding_mode_;
|
||||||
@@ -153,14 +148,9 @@ TEST_P(CpuSpeedTest, TestLowBitrate) {
|
|||||||
ASSERT_NO_FATAL_FAILURE(RunLoop(&video));
|
ASSERT_NO_FATAL_FAILURE(RunLoop(&video));
|
||||||
}
|
}
|
||||||
|
|
||||||
VP9_INSTANTIATE_TEST_CASE(
|
VP9_INSTANTIATE_TEST_CASE(CpuSpeedTest,
|
||||||
CpuSpeedTest,
|
::testing::Values(::libvpx_test::kTwoPassGood,
|
||||||
::testing::Values(::libvpx_test::kTwoPassGood, ::libvpx_test::kOnePassGood,
|
::libvpx_test::kOnePassGood,
|
||||||
::libvpx_test::kRealTime),
|
::libvpx_test::kRealTime),
|
||||||
::testing::Range(0, 9));
|
::testing::Range(0, 9));
|
||||||
|
|
||||||
VP10_INSTANTIATE_TEST_CASE(
|
|
||||||
CpuSpeedTest,
|
|
||||||
::testing::Values(::libvpx_test::kTwoPassGood, ::libvpx_test::kOnePassGood),
|
|
||||||
::testing::Range(0, 3));
|
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|||||||
@@ -29,9 +29,7 @@ class CQTest : public ::libvpx_test::EncoderTest,
|
|||||||
// maps the cqlevel to the bitrate produced.
|
// maps the cqlevel to the bitrate produced.
|
||||||
typedef std::map<int, uint32_t> BitrateMap;
|
typedef std::map<int, uint32_t> BitrateMap;
|
||||||
|
|
||||||
static void SetUpTestCase() {
|
static void SetUpTestCase() { bitrates_.clear(); }
|
||||||
bitrates_.clear();
|
|
||||||
}
|
|
||||||
|
|
||||||
static void TearDownTestCase() {
|
static void TearDownTestCase() {
|
||||||
ASSERT_TRUE(!HasFailure())
|
ASSERT_TRUE(!HasFailure())
|
||||||
@@ -128,7 +126,6 @@ TEST_P(CQTest, LinearPSNRIsHigherForCQLevel) {
|
|||||||
EXPECT_GE(cq_psnr_lin, vbr_psnr_lin);
|
EXPECT_GE(cq_psnr_lin, vbr_psnr_lin);
|
||||||
}
|
}
|
||||||
|
|
||||||
VP8_INSTANTIATE_TEST_CASE(CQTest,
|
VP8_INSTANTIATE_TEST_CASE(CQTest, ::testing::Range(kCQLevelMin, kCQLevelMax,
|
||||||
::testing::Range(kCQLevelMin, kCQLevelMax,
|
|
||||||
kCQLevelStep));
|
kCQLevelStep));
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
#!/bin/sh
|
#!/bin/sh
|
||||||
##
|
##
|
||||||
## Copyright (c) 2014 The WebM project authors. All Rights Reserved.
|
## Copyright (c) 2016 The WebM project authors. All Rights Reserved.
|
||||||
##
|
##
|
||||||
## Use of this source code is governed by a BSD-style license
|
## Use of this source code is governed by a BSD-style license
|
||||||
## that can be found in the LICENSE file in the root of the source
|
## that can be found in the LICENSE file in the root of the source
|
||||||
@@ -8,30 +8,27 @@
|
|||||||
## in the file PATENTS. All contributing project authors may
|
## in the file PATENTS. All contributing project authors may
|
||||||
## be found in the AUTHORS file in the root of the source tree.
|
## be found in the AUTHORS file in the root of the source tree.
|
||||||
##
|
##
|
||||||
## This file tests the libvpx vp8cx_set_ref example. To add new tests to this
|
## This file tests the libvpx cx_set_ref example. To add new tests to this
|
||||||
## file, do the following:
|
## file, do the following:
|
||||||
## 1. Write a shell function (this is your test).
|
## 1. Write a shell function (this is your test).
|
||||||
## 2. Add the function to vp8cx_set_ref_tests (on a new line).
|
## 2. Add the function to cx_set_ref_tests (on a new line).
|
||||||
##
|
##
|
||||||
. $(dirname $0)/tools_common.sh
|
. $(dirname $0)/tools_common.sh
|
||||||
|
|
||||||
# Environment check: $YUV_RAW_INPUT is required.
|
# Environment check: $YUV_RAW_INPUT is required.
|
||||||
vp8cx_set_ref_verify_environment() {
|
cx_set_ref_verify_environment() {
|
||||||
if [ ! -e "${YUV_RAW_INPUT}" ]; then
|
if [ ! -e "${YUV_RAW_INPUT}" ]; then
|
||||||
echo "Libvpx test data must exist in LIBVPX_TEST_DATA_PATH."
|
echo "Libvpx test data must exist in LIBVPX_TEST_DATA_PATH."
|
||||||
return 1
|
return 1
|
||||||
fi
|
fi
|
||||||
}
|
}
|
||||||
|
|
||||||
# Runs vp8cx_set_ref and updates the reference frame before encoding frame 90.
|
# Runs cx_set_ref and updates the reference frame before encoding frame 90.
|
||||||
# $1 is the codec name, which vp8cx_set_ref does not support at present: It's
|
# $1 is the codec name.
|
||||||
# currently used only to name the output file.
|
|
||||||
# TODO(tomfinegan): Pass the codec param once the example is updated to support
|
|
||||||
# VP9.
|
|
||||||
vpx_set_ref() {
|
vpx_set_ref() {
|
||||||
local encoder="${LIBVPX_BIN_PATH}/vp8cx_set_ref${VPX_TEST_EXE_SUFFIX}"
|
|
||||||
local codec="$1"
|
local codec="$1"
|
||||||
local output_file="${VPX_TEST_OUTPUT_DIR}/vp8cx_set_ref_${codec}.ivf"
|
local encoder="${LIBVPX_BIN_PATH}/${codec}cx_set_ref${VPX_TEST_EXE_SUFFIX}"
|
||||||
|
local output_file="${VPX_TEST_OUTPUT_DIR}/${codec}cx_set_ref_${codec}.ivf"
|
||||||
local ref_frame_num=90
|
local ref_frame_num=90
|
||||||
|
|
||||||
if [ ! -x "${encoder}" ]; then
|
if [ ! -x "${encoder}" ]; then
|
||||||
@@ -46,12 +43,18 @@ vpx_set_ref() {
|
|||||||
[ -e "${output_file}" ] || return 1
|
[ -e "${output_file}" ] || return 1
|
||||||
}
|
}
|
||||||
|
|
||||||
vp8cx_set_ref_vp8() {
|
cx_set_ref_vp8() {
|
||||||
if [ "$(vp8_encode_available)" = "yes" ]; then
|
if [ "$(vp8_encode_available)" = "yes" ]; then
|
||||||
vpx_set_ref vp8 || return 1
|
vpx_set_ref vp8 || return 1
|
||||||
fi
|
fi
|
||||||
}
|
}
|
||||||
|
|
||||||
vp8cx_set_ref_tests="vp8cx_set_ref_vp8"
|
cx_set_ref_vp9() {
|
||||||
|
if [ "$(vp9_encode_available)" = "yes" ]; then
|
||||||
|
vpx_set_ref vp9 || return 1
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
run_tests vp8cx_set_ref_verify_environment "${vp8cx_set_ref_tests}"
|
cx_set_ref_tests="cx_set_ref_vp8 cx_set_ref_vp9"
|
||||||
|
|
||||||
|
run_tests cx_set_ref_verify_environment "${cx_set_ref_tests}"
|
||||||
@@ -18,8 +18,9 @@
|
|||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
|
|
||||||
class DatarateTestLarge : public ::libvpx_test::EncoderTest,
|
class DatarateTestLarge
|
||||||
public ::libvpx_test::CodecTestWithParam<libvpx_test::TestMode> {
|
: public ::libvpx_test::EncoderTest,
|
||||||
|
public ::libvpx_test::CodecTestWith2Params<libvpx_test::TestMode, int> {
|
||||||
public:
|
public:
|
||||||
DatarateTestLarge() : EncoderTest(GET_PARAM(0)) {}
|
DatarateTestLarge() : EncoderTest(GET_PARAM(0)) {}
|
||||||
|
|
||||||
@@ -29,6 +30,7 @@ class DatarateTestLarge : public ::libvpx_test::EncoderTest,
|
|||||||
virtual void SetUp() {
|
virtual void SetUp() {
|
||||||
InitializeConfig();
|
InitializeConfig();
|
||||||
SetMode(GET_PARAM(1));
|
SetMode(GET_PARAM(1));
|
||||||
|
set_cpu_used_ = GET_PARAM(2);
|
||||||
ResetModel();
|
ResetModel();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -41,12 +43,16 @@ class DatarateTestLarge : public ::libvpx_test::EncoderTest,
|
|||||||
duration_ = 0.0;
|
duration_ = 0.0;
|
||||||
denoiser_offon_test_ = 0;
|
denoiser_offon_test_ = 0;
|
||||||
denoiser_offon_period_ = -1;
|
denoiser_offon_period_ = -1;
|
||||||
|
gf_boost_ = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual void PreEncodeFrameHook(::libvpx_test::VideoSource *video,
|
virtual void PreEncodeFrameHook(::libvpx_test::VideoSource *video,
|
||||||
::libvpx_test::Encoder *encoder) {
|
::libvpx_test::Encoder *encoder) {
|
||||||
if (video->frame() == 0)
|
if (video->frame() == 0) {
|
||||||
encoder->Control(VP8E_SET_NOISE_SENSITIVITY, denoiser_on_);
|
encoder->Control(VP8E_SET_NOISE_SENSITIVITY, denoiser_on_);
|
||||||
|
encoder->Control(VP8E_SET_CPUUSED, set_cpu_used_);
|
||||||
|
encoder->Control(VP8E_SET_GF_CBR_BOOST_PCT, gf_boost_);
|
||||||
|
}
|
||||||
|
|
||||||
if (denoiser_offon_test_) {
|
if (denoiser_offon_test_) {
|
||||||
ASSERT_GT(denoiser_offon_period_, 0)
|
ASSERT_GT(denoiser_offon_period_, 0)
|
||||||
@@ -71,8 +77,7 @@ class DatarateTestLarge : public ::libvpx_test::EncoderTest,
|
|||||||
// http://code.google.com/p/webm/issues/detail?id=496 is fixed.
|
// http://code.google.com/p/webm/issues/detail?id=496 is fixed.
|
||||||
// For now the codec assumes buffer starts at starting buffer rate
|
// For now the codec assumes buffer starts at starting buffer rate
|
||||||
// plus one frame's time.
|
// plus one frame's time.
|
||||||
if (last_pts_ == 0)
|
if (last_pts_ == 0) duration = 1;
|
||||||
duration = 1;
|
|
||||||
|
|
||||||
// Add to the buffer the bits we'd expect from a constant bitrate server.
|
// Add to the buffer the bits we'd expect from a constant bitrate server.
|
||||||
bits_in_buffer_model_ += static_cast<int64_t>(
|
bits_in_buffer_model_ += static_cast<int64_t>(
|
||||||
@@ -83,14 +88,14 @@ class DatarateTestLarge : public ::libvpx_test::EncoderTest,
|
|||||||
* empty - and then stop showing frames until we've got enough bits to
|
* empty - and then stop showing frames until we've got enough bits to
|
||||||
* show one. As noted in comment below (issue 495), this does not currently
|
* show one. As noted in comment below (issue 495), this does not currently
|
||||||
* apply to key frames. For now exclude key frames in condition below. */
|
* apply to key frames. For now exclude key frames in condition below. */
|
||||||
const bool key_frame = (pkt->data.frame.flags & VPX_FRAME_IS_KEY)
|
const bool key_frame =
|
||||||
? true: false;
|
(pkt->data.frame.flags & VPX_FRAME_IS_KEY) ? true : false;
|
||||||
if (!key_frame) {
|
if (!key_frame) {
|
||||||
ASSERT_GE(bits_in_buffer_model_, 0) << "Buffer Underrun at frame "
|
ASSERT_GE(bits_in_buffer_model_, 0) << "Buffer Underrun at frame "
|
||||||
<< pkt->data.frame.pts;
|
<< pkt->data.frame.pts;
|
||||||
}
|
}
|
||||||
|
|
||||||
const size_t frame_size_in_bits = pkt->data.frame.sz * 8;
|
const int64_t frame_size_in_bits = pkt->data.frame.sz * 8;
|
||||||
|
|
||||||
// Subtract from the buffer the bits associated with a played back frame.
|
// Subtract from the buffer the bits associated with a played back frame.
|
||||||
bits_in_buffer_model_ -= frame_size_in_bits;
|
bits_in_buffer_model_ -= frame_size_in_bits;
|
||||||
@@ -99,8 +104,7 @@ class DatarateTestLarge : public ::libvpx_test::EncoderTest,
|
|||||||
bits_total_ += frame_size_in_bits;
|
bits_total_ += frame_size_in_bits;
|
||||||
|
|
||||||
// If first drop not set and we have a drop set it to this time.
|
// If first drop not set and we have a drop set it to this time.
|
||||||
if (!first_drop_ && duration > 1)
|
if (!first_drop_ && duration > 1) first_drop_ = last_pts_ + 1;
|
||||||
first_drop_ = last_pts_ + 1;
|
|
||||||
|
|
||||||
// Update the most recent pts.
|
// Update the most recent pts.
|
||||||
last_pts_ = pkt->data.frame.pts;
|
last_pts_ = pkt->data.frame.pts;
|
||||||
@@ -119,8 +123,8 @@ class DatarateTestLarge : public ::libvpx_test::EncoderTest,
|
|||||||
duration_ = (last_pts_ + 1) * timebase_;
|
duration_ = (last_pts_ + 1) * timebase_;
|
||||||
|
|
||||||
// Effective file datarate includes the time spent prebuffering.
|
// Effective file datarate includes the time spent prebuffering.
|
||||||
effective_datarate_ = (bits_total_ - bits_in_last_frame_) / 1000.0
|
effective_datarate_ = (bits_total_ - bits_in_last_frame_) / 1000.0 /
|
||||||
/ (cfg_.rc_buf_initial_sz / 1000.0 + duration_);
|
(cfg_.rc_buf_initial_sz / 1000.0 + duration_);
|
||||||
|
|
||||||
file_datarate_ = file_size_in_kb / duration_;
|
file_datarate_ = file_size_in_kb / duration_;
|
||||||
}
|
}
|
||||||
@@ -135,10 +139,12 @@ class DatarateTestLarge : public ::libvpx_test::EncoderTest,
|
|||||||
double duration_;
|
double duration_;
|
||||||
double file_datarate_;
|
double file_datarate_;
|
||||||
double effective_datarate_;
|
double effective_datarate_;
|
||||||
size_t bits_in_last_frame_;
|
int64_t bits_in_last_frame_;
|
||||||
int denoiser_on_;
|
int denoiser_on_;
|
||||||
int denoiser_offon_test_;
|
int denoiser_offon_test_;
|
||||||
int denoiser_offon_period_;
|
int denoiser_offon_period_;
|
||||||
|
int set_cpu_used_;
|
||||||
|
int gf_boost_;
|
||||||
};
|
};
|
||||||
|
|
||||||
#if CONFIG_TEMPORAL_DENOISING
|
#if CONFIG_TEMPORAL_DENOISING
|
||||||
@@ -156,9 +162,6 @@ TEST_P(DatarateTestLarge, DenoiserLevels) {
|
|||||||
// For the temporal denoiser (#if CONFIG_TEMPORAL_DENOISING) the level j
|
// For the temporal denoiser (#if CONFIG_TEMPORAL_DENOISING) the level j
|
||||||
// refers to the 4 denoiser modes: denoiserYonly, denoiserOnYUV,
|
// refers to the 4 denoiser modes: denoiserYonly, denoiserOnYUV,
|
||||||
// denoiserOnAggressive, and denoiserOnAdaptive.
|
// denoiserOnAggressive, and denoiserOnAdaptive.
|
||||||
// For the spatial denoiser (if !CONFIG_TEMPORAL_DENOISING), the level j
|
|
||||||
// refers to the blur thresholds: 20, 40, 60 80.
|
|
||||||
// The j = 0 case (denoiser off) is covered in the tests below.
|
|
||||||
denoiser_on_ = j;
|
denoiser_on_ = j;
|
||||||
cfg_.rc_target_bitrate = 300;
|
cfg_.rc_target_bitrate = 300;
|
||||||
ResetModel();
|
ResetModel();
|
||||||
@@ -166,7 +169,7 @@ TEST_P(DatarateTestLarge, DenoiserLevels) {
|
|||||||
ASSERT_GE(cfg_.rc_target_bitrate, effective_datarate_ * 0.95)
|
ASSERT_GE(cfg_.rc_target_bitrate, effective_datarate_ * 0.95)
|
||||||
<< " The datarate for the file exceeds the target!";
|
<< " The datarate for the file exceeds the target!";
|
||||||
|
|
||||||
ASSERT_LE(cfg_.rc_target_bitrate, file_datarate_ * 1.3)
|
ASSERT_LE(cfg_.rc_target_bitrate, file_datarate_ * 1.4)
|
||||||
<< " The datarate for the file missed the target!";
|
<< " The datarate for the file missed the target!";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -190,7 +193,7 @@ TEST_P(DatarateTestLarge, DenoiserOffOn) {
|
|||||||
ASSERT_NO_FATAL_FAILURE(RunLoop(&video));
|
ASSERT_NO_FATAL_FAILURE(RunLoop(&video));
|
||||||
ASSERT_GE(cfg_.rc_target_bitrate, effective_datarate_ * 0.95)
|
ASSERT_GE(cfg_.rc_target_bitrate, effective_datarate_ * 0.95)
|
||||||
<< " The datarate for the file exceeds the target!";
|
<< " The datarate for the file exceeds the target!";
|
||||||
ASSERT_LE(cfg_.rc_target_bitrate, file_datarate_ * 1.3)
|
ASSERT_LE(cfg_.rc_target_bitrate, file_datarate_ * 1.4)
|
||||||
<< " The datarate for the file missed the target!";
|
<< " The datarate for the file missed the target!";
|
||||||
}
|
}
|
||||||
#endif // CONFIG_TEMPORAL_DENOISING
|
#endif // CONFIG_TEMPORAL_DENOISING
|
||||||
@@ -221,8 +224,7 @@ TEST_P(DatarateTestLarge, BasicBufferModel) {
|
|||||||
ASSERT_NO_FATAL_FAILURE(RunLoop(&video));
|
ASSERT_NO_FATAL_FAILURE(RunLoop(&video));
|
||||||
ASSERT_GE(cfg_.rc_target_bitrate, effective_datarate_ * 0.95)
|
ASSERT_GE(cfg_.rc_target_bitrate, effective_datarate_ * 0.95)
|
||||||
<< " The datarate for the file exceeds the target!";
|
<< " The datarate for the file exceeds the target!";
|
||||||
|
ASSERT_LE(cfg_.rc_target_bitrate, file_datarate_ * 1.4)
|
||||||
ASSERT_LE(cfg_.rc_target_bitrate, file_datarate_ * 1.3)
|
|
||||||
<< " The datarate for the file missed the target!";
|
<< " The datarate for the file missed the target!";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -256,7 +258,201 @@ TEST_P(DatarateTestLarge, ChangingDropFrameThresh) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class DatarateTestVP9Large : public ::libvpx_test::EncoderTest,
|
// 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;
|
||||||
|
cfg_.rc_dropframe_thresh = 30;
|
||||||
|
cfg_.rc_max_quantizer = 56;
|
||||||
|
cfg_.rc_end_usage = VPX_CBR;
|
||||||
|
cfg_.g_threads = 2;
|
||||||
|
|
||||||
|
::libvpx_test::I420VideoSource video("hantro_collage_w352h288.yuv", 352, 288,
|
||||||
|
30, 1, 0, 140);
|
||||||
|
cfg_.rc_target_bitrate = 200;
|
||||||
|
ResetModel();
|
||||||
|
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!";
|
||||||
|
}
|
||||||
|
#endif // !BUILDING_WITH_TSAN
|
||||||
|
|
||||||
|
class DatarateTestRealTime : public DatarateTestLarge {
|
||||||
|
public:
|
||||||
|
virtual ~DatarateTestRealTime() {}
|
||||||
|
};
|
||||||
|
|
||||||
|
#if CONFIG_TEMPORAL_DENOISING
|
||||||
|
// Check basic datarate targeting, for a single bitrate, but loop over the
|
||||||
|
// various denoiser settings.
|
||||||
|
TEST_P(DatarateTestRealTime, DenoiserLevels) {
|
||||||
|
cfg_.rc_buf_initial_sz = 500;
|
||||||
|
cfg_.rc_dropframe_thresh = 1;
|
||||||
|
cfg_.rc_max_quantizer = 56;
|
||||||
|
cfg_.rc_end_usage = VPX_CBR;
|
||||||
|
::libvpx_test::I420VideoSource video("hantro_collage_w352h288.yuv", 352, 288,
|
||||||
|
30, 1, 0, 140);
|
||||||
|
for (int j = 1; j < 5; ++j) {
|
||||||
|
// Run over the denoiser levels.
|
||||||
|
// For the temporal denoiser (#if CONFIG_TEMPORAL_DENOISING) the level j
|
||||||
|
// refers to the 4 denoiser modes: denoiserYonly, denoiserOnYUV,
|
||||||
|
// denoiserOnAggressive, and denoiserOnAdaptive.
|
||||||
|
denoiser_on_ = j;
|
||||||
|
cfg_.rc_target_bitrate = 300;
|
||||||
|
ResetModel();
|
||||||
|
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!";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check basic datarate targeting, for a single bitrate, when denoiser is off
|
||||||
|
// and on.
|
||||||
|
TEST_P(DatarateTestRealTime, DenoiserOffOn) {
|
||||||
|
cfg_.rc_buf_initial_sz = 500;
|
||||||
|
cfg_.rc_dropframe_thresh = 1;
|
||||||
|
cfg_.rc_max_quantizer = 56;
|
||||||
|
cfg_.rc_end_usage = VPX_CBR;
|
||||||
|
::libvpx_test::I420VideoSource video("hantro_collage_w352h288.yuv", 352, 288,
|
||||||
|
30, 1, 0, 299);
|
||||||
|
cfg_.rc_target_bitrate = 300;
|
||||||
|
ResetModel();
|
||||||
|
// The denoiser is off by default.
|
||||||
|
denoiser_on_ = 0;
|
||||||
|
// Set the offon test flag.
|
||||||
|
denoiser_offon_test_ = 1;
|
||||||
|
denoiser_offon_period_ = 100;
|
||||||
|
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!";
|
||||||
|
}
|
||||||
|
#endif // CONFIG_TEMPORAL_DENOISING
|
||||||
|
|
||||||
|
TEST_P(DatarateTestRealTime, BasicBufferModel) {
|
||||||
|
denoiser_on_ = 0;
|
||||||
|
cfg_.rc_buf_initial_sz = 500;
|
||||||
|
cfg_.rc_dropframe_thresh = 1;
|
||||||
|
cfg_.rc_max_quantizer = 56;
|
||||||
|
cfg_.rc_end_usage = VPX_CBR;
|
||||||
|
// 2 pass cbr datarate control has a bug hidden by the small # of
|
||||||
|
// frames selected in this encode. The problem is that even if the buffer is
|
||||||
|
// negative we produce a keyframe on a cutscene, ignoring datarate
|
||||||
|
// constraints
|
||||||
|
// TODO(jimbankoski): Fix when issue
|
||||||
|
// http://bugs.chromium.org/p/webm/issues/detail?id=495 is addressed.
|
||||||
|
::libvpx_test::I420VideoSource video("hantro_collage_w352h288.yuv", 352, 288,
|
||||||
|
30, 1, 0, 140);
|
||||||
|
|
||||||
|
// There is an issue for low bitrates in real-time mode, where the
|
||||||
|
// effective_datarate slightly overshoots the target bitrate.
|
||||||
|
// This is same the issue as noted above (#495).
|
||||||
|
// TODO(jimbankoski/marpan): Update test to run for lower bitrates (< 100),
|
||||||
|
// when the issue is resolved.
|
||||||
|
for (int i = 100; i <= 700; i += 200) {
|
||||||
|
cfg_.rc_target_bitrate = i;
|
||||||
|
ResetModel();
|
||||||
|
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!";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_P(DatarateTestRealTime, ChangingDropFrameThresh) {
|
||||||
|
denoiser_on_ = 0;
|
||||||
|
cfg_.rc_buf_initial_sz = 500;
|
||||||
|
cfg_.rc_max_quantizer = 36;
|
||||||
|
cfg_.rc_end_usage = VPX_CBR;
|
||||||
|
cfg_.rc_target_bitrate = 200;
|
||||||
|
cfg_.kf_mode = VPX_KF_DISABLED;
|
||||||
|
|
||||||
|
const int frame_count = 40;
|
||||||
|
::libvpx_test::I420VideoSource video("hantro_collage_w352h288.yuv", 352, 288,
|
||||||
|
30, 1, 0, frame_count);
|
||||||
|
|
||||||
|
// Check that the first dropped frame gets earlier and earlier
|
||||||
|
// as the drop frame threshold is increased.
|
||||||
|
|
||||||
|
const int kDropFrameThreshTestStep = 30;
|
||||||
|
vpx_codec_pts_t last_drop = frame_count;
|
||||||
|
for (int i = 1; i < 91; i += kDropFrameThreshTestStep) {
|
||||||
|
cfg_.rc_dropframe_thresh = i;
|
||||||
|
ResetModel();
|
||||||
|
ASSERT_NO_FATAL_FAILURE(RunLoop(&video));
|
||||||
|
ASSERT_LE(first_drop_, last_drop)
|
||||||
|
<< " The first dropped frame for drop_thresh " << i
|
||||||
|
<< " > first dropped frame for drop_thresh "
|
||||||
|
<< i - kDropFrameThreshTestStep;
|
||||||
|
last_drop = first_drop_;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 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;
|
||||||
|
cfg_.rc_dropframe_thresh = 30;
|
||||||
|
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, 140);
|
||||||
|
cfg_.rc_target_bitrate = 200;
|
||||||
|
ResetModel();
|
||||||
|
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!";
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
TEST_P(DatarateTestRealTime, GFBoost) {
|
||||||
|
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;
|
||||||
|
cfg_.g_error_resilient = 0;
|
||||||
|
|
||||||
|
::libvpx_test::I420VideoSource video("hantro_collage_w352h288.yuv", 352, 288,
|
||||||
|
30, 1, 0, 300);
|
||||||
|
cfg_.rc_target_bitrate = 300;
|
||||||
|
ResetModel();
|
||||||
|
// Apply a gf boost.
|
||||||
|
gf_boost_ = 50;
|
||||||
|
|
||||||
|
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!";
|
||||||
|
}
|
||||||
|
|
||||||
|
class DatarateTestVP9Large
|
||||||
|
: public ::libvpx_test::EncoderTest,
|
||||||
public ::libvpx_test::CodecTestWith2Params<libvpx_test::TestMode, int> {
|
public ::libvpx_test::CodecTestWith2Params<libvpx_test::TestMode, int> {
|
||||||
public:
|
public:
|
||||||
DatarateTestVP9Large() : EncoderTest(GET_PARAM(0)) {}
|
DatarateTestVP9Large() : EncoderTest(GET_PARAM(0)) {}
|
||||||
@@ -307,8 +503,8 @@ class DatarateTestVP9Large : public ::libvpx_test::EncoderTest,
|
|||||||
if (num_temp_layers == 2) {
|
if (num_temp_layers == 2) {
|
||||||
if (frame_num % 2 == 0) {
|
if (frame_num % 2 == 0) {
|
||||||
// Layer 0: predict from L and ARF, update L.
|
// Layer 0: predict from L and ARF, update L.
|
||||||
frame_flags = VP8_EFLAG_NO_REF_GF | VP8_EFLAG_NO_UPD_GF |
|
frame_flags =
|
||||||
VP8_EFLAG_NO_UPD_ARF;
|
VP8_EFLAG_NO_REF_GF | VP8_EFLAG_NO_UPD_GF | VP8_EFLAG_NO_UPD_ARF;
|
||||||
} else {
|
} else {
|
||||||
// Layer 1: predict from L, G and ARF, and update G.
|
// Layer 1: predict from L, G and ARF, and update G.
|
||||||
frame_flags = VP8_EFLAG_NO_UPD_ARF | VP8_EFLAG_NO_UPD_LAST |
|
frame_flags = VP8_EFLAG_NO_UPD_ARF | VP8_EFLAG_NO_UPD_LAST |
|
||||||
@@ -317,15 +513,15 @@ class DatarateTestVP9Large : public ::libvpx_test::EncoderTest,
|
|||||||
} else if (num_temp_layers == 3) {
|
} else if (num_temp_layers == 3) {
|
||||||
if (frame_num % 4 == 0) {
|
if (frame_num % 4 == 0) {
|
||||||
// Layer 0: predict from L and ARF; update L.
|
// Layer 0: predict from L and ARF; update L.
|
||||||
frame_flags = VP8_EFLAG_NO_UPD_GF | VP8_EFLAG_NO_UPD_ARF |
|
frame_flags =
|
||||||
VP8_EFLAG_NO_REF_GF;
|
VP8_EFLAG_NO_UPD_GF | VP8_EFLAG_NO_UPD_ARF | VP8_EFLAG_NO_REF_GF;
|
||||||
} else if ((frame_num - 2) % 4 == 0) {
|
} else if ((frame_num - 2) % 4 == 0) {
|
||||||
// Layer 1: predict from L, G, ARF; update G.
|
// Layer 1: predict from L, G, ARF; update G.
|
||||||
frame_flags = VP8_EFLAG_NO_UPD_ARF | VP8_EFLAG_NO_UPD_LAST;
|
frame_flags = VP8_EFLAG_NO_UPD_ARF | VP8_EFLAG_NO_UPD_LAST;
|
||||||
} else if ((frame_num - 1) % 2 == 0) {
|
} else if ((frame_num - 1) % 2 == 0) {
|
||||||
// Layer 2: predict from L, G, ARF; update none.
|
// Layer 2: predict from L, G, ARF; update none.
|
||||||
frame_flags = VP8_EFLAG_NO_UPD_GF | VP8_EFLAG_NO_UPD_ARF |
|
frame_flags =
|
||||||
VP8_EFLAG_NO_UPD_LAST;
|
VP8_EFLAG_NO_UPD_GF | VP8_EFLAG_NO_UPD_ARF | VP8_EFLAG_NO_UPD_LAST;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return frame_flags;
|
return frame_flags;
|
||||||
@@ -353,8 +549,7 @@ class DatarateTestVP9Large : public ::libvpx_test::EncoderTest,
|
|||||||
|
|
||||||
virtual void PreEncodeFrameHook(::libvpx_test::VideoSource *video,
|
virtual void PreEncodeFrameHook(::libvpx_test::VideoSource *video,
|
||||||
::libvpx_test::Encoder *encoder) {
|
::libvpx_test::Encoder *encoder) {
|
||||||
if (video->frame() == 0)
|
if (video->frame() == 0) encoder->Control(VP8E_SET_CPUUSED, set_cpu_used_);
|
||||||
encoder->Control(VP8E_SET_CPUUSED, set_cpu_used_);
|
|
||||||
|
|
||||||
if (denoiser_offon_test_) {
|
if (denoiser_offon_test_) {
|
||||||
ASSERT_GT(denoiser_offon_period_, 0)
|
ASSERT_GT(denoiser_offon_period_, 0)
|
||||||
@@ -374,8 +569,8 @@ class DatarateTestVP9Large : public ::libvpx_test::EncoderTest,
|
|||||||
vpx_svc_layer_id_t layer_id;
|
vpx_svc_layer_id_t layer_id;
|
||||||
layer_id.spatial_layer_id = 0;
|
layer_id.spatial_layer_id = 0;
|
||||||
frame_flags_ = SetFrameFlags(video->frame(), cfg_.ts_number_layers);
|
frame_flags_ = SetFrameFlags(video->frame(), cfg_.ts_number_layers);
|
||||||
layer_id.temporal_layer_id = SetLayerId(video->frame(),
|
layer_id.temporal_layer_id =
|
||||||
cfg_.ts_number_layers);
|
SetLayerId(video->frame(), cfg_.ts_number_layers);
|
||||||
encoder->Control(VP9E_SET_SVC_LAYER_ID, &layer_id);
|
encoder->Control(VP9E_SET_SVC_LAYER_ID, &layer_id);
|
||||||
}
|
}
|
||||||
const vpx_rational_t tb = video->timebase();
|
const vpx_rational_t tb = video->timebase();
|
||||||
@@ -383,15 +578,13 @@ class DatarateTestVP9Large : public ::libvpx_test::EncoderTest,
|
|||||||
duration_ = 0;
|
duration_ = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
virtual void FramePktHook(const vpx_codec_cx_pkt_t *pkt) {
|
virtual void FramePktHook(const vpx_codec_cx_pkt_t *pkt) {
|
||||||
// Time since last timestamp = duration.
|
// Time since last timestamp = duration.
|
||||||
vpx_codec_pts_t duration = pkt->data.frame.pts - last_pts_;
|
vpx_codec_pts_t duration = pkt->data.frame.pts - last_pts_;
|
||||||
|
|
||||||
if (duration > 1) {
|
if (duration > 1) {
|
||||||
// If first drop not set and we have a drop set it to this time.
|
// If first drop not set and we have a drop set it to this time.
|
||||||
if (!first_drop_)
|
if (!first_drop_) first_drop_ = last_pts_ + 1;
|
||||||
first_drop_ = last_pts_ + 1;
|
|
||||||
// Update the number of frame drops.
|
// Update the number of frame drops.
|
||||||
num_drops_ += static_cast<int>(duration - 1);
|
num_drops_ += static_cast<int>(duration - 1);
|
||||||
// Update counter for total number of frames (#frames input to encoder).
|
// Update counter for total number of frames (#frames input to encoder).
|
||||||
@@ -450,7 +643,55 @@ class DatarateTestVP9Large : public ::libvpx_test::EncoderTest,
|
|||||||
int denoiser_offon_period_;
|
int denoiser_offon_period_;
|
||||||
};
|
};
|
||||||
|
|
||||||
// Check basic rate targeting,
|
// Check basic rate targeting for VBR mode with 0 lag.
|
||||||
|
TEST_P(DatarateTestVP9Large, BasicRateTargetingVBRLagZero) {
|
||||||
|
cfg_.rc_min_quantizer = 0;
|
||||||
|
cfg_.rc_max_quantizer = 63;
|
||||||
|
cfg_.g_error_resilient = 0;
|
||||||
|
cfg_.rc_end_usage = VPX_VBR;
|
||||||
|
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();
|
||||||
|
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)
|
||||||
|
<< " The datarate for the file is greater than target by too much!";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check basic rate targeting for VBR mode with non-zero lag.
|
||||||
|
TEST_P(DatarateTestVP9Large, BasicRateTargetingVBRLagNonZero) {
|
||||||
|
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();
|
||||||
|
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)
|
||||||
|
<< " The datarate for the file is greater than target by too much!";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check basic rate targeting for CBR mode.
|
||||||
TEST_P(DatarateTestVP9Large, BasicRateTargeting) {
|
TEST_P(DatarateTestVP9Large, BasicRateTargeting) {
|
||||||
cfg_.rc_buf_initial_sz = 500;
|
cfg_.rc_buf_initial_sz = 500;
|
||||||
cfg_.rc_buf_optimal_sz = 500;
|
cfg_.rc_buf_optimal_sz = 500;
|
||||||
@@ -474,7 +715,31 @@ TEST_P(DatarateTestVP9Large, BasicRateTargeting) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check basic rate targeting,
|
// Check basic rate targeting for CBR mode, with 2 threads and dropped frames.
|
||||||
|
TEST_P(DatarateTestVP9Large, BasicRateTargetingDropFramesMultiThreads) {
|
||||||
|
cfg_.rc_buf_initial_sz = 500;
|
||||||
|
cfg_.rc_buf_optimal_sz = 500;
|
||||||
|
cfg_.rc_buf_sz = 1000;
|
||||||
|
cfg_.rc_dropframe_thresh = 30;
|
||||||
|
cfg_.rc_min_quantizer = 0;
|
||||||
|
cfg_.rc_max_quantizer = 63;
|
||||||
|
cfg_.rc_end_usage = VPX_CBR;
|
||||||
|
cfg_.g_lag_in_frames = 0;
|
||||||
|
// Encode using multiple threads.
|
||||||
|
cfg_.g_threads = 2;
|
||||||
|
|
||||||
|
::libvpx_test::I420VideoSource video("hantro_collage_w352h288.yuv", 352, 288,
|
||||||
|
30, 1, 0, 140);
|
||||||
|
cfg_.rc_target_bitrate = 200;
|
||||||
|
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!";
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check basic rate targeting for CBR.
|
||||||
TEST_P(DatarateTestVP9Large, BasicRateTargeting444) {
|
TEST_P(DatarateTestVP9Large, BasicRateTargeting444) {
|
||||||
::libvpx_test::Y4mVideoSource video("rush_hour_444.y4m", 0, 140);
|
::libvpx_test::Y4mVideoSource video("rush_hour_444.y4m", 0, 140);
|
||||||
|
|
||||||
@@ -569,8 +834,7 @@ TEST_P(DatarateTestVP9Large, BasicRateTargeting2TemporalLayers) {
|
|||||||
|
|
||||||
cfg_.temporal_layering_mode = VP9E_TEMPORAL_LAYERING_MODE_BYPASS;
|
cfg_.temporal_layering_mode = VP9E_TEMPORAL_LAYERING_MODE_BYPASS;
|
||||||
|
|
||||||
if (deadline_ == VPX_DL_REALTIME)
|
if (deadline_ == VPX_DL_REALTIME) cfg_.g_error_resilient = 1;
|
||||||
cfg_.g_error_resilient = 1;
|
|
||||||
|
|
||||||
::libvpx_test::I420VideoSource video("hantro_collage_w352h288.yuv", 352, 288,
|
::libvpx_test::I420VideoSource video("hantro_collage_w352h288.yuv", 352, 288,
|
||||||
30, 1, 0, 200);
|
30, 1, 0, 200);
|
||||||
@@ -584,10 +848,12 @@ TEST_P(DatarateTestVP9Large, BasicRateTargeting2TemporalLayers) {
|
|||||||
for (int j = 0; j < static_cast<int>(cfg_.ts_number_layers); ++j) {
|
for (int j = 0; j < static_cast<int>(cfg_.ts_number_layers); ++j) {
|
||||||
ASSERT_GE(effective_datarate_[j], cfg_.layer_target_bitrate[j] * 0.85)
|
ASSERT_GE(effective_datarate_[j], cfg_.layer_target_bitrate[j] * 0.85)
|
||||||
<< " The datarate for the file is lower than target by too much, "
|
<< " The datarate for the file is lower than target by too much, "
|
||||||
"for layer: " << j;
|
"for layer: "
|
||||||
|
<< j;
|
||||||
ASSERT_LE(effective_datarate_[j], cfg_.layer_target_bitrate[j] * 1.15)
|
ASSERT_LE(effective_datarate_[j], cfg_.layer_target_bitrate[j] * 1.15)
|
||||||
<< " The datarate for the file is greater than target by too much, "
|
<< " The datarate for the file is greater than target by too much, "
|
||||||
"for layer: " << j;
|
"for layer: "
|
||||||
|
<< j;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -627,12 +893,14 @@ TEST_P(DatarateTestVP9Large, BasicRateTargeting3TemporalLayers) {
|
|||||||
// Adjust the thresholds to be tighter than .75.
|
// Adjust the thresholds to be tighter than .75.
|
||||||
ASSERT_GE(effective_datarate_[j], cfg_.layer_target_bitrate[j] * 0.75)
|
ASSERT_GE(effective_datarate_[j], cfg_.layer_target_bitrate[j] * 0.75)
|
||||||
<< " The datarate for the file is lower than target by too much, "
|
<< " The datarate for the file is lower than target by too much, "
|
||||||
"for layer: " << j;
|
"for layer: "
|
||||||
|
<< j;
|
||||||
// TODO(yaowu): Work out more stable rc control strategy and
|
// TODO(yaowu): Work out more stable rc control strategy and
|
||||||
// Adjust the thresholds to be tighter than 1.25.
|
// Adjust the thresholds to be tighter than 1.25.
|
||||||
ASSERT_LE(effective_datarate_[j], cfg_.layer_target_bitrate[j] * 1.25)
|
ASSERT_LE(effective_datarate_[j], cfg_.layer_target_bitrate[j] * 1.25)
|
||||||
<< " The datarate for the file is greater than target by too much, "
|
<< " The datarate for the file is greater than target by too much, "
|
||||||
"for layer: " << j;
|
"for layer: "
|
||||||
|
<< j;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -672,10 +940,12 @@ TEST_P(DatarateTestVP9Large, BasicRateTargeting3TemporalLayersFrameDropping) {
|
|||||||
for (int j = 0; j < static_cast<int>(cfg_.ts_number_layers); ++j) {
|
for (int j = 0; j < static_cast<int>(cfg_.ts_number_layers); ++j) {
|
||||||
ASSERT_GE(effective_datarate_[j], cfg_.layer_target_bitrate[j] * 0.85)
|
ASSERT_GE(effective_datarate_[j], cfg_.layer_target_bitrate[j] * 0.85)
|
||||||
<< " The datarate for the file is lower than target by too much, "
|
<< " The datarate for the file is lower than target by too much, "
|
||||||
"for layer: " << j;
|
"for layer: "
|
||||||
|
<< j;
|
||||||
ASSERT_LE(effective_datarate_[j], cfg_.layer_target_bitrate[j] * 1.15)
|
ASSERT_LE(effective_datarate_[j], cfg_.layer_target_bitrate[j] * 1.15)
|
||||||
<< " The datarate for the file is greater than target by too much, "
|
<< " The datarate for the file is greater than target by too much, "
|
||||||
"for layer: " << j;
|
"for layer: "
|
||||||
|
<< j;
|
||||||
// Expect some frame drops in this test: for this 200 frames test,
|
// Expect some frame drops in this test: for this 200 frames test,
|
||||||
// expect at least 10% and not more than 60% drops.
|
// expect at least 10% and not more than 60% drops.
|
||||||
ASSERT_GE(num_drops_, 20);
|
ASSERT_GE(num_drops_, 20);
|
||||||
@@ -684,8 +954,13 @@ TEST_P(DatarateTestVP9Large, BasicRateTargeting3TemporalLayersFrameDropping) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#if CONFIG_VP9_TEMPORAL_DENOISING
|
#if CONFIG_VP9_TEMPORAL_DENOISING
|
||||||
|
class DatarateTestVP9LargeDenoiser : public DatarateTestVP9Large {
|
||||||
|
public:
|
||||||
|
virtual ~DatarateTestVP9LargeDenoiser() {}
|
||||||
|
};
|
||||||
|
|
||||||
// Check basic datarate targeting, for a single bitrate, when denoiser is on.
|
// 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_initial_sz = 500;
|
||||||
cfg_.rc_buf_optimal_sz = 500;
|
cfg_.rc_buf_optimal_sz = 500;
|
||||||
cfg_.rc_buf_sz = 1000;
|
cfg_.rc_buf_sz = 1000;
|
||||||
@@ -712,9 +987,37 @@ TEST_P(DatarateTestVP9Large, DenoiserLevels) {
|
|||||||
<< " The datarate for the file is greater than target by too much!";
|
<< " 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.
|
||||||
|
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;
|
||||||
|
|
||||||
|
::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: 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.15)
|
||||||
|
<< " The datarate for the file is greater than target by too much!";
|
||||||
|
}
|
||||||
|
|
||||||
// Check basic datarate targeting, for a single bitrate, when denoiser is off
|
// Check basic datarate targeting, for a single bitrate, when denoiser is off
|
||||||
// and on.
|
// and on.
|
||||||
TEST_P(DatarateTestVP9Large, DenoiserOffOn) {
|
TEST_P(DatarateTestVP9LargeDenoiser, DenoiserOffOn) {
|
||||||
cfg_.rc_buf_initial_sz = 500;
|
cfg_.rc_buf_initial_sz = 500;
|
||||||
cfg_.rc_buf_optimal_sz = 500;
|
cfg_.rc_buf_optimal_sz = 500;
|
||||||
cfg_.rc_buf_sz = 1000;
|
cfg_.rc_buf_sz = 1000;
|
||||||
@@ -745,11 +1048,15 @@ TEST_P(DatarateTestVP9Large, DenoiserOffOn) {
|
|||||||
}
|
}
|
||||||
#endif // CONFIG_VP9_TEMPORAL_DENOISING
|
#endif // CONFIG_VP9_TEMPORAL_DENOISING
|
||||||
|
|
||||||
class DatarateOnePassCbrSvc : public ::libvpx_test::EncoderTest,
|
class DatarateOnePassCbrSvc
|
||||||
|
: public ::libvpx_test::EncoderTest,
|
||||||
public ::libvpx_test::CodecTestWith2Params<libvpx_test::TestMode, int> {
|
public ::libvpx_test::CodecTestWith2Params<libvpx_test::TestMode, int> {
|
||||||
public:
|
public:
|
||||||
DatarateOnePassCbrSvc() : EncoderTest(GET_PARAM(0)) {}
|
DatarateOnePassCbrSvc() : EncoderTest(GET_PARAM(0)) {
|
||||||
|
memset(&svc_params_, 0, sizeof(svc_params_));
|
||||||
|
}
|
||||||
virtual ~DatarateOnePassCbrSvc() {}
|
virtual ~DatarateOnePassCbrSvc() {}
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
virtual void SetUp() {
|
virtual void SetUp() {
|
||||||
InitializeConfig();
|
InitializeConfig();
|
||||||
@@ -767,8 +1074,7 @@ class DatarateOnePassCbrSvc : public ::libvpx_test::EncoderTest,
|
|||||||
mismatch_psnr_ = 0.0;
|
mismatch_psnr_ = 0.0;
|
||||||
mismatch_nframes_ = 0;
|
mismatch_nframes_ = 0;
|
||||||
}
|
}
|
||||||
virtual void BeginPassHook(unsigned int /*pass*/) {
|
virtual void BeginPassHook(unsigned int /*pass*/) {}
|
||||||
}
|
|
||||||
virtual void PreEncodeFrameHook(::libvpx_test::VideoSource *video,
|
virtual void PreEncodeFrameHook(::libvpx_test::VideoSource *video,
|
||||||
::libvpx_test::Encoder *encoder) {
|
::libvpx_test::Encoder *encoder) {
|
||||||
if (video->frame() == 0) {
|
if (video->frame() == 0) {
|
||||||
@@ -777,12 +1083,17 @@ class DatarateOnePassCbrSvc : public ::libvpx_test::EncoderTest,
|
|||||||
svc_params_.max_quantizers[i] = 63;
|
svc_params_.max_quantizers[i] = 63;
|
||||||
svc_params_.min_quantizers[i] = 0;
|
svc_params_.min_quantizers[i] = 0;
|
||||||
}
|
}
|
||||||
|
svc_params_.speed_per_layer[0] = 5;
|
||||||
|
for (i = 1; i < VPX_SS_MAX_LAYERS; ++i) {
|
||||||
|
svc_params_.speed_per_layer[i] = speed_setting_;
|
||||||
|
}
|
||||||
encoder->Control(VP9E_SET_SVC, 1);
|
encoder->Control(VP9E_SET_SVC, 1);
|
||||||
encoder->Control(VP9E_SET_SVC_PARAMETERS, &svc_params_);
|
encoder->Control(VP9E_SET_SVC_PARAMETERS, &svc_params_);
|
||||||
encoder->Control(VP8E_SET_CPUUSED, speed_setting_);
|
encoder->Control(VP8E_SET_CPUUSED, speed_setting_);
|
||||||
encoder->Control(VP9E_SET_TILE_COLUMNS, 0);
|
encoder->Control(VP9E_SET_TILE_COLUMNS, 0);
|
||||||
encoder->Control(VP8E_SET_MAX_INTRA_BITRATE_PCT, 300);
|
encoder->Control(VP8E_SET_MAX_INTRA_BITRATE_PCT, 300);
|
||||||
encoder->Control(VP9E_SET_TILE_COLUMNS, (cfg_.g_threads >> 1));
|
encoder->Control(VP9E_SET_TILE_COLUMNS, (cfg_.g_threads >> 1));
|
||||||
|
encoder->Control(VP8E_SET_STATIC_THRESHOLD, 1);
|
||||||
}
|
}
|
||||||
const vpx_rational_t tb = video->timebase();
|
const vpx_rational_t tb = video->timebase();
|
||||||
timebase_ = static_cast<double>(tb.num) / tb.den;
|
timebase_ = static_cast<double>(tb.num) / tb.den;
|
||||||
@@ -790,21 +1101,21 @@ class DatarateOnePassCbrSvc : public ::libvpx_test::EncoderTest,
|
|||||||
}
|
}
|
||||||
virtual void FramePktHook(const vpx_codec_cx_pkt_t *pkt) {
|
virtual void FramePktHook(const vpx_codec_cx_pkt_t *pkt) {
|
||||||
vpx_codec_pts_t duration = pkt->data.frame.pts - last_pts_;
|
vpx_codec_pts_t duration = pkt->data.frame.pts - last_pts_;
|
||||||
if (last_pts_ == 0)
|
if (last_pts_ == 0) duration = 1;
|
||||||
duration = 1;
|
|
||||||
bits_in_buffer_model_ += static_cast<int64_t>(
|
bits_in_buffer_model_ += static_cast<int64_t>(
|
||||||
duration * timebase_ * cfg_.rc_target_bitrate * 1000);
|
duration * timebase_ * cfg_.rc_target_bitrate * 1000);
|
||||||
const bool key_frame = (pkt->data.frame.flags & VPX_FRAME_IS_KEY)
|
const bool key_frame =
|
||||||
? true: false;
|
(pkt->data.frame.flags & VPX_FRAME_IS_KEY) ? true : false;
|
||||||
if (!key_frame) {
|
if (!key_frame) {
|
||||||
ASSERT_GE(bits_in_buffer_model_, 0) << "Buffer Underrun at frame "
|
// TODO(marpan): This check currently fails for some of the SVC tests,
|
||||||
<< pkt->data.frame.pts;
|
// 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;
|
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;
|
bits_total_ += frame_size_in_bits;
|
||||||
if (!first_drop_ && duration > 1)
|
if (!first_drop_ && duration > 1) first_drop_ = last_pts_ + 1;
|
||||||
first_drop_ = last_pts_ + 1;
|
|
||||||
last_pts_ = pkt->data.frame.pts;
|
last_pts_ = pkt->data.frame.pts;
|
||||||
bits_in_last_frame_ = frame_size_in_bits;
|
bits_in_last_frame_ = frame_size_in_bits;
|
||||||
++frame_number_;
|
++frame_number_;
|
||||||
@@ -817,16 +1128,13 @@ class DatarateOnePassCbrSvc : public ::libvpx_test::EncoderTest,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual void MismatchHook(const vpx_image_t *img1,
|
virtual void MismatchHook(const vpx_image_t *img1, const vpx_image_t *img2) {
|
||||||
const vpx_image_t *img2) {
|
|
||||||
double mismatch_psnr = compute_psnr(img1, img2);
|
double mismatch_psnr = compute_psnr(img1, img2);
|
||||||
mismatch_psnr_ += mismatch_psnr;
|
mismatch_psnr_ += mismatch_psnr;
|
||||||
++mismatch_nframes_;
|
++mismatch_nframes_;
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned int GetMismatchFrames() {
|
unsigned int GetMismatchFrames() { return mismatch_nframes_; }
|
||||||
return mismatch_nframes_;
|
|
||||||
}
|
|
||||||
|
|
||||||
vpx_codec_pts_t last_pts_;
|
vpx_codec_pts_t last_pts_;
|
||||||
int64_t bits_in_buffer_model_;
|
int64_t bits_in_buffer_model_;
|
||||||
@@ -844,36 +1152,30 @@ class DatarateOnePassCbrSvc : public ::libvpx_test::EncoderTest,
|
|||||||
};
|
};
|
||||||
static void assign_layer_bitrates(vpx_codec_enc_cfg_t *const enc_cfg,
|
static void assign_layer_bitrates(vpx_codec_enc_cfg_t *const enc_cfg,
|
||||||
const vpx_svc_extra_cfg_t *svc_params,
|
const vpx_svc_extra_cfg_t *svc_params,
|
||||||
int spatial_layers,
|
int spatial_layers, int temporal_layers,
|
||||||
int temporal_layers,
|
|
||||||
int temporal_layering_mode) {
|
int temporal_layering_mode) {
|
||||||
int sl, spatial_layer_target;
|
int sl, spatial_layer_target;
|
||||||
float total = 0;
|
float total = 0;
|
||||||
float alloc_ratio[VPX_MAX_LAYERS] = { 0 };
|
float alloc_ratio[VPX_MAX_LAYERS] = { 0 };
|
||||||
for (sl = 0; sl < spatial_layers; ++sl) {
|
for (sl = 0; sl < spatial_layers; ++sl) {
|
||||||
if (svc_params->scaling_factor_den[sl] > 0) {
|
if (svc_params->scaling_factor_den[sl] > 0) {
|
||||||
alloc_ratio[sl] = (float)(svc_params->scaling_factor_num[sl] *
|
alloc_ratio[sl] = (float)(svc_params->scaling_factor_num[sl] * 1.0 /
|
||||||
1.0 / svc_params->scaling_factor_den[sl]);
|
svc_params->scaling_factor_den[sl]);
|
||||||
total += alloc_ratio[sl];
|
total += alloc_ratio[sl];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
for (sl = 0; sl < spatial_layers; ++sl) {
|
for (sl = 0; sl < spatial_layers; ++sl) {
|
||||||
enc_cfg->ss_target_bitrate[sl] = spatial_layer_target =
|
enc_cfg->ss_target_bitrate[sl] = spatial_layer_target =
|
||||||
(unsigned int)(enc_cfg->rc_target_bitrate *
|
(unsigned int)(enc_cfg->rc_target_bitrate * alloc_ratio[sl] / total);
|
||||||
alloc_ratio[sl] / total);
|
|
||||||
const int index = sl * temporal_layers;
|
const int index = sl * temporal_layers;
|
||||||
if (temporal_layering_mode == 3) {
|
if (temporal_layering_mode == 3) {
|
||||||
enc_cfg->layer_target_bitrate[index] =
|
enc_cfg->layer_target_bitrate[index] = spatial_layer_target >> 1;
|
||||||
spatial_layer_target >> 1;
|
|
||||||
enc_cfg->layer_target_bitrate[index + 1] =
|
enc_cfg->layer_target_bitrate[index + 1] =
|
||||||
(spatial_layer_target >> 1) + (spatial_layer_target >> 2);
|
(spatial_layer_target >> 1) + (spatial_layer_target >> 2);
|
||||||
enc_cfg->layer_target_bitrate[index + 2] =
|
enc_cfg->layer_target_bitrate[index + 2] = spatial_layer_target;
|
||||||
spatial_layer_target;
|
|
||||||
} else if (temporal_layering_mode == 2) {
|
} else if (temporal_layering_mode == 2) {
|
||||||
enc_cfg->layer_target_bitrate[index] =
|
enc_cfg->layer_target_bitrate[index] = spatial_layer_target * 2 / 3;
|
||||||
spatial_layer_target * 2 / 3;
|
enc_cfg->layer_target_bitrate[index + 1] = spatial_layer_target;
|
||||||
enc_cfg->layer_target_bitrate[index + 1] =
|
|
||||||
spatial_layer_target;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -904,7 +1206,7 @@ TEST_P(DatarateOnePassCbrSvc, OnePassCbrSvc2SpatialLayers) {
|
|||||||
cfg_.kf_max_dist = 9999;
|
cfg_.kf_max_dist = 9999;
|
||||||
::libvpx_test::I420VideoSource video("hantro_collage_w352h288.yuv", 352, 288,
|
::libvpx_test::I420VideoSource video("hantro_collage_w352h288.yuv", 352, 288,
|
||||||
30, 1, 0, 200);
|
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.
|
// layer target_bitrate.
|
||||||
for (int i = 200; i <= 800; i += 200) {
|
for (int i = 200; i <= 800; i += 200) {
|
||||||
cfg_.rc_target_bitrate = i;
|
cfg_.rc_target_bitrate = i;
|
||||||
@@ -986,8 +1288,7 @@ TEST_P(DatarateOnePassCbrSvc, OnePassCbrSvc2SpatialLayers4threads) {
|
|||||||
svc_params_.scaling_factor_den[1] = 288;
|
svc_params_.scaling_factor_den[1] = 288;
|
||||||
cfg_.rc_dropframe_thresh = 10;
|
cfg_.rc_dropframe_thresh = 10;
|
||||||
cfg_.kf_max_dist = 9999;
|
cfg_.kf_max_dist = 9999;
|
||||||
::libvpx_test::I420VideoSource video("niklas_1280_720_30.y4m", 1280, 720,
|
::libvpx_test::Y4mVideoSource video("niklas_1280_720_30.y4m", 0, 300);
|
||||||
30, 1, 0, 300);
|
|
||||||
cfg_.rc_target_bitrate = 800;
|
cfg_.rc_target_bitrate = 800;
|
||||||
ResetModel();
|
ResetModel();
|
||||||
assign_layer_bitrates(&cfg_, &svc_params_, cfg_.ss_number_layers,
|
assign_layer_bitrates(&cfg_, &svc_params_, cfg_.ss_number_layers,
|
||||||
@@ -1026,8 +1327,7 @@ TEST_P(DatarateOnePassCbrSvc, OnePassCbrSvc3SpatialLayers) {
|
|||||||
svc_params_.scaling_factor_den[2] = 288;
|
svc_params_.scaling_factor_den[2] = 288;
|
||||||
cfg_.rc_dropframe_thresh = 10;
|
cfg_.rc_dropframe_thresh = 10;
|
||||||
cfg_.kf_max_dist = 9999;
|
cfg_.kf_max_dist = 9999;
|
||||||
::libvpx_test::I420VideoSource video("niklas_1280_720_30.y4m", 1280, 720,
|
::libvpx_test::Y4mVideoSource video("niklas_1280_720_30.y4m", 0, 300);
|
||||||
30, 1, 0, 300);
|
|
||||||
cfg_.rc_target_bitrate = 800;
|
cfg_.rc_target_bitrate = 800;
|
||||||
ResetModel();
|
ResetModel();
|
||||||
assign_layer_bitrates(&cfg_, &svc_params_, cfg_.ss_number_layers,
|
assign_layer_bitrates(&cfg_, &svc_params_, cfg_.ss_number_layers,
|
||||||
@@ -1065,8 +1365,7 @@ TEST_P(DatarateOnePassCbrSvc, OnePassCbrSvc3SpatialLayersSmallKf) {
|
|||||||
svc_params_.scaling_factor_num[2] = 288;
|
svc_params_.scaling_factor_num[2] = 288;
|
||||||
svc_params_.scaling_factor_den[2] = 288;
|
svc_params_.scaling_factor_den[2] = 288;
|
||||||
cfg_.rc_dropframe_thresh = 10;
|
cfg_.rc_dropframe_thresh = 10;
|
||||||
::libvpx_test::I420VideoSource video("niklas_1280_720_30.y4m", 1280, 720,
|
::libvpx_test::Y4mVideoSource video("niklas_1280_720_30.y4m", 0, 300);
|
||||||
30, 1, 0, 300);
|
|
||||||
cfg_.rc_target_bitrate = 800;
|
cfg_.rc_target_bitrate = 800;
|
||||||
// For this 3 temporal layer case, pattern repeats every 4 frames, so choose
|
// 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).
|
// 4 key neighboring key frame periods (so key frame will land on 0-2-1-2).
|
||||||
@@ -1110,8 +1409,7 @@ TEST_P(DatarateOnePassCbrSvc, OnePassCbrSvc3SpatialLayers4threads) {
|
|||||||
svc_params_.scaling_factor_den[2] = 288;
|
svc_params_.scaling_factor_den[2] = 288;
|
||||||
cfg_.rc_dropframe_thresh = 10;
|
cfg_.rc_dropframe_thresh = 10;
|
||||||
cfg_.kf_max_dist = 9999;
|
cfg_.kf_max_dist = 9999;
|
||||||
::libvpx_test::I420VideoSource video("niklas_1280_720_30.y4m", 1280, 720,
|
::libvpx_test::Y4mVideoSource video("niklas_1280_720_30.y4m", 0, 300);
|
||||||
30, 1, 0, 300);
|
|
||||||
cfg_.rc_target_bitrate = 800;
|
cfg_.rc_target_bitrate = 800;
|
||||||
ResetModel();
|
ResetModel();
|
||||||
assign_layer_bitrates(&cfg_, &svc_params_, cfg_.ss_number_layers,
|
assign_layer_bitrates(&cfg_, &svc_params_, cfg_.ss_number_layers,
|
||||||
@@ -1124,11 +1422,54 @@ TEST_P(DatarateOnePassCbrSvc, OnePassCbrSvc3SpatialLayers4threads) {
|
|||||||
EXPECT_EQ(static_cast<unsigned int>(0), GetMismatchFrames());
|
EXPECT_EQ(static_cast<unsigned int>(0), GetMismatchFrames());
|
||||||
}
|
}
|
||||||
|
|
||||||
VP8_INSTANTIATE_TEST_CASE(DatarateTestLarge, ALL_TEST_MODES);
|
// Run SVC encoder for 1 temporal layer, 2 spatial layers, with spatial
|
||||||
|
// downscale 5x5.
|
||||||
|
TEST_P(DatarateOnePassCbrSvc, OnePassCbrSvc2SpatialLayers5x5MultipleRuns) {
|
||||||
|
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 = 0;
|
||||||
|
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());
|
||||||
|
}
|
||||||
|
|
||||||
|
VP8_INSTANTIATE_TEST_CASE(DatarateTestLarge, ALL_TEST_MODES,
|
||||||
|
::testing::Values(0));
|
||||||
|
VP8_INSTANTIATE_TEST_CASE(DatarateTestRealTime,
|
||||||
|
::testing::Values(::libvpx_test::kRealTime),
|
||||||
|
::testing::Values(-6, -12));
|
||||||
VP9_INSTANTIATE_TEST_CASE(DatarateTestVP9Large,
|
VP9_INSTANTIATE_TEST_CASE(DatarateTestVP9Large,
|
||||||
::testing::Values(::libvpx_test::kOnePassGood,
|
::testing::Values(::libvpx_test::kOnePassGood,
|
||||||
::libvpx_test::kRealTime),
|
::libvpx_test::kRealTime),
|
||||||
::testing::Range(2, 9));
|
::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,
|
VP9_INSTANTIATE_TEST_CASE(DatarateOnePassCbrSvc,
|
||||||
::testing::Values(::libvpx_test::kRealTime),
|
::testing::Values(::libvpx_test::kRealTime),
|
||||||
::testing::Range(5, 9));
|
::testing::Range(5, 9));
|
||||||
|
|||||||
@@ -25,20 +25,12 @@
|
|||||||
#include "vpx/vpx_codec.h"
|
#include "vpx/vpx_codec.h"
|
||||||
#include "vpx/vpx_integer.h"
|
#include "vpx/vpx_integer.h"
|
||||||
#include "vpx_ports/mem.h"
|
#include "vpx_ports/mem.h"
|
||||||
|
#include "vpx_ports/msvc.h" // for round()
|
||||||
|
|
||||||
using libvpx_test::ACMRandom;
|
using libvpx_test::ACMRandom;
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
|
|
||||||
#ifdef _MSC_VER
|
|
||||||
static int round(double x) {
|
|
||||||
if (x < 0)
|
|
||||||
return static_cast<int>(ceil(x - 0.5));
|
|
||||||
else
|
|
||||||
return static_cast<int>(floor(x + 0.5));
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
const int kNumCoeffs = 256;
|
const int kNumCoeffs = 256;
|
||||||
const double C1 = 0.995184726672197;
|
const double C1 = 0.995184726672197;
|
||||||
const double C2 = 0.98078528040323;
|
const double C2 = 0.98078528040323;
|
||||||
@@ -216,21 +208,17 @@ void reference_16x16_dct_2d(int16_t input[256], double output[256]) {
|
|||||||
// First transform columns
|
// First transform columns
|
||||||
for (int i = 0; i < 16; ++i) {
|
for (int i = 0; i < 16; ++i) {
|
||||||
double temp_in[16], temp_out[16];
|
double temp_in[16], temp_out[16];
|
||||||
for (int j = 0; j < 16; ++j)
|
for (int j = 0; j < 16; ++j) temp_in[j] = input[j * 16 + i];
|
||||||
temp_in[j] = input[j * 16 + i];
|
|
||||||
butterfly_16x16_dct_1d(temp_in, temp_out);
|
butterfly_16x16_dct_1d(temp_in, temp_out);
|
||||||
for (int j = 0; j < 16; ++j)
|
for (int j = 0; j < 16; ++j) output[j * 16 + i] = temp_out[j];
|
||||||
output[j * 16 + i] = temp_out[j];
|
|
||||||
}
|
}
|
||||||
// Then transform rows
|
// Then transform rows
|
||||||
for (int i = 0; i < 16; ++i) {
|
for (int i = 0; i < 16; ++i) {
|
||||||
double temp_in[16], temp_out[16];
|
double temp_in[16], temp_out[16];
|
||||||
for (int j = 0; j < 16; ++j)
|
for (int j = 0; j < 16; ++j) temp_in[j] = output[j + i * 16];
|
||||||
temp_in[j] = output[j + i * 16];
|
|
||||||
butterfly_16x16_dct_1d(temp_in, temp_out);
|
butterfly_16x16_dct_1d(temp_in, temp_out);
|
||||||
// Scale by some magic number
|
// Scale by some magic number
|
||||||
for (int j = 0; j < 16; ++j)
|
for (int j = 0; j < 16; ++j) output[j + i * 16] = temp_out[j] / 2;
|
||||||
output[j + i * 16] = temp_out[j]/2;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -256,8 +244,7 @@ void idct16x16_ref(const tran_low_t *in, uint8_t *dest, int stride,
|
|||||||
vpx_idct16x16_256_add_c(in, dest, stride);
|
vpx_idct16x16_256_add_c(in, dest, stride);
|
||||||
}
|
}
|
||||||
|
|
||||||
void fht16x16_ref(const int16_t *in, tran_low_t *out, int stride,
|
void fht16x16_ref(const int16_t *in, tran_low_t *out, int stride, int tx_type) {
|
||||||
int tx_type) {
|
|
||||||
vp9_fht16x16_c(in, out, stride, tx_type);
|
vp9_fht16x16_c(in, out, stride, tx_type);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -359,11 +346,10 @@ class Trans16x16TestBase {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ASM_REGISTER_STATE_CHECK(RunFwdTxfm(test_input_block,
|
|
||||||
test_temp_block, pitch_));
|
|
||||||
if (bit_depth_ == VPX_BITS_8) {
|
|
||||||
ASM_REGISTER_STATE_CHECK(
|
ASM_REGISTER_STATE_CHECK(
|
||||||
RunInvTxfm(test_temp_block, dst, pitch_));
|
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
|
#if CONFIG_VP9_HIGHBITDEPTH
|
||||||
} else {
|
} else {
|
||||||
ASM_REGISTER_STATE_CHECK(
|
ASM_REGISTER_STATE_CHECK(
|
||||||
@@ -373,14 +359,13 @@ class Trans16x16TestBase {
|
|||||||
|
|
||||||
for (int j = 0; j < kNumCoeffs; ++j) {
|
for (int j = 0; j < kNumCoeffs; ++j) {
|
||||||
#if CONFIG_VP9_HIGHBITDEPTH
|
#if CONFIG_VP9_HIGHBITDEPTH
|
||||||
const uint32_t diff =
|
const int32_t diff =
|
||||||
bit_depth_ == VPX_BITS_8 ? dst[j] - src[j] : dst16[j] - src16[j];
|
bit_depth_ == VPX_BITS_8 ? dst[j] - src[j] : dst16[j] - src16[j];
|
||||||
#else
|
#else
|
||||||
const uint32_t diff = dst[j] - src[j];
|
const int32_t diff = dst[j] - src[j];
|
||||||
#endif
|
#endif
|
||||||
const uint32_t error = diff * diff;
|
const uint32_t error = diff * diff;
|
||||||
if (max_error < error)
|
if (max_error < error) max_error = error;
|
||||||
max_error = error;
|
|
||||||
total_error += error;
|
total_error += error;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -401,8 +386,9 @@ class Trans16x16TestBase {
|
|||||||
|
|
||||||
for (int i = 0; i < count_test_block; ++i) {
|
for (int i = 0; i < count_test_block; ++i) {
|
||||||
// Initialize a test block with input range [-mask_, mask_].
|
// Initialize a test block with input range [-mask_, mask_].
|
||||||
for (int j = 0; j < kNumCoeffs; ++j)
|
for (int j = 0; j < kNumCoeffs; ++j) {
|
||||||
input_block[j] = (rnd.Rand16() & mask_) - (rnd.Rand16() & mask_);
|
input_block[j] = (rnd.Rand16() & mask_) - (rnd.Rand16() & mask_);
|
||||||
|
}
|
||||||
|
|
||||||
fwd_txfm_ref(input_block, output_ref_block, pitch_, tx_type_);
|
fwd_txfm_ref(input_block, output_ref_block, pitch_, tx_type_);
|
||||||
ASM_REGISTER_STATE_CHECK(RunFwdTxfm(input_block, output_block, pitch_));
|
ASM_REGISTER_STATE_CHECK(RunFwdTxfm(input_block, output_block, pitch_));
|
||||||
@@ -426,16 +412,14 @@ class Trans16x16TestBase {
|
|||||||
input_extreme_block[j] = rnd.Rand8() % 2 ? mask_ : -mask_;
|
input_extreme_block[j] = rnd.Rand8() % 2 ? mask_ : -mask_;
|
||||||
}
|
}
|
||||||
if (i == 0) {
|
if (i == 0) {
|
||||||
for (int j = 0; j < kNumCoeffs; ++j)
|
for (int j = 0; j < kNumCoeffs; ++j) input_extreme_block[j] = mask_;
|
||||||
input_extreme_block[j] = mask_;
|
|
||||||
} else if (i == 1) {
|
} else if (i == 1) {
|
||||||
for (int j = 0; j < kNumCoeffs; ++j)
|
for (int j = 0; j < kNumCoeffs; ++j) input_extreme_block[j] = -mask_;
|
||||||
input_extreme_block[j] = -mask_;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fwd_txfm_ref(input_extreme_block, output_ref_block, pitch_, tx_type_);
|
fwd_txfm_ref(input_extreme_block, output_ref_block, pitch_, tx_type_);
|
||||||
ASM_REGISTER_STATE_CHECK(RunFwdTxfm(input_extreme_block,
|
ASM_REGISTER_STATE_CHECK(
|
||||||
output_block, pitch_));
|
RunFwdTxfm(input_extreme_block, output_block, pitch_));
|
||||||
|
|
||||||
// The minimum quant value is 4.
|
// The minimum quant value is 4.
|
||||||
for (int j = 0; j < kNumCoeffs; ++j) {
|
for (int j = 0; j < kNumCoeffs; ++j) {
|
||||||
@@ -464,12 +448,12 @@ class Trans16x16TestBase {
|
|||||||
for (int j = 0; j < kNumCoeffs; ++j) {
|
for (int j = 0; j < kNumCoeffs; ++j) {
|
||||||
input_extreme_block[j] = rnd.Rand8() % 2 ? mask_ : -mask_;
|
input_extreme_block[j] = rnd.Rand8() % 2 ? mask_ : -mask_;
|
||||||
}
|
}
|
||||||
if (i == 0)
|
if (i == 0) {
|
||||||
for (int j = 0; j < kNumCoeffs; ++j)
|
for (int j = 0; j < kNumCoeffs; ++j) input_extreme_block[j] = mask_;
|
||||||
input_extreme_block[j] = mask_;
|
}
|
||||||
if (i == 1)
|
if (i == 1) {
|
||||||
for (int j = 0; j < kNumCoeffs; ++j)
|
for (int j = 0; j < kNumCoeffs; ++j) input_extreme_block[j] = -mask_;
|
||||||
input_extreme_block[j] = -mask_;
|
}
|
||||||
|
|
||||||
fwd_txfm_ref(input_extreme_block, output_ref_block, pitch_, tx_type_);
|
fwd_txfm_ref(input_extreme_block, output_ref_block, pitch_, tx_type_);
|
||||||
|
|
||||||
@@ -483,8 +467,9 @@ class Trans16x16TestBase {
|
|||||||
|
|
||||||
// quantization with maximum allowed step sizes
|
// quantization with maximum allowed step sizes
|
||||||
output_ref_block[0] = (output_ref_block[0] / dc_thred) * dc_thred;
|
output_ref_block[0] = (output_ref_block[0] / dc_thred) * dc_thred;
|
||||||
for (int j = 1; j < kNumCoeffs; ++j)
|
for (int j = 1; j < kNumCoeffs; ++j) {
|
||||||
output_ref_block[j] = (output_ref_block[j] / ac_thred) * ac_thred;
|
output_ref_block[j] = (output_ref_block[j] / ac_thred) * ac_thred;
|
||||||
|
}
|
||||||
if (bit_depth_ == VPX_BITS_8) {
|
if (bit_depth_ == VPX_BITS_8) {
|
||||||
inv_txfm_ref(output_ref_block, ref, pitch_, tx_type_);
|
inv_txfm_ref(output_ref_block, ref, pitch_, tx_type_);
|
||||||
ASM_REGISTER_STATE_CHECK(RunInvTxfm(output_ref_block, dst, pitch_));
|
ASM_REGISTER_STATE_CHECK(RunInvTxfm(output_ref_block, dst, pitch_));
|
||||||
@@ -492,17 +477,15 @@ class Trans16x16TestBase {
|
|||||||
} else {
|
} else {
|
||||||
inv_txfm_ref(output_ref_block, CONVERT_TO_BYTEPTR(ref16), pitch_,
|
inv_txfm_ref(output_ref_block, CONVERT_TO_BYTEPTR(ref16), pitch_,
|
||||||
tx_type_);
|
tx_type_);
|
||||||
ASM_REGISTER_STATE_CHECK(RunInvTxfm(output_ref_block,
|
ASM_REGISTER_STATE_CHECK(
|
||||||
CONVERT_TO_BYTEPTR(dst16), pitch_));
|
RunInvTxfm(output_ref_block, CONVERT_TO_BYTEPTR(dst16), pitch_));
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
if (bit_depth_ == VPX_BITS_8) {
|
if (bit_depth_ == VPX_BITS_8) {
|
||||||
for (int j = 0; j < kNumCoeffs; ++j)
|
for (int j = 0; j < kNumCoeffs; ++j) EXPECT_EQ(ref[j], dst[j]);
|
||||||
EXPECT_EQ(ref[j], dst[j]);
|
|
||||||
#if CONFIG_VP9_HIGHBITDEPTH
|
#if CONFIG_VP9_HIGHBITDEPTH
|
||||||
} else {
|
} else {
|
||||||
for (int j = 0; j < kNumCoeffs; ++j)
|
for (int j = 0; j < kNumCoeffs; ++j) EXPECT_EQ(ref16[j], dst16[j]);
|
||||||
EXPECT_EQ(ref16[j], dst16[j]);
|
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -539,15 +522,16 @@ class Trans16x16TestBase {
|
|||||||
}
|
}
|
||||||
|
|
||||||
reference_16x16_dct_2d(in, out_r);
|
reference_16x16_dct_2d(in, out_r);
|
||||||
for (int j = 0; j < kNumCoeffs; ++j)
|
for (int j = 0; j < kNumCoeffs; ++j) {
|
||||||
coeff[j] = static_cast<tran_low_t>(round(out_r[j]));
|
coeff[j] = static_cast<tran_low_t>(round(out_r[j]));
|
||||||
|
}
|
||||||
|
|
||||||
if (bit_depth_ == VPX_BITS_8) {
|
if (bit_depth_ == VPX_BITS_8) {
|
||||||
ASM_REGISTER_STATE_CHECK(RunInvTxfm(coeff, dst, 16));
|
ASM_REGISTER_STATE_CHECK(RunInvTxfm(coeff, dst, 16));
|
||||||
#if CONFIG_VP9_HIGHBITDEPTH
|
#if CONFIG_VP9_HIGHBITDEPTH
|
||||||
} else {
|
} else {
|
||||||
ASM_REGISTER_STATE_CHECK(RunInvTxfm(coeff, CONVERT_TO_BYTEPTR(dst16),
|
ASM_REGISTER_STATE_CHECK(
|
||||||
16));
|
RunInvTxfm(coeff, CONVERT_TO_BYTEPTR(dst16), 16));
|
||||||
#endif // CONFIG_VP9_HIGHBITDEPTH
|
#endif // CONFIG_VP9_HIGHBITDEPTH
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -559,8 +543,7 @@ class Trans16x16TestBase {
|
|||||||
const uint32_t diff = dst[j] - src[j];
|
const uint32_t diff = dst[j] - src[j];
|
||||||
#endif // CONFIG_VP9_HIGHBITDEPTH
|
#endif // CONFIG_VP9_HIGHBITDEPTH
|
||||||
const uint32_t error = diff * diff;
|
const uint32_t error = diff * diff;
|
||||||
EXPECT_GE(1u, error)
|
EXPECT_GE(1u, error) << "Error: 16x16 IDCT has error " << error
|
||||||
<< "Error: 16x16 IDCT has error " << error
|
|
||||||
<< " at index " << j;
|
<< " at index " << j;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -603,8 +586,8 @@ class Trans16x16TestBase {
|
|||||||
} else {
|
} else {
|
||||||
#if CONFIG_VP9_HIGHBITDEPTH
|
#if CONFIG_VP9_HIGHBITDEPTH
|
||||||
ref_txfm(coeff, CONVERT_TO_BYTEPTR(ref16), pitch_);
|
ref_txfm(coeff, CONVERT_TO_BYTEPTR(ref16), pitch_);
|
||||||
ASM_REGISTER_STATE_CHECK(RunInvTxfm(coeff, CONVERT_TO_BYTEPTR(dst16),
|
ASM_REGISTER_STATE_CHECK(
|
||||||
pitch_));
|
RunInvTxfm(coeff, CONVERT_TO_BYTEPTR(dst16), pitch_));
|
||||||
#endif // CONFIG_VP9_HIGHBITDEPTH
|
#endif // CONFIG_VP9_HIGHBITDEPTH
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -616,9 +599,8 @@ class Trans16x16TestBase {
|
|||||||
const uint32_t diff = dst[j] - ref[j];
|
const uint32_t diff = dst[j] - ref[j];
|
||||||
#endif // CONFIG_VP9_HIGHBITDEPTH
|
#endif // CONFIG_VP9_HIGHBITDEPTH
|
||||||
const uint32_t error = diff * diff;
|
const uint32_t error = diff * diff;
|
||||||
EXPECT_EQ(0u, error)
|
EXPECT_EQ(0u, error) << "Error: 16x16 IDCT Comparison has error "
|
||||||
<< "Error: 16x16 IDCT Comparison has error " << error
|
<< error << " at index " << j;
|
||||||
<< " at index " << j;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -631,8 +613,7 @@ class Trans16x16TestBase {
|
|||||||
IhtFunc inv_txfm_ref;
|
IhtFunc inv_txfm_ref;
|
||||||
};
|
};
|
||||||
|
|
||||||
class Trans16x16DCT
|
class Trans16x16DCT : public Trans16x16TestBase,
|
||||||
: public Trans16x16TestBase,
|
|
||||||
public ::testing::TestWithParam<Dct16x16Param> {
|
public ::testing::TestWithParam<Dct16x16Param> {
|
||||||
public:
|
public:
|
||||||
virtual ~Trans16x16DCT() {}
|
virtual ~Trans16x16DCT() {}
|
||||||
@@ -648,15 +629,9 @@ class Trans16x16DCT
|
|||||||
mask_ = (1 << bit_depth_) - 1;
|
mask_ = (1 << bit_depth_) - 1;
|
||||||
#if CONFIG_VP9_HIGHBITDEPTH
|
#if CONFIG_VP9_HIGHBITDEPTH
|
||||||
switch (bit_depth_) {
|
switch (bit_depth_) {
|
||||||
case VPX_BITS_10:
|
case VPX_BITS_10: inv_txfm_ref = idct16x16_10_ref; break;
|
||||||
inv_txfm_ref = idct16x16_10_ref;
|
case VPX_BITS_12: inv_txfm_ref = idct16x16_12_ref; break;
|
||||||
break;
|
default: inv_txfm_ref = idct16x16_ref; break;
|
||||||
case VPX_BITS_12:
|
|
||||||
inv_txfm_ref = idct16x16_12_ref;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
inv_txfm_ref = idct16x16_ref;
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
inv_txfm_ref = idct16x16_ref;
|
inv_txfm_ref = idct16x16_ref;
|
||||||
@@ -676,17 +651,11 @@ class Trans16x16DCT
|
|||||||
IdctFunc inv_txfm_;
|
IdctFunc inv_txfm_;
|
||||||
};
|
};
|
||||||
|
|
||||||
TEST_P(Trans16x16DCT, AccuracyCheck) {
|
TEST_P(Trans16x16DCT, AccuracyCheck) { RunAccuracyCheck(); }
|
||||||
RunAccuracyCheck();
|
|
||||||
}
|
|
||||||
|
|
||||||
TEST_P(Trans16x16DCT, CoeffCheck) {
|
TEST_P(Trans16x16DCT, CoeffCheck) { RunCoeffCheck(); }
|
||||||
RunCoeffCheck();
|
|
||||||
}
|
|
||||||
|
|
||||||
TEST_P(Trans16x16DCT, MemCheck) {
|
TEST_P(Trans16x16DCT, MemCheck) { RunMemCheck(); }
|
||||||
RunMemCheck();
|
|
||||||
}
|
|
||||||
|
|
||||||
TEST_P(Trans16x16DCT, QuantCheck) {
|
TEST_P(Trans16x16DCT, QuantCheck) {
|
||||||
// Use maximally allowed quantization step sizes for DC and AC
|
// Use maximally allowed quantization step sizes for DC and AC
|
||||||
@@ -694,12 +663,9 @@ TEST_P(Trans16x16DCT, QuantCheck) {
|
|||||||
RunQuantCheck(1336, 1828);
|
RunQuantCheck(1336, 1828);
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_P(Trans16x16DCT, InvAccuracyCheck) {
|
TEST_P(Trans16x16DCT, InvAccuracyCheck) { RunInvAccuracyCheck(); }
|
||||||
RunInvAccuracyCheck();
|
|
||||||
}
|
|
||||||
|
|
||||||
class Trans16x16HT
|
class Trans16x16HT : public Trans16x16TestBase,
|
||||||
: public Trans16x16TestBase,
|
|
||||||
public ::testing::TestWithParam<Ht16x16Param> {
|
public ::testing::TestWithParam<Ht16x16Param> {
|
||||||
public:
|
public:
|
||||||
virtual ~Trans16x16HT() {}
|
virtual ~Trans16x16HT() {}
|
||||||
@@ -715,15 +681,9 @@ class Trans16x16HT
|
|||||||
mask_ = (1 << bit_depth_) - 1;
|
mask_ = (1 << bit_depth_) - 1;
|
||||||
#if CONFIG_VP9_HIGHBITDEPTH
|
#if CONFIG_VP9_HIGHBITDEPTH
|
||||||
switch (bit_depth_) {
|
switch (bit_depth_) {
|
||||||
case VPX_BITS_10:
|
case VPX_BITS_10: inv_txfm_ref = iht16x16_10; break;
|
||||||
inv_txfm_ref = iht16x16_10;
|
case VPX_BITS_12: inv_txfm_ref = iht16x16_12; break;
|
||||||
break;
|
default: inv_txfm_ref = iht16x16_ref; break;
|
||||||
case VPX_BITS_12:
|
|
||||||
inv_txfm_ref = iht16x16_12;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
inv_txfm_ref = iht16x16_ref;
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
inv_txfm_ref = iht16x16_ref;
|
inv_txfm_ref = iht16x16_ref;
|
||||||
@@ -743,17 +703,11 @@ class Trans16x16HT
|
|||||||
IhtFunc inv_txfm_;
|
IhtFunc inv_txfm_;
|
||||||
};
|
};
|
||||||
|
|
||||||
TEST_P(Trans16x16HT, AccuracyCheck) {
|
TEST_P(Trans16x16HT, AccuracyCheck) { RunAccuracyCheck(); }
|
||||||
RunAccuracyCheck();
|
|
||||||
}
|
|
||||||
|
|
||||||
TEST_P(Trans16x16HT, CoeffCheck) {
|
TEST_P(Trans16x16HT, CoeffCheck) { RunCoeffCheck(); }
|
||||||
RunCoeffCheck();
|
|
||||||
}
|
|
||||||
|
|
||||||
TEST_P(Trans16x16HT, MemCheck) {
|
TEST_P(Trans16x16HT, MemCheck) { RunMemCheck(); }
|
||||||
RunMemCheck();
|
|
||||||
}
|
|
||||||
|
|
||||||
TEST_P(Trans16x16HT, QuantCheck) {
|
TEST_P(Trans16x16HT, QuantCheck) {
|
||||||
// The encoder skips any non-DC intra prediction modes,
|
// The encoder skips any non-DC intra prediction modes,
|
||||||
@@ -761,8 +715,7 @@ TEST_P(Trans16x16HT, QuantCheck) {
|
|||||||
RunQuantCheck(429, 729);
|
RunQuantCheck(429, 729);
|
||||||
}
|
}
|
||||||
|
|
||||||
class InvTrans16x16DCT
|
class InvTrans16x16DCT : public Trans16x16TestBase,
|
||||||
: public Trans16x16TestBase,
|
|
||||||
public ::testing::TestWithParam<Idct16x16Param> {
|
public ::testing::TestWithParam<Idct16x16Param> {
|
||||||
public:
|
public:
|
||||||
virtual ~InvTrans16x16DCT() {}
|
virtual ~InvTrans16x16DCT() {}
|
||||||
@@ -792,8 +745,7 @@ TEST_P(InvTrans16x16DCT, CompareReference) {
|
|||||||
CompareInvReference(ref_txfm_, thresh_);
|
CompareInvReference(ref_txfm_, thresh_);
|
||||||
}
|
}
|
||||||
|
|
||||||
class PartialTrans16x16Test
|
class PartialTrans16x16Test : public ::testing::TestWithParam<
|
||||||
: public ::testing::TestWithParam<
|
|
||||||
std::tr1::tuple<FdctFunc, vpx_bit_depth_t> > {
|
std::tr1::tuple<FdctFunc, vpx_bit_depth_t> > {
|
||||||
public:
|
public:
|
||||||
virtual ~PartialTrans16x16Test() {}
|
virtual ~PartialTrans16x16Test() {}
|
||||||
@@ -863,10 +815,10 @@ INSTANTIATE_TEST_CASE_P(
|
|||||||
make_tuple(&vpx_highbd_fdct16x16_c, &idct16x16_12, 0, VPX_BITS_12),
|
make_tuple(&vpx_highbd_fdct16x16_c, &idct16x16_12, 0, VPX_BITS_12),
|
||||||
make_tuple(&vpx_fdct16x16_c, &vpx_idct16x16_256_add_c, 0, VPX_BITS_8)));
|
make_tuple(&vpx_fdct16x16_c, &vpx_idct16x16_256_add_c, 0, VPX_BITS_8)));
|
||||||
#else
|
#else
|
||||||
INSTANTIATE_TEST_CASE_P(
|
INSTANTIATE_TEST_CASE_P(C, Trans16x16DCT,
|
||||||
C, Trans16x16DCT,
|
::testing::Values(make_tuple(&vpx_fdct16x16_c,
|
||||||
::testing::Values(
|
&vpx_idct16x16_256_add_c,
|
||||||
make_tuple(&vpx_fdct16x16_c, &vpx_idct16x16_256_add_c, 0, VPX_BITS_8)));
|
0, VPX_BITS_8)));
|
||||||
#endif // CONFIG_VP9_HIGHBITDEPTH
|
#endif // CONFIG_VP9_HIGHBITDEPTH
|
||||||
|
|
||||||
#if CONFIG_VP9_HIGHBITDEPTH
|
#if CONFIG_VP9_HIGHBITDEPTH
|
||||||
@@ -903,31 +855,28 @@ INSTANTIATE_TEST_CASE_P(C, PartialTrans16x16Test,
|
|||||||
VPX_BITS_8)));
|
VPX_BITS_8)));
|
||||||
#endif // CONFIG_VP9_HIGHBITDEPTH
|
#endif // CONFIG_VP9_HIGHBITDEPTH
|
||||||
|
|
||||||
#if HAVE_NEON_ASM && !CONFIG_VP9_HIGHBITDEPTH && !CONFIG_EMULATE_HARDWARE
|
#if HAVE_NEON && !CONFIG_VP9_HIGHBITDEPTH && !CONFIG_EMULATE_HARDWARE
|
||||||
INSTANTIATE_TEST_CASE_P(
|
INSTANTIATE_TEST_CASE_P(
|
||||||
NEON, Trans16x16DCT,
|
NEON, Trans16x16DCT,
|
||||||
::testing::Values(
|
::testing::Values(make_tuple(&vpx_fdct16x16_c, &vpx_idct16x16_256_add_neon,
|
||||||
make_tuple(&vpx_fdct16x16_c,
|
0, VPX_BITS_8)));
|
||||||
&vpx_idct16x16_256_add_neon, 0, VPX_BITS_8)));
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if HAVE_SSE2 && !CONFIG_VP9_HIGHBITDEPTH && !CONFIG_EMULATE_HARDWARE
|
#if HAVE_SSE2 && !CONFIG_VP9_HIGHBITDEPTH && !CONFIG_EMULATE_HARDWARE
|
||||||
INSTANTIATE_TEST_CASE_P(
|
INSTANTIATE_TEST_CASE_P(
|
||||||
SSE2, Trans16x16DCT,
|
SSE2, Trans16x16DCT,
|
||||||
::testing::Values(
|
::testing::Values(make_tuple(&vpx_fdct16x16_sse2,
|
||||||
make_tuple(&vpx_fdct16x16_sse2,
|
|
||||||
&vpx_idct16x16_256_add_sse2, 0, VPX_BITS_8)));
|
&vpx_idct16x16_256_add_sse2, 0, VPX_BITS_8)));
|
||||||
INSTANTIATE_TEST_CASE_P(
|
INSTANTIATE_TEST_CASE_P(
|
||||||
SSE2, Trans16x16HT,
|
SSE2, Trans16x16HT,
|
||||||
::testing::Values(
|
::testing::Values(make_tuple(&vp9_fht16x16_sse2, &vp9_iht16x16_256_add_sse2,
|
||||||
make_tuple(&vp9_fht16x16_sse2, &vp9_iht16x16_256_add_sse2, 0,
|
0, VPX_BITS_8),
|
||||||
VPX_BITS_8),
|
make_tuple(&vp9_fht16x16_sse2, &vp9_iht16x16_256_add_sse2,
|
||||||
make_tuple(&vp9_fht16x16_sse2, &vp9_iht16x16_256_add_sse2, 1,
|
1, VPX_BITS_8),
|
||||||
VPX_BITS_8),
|
make_tuple(&vp9_fht16x16_sse2, &vp9_iht16x16_256_add_sse2,
|
||||||
make_tuple(&vp9_fht16x16_sse2, &vp9_iht16x16_256_add_sse2, 2,
|
2, VPX_BITS_8),
|
||||||
VPX_BITS_8),
|
make_tuple(&vp9_fht16x16_sse2, &vp9_iht16x16_256_add_sse2,
|
||||||
make_tuple(&vp9_fht16x16_sse2, &vp9_iht16x16_256_add_sse2, 3,
|
3, VPX_BITS_8)));
|
||||||
VPX_BITS_8)));
|
|
||||||
INSTANTIATE_TEST_CASE_P(SSE2, PartialTrans16x16Test,
|
INSTANTIATE_TEST_CASE_P(SSE2, PartialTrans16x16Test,
|
||||||
::testing::Values(make_tuple(&vpx_fdct16x16_1_sse2,
|
::testing::Values(make_tuple(&vpx_fdct16x16_1_sse2,
|
||||||
VPX_BITS_8)));
|
VPX_BITS_8)));
|
||||||
@@ -937,16 +886,14 @@ INSTANTIATE_TEST_CASE_P(SSE2, PartialTrans16x16Test,
|
|||||||
INSTANTIATE_TEST_CASE_P(
|
INSTANTIATE_TEST_CASE_P(
|
||||||
SSE2, Trans16x16DCT,
|
SSE2, Trans16x16DCT,
|
||||||
::testing::Values(
|
::testing::Values(
|
||||||
make_tuple(&vpx_highbd_fdct16x16_sse2,
|
make_tuple(&vpx_highbd_fdct16x16_sse2, &idct16x16_10, 0, VPX_BITS_10),
|
||||||
&idct16x16_10, 0, VPX_BITS_10),
|
make_tuple(&vpx_highbd_fdct16x16_c, &idct16x16_256_add_10_sse2, 0,
|
||||||
make_tuple(&vpx_highbd_fdct16x16_c,
|
VPX_BITS_10),
|
||||||
&idct16x16_256_add_10_sse2, 0, VPX_BITS_10),
|
make_tuple(&vpx_highbd_fdct16x16_sse2, &idct16x16_12, 0, VPX_BITS_12),
|
||||||
make_tuple(&vpx_highbd_fdct16x16_sse2,
|
make_tuple(&vpx_highbd_fdct16x16_c, &idct16x16_256_add_12_sse2, 0,
|
||||||
&idct16x16_12, 0, VPX_BITS_12),
|
VPX_BITS_12),
|
||||||
make_tuple(&vpx_highbd_fdct16x16_c,
|
make_tuple(&vpx_fdct16x16_sse2, &vpx_idct16x16_256_add_c, 0,
|
||||||
&idct16x16_256_add_12_sse2, 0, VPX_BITS_12),
|
VPX_BITS_8)));
|
||||||
make_tuple(&vpx_fdct16x16_sse2,
|
|
||||||
&vpx_idct16x16_256_add_c, 0, VPX_BITS_8)));
|
|
||||||
INSTANTIATE_TEST_CASE_P(
|
INSTANTIATE_TEST_CASE_P(
|
||||||
SSE2, Trans16x16HT,
|
SSE2, Trans16x16HT,
|
||||||
::testing::Values(
|
::testing::Values(
|
||||||
@@ -959,26 +906,24 @@ INSTANTIATE_TEST_CASE_P(
|
|||||||
// that to test both branches.
|
// that to test both branches.
|
||||||
INSTANTIATE_TEST_CASE_P(
|
INSTANTIATE_TEST_CASE_P(
|
||||||
SSE2, InvTrans16x16DCT,
|
SSE2, InvTrans16x16DCT,
|
||||||
::testing::Values(
|
::testing::Values(make_tuple(&idct16x16_10_add_10_c,
|
||||||
make_tuple(&idct16x16_10_add_10_c,
|
|
||||||
&idct16x16_10_add_10_sse2, 3167, VPX_BITS_10),
|
&idct16x16_10_add_10_sse2, 3167, VPX_BITS_10),
|
||||||
make_tuple(&idct16x16_10,
|
make_tuple(&idct16x16_10, &idct16x16_256_add_10_sse2,
|
||||||
&idct16x16_256_add_10_sse2, 3167, VPX_BITS_10),
|
3167, VPX_BITS_10),
|
||||||
make_tuple(&idct16x16_10_add_12_c,
|
make_tuple(&idct16x16_10_add_12_c,
|
||||||
&idct16x16_10_add_12_sse2, 3167, VPX_BITS_12),
|
&idct16x16_10_add_12_sse2, 3167, VPX_BITS_12),
|
||||||
make_tuple(&idct16x16_12,
|
make_tuple(&idct16x16_12, &idct16x16_256_add_12_sse2,
|
||||||
&idct16x16_256_add_12_sse2, 3167, VPX_BITS_12)));
|
3167, VPX_BITS_12)));
|
||||||
INSTANTIATE_TEST_CASE_P(SSE2, PartialTrans16x16Test,
|
INSTANTIATE_TEST_CASE_P(SSE2, PartialTrans16x16Test,
|
||||||
::testing::Values(make_tuple(&vpx_fdct16x16_1_sse2,
|
::testing::Values(make_tuple(&vpx_fdct16x16_1_sse2,
|
||||||
VPX_BITS_8)));
|
VPX_BITS_8)));
|
||||||
#endif // HAVE_SSE2 && CONFIG_VP9_HIGHBITDEPTH && !CONFIG_EMULATE_HARDWARE
|
#endif // HAVE_SSE2 && CONFIG_VP9_HIGHBITDEPTH && !CONFIG_EMULATE_HARDWARE
|
||||||
|
|
||||||
#if HAVE_MSA && !CONFIG_VP9_HIGHBITDEPTH && !CONFIG_EMULATE_HARDWARE
|
#if HAVE_MSA && !CONFIG_VP9_HIGHBITDEPTH && !CONFIG_EMULATE_HARDWARE
|
||||||
INSTANTIATE_TEST_CASE_P(
|
INSTANTIATE_TEST_CASE_P(MSA, Trans16x16DCT,
|
||||||
MSA, Trans16x16DCT,
|
::testing::Values(make_tuple(&vpx_fdct16x16_msa,
|
||||||
::testing::Values(
|
&vpx_idct16x16_256_add_msa,
|
||||||
make_tuple(&vpx_fdct16x16_msa,
|
0, VPX_BITS_8)));
|
||||||
&vpx_idct16x16_256_add_msa, 0, VPX_BITS_8)));
|
|
||||||
INSTANTIATE_TEST_CASE_P(
|
INSTANTIATE_TEST_CASE_P(
|
||||||
MSA, Trans16x16HT,
|
MSA, Trans16x16HT,
|
||||||
::testing::Values(
|
::testing::Values(
|
||||||
|
|||||||
@@ -25,18 +25,11 @@
|
|||||||
#include "vpx/vpx_codec.h"
|
#include "vpx/vpx_codec.h"
|
||||||
#include "vpx/vpx_integer.h"
|
#include "vpx/vpx_integer.h"
|
||||||
#include "vpx_ports/mem.h"
|
#include "vpx_ports/mem.h"
|
||||||
|
#include "vpx_ports/msvc.h" // for round()
|
||||||
|
|
||||||
using libvpx_test::ACMRandom;
|
using libvpx_test::ACMRandom;
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
#ifdef _MSC_VER
|
|
||||||
static int round(double x) {
|
|
||||||
if (x < 0)
|
|
||||||
return static_cast<int>(ceil(x - 0.5));
|
|
||||||
else
|
|
||||||
return static_cast<int>(floor(x + 0.5));
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
const int kNumCoeffs = 1024;
|
const int kNumCoeffs = 1024;
|
||||||
const double kPi = 3.141592653589793238462643383279502884;
|
const double kPi = 3.141592653589793238462643383279502884;
|
||||||
@@ -44,10 +37,10 @@ void reference_32x32_dct_1d(const double in[32], double out[32]) {
|
|||||||
const double kInvSqrt2 = 0.707106781186547524400844362104;
|
const double kInvSqrt2 = 0.707106781186547524400844362104;
|
||||||
for (int k = 0; k < 32; k++) {
|
for (int k = 0; k < 32; k++) {
|
||||||
out[k] = 0.0;
|
out[k] = 0.0;
|
||||||
for (int n = 0; n < 32; n++)
|
for (int n = 0; n < 32; n++) {
|
||||||
out[k] += in[n] * cos(kPi * (2 * n + 1) * k / 64.0);
|
out[k] += in[n] * cos(kPi * (2 * n + 1) * k / 64.0);
|
||||||
if (k == 0)
|
}
|
||||||
out[k] = out[k] * kInvSqrt2;
|
if (k == 0) out[k] = out[k] * kInvSqrt2;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -56,21 +49,17 @@ void reference_32x32_dct_2d(const int16_t input[kNumCoeffs],
|
|||||||
// First transform columns
|
// First transform columns
|
||||||
for (int i = 0; i < 32; ++i) {
|
for (int i = 0; i < 32; ++i) {
|
||||||
double temp_in[32], temp_out[32];
|
double temp_in[32], temp_out[32];
|
||||||
for (int j = 0; j < 32; ++j)
|
for (int j = 0; j < 32; ++j) temp_in[j] = input[j * 32 + i];
|
||||||
temp_in[j] = input[j*32 + i];
|
|
||||||
reference_32x32_dct_1d(temp_in, temp_out);
|
reference_32x32_dct_1d(temp_in, temp_out);
|
||||||
for (int j = 0; j < 32; ++j)
|
for (int j = 0; j < 32; ++j) output[j * 32 + i] = temp_out[j];
|
||||||
output[j * 32 + i] = temp_out[j];
|
|
||||||
}
|
}
|
||||||
// Then transform rows
|
// Then transform rows
|
||||||
for (int i = 0; i < 32; ++i) {
|
for (int i = 0; i < 32; ++i) {
|
||||||
double temp_in[32], temp_out[32];
|
double temp_in[32], temp_out[32];
|
||||||
for (int j = 0; j < 32; ++j)
|
for (int j = 0; j < 32; ++j) temp_in[j] = output[j + i * 32];
|
||||||
temp_in[j] = output[j + i*32];
|
|
||||||
reference_32x32_dct_1d(temp_in, temp_out);
|
reference_32x32_dct_1d(temp_in, temp_out);
|
||||||
// Scale by some magic number
|
// Scale by some magic number
|
||||||
for (int j = 0; j < 32; ++j)
|
for (int j = 0; j < 32; ++j) output[j + i * 32] = temp_out[j] / 4;
|
||||||
output[j + i * 32] = temp_out[j] / 4;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -147,21 +136,20 @@ TEST_P(Trans32x32Test, AccuracyCheck) {
|
|||||||
ASM_REGISTER_STATE_CHECK(inv_txfm_(test_temp_block, dst, 32));
|
ASM_REGISTER_STATE_CHECK(inv_txfm_(test_temp_block, dst, 32));
|
||||||
#if CONFIG_VP9_HIGHBITDEPTH
|
#if CONFIG_VP9_HIGHBITDEPTH
|
||||||
} else {
|
} else {
|
||||||
ASM_REGISTER_STATE_CHECK(inv_txfm_(test_temp_block,
|
ASM_REGISTER_STATE_CHECK(
|
||||||
CONVERT_TO_BYTEPTR(dst16), 32));
|
inv_txfm_(test_temp_block, CONVERT_TO_BYTEPTR(dst16), 32));
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
for (int j = 0; j < kNumCoeffs; ++j) {
|
for (int j = 0; j < kNumCoeffs; ++j) {
|
||||||
#if CONFIG_VP9_HIGHBITDEPTH
|
#if CONFIG_VP9_HIGHBITDEPTH
|
||||||
const uint32_t diff =
|
const int32_t diff =
|
||||||
bit_depth_ == VPX_BITS_8 ? dst[j] - src[j] : dst16[j] - src16[j];
|
bit_depth_ == VPX_BITS_8 ? dst[j] - src[j] : dst16[j] - src16[j];
|
||||||
#else
|
#else
|
||||||
const uint32_t diff = dst[j] - src[j];
|
const int32_t diff = dst[j] - src[j];
|
||||||
#endif
|
#endif
|
||||||
const uint32_t error = diff * diff;
|
const uint32_t error = diff * diff;
|
||||||
if (max_error < error)
|
if (max_error < error) max_error = error;
|
||||||
max_error = error;
|
|
||||||
total_error += error;
|
total_error += error;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -187,8 +175,9 @@ TEST_P(Trans32x32Test, CoeffCheck) {
|
|||||||
DECLARE_ALIGNED(16, tran_low_t, output_block[kNumCoeffs]);
|
DECLARE_ALIGNED(16, tran_low_t, output_block[kNumCoeffs]);
|
||||||
|
|
||||||
for (int i = 0; i < count_test_block; ++i) {
|
for (int i = 0; i < count_test_block; ++i) {
|
||||||
for (int j = 0; j < kNumCoeffs; ++j)
|
for (int j = 0; j < kNumCoeffs; ++j) {
|
||||||
input_block[j] = (rnd.Rand16() & mask_) - (rnd.Rand16() & mask_);
|
input_block[j] = (rnd.Rand16() & mask_) - (rnd.Rand16() & mask_);
|
||||||
|
}
|
||||||
|
|
||||||
const int stride = 32;
|
const int stride = 32;
|
||||||
vpx_fdct32x32_c(input_block, output_ref_block, stride);
|
vpx_fdct32x32_c(input_block, output_ref_block, stride);
|
||||||
@@ -220,11 +209,9 @@ TEST_P(Trans32x32Test, MemCheck) {
|
|||||||
input_extreme_block[j] = rnd.Rand8() & 1 ? mask_ : -mask_;
|
input_extreme_block[j] = rnd.Rand8() & 1 ? mask_ : -mask_;
|
||||||
}
|
}
|
||||||
if (i == 0) {
|
if (i == 0) {
|
||||||
for (int j = 0; j < kNumCoeffs; ++j)
|
for (int j = 0; j < kNumCoeffs; ++j) input_extreme_block[j] = mask_;
|
||||||
input_extreme_block[j] = mask_;
|
|
||||||
} else if (i == 1) {
|
} else if (i == 1) {
|
||||||
for (int j = 0; j < kNumCoeffs; ++j)
|
for (int j = 0; j < kNumCoeffs; ++j) input_extreme_block[j] = -mask_;
|
||||||
input_extreme_block[j] = -mask_;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const int stride = 32;
|
const int stride = 32;
|
||||||
@@ -281,8 +268,9 @@ TEST_P(Trans32x32Test, InverseAccuracy) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
reference_32x32_dct_2d(in, out_r);
|
reference_32x32_dct_2d(in, out_r);
|
||||||
for (int j = 0; j < kNumCoeffs; ++j)
|
for (int j = 0; j < kNumCoeffs; ++j) {
|
||||||
coeff[j] = static_cast<tran_low_t>(round(out_r[j]));
|
coeff[j] = static_cast<tran_low_t>(round(out_r[j]));
|
||||||
|
}
|
||||||
if (bit_depth_ == VPX_BITS_8) {
|
if (bit_depth_ == VPX_BITS_8) {
|
||||||
ASM_REGISTER_STATE_CHECK(inv_txfm_(coeff, dst, 32));
|
ASM_REGISTER_STATE_CHECK(inv_txfm_(coeff, dst, 32));
|
||||||
#if CONFIG_VP9_HIGHBITDEPTH
|
#if CONFIG_VP9_HIGHBITDEPTH
|
||||||
@@ -298,8 +286,7 @@ TEST_P(Trans32x32Test, InverseAccuracy) {
|
|||||||
const int diff = dst[j] - src[j];
|
const int diff = dst[j] - src[j];
|
||||||
#endif
|
#endif
|
||||||
const int error = diff * diff;
|
const int error = diff * diff;
|
||||||
EXPECT_GE(1, error)
|
EXPECT_GE(1, error) << "Error: 32x32 IDCT has error " << error
|
||||||
<< "Error: 32x32 IDCT has error " << error
|
|
||||||
<< " at index " << j;
|
<< " at index " << j;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -372,18 +359,13 @@ using std::tr1::make_tuple;
|
|||||||
INSTANTIATE_TEST_CASE_P(
|
INSTANTIATE_TEST_CASE_P(
|
||||||
C, Trans32x32Test,
|
C, Trans32x32Test,
|
||||||
::testing::Values(
|
::testing::Values(
|
||||||
make_tuple(&vpx_highbd_fdct32x32_c,
|
make_tuple(&vpx_highbd_fdct32x32_c, &idct32x32_10, 0, VPX_BITS_10),
|
||||||
&idct32x32_10, 0, VPX_BITS_10),
|
make_tuple(&vpx_highbd_fdct32x32_rd_c, &idct32x32_10, 1, VPX_BITS_10),
|
||||||
make_tuple(&vpx_highbd_fdct32x32_rd_c,
|
make_tuple(&vpx_highbd_fdct32x32_c, &idct32x32_12, 0, VPX_BITS_12),
|
||||||
&idct32x32_10, 1, VPX_BITS_10),
|
make_tuple(&vpx_highbd_fdct32x32_rd_c, &idct32x32_12, 1, VPX_BITS_12),
|
||||||
make_tuple(&vpx_highbd_fdct32x32_c,
|
make_tuple(&vpx_fdct32x32_c, &vpx_idct32x32_1024_add_c, 0, VPX_BITS_8),
|
||||||
&idct32x32_12, 0, VPX_BITS_12),
|
make_tuple(&vpx_fdct32x32_rd_c, &vpx_idct32x32_1024_add_c, 1,
|
||||||
make_tuple(&vpx_highbd_fdct32x32_rd_c,
|
VPX_BITS_8)));
|
||||||
&idct32x32_12, 1, VPX_BITS_12),
|
|
||||||
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(
|
INSTANTIATE_TEST_CASE_P(
|
||||||
C, PartialTrans32x32Test,
|
C, PartialTrans32x32Test,
|
||||||
::testing::Values(make_tuple(&vpx_highbd_fdct32x32_1_c, VPX_BITS_8),
|
::testing::Values(make_tuple(&vpx_highbd_fdct32x32_1_c, VPX_BITS_8),
|
||||||
@@ -392,11 +374,10 @@ INSTANTIATE_TEST_CASE_P(
|
|||||||
#else
|
#else
|
||||||
INSTANTIATE_TEST_CASE_P(
|
INSTANTIATE_TEST_CASE_P(
|
||||||
C, Trans32x32Test,
|
C, Trans32x32Test,
|
||||||
::testing::Values(
|
::testing::Values(make_tuple(&vpx_fdct32x32_c, &vpx_idct32x32_1024_add_c, 0,
|
||||||
make_tuple(&vpx_fdct32x32_c,
|
VPX_BITS_8),
|
||||||
&vpx_idct32x32_1024_add_c, 0, VPX_BITS_8),
|
make_tuple(&vpx_fdct32x32_rd_c, &vpx_idct32x32_1024_add_c,
|
||||||
make_tuple(&vpx_fdct32x32_rd_c,
|
1, VPX_BITS_8)));
|
||||||
&vpx_idct32x32_1024_add_c, 1, VPX_BITS_8)));
|
|
||||||
INSTANTIATE_TEST_CASE_P(C, PartialTrans32x32Test,
|
INSTANTIATE_TEST_CASE_P(C, PartialTrans32x32Test,
|
||||||
::testing::Values(make_tuple(&vpx_fdct32x32_1_c,
|
::testing::Values(make_tuple(&vpx_fdct32x32_1_c,
|
||||||
VPX_BITS_8)));
|
VPX_BITS_8)));
|
||||||
@@ -405,9 +386,8 @@ INSTANTIATE_TEST_CASE_P(C, PartialTrans32x32Test,
|
|||||||
#if HAVE_NEON && !CONFIG_VP9_HIGHBITDEPTH && !CONFIG_EMULATE_HARDWARE
|
#if HAVE_NEON && !CONFIG_VP9_HIGHBITDEPTH && !CONFIG_EMULATE_HARDWARE
|
||||||
INSTANTIATE_TEST_CASE_P(
|
INSTANTIATE_TEST_CASE_P(
|
||||||
NEON, Trans32x32Test,
|
NEON, Trans32x32Test,
|
||||||
::testing::Values(
|
::testing::Values(make_tuple(&vpx_fdct32x32_c, &vpx_idct32x32_1024_add_neon,
|
||||||
make_tuple(&vpx_fdct32x32_c,
|
0, VPX_BITS_8),
|
||||||
&vpx_idct32x32_1024_add_neon, 0, VPX_BITS_8),
|
|
||||||
make_tuple(&vpx_fdct32x32_rd_c,
|
make_tuple(&vpx_fdct32x32_rd_c,
|
||||||
&vpx_idct32x32_1024_add_neon, 1, VPX_BITS_8)));
|
&vpx_idct32x32_1024_add_neon, 1, VPX_BITS_8)));
|
||||||
#endif // HAVE_NEON && !CONFIG_VP9_HIGHBITDEPTH && !CONFIG_EMULATE_HARDWARE
|
#endif // HAVE_NEON && !CONFIG_VP9_HIGHBITDEPTH && !CONFIG_EMULATE_HARDWARE
|
||||||
@@ -415,8 +395,7 @@ INSTANTIATE_TEST_CASE_P(
|
|||||||
#if HAVE_SSE2 && !CONFIG_VP9_HIGHBITDEPTH && !CONFIG_EMULATE_HARDWARE
|
#if HAVE_SSE2 && !CONFIG_VP9_HIGHBITDEPTH && !CONFIG_EMULATE_HARDWARE
|
||||||
INSTANTIATE_TEST_CASE_P(
|
INSTANTIATE_TEST_CASE_P(
|
||||||
SSE2, Trans32x32Test,
|
SSE2, Trans32x32Test,
|
||||||
::testing::Values(
|
::testing::Values(make_tuple(&vpx_fdct32x32_sse2,
|
||||||
make_tuple(&vpx_fdct32x32_sse2,
|
|
||||||
&vpx_idct32x32_1024_add_sse2, 0, VPX_BITS_8),
|
&vpx_idct32x32_1024_add_sse2, 0, VPX_BITS_8),
|
||||||
make_tuple(&vpx_fdct32x32_rd_sse2,
|
make_tuple(&vpx_fdct32x32_rd_sse2,
|
||||||
&vpx_idct32x32_1024_add_sse2, 1, VPX_BITS_8)));
|
&vpx_idct32x32_1024_add_sse2, 1, VPX_BITS_8)));
|
||||||
@@ -447,8 +426,7 @@ INSTANTIATE_TEST_CASE_P(SSE2, PartialTrans32x32Test,
|
|||||||
#if HAVE_AVX2 && !CONFIG_VP9_HIGHBITDEPTH && !CONFIG_EMULATE_HARDWARE
|
#if HAVE_AVX2 && !CONFIG_VP9_HIGHBITDEPTH && !CONFIG_EMULATE_HARDWARE
|
||||||
INSTANTIATE_TEST_CASE_P(
|
INSTANTIATE_TEST_CASE_P(
|
||||||
AVX2, Trans32x32Test,
|
AVX2, Trans32x32Test,
|
||||||
::testing::Values(
|
::testing::Values(make_tuple(&vpx_fdct32x32_avx2,
|
||||||
make_tuple(&vpx_fdct32x32_avx2,
|
|
||||||
&vpx_idct32x32_1024_add_sse2, 0, VPX_BITS_8),
|
&vpx_idct32x32_1024_add_sse2, 0, VPX_BITS_8),
|
||||||
make_tuple(&vpx_fdct32x32_rd_avx2,
|
make_tuple(&vpx_fdct32x32_rd_avx2,
|
||||||
&vpx_idct32x32_1024_add_sse2, 1, VPX_BITS_8)));
|
&vpx_idct32x32_1024_add_sse2, 1, VPX_BITS_8)));
|
||||||
@@ -457,8 +435,7 @@ INSTANTIATE_TEST_CASE_P(
|
|||||||
#if HAVE_MSA && !CONFIG_VP9_HIGHBITDEPTH && !CONFIG_EMULATE_HARDWARE
|
#if HAVE_MSA && !CONFIG_VP9_HIGHBITDEPTH && !CONFIG_EMULATE_HARDWARE
|
||||||
INSTANTIATE_TEST_CASE_P(
|
INSTANTIATE_TEST_CASE_P(
|
||||||
MSA, Trans32x32Test,
|
MSA, Trans32x32Test,
|
||||||
::testing::Values(
|
::testing::Values(make_tuple(&vpx_fdct32x32_msa,
|
||||||
make_tuple(&vpx_fdct32x32_msa,
|
|
||||||
&vpx_idct32x32_1024_add_msa, 0, VPX_BITS_8),
|
&vpx_idct32x32_1024_add_msa, 0, VPX_BITS_8),
|
||||||
make_tuple(&vpx_fdct32x32_rd_msa,
|
make_tuple(&vpx_fdct32x32_rd_msa,
|
||||||
&vpx_idct32x32_1024_add_msa, 1, VPX_BITS_8)));
|
&vpx_idct32x32_1024_add_msa, 1, VPX_BITS_8)));
|
||||||
|
|||||||
@@ -26,9 +26,6 @@ TEST(DecodeAPI, InvalidParams) {
|
|||||||
#endif
|
#endif
|
||||||
#if CONFIG_VP9_DECODER
|
#if CONFIG_VP9_DECODER
|
||||||
&vpx_codec_vp9_dx_algo,
|
&vpx_codec_vp9_dx_algo,
|
||||||
#endif
|
|
||||||
#if CONFIG_VP10_DECODER
|
|
||||||
&vpx_codec_vp10_dx_algo,
|
|
||||||
#endif
|
#endif
|
||||||
};
|
};
|
||||||
uint8_t buf[1] = { 0 };
|
uint8_t buf[1] = { 0 };
|
||||||
@@ -54,8 +51,7 @@ TEST(DecodeAPI, InvalidParams) {
|
|||||||
vpx_codec_decode(&dec, buf, NELEMENTS(buf), NULL, 0));
|
vpx_codec_decode(&dec, buf, NELEMENTS(buf), NULL, 0));
|
||||||
EXPECT_EQ(VPX_CODEC_INVALID_PARAM,
|
EXPECT_EQ(VPX_CODEC_INVALID_PARAM,
|
||||||
vpx_codec_decode(&dec, NULL, NELEMENTS(buf), NULL, 0));
|
vpx_codec_decode(&dec, NULL, NELEMENTS(buf), NULL, 0));
|
||||||
EXPECT_EQ(VPX_CODEC_INVALID_PARAM,
|
EXPECT_EQ(VPX_CODEC_INVALID_PARAM, vpx_codec_decode(&dec, buf, 0, NULL, 0));
|
||||||
vpx_codec_decode(&dec, buf, 0, NULL, 0));
|
|
||||||
|
|
||||||
EXPECT_EQ(VPX_CODEC_OK, vpx_codec_destroy(&dec));
|
EXPECT_EQ(VPX_CODEC_OK, vpx_codec_destroy(&dec));
|
||||||
}
|
}
|
||||||
@@ -80,12 +76,9 @@ TEST(DecodeAPI, OptionalParams) {
|
|||||||
// Test VP9 codec controls after a decode error to ensure the code doesn't
|
// Test VP9 codec controls after a decode error to ensure the code doesn't
|
||||||
// misbehave.
|
// misbehave.
|
||||||
void TestVp9Controls(vpx_codec_ctx_t *dec) {
|
void TestVp9Controls(vpx_codec_ctx_t *dec) {
|
||||||
static const int kControls[] = {
|
static const int kControls[] = { VP8D_GET_LAST_REF_UPDATES,
|
||||||
VP8D_GET_LAST_REF_UPDATES,
|
|
||||||
VP8D_GET_FRAME_CORRUPTED,
|
VP8D_GET_FRAME_CORRUPTED,
|
||||||
VP9D_GET_DISPLAY_SIZE,
|
VP9D_GET_DISPLAY_SIZE, VP9D_GET_FRAME_SIZE };
|
||||||
VP9D_GET_FRAME_SIZE
|
|
||||||
};
|
|
||||||
int val[2];
|
int val[2];
|
||||||
|
|
||||||
for (int i = 0; i < NELEMENTS(kControls); ++i) {
|
for (int i = 0; i < NELEMENTS(kControls); ++i) {
|
||||||
@@ -94,9 +87,7 @@ void TestVp9Controls(vpx_codec_ctx_t *dec) {
|
|||||||
case VP8D_GET_FRAME_CORRUPTED:
|
case VP8D_GET_FRAME_CORRUPTED:
|
||||||
EXPECT_EQ(VPX_CODEC_ERROR, res) << kControls[i];
|
EXPECT_EQ(VPX_CODEC_ERROR, res) << kControls[i];
|
||||||
break;
|
break;
|
||||||
default:
|
default: EXPECT_EQ(VPX_CODEC_OK, res) << kControls[i]; break;
|
||||||
EXPECT_EQ(VPX_CODEC_OK, res) << kControls[i];
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
EXPECT_EQ(VPX_CODEC_INVALID_PARAM,
|
EXPECT_EQ(VPX_CODEC_INVALID_PARAM,
|
||||||
vpx_codec_control_(dec, kControls[i], NULL));
|
vpx_codec_control_(dec, kControls[i], NULL));
|
||||||
@@ -146,6 +137,39 @@ TEST(DecodeAPI, Vp9InvalidDecode) {
|
|||||||
TestVp9Controls(&dec);
|
TestVp9Controls(&dec);
|
||||||
EXPECT_EQ(VPX_CODEC_OK, vpx_codec_destroy(&dec));
|
EXPECT_EQ(VPX_CODEC_OK, vpx_codec_destroy(&dec));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TEST(DecodeAPI, Vp9PeekSI) {
|
||||||
|
const vpx_codec_iface_t *const codec = &vpx_codec_vp9_dx_algo;
|
||||||
|
// The first 9 bytes are valid and the rest of the bytes are made up. Until
|
||||||
|
// size 10, this should return VPX_CODEC_UNSUP_BITSTREAM and after that it
|
||||||
|
// should return VPX_CODEC_CORRUPT_FRAME.
|
||||||
|
const uint8_t data[32] = {
|
||||||
|
0x85, 0xa4, 0xc1, 0xa1, 0x38, 0x81, 0xa3, 0x49, 0x83, 0xff, 0xff,
|
||||||
|
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||||
|
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||||
|
};
|
||||||
|
|
||||||
|
for (uint32_t data_sz = 1; data_sz <= 32; ++data_sz) {
|
||||||
|
// Verify behavior of vpx_codec_decode. vpx_codec_decode doesn't even get
|
||||||
|
// to decoder_peek_si_internal on frames of size < 8.
|
||||||
|
if (data_sz >= 8) {
|
||||||
|
vpx_codec_ctx_t dec;
|
||||||
|
EXPECT_EQ(VPX_CODEC_OK, vpx_codec_dec_init(&dec, codec, NULL, 0));
|
||||||
|
EXPECT_EQ(
|
||||||
|
(data_sz < 10) ? VPX_CODEC_UNSUP_BITSTREAM : VPX_CODEC_CORRUPT_FRAME,
|
||||||
|
vpx_codec_decode(&dec, data, data_sz, NULL, 0));
|
||||||
|
vpx_codec_iter_t iter = NULL;
|
||||||
|
EXPECT_EQ(NULL, vpx_codec_get_frame(&dec, &iter));
|
||||||
|
EXPECT_EQ(VPX_CODEC_OK, vpx_codec_destroy(&dec));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Verify behavior of vpx_codec_peek_stream_info.
|
||||||
|
vpx_codec_stream_info_t si;
|
||||||
|
si.sz = sizeof(si);
|
||||||
|
EXPECT_EQ((data_sz < 10) ? VPX_CODEC_UNSUP_BITSTREAM : VPX_CODEC_OK,
|
||||||
|
vpx_codec_peek_stream_info(codec, data, data_sz, &si));
|
||||||
|
}
|
||||||
|
}
|
||||||
#endif // CONFIG_VP9_DECODER
|
#endif // CONFIG_VP9_DECODER
|
||||||
|
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|||||||
@@ -28,7 +28,6 @@ namespace {
|
|||||||
#define VIDEO_NAME 0
|
#define VIDEO_NAME 0
|
||||||
#define THREADS 1
|
#define THREADS 1
|
||||||
|
|
||||||
const int kMaxPsnr = 100;
|
|
||||||
const double kUsecsInSec = 1000000.0;
|
const double kUsecsInSec = 1000000.0;
|
||||||
const char kNewEncodeOutputFile[] = "new_encode.ivf";
|
const char kNewEncodeOutputFile[] = "new_encode.ivf";
|
||||||
|
|
||||||
@@ -70,8 +69,7 @@ const DecodePerfParam kVP9DecodePerfVectors[] = {
|
|||||||
power/temp/min max frame decode times/etc
|
power/temp/min max frame decode times/etc
|
||||||
*/
|
*/
|
||||||
|
|
||||||
class DecodePerfTest : public ::testing::TestWithParam<DecodePerfParam> {
|
class DecodePerfTest : public ::testing::TestWithParam<DecodePerfParam> {};
|
||||||
};
|
|
||||||
|
|
||||||
TEST_P(DecodePerfTest, PerfTest) {
|
TEST_P(DecodePerfTest, PerfTest) {
|
||||||
const char *const video_name = GET_PARAM(VIDEO_NAME);
|
const char *const video_name = GET_PARAM(VIDEO_NAME);
|
||||||
@@ -92,8 +90,7 @@ TEST_P(DecodePerfTest, PerfTest) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
vpx_usec_timer_mark(&t);
|
vpx_usec_timer_mark(&t);
|
||||||
const double elapsed_secs = double(vpx_usec_timer_elapsed(&t))
|
const double elapsed_secs = double(vpx_usec_timer_elapsed(&t)) / kUsecsInSec;
|
||||||
/ kUsecsInSec;
|
|
||||||
const unsigned frames = video.frame_number();
|
const unsigned frames = video.frame_number();
|
||||||
const double fps = double(frames) / elapsed_secs;
|
const double fps = double(frames) / elapsed_secs;
|
||||||
|
|
||||||
@@ -111,17 +108,13 @@ TEST_P(DecodePerfTest, PerfTest) {
|
|||||||
INSTANTIATE_TEST_CASE_P(VP9, DecodePerfTest,
|
INSTANTIATE_TEST_CASE_P(VP9, DecodePerfTest,
|
||||||
::testing::ValuesIn(kVP9DecodePerfVectors));
|
::testing::ValuesIn(kVP9DecodePerfVectors));
|
||||||
|
|
||||||
class VP9NewEncodeDecodePerfTest :
|
class VP9NewEncodeDecodePerfTest
|
||||||
public ::libvpx_test::EncoderTest,
|
: public ::libvpx_test::EncoderTest,
|
||||||
public ::libvpx_test::CodecTestWithParam<libvpx_test::TestMode> {
|
public ::libvpx_test::CodecTestWithParam<libvpx_test::TestMode> {
|
||||||
protected:
|
protected:
|
||||||
VP9NewEncodeDecodePerfTest()
|
VP9NewEncodeDecodePerfTest()
|
||||||
: EncoderTest(GET_PARAM(0)),
|
: EncoderTest(GET_PARAM(0)), encoding_mode_(GET_PARAM(1)), speed_(0),
|
||||||
encoding_mode_(GET_PARAM(1)),
|
outfile_(0), out_frames_(0) {}
|
||||||
speed_(0),
|
|
||||||
outfile_(0),
|
|
||||||
out_frames_(0) {
|
|
||||||
}
|
|
||||||
|
|
||||||
virtual ~VP9NewEncodeDecodePerfTest() {}
|
virtual ~VP9NewEncodeDecodePerfTest() {}
|
||||||
|
|
||||||
@@ -160,8 +153,9 @@ class VP9NewEncodeDecodePerfTest :
|
|||||||
|
|
||||||
virtual void EndPassHook() {
|
virtual void EndPassHook() {
|
||||||
if (outfile_ != NULL) {
|
if (outfile_ != NULL) {
|
||||||
if (!fseek(outfile_, 0, SEEK_SET))
|
if (!fseek(outfile_, 0, SEEK_SET)) {
|
||||||
ivf_write_file_header(outfile_, &cfg_, VP9_FOURCC, out_frames_);
|
ivf_write_file_header(outfile_, &cfg_, VP9_FOURCC, out_frames_);
|
||||||
|
}
|
||||||
fclose(outfile_);
|
fclose(outfile_);
|
||||||
outfile_ = NULL;
|
outfile_ = NULL;
|
||||||
}
|
}
|
||||||
@@ -171,8 +165,9 @@ class VP9NewEncodeDecodePerfTest :
|
|||||||
++out_frames_;
|
++out_frames_;
|
||||||
|
|
||||||
// Write initial file header if first frame.
|
// Write initial file header if first frame.
|
||||||
if (pkt->data.frame.pts == 0)
|
if (pkt->data.frame.pts == 0) {
|
||||||
ivf_write_file_header(outfile_, &cfg_, VP9_FOURCC, out_frames_);
|
ivf_write_file_header(outfile_, &cfg_, VP9_FOURCC, out_frames_);
|
||||||
|
}
|
||||||
|
|
||||||
// Write frame header and data.
|
// Write frame header and data.
|
||||||
ivf_write_frame_header(outfile_, out_frames_, pkt->data.frame.sz);
|
ivf_write_frame_header(outfile_, out_frames_, pkt->data.frame.sz);
|
||||||
@@ -180,11 +175,9 @@ class VP9NewEncodeDecodePerfTest :
|
|||||||
pkt->data.frame.sz);
|
pkt->data.frame.sz);
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual bool DoDecode() { return false; }
|
virtual bool DoDecode() const { return false; }
|
||||||
|
|
||||||
void set_speed(unsigned int speed) {
|
void set_speed(unsigned int speed) { speed_ = speed; }
|
||||||
speed_ = speed;
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
libvpx_test::TestMode encoding_mode_;
|
libvpx_test::TestMode encoding_mode_;
|
||||||
@@ -196,10 +189,7 @@ class VP9NewEncodeDecodePerfTest :
|
|||||||
struct EncodePerfTestVideo {
|
struct EncodePerfTestVideo {
|
||||||
EncodePerfTestVideo(const char *name_, uint32_t width_, uint32_t height_,
|
EncodePerfTestVideo(const char *name_, uint32_t width_, uint32_t height_,
|
||||||
uint32_t bitrate_, int frames_)
|
uint32_t bitrate_, int frames_)
|
||||||
: name(name_),
|
: name(name_), width(width_), height(height_), bitrate(bitrate_),
|
||||||
width(width_),
|
|
||||||
height(height_),
|
|
||||||
bitrate(bitrate_),
|
|
||||||
frames(frames_) {}
|
frames(frames_) {}
|
||||||
const char *name;
|
const char *name;
|
||||||
uint32_t width;
|
uint32_t width;
|
||||||
@@ -225,10 +215,8 @@ TEST_P(VP9NewEncodeDecodePerfTest, PerfTest) {
|
|||||||
|
|
||||||
const char *video_name = kVP9EncodePerfTestVectors[i].name;
|
const char *video_name = kVP9EncodePerfTestVectors[i].name;
|
||||||
libvpx_test::I420VideoSource video(
|
libvpx_test::I420VideoSource video(
|
||||||
video_name,
|
video_name, kVP9EncodePerfTestVectors[i].width,
|
||||||
kVP9EncodePerfTestVectors[i].width,
|
kVP9EncodePerfTestVectors[i].height, timebase.den, timebase.num, 0,
|
||||||
kVP9EncodePerfTestVectors[i].height,
|
|
||||||
timebase.den, timebase.num, 0,
|
|
||||||
kVP9EncodePerfTestVectors[i].frames);
|
kVP9EncodePerfTestVectors[i].frames);
|
||||||
set_speed(2);
|
set_speed(2);
|
||||||
|
|
||||||
@@ -268,6 +256,6 @@ TEST_P(VP9NewEncodeDecodePerfTest, PerfTest) {
|
|||||||
printf("}\n");
|
printf("}\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
VP9_INSTANTIATE_TEST_CASE(
|
VP9_INSTANTIATE_TEST_CASE(VP9NewEncodeDecodePerfTest,
|
||||||
VP9NewEncodeDecodePerfTest, ::testing::Values(::libvpx_test::kTwoPassGood));
|
::testing::Values(::libvpx_test::kTwoPassGood));
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|||||||
124
test/decode_svc_test.cc
Normal file
124
test/decode_svc_test.cc
Normal file
@@ -0,0 +1,124 @@
|
|||||||
|
/*
|
||||||
|
* 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 <string>
|
||||||
|
|
||||||
|
#include "test/codec_factory.h"
|
||||||
|
#include "test/decode_test_driver.h"
|
||||||
|
#include "test/ivf_video_source.h"
|
||||||
|
#include "test/test_vectors.h"
|
||||||
|
#include "test/util.h"
|
||||||
|
|
||||||
|
namespace {
|
||||||
|
|
||||||
|
const unsigned int kNumFrames = 19;
|
||||||
|
|
||||||
|
class DecodeSvcTest : public ::libvpx_test::DecoderTest,
|
||||||
|
public ::libvpx_test::CodecTestWithParam<const char *> {
|
||||||
|
protected:
|
||||||
|
DecodeSvcTest() : DecoderTest(GET_PARAM(::libvpx_test::kCodecFactoryParam)) {}
|
||||||
|
virtual ~DecodeSvcTest() {}
|
||||||
|
|
||||||
|
virtual void PreDecodeFrameHook(
|
||||||
|
const libvpx_test::CompressedVideoSource &video,
|
||||||
|
libvpx_test::Decoder *decoder) {
|
||||||
|
if (video.frame_number() == 0)
|
||||||
|
decoder->Control(VP9_DECODE_SVC_SPATIAL_LAYER, spatial_layer_);
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual void DecompressedFrameHook(const vpx_image_t &img,
|
||||||
|
const unsigned int frame_number) {
|
||||||
|
ASSERT_EQ(img.d_w, width_);
|
||||||
|
ASSERT_EQ(img.d_h, height_);
|
||||||
|
total_frames_ = frame_number;
|
||||||
|
}
|
||||||
|
|
||||||
|
int spatial_layer_;
|
||||||
|
unsigned int width_;
|
||||||
|
unsigned int height_;
|
||||||
|
unsigned int total_frames_;
|
||||||
|
};
|
||||||
|
|
||||||
|
// SVC test vector is 1280x720, with 3 spatial layers, and 20 frames.
|
||||||
|
|
||||||
|
// Decode the SVC test vector, which has 3 spatial layers, and decode up to
|
||||||
|
// spatial layer 0. Verify the resolution of each decoded frame and the total
|
||||||
|
// number of frames decoded. This results in 1/4x1/4 resolution (320x180).
|
||||||
|
TEST_P(DecodeSvcTest, DecodeSvcTestUpToSpatialLayer0) {
|
||||||
|
const std::string filename = GET_PARAM(1);
|
||||||
|
testing::internal::scoped_ptr<libvpx_test::CompressedVideoSource> video;
|
||||||
|
video.reset(new libvpx_test::IVFVideoSource(filename));
|
||||||
|
ASSERT_TRUE(video.get() != NULL);
|
||||||
|
video->Init();
|
||||||
|
total_frames_ = 0;
|
||||||
|
spatial_layer_ = 0;
|
||||||
|
width_ = 320;
|
||||||
|
height_ = 180;
|
||||||
|
ASSERT_NO_FATAL_FAILURE(RunLoop(video.get()));
|
||||||
|
ASSERT_EQ(total_frames_, kNumFrames);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Decode the SVC test vector, which has 3 spatial layers, and decode up to
|
||||||
|
// spatial layer 1. Verify the resolution of each decoded frame and the total
|
||||||
|
// number of frames decoded. This results in 1/2x1/2 resolution (640x360).
|
||||||
|
TEST_P(DecodeSvcTest, DecodeSvcTestUpToSpatialLayer1) {
|
||||||
|
const std::string filename = GET_PARAM(1);
|
||||||
|
testing::internal::scoped_ptr<libvpx_test::CompressedVideoSource> video;
|
||||||
|
video.reset(new libvpx_test::IVFVideoSource(filename));
|
||||||
|
ASSERT_TRUE(video.get() != NULL);
|
||||||
|
video->Init();
|
||||||
|
total_frames_ = 0;
|
||||||
|
spatial_layer_ = 1;
|
||||||
|
width_ = 640;
|
||||||
|
height_ = 360;
|
||||||
|
ASSERT_NO_FATAL_FAILURE(RunLoop(video.get()));
|
||||||
|
ASSERT_EQ(total_frames_, kNumFrames);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Decode the SVC test vector, which has 3 spatial layers, and decode up to
|
||||||
|
// spatial layer 2. Verify the resolution of each decoded frame and the total
|
||||||
|
// number of frames decoded. This results in the full resolution (1280x720).
|
||||||
|
TEST_P(DecodeSvcTest, DecodeSvcTestUpToSpatialLayer2) {
|
||||||
|
const std::string filename = GET_PARAM(1);
|
||||||
|
testing::internal::scoped_ptr<libvpx_test::CompressedVideoSource> video;
|
||||||
|
video.reset(new libvpx_test::IVFVideoSource(filename));
|
||||||
|
ASSERT_TRUE(video.get() != NULL);
|
||||||
|
video->Init();
|
||||||
|
total_frames_ = 0;
|
||||||
|
spatial_layer_ = 2;
|
||||||
|
width_ = 1280;
|
||||||
|
height_ = 720;
|
||||||
|
ASSERT_NO_FATAL_FAILURE(RunLoop(video.get()));
|
||||||
|
ASSERT_EQ(total_frames_, kNumFrames);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Decode the SVC test vector, which has 3 spatial layers, and decode up to
|
||||||
|
// spatial layer 10. Verify the resolution of each decoded frame and the total
|
||||||
|
// number of frames decoded. This is beyond the number of spatial layers, so
|
||||||
|
// the decoding should result in the full resolution (1280x720).
|
||||||
|
TEST_P(DecodeSvcTest, DecodeSvcTestUpToSpatialLayer10) {
|
||||||
|
const std::string filename = GET_PARAM(1);
|
||||||
|
testing::internal::scoped_ptr<libvpx_test::CompressedVideoSource> video;
|
||||||
|
video.reset(new libvpx_test::IVFVideoSource(filename));
|
||||||
|
ASSERT_TRUE(video.get() != NULL);
|
||||||
|
video->Init();
|
||||||
|
total_frames_ = 0;
|
||||||
|
spatial_layer_ = 10;
|
||||||
|
width_ = 1280;
|
||||||
|
height_ = 720;
|
||||||
|
ASSERT_NO_FATAL_FAILURE(RunLoop(video.get()));
|
||||||
|
ASSERT_EQ(total_frames_, kNumFrames);
|
||||||
|
}
|
||||||
|
|
||||||
|
VP9_INSTANTIATE_TEST_CASE(
|
||||||
|
DecodeSvcTest, ::testing::ValuesIn(libvpx_test::kVP9TestVectorsSvc,
|
||||||
|
libvpx_test::kVP9TestVectorsSvc +
|
||||||
|
libvpx_test::kNumVP9TestVectorsSvc));
|
||||||
|
} // namespace
|
||||||
@@ -21,9 +21,8 @@ const char kVP8Name[] = "WebM Project VP8";
|
|||||||
|
|
||||||
vpx_codec_err_t Decoder::PeekStream(const uint8_t *cxdata, size_t size,
|
vpx_codec_err_t Decoder::PeekStream(const uint8_t *cxdata, size_t size,
|
||||||
vpx_codec_stream_info_t *stream_info) {
|
vpx_codec_stream_info_t *stream_info) {
|
||||||
return vpx_codec_peek_stream_info(CodecInterface(),
|
return vpx_codec_peek_stream_info(
|
||||||
cxdata, static_cast<unsigned int>(size),
|
CodecInterface(), cxdata, static_cast<unsigned int>(size), stream_info);
|
||||||
stream_info);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
vpx_codec_err_t Decoder::DecodeFrame(const uint8_t *cxdata, size_t size) {
|
vpx_codec_err_t Decoder::DecodeFrame(const uint8_t *cxdata, size_t size) {
|
||||||
@@ -35,9 +34,8 @@ vpx_codec_err_t Decoder::DecodeFrame(const uint8_t *cxdata, size_t size,
|
|||||||
vpx_codec_err_t res_dec;
|
vpx_codec_err_t res_dec;
|
||||||
InitOnce();
|
InitOnce();
|
||||||
API_REGISTER_STATE_CHECK(
|
API_REGISTER_STATE_CHECK(
|
||||||
res_dec = vpx_codec_decode(&decoder_,
|
res_dec = vpx_codec_decode(
|
||||||
cxdata, static_cast<unsigned int>(size),
|
&decoder_, cxdata, static_cast<unsigned int>(size), user_priv, 0));
|
||||||
user_priv, 0));
|
|
||||||
return res_dec;
|
return res_dec;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -67,7 +65,7 @@ void DecoderTest::HandlePeekResult(Decoder *const decoder,
|
|||||||
|
|
||||||
void DecoderTest::RunLoop(CompressedVideoSource *video,
|
void DecoderTest::RunLoop(CompressedVideoSource *video,
|
||||||
const vpx_codec_dec_cfg_t &dec_cfg) {
|
const vpx_codec_dec_cfg_t &dec_cfg) {
|
||||||
Decoder* const decoder = codec_->CreateDecoder(dec_cfg, flags_, 0);
|
Decoder *const decoder = codec_->CreateDecoder(dec_cfg, flags_);
|
||||||
ASSERT_TRUE(decoder != NULL);
|
ASSERT_TRUE(decoder != NULL);
|
||||||
bool end_of_file = false;
|
bool end_of_file = false;
|
||||||
|
|
||||||
@@ -80,16 +78,14 @@ void DecoderTest::RunLoop(CompressedVideoSource *video,
|
|||||||
stream_info.sz = sizeof(stream_info);
|
stream_info.sz = sizeof(stream_info);
|
||||||
|
|
||||||
if (video->cxdata() != NULL) {
|
if (video->cxdata() != NULL) {
|
||||||
const vpx_codec_err_t res_peek = decoder->PeekStream(video->cxdata(),
|
const vpx_codec_err_t res_peek = decoder->PeekStream(
|
||||||
video->frame_size(),
|
video->cxdata(), video->frame_size(), &stream_info);
|
||||||
&stream_info);
|
|
||||||
HandlePeekResult(decoder, video, res_peek);
|
HandlePeekResult(decoder, video, res_peek);
|
||||||
ASSERT_FALSE(::testing::Test::HasFailure());
|
ASSERT_FALSE(::testing::Test::HasFailure());
|
||||||
|
|
||||||
vpx_codec_err_t res_dec = decoder->DecodeFrame(video->cxdata(),
|
vpx_codec_err_t res_dec =
|
||||||
video->frame_size());
|
decoder->DecodeFrame(video->cxdata(), video->frame_size());
|
||||||
if (!HandleDecodeResult(res_dec, *video, decoder))
|
if (!HandleDecodeResult(res_dec, *video, decoder)) break;
|
||||||
break;
|
|
||||||
} else {
|
} else {
|
||||||
// Signal end of the file to the decoder.
|
// Signal end of the file to the decoder.
|
||||||
const vpx_codec_err_t res_dec = decoder->DecodeFrame(NULL, 0);
|
const vpx_codec_err_t res_dec = decoder->DecodeFrame(NULL, 0);
|
||||||
@@ -101,9 +97,10 @@ void DecoderTest::RunLoop(CompressedVideoSource *video,
|
|||||||
const vpx_image_t *img = NULL;
|
const vpx_image_t *img = NULL;
|
||||||
|
|
||||||
// Get decompressed data
|
// Get decompressed data
|
||||||
while ((img = dec_iter.Next()))
|
while ((img = dec_iter.Next())) {
|
||||||
DecompressedFrameHook(*img, video->frame_number());
|
DecompressedFrameHook(*img, video->frame_number());
|
||||||
}
|
}
|
||||||
|
}
|
||||||
delete decoder;
|
delete decoder;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -116,8 +113,6 @@ void DecoderTest::set_cfg(const vpx_codec_dec_cfg_t &dec_cfg) {
|
|||||||
memcpy(&cfg_, &dec_cfg, sizeof(cfg_));
|
memcpy(&cfg_, &dec_cfg, sizeof(cfg_));
|
||||||
}
|
}
|
||||||
|
|
||||||
void DecoderTest::set_flags(const vpx_codec_flags_t flags) {
|
void DecoderTest::set_flags(const vpx_codec_flags_t flags) { flags_ = flags; }
|
||||||
flags_ = flags;
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace libvpx_test
|
} // namespace libvpx_test
|
||||||
|
|||||||
@@ -26,9 +26,7 @@ class DxDataIterator {
|
|||||||
explicit DxDataIterator(vpx_codec_ctx_t *decoder)
|
explicit DxDataIterator(vpx_codec_ctx_t *decoder)
|
||||||
: decoder_(decoder), iter_(NULL) {}
|
: decoder_(decoder), iter_(NULL) {}
|
||||||
|
|
||||||
const vpx_image_t *Next() {
|
const vpx_image_t *Next() { return vpx_codec_get_frame(decoder_, &iter_); }
|
||||||
return vpx_codec_get_frame(decoder_, &iter_);
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
vpx_codec_ctx_t *decoder_;
|
vpx_codec_ctx_t *decoder_;
|
||||||
@@ -40,20 +38,17 @@ class DxDataIterator {
|
|||||||
// as more tests are added.
|
// as more tests are added.
|
||||||
class Decoder {
|
class Decoder {
|
||||||
public:
|
public:
|
||||||
Decoder(vpx_codec_dec_cfg_t cfg, unsigned long deadline)
|
explicit Decoder(vpx_codec_dec_cfg_t cfg)
|
||||||
: cfg_(cfg), flags_(0), deadline_(deadline), init_done_(false) {
|
: cfg_(cfg), flags_(0), init_done_(false) {
|
||||||
memset(&decoder_, 0, sizeof(decoder_));
|
memset(&decoder_, 0, sizeof(decoder_));
|
||||||
}
|
}
|
||||||
|
|
||||||
Decoder(vpx_codec_dec_cfg_t cfg, const vpx_codec_flags_t flag,
|
Decoder(vpx_codec_dec_cfg_t cfg, const vpx_codec_flags_t flag)
|
||||||
unsigned long deadline) // NOLINT
|
: cfg_(cfg), flags_(flag), init_done_(false) {
|
||||||
: cfg_(cfg), flags_(flag), deadline_(deadline), init_done_(false) {
|
|
||||||
memset(&decoder_, 0, sizeof(decoder_));
|
memset(&decoder_, 0, sizeof(decoder_));
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual ~Decoder() {
|
virtual ~Decoder() { vpx_codec_destroy(&decoder_); }
|
||||||
vpx_codec_destroy(&decoder_);
|
|
||||||
}
|
|
||||||
|
|
||||||
vpx_codec_err_t PeekStream(const uint8_t *cxdata, size_t size,
|
vpx_codec_err_t PeekStream(const uint8_t *cxdata, size_t size,
|
||||||
vpx_codec_stream_info_t *stream_info);
|
vpx_codec_stream_info_t *stream_info);
|
||||||
@@ -63,17 +58,9 @@ class Decoder {
|
|||||||
vpx_codec_err_t DecodeFrame(const uint8_t *cxdata, size_t size,
|
vpx_codec_err_t DecodeFrame(const uint8_t *cxdata, size_t size,
|
||||||
void *user_priv);
|
void *user_priv);
|
||||||
|
|
||||||
DxDataIterator GetDxData() {
|
DxDataIterator GetDxData() { return DxDataIterator(&decoder_); }
|
||||||
return DxDataIterator(&decoder_);
|
|
||||||
}
|
|
||||||
|
|
||||||
void set_deadline(unsigned long deadline) {
|
void Control(int ctrl_id, int arg) { Control(ctrl_id, arg, VPX_CODEC_OK); }
|
||||||
deadline_ = deadline;
|
|
||||||
}
|
|
||||||
|
|
||||||
void Control(int ctrl_id, int arg) {
|
|
||||||
Control(ctrl_id, arg, VPX_CODEC_OK);
|
|
||||||
}
|
|
||||||
|
|
||||||
void Control(int ctrl_id, const void *arg) {
|
void Control(int ctrl_id, const void *arg) {
|
||||||
InitOnce();
|
InitOnce();
|
||||||
@@ -97,8 +84,8 @@ class Decoder {
|
|||||||
vpx_get_frame_buffer_cb_fn_t cb_get,
|
vpx_get_frame_buffer_cb_fn_t cb_get,
|
||||||
vpx_release_frame_buffer_cb_fn_t cb_release, void *user_priv) {
|
vpx_release_frame_buffer_cb_fn_t cb_release, void *user_priv) {
|
||||||
InitOnce();
|
InitOnce();
|
||||||
return vpx_codec_set_frame_buffer_functions(
|
return vpx_codec_set_frame_buffer_functions(&decoder_, cb_get, cb_release,
|
||||||
&decoder_, cb_get, cb_release, user_priv);
|
user_priv);
|
||||||
}
|
}
|
||||||
|
|
||||||
const char *GetDecoderName() const {
|
const char *GetDecoderName() const {
|
||||||
@@ -107,18 +94,15 @@ class Decoder {
|
|||||||
|
|
||||||
bool IsVP8() const;
|
bool IsVP8() const;
|
||||||
|
|
||||||
vpx_codec_ctx_t * GetDecoder() {
|
vpx_codec_ctx_t *GetDecoder() { return &decoder_; }
|
||||||
return &decoder_;
|
|
||||||
}
|
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
virtual vpx_codec_iface_t *CodecInterface() const = 0;
|
virtual vpx_codec_iface_t *CodecInterface() const = 0;
|
||||||
|
|
||||||
void InitOnce() {
|
void InitOnce() {
|
||||||
if (!init_done_) {
|
if (!init_done_) {
|
||||||
const vpx_codec_err_t res = vpx_codec_dec_init(&decoder_,
|
const vpx_codec_err_t res =
|
||||||
CodecInterface(),
|
vpx_codec_dec_init(&decoder_, CodecInterface(), &cfg_, flags_);
|
||||||
&cfg_, flags_);
|
|
||||||
ASSERT_EQ(VPX_CODEC_OK, res) << DecodeError();
|
ASSERT_EQ(VPX_CODEC_OK, res) << DecodeError();
|
||||||
init_done_ = true;
|
init_done_ = true;
|
||||||
}
|
}
|
||||||
@@ -127,7 +111,6 @@ class Decoder {
|
|||||||
vpx_codec_ctx_t decoder_;
|
vpx_codec_ctx_t decoder_;
|
||||||
vpx_codec_dec_cfg_t cfg_;
|
vpx_codec_dec_cfg_t cfg_;
|
||||||
vpx_codec_flags_t flags_;
|
vpx_codec_flags_t flags_;
|
||||||
unsigned int deadline_;
|
|
||||||
bool init_done_;
|
bool init_done_;
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -165,9 +148,7 @@ class DecoderTest {
|
|||||||
|
|
||||||
protected:
|
protected:
|
||||||
explicit DecoderTest(const CodecFactory *codec)
|
explicit DecoderTest(const CodecFactory *codec)
|
||||||
: codec_(codec),
|
: codec_(codec), cfg_(), flags_(0) {}
|
||||||
cfg_(),
|
|
||||||
flags_(0) {}
|
|
||||||
|
|
||||||
virtual ~DecoderTest() {}
|
virtual ~DecoderTest() {}
|
||||||
|
|
||||||
|
|||||||
@@ -25,9 +25,6 @@ TEST(EncodeAPI, InvalidParams) {
|
|||||||
#endif
|
#endif
|
||||||
#if CONFIG_VP9_ENCODER
|
#if CONFIG_VP9_ENCODER
|
||||||
&vpx_codec_vp9_cx_algo,
|
&vpx_codec_vp9_cx_algo,
|
||||||
#endif
|
|
||||||
#if CONFIG_VP10_ENCODER
|
|
||||||
&vpx_codec_vp10_cx_algo,
|
|
||||||
#endif
|
#endif
|
||||||
};
|
};
|
||||||
uint8_t buf[1] = { 0 };
|
uint8_t buf[1] = { 0 };
|
||||||
|
|||||||
@@ -26,10 +26,7 @@ const double kUsecsInSec = 1000000.0;
|
|||||||
struct EncodePerfTestVideo {
|
struct EncodePerfTestVideo {
|
||||||
EncodePerfTestVideo(const char *name_, uint32_t width_, uint32_t height_,
|
EncodePerfTestVideo(const char *name_, uint32_t width_, uint32_t height_,
|
||||||
uint32_t bitrate_, int frames_)
|
uint32_t bitrate_, int frames_)
|
||||||
: name(name_),
|
: name(name_), width(width_), height(height_), bitrate(bitrate_),
|
||||||
width(width_),
|
|
||||||
height(height_),
|
|
||||||
bitrate(bitrate_),
|
|
||||||
frames(frames_) {}
|
frames(frames_) {}
|
||||||
const char *name;
|
const char *name;
|
||||||
uint32_t width;
|
uint32_t width;
|
||||||
@@ -45,8 +42,8 @@ const EncodePerfTestVideo kVP9EncodePerfTestVectors[] = {
|
|||||||
EncodePerfTestVideo("macmarcostationary_640_480_30.yuv", 640, 480, 200, 718),
|
EncodePerfTestVideo("macmarcostationary_640_480_30.yuv", 640, 480, 200, 718),
|
||||||
EncodePerfTestVideo("niklas_640_480_30.yuv", 640, 480, 200, 471),
|
EncodePerfTestVideo("niklas_640_480_30.yuv", 640, 480, 200, 471),
|
||||||
EncodePerfTestVideo("tacomanarrows_640_480_30.yuv", 640, 480, 200, 300),
|
EncodePerfTestVideo("tacomanarrows_640_480_30.yuv", 640, 480, 200, 300),
|
||||||
EncodePerfTestVideo("tacomasmallcameramovement_640_480_30.yuv",
|
EncodePerfTestVideo("tacomasmallcameramovement_640_480_30.yuv", 640, 480, 200,
|
||||||
640, 480, 200, 300),
|
300),
|
||||||
EncodePerfTestVideo("thaloundeskmtg_640_480_30.yuv", 640, 480, 200, 300),
|
EncodePerfTestVideo("thaloundeskmtg_640_480_30.yuv", 640, 480, 200, 300),
|
||||||
EncodePerfTestVideo("niklas_1280_720_30.yuv", 1280, 720, 600, 470),
|
EncodePerfTestVideo("niklas_1280_720_30.yuv", 1280, 720, 600, 470),
|
||||||
};
|
};
|
||||||
@@ -61,12 +58,8 @@ class VP9EncodePerfTest
|
|||||||
public ::libvpx_test::CodecTestWithParam<libvpx_test::TestMode> {
|
public ::libvpx_test::CodecTestWithParam<libvpx_test::TestMode> {
|
||||||
protected:
|
protected:
|
||||||
VP9EncodePerfTest()
|
VP9EncodePerfTest()
|
||||||
: EncoderTest(GET_PARAM(0)),
|
: EncoderTest(GET_PARAM(0)), min_psnr_(kMaxPsnr), nframes_(0),
|
||||||
min_psnr_(kMaxPsnr),
|
encoding_mode_(GET_PARAM(1)), speed_(0), threads_(1) {}
|
||||||
nframes_(0),
|
|
||||||
encoding_mode_(GET_PARAM(1)),
|
|
||||||
speed_(0),
|
|
||||||
threads_(1) {}
|
|
||||||
|
|
||||||
virtual ~VP9EncodePerfTest() {}
|
virtual ~VP9EncodePerfTest() {}
|
||||||
|
|
||||||
@@ -112,19 +105,13 @@ class VP9EncodePerfTest
|
|||||||
}
|
}
|
||||||
|
|
||||||
// for performance reasons don't decode
|
// for performance reasons don't decode
|
||||||
virtual bool DoDecode() { return 0; }
|
virtual bool DoDecode() const { return false; }
|
||||||
|
|
||||||
double min_psnr() const {
|
double min_psnr() const { return min_psnr_; }
|
||||||
return min_psnr_;
|
|
||||||
}
|
|
||||||
|
|
||||||
void set_speed(unsigned int speed) {
|
void set_speed(unsigned int speed) { speed_ = speed; }
|
||||||
speed_ = speed;
|
|
||||||
}
|
|
||||||
|
|
||||||
void set_threads(unsigned int threads) {
|
void set_threads(unsigned int threads) { threads_ = threads; }
|
||||||
threads_ = threads;
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
double min_psnr_;
|
double min_psnr_;
|
||||||
@@ -139,11 +126,12 @@ TEST_P(VP9EncodePerfTest, PerfTest) {
|
|||||||
for (size_t j = 0; j < NELEMENTS(kEncodePerfTestSpeeds); ++j) {
|
for (size_t j = 0; j < NELEMENTS(kEncodePerfTestSpeeds); ++j) {
|
||||||
for (size_t k = 0; k < NELEMENTS(kEncodePerfTestThreads); ++k) {
|
for (size_t k = 0; k < NELEMENTS(kEncodePerfTestThreads); ++k) {
|
||||||
if (kVP9EncodePerfTestVectors[i].width < 512 &&
|
if (kVP9EncodePerfTestVectors[i].width < 512 &&
|
||||||
kEncodePerfTestThreads[k] > 1)
|
kEncodePerfTestThreads[k] > 1) {
|
||||||
continue;
|
continue;
|
||||||
else if (kVP9EncodePerfTestVectors[i].width < 1024 &&
|
} else if (kVP9EncodePerfTestVectors[i].width < 1024 &&
|
||||||
kEncodePerfTestThreads[k] > 2)
|
kEncodePerfTestThreads[k] > 2) {
|
||||||
continue;
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
set_threads(kEncodePerfTestThreads[k]);
|
set_threads(kEncodePerfTestThreads[k]);
|
||||||
SetUp();
|
SetUp();
|
||||||
@@ -157,10 +145,8 @@ TEST_P(VP9EncodePerfTest, PerfTest) {
|
|||||||
const unsigned frames = kVP9EncodePerfTestVectors[i].frames;
|
const unsigned frames = kVP9EncodePerfTestVectors[i].frames;
|
||||||
const char *video_name = kVP9EncodePerfTestVectors[i].name;
|
const char *video_name = kVP9EncodePerfTestVectors[i].name;
|
||||||
libvpx_test::I420VideoSource video(
|
libvpx_test::I420VideoSource video(
|
||||||
video_name,
|
video_name, kVP9EncodePerfTestVectors[i].width,
|
||||||
kVP9EncodePerfTestVectors[i].width,
|
kVP9EncodePerfTestVectors[i].height, timebase.den, timebase.num, 0,
|
||||||
kVP9EncodePerfTestVectors[i].height,
|
|
||||||
timebase.den, timebase.num, 0,
|
|
||||||
kVP9EncodePerfTestVectors[i].frames);
|
kVP9EncodePerfTestVectors[i].frames);
|
||||||
set_speed(kEncodePerfTestSpeeds[j]);
|
set_speed(kEncodePerfTestSpeeds[j]);
|
||||||
|
|
||||||
@@ -197,6 +183,6 @@ TEST_P(VP9EncodePerfTest, PerfTest) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
VP9_INSTANTIATE_TEST_CASE(
|
VP9_INSTANTIATE_TEST_CASE(VP9EncodePerfTest,
|
||||||
VP9EncodePerfTest, ::testing::Values(::libvpx_test::kRealTime));
|
::testing::Values(::libvpx_test::kRealTime));
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|||||||
@@ -30,8 +30,7 @@ void Encoder::InitEncoder(VideoSource *video) {
|
|||||||
cfg_.g_timebase = video->timebase();
|
cfg_.g_timebase = video->timebase();
|
||||||
cfg_.rc_twopass_stats_in = stats_->buf();
|
cfg_.rc_twopass_stats_in = stats_->buf();
|
||||||
|
|
||||||
res = vpx_codec_enc_init(&encoder_, CodecInterface(), &cfg_,
|
res = vpx_codec_enc_init(&encoder_, CodecInterface(), &cfg_, init_flags_);
|
||||||
init_flags_);
|
|
||||||
ASSERT_EQ(VPX_CODEC_OK, res) << EncoderError();
|
ASSERT_EQ(VPX_CODEC_OK, res) << EncoderError();
|
||||||
|
|
||||||
#if CONFIG_VP9_ENCODER
|
#if CONFIG_VP9_ENCODER
|
||||||
@@ -42,15 +41,6 @@ void Encoder::InitEncoder(VideoSource *video) {
|
|||||||
log2_tile_columns);
|
log2_tile_columns);
|
||||||
ASSERT_EQ(VPX_CODEC_OK, res) << EncoderError();
|
ASSERT_EQ(VPX_CODEC_OK, res) << EncoderError();
|
||||||
} else
|
} else
|
||||||
#endif
|
|
||||||
#if CONFIG_VP10_ENCODER
|
|
||||||
if (CodecInterface() == &vpx_codec_vp10_cx_algo) {
|
|
||||||
// Default to 1 tile column for VP10.
|
|
||||||
const int log2_tile_columns = 0;
|
|
||||||
res = vpx_codec_control_(&encoder_, VP9E_SET_TILE_COLUMNS,
|
|
||||||
log2_tile_columns);
|
|
||||||
ASSERT_EQ(VPX_CODEC_OK, res) << EncoderError();
|
|
||||||
} else
|
|
||||||
#endif
|
#endif
|
||||||
{
|
{
|
||||||
#if CONFIG_VP8_ENCODER
|
#if CONFIG_VP8_ENCODER
|
||||||
@@ -62,17 +52,17 @@ void Encoder::InitEncoder(VideoSource *video) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void Encoder::EncodeFrame(VideoSource *video, const unsigned long frame_flags) {
|
void Encoder::EncodeFrame(VideoSource *video, const unsigned long frame_flags) {
|
||||||
if (video->img())
|
if (video->img()) {
|
||||||
EncodeFrameInternal(*video, frame_flags);
|
EncodeFrameInternal(*video, frame_flags);
|
||||||
else
|
} else {
|
||||||
Flush();
|
Flush();
|
||||||
|
}
|
||||||
|
|
||||||
// Handle twopass stats
|
// Handle twopass stats
|
||||||
CxDataIterator iter = GetCxData();
|
CxDataIterator iter = GetCxData();
|
||||||
|
|
||||||
while (const vpx_codec_cx_pkt_t *pkt = iter.Next()) {
|
while (const vpx_codec_cx_pkt_t *pkt = iter.Next()) {
|
||||||
if (pkt->kind != VPX_CODEC_STATS_PKT)
|
if (pkt->kind != VPX_CODEC_STATS_PKT) continue;
|
||||||
continue;
|
|
||||||
|
|
||||||
stats_->Append(*pkt);
|
stats_->Append(*pkt);
|
||||||
}
|
}
|
||||||
@@ -92,15 +82,15 @@ void Encoder::EncodeFrameInternal(const VideoSource &video,
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Encode the frame
|
// Encode the frame
|
||||||
API_REGISTER_STATE_CHECK(
|
API_REGISTER_STATE_CHECK(res = vpx_codec_encode(&encoder_, img, video.pts(),
|
||||||
res = vpx_codec_encode(&encoder_, img, video.pts(), video.duration(),
|
video.duration(), frame_flags,
|
||||||
frame_flags, deadline_));
|
deadline_));
|
||||||
ASSERT_EQ(VPX_CODEC_OK, res) << EncoderError();
|
ASSERT_EQ(VPX_CODEC_OK, res) << EncoderError();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Encoder::Flush() {
|
void Encoder::Flush() {
|
||||||
const vpx_codec_err_t res = vpx_codec_encode(&encoder_, NULL, 0, 0, 0,
|
const vpx_codec_err_t res =
|
||||||
deadline_);
|
vpx_codec_encode(&encoder_, NULL, 0, 0, 0, deadline_);
|
||||||
if (!encoder_.priv)
|
if (!encoder_.priv)
|
||||||
ASSERT_EQ(VPX_CODEC_ERROR, res) << EncoderError();
|
ASSERT_EQ(VPX_CODEC_ERROR, res) << EncoderError();
|
||||||
else
|
else
|
||||||
@@ -115,55 +105,52 @@ void EncoderTest::InitializeConfig() {
|
|||||||
|
|
||||||
void EncoderTest::SetMode(TestMode mode) {
|
void EncoderTest::SetMode(TestMode mode) {
|
||||||
switch (mode) {
|
switch (mode) {
|
||||||
case kRealTime:
|
case kRealTime: deadline_ = VPX_DL_REALTIME; break;
|
||||||
deadline_ = VPX_DL_REALTIME;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case kOnePassGood:
|
case kOnePassGood:
|
||||||
case kTwoPassGood:
|
case kTwoPassGood: deadline_ = VPX_DL_GOOD_QUALITY; break;
|
||||||
deadline_ = VPX_DL_GOOD_QUALITY;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case kOnePassBest:
|
case kOnePassBest:
|
||||||
case kTwoPassBest:
|
case kTwoPassBest: deadline_ = VPX_DL_BEST_QUALITY; break;
|
||||||
deadline_ = VPX_DL_BEST_QUALITY;
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
default: ASSERT_TRUE(false) << "Unexpected mode " << mode;
|
||||||
ASSERT_TRUE(false) << "Unexpected mode " << mode;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (mode == kTwoPassGood || mode == kTwoPassBest)
|
if (mode == kTwoPassGood || mode == kTwoPassBest) {
|
||||||
passes_ = 2;
|
passes_ = 2;
|
||||||
else
|
} else {
|
||||||
passes_ = 1;
|
passes_ = 1;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
// The function should return "true" most of the time, therefore no early
|
// The function should return "true" most of the time, therefore no early
|
||||||
// break-out is implemented within the match checking process.
|
// break-out is implemented within the match checking process.
|
||||||
static bool compare_img(const vpx_image_t *img1,
|
static bool compare_img(const vpx_image_t *img1, const vpx_image_t *img2) {
|
||||||
const vpx_image_t *img2) {
|
bool match = (img1->fmt == img2->fmt) && (img1->cs == img2->cs) &&
|
||||||
bool match = (img1->fmt == img2->fmt) &&
|
(img1->d_w == img2->d_w) && (img1->d_h == img2->d_h);
|
||||||
(img1->cs == img2->cs) &&
|
|
||||||
(img1->d_w == img2->d_w) &&
|
|
||||||
(img1->d_h == img2->d_h);
|
|
||||||
|
|
||||||
const unsigned int width_y = img1->d_w;
|
const unsigned int width_y = img1->d_w;
|
||||||
const unsigned int height_y = img1->d_h;
|
const unsigned int height_y = img1->d_h;
|
||||||
unsigned int i;
|
unsigned int i;
|
||||||
for (i = 0; i < height_y; ++i)
|
for (i = 0; i < height_y; ++i) {
|
||||||
match = (memcmp(img1->planes[VPX_PLANE_Y] + i * img1->stride[VPX_PLANE_Y],
|
match = (memcmp(img1->planes[VPX_PLANE_Y] + i * img1->stride[VPX_PLANE_Y],
|
||||||
img2->planes[VPX_PLANE_Y] + i * img2->stride[VPX_PLANE_Y],
|
img2->planes[VPX_PLANE_Y] + i * img2->stride[VPX_PLANE_Y],
|
||||||
width_y) == 0) && match;
|
width_y) == 0) &&
|
||||||
|
match;
|
||||||
|
}
|
||||||
const unsigned int width_uv = (img1->d_w + 1) >> 1;
|
const unsigned int width_uv = (img1->d_w + 1) >> 1;
|
||||||
const unsigned int height_uv = (img1->d_h + 1) >> 1;
|
const unsigned int height_uv = (img1->d_h + 1) >> 1;
|
||||||
for (i = 0; i < height_uv; ++i)
|
for (i = 0; i < height_uv; ++i) {
|
||||||
match = (memcmp(img1->planes[VPX_PLANE_U] + i * img1->stride[VPX_PLANE_U],
|
match = (memcmp(img1->planes[VPX_PLANE_U] + i * img1->stride[VPX_PLANE_U],
|
||||||
img2->planes[VPX_PLANE_U] + i * img2->stride[VPX_PLANE_U],
|
img2->planes[VPX_PLANE_U] + i * img2->stride[VPX_PLANE_U],
|
||||||
width_uv) == 0) && match;
|
width_uv) == 0) &&
|
||||||
for (i = 0; i < height_uv; ++i)
|
match;
|
||||||
|
}
|
||||||
|
for (i = 0; i < height_uv; ++i) {
|
||||||
match = (memcmp(img1->planes[VPX_PLANE_V] + i * img1->stride[VPX_PLANE_V],
|
match = (memcmp(img1->planes[VPX_PLANE_V] + i * img1->stride[VPX_PLANE_V],
|
||||||
img2->planes[VPX_PLANE_V] + i * img2->stride[VPX_PLANE_V],
|
img2->planes[VPX_PLANE_V] + i * img2->stride[VPX_PLANE_V],
|
||||||
width_uv) == 0) && match;
|
width_uv) == 0) &&
|
||||||
|
match;
|
||||||
|
}
|
||||||
return match;
|
return match;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -181,34 +168,37 @@ void EncoderTest::RunLoop(VideoSource *video) {
|
|||||||
for (unsigned int pass = 0; pass < passes_; pass++) {
|
for (unsigned int pass = 0; pass < passes_; pass++) {
|
||||||
last_pts_ = 0;
|
last_pts_ = 0;
|
||||||
|
|
||||||
if (passes_ == 1)
|
if (passes_ == 1) {
|
||||||
cfg_.g_pass = VPX_RC_ONE_PASS;
|
cfg_.g_pass = VPX_RC_ONE_PASS;
|
||||||
else if (pass == 0)
|
} else if (pass == 0) {
|
||||||
cfg_.g_pass = VPX_RC_FIRST_PASS;
|
cfg_.g_pass = VPX_RC_FIRST_PASS;
|
||||||
else
|
} else {
|
||||||
cfg_.g_pass = VPX_RC_LAST_PASS;
|
cfg_.g_pass = VPX_RC_LAST_PASS;
|
||||||
|
}
|
||||||
|
|
||||||
BeginPassHook(pass);
|
BeginPassHook(pass);
|
||||||
Encoder* const encoder = codec_->CreateEncoder(cfg_, deadline_, init_flags_,
|
testing::internal::scoped_ptr<Encoder> encoder(
|
||||||
&stats_);
|
codec_->CreateEncoder(cfg_, deadline_, init_flags_, &stats_));
|
||||||
ASSERT_TRUE(encoder != NULL);
|
ASSERT_TRUE(encoder.get() != NULL);
|
||||||
|
|
||||||
video->Begin();
|
ASSERT_NO_FATAL_FAILURE(video->Begin());
|
||||||
encoder->InitEncoder(video);
|
encoder->InitEncoder(video);
|
||||||
ASSERT_FALSE(::testing::Test::HasFatalFailure());
|
ASSERT_FALSE(::testing::Test::HasFatalFailure());
|
||||||
|
|
||||||
unsigned long dec_init_flags = 0; // NOLINT
|
unsigned long dec_init_flags = 0; // NOLINT
|
||||||
// Use fragment decoder if encoder outputs partitions.
|
// Use fragment decoder if encoder outputs partitions.
|
||||||
// NOTE: fragment decoder and partition encoder are only supported by VP8.
|
// NOTE: fragment decoder and partition encoder are only supported by VP8.
|
||||||
if (init_flags_ & VPX_CODEC_USE_OUTPUT_PARTITION)
|
if (init_flags_ & VPX_CODEC_USE_OUTPUT_PARTITION) {
|
||||||
dec_init_flags |= VPX_CODEC_USE_INPUT_FRAGMENTS;
|
dec_init_flags |= VPX_CODEC_USE_INPUT_FRAGMENTS;
|
||||||
Decoder* const decoder = codec_->CreateDecoder(dec_cfg, dec_init_flags, 0);
|
}
|
||||||
|
testing::internal::scoped_ptr<Decoder> decoder(
|
||||||
|
codec_->CreateDecoder(dec_cfg, dec_init_flags));
|
||||||
bool again;
|
bool again;
|
||||||
for (again = true; again; video->Next()) {
|
for (again = true; again; video->Next()) {
|
||||||
again = (video->img() != NULL);
|
again = (video->img() != NULL);
|
||||||
|
|
||||||
PreEncodeFrameHook(video);
|
PreEncodeFrameHook(video);
|
||||||
PreEncodeFrameHook(video, encoder);
|
PreEncodeFrameHook(video, encoder.get());
|
||||||
encoder->EncodeFrame(video, frame_flags_);
|
encoder->EncodeFrame(video, frame_flags_);
|
||||||
|
|
||||||
CxDataIterator iter = encoder->GetCxData();
|
CxDataIterator iter = encoder->GetCxData();
|
||||||
@@ -221,12 +211,11 @@ void EncoderTest::RunLoop(VideoSource *video) {
|
|||||||
switch (pkt->kind) {
|
switch (pkt->kind) {
|
||||||
case VPX_CODEC_CX_FRAME_PKT:
|
case VPX_CODEC_CX_FRAME_PKT:
|
||||||
has_cxdata = true;
|
has_cxdata = true;
|
||||||
if (decoder && DoDecode()) {
|
if (decoder.get() != NULL && DoDecode()) {
|
||||||
vpx_codec_err_t res_dec = decoder->DecodeFrame(
|
vpx_codec_err_t res_dec = decoder->DecodeFrame(
|
||||||
(const uint8_t *)pkt->data.frame.buf, pkt->data.frame.sz);
|
(const uint8_t *)pkt->data.frame.buf, pkt->data.frame.sz);
|
||||||
|
|
||||||
if (!HandleDecodeResult(res_dec, *video, decoder))
|
if (!HandleDecodeResult(res_dec, *video, decoder.get())) break;
|
||||||
break;
|
|
||||||
|
|
||||||
has_dxdata = true;
|
has_dxdata = true;
|
||||||
}
|
}
|
||||||
@@ -235,20 +224,16 @@ void EncoderTest::RunLoop(VideoSource *video) {
|
|||||||
FramePktHook(pkt);
|
FramePktHook(pkt);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case VPX_CODEC_PSNR_PKT:
|
case VPX_CODEC_PSNR_PKT: PSNRPktHook(pkt); break;
|
||||||
PSNRPktHook(pkt);
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
default: break;
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Flush the decoder when there are no more fragments.
|
// Flush the decoder when there are no more fragments.
|
||||||
if ((init_flags_ & VPX_CODEC_USE_OUTPUT_PARTITION) && has_dxdata) {
|
if ((init_flags_ & VPX_CODEC_USE_OUTPUT_PARTITION) && has_dxdata) {
|
||||||
const vpx_codec_err_t res_dec = decoder->DecodeFrame(NULL, 0);
|
const vpx_codec_err_t res_dec = decoder->DecodeFrame(NULL, 0);
|
||||||
if (!HandleDecodeResult(res_dec, *video, decoder))
|
if (!HandleDecodeResult(res_dec, *video, decoder.get())) break;
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (has_dxdata && has_cxdata) {
|
if (has_dxdata && has_cxdata) {
|
||||||
@@ -261,21 +246,14 @@ void EncoderTest::RunLoop(VideoSource *video) {
|
|||||||
MismatchHook(img_enc, img_dec);
|
MismatchHook(img_enc, img_dec);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (img_dec)
|
if (img_dec) DecompressedFrameHook(*img_dec, video->pts());
|
||||||
DecompressedFrameHook(*img_dec, video->pts());
|
|
||||||
}
|
}
|
||||||
if (!Continue())
|
if (!Continue()) break;
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
EndPassHook();
|
EndPassHook();
|
||||||
|
|
||||||
if (decoder)
|
if (!Continue()) break;
|
||||||
delete decoder;
|
|
||||||
delete encoder;
|
|
||||||
|
|
||||||
if (!Continue())
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -16,7 +16,7 @@
|
|||||||
#include "third_party/googletest/src/include/gtest/gtest.h"
|
#include "third_party/googletest/src/include/gtest/gtest.h"
|
||||||
|
|
||||||
#include "./vpx_config.h"
|
#include "./vpx_config.h"
|
||||||
#if CONFIG_VP8_ENCODER || CONFIG_VP9_ENCODER || CONFIG_VP10_ENCODER
|
#if CONFIG_VP8_ENCODER || CONFIG_VP9_ENCODER
|
||||||
#include "vpx/vp8cx.h"
|
#include "vpx/vp8cx.h"
|
||||||
#endif
|
#endif
|
||||||
#include "vpx/vpx_encoder.h"
|
#include "vpx/vpx_encoder.h"
|
||||||
@@ -33,19 +33,17 @@ enum TestMode {
|
|||||||
kTwoPassGood,
|
kTwoPassGood,
|
||||||
kTwoPassBest
|
kTwoPassBest
|
||||||
};
|
};
|
||||||
#define ALL_TEST_MODES ::testing::Values(::libvpx_test::kRealTime, \
|
#define ALL_TEST_MODES \
|
||||||
::libvpx_test::kOnePassGood, \
|
::testing::Values(::libvpx_test::kRealTime, ::libvpx_test::kOnePassGood, \
|
||||||
::libvpx_test::kOnePassBest, \
|
::libvpx_test::kOnePassBest, ::libvpx_test::kTwoPassGood, \
|
||||||
::libvpx_test::kTwoPassGood, \
|
|
||||||
::libvpx_test::kTwoPassBest)
|
::libvpx_test::kTwoPassBest)
|
||||||
|
|
||||||
#define ONE_PASS_TEST_MODES ::testing::Values(::libvpx_test::kRealTime, \
|
#define ONE_PASS_TEST_MODES \
|
||||||
::libvpx_test::kOnePassGood, \
|
::testing::Values(::libvpx_test::kRealTime, ::libvpx_test::kOnePassGood, \
|
||||||
::libvpx_test::kOnePassBest)
|
::libvpx_test::kOnePassBest)
|
||||||
|
|
||||||
#define TWO_PASS_TEST_MODES ::testing::Values(::libvpx_test::kTwoPassGood, \
|
#define TWO_PASS_TEST_MODES \
|
||||||
::libvpx_test::kTwoPassBest)
|
::testing::Values(::libvpx_test::kTwoPassGood, ::libvpx_test::kTwoPassBest)
|
||||||
|
|
||||||
|
|
||||||
// Provides an object to handle the libvpx get_cx_data() iteration pattern
|
// Provides an object to handle the libvpx get_cx_data() iteration pattern
|
||||||
class CxDataIterator {
|
class CxDataIterator {
|
||||||
@@ -75,15 +73,12 @@ class TwopassStatsStore {
|
|||||||
return buf;
|
return buf;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Reset() {
|
void Reset() { buffer_.clear(); }
|
||||||
buffer_.clear();
|
|
||||||
}
|
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
std::string buffer_;
|
std::string buffer_;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
// Provides a simplified interface to manage one video encoding pass, given
|
// Provides a simplified interface to manage one video encoding pass, given
|
||||||
// a configuration and video source.
|
// a configuration and video source.
|
||||||
//
|
//
|
||||||
@@ -97,13 +92,9 @@ class Encoder {
|
|||||||
memset(&encoder_, 0, sizeof(encoder_));
|
memset(&encoder_, 0, sizeof(encoder_));
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual ~Encoder() {
|
virtual ~Encoder() { vpx_codec_destroy(&encoder_); }
|
||||||
vpx_codec_destroy(&encoder_);
|
|
||||||
}
|
|
||||||
|
|
||||||
CxDataIterator GetCxData() {
|
CxDataIterator GetCxData() { return CxDataIterator(&encoder_); }
|
||||||
return CxDataIterator(&encoder_);
|
|
||||||
}
|
|
||||||
|
|
||||||
void InitEncoder(VideoSource *video);
|
void InitEncoder(VideoSource *video);
|
||||||
|
|
||||||
@@ -115,9 +106,7 @@ class Encoder {
|
|||||||
void EncodeFrame(VideoSource *video, const unsigned long frame_flags);
|
void EncodeFrame(VideoSource *video, const unsigned long frame_flags);
|
||||||
|
|
||||||
// Convenience wrapper for EncodeFrame()
|
// Convenience wrapper for EncodeFrame()
|
||||||
void EncodeFrame(VideoSource *video) {
|
void EncodeFrame(VideoSource *video) { EncodeFrame(video, 0); }
|
||||||
EncodeFrame(video, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
void Control(int ctrl_id, int arg) {
|
void Control(int ctrl_id, int arg) {
|
||||||
const vpx_codec_err_t res = vpx_codec_control_(&encoder_, ctrl_id, arg);
|
const vpx_codec_err_t res = vpx_codec_control_(&encoder_, ctrl_id, arg);
|
||||||
@@ -143,7 +132,7 @@ class Encoder {
|
|||||||
const vpx_codec_err_t res = vpx_codec_control_(&encoder_, ctrl_id, arg);
|
const vpx_codec_err_t res = vpx_codec_control_(&encoder_, ctrl_id, arg);
|
||||||
ASSERT_EQ(VPX_CODEC_OK, res) << EncoderError();
|
ASSERT_EQ(VPX_CODEC_OK, res) << EncoderError();
|
||||||
}
|
}
|
||||||
#if CONFIG_VP8_ENCODER || CONFIG_VP9_ENCODER || CONFIG_VP10_ENCODER
|
#if CONFIG_VP8_ENCODER || CONFIG_VP9_ENCODER
|
||||||
void Control(int ctrl_id, vpx_active_map_t *arg) {
|
void Control(int ctrl_id, vpx_active_map_t *arg) {
|
||||||
const vpx_codec_err_t res = vpx_codec_control_(&encoder_, ctrl_id, arg);
|
const vpx_codec_err_t res = vpx_codec_control_(&encoder_, ctrl_id, arg);
|
||||||
ASSERT_EQ(VPX_CODEC_OK, res) << EncoderError();
|
ASSERT_EQ(VPX_CODEC_OK, res) << EncoderError();
|
||||||
@@ -156,9 +145,7 @@ class Encoder {
|
|||||||
cfg_ = *cfg;
|
cfg_ = *cfg;
|
||||||
}
|
}
|
||||||
|
|
||||||
void set_deadline(unsigned long deadline) {
|
void set_deadline(unsigned long deadline) { deadline_ = deadline; }
|
||||||
deadline_ = deadline;
|
|
||||||
}
|
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
virtual vpx_codec_iface_t *CodecInterface() const = 0;
|
virtual vpx_codec_iface_t *CodecInterface() const = 0;
|
||||||
@@ -241,8 +228,7 @@ class EncoderTest {
|
|||||||
virtual bool DoDecode() const { return 1; }
|
virtual bool DoDecode() const { return 1; }
|
||||||
|
|
||||||
// Hook to handle encode/decode mismatch
|
// Hook to handle encode/decode mismatch
|
||||||
virtual void MismatchHook(const vpx_image_t *img1,
|
virtual void MismatchHook(const vpx_image_t *img1, const vpx_image_t *img2);
|
||||||
const vpx_image_t *img2);
|
|
||||||
|
|
||||||
// Hook to be called on every decompressed frame.
|
// Hook to be called on every decompressed frame.
|
||||||
virtual void DecompressedFrameHook(const vpx_image_t & /*img*/,
|
virtual void DecompressedFrameHook(const vpx_image_t & /*img*/,
|
||||||
|
|||||||
@@ -19,16 +19,13 @@ namespace {
|
|||||||
const int kMaxErrorFrames = 12;
|
const int kMaxErrorFrames = 12;
|
||||||
const int kMaxDroppableFrames = 12;
|
const int kMaxDroppableFrames = 12;
|
||||||
|
|
||||||
class ErrorResilienceTestLarge : public ::libvpx_test::EncoderTest,
|
class ErrorResilienceTestLarge
|
||||||
|
: public ::libvpx_test::EncoderTest,
|
||||||
public ::libvpx_test::CodecTestWith2Params<libvpx_test::TestMode, bool> {
|
public ::libvpx_test::CodecTestWith2Params<libvpx_test::TestMode, bool> {
|
||||||
protected:
|
protected:
|
||||||
ErrorResilienceTestLarge()
|
ErrorResilienceTestLarge()
|
||||||
: EncoderTest(GET_PARAM(0)),
|
: EncoderTest(GET_PARAM(0)), svc_support_(GET_PARAM(2)), psnr_(0.0),
|
||||||
svc_support_(GET_PARAM(2)),
|
nframes_(0), mismatch_psnr_(0.0), mismatch_nframes_(0),
|
||||||
psnr_(0.0),
|
|
||||||
nframes_(0),
|
|
||||||
mismatch_psnr_(0.0),
|
|
||||||
mismatch_nframes_(0),
|
|
||||||
encoding_mode_(GET_PARAM(1)) {
|
encoding_mode_(GET_PARAM(1)) {
|
||||||
Reset();
|
Reset();
|
||||||
}
|
}
|
||||||
@@ -66,32 +63,26 @@ class ErrorResilienceTestLarge : public ::libvpx_test::EncoderTest,
|
|||||||
// LAST is updated on base/layer 0, GOLDEN updated on layer 1.
|
// LAST is updated on base/layer 0, GOLDEN updated on layer 1.
|
||||||
// Non-zero pattern_switch parameter means pattern will switch to
|
// Non-zero pattern_switch parameter means pattern will switch to
|
||||||
// not using LAST for frame_num >= pattern_switch.
|
// not using LAST for frame_num >= pattern_switch.
|
||||||
int SetFrameFlags(int frame_num,
|
int SetFrameFlags(int frame_num, int num_temp_layers, int pattern_switch) {
|
||||||
int num_temp_layers,
|
|
||||||
int pattern_switch) {
|
|
||||||
int frame_flags = 0;
|
int frame_flags = 0;
|
||||||
if (num_temp_layers == 2) {
|
if (num_temp_layers == 2) {
|
||||||
if (frame_num % 2 == 0) {
|
if (frame_num % 2 == 0) {
|
||||||
if (frame_num < pattern_switch || pattern_switch == 0) {
|
if (frame_num < pattern_switch || pattern_switch == 0) {
|
||||||
// Layer 0: predict from LAST and ARF, update LAST.
|
// Layer 0: predict from LAST and ARF, update LAST.
|
||||||
frame_flags = VP8_EFLAG_NO_REF_GF |
|
frame_flags =
|
||||||
VP8_EFLAG_NO_UPD_GF |
|
VP8_EFLAG_NO_REF_GF | VP8_EFLAG_NO_UPD_GF | VP8_EFLAG_NO_UPD_ARF;
|
||||||
VP8_EFLAG_NO_UPD_ARF;
|
|
||||||
} else {
|
} else {
|
||||||
// Layer 0: predict from GF and ARF, update GF.
|
// Layer 0: predict from GF and ARF, update GF.
|
||||||
frame_flags = VP8_EFLAG_NO_REF_LAST |
|
frame_flags = VP8_EFLAG_NO_REF_LAST | VP8_EFLAG_NO_UPD_LAST |
|
||||||
VP8_EFLAG_NO_UPD_LAST |
|
|
||||||
VP8_EFLAG_NO_UPD_ARF;
|
VP8_EFLAG_NO_UPD_ARF;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (frame_num < pattern_switch || pattern_switch == 0) {
|
if (frame_num < pattern_switch || pattern_switch == 0) {
|
||||||
// Layer 1: predict from L, GF, and ARF, update GF.
|
// Layer 1: predict from L, GF, and ARF, update GF.
|
||||||
frame_flags = VP8_EFLAG_NO_UPD_ARF |
|
frame_flags = VP8_EFLAG_NO_UPD_ARF | VP8_EFLAG_NO_UPD_LAST;
|
||||||
VP8_EFLAG_NO_UPD_LAST;
|
|
||||||
} else {
|
} else {
|
||||||
// Layer 1: predict from GF and ARF, update GF.
|
// Layer 1: predict from GF and ARF, update GF.
|
||||||
frame_flags = VP8_EFLAG_NO_REF_LAST |
|
frame_flags = VP8_EFLAG_NO_REF_LAST | VP8_EFLAG_NO_UPD_LAST |
|
||||||
VP8_EFLAG_NO_UPD_LAST |
|
|
||||||
VP8_EFLAG_NO_UPD_ARF;
|
VP8_EFLAG_NO_UPD_ARF;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -99,20 +90,17 @@ class ErrorResilienceTestLarge : public ::libvpx_test::EncoderTest,
|
|||||||
return frame_flags;
|
return frame_flags;
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual void PreEncodeFrameHook(libvpx_test::VideoSource *video,
|
virtual void PreEncodeFrameHook(libvpx_test::VideoSource *video) {
|
||||||
::libvpx_test::Encoder * /*encoder*/) {
|
frame_flags_ &=
|
||||||
frame_flags_ &= ~(VP8_EFLAG_NO_UPD_LAST |
|
~(VP8_EFLAG_NO_UPD_LAST | VP8_EFLAG_NO_UPD_GF | VP8_EFLAG_NO_UPD_ARF);
|
||||||
VP8_EFLAG_NO_UPD_GF |
|
|
||||||
VP8_EFLAG_NO_UPD_ARF);
|
|
||||||
// For temporal layer case.
|
// For temporal layer case.
|
||||||
if (cfg_.ts_number_layers > 1) {
|
if (cfg_.ts_number_layers > 1) {
|
||||||
frame_flags_ = SetFrameFlags(video->frame(),
|
frame_flags_ =
|
||||||
cfg_.ts_number_layers,
|
SetFrameFlags(video->frame(), cfg_.ts_number_layers, pattern_switch_);
|
||||||
pattern_switch_);
|
|
||||||
for (unsigned int i = 0; i < droppable_nframes_; ++i) {
|
for (unsigned int i = 0; i < droppable_nframes_; ++i) {
|
||||||
if (droppable_frames_[i] == video->frame()) {
|
if (droppable_frames_[i] == video->frame()) {
|
||||||
std::cout << "Encoding droppable frame: "
|
std::cout << "Encoding droppable frame: " << droppable_frames_[i]
|
||||||
<< droppable_frames_[i] << "\n";
|
<< "\n";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
@@ -120,10 +108,9 @@ class ErrorResilienceTestLarge : public ::libvpx_test::EncoderTest,
|
|||||||
(cfg_.g_pass == VPX_RC_LAST_PASS || cfg_.g_pass == VPX_RC_ONE_PASS)) {
|
(cfg_.g_pass == VPX_RC_LAST_PASS || cfg_.g_pass == VPX_RC_ONE_PASS)) {
|
||||||
for (unsigned int i = 0; i < droppable_nframes_; ++i) {
|
for (unsigned int i = 0; i < droppable_nframes_; ++i) {
|
||||||
if (droppable_frames_[i] == video->frame()) {
|
if (droppable_frames_[i] == video->frame()) {
|
||||||
std::cout << "Encoding droppable frame: "
|
std::cout << "Encoding droppable frame: " << droppable_frames_[i]
|
||||||
<< droppable_frames_[i] << "\n";
|
<< "\n";
|
||||||
frame_flags_ |= (VP8_EFLAG_NO_UPD_LAST |
|
frame_flags_ |= (VP8_EFLAG_NO_UPD_LAST | VP8_EFLAG_NO_UPD_GF |
|
||||||
VP8_EFLAG_NO_UPD_GF |
|
|
||||||
VP8_EFLAG_NO_UPD_ARF);
|
VP8_EFLAG_NO_UPD_ARF);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -133,14 +120,12 @@ class ErrorResilienceTestLarge : public ::libvpx_test::EncoderTest,
|
|||||||
}
|
}
|
||||||
|
|
||||||
double GetAveragePsnr() const {
|
double GetAveragePsnr() const {
|
||||||
if (nframes_)
|
if (nframes_) return psnr_ / nframes_;
|
||||||
return psnr_ / nframes_;
|
|
||||||
return 0.0;
|
return 0.0;
|
||||||
}
|
}
|
||||||
|
|
||||||
double GetAverageMismatchPsnr() const {
|
double GetAverageMismatchPsnr() const {
|
||||||
if (mismatch_nframes_)
|
if (mismatch_nframes_) return mismatch_psnr_ / mismatch_nframes_;
|
||||||
return mismatch_psnr_ / mismatch_nframes_;
|
|
||||||
return 0.0;
|
return 0.0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -158,8 +143,7 @@ class ErrorResilienceTestLarge : public ::libvpx_test::EncoderTest,
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual void MismatchHook(const vpx_image_t *img1,
|
virtual void MismatchHook(const vpx_image_t *img1, const vpx_image_t *img2) {
|
||||||
const vpx_image_t *img2) {
|
|
||||||
double mismatch_psnr = compute_psnr(img1, img2);
|
double mismatch_psnr = compute_psnr(img1, img2);
|
||||||
mismatch_psnr_ += mismatch_psnr;
|
mismatch_psnr_ += mismatch_psnr;
|
||||||
++mismatch_nframes_;
|
++mismatch_nframes_;
|
||||||
@@ -167,32 +151,32 @@ class ErrorResilienceTestLarge : public ::libvpx_test::EncoderTest,
|
|||||||
}
|
}
|
||||||
|
|
||||||
void SetErrorFrames(int num, unsigned int *list) {
|
void SetErrorFrames(int num, unsigned int *list) {
|
||||||
if (num > kMaxErrorFrames)
|
if (num > kMaxErrorFrames) {
|
||||||
num = kMaxErrorFrames;
|
num = kMaxErrorFrames;
|
||||||
else if (num < 0)
|
} else if (num < 0) {
|
||||||
num = 0;
|
num = 0;
|
||||||
|
}
|
||||||
error_nframes_ = num;
|
error_nframes_ = num;
|
||||||
for (unsigned int i = 0; i < error_nframes_; ++i)
|
for (unsigned int i = 0; i < error_nframes_; ++i) {
|
||||||
error_frames_[i] = list[i];
|
error_frames_[i] = list[i];
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void SetDroppableFrames(int num, unsigned int *list) {
|
void SetDroppableFrames(int num, unsigned int *list) {
|
||||||
if (num > kMaxDroppableFrames)
|
if (num > kMaxDroppableFrames) {
|
||||||
num = kMaxDroppableFrames;
|
num = kMaxDroppableFrames;
|
||||||
else if (num < 0)
|
} else if (num < 0) {
|
||||||
num = 0;
|
num = 0;
|
||||||
|
}
|
||||||
droppable_nframes_ = num;
|
droppable_nframes_ = num;
|
||||||
for (unsigned int i = 0; i < droppable_nframes_; ++i)
|
for (unsigned int i = 0; i < droppable_nframes_; ++i) {
|
||||||
droppable_frames_[i] = list[i];
|
droppable_frames_[i] = list[i];
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned int GetMismatchFrames() {
|
|
||||||
return mismatch_nframes_;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void SetPatternSwitch(int frame_switch) {
|
unsigned int GetMismatchFrames() { return mismatch_nframes_; }
|
||||||
pattern_switch_ = frame_switch;
|
|
||||||
}
|
void SetPatternSwitch(int frame_switch) { pattern_switch_ = frame_switch; }
|
||||||
|
|
||||||
bool svc_support_;
|
bool svc_support_;
|
||||||
|
|
||||||
@@ -265,14 +249,13 @@ TEST_P(ErrorResilienceTestLarge, DropFramesWithoutRecovery) {
|
|||||||
// In addition to isolated loss/drop, add a long consecutive series
|
// In addition to isolated loss/drop, add a long consecutive series
|
||||||
// (of size 9) of dropped frames.
|
// (of size 9) of dropped frames.
|
||||||
unsigned int num_droppable_frames = 11;
|
unsigned int num_droppable_frames = 11;
|
||||||
unsigned int droppable_frame_list[] = {5, 16, 22, 23, 24, 25, 26, 27, 28,
|
unsigned int droppable_frame_list[] = { 5, 16, 22, 23, 24, 25,
|
||||||
29, 30};
|
26, 27, 28, 29, 30 };
|
||||||
SetDroppableFrames(num_droppable_frames, droppable_frame_list);
|
SetDroppableFrames(num_droppable_frames, droppable_frame_list);
|
||||||
SetErrorFrames(num_droppable_frames, droppable_frame_list);
|
SetErrorFrames(num_droppable_frames, droppable_frame_list);
|
||||||
ASSERT_NO_FATAL_FAILURE(RunLoop(&video));
|
ASSERT_NO_FATAL_FAILURE(RunLoop(&video));
|
||||||
// Test that no mismatches have been found
|
// Test that no mismatches have been found
|
||||||
std::cout << " Mismatch frames: "
|
std::cout << " Mismatch frames: " << GetMismatchFrames() << "\n";
|
||||||
<< GetMismatchFrames() << "\n";
|
|
||||||
EXPECT_EQ(GetMismatchFrames(), (unsigned int)0);
|
EXPECT_EQ(GetMismatchFrames(), (unsigned int)0);
|
||||||
|
|
||||||
// Reset previously set of error/droppable frames.
|
// Reset previously set of error/droppable frames.
|
||||||
@@ -306,8 +289,7 @@ TEST_P(ErrorResilienceTestLarge, DropFramesWithoutRecovery) {
|
|||||||
// layer, so successful decoding is expected.
|
// layer, so successful decoding is expected.
|
||||||
TEST_P(ErrorResilienceTestLarge, 2LayersDropEnhancement) {
|
TEST_P(ErrorResilienceTestLarge, 2LayersDropEnhancement) {
|
||||||
// This test doesn't run if SVC is not supported.
|
// This test doesn't run if SVC is not supported.
|
||||||
if (!svc_support_)
|
if (!svc_support_) return;
|
||||||
return;
|
|
||||||
|
|
||||||
const vpx_rational timebase = { 33333333, 1000000000 };
|
const vpx_rational timebase = { 33333333, 1000000000 };
|
||||||
cfg_.g_timebase = timebase;
|
cfg_.g_timebase = timebase;
|
||||||
@@ -342,8 +324,7 @@ TEST_P(ErrorResilienceTestLarge, 2LayersDropEnhancement) {
|
|||||||
SetErrorFrames(num_droppable_frames, droppable_frame_list);
|
SetErrorFrames(num_droppable_frames, droppable_frame_list);
|
||||||
ASSERT_NO_FATAL_FAILURE(RunLoop(&video));
|
ASSERT_NO_FATAL_FAILURE(RunLoop(&video));
|
||||||
// Test that no mismatches have been found
|
// Test that no mismatches have been found
|
||||||
std::cout << " Mismatch frames: "
|
std::cout << " Mismatch frames: " << GetMismatchFrames() << "\n";
|
||||||
<< GetMismatchFrames() << "\n";
|
|
||||||
EXPECT_EQ(GetMismatchFrames(), (unsigned int)0);
|
EXPECT_EQ(GetMismatchFrames(), (unsigned int)0);
|
||||||
|
|
||||||
// Reset previously set of error/droppable frames.
|
// Reset previously set of error/droppable frames.
|
||||||
@@ -355,8 +336,7 @@ TEST_P(ErrorResilienceTestLarge, 2LayersDropEnhancement) {
|
|||||||
// sequence, the LAST ref is not used anymore.
|
// sequence, the LAST ref is not used anymore.
|
||||||
TEST_P(ErrorResilienceTestLarge, 2LayersNoRefLast) {
|
TEST_P(ErrorResilienceTestLarge, 2LayersNoRefLast) {
|
||||||
// This test doesn't run if SVC is not supported.
|
// This test doesn't run if SVC is not supported.
|
||||||
if (!svc_support_)
|
if (!svc_support_) return;
|
||||||
return;
|
|
||||||
|
|
||||||
const vpx_rational timebase = { 33333333, 1000000000 };
|
const vpx_rational timebase = { 33333333, 1000000000 };
|
||||||
cfg_.g_timebase = timebase;
|
cfg_.g_timebase = timebase;
|
||||||
@@ -385,20 +365,19 @@ TEST_P(ErrorResilienceTestLarge, 2LayersNoRefLast) {
|
|||||||
|
|
||||||
ASSERT_NO_FATAL_FAILURE(RunLoop(&video));
|
ASSERT_NO_FATAL_FAILURE(RunLoop(&video));
|
||||||
// Test that no mismatches have been found
|
// Test that no mismatches have been found
|
||||||
std::cout << " Mismatch frames: "
|
std::cout << " Mismatch frames: " << GetMismatchFrames() << "\n";
|
||||||
<< GetMismatchFrames() << "\n";
|
|
||||||
EXPECT_EQ(GetMismatchFrames(), (unsigned int)0);
|
EXPECT_EQ(GetMismatchFrames(), (unsigned int)0);
|
||||||
|
|
||||||
// Reset previously set of error/droppable frames.
|
// Reset previously set of error/droppable frames.
|
||||||
Reset();
|
Reset();
|
||||||
}
|
}
|
||||||
|
|
||||||
class ErrorResilienceTestLargeCodecControls : public ::libvpx_test::EncoderTest,
|
class ErrorResilienceTestLargeCodecControls
|
||||||
|
: public ::libvpx_test::EncoderTest,
|
||||||
public ::libvpx_test::CodecTestWithParam<libvpx_test::TestMode> {
|
public ::libvpx_test::CodecTestWithParam<libvpx_test::TestMode> {
|
||||||
protected:
|
protected:
|
||||||
ErrorResilienceTestLargeCodecControls()
|
ErrorResilienceTestLargeCodecControls()
|
||||||
: EncoderTest(GET_PARAM(0)),
|
: EncoderTest(GET_PARAM(0)), encoding_mode_(GET_PARAM(1)) {
|
||||||
encoding_mode_(GET_PARAM(1)) {
|
|
||||||
Reset();
|
Reset();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -437,8 +416,8 @@ class ErrorResilienceTestLargeCodecControls : public ::libvpx_test::EncoderTest,
|
|||||||
if (num_temp_layers == 2) {
|
if (num_temp_layers == 2) {
|
||||||
if (frame_num % 2 == 0) {
|
if (frame_num % 2 == 0) {
|
||||||
// Layer 0: predict from L and ARF, update L.
|
// Layer 0: predict from L and ARF, update L.
|
||||||
frame_flags = VP8_EFLAG_NO_REF_GF | VP8_EFLAG_NO_UPD_GF |
|
frame_flags =
|
||||||
VP8_EFLAG_NO_UPD_ARF;
|
VP8_EFLAG_NO_REF_GF | VP8_EFLAG_NO_UPD_GF | VP8_EFLAG_NO_UPD_ARF;
|
||||||
} else {
|
} else {
|
||||||
// Layer 1: predict from L, G and ARF, and update G.
|
// Layer 1: predict from L, G and ARF, and update G.
|
||||||
frame_flags = VP8_EFLAG_NO_UPD_ARF | VP8_EFLAG_NO_UPD_LAST |
|
frame_flags = VP8_EFLAG_NO_UPD_ARF | VP8_EFLAG_NO_UPD_LAST |
|
||||||
@@ -451,8 +430,8 @@ class ErrorResilienceTestLargeCodecControls : public ::libvpx_test::EncoderTest,
|
|||||||
VP8_EFLAG_NO_REF_GF | VP8_EFLAG_NO_REF_ARF;
|
VP8_EFLAG_NO_REF_GF | VP8_EFLAG_NO_REF_ARF;
|
||||||
} else if ((frame_num - 2) % 4 == 0) {
|
} else if ((frame_num - 2) % 4 == 0) {
|
||||||
// Layer 1: predict from L, G, update G.
|
// Layer 1: predict from L, G, update G.
|
||||||
frame_flags = VP8_EFLAG_NO_UPD_ARF | VP8_EFLAG_NO_UPD_LAST |
|
frame_flags =
|
||||||
VP8_EFLAG_NO_REF_ARF;
|
VP8_EFLAG_NO_UPD_ARF | VP8_EFLAG_NO_UPD_LAST | VP8_EFLAG_NO_REF_ARF;
|
||||||
} else if ((frame_num - 1) % 2 == 0) {
|
} else if ((frame_num - 1) % 2 == 0) {
|
||||||
// Layer 2: predict from L, G, ARF; update ARG.
|
// Layer 2: predict from L, G, ARF; update ARG.
|
||||||
frame_flags = VP8_EFLAG_NO_UPD_GF | VP8_EFLAG_NO_UPD_LAST;
|
frame_flags = VP8_EFLAG_NO_UPD_GF | VP8_EFLAG_NO_UPD_LAST;
|
||||||
@@ -524,13 +503,15 @@ class ErrorResilienceTestLargeCodecControls : public ::libvpx_test::EncoderTest,
|
|||||||
++layer) {
|
++layer) {
|
||||||
if (bits_total_[layer]) {
|
if (bits_total_[layer]) {
|
||||||
// Effective file datarate:
|
// Effective file datarate:
|
||||||
effective_datarate_[layer] = (bits_total_[layer] / 1000.0) / duration_;
|
effective_datarate_[layer] =
|
||||||
|
(bits_total_[layer] / 1000.0) / duration_;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
double effective_datarate_[3];
|
double effective_datarate_[3];
|
||||||
|
|
||||||
private:
|
private:
|
||||||
libvpx_test::TestMode encoding_mode_;
|
libvpx_test::TestMode encoding_mode_;
|
||||||
vpx_codec_pts_t last_pts_;
|
vpx_codec_pts_t last_pts_;
|
||||||
@@ -582,10 +563,12 @@ TEST_P(ErrorResilienceTestLargeCodecControls, CodecControl3TemporalLayers) {
|
|||||||
for (int j = 0; j < static_cast<int>(cfg_.ts_number_layers); ++j) {
|
for (int j = 0; j < static_cast<int>(cfg_.ts_number_layers); ++j) {
|
||||||
ASSERT_GE(effective_datarate_[j], cfg_.ts_target_bitrate[j] * 0.75)
|
ASSERT_GE(effective_datarate_[j], cfg_.ts_target_bitrate[j] * 0.75)
|
||||||
<< " The datarate for the file is lower than target by too much, "
|
<< " The datarate for the file is lower than target by too much, "
|
||||||
"for layer: " << j;
|
"for layer: "
|
||||||
|
<< j;
|
||||||
ASSERT_LE(effective_datarate_[j], cfg_.ts_target_bitrate[j] * 1.25)
|
ASSERT_LE(effective_datarate_[j], cfg_.ts_target_bitrate[j] * 1.25)
|
||||||
<< " The datarate for the file is greater than target by too much, "
|
<< " The datarate for the file is greater than target by too much, "
|
||||||
"for layer: " << j;
|
"for layer: "
|
||||||
|
<< j;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -596,7 +579,4 @@ VP8_INSTANTIATE_TEST_CASE(ErrorResilienceTestLargeCodecControls,
|
|||||||
ONE_PASS_TEST_MODES);
|
ONE_PASS_TEST_MODES);
|
||||||
VP9_INSTANTIATE_TEST_CASE(ErrorResilienceTestLarge, ONE_PASS_TEST_MODES,
|
VP9_INSTANTIATE_TEST_CASE(ErrorResilienceTestLarge, ONE_PASS_TEST_MODES,
|
||||||
::testing::Values(true));
|
::testing::Values(true));
|
||||||
// SVC-related tests don't run for VP10 since SVC is not supported.
|
|
||||||
VP10_INSTANTIATE_TEST_CASE(ErrorResilienceTestLarge, ONE_PASS_TEST_MODES,
|
|
||||||
::testing::Values(false));
|
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|||||||
@@ -15,7 +15,7 @@
|
|||||||
example_tests=$(ls $(dirname $0)/*.sh)
|
example_tests=$(ls $(dirname $0)/*.sh)
|
||||||
|
|
||||||
# List of script names to exclude.
|
# List of script names to exclude.
|
||||||
exclude_list="examples tools_common"
|
exclude_list="examples stress tools_common"
|
||||||
|
|
||||||
# Filter out the scripts in $exclude_list.
|
# Filter out the scripts in $exclude_list.
|
||||||
for word in ${exclude_list}; do
|
for word in ${exclude_list}; do
|
||||||
|
|||||||
@@ -34,9 +34,7 @@ struct ExternalFrameBuffer {
|
|||||||
// Class to manipulate a list of external frame buffers.
|
// Class to manipulate a list of external frame buffers.
|
||||||
class ExternalFrameBufferList {
|
class ExternalFrameBufferList {
|
||||||
public:
|
public:
|
||||||
ExternalFrameBufferList()
|
ExternalFrameBufferList() : num_buffers_(0), ext_fb_list_(NULL) {}
|
||||||
: num_buffers_(0),
|
|
||||||
ext_fb_list_(NULL) {}
|
|
||||||
|
|
||||||
virtual ~ExternalFrameBufferList() {
|
virtual ~ExternalFrameBufferList() {
|
||||||
for (int i = 0; i < num_buffers_; ++i) {
|
for (int i = 0; i < num_buffers_; ++i) {
|
||||||
@@ -47,8 +45,7 @@ class ExternalFrameBufferList {
|
|||||||
|
|
||||||
// Creates the list to hold the external buffers. Returns true on success.
|
// Creates the list to hold the external buffers. Returns true on success.
|
||||||
bool CreateBufferList(int num_buffers) {
|
bool CreateBufferList(int num_buffers) {
|
||||||
if (num_buffers < 0)
|
if (num_buffers < 0) return false;
|
||||||
return false;
|
|
||||||
|
|
||||||
num_buffers_ = num_buffers;
|
num_buffers_ = num_buffers;
|
||||||
ext_fb_list_ = new ExternalFrameBuffer[num_buffers_];
|
ext_fb_list_ = new ExternalFrameBuffer[num_buffers_];
|
||||||
@@ -64,8 +61,7 @@ class ExternalFrameBufferList {
|
|||||||
int GetFreeFrameBuffer(size_t min_size, vpx_codec_frame_buffer_t *fb) {
|
int GetFreeFrameBuffer(size_t min_size, vpx_codec_frame_buffer_t *fb) {
|
||||||
EXPECT_TRUE(fb != NULL);
|
EXPECT_TRUE(fb != NULL);
|
||||||
const int idx = FindFreeBufferIndex();
|
const int idx = FindFreeBufferIndex();
|
||||||
if (idx == num_buffers_)
|
if (idx == num_buffers_) return -1;
|
||||||
return -1;
|
|
||||||
|
|
||||||
if (ext_fb_list_[idx].size < min_size) {
|
if (ext_fb_list_[idx].size < min_size) {
|
||||||
delete[] ext_fb_list_[idx].data;
|
delete[] ext_fb_list_[idx].data;
|
||||||
@@ -83,8 +79,7 @@ class ExternalFrameBufferList {
|
|||||||
int GetZeroFrameBuffer(size_t min_size, vpx_codec_frame_buffer_t *fb) {
|
int GetZeroFrameBuffer(size_t min_size, vpx_codec_frame_buffer_t *fb) {
|
||||||
EXPECT_TRUE(fb != NULL);
|
EXPECT_TRUE(fb != NULL);
|
||||||
const int idx = FindFreeBufferIndex();
|
const int idx = FindFreeBufferIndex();
|
||||||
if (idx == num_buffers_)
|
if (idx == num_buffers_) return -1;
|
||||||
return -1;
|
|
||||||
|
|
||||||
if (ext_fb_list_[idx].size < min_size) {
|
if (ext_fb_list_[idx].size < min_size) {
|
||||||
delete[] ext_fb_list_[idx].data;
|
delete[] ext_fb_list_[idx].data;
|
||||||
@@ -133,8 +128,7 @@ class ExternalFrameBufferList {
|
|||||||
int i;
|
int i;
|
||||||
// Find a free frame buffer.
|
// Find a free frame buffer.
|
||||||
for (i = 0; i < num_buffers_; ++i) {
|
for (i = 0; i < num_buffers_; ++i) {
|
||||||
if (!ext_fb_list_[i].in_use)
|
if (!ext_fb_list_[i].in_use) break;
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
return i;
|
return i;
|
||||||
}
|
}
|
||||||
@@ -167,8 +161,7 @@ int get_vp9_frame_buffer(void *user_priv, size_t min_size,
|
|||||||
|
|
||||||
// Callback used by libvpx to tell the application that |fb| is not needed
|
// Callback used by libvpx to tell the application that |fb| is not needed
|
||||||
// anymore.
|
// anymore.
|
||||||
int release_vp9_frame_buffer(void *user_priv,
|
int release_vp9_frame_buffer(void *user_priv, vpx_codec_frame_buffer_t *fb) {
|
||||||
vpx_codec_frame_buffer_t *fb) {
|
|
||||||
ExternalFrameBufferList *const fb_list =
|
ExternalFrameBufferList *const fb_list =
|
||||||
reinterpret_cast<ExternalFrameBufferList *>(user_priv);
|
reinterpret_cast<ExternalFrameBufferList *>(user_priv);
|
||||||
return fb_list->ReturnFrameBuffer(fb);
|
return fb_list->ReturnFrameBuffer(fb);
|
||||||
@@ -207,12 +200,10 @@ class ExternalFrameBufferMD5Test
|
|||||||
protected:
|
protected:
|
||||||
ExternalFrameBufferMD5Test()
|
ExternalFrameBufferMD5Test()
|
||||||
: DecoderTest(GET_PARAM(::libvpx_test::kCodecFactoryParam)),
|
: DecoderTest(GET_PARAM(::libvpx_test::kCodecFactoryParam)),
|
||||||
md5_file_(NULL),
|
md5_file_(NULL), num_buffers_(0) {}
|
||||||
num_buffers_(0) {}
|
|
||||||
|
|
||||||
virtual ~ExternalFrameBufferMD5Test() {
|
virtual ~ExternalFrameBufferMD5Test() {
|
||||||
if (md5_file_ != NULL)
|
if (md5_file_ != NULL) fclose(md5_file_);
|
||||||
fclose(md5_file_);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual void PreDecodeFrameHook(
|
virtual void PreDecodeFrameHook(
|
||||||
@@ -222,8 +213,8 @@ class ExternalFrameBufferMD5Test
|
|||||||
// Have libvpx use frame buffers we create.
|
// Have libvpx use frame buffers we create.
|
||||||
ASSERT_TRUE(fb_list_.CreateBufferList(num_buffers_));
|
ASSERT_TRUE(fb_list_.CreateBufferList(num_buffers_));
|
||||||
ASSERT_EQ(VPX_CODEC_OK,
|
ASSERT_EQ(VPX_CODEC_OK,
|
||||||
decoder->SetFrameBufferFunctions(
|
decoder->SetFrameBufferFunctions(GetVP9FrameBuffer,
|
||||||
GetVP9FrameBuffer, ReleaseVP9FrameBuffer, this));
|
ReleaseVP9FrameBuffer, this));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -286,10 +277,7 @@ const char kVP9TestFile[] = "vp90-2-02-size-lf-1920x1080.webm";
|
|||||||
// Class for testing passing in external frame buffers to libvpx.
|
// Class for testing passing in external frame buffers to libvpx.
|
||||||
class ExternalFrameBufferTest : public ::testing::Test {
|
class ExternalFrameBufferTest : public ::testing::Test {
|
||||||
protected:
|
protected:
|
||||||
ExternalFrameBufferTest()
|
ExternalFrameBufferTest() : video_(NULL), decoder_(NULL), num_buffers_(0) {}
|
||||||
: video_(NULL),
|
|
||||||
decoder_(NULL),
|
|
||||||
num_buffers_(0) {}
|
|
||||||
|
|
||||||
virtual void SetUp() {
|
virtual void SetUp() {
|
||||||
video_ = new libvpx_test::WebMVideoSource(kVP9TestFile);
|
video_ = new libvpx_test::WebMVideoSource(kVP9TestFile);
|
||||||
@@ -309,8 +297,7 @@ class ExternalFrameBufferTest : public ::testing::Test {
|
|||||||
|
|
||||||
// Passes the external frame buffer information to libvpx.
|
// Passes the external frame buffer information to libvpx.
|
||||||
vpx_codec_err_t SetFrameBufferFunctions(
|
vpx_codec_err_t SetFrameBufferFunctions(
|
||||||
int num_buffers,
|
int num_buffers, vpx_get_frame_buffer_cb_fn_t cb_get,
|
||||||
vpx_get_frame_buffer_cb_fn_t cb_get,
|
|
||||||
vpx_release_frame_buffer_cb_fn_t cb_release) {
|
vpx_release_frame_buffer_cb_fn_t cb_release) {
|
||||||
if (num_buffers > 0) {
|
if (num_buffers > 0) {
|
||||||
num_buffers_ = num_buffers;
|
num_buffers_ = num_buffers;
|
||||||
@@ -324,8 +311,7 @@ class ExternalFrameBufferTest : public ::testing::Test {
|
|||||||
const vpx_codec_err_t res =
|
const vpx_codec_err_t res =
|
||||||
decoder_->DecodeFrame(video_->cxdata(), video_->frame_size());
|
decoder_->DecodeFrame(video_->cxdata(), video_->frame_size());
|
||||||
CheckDecodedFrames();
|
CheckDecodedFrames();
|
||||||
if (res == VPX_CODEC_OK)
|
if (res == VPX_CODEC_OK) video_->Next();
|
||||||
video_->Next();
|
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -333,8 +319,7 @@ class ExternalFrameBufferTest : public ::testing::Test {
|
|||||||
for (; video_->cxdata() != NULL; video_->Next()) {
|
for (; video_->cxdata() != NULL; video_->Next()) {
|
||||||
const vpx_codec_err_t res =
|
const vpx_codec_err_t res =
|
||||||
decoder_->DecodeFrame(video_->cxdata(), video_->frame_size());
|
decoder_->DecodeFrame(video_->cxdata(), video_->frame_size());
|
||||||
if (res != VPX_CODEC_OK)
|
if (res != VPX_CODEC_OK) return res;
|
||||||
return res;
|
|
||||||
CheckDecodedFrames();
|
CheckDecodedFrames();
|
||||||
}
|
}
|
||||||
return VPX_CODEC_OK;
|
return VPX_CODEC_OK;
|
||||||
@@ -365,7 +350,6 @@ class ExternalFrameBufferTest : public ::testing::Test {
|
|||||||
// Otherwise, the test failed.
|
// Otherwise, the test failed.
|
||||||
TEST_P(ExternalFrameBufferMD5Test, ExtFBMD5Match) {
|
TEST_P(ExternalFrameBufferMD5Test, ExtFBMD5Match) {
|
||||||
const std::string filename = GET_PARAM(kVideoNameParam);
|
const std::string filename = GET_PARAM(kVideoNameParam);
|
||||||
libvpx_test::CompressedVideoSource *video = NULL;
|
|
||||||
|
|
||||||
// Number of buffers equals #VP9_MAXIMUM_REF_BUFFERS +
|
// Number of buffers equals #VP9_MAXIMUM_REF_BUFFERS +
|
||||||
// #VPX_MAXIMUM_WORK_BUFFERS + four jitter buffers.
|
// #VPX_MAXIMUM_WORK_BUFFERS + four jitter buffers.
|
||||||
@@ -380,18 +364,19 @@ TEST_P(ExternalFrameBufferMD5Test, ExtFBMD5Match) {
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
// Open compressed video file.
|
// Open compressed video file.
|
||||||
|
testing::internal::scoped_ptr<libvpx_test::CompressedVideoSource> video;
|
||||||
if (filename.substr(filename.length() - 3, 3) == "ivf") {
|
if (filename.substr(filename.length() - 3, 3) == "ivf") {
|
||||||
video = new libvpx_test::IVFVideoSource(filename);
|
video.reset(new libvpx_test::IVFVideoSource(filename));
|
||||||
} else {
|
} else {
|
||||||
#if CONFIG_WEBM_IO
|
#if CONFIG_WEBM_IO
|
||||||
video = new libvpx_test::WebMVideoSource(filename);
|
video.reset(new libvpx_test::WebMVideoSource(filename));
|
||||||
#else
|
#else
|
||||||
fprintf(stderr, "WebM IO is disabled, skipping test vector %s\n",
|
fprintf(stderr, "WebM IO is disabled, skipping test vector %s\n",
|
||||||
filename.c_str());
|
filename.c_str());
|
||||||
return;
|
return;
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
ASSERT_TRUE(video != NULL);
|
ASSERT_TRUE(video.get() != NULL);
|
||||||
video->Init();
|
video->Init();
|
||||||
|
|
||||||
// Construct md5 file name.
|
// Construct md5 file name.
|
||||||
@@ -399,8 +384,7 @@ TEST_P(ExternalFrameBufferMD5Test, ExtFBMD5Match) {
|
|||||||
OpenMD5File(md5_filename);
|
OpenMD5File(md5_filename);
|
||||||
|
|
||||||
// Decode frame, and check the md5 matching.
|
// Decode frame, and check the md5 matching.
|
||||||
ASSERT_NO_FATAL_FAILURE(RunLoop(video));
|
ASSERT_NO_FATAL_FAILURE(RunLoop(video.get()));
|
||||||
delete video;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#if CONFIG_WEBM_IO
|
#if CONFIG_WEBM_IO
|
||||||
@@ -409,8 +393,8 @@ TEST_F(ExternalFrameBufferTest, MinFrameBuffers) {
|
|||||||
// #VP9_MAXIMUM_REF_BUFFERS + #VPX_MAXIMUM_WORK_BUFFERS.
|
// #VP9_MAXIMUM_REF_BUFFERS + #VPX_MAXIMUM_WORK_BUFFERS.
|
||||||
const int num_buffers = VP9_MAXIMUM_REF_BUFFERS + VPX_MAXIMUM_WORK_BUFFERS;
|
const int num_buffers = VP9_MAXIMUM_REF_BUFFERS + VPX_MAXIMUM_WORK_BUFFERS;
|
||||||
ASSERT_EQ(VPX_CODEC_OK,
|
ASSERT_EQ(VPX_CODEC_OK,
|
||||||
SetFrameBufferFunctions(
|
SetFrameBufferFunctions(num_buffers, get_vp9_frame_buffer,
|
||||||
num_buffers, get_vp9_frame_buffer, release_vp9_frame_buffer));
|
release_vp9_frame_buffer));
|
||||||
ASSERT_EQ(VPX_CODEC_OK, DecodeRemainingFrames());
|
ASSERT_EQ(VPX_CODEC_OK, DecodeRemainingFrames());
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -421,8 +405,8 @@ TEST_F(ExternalFrameBufferTest, EightJitterBuffers) {
|
|||||||
const int num_buffers =
|
const int num_buffers =
|
||||||
VP9_MAXIMUM_REF_BUFFERS + VPX_MAXIMUM_WORK_BUFFERS + jitter_buffers;
|
VP9_MAXIMUM_REF_BUFFERS + VPX_MAXIMUM_WORK_BUFFERS + jitter_buffers;
|
||||||
ASSERT_EQ(VPX_CODEC_OK,
|
ASSERT_EQ(VPX_CODEC_OK,
|
||||||
SetFrameBufferFunctions(
|
SetFrameBufferFunctions(num_buffers, get_vp9_frame_buffer,
|
||||||
num_buffers, get_vp9_frame_buffer, release_vp9_frame_buffer));
|
release_vp9_frame_buffer));
|
||||||
ASSERT_EQ(VPX_CODEC_OK, DecodeRemainingFrames());
|
ASSERT_EQ(VPX_CODEC_OK, DecodeRemainingFrames());
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -432,8 +416,8 @@ TEST_F(ExternalFrameBufferTest, NotEnoughBuffers) {
|
|||||||
// only use 5 frame buffers at one time.
|
// only use 5 frame buffers at one time.
|
||||||
const int num_buffers = 2;
|
const int num_buffers = 2;
|
||||||
ASSERT_EQ(VPX_CODEC_OK,
|
ASSERT_EQ(VPX_CODEC_OK,
|
||||||
SetFrameBufferFunctions(
|
SetFrameBufferFunctions(num_buffers, get_vp9_frame_buffer,
|
||||||
num_buffers, get_vp9_frame_buffer, release_vp9_frame_buffer));
|
release_vp9_frame_buffer));
|
||||||
ASSERT_EQ(VPX_CODEC_OK, DecodeOneFrame());
|
ASSERT_EQ(VPX_CODEC_OK, DecodeOneFrame());
|
||||||
ASSERT_EQ(VPX_CODEC_MEM_ERROR, DecodeRemainingFrames());
|
ASSERT_EQ(VPX_CODEC_MEM_ERROR, DecodeRemainingFrames());
|
||||||
}
|
}
|
||||||
@@ -457,8 +441,7 @@ TEST_F(ExternalFrameBufferTest, NullRealloc) {
|
|||||||
|
|
||||||
TEST_F(ExternalFrameBufferTest, ReallocOneLessByte) {
|
TEST_F(ExternalFrameBufferTest, ReallocOneLessByte) {
|
||||||
const int num_buffers = VP9_MAXIMUM_REF_BUFFERS + VPX_MAXIMUM_WORK_BUFFERS;
|
const int num_buffers = VP9_MAXIMUM_REF_BUFFERS + VPX_MAXIMUM_WORK_BUFFERS;
|
||||||
ASSERT_EQ(VPX_CODEC_OK,
|
ASSERT_EQ(VPX_CODEC_OK, SetFrameBufferFunctions(
|
||||||
SetFrameBufferFunctions(
|
|
||||||
num_buffers, get_vp9_one_less_byte_frame_buffer,
|
num_buffers, get_vp9_one_less_byte_frame_buffer,
|
||||||
release_vp9_frame_buffer));
|
release_vp9_frame_buffer));
|
||||||
ASSERT_EQ(VPX_CODEC_MEM_ERROR, DecodeOneFrame());
|
ASSERT_EQ(VPX_CODEC_MEM_ERROR, DecodeOneFrame());
|
||||||
@@ -466,9 +449,9 @@ TEST_F(ExternalFrameBufferTest, ReallocOneLessByte) {
|
|||||||
|
|
||||||
TEST_F(ExternalFrameBufferTest, NullGetFunction) {
|
TEST_F(ExternalFrameBufferTest, NullGetFunction) {
|
||||||
const int num_buffers = VP9_MAXIMUM_REF_BUFFERS + VPX_MAXIMUM_WORK_BUFFERS;
|
const int num_buffers = VP9_MAXIMUM_REF_BUFFERS + VPX_MAXIMUM_WORK_BUFFERS;
|
||||||
ASSERT_EQ(VPX_CODEC_INVALID_PARAM,
|
ASSERT_EQ(
|
||||||
SetFrameBufferFunctions(num_buffers, NULL,
|
VPX_CODEC_INVALID_PARAM,
|
||||||
release_vp9_frame_buffer));
|
SetFrameBufferFunctions(num_buffers, NULL, release_vp9_frame_buffer));
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(ExternalFrameBufferTest, NullReleaseFunction) {
|
TEST_F(ExternalFrameBufferTest, NullReleaseFunction) {
|
||||||
@@ -481,12 +464,13 @@ TEST_F(ExternalFrameBufferTest, SetAfterDecode) {
|
|||||||
const int num_buffers = VP9_MAXIMUM_REF_BUFFERS + VPX_MAXIMUM_WORK_BUFFERS;
|
const int num_buffers = VP9_MAXIMUM_REF_BUFFERS + VPX_MAXIMUM_WORK_BUFFERS;
|
||||||
ASSERT_EQ(VPX_CODEC_OK, DecodeOneFrame());
|
ASSERT_EQ(VPX_CODEC_OK, DecodeOneFrame());
|
||||||
ASSERT_EQ(VPX_CODEC_ERROR,
|
ASSERT_EQ(VPX_CODEC_ERROR,
|
||||||
SetFrameBufferFunctions(
|
SetFrameBufferFunctions(num_buffers, get_vp9_frame_buffer,
|
||||||
num_buffers, get_vp9_frame_buffer, release_vp9_frame_buffer));
|
release_vp9_frame_buffer));
|
||||||
}
|
}
|
||||||
#endif // CONFIG_WEBM_IO
|
#endif // CONFIG_WEBM_IO
|
||||||
|
|
||||||
VP9_INSTANTIATE_TEST_CASE(ExternalFrameBufferMD5Test,
|
VP9_INSTANTIATE_TEST_CASE(
|
||||||
|
ExternalFrameBufferMD5Test,
|
||||||
::testing::ValuesIn(libvpx_test::kVP9TestVectors,
|
::testing::ValuesIn(libvpx_test::kVP9TestVectors,
|
||||||
libvpx_test::kVP9TestVectors +
|
libvpx_test::kVP9TestVectors +
|
||||||
libvpx_test::kNumVP9TestVectors));
|
libvpx_test::kNumVP9TestVectors));
|
||||||
|
|||||||
@@ -128,35 +128,33 @@ class Trans4x4TestBase {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ASM_REGISTER_STATE_CHECK(RunFwdTxfm(test_input_block,
|
ASM_REGISTER_STATE_CHECK(
|
||||||
test_temp_block, pitch_));
|
RunFwdTxfm(test_input_block, test_temp_block, pitch_));
|
||||||
if (bit_depth_ == VPX_BITS_8) {
|
if (bit_depth_ == VPX_BITS_8) {
|
||||||
ASM_REGISTER_STATE_CHECK(RunInvTxfm(test_temp_block, dst, pitch_));
|
ASM_REGISTER_STATE_CHECK(RunInvTxfm(test_temp_block, dst, pitch_));
|
||||||
#if CONFIG_VP9_HIGHBITDEPTH
|
#if CONFIG_VP9_HIGHBITDEPTH
|
||||||
} else {
|
} else {
|
||||||
ASM_REGISTER_STATE_CHECK(RunInvTxfm(test_temp_block,
|
ASM_REGISTER_STATE_CHECK(
|
||||||
CONVERT_TO_BYTEPTR(dst16), pitch_));
|
RunInvTxfm(test_temp_block, CONVERT_TO_BYTEPTR(dst16), pitch_));
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
for (int j = 0; j < kNumCoeffs; ++j) {
|
for (int j = 0; j < kNumCoeffs; ++j) {
|
||||||
#if CONFIG_VP9_HIGHBITDEPTH
|
#if CONFIG_VP9_HIGHBITDEPTH
|
||||||
const uint32_t diff =
|
const int diff =
|
||||||
bit_depth_ == VPX_BITS_8 ? dst[j] - src[j] : dst16[j] - src16[j];
|
bit_depth_ == VPX_BITS_8 ? dst[j] - src[j] : dst16[j] - src16[j];
|
||||||
#else
|
#else
|
||||||
ASSERT_EQ(VPX_BITS_8, bit_depth_);
|
ASSERT_EQ(VPX_BITS_8, bit_depth_);
|
||||||
const uint32_t diff = dst[j] - src[j];
|
const int diff = dst[j] - src[j];
|
||||||
#endif
|
#endif
|
||||||
const uint32_t error = diff * diff;
|
const uint32_t error = diff * diff;
|
||||||
if (max_error < error)
|
if (max_error < error) max_error = error;
|
||||||
max_error = error;
|
|
||||||
total_error += error;
|
total_error += error;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
EXPECT_GE(static_cast<uint32_t>(limit), max_error)
|
EXPECT_GE(static_cast<uint32_t>(limit), max_error)
|
||||||
<< "Error: 4x4 FHT/IHT has an individual round trip error > "
|
<< "Error: 4x4 FHT/IHT has an individual round trip error > " << limit;
|
||||||
<< limit;
|
|
||||||
|
|
||||||
EXPECT_GE(count_test_block * limit, total_error)
|
EXPECT_GE(count_test_block * limit, total_error)
|
||||||
<< "Error: 4x4 FHT/IHT has average round trip error > " << limit
|
<< "Error: 4x4 FHT/IHT has average round trip error > " << limit
|
||||||
@@ -172,8 +170,9 @@ class Trans4x4TestBase {
|
|||||||
|
|
||||||
for (int i = 0; i < count_test_block; ++i) {
|
for (int i = 0; i < count_test_block; ++i) {
|
||||||
// Initialize a test block with input range [-mask_, mask_].
|
// Initialize a test block with input range [-mask_, mask_].
|
||||||
for (int j = 0; j < kNumCoeffs; ++j)
|
for (int j = 0; j < kNumCoeffs; ++j) {
|
||||||
input_block[j] = (rnd.Rand16() & mask_) - (rnd.Rand16() & mask_);
|
input_block[j] = (rnd.Rand16() & mask_) - (rnd.Rand16() & mask_);
|
||||||
|
}
|
||||||
|
|
||||||
fwd_txfm_ref(input_block, output_ref_block, pitch_, tx_type_);
|
fwd_txfm_ref(input_block, output_ref_block, pitch_, tx_type_);
|
||||||
ASM_REGISTER_STATE_CHECK(RunFwdTxfm(input_block, output_block, pitch_));
|
ASM_REGISTER_STATE_CHECK(RunFwdTxfm(input_block, output_block, pitch_));
|
||||||
@@ -197,16 +196,14 @@ class Trans4x4TestBase {
|
|||||||
input_extreme_block[j] = rnd.Rand8() % 2 ? mask_ : -mask_;
|
input_extreme_block[j] = rnd.Rand8() % 2 ? mask_ : -mask_;
|
||||||
}
|
}
|
||||||
if (i == 0) {
|
if (i == 0) {
|
||||||
for (int j = 0; j < kNumCoeffs; ++j)
|
for (int j = 0; j < kNumCoeffs; ++j) input_extreme_block[j] = mask_;
|
||||||
input_extreme_block[j] = mask_;
|
|
||||||
} else if (i == 1) {
|
} else if (i == 1) {
|
||||||
for (int j = 0; j < kNumCoeffs; ++j)
|
for (int j = 0; j < kNumCoeffs; ++j) input_extreme_block[j] = -mask_;
|
||||||
input_extreme_block[j] = -mask_;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fwd_txfm_ref(input_extreme_block, output_ref_block, pitch_, tx_type_);
|
fwd_txfm_ref(input_extreme_block, output_ref_block, pitch_, tx_type_);
|
||||||
ASM_REGISTER_STATE_CHECK(RunFwdTxfm(input_extreme_block,
|
ASM_REGISTER_STATE_CHECK(
|
||||||
output_block, pitch_));
|
RunFwdTxfm(input_extreme_block, output_block, pitch_));
|
||||||
|
|
||||||
// The minimum quant value is 4.
|
// The minimum quant value is 4.
|
||||||
for (int j = 0; j < kNumCoeffs; ++j) {
|
for (int j = 0; j < kNumCoeffs; ++j) {
|
||||||
@@ -251,22 +248,21 @@ class Trans4x4TestBase {
|
|||||||
ASM_REGISTER_STATE_CHECK(RunInvTxfm(coeff, dst, pitch_));
|
ASM_REGISTER_STATE_CHECK(RunInvTxfm(coeff, dst, pitch_));
|
||||||
#if CONFIG_VP9_HIGHBITDEPTH
|
#if CONFIG_VP9_HIGHBITDEPTH
|
||||||
} else {
|
} else {
|
||||||
ASM_REGISTER_STATE_CHECK(RunInvTxfm(coeff, CONVERT_TO_BYTEPTR(dst16),
|
ASM_REGISTER_STATE_CHECK(
|
||||||
pitch_));
|
RunInvTxfm(coeff, CONVERT_TO_BYTEPTR(dst16), pitch_));
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
for (int j = 0; j < kNumCoeffs; ++j) {
|
for (int j = 0; j < kNumCoeffs; ++j) {
|
||||||
#if CONFIG_VP9_HIGHBITDEPTH
|
#if CONFIG_VP9_HIGHBITDEPTH
|
||||||
const uint32_t diff =
|
const int diff =
|
||||||
bit_depth_ == VPX_BITS_8 ? dst[j] - src[j] : dst16[j] - src16[j];
|
bit_depth_ == VPX_BITS_8 ? dst[j] - src[j] : dst16[j] - src16[j];
|
||||||
#else
|
#else
|
||||||
const uint32_t diff = dst[j] - src[j];
|
const int diff = dst[j] - src[j];
|
||||||
#endif
|
#endif
|
||||||
const uint32_t error = diff * diff;
|
const uint32_t error = diff * diff;
|
||||||
EXPECT_GE(static_cast<uint32_t>(limit), error)
|
EXPECT_GE(static_cast<uint32_t>(limit), error)
|
||||||
<< "Error: 4x4 IDCT has error " << error
|
<< "Error: 4x4 IDCT has error " << error << " at index " << j;
|
||||||
<< " at index " << j;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -278,8 +274,7 @@ class Trans4x4TestBase {
|
|||||||
int mask_;
|
int mask_;
|
||||||
};
|
};
|
||||||
|
|
||||||
class Trans4x4DCT
|
class Trans4x4DCT : public Trans4x4TestBase,
|
||||||
: public Trans4x4TestBase,
|
|
||||||
public ::testing::TestWithParam<Dct4x4Param> {
|
public ::testing::TestWithParam<Dct4x4Param> {
|
||||||
public:
|
public:
|
||||||
virtual ~Trans4x4DCT() {}
|
virtual ~Trans4x4DCT() {}
|
||||||
@@ -307,24 +302,15 @@ class Trans4x4DCT
|
|||||||
IdctFunc inv_txfm_;
|
IdctFunc inv_txfm_;
|
||||||
};
|
};
|
||||||
|
|
||||||
TEST_P(Trans4x4DCT, AccuracyCheck) {
|
TEST_P(Trans4x4DCT, AccuracyCheck) { RunAccuracyCheck(1); }
|
||||||
RunAccuracyCheck(1);
|
|
||||||
}
|
|
||||||
|
|
||||||
TEST_P(Trans4x4DCT, CoeffCheck) {
|
TEST_P(Trans4x4DCT, CoeffCheck) { RunCoeffCheck(); }
|
||||||
RunCoeffCheck();
|
|
||||||
}
|
|
||||||
|
|
||||||
TEST_P(Trans4x4DCT, MemCheck) {
|
TEST_P(Trans4x4DCT, MemCheck) { RunMemCheck(); }
|
||||||
RunMemCheck();
|
|
||||||
}
|
|
||||||
|
|
||||||
TEST_P(Trans4x4DCT, InvAccuracyCheck) {
|
TEST_P(Trans4x4DCT, InvAccuracyCheck) { RunInvAccuracyCheck(1); }
|
||||||
RunInvAccuracyCheck(1);
|
|
||||||
}
|
|
||||||
|
|
||||||
class Trans4x4HT
|
class Trans4x4HT : public Trans4x4TestBase,
|
||||||
: public Trans4x4TestBase,
|
|
||||||
public ::testing::TestWithParam<Ht4x4Param> {
|
public ::testing::TestWithParam<Ht4x4Param> {
|
||||||
public:
|
public:
|
||||||
virtual ~Trans4x4HT() {}
|
virtual ~Trans4x4HT() {}
|
||||||
@@ -353,24 +339,15 @@ class Trans4x4HT
|
|||||||
IhtFunc inv_txfm_;
|
IhtFunc inv_txfm_;
|
||||||
};
|
};
|
||||||
|
|
||||||
TEST_P(Trans4x4HT, AccuracyCheck) {
|
TEST_P(Trans4x4HT, AccuracyCheck) { RunAccuracyCheck(1); }
|
||||||
RunAccuracyCheck(1);
|
|
||||||
}
|
|
||||||
|
|
||||||
TEST_P(Trans4x4HT, CoeffCheck) {
|
TEST_P(Trans4x4HT, CoeffCheck) { RunCoeffCheck(); }
|
||||||
RunCoeffCheck();
|
|
||||||
}
|
|
||||||
|
|
||||||
TEST_P(Trans4x4HT, MemCheck) {
|
TEST_P(Trans4x4HT, MemCheck) { RunMemCheck(); }
|
||||||
RunMemCheck();
|
|
||||||
}
|
|
||||||
|
|
||||||
TEST_P(Trans4x4HT, InvAccuracyCheck) {
|
TEST_P(Trans4x4HT, InvAccuracyCheck) { RunInvAccuracyCheck(1); }
|
||||||
RunInvAccuracyCheck(1);
|
|
||||||
}
|
|
||||||
|
|
||||||
class Trans4x4WHT
|
class Trans4x4WHT : public Trans4x4TestBase,
|
||||||
: public Trans4x4TestBase,
|
|
||||||
public ::testing::TestWithParam<Dct4x4Param> {
|
public ::testing::TestWithParam<Dct4x4Param> {
|
||||||
public:
|
public:
|
||||||
virtual ~Trans4x4WHT() {}
|
virtual ~Trans4x4WHT() {}
|
||||||
@@ -398,21 +375,13 @@ class Trans4x4WHT
|
|||||||
IdctFunc inv_txfm_;
|
IdctFunc inv_txfm_;
|
||||||
};
|
};
|
||||||
|
|
||||||
TEST_P(Trans4x4WHT, AccuracyCheck) {
|
TEST_P(Trans4x4WHT, AccuracyCheck) { RunAccuracyCheck(0); }
|
||||||
RunAccuracyCheck(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
TEST_P(Trans4x4WHT, CoeffCheck) {
|
TEST_P(Trans4x4WHT, CoeffCheck) { RunCoeffCheck(); }
|
||||||
RunCoeffCheck();
|
|
||||||
}
|
|
||||||
|
|
||||||
TEST_P(Trans4x4WHT, MemCheck) {
|
TEST_P(Trans4x4WHT, MemCheck) { RunMemCheck(); }
|
||||||
RunMemCheck();
|
|
||||||
}
|
|
||||||
|
|
||||||
TEST_P(Trans4x4WHT, InvAccuracyCheck) {
|
TEST_P(Trans4x4WHT, InvAccuracyCheck) { RunInvAccuracyCheck(0); }
|
||||||
RunInvAccuracyCheck(0);
|
|
||||||
}
|
|
||||||
using std::tr1::make_tuple;
|
using std::tr1::make_tuple;
|
||||||
|
|
||||||
#if CONFIG_VP9_HIGHBITDEPTH
|
#if CONFIG_VP9_HIGHBITDEPTH
|
||||||
@@ -423,10 +392,10 @@ INSTANTIATE_TEST_CASE_P(
|
|||||||
make_tuple(&vpx_highbd_fdct4x4_c, &idct4x4_12, 0, VPX_BITS_12),
|
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)));
|
make_tuple(&vpx_fdct4x4_c, &vpx_idct4x4_16_add_c, 0, VPX_BITS_8)));
|
||||||
#else
|
#else
|
||||||
INSTANTIATE_TEST_CASE_P(
|
INSTANTIATE_TEST_CASE_P(C, Trans4x4DCT,
|
||||||
C, Trans4x4DCT,
|
::testing::Values(make_tuple(&vpx_fdct4x4_c,
|
||||||
::testing::Values(
|
&vpx_idct4x4_16_add_c, 0,
|
||||||
make_tuple(&vpx_fdct4x4_c, &vpx_idct4x4_16_add_c, 0, VPX_BITS_8)));
|
VPX_BITS_8)));
|
||||||
#endif // CONFIG_VP9_HIGHBITDEPTH
|
#endif // CONFIG_VP9_HIGHBITDEPTH
|
||||||
|
|
||||||
#if CONFIG_VP9_HIGHBITDEPTH
|
#if CONFIG_VP9_HIGHBITDEPTH
|
||||||
@@ -463,21 +432,18 @@ INSTANTIATE_TEST_CASE_P(
|
|||||||
make_tuple(&vp9_highbd_fwht4x4_c, &iwht4x4_12, 0, VPX_BITS_12),
|
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)));
|
make_tuple(&vp9_fwht4x4_c, &vpx_iwht4x4_16_add_c, 0, VPX_BITS_8)));
|
||||||
#else
|
#else
|
||||||
INSTANTIATE_TEST_CASE_P(
|
INSTANTIATE_TEST_CASE_P(C, Trans4x4WHT,
|
||||||
C, Trans4x4WHT,
|
::testing::Values(make_tuple(&vp9_fwht4x4_c,
|
||||||
::testing::Values(
|
&vpx_iwht4x4_16_add_c, 0,
|
||||||
make_tuple(&vp9_fwht4x4_c, &vpx_iwht4x4_16_add_c, 0, VPX_BITS_8)));
|
VPX_BITS_8)));
|
||||||
#endif // CONFIG_VP9_HIGHBITDEPTH
|
#endif // CONFIG_VP9_HIGHBITDEPTH
|
||||||
|
|
||||||
#if HAVE_NEON_ASM && !CONFIG_VP9_HIGHBITDEPTH && !CONFIG_EMULATE_HARDWARE
|
#if HAVE_NEON && !CONFIG_EMULATE_HARDWARE
|
||||||
INSTANTIATE_TEST_CASE_P(
|
INSTANTIATE_TEST_CASE_P(NEON, Trans4x4DCT,
|
||||||
NEON, Trans4x4DCT,
|
::testing::Values(make_tuple(&vpx_fdct4x4_c,
|
||||||
::testing::Values(
|
&vpx_idct4x4_16_add_neon,
|
||||||
make_tuple(&vpx_fdct4x4_c,
|
0, VPX_BITS_8)));
|
||||||
&vpx_idct4x4_16_add_neon, 0, VPX_BITS_8)));
|
#if !CONFIG_VP9_HIGHBITDEPTH
|
||||||
#endif // HAVE_NEON_ASM && !CONFIG_VP9_HIGHBITDEPTH && !CONFIG_EMULATE_HARDWARE
|
|
||||||
|
|
||||||
#if HAVE_NEON && !CONFIG_VP9_HIGHBITDEPTH && !CONFIG_EMULATE_HARDWARE
|
|
||||||
INSTANTIATE_TEST_CASE_P(
|
INSTANTIATE_TEST_CASE_P(
|
||||||
NEON, Trans4x4HT,
|
NEON, Trans4x4HT,
|
||||||
::testing::Values(
|
::testing::Values(
|
||||||
@@ -485,30 +451,22 @@ INSTANTIATE_TEST_CASE_P(
|
|||||||
make_tuple(&vp9_fht4x4_c, &vp9_iht4x4_16_add_neon, 1, 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, 2, VPX_BITS_8),
|
||||||
make_tuple(&vp9_fht4x4_c, &vp9_iht4x4_16_add_neon, 3, 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
|
#endif // !CONFIG_VP9_HIGHBITDEPTH
|
||||||
|
#endif // HAVE_NEON && !CONFIG_EMULATE_HARDWARE
|
||||||
|
|
||||||
#if CONFIG_USE_X86INC && HAVE_MMX && !CONFIG_VP9_HIGHBITDEPTH && \
|
#if HAVE_SSE2 && !CONFIG_EMULATE_HARDWARE
|
||||||
!CONFIG_EMULATE_HARDWARE
|
|
||||||
INSTANTIATE_TEST_CASE_P(
|
|
||||||
MMX, Trans4x4WHT,
|
|
||||||
::testing::Values(
|
|
||||||
make_tuple(&vp9_fwht4x4_mmx, &vpx_iwht4x4_16_add_c, 0, VPX_BITS_8)));
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if CONFIG_USE_X86INC && HAVE_SSE2 && !CONFIG_VP9_HIGHBITDEPTH && \
|
|
||||||
!CONFIG_EMULATE_HARDWARE
|
|
||||||
INSTANTIATE_TEST_CASE_P(
|
INSTANTIATE_TEST_CASE_P(
|
||||||
SSE2, Trans4x4WHT,
|
SSE2, Trans4x4WHT,
|
||||||
::testing::Values(
|
::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)));
|
make_tuple(&vp9_fwht4x4_c, &vpx_iwht4x4_16_add_sse2, 0, VPX_BITS_8)));
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if HAVE_SSE2 && !CONFIG_VP9_HIGHBITDEPTH && !CONFIG_EMULATE_HARDWARE
|
#if HAVE_SSE2 && !CONFIG_VP9_HIGHBITDEPTH && !CONFIG_EMULATE_HARDWARE
|
||||||
INSTANTIATE_TEST_CASE_P(
|
INSTANTIATE_TEST_CASE_P(SSE2, Trans4x4DCT,
|
||||||
SSE2, Trans4x4DCT,
|
::testing::Values(make_tuple(&vpx_fdct4x4_sse2,
|
||||||
::testing::Values(
|
&vpx_idct4x4_16_add_sse2,
|
||||||
make_tuple(&vpx_fdct4x4_sse2,
|
0, VPX_BITS_8)));
|
||||||
&vpx_idct4x4_16_add_sse2, 0, VPX_BITS_8)));
|
|
||||||
INSTANTIATE_TEST_CASE_P(
|
INSTANTIATE_TEST_CASE_P(
|
||||||
SSE2, Trans4x4HT,
|
SSE2, Trans4x4HT,
|
||||||
::testing::Values(
|
::testing::Values(
|
||||||
@@ -526,8 +484,7 @@ INSTANTIATE_TEST_CASE_P(
|
|||||||
make_tuple(&vpx_highbd_fdct4x4_sse2, &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_c, &idct4x4_12_sse2, 0, VPX_BITS_12),
|
||||||
make_tuple(&vpx_highbd_fdct4x4_sse2, &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,
|
make_tuple(&vpx_fdct4x4_sse2, &vpx_idct4x4_16_add_c, 0, VPX_BITS_8)));
|
||||||
VPX_BITS_8)));
|
|
||||||
|
|
||||||
INSTANTIATE_TEST_CASE_P(
|
INSTANTIATE_TEST_CASE_P(
|
||||||
SSE2, Trans4x4HT,
|
SSE2, Trans4x4HT,
|
||||||
@@ -539,10 +496,10 @@ INSTANTIATE_TEST_CASE_P(
|
|||||||
#endif // HAVE_SSE2 && CONFIG_VP9_HIGHBITDEPTH && !CONFIG_EMULATE_HARDWARE
|
#endif // HAVE_SSE2 && CONFIG_VP9_HIGHBITDEPTH && !CONFIG_EMULATE_HARDWARE
|
||||||
|
|
||||||
#if HAVE_MSA && !CONFIG_VP9_HIGHBITDEPTH && !CONFIG_EMULATE_HARDWARE
|
#if HAVE_MSA && !CONFIG_VP9_HIGHBITDEPTH && !CONFIG_EMULATE_HARDWARE
|
||||||
INSTANTIATE_TEST_CASE_P(
|
INSTANTIATE_TEST_CASE_P(MSA, Trans4x4DCT,
|
||||||
MSA, Trans4x4DCT,
|
::testing::Values(make_tuple(&vpx_fdct4x4_msa,
|
||||||
::testing::Values(
|
&vpx_idct4x4_16_add_msa, 0,
|
||||||
make_tuple(&vpx_fdct4x4_msa, &vpx_idct4x4_16_add_msa, 0, VPX_BITS_8)));
|
VPX_BITS_8)));
|
||||||
INSTANTIATE_TEST_CASE_P(
|
INSTANTIATE_TEST_CASE_P(
|
||||||
MSA, Trans4x4HT,
|
MSA, Trans4x4HT,
|
||||||
::testing::Values(
|
::testing::Values(
|
||||||
|
|||||||
@@ -51,10 +51,10 @@ void reference_8x8_dct_1d(const double in[8], double out[8]) {
|
|||||||
const double kInvSqrt2 = 0.707106781186547524400844362104;
|
const double kInvSqrt2 = 0.707106781186547524400844362104;
|
||||||
for (int k = 0; k < 8; k++) {
|
for (int k = 0; k < 8; k++) {
|
||||||
out[k] = 0.0;
|
out[k] = 0.0;
|
||||||
for (int n = 0; n < 8; n++)
|
for (int n = 0; n < 8; n++) {
|
||||||
out[k] += in[n] * cos(kPi * (2 * n + 1) * k / 16.0);
|
out[k] += in[n] * cos(kPi * (2 * n + 1) * k / 16.0);
|
||||||
if (k == 0)
|
}
|
||||||
out[k] = out[k] * kInvSqrt2;
|
if (k == 0) out[k] = out[k] * kInvSqrt2;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -63,25 +63,20 @@ void reference_8x8_dct_2d(const int16_t input[kNumCoeffs],
|
|||||||
// First transform columns
|
// First transform columns
|
||||||
for (int i = 0; i < 8; ++i) {
|
for (int i = 0; i < 8; ++i) {
|
||||||
double temp_in[8], temp_out[8];
|
double temp_in[8], temp_out[8];
|
||||||
for (int j = 0; j < 8; ++j)
|
for (int j = 0; j < 8; ++j) temp_in[j] = input[j * 8 + i];
|
||||||
temp_in[j] = input[j*8 + i];
|
|
||||||
reference_8x8_dct_1d(temp_in, temp_out);
|
reference_8x8_dct_1d(temp_in, temp_out);
|
||||||
for (int j = 0; j < 8; ++j)
|
for (int j = 0; j < 8; ++j) output[j * 8 + i] = temp_out[j];
|
||||||
output[j * 8 + i] = temp_out[j];
|
|
||||||
}
|
}
|
||||||
// Then transform rows
|
// Then transform rows
|
||||||
for (int i = 0; i < 8; ++i) {
|
for (int i = 0; i < 8; ++i) {
|
||||||
double temp_in[8], temp_out[8];
|
double temp_in[8], temp_out[8];
|
||||||
for (int j = 0; j < 8; ++j)
|
for (int j = 0; j < 8; ++j) temp_in[j] = output[j + i * 8];
|
||||||
temp_in[j] = output[j + i*8];
|
|
||||||
reference_8x8_dct_1d(temp_in, temp_out);
|
reference_8x8_dct_1d(temp_in, temp_out);
|
||||||
// Scale by some magic number
|
// Scale by some magic number
|
||||||
for (int j = 0; j < 8; ++j)
|
for (int j = 0; j < 8; ++j) output[j + i * 8] = temp_out[j] * 2;
|
||||||
output[j + i * 8] = temp_out[j] * 2;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void fdct8x8_ref(const int16_t *in, tran_low_t *out, int stride,
|
void fdct8x8_ref(const int16_t *in, tran_low_t *out, int stride,
|
||||||
int /*tx_type*/) {
|
int /*tx_type*/) {
|
||||||
vpx_fdct8x8_c(in, out, stride);
|
vpx_fdct8x8_c(in, out, stride);
|
||||||
@@ -110,20 +105,20 @@ void iht8x8_12(const tran_low_t *in, uint8_t *out, int stride, int tx_type) {
|
|||||||
|
|
||||||
#if HAVE_SSE2
|
#if HAVE_SSE2
|
||||||
|
|
||||||
void idct8x8_10_add_10_c(const tran_low_t *in, uint8_t *out, int stride) {
|
void idct8x8_12_add_10_c(const tran_low_t *in, uint8_t *out, int stride) {
|
||||||
vpx_highbd_idct8x8_10_add_c(in, out, stride, 10);
|
vpx_highbd_idct8x8_12_add_c(in, out, stride, 10);
|
||||||
}
|
}
|
||||||
|
|
||||||
void idct8x8_10_add_12_c(const tran_low_t *in, uint8_t *out, int stride) {
|
void idct8x8_12_add_12_c(const tran_low_t *in, uint8_t *out, int stride) {
|
||||||
vpx_highbd_idct8x8_10_add_c(in, out, stride, 12);
|
vpx_highbd_idct8x8_12_add_c(in, out, stride, 12);
|
||||||
}
|
}
|
||||||
|
|
||||||
void idct8x8_10_add_10_sse2(const tran_low_t *in, uint8_t *out, int stride) {
|
void idct8x8_12_add_10_sse2(const tran_low_t *in, uint8_t *out, int stride) {
|
||||||
vpx_highbd_idct8x8_10_add_sse2(in, out, stride, 10);
|
vpx_highbd_idct8x8_12_add_sse2(in, out, stride, 10);
|
||||||
}
|
}
|
||||||
|
|
||||||
void idct8x8_10_add_12_sse2(const tran_low_t *in, uint8_t *out, int stride) {
|
void idct8x8_12_add_12_sse2(const tran_low_t *in, uint8_t *out, int stride) {
|
||||||
vpx_highbd_idct8x8_10_add_sse2(in, out, stride, 12);
|
vpx_highbd_idct8x8_12_add_sse2(in, out, stride, 12);
|
||||||
}
|
}
|
||||||
|
|
||||||
void idct8x8_64_add_10_sse2(const tran_low_t *in, uint8_t *out, int stride) {
|
void idct8x8_64_add_10_sse2(const tran_low_t *in, uint8_t *out, int stride) {
|
||||||
@@ -155,19 +150,21 @@ class FwdTrans8x8TestBase {
|
|||||||
|
|
||||||
for (int i = 0; i < count_test_block; ++i) {
|
for (int i = 0; i < count_test_block; ++i) {
|
||||||
// Initialize a test block with input range [-255, 255].
|
// Initialize a test block with input range [-255, 255].
|
||||||
for (int j = 0; j < 64; ++j)
|
for (int j = 0; j < 64; ++j) {
|
||||||
test_input_block[j] = ((rnd.Rand16() >> (16 - bit_depth_)) & mask_) -
|
test_input_block[j] = ((rnd.Rand16() >> (16 - bit_depth_)) & mask_) -
|
||||||
((rnd.Rand16() >> (16 - bit_depth_)) & mask_);
|
((rnd.Rand16() >> (16 - bit_depth_)) & mask_);
|
||||||
|
}
|
||||||
ASM_REGISTER_STATE_CHECK(
|
ASM_REGISTER_STATE_CHECK(
|
||||||
RunFwdTxfm(test_input_block, test_output_block, pitch_));
|
RunFwdTxfm(test_input_block, test_output_block, pitch_));
|
||||||
|
|
||||||
for (int j = 0; j < 64; ++j) {
|
for (int j = 0; j < 64; ++j) {
|
||||||
if (test_output_block[j] < 0)
|
if (test_output_block[j] < 0) {
|
||||||
++count_sign_block[j][0];
|
++count_sign_block[j][0];
|
||||||
else if (test_output_block[j] > 0)
|
} else if (test_output_block[j] > 0) {
|
||||||
++count_sign_block[j][1];
|
++count_sign_block[j][1];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
for (int j = 0; j < 64; ++j) {
|
for (int j = 0; j < 64; ++j) {
|
||||||
const int diff = abs(count_sign_block[j][0] - count_sign_block[j][1]);
|
const int diff = abs(count_sign_block[j][0] - count_sign_block[j][1]);
|
||||||
@@ -177,27 +174,28 @@ class FwdTrans8x8TestBase {
|
|||||||
<< 1. * max_diff / count_test_block * 100 << "%"
|
<< 1. * max_diff / count_test_block * 100 << "%"
|
||||||
<< " for input range [-255, 255] at index " << j
|
<< " for input range [-255, 255] at index " << j
|
||||||
<< " count0: " << count_sign_block[j][0]
|
<< " count0: " << count_sign_block[j][0]
|
||||||
<< " count1: " << count_sign_block[j][1]
|
<< " count1: " << count_sign_block[j][1] << " diff: " << diff;
|
||||||
<< " diff: " << diff;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
memset(count_sign_block, 0, sizeof(count_sign_block));
|
memset(count_sign_block, 0, sizeof(count_sign_block));
|
||||||
|
|
||||||
for (int i = 0; i < count_test_block; ++i) {
|
for (int i = 0; i < count_test_block; ++i) {
|
||||||
// Initialize a test block with input range [-mask_ / 16, mask_ / 16].
|
// Initialize a test block with input range [-mask_ / 16, mask_ / 16].
|
||||||
for (int j = 0; j < 64; ++j)
|
for (int j = 0; j < 64; ++j) {
|
||||||
test_input_block[j] = ((rnd.Rand16() & mask_) >> 4) -
|
test_input_block[j] =
|
||||||
((rnd.Rand16() & mask_) >> 4);
|
((rnd.Rand16() & mask_) >> 4) - ((rnd.Rand16() & mask_) >> 4);
|
||||||
|
}
|
||||||
ASM_REGISTER_STATE_CHECK(
|
ASM_REGISTER_STATE_CHECK(
|
||||||
RunFwdTxfm(test_input_block, test_output_block, pitch_));
|
RunFwdTxfm(test_input_block, test_output_block, pitch_));
|
||||||
|
|
||||||
for (int j = 0; j < 64; ++j) {
|
for (int j = 0; j < 64; ++j) {
|
||||||
if (test_output_block[j] < 0)
|
if (test_output_block[j] < 0) {
|
||||||
++count_sign_block[j][0];
|
++count_sign_block[j][0];
|
||||||
else if (test_output_block[j] > 0)
|
} else if (test_output_block[j] > 0) {
|
||||||
++count_sign_block[j][1];
|
++count_sign_block[j][1];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
for (int j = 0; j < 64; ++j) {
|
for (int j = 0; j < 64; ++j) {
|
||||||
const int diff = abs(count_sign_block[j][0] - count_sign_block[j][1]);
|
const int diff = abs(count_sign_block[j][0] - count_sign_block[j][1]);
|
||||||
@@ -207,8 +205,7 @@ class FwdTrans8x8TestBase {
|
|||||||
<< 1. * max_diff / count_test_block * 100 << "%"
|
<< 1. * max_diff / count_test_block * 100 << "%"
|
||||||
<< " for input range [-15, 15] at index " << j
|
<< " for input range [-15, 15] at index " << j
|
||||||
<< " count0: " << count_sign_block[j][0]
|
<< " count0: " << count_sign_block[j][0]
|
||||||
<< " count1: " << count_sign_block[j][1]
|
<< " count1: " << count_sign_block[j][1] << " diff: " << diff;
|
||||||
<< " diff: " << diff;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -256,8 +253,7 @@ class FwdTrans8x8TestBase {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (bit_depth_ == VPX_BITS_8) {
|
if (bit_depth_ == VPX_BITS_8) {
|
||||||
ASM_REGISTER_STATE_CHECK(
|
ASM_REGISTER_STATE_CHECK(RunInvTxfm(test_temp_block, dst, pitch_));
|
||||||
RunInvTxfm(test_temp_block, dst, pitch_));
|
|
||||||
#if CONFIG_VP9_HIGHBITDEPTH
|
#if CONFIG_VP9_HIGHBITDEPTH
|
||||||
} else {
|
} else {
|
||||||
ASM_REGISTER_STATE_CHECK(
|
ASM_REGISTER_STATE_CHECK(
|
||||||
@@ -273,8 +269,7 @@ class FwdTrans8x8TestBase {
|
|||||||
const int diff = dst[j] - src[j];
|
const int diff = dst[j] - src[j];
|
||||||
#endif
|
#endif
|
||||||
const int error = diff * diff;
|
const int error = diff * diff;
|
||||||
if (max_error < error)
|
if (max_error < error) max_error = error;
|
||||||
max_error = error;
|
|
||||||
total_error += error;
|
total_error += error;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -341,8 +336,7 @@ class FwdTrans8x8TestBase {
|
|||||||
ASM_REGISTER_STATE_CHECK(
|
ASM_REGISTER_STATE_CHECK(
|
||||||
fwd_txfm_ref(test_input_block, ref_temp_block, pitch_, tx_type_));
|
fwd_txfm_ref(test_input_block, ref_temp_block, pitch_, tx_type_));
|
||||||
if (bit_depth_ == VPX_BITS_8) {
|
if (bit_depth_ == VPX_BITS_8) {
|
||||||
ASM_REGISTER_STATE_CHECK(
|
ASM_REGISTER_STATE_CHECK(RunInvTxfm(test_temp_block, dst, pitch_));
|
||||||
RunInvTxfm(test_temp_block, dst, pitch_));
|
|
||||||
#if CONFIG_VP9_HIGHBITDEPTH
|
#if CONFIG_VP9_HIGHBITDEPTH
|
||||||
} else {
|
} else {
|
||||||
ASM_REGISTER_STATE_CHECK(
|
ASM_REGISTER_STATE_CHECK(
|
||||||
@@ -358,8 +352,7 @@ class FwdTrans8x8TestBase {
|
|||||||
const int diff = dst[j] - src[j];
|
const int diff = dst[j] - src[j];
|
||||||
#endif
|
#endif
|
||||||
const int error = diff * diff;
|
const int error = diff * diff;
|
||||||
if (max_error < error)
|
if (max_error < error) max_error = error;
|
||||||
max_error = error;
|
|
||||||
total_error += error;
|
total_error += error;
|
||||||
|
|
||||||
const int coeff_diff = test_temp_block[j] - ref_temp_block[j];
|
const int coeff_diff = test_temp_block[j] - ref_temp_block[j];
|
||||||
@@ -411,29 +404,29 @@ class FwdTrans8x8TestBase {
|
|||||||
}
|
}
|
||||||
|
|
||||||
reference_8x8_dct_2d(in, out_r);
|
reference_8x8_dct_2d(in, out_r);
|
||||||
for (int j = 0; j < kNumCoeffs; ++j)
|
for (int j = 0; j < kNumCoeffs; ++j) {
|
||||||
coeff[j] = static_cast<tran_low_t>(round(out_r[j]));
|
coeff[j] = static_cast<tran_low_t>(round(out_r[j]));
|
||||||
|
}
|
||||||
|
|
||||||
if (bit_depth_ == VPX_BITS_8) {
|
if (bit_depth_ == VPX_BITS_8) {
|
||||||
ASM_REGISTER_STATE_CHECK(RunInvTxfm(coeff, dst, pitch_));
|
ASM_REGISTER_STATE_CHECK(RunInvTxfm(coeff, dst, pitch_));
|
||||||
#if CONFIG_VP9_HIGHBITDEPTH
|
#if CONFIG_VP9_HIGHBITDEPTH
|
||||||
} else {
|
} else {
|
||||||
ASM_REGISTER_STATE_CHECK(RunInvTxfm(coeff, CONVERT_TO_BYTEPTR(dst16),
|
ASM_REGISTER_STATE_CHECK(
|
||||||
pitch_));
|
RunInvTxfm(coeff, CONVERT_TO_BYTEPTR(dst16), pitch_));
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
for (int j = 0; j < kNumCoeffs; ++j) {
|
for (int j = 0; j < kNumCoeffs; ++j) {
|
||||||
#if CONFIG_VP9_HIGHBITDEPTH
|
#if CONFIG_VP9_HIGHBITDEPTH
|
||||||
const uint32_t diff =
|
const int diff =
|
||||||
bit_depth_ == VPX_BITS_8 ? dst[j] - src[j] : dst16[j] - src16[j];
|
bit_depth_ == VPX_BITS_8 ? dst[j] - src[j] : dst16[j] - src16[j];
|
||||||
#else
|
#else
|
||||||
const uint32_t diff = dst[j] - src[j];
|
const int diff = dst[j] - src[j];
|
||||||
#endif
|
#endif
|
||||||
const uint32_t error = diff * diff;
|
const uint32_t error = diff * diff;
|
||||||
EXPECT_GE(1u << 2 * (bit_depth_ - 8), error)
|
EXPECT_GE(1u << 2 * (bit_depth_ - 8), error)
|
||||||
<< "Error: 8x8 IDCT has error " << error
|
<< "Error: 8x8 IDCT has error " << error << " at index " << j;
|
||||||
<< " at index " << j;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -449,20 +442,21 @@ class FwdTrans8x8TestBase {
|
|||||||
double out_r[kNumCoeffs];
|
double out_r[kNumCoeffs];
|
||||||
|
|
||||||
// Initialize a test block with input range [-mask_, mask_].
|
// Initialize a test block with input range [-mask_, mask_].
|
||||||
for (int j = 0; j < kNumCoeffs; ++j)
|
for (int j = 0; j < kNumCoeffs; ++j) {
|
||||||
in[j] = rnd.Rand8() % 2 == 0 ? mask_ : -mask_;
|
in[j] = rnd.Rand8() % 2 == 0 ? mask_ : -mask_;
|
||||||
|
}
|
||||||
|
|
||||||
RunFwdTxfm(in, coeff, pitch_);
|
RunFwdTxfm(in, coeff, pitch_);
|
||||||
reference_8x8_dct_2d(in, out_r);
|
reference_8x8_dct_2d(in, out_r);
|
||||||
for (int j = 0; j < kNumCoeffs; ++j)
|
for (int j = 0; j < kNumCoeffs; ++j) {
|
||||||
coeff_r[j] = static_cast<tran_low_t>(round(out_r[j]));
|
coeff_r[j] = static_cast<tran_low_t>(round(out_r[j]));
|
||||||
|
}
|
||||||
|
|
||||||
for (int j = 0; j < kNumCoeffs; ++j) {
|
for (int j = 0; j < kNumCoeffs; ++j) {
|
||||||
const uint32_t diff = coeff[j] - coeff_r[j];
|
const int32_t diff = coeff[j] - coeff_r[j];
|
||||||
const uint32_t error = diff * diff;
|
const uint32_t error = diff * diff;
|
||||||
EXPECT_GE(9u << 2 * (bit_depth_ - 8), error)
|
EXPECT_GE(9u << 2 * (bit_depth_ - 8), error)
|
||||||
<< "Error: 8x8 DCT has error " << error
|
<< "Error: 8x8 DCT has error " << error << " at index " << j;
|
||||||
<< " at index " << j;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -504,21 +498,20 @@ void CompareInvReference(IdctFunc ref_txfm, int thresh) {
|
|||||||
#if CONFIG_VP9_HIGHBITDEPTH
|
#if CONFIG_VP9_HIGHBITDEPTH
|
||||||
} else {
|
} else {
|
||||||
ref_txfm(coeff, CONVERT_TO_BYTEPTR(ref16), pitch_);
|
ref_txfm(coeff, CONVERT_TO_BYTEPTR(ref16), pitch_);
|
||||||
ASM_REGISTER_STATE_CHECK(RunInvTxfm(coeff, CONVERT_TO_BYTEPTR(dst16),
|
ASM_REGISTER_STATE_CHECK(
|
||||||
pitch_));
|
RunInvTxfm(coeff, CONVERT_TO_BYTEPTR(dst16), pitch_));
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
for (int j = 0; j < kNumCoeffs; ++j) {
|
for (int j = 0; j < kNumCoeffs; ++j) {
|
||||||
#if CONFIG_VP9_HIGHBITDEPTH
|
#if CONFIG_VP9_HIGHBITDEPTH
|
||||||
const uint32_t diff =
|
const int diff =
|
||||||
bit_depth_ == VPX_BITS_8 ? dst[j] - ref[j] : dst16[j] - ref16[j];
|
bit_depth_ == VPX_BITS_8 ? dst[j] - ref[j] : dst16[j] - ref16[j];
|
||||||
#else
|
#else
|
||||||
const uint32_t diff = dst[j] - ref[j];
|
const int diff = dst[j] - ref[j];
|
||||||
#endif
|
#endif
|
||||||
const uint32_t error = diff * diff;
|
const uint32_t error = diff * diff;
|
||||||
EXPECT_EQ(0u, error)
|
EXPECT_EQ(0u, error) << "Error: 8x8 IDCT has error " << error
|
||||||
<< "Error: 8x8 IDCT has error " << error
|
|
||||||
<< " at index " << j;
|
<< " at index " << j;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -530,8 +523,7 @@ void CompareInvReference(IdctFunc ref_txfm, int thresh) {
|
|||||||
int mask_;
|
int mask_;
|
||||||
};
|
};
|
||||||
|
|
||||||
class FwdTrans8x8DCT
|
class FwdTrans8x8DCT : public FwdTrans8x8TestBase,
|
||||||
: public FwdTrans8x8TestBase,
|
|
||||||
public ::testing::TestWithParam<Dct8x8Param> {
|
public ::testing::TestWithParam<Dct8x8Param> {
|
||||||
public:
|
public:
|
||||||
virtual ~FwdTrans8x8DCT() {}
|
virtual ~FwdTrans8x8DCT() {}
|
||||||
@@ -560,28 +552,17 @@ class FwdTrans8x8DCT
|
|||||||
IdctFunc inv_txfm_;
|
IdctFunc inv_txfm_;
|
||||||
};
|
};
|
||||||
|
|
||||||
TEST_P(FwdTrans8x8DCT, SignBiasCheck) {
|
TEST_P(FwdTrans8x8DCT, SignBiasCheck) { RunSignBiasCheck(); }
|
||||||
RunSignBiasCheck();
|
|
||||||
}
|
|
||||||
|
|
||||||
TEST_P(FwdTrans8x8DCT, RoundTripErrorCheck) {
|
TEST_P(FwdTrans8x8DCT, RoundTripErrorCheck) { RunRoundTripErrorCheck(); }
|
||||||
RunRoundTripErrorCheck();
|
|
||||||
}
|
|
||||||
|
|
||||||
TEST_P(FwdTrans8x8DCT, ExtremalCheck) {
|
TEST_P(FwdTrans8x8DCT, ExtremalCheck) { RunExtremalCheck(); }
|
||||||
RunExtremalCheck();
|
|
||||||
}
|
|
||||||
|
|
||||||
TEST_P(FwdTrans8x8DCT, FwdAccuracyCheck) {
|
TEST_P(FwdTrans8x8DCT, FwdAccuracyCheck) { RunFwdAccuracyCheck(); }
|
||||||
RunFwdAccuracyCheck();
|
|
||||||
}
|
|
||||||
|
|
||||||
TEST_P(FwdTrans8x8DCT, InvAccuracyCheck) {
|
TEST_P(FwdTrans8x8DCT, InvAccuracyCheck) { RunInvAccuracyCheck(); }
|
||||||
RunInvAccuracyCheck();
|
|
||||||
}
|
|
||||||
|
|
||||||
class FwdTrans8x8HT
|
class FwdTrans8x8HT : public FwdTrans8x8TestBase,
|
||||||
: public FwdTrans8x8TestBase,
|
|
||||||
public ::testing::TestWithParam<Ht8x8Param> {
|
public ::testing::TestWithParam<Ht8x8Param> {
|
||||||
public:
|
public:
|
||||||
virtual ~FwdTrans8x8HT() {}
|
virtual ~FwdTrans8x8HT() {}
|
||||||
@@ -610,20 +591,13 @@ class FwdTrans8x8HT
|
|||||||
IhtFunc inv_txfm_;
|
IhtFunc inv_txfm_;
|
||||||
};
|
};
|
||||||
|
|
||||||
TEST_P(FwdTrans8x8HT, SignBiasCheck) {
|
TEST_P(FwdTrans8x8HT, SignBiasCheck) { RunSignBiasCheck(); }
|
||||||
RunSignBiasCheck();
|
|
||||||
}
|
|
||||||
|
|
||||||
TEST_P(FwdTrans8x8HT, RoundTripErrorCheck) {
|
TEST_P(FwdTrans8x8HT, RoundTripErrorCheck) { RunRoundTripErrorCheck(); }
|
||||||
RunRoundTripErrorCheck();
|
|
||||||
}
|
|
||||||
|
|
||||||
TEST_P(FwdTrans8x8HT, ExtremalCheck) {
|
TEST_P(FwdTrans8x8HT, ExtremalCheck) { RunExtremalCheck(); }
|
||||||
RunExtremalCheck();
|
|
||||||
}
|
|
||||||
|
|
||||||
class InvTrans8x8DCT
|
class InvTrans8x8DCT : public FwdTrans8x8TestBase,
|
||||||
: public FwdTrans8x8TestBase,
|
|
||||||
public ::testing::TestWithParam<Idct8x8Param> {
|
public ::testing::TestWithParam<Idct8x8Param> {
|
||||||
public:
|
public:
|
||||||
virtual ~InvTrans8x8DCT() {}
|
virtual ~InvTrans8x8DCT() {}
|
||||||
@@ -664,10 +638,10 @@ INSTANTIATE_TEST_CASE_P(
|
|||||||
make_tuple(&vpx_highbd_fdct8x8_c, &idct8x8_10, 0, VPX_BITS_10),
|
make_tuple(&vpx_highbd_fdct8x8_c, &idct8x8_10, 0, VPX_BITS_10),
|
||||||
make_tuple(&vpx_highbd_fdct8x8_c, &idct8x8_12, 0, VPX_BITS_12)));
|
make_tuple(&vpx_highbd_fdct8x8_c, &idct8x8_12, 0, VPX_BITS_12)));
|
||||||
#else
|
#else
|
||||||
INSTANTIATE_TEST_CASE_P(
|
INSTANTIATE_TEST_CASE_P(C, FwdTrans8x8DCT,
|
||||||
C, FwdTrans8x8DCT,
|
::testing::Values(make_tuple(&vpx_fdct8x8_c,
|
||||||
::testing::Values(
|
&vpx_idct8x8_64_add_c, 0,
|
||||||
make_tuple(&vpx_fdct8x8_c, &vpx_idct8x8_64_add_c, 0, VPX_BITS_8)));
|
VPX_BITS_8)));
|
||||||
#endif // CONFIG_VP9_HIGHBITDEPTH
|
#endif // CONFIG_VP9_HIGHBITDEPTH
|
||||||
|
|
||||||
#if CONFIG_VP9_HIGHBITDEPTH
|
#if CONFIG_VP9_HIGHBITDEPTH
|
||||||
@@ -696,15 +670,17 @@ INSTANTIATE_TEST_CASE_P(
|
|||||||
make_tuple(&vp9_fht8x8_c, &vp9_iht8x8_64_add_c, 3, VPX_BITS_8)));
|
make_tuple(&vp9_fht8x8_c, &vp9_iht8x8_64_add_c, 3, VPX_BITS_8)));
|
||||||
#endif // CONFIG_VP9_HIGHBITDEPTH
|
#endif // CONFIG_VP9_HIGHBITDEPTH
|
||||||
|
|
||||||
#if HAVE_NEON_ASM && !CONFIG_VP9_HIGHBITDEPTH && !CONFIG_EMULATE_HARDWARE
|
#if HAVE_NEON && !CONFIG_EMULATE_HARDWARE
|
||||||
INSTANTIATE_TEST_CASE_P(
|
#if CONFIG_VP9_HIGHBITDEPTH
|
||||||
NEON, FwdTrans8x8DCT,
|
INSTANTIATE_TEST_CASE_P(NEON, FwdTrans8x8DCT,
|
||||||
::testing::Values(
|
::testing::Values(make_tuple(&vpx_fdct8x8_c,
|
||||||
make_tuple(&vpx_fdct8x8_neon, &vpx_idct8x8_64_add_neon, 0,
|
&vpx_idct8x8_64_add_neon,
|
||||||
VPX_BITS_8)));
|
0, VPX_BITS_8)));
|
||||||
#endif // HAVE_NEON_ASM && !CONFIG_VP9_HIGHBITDEPTH && !CONFIG_EMULATE_HARDWARE
|
#else // !CONFIG_VP9_HIGHBITDEPTH
|
||||||
|
INSTANTIATE_TEST_CASE_P(NEON, FwdTrans8x8DCT,
|
||||||
#if HAVE_NEON && !CONFIG_VP9_HIGHBITDEPTH && !CONFIG_EMULATE_HARDWARE
|
::testing::Values(make_tuple(&vpx_fdct8x8_neon,
|
||||||
|
&vpx_idct8x8_64_add_neon,
|
||||||
|
0, VPX_BITS_8)));
|
||||||
INSTANTIATE_TEST_CASE_P(
|
INSTANTIATE_TEST_CASE_P(
|
||||||
NEON, FwdTrans8x8HT,
|
NEON, FwdTrans8x8HT,
|
||||||
::testing::Values(
|
::testing::Values(
|
||||||
@@ -712,14 +688,14 @@ 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, 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, 2, VPX_BITS_8),
|
||||||
make_tuple(&vp9_fht8x8_c, &vp9_iht8x8_64_add_neon, 3, VPX_BITS_8)));
|
make_tuple(&vp9_fht8x8_c, &vp9_iht8x8_64_add_neon, 3, VPX_BITS_8)));
|
||||||
|
#endif // CONFIG_VP9_HIGHBITDEPTH
|
||||||
#endif // HAVE_NEON && !CONFIG_VP9_HIGHBITDEPTH && !CONFIG_EMULATE_HARDWARE
|
#endif // HAVE_NEON && !CONFIG_VP9_HIGHBITDEPTH && !CONFIG_EMULATE_HARDWARE
|
||||||
|
|
||||||
#if HAVE_SSE2 && !CONFIG_VP9_HIGHBITDEPTH && !CONFIG_EMULATE_HARDWARE
|
#if HAVE_SSE2 && !CONFIG_VP9_HIGHBITDEPTH && !CONFIG_EMULATE_HARDWARE
|
||||||
INSTANTIATE_TEST_CASE_P(
|
INSTANTIATE_TEST_CASE_P(SSE2, FwdTrans8x8DCT,
|
||||||
SSE2, FwdTrans8x8DCT,
|
::testing::Values(make_tuple(&vpx_fdct8x8_sse2,
|
||||||
::testing::Values(
|
&vpx_idct8x8_64_add_sse2,
|
||||||
make_tuple(&vpx_fdct8x8_sse2, &vpx_idct8x8_64_add_sse2, 0,
|
0, VPX_BITS_8)));
|
||||||
VPX_BITS_8)));
|
|
||||||
INSTANTIATE_TEST_CASE_P(
|
INSTANTIATE_TEST_CASE_P(
|
||||||
SSE2, FwdTrans8x8HT,
|
SSE2, FwdTrans8x8HT,
|
||||||
::testing::Values(
|
::testing::Values(
|
||||||
@@ -732,14 +708,14 @@ INSTANTIATE_TEST_CASE_P(
|
|||||||
#if HAVE_SSE2 && CONFIG_VP9_HIGHBITDEPTH && !CONFIG_EMULATE_HARDWARE
|
#if HAVE_SSE2 && CONFIG_VP9_HIGHBITDEPTH && !CONFIG_EMULATE_HARDWARE
|
||||||
INSTANTIATE_TEST_CASE_P(
|
INSTANTIATE_TEST_CASE_P(
|
||||||
SSE2, FwdTrans8x8DCT,
|
SSE2, FwdTrans8x8DCT,
|
||||||
::testing::Values(
|
::testing::Values(make_tuple(&vpx_fdct8x8_sse2, &vpx_idct8x8_64_add_c, 0,
|
||||||
make_tuple(&vpx_fdct8x8_sse2, &vpx_idct8x8_64_add_c, 0, VPX_BITS_8),
|
VPX_BITS_8),
|
||||||
make_tuple(&vpx_highbd_fdct8x8_c,
|
make_tuple(&vpx_highbd_fdct8x8_c, &idct8x8_64_add_10_sse2,
|
||||||
&idct8x8_64_add_10_sse2, 12, VPX_BITS_10),
|
12, VPX_BITS_10),
|
||||||
make_tuple(&vpx_highbd_fdct8x8_sse2,
|
make_tuple(&vpx_highbd_fdct8x8_sse2,
|
||||||
&idct8x8_64_add_10_sse2, 12, VPX_BITS_10),
|
&idct8x8_64_add_10_sse2, 12, VPX_BITS_10),
|
||||||
make_tuple(&vpx_highbd_fdct8x8_c,
|
make_tuple(&vpx_highbd_fdct8x8_c, &idct8x8_64_add_12_sse2,
|
||||||
&idct8x8_64_add_12_sse2, 12, VPX_BITS_12),
|
12, VPX_BITS_12),
|
||||||
make_tuple(&vpx_highbd_fdct8x8_sse2,
|
make_tuple(&vpx_highbd_fdct8x8_sse2,
|
||||||
&idct8x8_64_add_12_sse2, 12, VPX_BITS_12)));
|
&idct8x8_64_add_12_sse2, 12, VPX_BITS_12)));
|
||||||
|
|
||||||
@@ -756,30 +732,27 @@ INSTANTIATE_TEST_CASE_P(
|
|||||||
INSTANTIATE_TEST_CASE_P(
|
INSTANTIATE_TEST_CASE_P(
|
||||||
SSE2, InvTrans8x8DCT,
|
SSE2, InvTrans8x8DCT,
|
||||||
::testing::Values(
|
::testing::Values(
|
||||||
make_tuple(&idct8x8_10_add_10_c,
|
make_tuple(&idct8x8_12_add_10_c, &idct8x8_12_add_10_sse2, 6225,
|
||||||
&idct8x8_10_add_10_sse2, 6225, VPX_BITS_10),
|
VPX_BITS_10),
|
||||||
make_tuple(&idct8x8_10,
|
make_tuple(&idct8x8_10, &idct8x8_64_add_10_sse2, 6225, VPX_BITS_10),
|
||||||
&idct8x8_64_add_10_sse2, 6225, VPX_BITS_10),
|
make_tuple(&idct8x8_12_add_12_c, &idct8x8_12_add_12_sse2, 6225,
|
||||||
make_tuple(&idct8x8_10_add_12_c,
|
VPX_BITS_12),
|
||||||
&idct8x8_10_add_12_sse2, 6225, VPX_BITS_12),
|
make_tuple(&idct8x8_12, &idct8x8_64_add_12_sse2, 6225, VPX_BITS_12)));
|
||||||
make_tuple(&idct8x8_12,
|
|
||||||
&idct8x8_64_add_12_sse2, 6225, VPX_BITS_12)));
|
|
||||||
#endif // HAVE_SSE2 && CONFIG_VP9_HIGHBITDEPTH && !CONFIG_EMULATE_HARDWARE
|
#endif // HAVE_SSE2 && CONFIG_VP9_HIGHBITDEPTH && !CONFIG_EMULATE_HARDWARE
|
||||||
|
|
||||||
#if HAVE_SSSE3 && CONFIG_USE_X86INC && ARCH_X86_64 && \
|
#if HAVE_SSSE3 && ARCH_X86_64 && !CONFIG_VP9_HIGHBITDEPTH && \
|
||||||
!CONFIG_VP9_HIGHBITDEPTH && !CONFIG_EMULATE_HARDWARE
|
!CONFIG_EMULATE_HARDWARE
|
||||||
INSTANTIATE_TEST_CASE_P(
|
INSTANTIATE_TEST_CASE_P(SSSE3, FwdTrans8x8DCT,
|
||||||
SSSE3, FwdTrans8x8DCT,
|
::testing::Values(make_tuple(&vpx_fdct8x8_ssse3,
|
||||||
::testing::Values(
|
&vpx_idct8x8_64_add_ssse3,
|
||||||
make_tuple(&vpx_fdct8x8_ssse3, &vpx_idct8x8_64_add_ssse3, 0,
|
0, VPX_BITS_8)));
|
||||||
VPX_BITS_8)));
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if HAVE_MSA && !CONFIG_VP9_HIGHBITDEPTH && !CONFIG_EMULATE_HARDWARE
|
#if HAVE_MSA && !CONFIG_VP9_HIGHBITDEPTH && !CONFIG_EMULATE_HARDWARE
|
||||||
INSTANTIATE_TEST_CASE_P(
|
INSTANTIATE_TEST_CASE_P(MSA, FwdTrans8x8DCT,
|
||||||
MSA, FwdTrans8x8DCT,
|
::testing::Values(make_tuple(&vpx_fdct8x8_msa,
|
||||||
::testing::Values(
|
&vpx_idct8x8_64_add_msa, 0,
|
||||||
make_tuple(&vpx_fdct8x8_msa, &vpx_idct8x8_64_add_msa, 0, VPX_BITS_8)));
|
VPX_BITS_8)));
|
||||||
INSTANTIATE_TEST_CASE_P(
|
INSTANTIATE_TEST_CASE_P(
|
||||||
MSA, FwdTrans8x8HT,
|
MSA, FwdTrans8x8HT,
|
||||||
::testing::Values(
|
::testing::Values(
|
||||||
|
|||||||
@@ -13,12 +13,11 @@
|
|||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
|
|
||||||
class VP9FrameSizeTestsLarge
|
class VP9FrameSizeTestsLarge : public ::libvpx_test::EncoderTest,
|
||||||
: public ::libvpx_test::EncoderTest,
|
|
||||||
public ::testing::Test {
|
public ::testing::Test {
|
||||||
protected:
|
protected:
|
||||||
VP9FrameSizeTestsLarge() : EncoderTest(&::libvpx_test::kVP9),
|
VP9FrameSizeTestsLarge()
|
||||||
expected_res_(VPX_CODEC_OK) {}
|
: EncoderTest(&::libvpx_test::kVP9), expected_res_(VPX_CODEC_OK) {}
|
||||||
virtual ~VP9FrameSizeTestsLarge() {}
|
virtual ~VP9FrameSizeTestsLarge() {}
|
||||||
|
|
||||||
virtual void SetUp() {
|
virtual void SetUp() {
|
||||||
|
|||||||
@@ -21,20 +21,7 @@ namespace {
|
|||||||
|
|
||||||
using ::libvpx_test::ACMRandom;
|
using ::libvpx_test::ACMRandom;
|
||||||
|
|
||||||
typedef void (*Hadamard8x8Func)(const int16_t *a, int a_stride,
|
typedef void (*HadamardFunc)(const int16_t *a, int a_stride, int16_t *b);
|
||||||
int16_t *b);
|
|
||||||
|
|
||||||
class HadamardTest : public ::testing::TestWithParam<Hadamard8x8Func> {
|
|
||||||
public:
|
|
||||||
virtual void SetUp() {
|
|
||||||
h_func_ = GetParam();
|
|
||||||
rnd_.Reset(ACMRandom::DeterministicSeed());
|
|
||||||
}
|
|
||||||
|
|
||||||
protected:
|
|
||||||
Hadamard8x8Func h_func_;
|
|
||||||
ACMRandom rnd_;
|
|
||||||
};
|
|
||||||
|
|
||||||
void hadamard_loop(const int16_t *a, int a_stride, int16_t *out) {
|
void hadamard_loop(const int16_t *a, int a_stride, int16_t *out) {
|
||||||
int16_t b[8];
|
int16_t b[8];
|
||||||
@@ -59,28 +46,74 @@ void hadamard_loop(const int16_t *a, int a_stride, int16_t *out) {
|
|||||||
out[5] = c[3] - c[7];
|
out[5] = c[3] - c[7];
|
||||||
}
|
}
|
||||||
|
|
||||||
void reference_hadamard(const int16_t *a, int a_stride, int16_t *b) {
|
void reference_hadamard8x8(const int16_t *a, int a_stride, int16_t *b) {
|
||||||
int16_t buf[64];
|
int16_t buf[64];
|
||||||
for (int i = 0; i < 8; i++) {
|
for (int i = 0; i < 8; ++i) {
|
||||||
hadamard_loop(a + i, a_stride, buf + i * 8);
|
hadamard_loop(a + i, a_stride, buf + i * 8);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (int i = 0; i < 8; i++) {
|
for (int i = 0; i < 8; ++i) {
|
||||||
hadamard_loop(buf + i, 8, b + i * 8);
|
hadamard_loop(buf + i, 8, b + i * 8);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_P(HadamardTest, CompareReferenceRandom) {
|
void reference_hadamard16x16(const int16_t *a, int a_stride, int16_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);
|
||||||
|
reference_hadamard8x8(a + 8 + 0 * a_stride, a_stride, b + 64);
|
||||||
|
reference_hadamard8x8(a + 0 + 8 * a_stride, a_stride, b + 128);
|
||||||
|
reference_hadamard8x8(a + 8 + 8 * a_stride, a_stride, b + 192);
|
||||||
|
|
||||||
|
/* 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];
|
||||||
|
|
||||||
|
/* 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;
|
||||||
|
|
||||||
|
/* Store a 16 bit value. */
|
||||||
|
b[0] = b0 + b2;
|
||||||
|
b[64] = b1 + b3;
|
||||||
|
b[128] = b0 - b2;
|
||||||
|
b[192] = b1 - b3;
|
||||||
|
|
||||||
|
++b;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class HadamardTestBase : public ::testing::TestWithParam<HadamardFunc> {
|
||||||
|
public:
|
||||||
|
virtual void SetUp() {
|
||||||
|
h_func_ = GetParam();
|
||||||
|
rnd_.Reset(ACMRandom::DeterministicSeed());
|
||||||
|
}
|
||||||
|
|
||||||
|
protected:
|
||||||
|
HadamardFunc h_func_;
|
||||||
|
ACMRandom rnd_;
|
||||||
|
};
|
||||||
|
|
||||||
|
class Hadamard8x8Test : public HadamardTestBase {};
|
||||||
|
|
||||||
|
TEST_P(Hadamard8x8Test, CompareReferenceRandom) {
|
||||||
DECLARE_ALIGNED(16, int16_t, a[64]);
|
DECLARE_ALIGNED(16, int16_t, a[64]);
|
||||||
DECLARE_ALIGNED(16, int16_t, b[64]);
|
DECLARE_ALIGNED(16, int16_t, b[64]);
|
||||||
int16_t b_ref[64];
|
int16_t b_ref[64];
|
||||||
for (int i = 0; i < 64; i++) {
|
for (int i = 0; i < 64; ++i) {
|
||||||
a[i] = rnd_.Rand9Signed();
|
a[i] = rnd_.Rand9Signed();
|
||||||
}
|
}
|
||||||
memset(b, 0, sizeof(b));
|
memset(b, 0, sizeof(b));
|
||||||
memset(b_ref, 0, sizeof(b_ref));
|
memset(b_ref, 0, sizeof(b_ref));
|
||||||
|
|
||||||
reference_hadamard(a, 8, b_ref);
|
reference_hadamard8x8(a, 8, b_ref);
|
||||||
ASM_REGISTER_STATE_CHECK(h_func_(a, 8, b));
|
ASM_REGISTER_STATE_CHECK(h_func_(a, 8, b));
|
||||||
|
|
||||||
// The order of the output is not important. Sort before checking.
|
// The order of the output is not important. Sort before checking.
|
||||||
@@ -89,11 +122,11 @@ TEST_P(HadamardTest, CompareReferenceRandom) {
|
|||||||
EXPECT_EQ(0, memcmp(b, b_ref, sizeof(b)));
|
EXPECT_EQ(0, memcmp(b, b_ref, sizeof(b)));
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_P(HadamardTest, VaryStride) {
|
TEST_P(Hadamard8x8Test, VaryStride) {
|
||||||
DECLARE_ALIGNED(16, int16_t, a[64 * 8]);
|
DECLARE_ALIGNED(16, int16_t, a[64 * 8]);
|
||||||
DECLARE_ALIGNED(16, int16_t, b[64]);
|
DECLARE_ALIGNED(16, int16_t, b[64]);
|
||||||
int16_t b_ref[64];
|
int16_t b_ref[64];
|
||||||
for (int i = 0; i < 64 * 8; i++) {
|
for (int i = 0; i < 64 * 8; ++i) {
|
||||||
a[i] = rnd_.Rand9Signed();
|
a[i] = rnd_.Rand9Signed();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -101,7 +134,7 @@ TEST_P(HadamardTest, VaryStride) {
|
|||||||
memset(b, 0, sizeof(b));
|
memset(b, 0, sizeof(b));
|
||||||
memset(b_ref, 0, sizeof(b_ref));
|
memset(b_ref, 0, sizeof(b_ref));
|
||||||
|
|
||||||
reference_hadamard(a, i, b_ref);
|
reference_hadamard8x8(a, i, b_ref);
|
||||||
ASM_REGISTER_STATE_CHECK(h_func_(a, i, b));
|
ASM_REGISTER_STATE_CHECK(h_func_(a, i, b));
|
||||||
|
|
||||||
// The order of the output is not important. Sort before checking.
|
// The order of the output is not important. Sort before checking.
|
||||||
@@ -111,16 +144,77 @@ TEST_P(HadamardTest, VaryStride) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
INSTANTIATE_TEST_CASE_P(C, HadamardTest,
|
INSTANTIATE_TEST_CASE_P(C, Hadamard8x8Test,
|
||||||
::testing::Values(&vpx_hadamard_8x8_c));
|
::testing::Values(&vpx_hadamard_8x8_c));
|
||||||
|
|
||||||
#if HAVE_SSE2
|
#if HAVE_SSE2
|
||||||
INSTANTIATE_TEST_CASE_P(SSE2, HadamardTest,
|
INSTANTIATE_TEST_CASE_P(SSE2, Hadamard8x8Test,
|
||||||
::testing::Values(&vpx_hadamard_8x8_sse2));
|
::testing::Values(&vpx_hadamard_8x8_sse2));
|
||||||
#endif // HAVE_SSE2
|
#endif // HAVE_SSE2
|
||||||
|
|
||||||
#if HAVE_SSSE3 && CONFIG_USE_X86INC && ARCH_X86_64
|
#if HAVE_SSSE3 && ARCH_X86_64
|
||||||
INSTANTIATE_TEST_CASE_P(SSSE3, HadamardTest,
|
INSTANTIATE_TEST_CASE_P(SSSE3, Hadamard8x8Test,
|
||||||
::testing::Values(&vpx_hadamard_8x8_ssse3));
|
::testing::Values(&vpx_hadamard_8x8_ssse3));
|
||||||
#endif // HAVE_SSSE3 && CONFIG_USE_X86INC && ARCH_X86_64
|
#endif // HAVE_SSSE3 && ARCH_X86_64
|
||||||
|
|
||||||
|
#if HAVE_NEON
|
||||||
|
INSTANTIATE_TEST_CASE_P(NEON, Hadamard8x8Test,
|
||||||
|
::testing::Values(&vpx_hadamard_8x8_neon));
|
||||||
|
#endif // HAVE_NEON
|
||||||
|
|
||||||
|
class Hadamard16x16Test : public HadamardTestBase {};
|
||||||
|
|
||||||
|
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];
|
||||||
|
for (int i = 0; i < 16 * 16; ++i) {
|
||||||
|
a[i] = rnd_.Rand9Signed();
|
||||||
|
}
|
||||||
|
memset(b, 0, sizeof(b));
|
||||||
|
memset(b_ref, 0, sizeof(b_ref));
|
||||||
|
|
||||||
|
reference_hadamard16x16(a, 16, b_ref);
|
||||||
|
ASM_REGISTER_STATE_CHECK(h_func_(a, 16, b));
|
||||||
|
|
||||||
|
// The order of the output is not important. Sort before checking.
|
||||||
|
std::sort(b, b + 16 * 16);
|
||||||
|
std::sort(b_ref, b_ref + 16 * 16);
|
||||||
|
EXPECT_EQ(0, memcmp(b, b_ref, sizeof(b)));
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_P(Hadamard16x16Test, VaryStride) {
|
||||||
|
DECLARE_ALIGNED(16, int16_t, a[16 * 16 * 8]);
|
||||||
|
DECLARE_ALIGNED(16, int16_t, b[16 * 16]);
|
||||||
|
int16_t b_ref[16 * 16];
|
||||||
|
for (int i = 0; i < 16 * 16 * 8; ++i) {
|
||||||
|
a[i] = rnd_.Rand9Signed();
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int i = 8; i < 64; i += 8) {
|
||||||
|
memset(b, 0, sizeof(b));
|
||||||
|
memset(b_ref, 0, sizeof(b_ref));
|
||||||
|
|
||||||
|
reference_hadamard16x16(a, i, b_ref);
|
||||||
|
ASM_REGISTER_STATE_CHECK(h_func_(a, i, b));
|
||||||
|
|
||||||
|
// The order of the output is not important. Sort before checking.
|
||||||
|
std::sort(b, b + 16 * 16);
|
||||||
|
std::sort(b_ref, b_ref + 16 * 16);
|
||||||
|
EXPECT_EQ(0, memcmp(b, b_ref, sizeof(b)));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
INSTANTIATE_TEST_CASE_P(C, Hadamard16x16Test,
|
||||||
|
::testing::Values(&vpx_hadamard_16x16_c));
|
||||||
|
|
||||||
|
#if HAVE_SSE2
|
||||||
|
INSTANTIATE_TEST_CASE_P(SSE2, Hadamard16x16Test,
|
||||||
|
::testing::Values(&vpx_hadamard_16x16_sse2));
|
||||||
|
#endif // HAVE_SSE2
|
||||||
|
|
||||||
|
#if HAVE_NEON
|
||||||
|
INSTANTIATE_TEST_CASE_P(NEON, Hadamard16x16Test,
|
||||||
|
::testing::Values(&vpx_hadamard_16x16_neon));
|
||||||
|
#endif // HAVE_NEON
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|||||||
@@ -21,14 +21,11 @@ namespace libvpx_test {
|
|||||||
// so that we can do actual file encodes.
|
// so that we can do actual file encodes.
|
||||||
class I420VideoSource : public YUVVideoSource {
|
class I420VideoSource : public YUVVideoSource {
|
||||||
public:
|
public:
|
||||||
I420VideoSource(const std::string &file_name,
|
I420VideoSource(const std::string &file_name, unsigned int width,
|
||||||
unsigned int width, unsigned int height,
|
unsigned int height, int rate_numerator, int rate_denominator,
|
||||||
int rate_numerator, int rate_denominator,
|
|
||||||
unsigned int start, int limit)
|
unsigned int start, int limit)
|
||||||
: YUVVideoSource(file_name, VPX_IMG_FMT_I420,
|
: YUVVideoSource(file_name, VPX_IMG_FMT_I420, width, height,
|
||||||
width, height,
|
rate_numerator, rate_denominator, start, limit) {}
|
||||||
rate_numerator, rate_denominator,
|
|
||||||
start, limit) {}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace libvpx_test
|
} // namespace libvpx_test
|
||||||
|
|||||||
@@ -17,29 +17,21 @@
|
|||||||
#include "./vpx_dsp_rtcd.h"
|
#include "./vpx_dsp_rtcd.h"
|
||||||
#include "test/acm_random.h"
|
#include "test/acm_random.h"
|
||||||
#include "vpx/vpx_integer.h"
|
#include "vpx/vpx_integer.h"
|
||||||
|
#include "vpx_ports/msvc.h" // for round()
|
||||||
|
|
||||||
using libvpx_test::ACMRandom;
|
using libvpx_test::ACMRandom;
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
|
|
||||||
#ifdef _MSC_VER
|
|
||||||
static int round(double x) {
|
|
||||||
if (x < 0)
|
|
||||||
return static_cast<int>(ceil(x - 0.5));
|
|
||||||
else
|
|
||||||
return static_cast<int>(floor(x + 0.5));
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
void reference_dct_1d(double input[8], double output[8]) {
|
void reference_dct_1d(double input[8], double output[8]) {
|
||||||
const double kPi = 3.141592653589793238462643383279502884;
|
const double kPi = 3.141592653589793238462643383279502884;
|
||||||
const double kInvSqrt2 = 0.707106781186547524400844362104;
|
const double kInvSqrt2 = 0.707106781186547524400844362104;
|
||||||
for (int k = 0; k < 8; k++) {
|
for (int k = 0; k < 8; k++) {
|
||||||
output[k] = 0.0;
|
output[k] = 0.0;
|
||||||
for (int n = 0; n < 8; n++)
|
for (int n = 0; n < 8; n++) {
|
||||||
output[k] += input[n] * cos(kPi * (2 * n + 1) * k / 16.0);
|
output[k] += input[n] * cos(kPi * (2 * n + 1) * k / 16.0);
|
||||||
if (k == 0)
|
}
|
||||||
output[k] = output[k]*kInvSqrt2;
|
if (k == 0) output[k] = output[k] * kInvSqrt2;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -47,24 +39,19 @@ void reference_dct_2d(int16_t input[64], double output[64]) {
|
|||||||
// First transform columns
|
// First transform columns
|
||||||
for (int i = 0; i < 8; ++i) {
|
for (int i = 0; i < 8; ++i) {
|
||||||
double temp_in[8], temp_out[8];
|
double temp_in[8], temp_out[8];
|
||||||
for (int j = 0; j < 8; ++j)
|
for (int j = 0; j < 8; ++j) temp_in[j] = input[j * 8 + i];
|
||||||
temp_in[j] = input[j*8 + i];
|
|
||||||
reference_dct_1d(temp_in, temp_out);
|
reference_dct_1d(temp_in, temp_out);
|
||||||
for (int j = 0; j < 8; ++j)
|
for (int j = 0; j < 8; ++j) output[j * 8 + i] = temp_out[j];
|
||||||
output[j*8 + i] = temp_out[j];
|
|
||||||
}
|
}
|
||||||
// Then transform rows
|
// Then transform rows
|
||||||
for (int i = 0; i < 8; ++i) {
|
for (int i = 0; i < 8; ++i) {
|
||||||
double temp_in[8], temp_out[8];
|
double temp_in[8], temp_out[8];
|
||||||
for (int j = 0; j < 8; ++j)
|
for (int j = 0; j < 8; ++j) temp_in[j] = output[j + i * 8];
|
||||||
temp_in[j] = output[j + i*8];
|
|
||||||
reference_dct_1d(temp_in, temp_out);
|
reference_dct_1d(temp_in, temp_out);
|
||||||
for (int j = 0; j < 8; ++j)
|
for (int j = 0; j < 8; ++j) output[j + i * 8] = temp_out[j];
|
||||||
output[j + i*8] = temp_out[j];
|
|
||||||
}
|
}
|
||||||
// Scale by some magic number
|
// Scale by some magic number
|
||||||
for (int i = 0; i < 64; ++i)
|
for (int i = 0; i < 64; ++i) output[i] *= 2;
|
||||||
output[i] *= 2;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(VP9Idct8x8Test, AccuracyCheck) {
|
TEST(VP9Idct8x8Test, AccuracyCheck) {
|
||||||
@@ -81,18 +68,17 @@ TEST(VP9Idct8x8Test, AccuracyCheck) {
|
|||||||
dst[j] = rnd.Rand8();
|
dst[j] = rnd.Rand8();
|
||||||
}
|
}
|
||||||
// Initialize a test block with input range [-255, 255].
|
// Initialize a test block with input range [-255, 255].
|
||||||
for (int j = 0; j < 64; ++j)
|
for (int j = 0; j < 64; ++j) input[j] = src[j] - dst[j];
|
||||||
input[j] = src[j] - dst[j];
|
|
||||||
|
|
||||||
reference_dct_2d(input, output_r);
|
reference_dct_2d(input, output_r);
|
||||||
for (int j = 0; j < 64; ++j)
|
for (int j = 0; j < 64; ++j) {
|
||||||
coeff[j] = round(output_r[j]);
|
coeff[j] = static_cast<tran_low_t>(round(output_r[j]));
|
||||||
|
}
|
||||||
vpx_idct8x8_64_add_c(coeff, dst, 8);
|
vpx_idct8x8_64_add_c(coeff, dst, 8);
|
||||||
for (int j = 0; j < 64; ++j) {
|
for (int j = 0; j < 64; ++j) {
|
||||||
const int diff = dst[j] - src[j];
|
const int diff = dst[j] - src[j];
|
||||||
const int error = diff * diff;
|
const int error = diff * diff;
|
||||||
EXPECT_GE(1, error)
|
EXPECT_GE(1, error) << "Error: 8x8 FDCT/IDCT has error " << error
|
||||||
<< "Error: 8x8 FDCT/IDCT has error " << error
|
|
||||||
<< " at index " << j;
|
<< " at index " << j;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -43,24 +43,26 @@ class IDCTTest : public ::testing::TestWithParam<IdctFunc> {
|
|||||||
TEST_P(IDCTTest, TestGuardBlocks) {
|
TEST_P(IDCTTest, TestGuardBlocks) {
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
for (i = 0; i < 256; i++)
|
for (i = 0; i < 256; i++) {
|
||||||
if ((i & 0xF) < 4 && i < 64)
|
if ((i & 0xF) < 4 && i < 64)
|
||||||
EXPECT_EQ(0, output[i]) << i;
|
EXPECT_EQ(0, output[i]) << i;
|
||||||
else
|
else
|
||||||
EXPECT_EQ(255, output[i]);
|
EXPECT_EQ(255, output[i]);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
TEST_P(IDCTTest, TestAllZeros) {
|
TEST_P(IDCTTest, TestAllZeros) {
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
ASM_REGISTER_STATE_CHECK(UUT(input, output, 16, output, 16));
|
ASM_REGISTER_STATE_CHECK(UUT(input, output, 16, output, 16));
|
||||||
|
|
||||||
for (i = 0; i < 256; i++)
|
for (i = 0; i < 256; i++) {
|
||||||
if ((i & 0xF) < 4 && i < 64)
|
if ((i & 0xF) < 4 && i < 64)
|
||||||
EXPECT_EQ(0, output[i]) << "i==" << i;
|
EXPECT_EQ(0, output[i]) << "i==" << i;
|
||||||
else
|
else
|
||||||
EXPECT_EQ(255, output[i]) << "i==" << i;
|
EXPECT_EQ(255, output[i]) << "i==" << i;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
TEST_P(IDCTTest, TestAllOnes) {
|
TEST_P(IDCTTest, TestAllOnes) {
|
||||||
int i;
|
int i;
|
||||||
@@ -68,12 +70,13 @@ TEST_P(IDCTTest, TestAllOnes) {
|
|||||||
input[0] = 4;
|
input[0] = 4;
|
||||||
ASM_REGISTER_STATE_CHECK(UUT(input, output, 16, output, 16));
|
ASM_REGISTER_STATE_CHECK(UUT(input, output, 16, output, 16));
|
||||||
|
|
||||||
for (i = 0; i < 256; i++)
|
for (i = 0; i < 256; i++) {
|
||||||
if ((i & 0xF) < 4 && i < 64)
|
if ((i & 0xF) < 4 && i < 64)
|
||||||
EXPECT_EQ(1, output[i]) << "i==" << i;
|
EXPECT_EQ(1, output[i]) << "i==" << i;
|
||||||
else
|
else
|
||||||
EXPECT_EQ(255, output[i]) << "i==" << i;
|
EXPECT_EQ(255, output[i]) << "i==" << i;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
TEST_P(IDCTTest, TestAddOne) {
|
TEST_P(IDCTTest, TestAddOne) {
|
||||||
int i;
|
int i;
|
||||||
@@ -82,12 +85,13 @@ TEST_P(IDCTTest, TestAddOne) {
|
|||||||
input[0] = 4;
|
input[0] = 4;
|
||||||
ASM_REGISTER_STATE_CHECK(UUT(input, predict, 16, output, 16));
|
ASM_REGISTER_STATE_CHECK(UUT(input, predict, 16, output, 16));
|
||||||
|
|
||||||
for (i = 0; i < 256; i++)
|
for (i = 0; i < 256; i++) {
|
||||||
if ((i & 0xF) < 4 && i < 64)
|
if ((i & 0xF) < 4 && i < 64)
|
||||||
EXPECT_EQ(i + 1, output[i]) << "i==" << i;
|
EXPECT_EQ(i + 1, output[i]) << "i==" << i;
|
||||||
else
|
else
|
||||||
EXPECT_EQ(255, output[i]) << "i==" << i;
|
EXPECT_EQ(255, output[i]) << "i==" << i;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
TEST_P(IDCTTest, TestWithData) {
|
TEST_P(IDCTTest, TestWithData) {
|
||||||
int i;
|
int i;
|
||||||
@@ -96,7 +100,7 @@ TEST_P(IDCTTest, TestWithData) {
|
|||||||
|
|
||||||
ASM_REGISTER_STATE_CHECK(UUT(input, output, 16, output, 16));
|
ASM_REGISTER_STATE_CHECK(UUT(input, output, 16, output, 16));
|
||||||
|
|
||||||
for (i = 0; i < 256; i++)
|
for (i = 0; i < 256; i++) {
|
||||||
if ((i & 0xF) > 3 || i > 63)
|
if ((i & 0xF) > 3 || i > 63)
|
||||||
EXPECT_EQ(255, output[i]) << "i==" << i;
|
EXPECT_EQ(255, output[i]) << "i==" << i;
|
||||||
else if (i == 0)
|
else if (i == 0)
|
||||||
@@ -108,8 +112,13 @@ TEST_P(IDCTTest, TestWithData) {
|
|||||||
else
|
else
|
||||||
EXPECT_EQ(0, output[i]) << "i==" << i;
|
EXPECT_EQ(0, output[i]) << "i==" << i;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
INSTANTIATE_TEST_CASE_P(C, IDCTTest, ::testing::Values(vp8_short_idct4x4llm_c));
|
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
|
||||||
#if HAVE_MMX
|
#if HAVE_MMX
|
||||||
INSTANTIATE_TEST_CASE_P(MMX, IDCTTest,
|
INSTANTIATE_TEST_CASE_P(MMX, IDCTTest,
|
||||||
::testing::Values(vp8_short_idct4x4llm_mmx));
|
::testing::Values(vp8_short_idct4x4llm_mmx));
|
||||||
|
|||||||
@@ -34,15 +34,13 @@ std::ostream &operator<<(std::ostream &os, const DecodeParam &dp) {
|
|||||||
return os << "threads: " << dp.threads << " file: " << dp.filename;
|
return os << "threads: " << dp.threads << " file: " << dp.filename;
|
||||||
}
|
}
|
||||||
|
|
||||||
class InvalidFileTest
|
class InvalidFileTest : public ::libvpx_test::DecoderTest,
|
||||||
: public ::libvpx_test::DecoderTest,
|
|
||||||
public ::libvpx_test::CodecTestWithParam<DecodeParam> {
|
public ::libvpx_test::CodecTestWithParam<DecodeParam> {
|
||||||
protected:
|
protected:
|
||||||
InvalidFileTest() : DecoderTest(GET_PARAM(0)), res_file_(NULL) {}
|
InvalidFileTest() : DecoderTest(GET_PARAM(0)), res_file_(NULL) {}
|
||||||
|
|
||||||
virtual ~InvalidFileTest() {
|
virtual ~InvalidFileTest() {
|
||||||
if (res_file_ != NULL)
|
if (res_file_ != NULL) fclose(res_file_);
|
||||||
fclose(res_file_);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void OpenResFile(const std::string &res_file_name_) {
|
void OpenResFile(const std::string &res_file_name_) {
|
||||||
@@ -72,8 +70,9 @@ class InvalidFileTest
|
|||||||
EXPECT_TRUE(res_dec == expected_res_dec ||
|
EXPECT_TRUE(res_dec == expected_res_dec ||
|
||||||
res_dec == VPX_CODEC_CORRUPT_FRAME)
|
res_dec == VPX_CODEC_CORRUPT_FRAME)
|
||||||
<< "Results don't match: frame number = " << video.frame_number()
|
<< "Results don't match: frame number = " << video.frame_number()
|
||||||
<< ". (" << decoder->DecodeError() << "). Expected: "
|
<< ". (" << decoder->DecodeError()
|
||||||
<< expected_res_dec << " or " << VPX_CODEC_CORRUPT_FRAME;
|
<< "). Expected: " << expected_res_dec << " or "
|
||||||
|
<< VPX_CODEC_CORRUPT_FRAME;
|
||||||
} else {
|
} else {
|
||||||
EXPECT_EQ(expected_res_dec, res_dec)
|
EXPECT_EQ(expected_res_dec, res_dec)
|
||||||
<< "Results don't match: frame number = " << video.frame_number()
|
<< "Results don't match: frame number = " << video.frame_number()
|
||||||
@@ -85,23 +84,24 @@ class InvalidFileTest
|
|||||||
|
|
||||||
void RunTest() {
|
void RunTest() {
|
||||||
const DecodeParam input = GET_PARAM(1);
|
const DecodeParam input = GET_PARAM(1);
|
||||||
libvpx_test::CompressedVideoSource *video = NULL;
|
|
||||||
vpx_codec_dec_cfg_t cfg = vpx_codec_dec_cfg_t();
|
vpx_codec_dec_cfg_t cfg = vpx_codec_dec_cfg_t();
|
||||||
cfg.threads = input.threads;
|
cfg.threads = input.threads;
|
||||||
const std::string filename = input.filename;
|
const std::string filename = input.filename;
|
||||||
|
|
||||||
// Open compressed video file.
|
// Open compressed video file.
|
||||||
|
testing::internal::scoped_ptr<libvpx_test::CompressedVideoSource> video;
|
||||||
if (filename.substr(filename.length() - 3, 3) == "ivf") {
|
if (filename.substr(filename.length() - 3, 3) == "ivf") {
|
||||||
video = new libvpx_test::IVFVideoSource(filename);
|
video.reset(new libvpx_test::IVFVideoSource(filename));
|
||||||
} else if (filename.substr(filename.length() - 4, 4) == "webm") {
|
} else if (filename.substr(filename.length() - 4, 4) == "webm") {
|
||||||
#if CONFIG_WEBM_IO
|
#if CONFIG_WEBM_IO
|
||||||
video = new libvpx_test::WebMVideoSource(filename);
|
video.reset(new libvpx_test::WebMVideoSource(filename));
|
||||||
#else
|
#else
|
||||||
fprintf(stderr, "WebM IO is disabled, skipping test vector %s\n",
|
fprintf(stderr, "WebM IO is disabled, skipping test vector %s\n",
|
||||||
filename.c_str());
|
filename.c_str());
|
||||||
return;
|
return;
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
ASSERT_TRUE(video.get() != NULL);
|
||||||
video->Init();
|
video->Init();
|
||||||
|
|
||||||
// Construct result file name. The file holds a list of expected integer
|
// Construct result file name. The file holds a list of expected integer
|
||||||
@@ -111,18 +111,16 @@ class InvalidFileTest
|
|||||||
OpenResFile(res_filename);
|
OpenResFile(res_filename);
|
||||||
|
|
||||||
// Decode frame, and check the md5 matching.
|
// Decode frame, and check the md5 matching.
|
||||||
ASSERT_NO_FATAL_FAILURE(RunLoop(video, cfg));
|
ASSERT_NO_FATAL_FAILURE(RunLoop(video.get(), cfg));
|
||||||
delete video;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
FILE *res_file_;
|
FILE *res_file_;
|
||||||
};
|
};
|
||||||
|
|
||||||
TEST_P(InvalidFileTest, ReturnCode) {
|
TEST_P(InvalidFileTest, ReturnCode) { RunTest(); }
|
||||||
RunTest();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
#if CONFIG_VP9_DECODER
|
||||||
const DecodeParam kVP9InvalidFileTests[] = {
|
const DecodeParam kVP9InvalidFileTests[] = {
|
||||||
{ 1, "invalid-vp90-02-v2.webm" },
|
{ 1, "invalid-vp90-02-v2.webm" },
|
||||||
#if CONFIG_VP9_HIGHBITDEPTH
|
#if CONFIG_VP9_HIGHBITDEPTH
|
||||||
@@ -131,6 +129,12 @@ const DecodeParam kVP9InvalidFileTests[] = {
|
|||||||
{ 1, "invalid-vp90-03-v3.webm" },
|
{ 1, "invalid-vp90-03-v3.webm" },
|
||||||
{ 1, "invalid-vp90-2-00-quantizer-11.webm.ivf.s52984_r01-05_b6-.ivf" },
|
{ 1, "invalid-vp90-2-00-quantizer-11.webm.ivf.s52984_r01-05_b6-.ivf" },
|
||||||
{ 1, "invalid-vp90-2-00-quantizer-11.webm.ivf.s52984_r01-05_b6-z.ivf" },
|
{ 1, "invalid-vp90-2-00-quantizer-11.webm.ivf.s52984_r01-05_b6-z.ivf" },
|
||||||
|
// This file will cause a large allocation which is expected to fail in 32-bit
|
||||||
|
// environments. Test x86 for coverage purposes as the allocation failure will
|
||||||
|
// be in platform agnostic code.
|
||||||
|
#if ARCH_X86
|
||||||
|
{ 1, "invalid-vp90-2-00-quantizer-63.ivf.kf_65527x61446.ivf" },
|
||||||
|
#endif
|
||||||
{ 1, "invalid-vp90-2-12-droppable_1.ivf.s3676_r01-05_b6-.ivf" },
|
{ 1, "invalid-vp90-2-12-droppable_1.ivf.s3676_r01-05_b6-.ivf" },
|
||||||
{ 1, "invalid-vp90-2-05-resize.ivf.s59293_r01-05_b6-.ivf" },
|
{ 1, "invalid-vp90-2-05-resize.ivf.s59293_r01-05_b6-.ivf" },
|
||||||
{ 1, "invalid-vp90-2-09-subpixel-00.ivf.s20492_r01-05_b6-.v2.ivf" },
|
{ 1, "invalid-vp90-2-09-subpixel-00.ivf.s20492_r01-05_b6-.v2.ivf" },
|
||||||
@@ -138,10 +142,14 @@ const DecodeParam kVP9InvalidFileTests[] = {
|
|||||||
{ 1, "invalid-vp90-2-12-droppable_1.ivf.s73804_r01-05_b6-.ivf" },
|
{ 1, "invalid-vp90-2-12-droppable_1.ivf.s73804_r01-05_b6-.ivf" },
|
||||||
{ 1, "invalid-vp90-2-03-size-224x196.webm.ivf.s44156_r01-05_b6-.ivf" },
|
{ 1, "invalid-vp90-2-03-size-224x196.webm.ivf.s44156_r01-05_b6-.ivf" },
|
||||||
{ 1, "invalid-vp90-2-03-size-202x210.webm.ivf.s113306_r01-05_b6-.ivf" },
|
{ 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,
|
VP9_INSTANTIATE_TEST_CASE(InvalidFileTest,
|
||||||
::testing::ValuesIn(kVP9InvalidFileTests));
|
::testing::ValuesIn(kVP9InvalidFileTests));
|
||||||
|
#endif // CONFIG_VP9_DECODER
|
||||||
|
|
||||||
// This class will include test vectors that are expected to fail
|
// This class will include test vectors that are expected to fail
|
||||||
// peek. However they are still expected to have no fatal failures.
|
// peek. However they are still expected to have no fatal failures.
|
||||||
@@ -153,10 +161,18 @@ class InvalidFileInvalidPeekTest : public InvalidFileTest {
|
|||||||
const vpx_codec_err_t /*res_peek*/) {}
|
const vpx_codec_err_t /*res_peek*/) {}
|
||||||
};
|
};
|
||||||
|
|
||||||
TEST_P(InvalidFileInvalidPeekTest, ReturnCode) {
|
TEST_P(InvalidFileInvalidPeekTest, ReturnCode) { RunTest(); }
|
||||||
RunTest();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
#if CONFIG_VP8_DECODER
|
||||||
|
const DecodeParam kVP8InvalidFileTests[] = {
|
||||||
|
{ 1, "invalid-vp80-00-comprehensive-018.ivf.2kf_0x6.ivf" },
|
||||||
|
};
|
||||||
|
|
||||||
|
VP8_INSTANTIATE_TEST_CASE(InvalidFileInvalidPeekTest,
|
||||||
|
::testing::ValuesIn(kVP8InvalidFileTests));
|
||||||
|
#endif // CONFIG_VP8_DECODER
|
||||||
|
|
||||||
|
#if CONFIG_VP9_DECODER
|
||||||
const DecodeParam kVP9InvalidFileInvalidPeekTests[] = {
|
const DecodeParam kVP9InvalidFileInvalidPeekTests[] = {
|
||||||
{ 1, "invalid-vp90-01-v3.webm" },
|
{ 1, "invalid-vp90-01-v3.webm" },
|
||||||
};
|
};
|
||||||
@@ -166,11 +182,14 @@ VP9_INSTANTIATE_TEST_CASE(InvalidFileInvalidPeekTest,
|
|||||||
|
|
||||||
const DecodeParam kMultiThreadedVP9InvalidFileTests[] = {
|
const DecodeParam kMultiThreadedVP9InvalidFileTests[] = {
|
||||||
{ 4, "invalid-vp90-2-08-tile_1x4_frame_parallel_all_key.webm" },
|
{ 4, "invalid-vp90-2-08-tile_1x4_frame_parallel_all_key.webm" },
|
||||||
{4, "invalid-"
|
{ 4,
|
||||||
|
"invalid-"
|
||||||
"vp90-2-08-tile_1x2_frame_parallel.webm.ivf.s47039_r01-05_b6-.ivf" },
|
"vp90-2-08-tile_1x2_frame_parallel.webm.ivf.s47039_r01-05_b6-.ivf" },
|
||||||
{4, "invalid-vp90-2-08-tile_1x8_frame_parallel.webm.ivf.s288_r01-05_b6-.ivf"},
|
{ 4,
|
||||||
|
"invalid-vp90-2-08-tile_1x8_frame_parallel.webm.ivf.s288_r01-05_b6-.ivf" },
|
||||||
{ 2, "invalid-vp90-2-09-aq2.webm.ivf.s3984_r01-05_b6-.v2.ivf" },
|
{ 2, "invalid-vp90-2-09-aq2.webm.ivf.s3984_r01-05_b6-.v2.ivf" },
|
||||||
{ 4, "invalid-vp90-2-09-subpixel-00.ivf.s19552_r01-05_b6-.v2.ivf" },
|
{ 4, "invalid-vp90-2-09-subpixel-00.ivf.s19552_r01-05_b6-.v2.ivf" },
|
||||||
|
{ 2, "invalid-crbug-629481.webm" },
|
||||||
};
|
};
|
||||||
|
|
||||||
INSTANTIATE_TEST_CASE_P(
|
INSTANTIATE_TEST_CASE_P(
|
||||||
@@ -179,4 +198,5 @@ INSTANTIATE_TEST_CASE_P(
|
|||||||
::testing::Values(
|
::testing::Values(
|
||||||
static_cast<const libvpx_test::CodecFactory *>(&libvpx_test::kVP9)),
|
static_cast<const libvpx_test::CodecFactory *>(&libvpx_test::kVP9)),
|
||||||
::testing::ValuesIn(kMultiThreadedVP9InvalidFileTests)));
|
::testing::ValuesIn(kMultiThreadedVP9InvalidFileTests)));
|
||||||
|
#endif // CONFIG_VP9_DECODER
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|||||||
@@ -29,19 +29,13 @@ static unsigned int MemGetLe32(const uint8_t *mem) {
|
|||||||
class IVFVideoSource : public CompressedVideoSource {
|
class IVFVideoSource : public CompressedVideoSource {
|
||||||
public:
|
public:
|
||||||
explicit IVFVideoSource(const std::string &file_name)
|
explicit IVFVideoSource(const std::string &file_name)
|
||||||
: file_name_(file_name),
|
: file_name_(file_name), input_file_(NULL), compressed_frame_buf_(NULL),
|
||||||
input_file_(NULL),
|
frame_sz_(0), frame_(0), end_of_file_(false) {}
|
||||||
compressed_frame_buf_(NULL),
|
|
||||||
frame_sz_(0),
|
|
||||||
frame_(0),
|
|
||||||
end_of_file_(false) {
|
|
||||||
}
|
|
||||||
|
|
||||||
virtual ~IVFVideoSource() {
|
virtual ~IVFVideoSource() {
|
||||||
delete[] compressed_frame_buf_;
|
delete[] compressed_frame_buf_;
|
||||||
|
|
||||||
if (input_file_)
|
if (input_file_) fclose(input_file_);
|
||||||
fclose(input_file_);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual void Init() {
|
virtual void Init() {
|
||||||
@@ -61,8 +55,9 @@ class IVFVideoSource : public CompressedVideoSource {
|
|||||||
ASSERT_EQ(kIvfFileHdrSize, fread(file_hdr, 1, kIvfFileHdrSize, input_file_))
|
ASSERT_EQ(kIvfFileHdrSize, fread(file_hdr, 1, kIvfFileHdrSize, input_file_))
|
||||||
<< "File header read failed.";
|
<< "File header read failed.";
|
||||||
// Check file header
|
// Check file header
|
||||||
ASSERT_TRUE(file_hdr[0] == 'D' && file_hdr[1] == 'K' && file_hdr[2] == 'I'
|
ASSERT_TRUE(file_hdr[0] == 'D' && file_hdr[1] == 'K' &&
|
||||||
&& file_hdr[3] == 'F') << "Input is not an IVF file.";
|
file_hdr[2] == 'I' && file_hdr[3] == 'F')
|
||||||
|
<< "Input is not an IVF file.";
|
||||||
|
|
||||||
FillFrame();
|
FillFrame();
|
||||||
}
|
}
|
||||||
@@ -76,8 +71,8 @@ class IVFVideoSource : public CompressedVideoSource {
|
|||||||
ASSERT_TRUE(input_file_ != NULL);
|
ASSERT_TRUE(input_file_ != NULL);
|
||||||
uint8_t frame_hdr[kIvfFrameHdrSize];
|
uint8_t frame_hdr[kIvfFrameHdrSize];
|
||||||
// Check frame header and read a frame from input_file.
|
// Check frame header and read a frame from input_file.
|
||||||
if (fread(frame_hdr, 1, kIvfFrameHdrSize, input_file_)
|
if (fread(frame_hdr, 1, kIvfFrameHdrSize, input_file_) !=
|
||||||
!= kIvfFrameHdrSize) {
|
kIvfFrameHdrSize) {
|
||||||
end_of_file_ = true;
|
end_of_file_ = true;
|
||||||
} else {
|
} else {
|
||||||
end_of_file_ = false;
|
end_of_file_ = false;
|
||||||
|
|||||||
@@ -17,7 +17,8 @@
|
|||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
|
|
||||||
class KeyframeTest : public ::libvpx_test::EncoderTest,
|
class KeyframeTest
|
||||||
|
: public ::libvpx_test::EncoderTest,
|
||||||
public ::libvpx_test::CodecTestWithParam<libvpx_test::TestMode> {
|
public ::libvpx_test::CodecTestWithParam<libvpx_test::TestMode> {
|
||||||
protected:
|
protected:
|
||||||
KeyframeTest() : EncoderTest(GET_PARAM(0)) {}
|
KeyframeTest() : EncoderTest(GET_PARAM(0)) {}
|
||||||
@@ -34,11 +35,13 @@ class KeyframeTest : public ::libvpx_test::EncoderTest,
|
|||||||
|
|
||||||
virtual void PreEncodeFrameHook(::libvpx_test::VideoSource *video,
|
virtual void PreEncodeFrameHook(::libvpx_test::VideoSource *video,
|
||||||
::libvpx_test::Encoder *encoder) {
|
::libvpx_test::Encoder *encoder) {
|
||||||
if (kf_do_force_kf_)
|
if (kf_do_force_kf_) {
|
||||||
frame_flags_ = (video->frame() % 3) ? 0 : VPX_EFLAG_FORCE_KF;
|
frame_flags_ = (video->frame() % 3) ? 0 : VPX_EFLAG_FORCE_KF;
|
||||||
if (set_cpu_used_ && video->frame() == 1)
|
}
|
||||||
|
if (set_cpu_used_ && video->frame() == 1) {
|
||||||
encoder->Control(VP8E_SET_CPUUSED, set_cpu_used_);
|
encoder->Control(VP8E_SET_CPUUSED, set_cpu_used_);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
virtual void FramePktHook(const vpx_codec_cx_pkt_t *pkt) {
|
virtual void FramePktHook(const vpx_codec_cx_pkt_t *pkt) {
|
||||||
if (pkt->data.frame.flags & VPX_FRAME_IS_KEY) {
|
if (pkt->data.frame.flags & VPX_FRAME_IS_KEY) {
|
||||||
@@ -65,8 +68,7 @@ TEST_P(KeyframeTest, TestRandomVideoSource) {
|
|||||||
|
|
||||||
// In realtime mode - auto placed keyframes are exceedingly rare, don't
|
// In realtime mode - auto placed keyframes are exceedingly rare, don't
|
||||||
// bother with this check if(GetParam() > 0)
|
// bother with this check if(GetParam() > 0)
|
||||||
if (GET_PARAM(1) > 0)
|
if (GET_PARAM(1) > 0) EXPECT_GT(kf_count_, 1);
|
||||||
EXPECT_GT(kf_count_, 1);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_P(KeyframeTest, TestDisableKeyframes) {
|
TEST_P(KeyframeTest, TestDisableKeyframes) {
|
||||||
@@ -114,8 +116,7 @@ TEST_P(KeyframeTest, TestAutoKeyframe) {
|
|||||||
// may not produce a keyframe like we expect. This is necessary when running
|
// may not produce a keyframe like we expect. This is necessary when running
|
||||||
// on very slow environments (like Valgrind). The step -11 was determined
|
// on very slow environments (like Valgrind). The step -11 was determined
|
||||||
// experimentally as the fastest mode that still throws the keyframe.
|
// experimentally as the fastest mode that still throws the keyframe.
|
||||||
if (deadline_ == VPX_DL_REALTIME)
|
if (deadline_ == VPX_DL_REALTIME) set_cpu_used_ = -11;
|
||||||
set_cpu_used_ = -11;
|
|
||||||
|
|
||||||
// This clip has a cut scene every 30 frames -> Frame 0, 30, 60, 90, 120.
|
// This clip has a cut scene every 30 frames -> Frame 0, 30, 60, 90, 120.
|
||||||
// I check only the first 40 frames to make sure there's a keyframe at frame
|
// I check only the first 40 frames to make sure there's a keyframe at frame
|
||||||
|
|||||||
147
test/level_test.cc
Normal file
147
test/level_test.cc
Normal file
@@ -0,0 +1,147 @@
|
|||||||
|
/*
|
||||||
|
* 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 "third_party/googletest/src/include/gtest/gtest.h"
|
||||||
|
#include "test/codec_factory.h"
|
||||||
|
#include "test/encode_test_driver.h"
|
||||||
|
#include "test/i420_video_source.h"
|
||||||
|
#include "test/util.h"
|
||||||
|
|
||||||
|
namespace {
|
||||||
|
class LevelTest
|
||||||
|
: public ::libvpx_test::EncoderTest,
|
||||||
|
public ::libvpx_test::CodecTestWith2Params<libvpx_test::TestMode, int> {
|
||||||
|
protected:
|
||||||
|
LevelTest()
|
||||||
|
: EncoderTest(GET_PARAM(0)), encoding_mode_(GET_PARAM(1)),
|
||||||
|
cpu_used_(GET_PARAM(2)), min_gf_internal_(24), target_level_(0),
|
||||||
|
level_(0) {}
|
||||||
|
virtual ~LevelTest() {}
|
||||||
|
|
||||||
|
virtual void SetUp() {
|
||||||
|
InitializeConfig();
|
||||||
|
SetMode(encoding_mode_);
|
||||||
|
if (encoding_mode_ != ::libvpx_test::kRealTime) {
|
||||||
|
cfg_.g_lag_in_frames = 25;
|
||||||
|
cfg_.rc_end_usage = VPX_VBR;
|
||||||
|
} else {
|
||||||
|
cfg_.g_lag_in_frames = 0;
|
||||||
|
cfg_.rc_end_usage = VPX_CBR;
|
||||||
|
}
|
||||||
|
cfg_.rc_2pass_vbr_minsection_pct = 5;
|
||||||
|
cfg_.rc_2pass_vbr_maxsection_pct = 2000;
|
||||||
|
cfg_.rc_target_bitrate = 400;
|
||||||
|
cfg_.rc_max_quantizer = 63;
|
||||||
|
cfg_.rc_min_quantizer = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual void PreEncodeFrameHook(::libvpx_test::VideoSource *video,
|
||||||
|
::libvpx_test::Encoder *encoder) {
|
||||||
|
if (video->frame() == 0) {
|
||||||
|
encoder->Control(VP8E_SET_CPUUSED, cpu_used_);
|
||||||
|
encoder->Control(VP9E_SET_TARGET_LEVEL, target_level_);
|
||||||
|
encoder->Control(VP9E_SET_MIN_GF_INTERVAL, min_gf_internal_);
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
encoder->Control(VP9E_GET_LEVEL, &level_);
|
||||||
|
ASSERT_LE(level_, 51);
|
||||||
|
ASSERT_GE(level_, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
::libvpx_test::TestMode encoding_mode_;
|
||||||
|
int cpu_used_;
|
||||||
|
int min_gf_internal_;
|
||||||
|
int target_level_;
|
||||||
|
int level_;
|
||||||
|
};
|
||||||
|
|
||||||
|
TEST_P(LevelTest, TestTargetLevel11) {
|
||||||
|
ASSERT_NE(encoding_mode_, ::libvpx_test::kRealTime);
|
||||||
|
::libvpx_test::I420VideoSource video("hantro_odd.yuv", 208, 144, 30, 1, 0,
|
||||||
|
90);
|
||||||
|
target_level_ = 11;
|
||||||
|
cfg_.rc_target_bitrate = 150;
|
||||||
|
ASSERT_NO_FATAL_FAILURE(RunLoop(&video));
|
||||||
|
ASSERT_EQ(target_level_, level_);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_P(LevelTest, TestTargetLevel20) {
|
||||||
|
ASSERT_NE(encoding_mode_, ::libvpx_test::kRealTime);
|
||||||
|
::libvpx_test::I420VideoSource video("hantro_collage_w352h288.yuv", 352, 288,
|
||||||
|
30, 1, 0, 90);
|
||||||
|
target_level_ = 20;
|
||||||
|
cfg_.rc_target_bitrate = 1200;
|
||||||
|
ASSERT_NO_FATAL_FAILURE(RunLoop(&video));
|
||||||
|
ASSERT_EQ(target_level_, level_);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_P(LevelTest, TestTargetLevel31) {
|
||||||
|
ASSERT_NE(encoding_mode_, ::libvpx_test::kRealTime);
|
||||||
|
::libvpx_test::I420VideoSource video("niklas_1280_720_30.y4m", 1280, 720, 30,
|
||||||
|
1, 0, 60);
|
||||||
|
target_level_ = 31;
|
||||||
|
cfg_.rc_target_bitrate = 8000;
|
||||||
|
ASSERT_NO_FATAL_FAILURE(RunLoop(&video));
|
||||||
|
ASSERT_EQ(target_level_, level_);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Test for keeping level stats only
|
||||||
|
TEST_P(LevelTest, TestTargetLevel0) {
|
||||||
|
::libvpx_test::I420VideoSource video("hantro_odd.yuv", 208, 144, 30, 1, 0,
|
||||||
|
40);
|
||||||
|
target_level_ = 0;
|
||||||
|
min_gf_internal_ = 4;
|
||||||
|
ASSERT_NO_FATAL_FAILURE(RunLoop(&video));
|
||||||
|
ASSERT_EQ(11, level_);
|
||||||
|
|
||||||
|
cfg_.rc_target_bitrate = 1600;
|
||||||
|
ASSERT_NO_FATAL_FAILURE(RunLoop(&video));
|
||||||
|
ASSERT_EQ(20, level_);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Test for level control being turned off
|
||||||
|
TEST_P(LevelTest, TestTargetLevel255) {
|
||||||
|
::libvpx_test::I420VideoSource video("hantro_odd.yuv", 208, 144, 30, 1, 0,
|
||||||
|
30);
|
||||||
|
target_level_ = 255;
|
||||||
|
ASSERT_NO_FATAL_FAILURE(RunLoop(&video));
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_P(LevelTest, TestTargetLevelApi) {
|
||||||
|
::libvpx_test::I420VideoSource video("hantro_odd.yuv", 208, 144, 30, 1, 0, 1);
|
||||||
|
static const vpx_codec_iface_t *codec = &vpx_codec_vp9_cx_algo;
|
||||||
|
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)
|
||||||
|
EXPECT_EQ(VPX_CODEC_OK,
|
||||||
|
vpx_codec_control(&enc, VP9E_SET_TARGET_LEVEL, level));
|
||||||
|
else
|
||||||
|
EXPECT_EQ(VPX_CODEC_INVALID_PARAM,
|
||||||
|
vpx_codec_control(&enc, VP9E_SET_TARGET_LEVEL, level));
|
||||||
|
}
|
||||||
|
EXPECT_EQ(VPX_CODEC_OK, vpx_codec_destroy(&enc));
|
||||||
|
}
|
||||||
|
|
||||||
|
VP9_INSTANTIATE_TEST_CASE(LevelTest,
|
||||||
|
::testing::Values(::libvpx_test::kTwoPassGood,
|
||||||
|
::libvpx_test::kOnePassGood),
|
||||||
|
::testing::Range(0, 9));
|
||||||
|
} // namespace
|
||||||
@@ -1,678 +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 <cmath>
|
|
||||||
#include <cstdlib>
|
|
||||||
#include <string>
|
|
||||||
|
|
||||||
#include "third_party/googletest/src/include/gtest/gtest.h"
|
|
||||||
|
|
||||||
#include "./vpx_config.h"
|
|
||||||
#include "./vpx_dsp_rtcd.h"
|
|
||||||
#include "test/acm_random.h"
|
|
||||||
#include "test/clear_system_state.h"
|
|
||||||
#include "test/register_state_check.h"
|
|
||||||
#include "test/util.h"
|
|
||||||
#include "vp9/common/vp9_entropy.h"
|
|
||||||
#include "vp9/common/vp9_loopfilter.h"
|
|
||||||
#include "vpx/vpx_integer.h"
|
|
||||||
|
|
||||||
using libvpx_test::ACMRandom;
|
|
||||||
|
|
||||||
namespace {
|
|
||||||
// Horizontally and Vertically need 32x32: 8 Coeffs preceeding filtered section
|
|
||||||
// 16 Coefs within filtered section
|
|
||||||
// 8 Coeffs following filtered section
|
|
||||||
const int kNumCoeffs = 1024;
|
|
||||||
|
|
||||||
const int number_of_iterations = 10000;
|
|
||||||
|
|
||||||
#if CONFIG_VP9_HIGHBITDEPTH
|
|
||||||
typedef void (*loop_op_t)(uint16_t *s, int p, const uint8_t *blimit,
|
|
||||||
const uint8_t *limit, const uint8_t *thresh,
|
|
||||||
int bd);
|
|
||||||
typedef void (*dual_loop_op_t)(uint16_t *s, int p, const uint8_t *blimit0,
|
|
||||||
const uint8_t *limit0, const uint8_t *thresh0,
|
|
||||||
const uint8_t *blimit1, const uint8_t *limit1,
|
|
||||||
const uint8_t *thresh1, int bd);
|
|
||||||
#else
|
|
||||||
typedef void (*loop_op_t)(uint8_t *s, int p, const uint8_t *blimit,
|
|
||||||
const uint8_t *limit, const uint8_t *thresh);
|
|
||||||
typedef void (*dual_loop_op_t)(uint8_t *s, int p, const uint8_t *blimit0,
|
|
||||||
const uint8_t *limit0, const uint8_t *thresh0,
|
|
||||||
const uint8_t *blimit1, const uint8_t *limit1,
|
|
||||||
const uint8_t *thresh1);
|
|
||||||
#endif // CONFIG_VP9_HIGHBITDEPTH
|
|
||||||
|
|
||||||
typedef std::tr1::tuple<loop_op_t, loop_op_t, int> loop8_param_t;
|
|
||||||
typedef std::tr1::tuple<dual_loop_op_t, dual_loop_op_t, int> dualloop8_param_t;
|
|
||||||
|
|
||||||
class Loop8Test6Param : public ::testing::TestWithParam<loop8_param_t> {
|
|
||||||
public:
|
|
||||||
virtual ~Loop8Test6Param() {}
|
|
||||||
virtual void SetUp() {
|
|
||||||
loopfilter_op_ = GET_PARAM(0);
|
|
||||||
ref_loopfilter_op_ = GET_PARAM(1);
|
|
||||||
bit_depth_ = GET_PARAM(2);
|
|
||||||
mask_ = (1 << bit_depth_) - 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
virtual void TearDown() { libvpx_test::ClearSystemState(); }
|
|
||||||
|
|
||||||
protected:
|
|
||||||
int bit_depth_;
|
|
||||||
int mask_;
|
|
||||||
loop_op_t loopfilter_op_;
|
|
||||||
loop_op_t ref_loopfilter_op_;
|
|
||||||
};
|
|
||||||
|
|
||||||
class Loop8Test9Param : public ::testing::TestWithParam<dualloop8_param_t> {
|
|
||||||
public:
|
|
||||||
virtual ~Loop8Test9Param() {}
|
|
||||||
virtual void SetUp() {
|
|
||||||
loopfilter_op_ = GET_PARAM(0);
|
|
||||||
ref_loopfilter_op_ = GET_PARAM(1);
|
|
||||||
bit_depth_ = GET_PARAM(2);
|
|
||||||
mask_ = (1 << bit_depth_) - 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
virtual void TearDown() { libvpx_test::ClearSystemState(); }
|
|
||||||
|
|
||||||
protected:
|
|
||||||
int bit_depth_;
|
|
||||||
int mask_;
|
|
||||||
dual_loop_op_t loopfilter_op_;
|
|
||||||
dual_loop_op_t ref_loopfilter_op_;
|
|
||||||
};
|
|
||||||
|
|
||||||
TEST_P(Loop8Test6Param, OperationCheck) {
|
|
||||||
ACMRandom rnd(ACMRandom::DeterministicSeed());
|
|
||||||
const int count_test_block = number_of_iterations;
|
|
||||||
#if CONFIG_VP9_HIGHBITDEPTH
|
|
||||||
int32_t bd = bit_depth_;
|
|
||||||
DECLARE_ALIGNED(16, uint16_t, s[kNumCoeffs]);
|
|
||||||
DECLARE_ALIGNED(16, uint16_t, ref_s[kNumCoeffs]);
|
|
||||||
#else
|
|
||||||
DECLARE_ALIGNED(8, uint8_t, s[kNumCoeffs]);
|
|
||||||
DECLARE_ALIGNED(8, uint8_t, ref_s[kNumCoeffs]);
|
|
||||||
#endif // CONFIG_VP9_HIGHBITDEPTH
|
|
||||||
int err_count_total = 0;
|
|
||||||
int first_failure = -1;
|
|
||||||
for (int i = 0; i < count_test_block; ++i) {
|
|
||||||
int err_count = 0;
|
|
||||||
uint8_t tmp = static_cast<uint8_t>(rnd(3 * MAX_LOOP_FILTER + 4));
|
|
||||||
DECLARE_ALIGNED(16, const uint8_t, blimit[16]) = {
|
|
||||||
tmp, tmp, tmp, tmp, tmp, tmp, tmp, tmp,
|
|
||||||
tmp, tmp, tmp, tmp, tmp, tmp, tmp, tmp
|
|
||||||
};
|
|
||||||
tmp = static_cast<uint8_t>(rnd(MAX_LOOP_FILTER));
|
|
||||||
DECLARE_ALIGNED(16, const uint8_t, limit[16]) = {
|
|
||||||
tmp, tmp, tmp, tmp, tmp, tmp, tmp, tmp,
|
|
||||||
tmp, tmp, tmp, tmp, tmp, tmp, tmp, tmp
|
|
||||||
};
|
|
||||||
tmp = rnd.Rand8();
|
|
||||||
DECLARE_ALIGNED(16, const uint8_t, thresh[16]) = {
|
|
||||||
tmp, tmp, tmp, tmp, tmp, tmp, tmp, tmp,
|
|
||||||
tmp, tmp, tmp, tmp, tmp, tmp, tmp, tmp
|
|
||||||
};
|
|
||||||
int32_t p = kNumCoeffs/32;
|
|
||||||
|
|
||||||
uint16_t tmp_s[kNumCoeffs];
|
|
||||||
int j = 0;
|
|
||||||
while (j < kNumCoeffs) {
|
|
||||||
uint8_t val = rnd.Rand8();
|
|
||||||
if (val & 0x80) { // 50% chance to choose a new value.
|
|
||||||
tmp_s[j] = rnd.Rand16();
|
|
||||||
j++;
|
|
||||||
} else { // 50% chance to repeat previous value in row X times
|
|
||||||
int k = 0;
|
|
||||||
while (k++ < ((val & 0x1f) + 1) && j < kNumCoeffs) {
|
|
||||||
if (j < 1) {
|
|
||||||
tmp_s[j] = rnd.Rand16();
|
|
||||||
} else if (val & 0x20) { // Increment by an value within the limit
|
|
||||||
tmp_s[j] = (tmp_s[j - 1] + (*limit - 1));
|
|
||||||
} else { // Decrement by an value within the limit
|
|
||||||
tmp_s[j] = (tmp_s[j - 1] - (*limit - 1));
|
|
||||||
}
|
|
||||||
j++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
for (j = 0; j < kNumCoeffs; j++) {
|
|
||||||
if (i % 2) {
|
|
||||||
s[j] = tmp_s[j] & mask_;
|
|
||||||
} else {
|
|
||||||
s[j] = tmp_s[p * (j % p) + j / p] & mask_;
|
|
||||||
}
|
|
||||||
ref_s[j] = s[j];
|
|
||||||
}
|
|
||||||
#if CONFIG_VP9_HIGHBITDEPTH
|
|
||||||
ref_loopfilter_op_(ref_s + 8 + p * 8, p, blimit, limit, thresh, bd);
|
|
||||||
ASM_REGISTER_STATE_CHECK(
|
|
||||||
loopfilter_op_(s + 8 + p * 8, p, blimit, limit, thresh, bd));
|
|
||||||
#else
|
|
||||||
ref_loopfilter_op_(ref_s+8+p*8, p, blimit, limit, thresh);
|
|
||||||
ASM_REGISTER_STATE_CHECK(
|
|
||||||
loopfilter_op_(s + 8 + p * 8, p, blimit, limit, thresh));
|
|
||||||
#endif // CONFIG_VP9_HIGHBITDEPTH
|
|
||||||
|
|
||||||
for (int j = 0; j < kNumCoeffs; ++j) {
|
|
||||||
err_count += ref_s[j] != s[j];
|
|
||||||
}
|
|
||||||
if (err_count && !err_count_total) {
|
|
||||||
first_failure = i;
|
|
||||||
}
|
|
||||||
err_count_total += err_count;
|
|
||||||
}
|
|
||||||
EXPECT_EQ(0, err_count_total)
|
|
||||||
<< "Error: Loop8Test6Param, C output doesn't match SSE2 "
|
|
||||||
"loopfilter output. "
|
|
||||||
<< "First failed at test case " << first_failure;
|
|
||||||
}
|
|
||||||
|
|
||||||
TEST_P(Loop8Test6Param, ValueCheck) {
|
|
||||||
ACMRandom rnd(ACMRandom::DeterministicSeed());
|
|
||||||
const int count_test_block = number_of_iterations;
|
|
||||||
#if CONFIG_VP9_HIGHBITDEPTH
|
|
||||||
const int32_t bd = bit_depth_;
|
|
||||||
DECLARE_ALIGNED(16, uint16_t, s[kNumCoeffs]);
|
|
||||||
DECLARE_ALIGNED(16, uint16_t, ref_s[kNumCoeffs]);
|
|
||||||
#else
|
|
||||||
DECLARE_ALIGNED(8, uint8_t, s[kNumCoeffs]);
|
|
||||||
DECLARE_ALIGNED(8, uint8_t, ref_s[kNumCoeffs]);
|
|
||||||
#endif // CONFIG_VP9_HIGHBITDEPTH
|
|
||||||
int err_count_total = 0;
|
|
||||||
int first_failure = -1;
|
|
||||||
|
|
||||||
// NOTE: The code in vp9_loopfilter.c:update_sharpness computes mblim as a
|
|
||||||
// function of sharpness_lvl and the loopfilter lvl as:
|
|
||||||
// block_inside_limit = lvl >> ((sharpness_lvl > 0) + (sharpness_lvl > 4));
|
|
||||||
// ...
|
|
||||||
// memset(lfi->lfthr[lvl].mblim, (2 * (lvl + 2) + block_inside_limit),
|
|
||||||
// SIMD_WIDTH);
|
|
||||||
// This means that the largest value for mblim will occur when sharpness_lvl
|
|
||||||
// is equal to 0, and lvl is equal to its greatest value (MAX_LOOP_FILTER).
|
|
||||||
// In this case block_inside_limit will be equal to MAX_LOOP_FILTER and
|
|
||||||
// therefore mblim will be equal to (2 * (lvl + 2) + block_inside_limit) =
|
|
||||||
// 2 * (MAX_LOOP_FILTER + 2) + MAX_LOOP_FILTER = 3 * MAX_LOOP_FILTER + 4
|
|
||||||
|
|
||||||
for (int i = 0; i < count_test_block; ++i) {
|
|
||||||
int err_count = 0;
|
|
||||||
uint8_t tmp = static_cast<uint8_t>(rnd(3 * MAX_LOOP_FILTER + 4));
|
|
||||||
DECLARE_ALIGNED(16, const uint8_t, blimit[16]) = {
|
|
||||||
tmp, tmp, tmp, tmp, tmp, tmp, tmp, tmp,
|
|
||||||
tmp, tmp, tmp, tmp, tmp, tmp, tmp, tmp
|
|
||||||
};
|
|
||||||
tmp = static_cast<uint8_t>(rnd(MAX_LOOP_FILTER));
|
|
||||||
DECLARE_ALIGNED(16, const uint8_t, limit[16]) = {
|
|
||||||
tmp, tmp, tmp, tmp, tmp, tmp, tmp, tmp,
|
|
||||||
tmp, tmp, tmp, tmp, tmp, tmp, tmp, tmp
|
|
||||||
};
|
|
||||||
tmp = rnd.Rand8();
|
|
||||||
DECLARE_ALIGNED(16, const uint8_t, thresh[16]) = {
|
|
||||||
tmp, tmp, tmp, tmp, tmp, tmp, tmp, tmp,
|
|
||||||
tmp, tmp, tmp, tmp, tmp, tmp, tmp, tmp
|
|
||||||
};
|
|
||||||
int32_t p = kNumCoeffs / 32;
|
|
||||||
for (int j = 0; j < kNumCoeffs; ++j) {
|
|
||||||
s[j] = rnd.Rand16() & mask_;
|
|
||||||
ref_s[j] = s[j];
|
|
||||||
}
|
|
||||||
#if CONFIG_VP9_HIGHBITDEPTH
|
|
||||||
ref_loopfilter_op_(ref_s + 8 + p * 8, p, blimit, limit, thresh, bd);
|
|
||||||
ASM_REGISTER_STATE_CHECK(
|
|
||||||
loopfilter_op_(s + 8 + p * 8, p, blimit, limit, thresh, bd));
|
|
||||||
#else
|
|
||||||
ref_loopfilter_op_(ref_s+8+p*8, p, blimit, limit, thresh);
|
|
||||||
ASM_REGISTER_STATE_CHECK(
|
|
||||||
loopfilter_op_(s + 8 + p * 8, p, blimit, limit, thresh));
|
|
||||||
#endif // CONFIG_VP9_HIGHBITDEPTH
|
|
||||||
for (int j = 0; j < kNumCoeffs; ++j) {
|
|
||||||
err_count += ref_s[j] != s[j];
|
|
||||||
}
|
|
||||||
if (err_count && !err_count_total) {
|
|
||||||
first_failure = i;
|
|
||||||
}
|
|
||||||
err_count_total += err_count;
|
|
||||||
}
|
|
||||||
EXPECT_EQ(0, err_count_total)
|
|
||||||
<< "Error: Loop8Test6Param, C output doesn't match SSE2 "
|
|
||||||
"loopfilter output. "
|
|
||||||
<< "First failed at test case " << first_failure;
|
|
||||||
}
|
|
||||||
|
|
||||||
TEST_P(Loop8Test9Param, OperationCheck) {
|
|
||||||
ACMRandom rnd(ACMRandom::DeterministicSeed());
|
|
||||||
const int count_test_block = number_of_iterations;
|
|
||||||
#if CONFIG_VP9_HIGHBITDEPTH
|
|
||||||
const int32_t bd = bit_depth_;
|
|
||||||
DECLARE_ALIGNED(16, uint16_t, s[kNumCoeffs]);
|
|
||||||
DECLARE_ALIGNED(16, uint16_t, ref_s[kNumCoeffs]);
|
|
||||||
#else
|
|
||||||
DECLARE_ALIGNED(8, uint8_t, s[kNumCoeffs]);
|
|
||||||
DECLARE_ALIGNED(8, uint8_t, ref_s[kNumCoeffs]);
|
|
||||||
#endif // CONFIG_VP9_HIGHBITDEPTH
|
|
||||||
int err_count_total = 0;
|
|
||||||
int first_failure = -1;
|
|
||||||
for (int i = 0; i < count_test_block; ++i) {
|
|
||||||
int err_count = 0;
|
|
||||||
uint8_t tmp = static_cast<uint8_t>(rnd(3 * MAX_LOOP_FILTER + 4));
|
|
||||||
DECLARE_ALIGNED(16, const uint8_t, blimit0[16]) = {
|
|
||||||
tmp, tmp, tmp, tmp, tmp, tmp, tmp, tmp,
|
|
||||||
tmp, tmp, tmp, tmp, tmp, tmp, tmp, tmp
|
|
||||||
};
|
|
||||||
tmp = static_cast<uint8_t>(rnd(MAX_LOOP_FILTER));
|
|
||||||
DECLARE_ALIGNED(16, const uint8_t, limit0[16]) = {
|
|
||||||
tmp, tmp, tmp, tmp, tmp, tmp, tmp, tmp,
|
|
||||||
tmp, tmp, tmp, tmp, tmp, tmp, tmp, tmp
|
|
||||||
};
|
|
||||||
tmp = rnd.Rand8();
|
|
||||||
DECLARE_ALIGNED(16, const uint8_t, thresh0[16]) = {
|
|
||||||
tmp, tmp, tmp, tmp, tmp, tmp, tmp, tmp,
|
|
||||||
tmp, tmp, tmp, tmp, tmp, tmp, tmp, tmp
|
|
||||||
};
|
|
||||||
tmp = static_cast<uint8_t>(rnd(3 * MAX_LOOP_FILTER + 4));
|
|
||||||
DECLARE_ALIGNED(16, const uint8_t, blimit1[16]) = {
|
|
||||||
tmp, tmp, tmp, tmp, tmp, tmp, tmp, tmp,
|
|
||||||
tmp, tmp, tmp, tmp, tmp, tmp, tmp, tmp
|
|
||||||
};
|
|
||||||
tmp = static_cast<uint8_t>(rnd(MAX_LOOP_FILTER));
|
|
||||||
DECLARE_ALIGNED(16, const uint8_t, limit1[16]) = {
|
|
||||||
tmp, tmp, tmp, tmp, tmp, tmp, tmp, tmp,
|
|
||||||
tmp, tmp, tmp, tmp, tmp, tmp, tmp, tmp
|
|
||||||
};
|
|
||||||
tmp = rnd.Rand8();
|
|
||||||
DECLARE_ALIGNED(16, const uint8_t, thresh1[16]) = {
|
|
||||||
tmp, tmp, tmp, tmp, tmp, tmp, tmp, tmp,
|
|
||||||
tmp, tmp, tmp, tmp, tmp, tmp, tmp, tmp
|
|
||||||
};
|
|
||||||
int32_t p = kNumCoeffs / 32;
|
|
||||||
uint16_t tmp_s[kNumCoeffs];
|
|
||||||
int j = 0;
|
|
||||||
const uint8_t limit = *limit0 < *limit1 ? *limit0 : *limit1;
|
|
||||||
while (j < kNumCoeffs) {
|
|
||||||
uint8_t val = rnd.Rand8();
|
|
||||||
if (val & 0x80) { // 50% chance to choose a new value.
|
|
||||||
tmp_s[j] = rnd.Rand16();
|
|
||||||
j++;
|
|
||||||
} else { // 50% chance to repeat previous value in row X times.
|
|
||||||
int k = 0;
|
|
||||||
while (k++ < ((val & 0x1f) + 1) && j < kNumCoeffs) {
|
|
||||||
if (j < 1) {
|
|
||||||
tmp_s[j] = rnd.Rand16();
|
|
||||||
} else if (val & 0x20) { // Increment by a value within the limit.
|
|
||||||
tmp_s[j] = (tmp_s[j - 1] + (limit - 1));
|
|
||||||
} else { // Decrement by an value within the limit.
|
|
||||||
tmp_s[j] = (tmp_s[j - 1] - (limit - 1));
|
|
||||||
}
|
|
||||||
j++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
for (j = 0; j < kNumCoeffs; j++) {
|
|
||||||
if (i % 2) {
|
|
||||||
s[j] = tmp_s[j] & mask_;
|
|
||||||
} else {
|
|
||||||
s[j] = tmp_s[p * (j % p) + j / p] & mask_;
|
|
||||||
}
|
|
||||||
ref_s[j] = s[j];
|
|
||||||
}
|
|
||||||
#if CONFIG_VP9_HIGHBITDEPTH
|
|
||||||
ref_loopfilter_op_(ref_s + 8 + p * 8, p, blimit0, limit0, thresh0,
|
|
||||||
blimit1, limit1, thresh1, bd);
|
|
||||||
ASM_REGISTER_STATE_CHECK(
|
|
||||||
loopfilter_op_(s + 8 + p * 8, p, blimit0, limit0, thresh0,
|
|
||||||
blimit1, limit1, thresh1, bd));
|
|
||||||
#else
|
|
||||||
ref_loopfilter_op_(ref_s + 8 + p * 8, p, blimit0, limit0, thresh0,
|
|
||||||
blimit1, limit1, thresh1);
|
|
||||||
ASM_REGISTER_STATE_CHECK(
|
|
||||||
loopfilter_op_(s + 8 + p * 8, p, blimit0, limit0, thresh0,
|
|
||||||
blimit1, limit1, thresh1));
|
|
||||||
#endif // CONFIG_VP9_HIGHBITDEPTH
|
|
||||||
for (int j = 0; j < kNumCoeffs; ++j) {
|
|
||||||
err_count += ref_s[j] != s[j];
|
|
||||||
}
|
|
||||||
if (err_count && !err_count_total) {
|
|
||||||
first_failure = i;
|
|
||||||
}
|
|
||||||
err_count_total += err_count;
|
|
||||||
}
|
|
||||||
EXPECT_EQ(0, err_count_total)
|
|
||||||
<< "Error: Loop8Test9Param, C output doesn't match SSE2 "
|
|
||||||
"loopfilter output. "
|
|
||||||
<< "First failed at test case " << first_failure;
|
|
||||||
}
|
|
||||||
|
|
||||||
TEST_P(Loop8Test9Param, ValueCheck) {
|
|
||||||
ACMRandom rnd(ACMRandom::DeterministicSeed());
|
|
||||||
const int count_test_block = number_of_iterations;
|
|
||||||
#if CONFIG_VP9_HIGHBITDEPTH
|
|
||||||
DECLARE_ALIGNED(16, uint16_t, s[kNumCoeffs]);
|
|
||||||
DECLARE_ALIGNED(16, uint16_t, ref_s[kNumCoeffs]);
|
|
||||||
#else
|
|
||||||
DECLARE_ALIGNED(8, uint8_t, s[kNumCoeffs]);
|
|
||||||
DECLARE_ALIGNED(8, uint8_t, ref_s[kNumCoeffs]);
|
|
||||||
#endif // CONFIG_VP9_HIGHBITDEPTH
|
|
||||||
int err_count_total = 0;
|
|
||||||
int first_failure = -1;
|
|
||||||
for (int i = 0; i < count_test_block; ++i) {
|
|
||||||
int err_count = 0;
|
|
||||||
uint8_t tmp = static_cast<uint8_t>(rnd(3 * MAX_LOOP_FILTER + 4));
|
|
||||||
DECLARE_ALIGNED(16, const uint8_t, blimit0[16]) = {
|
|
||||||
tmp, tmp, tmp, tmp, tmp, tmp, tmp, tmp,
|
|
||||||
tmp, tmp, tmp, tmp, tmp, tmp, tmp, tmp
|
|
||||||
};
|
|
||||||
tmp = static_cast<uint8_t>(rnd(MAX_LOOP_FILTER));
|
|
||||||
DECLARE_ALIGNED(16, const uint8_t, limit0[16]) = {
|
|
||||||
tmp, tmp, tmp, tmp, tmp, tmp, tmp, tmp,
|
|
||||||
tmp, tmp, tmp, tmp, tmp, tmp, tmp, tmp
|
|
||||||
};
|
|
||||||
tmp = rnd.Rand8();
|
|
||||||
DECLARE_ALIGNED(16, const uint8_t, thresh0[16]) = {
|
|
||||||
tmp, tmp, tmp, tmp, tmp, tmp, tmp, tmp,
|
|
||||||
tmp, tmp, tmp, tmp, tmp, tmp, tmp, tmp
|
|
||||||
};
|
|
||||||
tmp = static_cast<uint8_t>(rnd(3 * MAX_LOOP_FILTER + 4));
|
|
||||||
DECLARE_ALIGNED(16, const uint8_t, blimit1[16]) = {
|
|
||||||
tmp, tmp, tmp, tmp, tmp, tmp, tmp, tmp,
|
|
||||||
tmp, tmp, tmp, tmp, tmp, tmp, tmp, tmp
|
|
||||||
};
|
|
||||||
tmp = static_cast<uint8_t>(rnd(MAX_LOOP_FILTER));
|
|
||||||
DECLARE_ALIGNED(16, const uint8_t, limit1[16]) = {
|
|
||||||
tmp, tmp, tmp, tmp, tmp, tmp, tmp, tmp,
|
|
||||||
tmp, tmp, tmp, tmp, tmp, tmp, tmp, tmp
|
|
||||||
};
|
|
||||||
tmp = rnd.Rand8();
|
|
||||||
DECLARE_ALIGNED(16, const uint8_t, thresh1[16]) = {
|
|
||||||
tmp, tmp, tmp, tmp, tmp, tmp, tmp, tmp,
|
|
||||||
tmp, tmp, tmp, tmp, tmp, tmp, tmp, tmp
|
|
||||||
};
|
|
||||||
int32_t p = kNumCoeffs / 32; // TODO(pdlf) can we have non-square here?
|
|
||||||
for (int j = 0; j < kNumCoeffs; ++j) {
|
|
||||||
s[j] = rnd.Rand16() & mask_;
|
|
||||||
ref_s[j] = s[j];
|
|
||||||
}
|
|
||||||
#if CONFIG_VP9_HIGHBITDEPTH
|
|
||||||
const int32_t bd = bit_depth_;
|
|
||||||
ref_loopfilter_op_(ref_s + 8 + p * 8, p, blimit0, limit0, thresh0,
|
|
||||||
blimit1, limit1, thresh1, bd);
|
|
||||||
ASM_REGISTER_STATE_CHECK(
|
|
||||||
loopfilter_op_(s + 8 + p * 8, p, blimit0, limit0,
|
|
||||||
thresh0, blimit1, limit1, thresh1, bd));
|
|
||||||
#else
|
|
||||||
ref_loopfilter_op_(ref_s + 8 + p * 8, p, blimit0, limit0, thresh0,
|
|
||||||
blimit1, limit1, thresh1);
|
|
||||||
ASM_REGISTER_STATE_CHECK(
|
|
||||||
loopfilter_op_(s + 8 + p * 8, p, blimit0, limit0, thresh0,
|
|
||||||
blimit1, limit1, thresh1));
|
|
||||||
#endif // CONFIG_VP9_HIGHBITDEPTH
|
|
||||||
for (int j = 0; j < kNumCoeffs; ++j) {
|
|
||||||
err_count += ref_s[j] != s[j];
|
|
||||||
}
|
|
||||||
if (err_count && !err_count_total) {
|
|
||||||
first_failure = i;
|
|
||||||
}
|
|
||||||
err_count_total += err_count;
|
|
||||||
}
|
|
||||||
EXPECT_EQ(0, err_count_total)
|
|
||||||
<< "Error: Loop8Test9Param, C output doesn't match SSE2"
|
|
||||||
"loopfilter output. "
|
|
||||||
<< "First failed at test case " << first_failure;
|
|
||||||
}
|
|
||||||
|
|
||||||
using std::tr1::make_tuple;
|
|
||||||
|
|
||||||
#if HAVE_MMX && CONFIG_USE_X86INC && !CONFIG_VP9_HIGHBITDEPTH
|
|
||||||
INSTANTIATE_TEST_CASE_P(
|
|
||||||
MMX, Loop8Test6Param,
|
|
||||||
::testing::Values(
|
|
||||||
make_tuple(&vpx_lpf_horizontal_4_mmx,
|
|
||||||
&vpx_lpf_horizontal_4_c, 8),
|
|
||||||
make_tuple(&vpx_lpf_vertical_4_mmx,
|
|
||||||
&vpx_lpf_vertical_4_c, 8)));
|
|
||||||
#endif // HAVE_MMX
|
|
||||||
|
|
||||||
#if HAVE_SSE2
|
|
||||||
#if CONFIG_VP9_HIGHBITDEPTH
|
|
||||||
INSTANTIATE_TEST_CASE_P(
|
|
||||||
SSE2, Loop8Test6Param,
|
|
||||||
::testing::Values(
|
|
||||||
make_tuple(&vpx_highbd_lpf_horizontal_4_sse2,
|
|
||||||
&vpx_highbd_lpf_horizontal_4_c, 8),
|
|
||||||
make_tuple(&vpx_highbd_lpf_vertical_4_sse2,
|
|
||||||
&vpx_highbd_lpf_vertical_4_c, 8),
|
|
||||||
make_tuple(&vpx_highbd_lpf_horizontal_8_sse2,
|
|
||||||
&vpx_highbd_lpf_horizontal_8_c, 8),
|
|
||||||
make_tuple(&vpx_highbd_lpf_horizontal_edge_8_sse2,
|
|
||||||
&vpx_highbd_lpf_horizontal_edge_8_c, 8),
|
|
||||||
make_tuple(&vpx_highbd_lpf_horizontal_edge_16_sse2,
|
|
||||||
&vpx_highbd_lpf_horizontal_edge_16_c, 8),
|
|
||||||
make_tuple(&vpx_highbd_lpf_vertical_8_sse2,
|
|
||||||
&vpx_highbd_lpf_vertical_8_c, 8),
|
|
||||||
make_tuple(&vpx_highbd_lpf_vertical_16_sse2,
|
|
||||||
&vpx_highbd_lpf_vertical_16_c, 8),
|
|
||||||
make_tuple(&vpx_highbd_lpf_horizontal_4_sse2,
|
|
||||||
&vpx_highbd_lpf_horizontal_4_c, 10),
|
|
||||||
make_tuple(&vpx_highbd_lpf_vertical_4_sse2,
|
|
||||||
&vpx_highbd_lpf_vertical_4_c, 10),
|
|
||||||
make_tuple(&vpx_highbd_lpf_horizontal_8_sse2,
|
|
||||||
&vpx_highbd_lpf_horizontal_8_c, 10),
|
|
||||||
make_tuple(&vpx_highbd_lpf_horizontal_edge_8_sse2,
|
|
||||||
&vpx_highbd_lpf_horizontal_edge_8_c, 10),
|
|
||||||
make_tuple(&vpx_highbd_lpf_horizontal_edge_16_sse2,
|
|
||||||
&vpx_highbd_lpf_horizontal_edge_16_c, 10),
|
|
||||||
make_tuple(&vpx_highbd_lpf_vertical_8_sse2,
|
|
||||||
&vpx_highbd_lpf_vertical_8_c, 10),
|
|
||||||
make_tuple(&vpx_highbd_lpf_vertical_16_sse2,
|
|
||||||
&vpx_highbd_lpf_vertical_16_c, 10),
|
|
||||||
make_tuple(&vpx_highbd_lpf_horizontal_4_sse2,
|
|
||||||
&vpx_highbd_lpf_horizontal_4_c, 12),
|
|
||||||
make_tuple(&vpx_highbd_lpf_vertical_4_sse2,
|
|
||||||
&vpx_highbd_lpf_vertical_4_c, 12),
|
|
||||||
make_tuple(&vpx_highbd_lpf_horizontal_8_sse2,
|
|
||||||
&vpx_highbd_lpf_horizontal_8_c, 12),
|
|
||||||
make_tuple(&vpx_highbd_lpf_horizontal_edge_8_sse2,
|
|
||||||
&vpx_highbd_lpf_horizontal_edge_8_c, 12),
|
|
||||||
make_tuple(&vpx_highbd_lpf_horizontal_edge_16_sse2,
|
|
||||||
&vpx_highbd_lpf_horizontal_edge_16_c, 12),
|
|
||||||
make_tuple(&vpx_highbd_lpf_vertical_8_sse2,
|
|
||||||
&vpx_highbd_lpf_vertical_8_c, 12),
|
|
||||||
make_tuple(&vpx_highbd_lpf_vertical_16_sse2,
|
|
||||||
&vpx_highbd_lpf_vertical_16_c, 12),
|
|
||||||
make_tuple(&vpx_highbd_lpf_vertical_16_dual_sse2,
|
|
||||||
&vpx_highbd_lpf_vertical_16_dual_c, 8),
|
|
||||||
make_tuple(&vpx_highbd_lpf_vertical_16_dual_sse2,
|
|
||||||
&vpx_highbd_lpf_vertical_16_dual_c, 10),
|
|
||||||
make_tuple(&vpx_highbd_lpf_vertical_16_dual_sse2,
|
|
||||||
&vpx_highbd_lpf_vertical_16_dual_c, 12)));
|
|
||||||
#else
|
|
||||||
INSTANTIATE_TEST_CASE_P(
|
|
||||||
SSE2, Loop8Test6Param,
|
|
||||||
::testing::Values(
|
|
||||||
make_tuple(&vpx_lpf_horizontal_8_sse2,
|
|
||||||
&vpx_lpf_horizontal_8_c, 8),
|
|
||||||
make_tuple(&vpx_lpf_horizontal_edge_8_sse2,
|
|
||||||
&vpx_lpf_horizontal_edge_8_c, 8),
|
|
||||||
make_tuple(&vpx_lpf_horizontal_edge_16_sse2,
|
|
||||||
&vpx_lpf_horizontal_edge_16_c, 8),
|
|
||||||
make_tuple(&vpx_lpf_vertical_8_sse2,
|
|
||||||
&vpx_lpf_vertical_8_c, 8),
|
|
||||||
make_tuple(&vpx_lpf_vertical_16_sse2,
|
|
||||||
&vpx_lpf_vertical_16_c, 8),
|
|
||||||
make_tuple(&vpx_lpf_vertical_16_dual_sse2,
|
|
||||||
&vpx_lpf_vertical_16_dual_c, 8)));
|
|
||||||
#endif // CONFIG_VP9_HIGHBITDEPTH
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if HAVE_AVX2 && (!CONFIG_VP9_HIGHBITDEPTH)
|
|
||||||
INSTANTIATE_TEST_CASE_P(
|
|
||||||
AVX2, Loop8Test6Param,
|
|
||||||
::testing::Values(
|
|
||||||
make_tuple(&vpx_lpf_horizontal_edge_8_avx2,
|
|
||||||
&vpx_lpf_horizontal_edge_8_c, 8),
|
|
||||||
make_tuple(&vpx_lpf_horizontal_edge_16_avx2,
|
|
||||||
&vpx_lpf_horizontal_edge_16_c, 8)));
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if HAVE_SSE2
|
|
||||||
#if CONFIG_VP9_HIGHBITDEPTH
|
|
||||||
INSTANTIATE_TEST_CASE_P(
|
|
||||||
SSE2, Loop8Test9Param,
|
|
||||||
::testing::Values(
|
|
||||||
make_tuple(&vpx_highbd_lpf_horizontal_4_dual_sse2,
|
|
||||||
&vpx_highbd_lpf_horizontal_4_dual_c, 8),
|
|
||||||
make_tuple(&vpx_highbd_lpf_horizontal_8_dual_sse2,
|
|
||||||
&vpx_highbd_lpf_horizontal_8_dual_c, 8),
|
|
||||||
make_tuple(&vpx_highbd_lpf_vertical_4_dual_sse2,
|
|
||||||
&vpx_highbd_lpf_vertical_4_dual_c, 8),
|
|
||||||
make_tuple(&vpx_highbd_lpf_vertical_8_dual_sse2,
|
|
||||||
&vpx_highbd_lpf_vertical_8_dual_c, 8),
|
|
||||||
make_tuple(&vpx_highbd_lpf_horizontal_4_dual_sse2,
|
|
||||||
&vpx_highbd_lpf_horizontal_4_dual_c, 10),
|
|
||||||
make_tuple(&vpx_highbd_lpf_horizontal_8_dual_sse2,
|
|
||||||
&vpx_highbd_lpf_horizontal_8_dual_c, 10),
|
|
||||||
make_tuple(&vpx_highbd_lpf_vertical_4_dual_sse2,
|
|
||||||
&vpx_highbd_lpf_vertical_4_dual_c, 10),
|
|
||||||
make_tuple(&vpx_highbd_lpf_vertical_8_dual_sse2,
|
|
||||||
&vpx_highbd_lpf_vertical_8_dual_c, 10),
|
|
||||||
make_tuple(&vpx_highbd_lpf_horizontal_4_dual_sse2,
|
|
||||||
&vpx_highbd_lpf_horizontal_4_dual_c, 12),
|
|
||||||
make_tuple(&vpx_highbd_lpf_horizontal_8_dual_sse2,
|
|
||||||
&vpx_highbd_lpf_horizontal_8_dual_c, 12),
|
|
||||||
make_tuple(&vpx_highbd_lpf_vertical_4_dual_sse2,
|
|
||||||
&vpx_highbd_lpf_vertical_4_dual_c, 12),
|
|
||||||
make_tuple(&vpx_highbd_lpf_vertical_8_dual_sse2,
|
|
||||||
&vpx_highbd_lpf_vertical_8_dual_c, 12)));
|
|
||||||
#else
|
|
||||||
INSTANTIATE_TEST_CASE_P(
|
|
||||||
SSE2, Loop8Test9Param,
|
|
||||||
::testing::Values(
|
|
||||||
make_tuple(&vpx_lpf_horizontal_4_dual_sse2,
|
|
||||||
&vpx_lpf_horizontal_4_dual_c, 8),
|
|
||||||
make_tuple(&vpx_lpf_horizontal_8_dual_sse2,
|
|
||||||
&vpx_lpf_horizontal_8_dual_c, 8),
|
|
||||||
make_tuple(&vpx_lpf_vertical_4_dual_sse2,
|
|
||||||
&vpx_lpf_vertical_4_dual_c, 8),
|
|
||||||
make_tuple(&vpx_lpf_vertical_8_dual_sse2,
|
|
||||||
&vpx_lpf_vertical_8_dual_c, 8)));
|
|
||||||
#endif // CONFIG_VP9_HIGHBITDEPTH
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if HAVE_NEON
|
|
||||||
#if CONFIG_VP9_HIGHBITDEPTH
|
|
||||||
// No neon high bitdepth functions.
|
|
||||||
#else
|
|
||||||
INSTANTIATE_TEST_CASE_P(
|
|
||||||
NEON, Loop8Test6Param,
|
|
||||||
::testing::Values(
|
|
||||||
#if HAVE_NEON_ASM
|
|
||||||
// Using #if inside the macro is unsupported on MSVS but the tests are not
|
|
||||||
// currently built for MSVS with ARM and NEON.
|
|
||||||
make_tuple(&vpx_lpf_horizontal_edge_8_neon,
|
|
||||||
&vpx_lpf_horizontal_edge_8_c, 8),
|
|
||||||
make_tuple(&vpx_lpf_horizontal_edge_16_neon,
|
|
||||||
&vpx_lpf_horizontal_edge_16_c, 8),
|
|
||||||
make_tuple(&vpx_lpf_vertical_16_neon,
|
|
||||||
&vpx_lpf_vertical_16_c, 8),
|
|
||||||
make_tuple(&vpx_lpf_vertical_16_dual_neon,
|
|
||||||
&vpx_lpf_vertical_16_dual_c, 8),
|
|
||||||
#endif // HAVE_NEON_ASM
|
|
||||||
make_tuple(&vpx_lpf_horizontal_8_neon,
|
|
||||||
&vpx_lpf_horizontal_8_c, 8),
|
|
||||||
make_tuple(&vpx_lpf_vertical_8_neon,
|
|
||||||
&vpx_lpf_vertical_8_c, 8),
|
|
||||||
make_tuple(&vpx_lpf_horizontal_4_neon,
|
|
||||||
&vpx_lpf_horizontal_4_c, 8),
|
|
||||||
make_tuple(&vpx_lpf_vertical_4_neon,
|
|
||||||
&vpx_lpf_vertical_4_c, 8)));
|
|
||||||
INSTANTIATE_TEST_CASE_P(
|
|
||||||
NEON, Loop8Test9Param,
|
|
||||||
::testing::Values(
|
|
||||||
#if HAVE_NEON_ASM
|
|
||||||
make_tuple(&vpx_lpf_horizontal_8_dual_neon,
|
|
||||||
&vpx_lpf_horizontal_8_dual_c, 8),
|
|
||||||
make_tuple(&vpx_lpf_vertical_8_dual_neon,
|
|
||||||
&vpx_lpf_vertical_8_dual_c, 8),
|
|
||||||
#endif // HAVE_NEON_ASM
|
|
||||||
make_tuple(&vpx_lpf_horizontal_4_dual_neon,
|
|
||||||
&vpx_lpf_horizontal_4_dual_c, 8),
|
|
||||||
make_tuple(&vpx_lpf_vertical_4_dual_neon,
|
|
||||||
&vpx_lpf_vertical_4_dual_c, 8)));
|
|
||||||
#endif // CONFIG_VP9_HIGHBITDEPTH
|
|
||||||
#endif // HAVE_NEON
|
|
||||||
|
|
||||||
#if HAVE_DSPR2 && !CONFIG_VP9_HIGHBITDEPTH
|
|
||||||
INSTANTIATE_TEST_CASE_P(
|
|
||||||
DSPR2, Loop8Test6Param,
|
|
||||||
::testing::Values(
|
|
||||||
make_tuple(&vpx_lpf_horizontal_4_dspr2,
|
|
||||||
&vpx_lpf_horizontal_4_c, 8),
|
|
||||||
make_tuple(&vpx_lpf_horizontal_8_dspr2,
|
|
||||||
&vpx_lpf_horizontal_8_c, 8),
|
|
||||||
make_tuple(&vpx_lpf_horizontal_edge_8,
|
|
||||||
&vpx_lpf_horizontal_edge_8, 8),
|
|
||||||
make_tuple(&vpx_lpf_horizontal_edge_16,
|
|
||||||
&vpx_lpf_horizontal_edge_16, 8),
|
|
||||||
make_tuple(&vpx_lpf_vertical_4_dspr2,
|
|
||||||
&vpx_lpf_vertical_4_c, 8),
|
|
||||||
make_tuple(&vpx_lpf_vertical_8_dspr2,
|
|
||||||
&vpx_lpf_vertical_8_c, 8),
|
|
||||||
make_tuple(&vpx_lpf_vertical_16_dspr2,
|
|
||||||
&vpx_lpf_vertical_16_c, 8),
|
|
||||||
make_tuple(&vpx_lpf_vertical_16_dual_dspr2,
|
|
||||||
&vpx_lpf_vertical_16_dual_c, 8)));
|
|
||||||
|
|
||||||
INSTANTIATE_TEST_CASE_P(
|
|
||||||
DSPR2, Loop8Test9Param,
|
|
||||||
::testing::Values(
|
|
||||||
make_tuple(&vpx_lpf_horizontal_4_dual_dspr2,
|
|
||||||
&vpx_lpf_horizontal_4_dual_c, 8),
|
|
||||||
make_tuple(&vpx_lpf_horizontal_8_dual_dspr2,
|
|
||||||
&vpx_lpf_horizontal_8_dual_c, 8),
|
|
||||||
make_tuple(&vpx_lpf_vertical_4_dual_dspr2,
|
|
||||||
&vpx_lpf_vertical_4_dual_c, 8),
|
|
||||||
make_tuple(&vpx_lpf_vertical_8_dual_dspr2,
|
|
||||||
&vpx_lpf_vertical_8_dual_c, 8)));
|
|
||||||
#endif // HAVE_DSPR2 && !CONFIG_VP9_HIGHBITDEPTH
|
|
||||||
|
|
||||||
#if HAVE_MSA && (!CONFIG_VP9_HIGHBITDEPTH)
|
|
||||||
INSTANTIATE_TEST_CASE_P(
|
|
||||||
MSA, Loop8Test6Param,
|
|
||||||
::testing::Values(
|
|
||||||
make_tuple(&vpx_lpf_horizontal_4_msa,
|
|
||||||
&vpx_lpf_horizontal_4_c, 8),
|
|
||||||
make_tuple(&vpx_lpf_horizontal_8_msa,
|
|
||||||
&vpx_lpf_horizontal_8_c, 8),
|
|
||||||
make_tuple(&vpx_lpf_horizontal_edge_8_msa,
|
|
||||||
&vpx_lpf_horizontal_edge_8_c, 8),
|
|
||||||
make_tuple(&vpx_lpf_horizontal_edge_16_msa,
|
|
||||||
&vpx_lpf_horizontal_edge_16_c, 8),
|
|
||||||
make_tuple(&vpx_lpf_vertical_4_msa,
|
|
||||||
&vpx_lpf_vertical_4_c, 8),
|
|
||||||
make_tuple(&vpx_lpf_vertical_8_msa,
|
|
||||||
&vpx_lpf_vertical_8_c, 8),
|
|
||||||
make_tuple(&vpx_lpf_vertical_16_msa,
|
|
||||||
&vpx_lpf_vertical_16_c, 8)));
|
|
||||||
|
|
||||||
INSTANTIATE_TEST_CASE_P(
|
|
||||||
MSA, Loop8Test9Param,
|
|
||||||
::testing::Values(
|
|
||||||
make_tuple(&vpx_lpf_horizontal_4_dual_msa,
|
|
||||||
&vpx_lpf_horizontal_4_dual_c, 8),
|
|
||||||
make_tuple(&vpx_lpf_horizontal_8_dual_msa,
|
|
||||||
&vpx_lpf_horizontal_8_dual_c, 8),
|
|
||||||
make_tuple(&vpx_lpf_vertical_4_dual_msa,
|
|
||||||
&vpx_lpf_vertical_4_dual_c, 8),
|
|
||||||
make_tuple(&vpx_lpf_vertical_8_dual_msa,
|
|
||||||
&vpx_lpf_vertical_8_dual_c, 8)));
|
|
||||||
#endif // HAVE_MSA && (!CONFIG_VP9_HIGHBITDEPTH)
|
|
||||||
|
|
||||||
} // namespace
|
|
||||||
672
test/lpf_test.cc
Normal file
672
test/lpf_test.cc
Normal file
@@ -0,0 +1,672 @@
|
|||||||
|
/*
|
||||||
|
* 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 <cmath>
|
||||||
|
#include <cstdlib>
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
#include "third_party/googletest/src/include/gtest/gtest.h"
|
||||||
|
|
||||||
|
#include "./vpx_config.h"
|
||||||
|
#include "./vpx_dsp_rtcd.h"
|
||||||
|
#include "test/acm_random.h"
|
||||||
|
#include "test/clear_system_state.h"
|
||||||
|
#include "test/register_state_check.h"
|
||||||
|
#include "test/util.h"
|
||||||
|
#include "vp9/common/vp9_entropy.h"
|
||||||
|
#include "vp9/common/vp9_loopfilter.h"
|
||||||
|
#include "vpx/vpx_integer.h"
|
||||||
|
|
||||||
|
using libvpx_test::ACMRandom;
|
||||||
|
|
||||||
|
namespace {
|
||||||
|
// Horizontally and Vertically need 32x32: 8 Coeffs preceeding filtered section
|
||||||
|
// 16 Coefs within filtered section
|
||||||
|
// 8 Coeffs following filtered section
|
||||||
|
const int kNumCoeffs = 1024;
|
||||||
|
|
||||||
|
const int number_of_iterations = 10000;
|
||||||
|
|
||||||
|
#if CONFIG_VP9_HIGHBITDEPTH
|
||||||
|
typedef uint16_t Pixel;
|
||||||
|
#define PIXEL_WIDTH 16
|
||||||
|
|
||||||
|
typedef void (*loop_op_t)(Pixel *s, int p, const uint8_t *blimit,
|
||||||
|
const uint8_t *limit, const uint8_t *thresh, int bd);
|
||||||
|
typedef void (*dual_loop_op_t)(Pixel *s, int p, const uint8_t *blimit0,
|
||||||
|
const uint8_t *limit0, const uint8_t *thresh0,
|
||||||
|
const uint8_t *blimit1, const uint8_t *limit1,
|
||||||
|
const uint8_t *thresh1, int bd);
|
||||||
|
#else
|
||||||
|
typedef uint8_t Pixel;
|
||||||
|
#define PIXEL_WIDTH 8
|
||||||
|
|
||||||
|
typedef void (*loop_op_t)(Pixel *s, int p, const uint8_t *blimit,
|
||||||
|
const uint8_t *limit, const uint8_t *thresh);
|
||||||
|
typedef void (*dual_loop_op_t)(Pixel *s, int p, const uint8_t *blimit0,
|
||||||
|
const uint8_t *limit0, const uint8_t *thresh0,
|
||||||
|
const uint8_t *blimit1, const uint8_t *limit1,
|
||||||
|
const uint8_t *thresh1);
|
||||||
|
#endif // CONFIG_VP9_HIGHBITDEPTH
|
||||||
|
|
||||||
|
typedef std::tr1::tuple<loop_op_t, loop_op_t, int> loop8_param_t;
|
||||||
|
typedef std::tr1::tuple<dual_loop_op_t, dual_loop_op_t, int> dualloop8_param_t;
|
||||||
|
|
||||||
|
void InitInput(Pixel *s, Pixel *ref_s, ACMRandom *rnd, const uint8_t limit,
|
||||||
|
const int mask, const int32_t p, const int i) {
|
||||||
|
uint16_t tmp_s[kNumCoeffs];
|
||||||
|
|
||||||
|
for (int j = 0; j < kNumCoeffs;) {
|
||||||
|
const uint8_t val = rnd->Rand8();
|
||||||
|
if (val & 0x80) { // 50% chance to choose a new value.
|
||||||
|
tmp_s[j] = rnd->Rand16();
|
||||||
|
j++;
|
||||||
|
} else { // 50% chance to repeat previous value in row X times.
|
||||||
|
int k = 0;
|
||||||
|
while (k++ < ((val & 0x1f) + 1) && j < kNumCoeffs) {
|
||||||
|
if (j < 1) {
|
||||||
|
tmp_s[j] = rnd->Rand16();
|
||||||
|
} else if (val & 0x20) { // Increment by a value within the limit.
|
||||||
|
tmp_s[j] = tmp_s[j - 1] + (limit - 1);
|
||||||
|
} else { // Decrement by a value within the limit.
|
||||||
|
tmp_s[j] = tmp_s[j - 1] - (limit - 1);
|
||||||
|
}
|
||||||
|
j++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int j = 0; j < kNumCoeffs;) {
|
||||||
|
const uint8_t val = rnd->Rand8();
|
||||||
|
if (val & 0x80) {
|
||||||
|
j++;
|
||||||
|
} else { // 50% chance to repeat previous value in column X times.
|
||||||
|
int k = 0;
|
||||||
|
while (k++ < ((val & 0x1f) + 1) && j < kNumCoeffs) {
|
||||||
|
if (j < 1) {
|
||||||
|
tmp_s[j] = rnd->Rand16();
|
||||||
|
} else if (val & 0x20) { // Increment by a value within the limit.
|
||||||
|
tmp_s[(j % 32) * 32 + j / 32] =
|
||||||
|
tmp_s[((j - 1) % 32) * 32 + (j - 1) / 32] + (limit - 1);
|
||||||
|
} else { // Decrement by a value within the limit.
|
||||||
|
tmp_s[(j % 32) * 32 + j / 32] =
|
||||||
|
tmp_s[((j - 1) % 32) * 32 + (j - 1) / 32] - (limit - 1);
|
||||||
|
}
|
||||||
|
j++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int j = 0; j < kNumCoeffs; j++) {
|
||||||
|
if (i % 2) {
|
||||||
|
s[j] = tmp_s[j] & mask;
|
||||||
|
} else {
|
||||||
|
s[j] = tmp_s[p * (j % p) + j / p] & mask;
|
||||||
|
}
|
||||||
|
ref_s[j] = s[j];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class Loop8Test6Param : public ::testing::TestWithParam<loop8_param_t> {
|
||||||
|
public:
|
||||||
|
virtual ~Loop8Test6Param() {}
|
||||||
|
virtual void SetUp() {
|
||||||
|
loopfilter_op_ = GET_PARAM(0);
|
||||||
|
ref_loopfilter_op_ = GET_PARAM(1);
|
||||||
|
bit_depth_ = GET_PARAM(2);
|
||||||
|
mask_ = (1 << bit_depth_) - 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual void TearDown() { libvpx_test::ClearSystemState(); }
|
||||||
|
|
||||||
|
protected:
|
||||||
|
int bit_depth_;
|
||||||
|
int mask_;
|
||||||
|
loop_op_t loopfilter_op_;
|
||||||
|
loop_op_t ref_loopfilter_op_;
|
||||||
|
};
|
||||||
|
|
||||||
|
class Loop8Test9Param : public ::testing::TestWithParam<dualloop8_param_t> {
|
||||||
|
public:
|
||||||
|
virtual ~Loop8Test9Param() {}
|
||||||
|
virtual void SetUp() {
|
||||||
|
loopfilter_op_ = GET_PARAM(0);
|
||||||
|
ref_loopfilter_op_ = GET_PARAM(1);
|
||||||
|
bit_depth_ = GET_PARAM(2);
|
||||||
|
mask_ = (1 << bit_depth_) - 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual void TearDown() { libvpx_test::ClearSystemState(); }
|
||||||
|
|
||||||
|
protected:
|
||||||
|
int bit_depth_;
|
||||||
|
int mask_;
|
||||||
|
dual_loop_op_t loopfilter_op_;
|
||||||
|
dual_loop_op_t ref_loopfilter_op_;
|
||||||
|
};
|
||||||
|
|
||||||
|
TEST_P(Loop8Test6Param, OperationCheck) {
|
||||||
|
ACMRandom rnd(ACMRandom::DeterministicSeed());
|
||||||
|
const int count_test_block = number_of_iterations;
|
||||||
|
const int32_t p = kNumCoeffs / 32;
|
||||||
|
DECLARE_ALIGNED(PIXEL_WIDTH, Pixel, s[kNumCoeffs]);
|
||||||
|
DECLARE_ALIGNED(PIXEL_WIDTH, Pixel, ref_s[kNumCoeffs]);
|
||||||
|
int err_count_total = 0;
|
||||||
|
int first_failure = -1;
|
||||||
|
for (int i = 0; i < count_test_block; ++i) {
|
||||||
|
int err_count = 0;
|
||||||
|
uint8_t tmp = static_cast<uint8_t>(rnd(3 * MAX_LOOP_FILTER + 4));
|
||||||
|
DECLARE_ALIGNED(16, const uint8_t,
|
||||||
|
blimit[16]) = { tmp, tmp, tmp, tmp, tmp, tmp, tmp, tmp,
|
||||||
|
tmp, tmp, tmp, tmp, tmp, tmp, tmp, tmp };
|
||||||
|
tmp = static_cast<uint8_t>(rnd(MAX_LOOP_FILTER));
|
||||||
|
DECLARE_ALIGNED(16, const uint8_t,
|
||||||
|
limit[16]) = { tmp, tmp, tmp, tmp, tmp, tmp, tmp, tmp,
|
||||||
|
tmp, tmp, tmp, tmp, tmp, tmp, tmp, tmp };
|
||||||
|
tmp = rnd.Rand8();
|
||||||
|
DECLARE_ALIGNED(16, const uint8_t,
|
||||||
|
thresh[16]) = { tmp, tmp, tmp, tmp, tmp, tmp, tmp, tmp,
|
||||||
|
tmp, tmp, tmp, tmp, tmp, tmp, tmp, tmp };
|
||||||
|
InitInput(s, ref_s, &rnd, *limit, mask_, p, i);
|
||||||
|
#if CONFIG_VP9_HIGHBITDEPTH
|
||||||
|
ref_loopfilter_op_(ref_s + 8 + p * 8, p, blimit, limit, thresh, bit_depth_);
|
||||||
|
ASM_REGISTER_STATE_CHECK(
|
||||||
|
loopfilter_op_(s + 8 + p * 8, p, blimit, limit, thresh, bit_depth_));
|
||||||
|
#else
|
||||||
|
ref_loopfilter_op_(ref_s + 8 + p * 8, p, blimit, limit, thresh);
|
||||||
|
ASM_REGISTER_STATE_CHECK(
|
||||||
|
loopfilter_op_(s + 8 + p * 8, p, blimit, limit, thresh));
|
||||||
|
#endif // CONFIG_VP9_HIGHBITDEPTH
|
||||||
|
|
||||||
|
for (int j = 0; j < kNumCoeffs; ++j) {
|
||||||
|
err_count += ref_s[j] != s[j];
|
||||||
|
}
|
||||||
|
if (err_count && !err_count_total) {
|
||||||
|
first_failure = i;
|
||||||
|
}
|
||||||
|
err_count_total += err_count;
|
||||||
|
}
|
||||||
|
EXPECT_EQ(0, err_count_total)
|
||||||
|
<< "Error: Loop8Test6Param, C output doesn't match SSE2 "
|
||||||
|
"loopfilter output. "
|
||||||
|
<< "First failed at test case " << first_failure;
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_P(Loop8Test6Param, ValueCheck) {
|
||||||
|
ACMRandom rnd(ACMRandom::DeterministicSeed());
|
||||||
|
const int count_test_block = number_of_iterations;
|
||||||
|
DECLARE_ALIGNED(PIXEL_WIDTH, Pixel, s[kNumCoeffs]);
|
||||||
|
DECLARE_ALIGNED(PIXEL_WIDTH, Pixel, ref_s[kNumCoeffs]);
|
||||||
|
int err_count_total = 0;
|
||||||
|
int first_failure = -1;
|
||||||
|
|
||||||
|
// NOTE: The code in vp9_loopfilter.c:update_sharpness computes mblim as a
|
||||||
|
// function of sharpness_lvl and the loopfilter lvl as:
|
||||||
|
// block_inside_limit = lvl >> ((sharpness_lvl > 0) + (sharpness_lvl > 4));
|
||||||
|
// ...
|
||||||
|
// memset(lfi->lfthr[lvl].mblim, (2 * (lvl + 2) + block_inside_limit),
|
||||||
|
// SIMD_WIDTH);
|
||||||
|
// This means that the largest value for mblim will occur when sharpness_lvl
|
||||||
|
// is equal to 0, and lvl is equal to its greatest value (MAX_LOOP_FILTER).
|
||||||
|
// In this case block_inside_limit will be equal to MAX_LOOP_FILTER and
|
||||||
|
// therefore mblim will be equal to (2 * (lvl + 2) + block_inside_limit) =
|
||||||
|
// 2 * (MAX_LOOP_FILTER + 2) + MAX_LOOP_FILTER = 3 * MAX_LOOP_FILTER + 4
|
||||||
|
|
||||||
|
for (int i = 0; i < count_test_block; ++i) {
|
||||||
|
int err_count = 0;
|
||||||
|
uint8_t tmp = static_cast<uint8_t>(rnd(3 * MAX_LOOP_FILTER + 4));
|
||||||
|
DECLARE_ALIGNED(16, const uint8_t,
|
||||||
|
blimit[16]) = { tmp, tmp, tmp, tmp, tmp, tmp, tmp, tmp,
|
||||||
|
tmp, tmp, tmp, tmp, tmp, tmp, tmp, tmp };
|
||||||
|
tmp = static_cast<uint8_t>(rnd(MAX_LOOP_FILTER));
|
||||||
|
DECLARE_ALIGNED(16, const uint8_t,
|
||||||
|
limit[16]) = { tmp, tmp, tmp, tmp, tmp, tmp, tmp, tmp,
|
||||||
|
tmp, tmp, tmp, tmp, tmp, tmp, tmp, tmp };
|
||||||
|
tmp = rnd.Rand8();
|
||||||
|
DECLARE_ALIGNED(16, const uint8_t,
|
||||||
|
thresh[16]) = { tmp, tmp, tmp, tmp, tmp, tmp, tmp, tmp,
|
||||||
|
tmp, tmp, tmp, tmp, tmp, tmp, tmp, tmp };
|
||||||
|
int32_t p = kNumCoeffs / 32;
|
||||||
|
for (int j = 0; j < kNumCoeffs; ++j) {
|
||||||
|
s[j] = rnd.Rand16() & mask_;
|
||||||
|
ref_s[j] = s[j];
|
||||||
|
}
|
||||||
|
#if CONFIG_VP9_HIGHBITDEPTH
|
||||||
|
ref_loopfilter_op_(ref_s + 8 + p * 8, p, blimit, limit, thresh, bit_depth_);
|
||||||
|
ASM_REGISTER_STATE_CHECK(
|
||||||
|
loopfilter_op_(s + 8 + p * 8, p, blimit, limit, thresh, bit_depth_));
|
||||||
|
#else
|
||||||
|
ref_loopfilter_op_(ref_s + 8 + p * 8, p, blimit, limit, thresh);
|
||||||
|
ASM_REGISTER_STATE_CHECK(
|
||||||
|
loopfilter_op_(s + 8 + p * 8, p, blimit, limit, thresh));
|
||||||
|
#endif // CONFIG_VP9_HIGHBITDEPTH
|
||||||
|
|
||||||
|
for (int j = 0; j < kNumCoeffs; ++j) {
|
||||||
|
err_count += ref_s[j] != s[j];
|
||||||
|
}
|
||||||
|
if (err_count && !err_count_total) {
|
||||||
|
first_failure = i;
|
||||||
|
}
|
||||||
|
err_count_total += err_count;
|
||||||
|
}
|
||||||
|
EXPECT_EQ(0, err_count_total)
|
||||||
|
<< "Error: Loop8Test6Param, C output doesn't match SSE2 "
|
||||||
|
"loopfilter output. "
|
||||||
|
<< "First failed at test case " << first_failure;
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_P(Loop8Test9Param, OperationCheck) {
|
||||||
|
ACMRandom rnd(ACMRandom::DeterministicSeed());
|
||||||
|
const int count_test_block = number_of_iterations;
|
||||||
|
DECLARE_ALIGNED(PIXEL_WIDTH, Pixel, s[kNumCoeffs]);
|
||||||
|
DECLARE_ALIGNED(PIXEL_WIDTH, Pixel, ref_s[kNumCoeffs]);
|
||||||
|
int err_count_total = 0;
|
||||||
|
int first_failure = -1;
|
||||||
|
for (int i = 0; i < count_test_block; ++i) {
|
||||||
|
int err_count = 0;
|
||||||
|
uint8_t tmp = static_cast<uint8_t>(rnd(3 * MAX_LOOP_FILTER + 4));
|
||||||
|
DECLARE_ALIGNED(16, const uint8_t,
|
||||||
|
blimit0[16]) = { tmp, tmp, tmp, tmp, tmp, tmp, tmp, tmp,
|
||||||
|
tmp, tmp, tmp, tmp, tmp, tmp, tmp, tmp };
|
||||||
|
tmp = static_cast<uint8_t>(rnd(MAX_LOOP_FILTER));
|
||||||
|
DECLARE_ALIGNED(16, const uint8_t,
|
||||||
|
limit0[16]) = { tmp, tmp, tmp, tmp, tmp, tmp, tmp, tmp,
|
||||||
|
tmp, tmp, tmp, tmp, tmp, tmp, tmp, tmp };
|
||||||
|
tmp = rnd.Rand8();
|
||||||
|
DECLARE_ALIGNED(16, const uint8_t,
|
||||||
|
thresh0[16]) = { tmp, tmp, tmp, tmp, tmp, tmp, tmp, tmp,
|
||||||
|
tmp, tmp, tmp, tmp, tmp, tmp, tmp, tmp };
|
||||||
|
tmp = static_cast<uint8_t>(rnd(3 * MAX_LOOP_FILTER + 4));
|
||||||
|
DECLARE_ALIGNED(16, const uint8_t,
|
||||||
|
blimit1[16]) = { tmp, tmp, tmp, tmp, tmp, tmp, tmp, tmp,
|
||||||
|
tmp, tmp, tmp, tmp, tmp, tmp, tmp, tmp };
|
||||||
|
tmp = static_cast<uint8_t>(rnd(MAX_LOOP_FILTER));
|
||||||
|
DECLARE_ALIGNED(16, const uint8_t,
|
||||||
|
limit1[16]) = { tmp, tmp, tmp, tmp, tmp, tmp, tmp, tmp,
|
||||||
|
tmp, tmp, tmp, tmp, tmp, tmp, tmp, tmp };
|
||||||
|
tmp = rnd.Rand8();
|
||||||
|
DECLARE_ALIGNED(16, const uint8_t,
|
||||||
|
thresh1[16]) = { tmp, tmp, tmp, tmp, tmp, tmp, tmp, tmp,
|
||||||
|
tmp, tmp, tmp, tmp, tmp, tmp, tmp, tmp };
|
||||||
|
int32_t p = kNumCoeffs / 32;
|
||||||
|
const uint8_t limit = *limit0 < *limit1 ? *limit0 : *limit1;
|
||||||
|
InitInput(s, ref_s, &rnd, limit, mask_, p, i);
|
||||||
|
#if CONFIG_VP9_HIGHBITDEPTH
|
||||||
|
ref_loopfilter_op_(ref_s + 8 + p * 8, p, blimit0, limit0, thresh0, blimit1,
|
||||||
|
limit1, thresh1, bit_depth_);
|
||||||
|
ASM_REGISTER_STATE_CHECK(loopfilter_op_(s + 8 + p * 8, p, blimit0, limit0,
|
||||||
|
thresh0, blimit1, limit1, thresh1,
|
||||||
|
bit_depth_));
|
||||||
|
#else
|
||||||
|
ref_loopfilter_op_(ref_s + 8 + p * 8, p, blimit0, limit0, thresh0, blimit1,
|
||||||
|
limit1, thresh1);
|
||||||
|
ASM_REGISTER_STATE_CHECK(loopfilter_op_(s + 8 + p * 8, p, blimit0, limit0,
|
||||||
|
thresh0, blimit1, limit1, thresh1));
|
||||||
|
#endif // CONFIG_VP9_HIGHBITDEPTH
|
||||||
|
|
||||||
|
for (int j = 0; j < kNumCoeffs; ++j) {
|
||||||
|
err_count += ref_s[j] != s[j];
|
||||||
|
}
|
||||||
|
if (err_count && !err_count_total) {
|
||||||
|
first_failure = i;
|
||||||
|
}
|
||||||
|
err_count_total += err_count;
|
||||||
|
}
|
||||||
|
EXPECT_EQ(0, err_count_total)
|
||||||
|
<< "Error: Loop8Test9Param, C output doesn't match SSE2 "
|
||||||
|
"loopfilter output. "
|
||||||
|
<< "First failed at test case " << first_failure;
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_P(Loop8Test9Param, ValueCheck) {
|
||||||
|
ACMRandom rnd(ACMRandom::DeterministicSeed());
|
||||||
|
const int count_test_block = number_of_iterations;
|
||||||
|
DECLARE_ALIGNED(PIXEL_WIDTH, Pixel, s[kNumCoeffs]);
|
||||||
|
DECLARE_ALIGNED(PIXEL_WIDTH, Pixel, ref_s[kNumCoeffs]);
|
||||||
|
int err_count_total = 0;
|
||||||
|
int first_failure = -1;
|
||||||
|
for (int i = 0; i < count_test_block; ++i) {
|
||||||
|
int err_count = 0;
|
||||||
|
uint8_t tmp = static_cast<uint8_t>(rnd(3 * MAX_LOOP_FILTER + 4));
|
||||||
|
DECLARE_ALIGNED(16, const uint8_t,
|
||||||
|
blimit0[16]) = { tmp, tmp, tmp, tmp, tmp, tmp, tmp, tmp,
|
||||||
|
tmp, tmp, tmp, tmp, tmp, tmp, tmp, tmp };
|
||||||
|
tmp = static_cast<uint8_t>(rnd(MAX_LOOP_FILTER));
|
||||||
|
DECLARE_ALIGNED(16, const uint8_t,
|
||||||
|
limit0[16]) = { tmp, tmp, tmp, tmp, tmp, tmp, tmp, tmp,
|
||||||
|
tmp, tmp, tmp, tmp, tmp, tmp, tmp, tmp };
|
||||||
|
tmp = rnd.Rand8();
|
||||||
|
DECLARE_ALIGNED(16, const uint8_t,
|
||||||
|
thresh0[16]) = { tmp, tmp, tmp, tmp, tmp, tmp, tmp, tmp,
|
||||||
|
tmp, tmp, tmp, tmp, tmp, tmp, tmp, tmp };
|
||||||
|
tmp = static_cast<uint8_t>(rnd(3 * MAX_LOOP_FILTER + 4));
|
||||||
|
DECLARE_ALIGNED(16, const uint8_t,
|
||||||
|
blimit1[16]) = { tmp, tmp, tmp, tmp, tmp, tmp, tmp, tmp,
|
||||||
|
tmp, tmp, tmp, tmp, tmp, tmp, tmp, tmp };
|
||||||
|
tmp = static_cast<uint8_t>(rnd(MAX_LOOP_FILTER));
|
||||||
|
DECLARE_ALIGNED(16, const uint8_t,
|
||||||
|
limit1[16]) = { tmp, tmp, tmp, tmp, tmp, tmp, tmp, tmp,
|
||||||
|
tmp, tmp, tmp, tmp, tmp, tmp, tmp, tmp };
|
||||||
|
tmp = rnd.Rand8();
|
||||||
|
DECLARE_ALIGNED(16, const uint8_t,
|
||||||
|
thresh1[16]) = { tmp, tmp, tmp, tmp, tmp, tmp, tmp, tmp,
|
||||||
|
tmp, tmp, tmp, tmp, tmp, tmp, tmp, tmp };
|
||||||
|
int32_t p = kNumCoeffs / 32; // TODO(pdlf) can we have non-square here?
|
||||||
|
for (int j = 0; j < kNumCoeffs; ++j) {
|
||||||
|
s[j] = rnd.Rand16() & mask_;
|
||||||
|
ref_s[j] = s[j];
|
||||||
|
}
|
||||||
|
#if CONFIG_VP9_HIGHBITDEPTH
|
||||||
|
ref_loopfilter_op_(ref_s + 8 + p * 8, p, blimit0, limit0, thresh0, blimit1,
|
||||||
|
limit1, thresh1, bit_depth_);
|
||||||
|
ASM_REGISTER_STATE_CHECK(loopfilter_op_(s + 8 + p * 8, p, blimit0, limit0,
|
||||||
|
thresh0, blimit1, limit1, thresh1,
|
||||||
|
bit_depth_));
|
||||||
|
#else
|
||||||
|
ref_loopfilter_op_(ref_s + 8 + p * 8, p, blimit0, limit0, thresh0, blimit1,
|
||||||
|
limit1, thresh1);
|
||||||
|
ASM_REGISTER_STATE_CHECK(loopfilter_op_(s + 8 + p * 8, p, blimit0, limit0,
|
||||||
|
thresh0, blimit1, limit1, thresh1));
|
||||||
|
#endif // CONFIG_VP9_HIGHBITDEPTH
|
||||||
|
|
||||||
|
for (int j = 0; j < kNumCoeffs; ++j) {
|
||||||
|
err_count += ref_s[j] != s[j];
|
||||||
|
}
|
||||||
|
if (err_count && !err_count_total) {
|
||||||
|
first_failure = i;
|
||||||
|
}
|
||||||
|
err_count_total += err_count;
|
||||||
|
}
|
||||||
|
EXPECT_EQ(0, err_count_total)
|
||||||
|
<< "Error: Loop8Test9Param, C output doesn't match SSE2"
|
||||||
|
"loopfilter output. "
|
||||||
|
<< "First failed at test case " << first_failure;
|
||||||
|
}
|
||||||
|
|
||||||
|
using std::tr1::make_tuple;
|
||||||
|
|
||||||
|
#if HAVE_SSE2
|
||||||
|
#if CONFIG_VP9_HIGHBITDEPTH
|
||||||
|
INSTANTIATE_TEST_CASE_P(
|
||||||
|
SSE2, Loop8Test6Param,
|
||||||
|
::testing::Values(make_tuple(&vpx_highbd_lpf_horizontal_4_sse2,
|
||||||
|
&vpx_highbd_lpf_horizontal_4_c, 8),
|
||||||
|
make_tuple(&vpx_highbd_lpf_vertical_4_sse2,
|
||||||
|
&vpx_highbd_lpf_vertical_4_c, 8),
|
||||||
|
make_tuple(&vpx_highbd_lpf_horizontal_8_sse2,
|
||||||
|
&vpx_highbd_lpf_horizontal_8_c, 8),
|
||||||
|
make_tuple(&vpx_highbd_lpf_horizontal_16_sse2,
|
||||||
|
&vpx_highbd_lpf_horizontal_16_c, 8),
|
||||||
|
make_tuple(&vpx_highbd_lpf_horizontal_16_dual_sse2,
|
||||||
|
&vpx_highbd_lpf_horizontal_16_dual_c, 8),
|
||||||
|
make_tuple(&vpx_highbd_lpf_vertical_8_sse2,
|
||||||
|
&vpx_highbd_lpf_vertical_8_c, 8),
|
||||||
|
make_tuple(&vpx_highbd_lpf_vertical_16_sse2,
|
||||||
|
&vpx_highbd_lpf_vertical_16_c, 8),
|
||||||
|
make_tuple(&vpx_highbd_lpf_horizontal_4_sse2,
|
||||||
|
&vpx_highbd_lpf_horizontal_4_c, 10),
|
||||||
|
make_tuple(&vpx_highbd_lpf_vertical_4_sse2,
|
||||||
|
&vpx_highbd_lpf_vertical_4_c, 10),
|
||||||
|
make_tuple(&vpx_highbd_lpf_horizontal_8_sse2,
|
||||||
|
&vpx_highbd_lpf_horizontal_8_c, 10),
|
||||||
|
make_tuple(&vpx_highbd_lpf_horizontal_16_sse2,
|
||||||
|
&vpx_highbd_lpf_horizontal_16_c, 10),
|
||||||
|
make_tuple(&vpx_highbd_lpf_horizontal_16_dual_sse2,
|
||||||
|
&vpx_highbd_lpf_horizontal_16_dual_c, 10),
|
||||||
|
make_tuple(&vpx_highbd_lpf_vertical_8_sse2,
|
||||||
|
&vpx_highbd_lpf_vertical_8_c, 10),
|
||||||
|
make_tuple(&vpx_highbd_lpf_vertical_16_sse2,
|
||||||
|
&vpx_highbd_lpf_vertical_16_c, 10),
|
||||||
|
make_tuple(&vpx_highbd_lpf_horizontal_4_sse2,
|
||||||
|
&vpx_highbd_lpf_horizontal_4_c, 12),
|
||||||
|
make_tuple(&vpx_highbd_lpf_vertical_4_sse2,
|
||||||
|
&vpx_highbd_lpf_vertical_4_c, 12),
|
||||||
|
make_tuple(&vpx_highbd_lpf_horizontal_8_sse2,
|
||||||
|
&vpx_highbd_lpf_horizontal_8_c, 12),
|
||||||
|
make_tuple(&vpx_highbd_lpf_horizontal_16_sse2,
|
||||||
|
&vpx_highbd_lpf_horizontal_16_c, 12),
|
||||||
|
make_tuple(&vpx_highbd_lpf_horizontal_16_dual_sse2,
|
||||||
|
&vpx_highbd_lpf_horizontal_16_dual_c, 12),
|
||||||
|
make_tuple(&vpx_highbd_lpf_vertical_8_sse2,
|
||||||
|
&vpx_highbd_lpf_vertical_8_c, 12),
|
||||||
|
make_tuple(&vpx_highbd_lpf_vertical_16_sse2,
|
||||||
|
&vpx_highbd_lpf_vertical_16_c, 12),
|
||||||
|
make_tuple(&vpx_highbd_lpf_vertical_16_dual_sse2,
|
||||||
|
&vpx_highbd_lpf_vertical_16_dual_c, 8),
|
||||||
|
make_tuple(&vpx_highbd_lpf_vertical_16_dual_sse2,
|
||||||
|
&vpx_highbd_lpf_vertical_16_dual_c, 10),
|
||||||
|
make_tuple(&vpx_highbd_lpf_vertical_16_dual_sse2,
|
||||||
|
&vpx_highbd_lpf_vertical_16_dual_c, 12)));
|
||||||
|
#else
|
||||||
|
INSTANTIATE_TEST_CASE_P(
|
||||||
|
SSE2, Loop8Test6Param,
|
||||||
|
::testing::Values(
|
||||||
|
make_tuple(&vpx_lpf_horizontal_4_sse2, &vpx_lpf_horizontal_4_c, 8),
|
||||||
|
make_tuple(&vpx_lpf_horizontal_8_sse2, &vpx_lpf_horizontal_8_c, 8),
|
||||||
|
make_tuple(&vpx_lpf_horizontal_16_sse2, &vpx_lpf_horizontal_16_c, 8),
|
||||||
|
make_tuple(&vpx_lpf_horizontal_16_dual_sse2,
|
||||||
|
&vpx_lpf_horizontal_16_dual_c, 8),
|
||||||
|
make_tuple(&vpx_lpf_vertical_4_sse2, &vpx_lpf_vertical_4_c, 8),
|
||||||
|
make_tuple(&vpx_lpf_vertical_8_sse2, &vpx_lpf_vertical_8_c, 8),
|
||||||
|
make_tuple(&vpx_lpf_vertical_16_sse2, &vpx_lpf_vertical_16_c, 8),
|
||||||
|
make_tuple(&vpx_lpf_vertical_16_dual_sse2, &vpx_lpf_vertical_16_dual_c,
|
||||||
|
8)));
|
||||||
|
#endif // CONFIG_VP9_HIGHBITDEPTH
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if HAVE_AVX2 && (!CONFIG_VP9_HIGHBITDEPTH)
|
||||||
|
INSTANTIATE_TEST_CASE_P(
|
||||||
|
AVX2, Loop8Test6Param,
|
||||||
|
::testing::Values(make_tuple(&vpx_lpf_horizontal_16_avx2,
|
||||||
|
&vpx_lpf_horizontal_16_c, 8),
|
||||||
|
make_tuple(&vpx_lpf_horizontal_16_dual_avx2,
|
||||||
|
&vpx_lpf_horizontal_16_dual_c, 8)));
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if HAVE_SSE2
|
||||||
|
#if CONFIG_VP9_HIGHBITDEPTH
|
||||||
|
INSTANTIATE_TEST_CASE_P(
|
||||||
|
SSE2, Loop8Test9Param,
|
||||||
|
::testing::Values(make_tuple(&vpx_highbd_lpf_horizontal_4_dual_sse2,
|
||||||
|
&vpx_highbd_lpf_horizontal_4_dual_c, 8),
|
||||||
|
make_tuple(&vpx_highbd_lpf_horizontal_8_dual_sse2,
|
||||||
|
&vpx_highbd_lpf_horizontal_8_dual_c, 8),
|
||||||
|
make_tuple(&vpx_highbd_lpf_vertical_4_dual_sse2,
|
||||||
|
&vpx_highbd_lpf_vertical_4_dual_c, 8),
|
||||||
|
make_tuple(&vpx_highbd_lpf_vertical_8_dual_sse2,
|
||||||
|
&vpx_highbd_lpf_vertical_8_dual_c, 8),
|
||||||
|
make_tuple(&vpx_highbd_lpf_horizontal_4_dual_sse2,
|
||||||
|
&vpx_highbd_lpf_horizontal_4_dual_c, 10),
|
||||||
|
make_tuple(&vpx_highbd_lpf_horizontal_8_dual_sse2,
|
||||||
|
&vpx_highbd_lpf_horizontal_8_dual_c, 10),
|
||||||
|
make_tuple(&vpx_highbd_lpf_vertical_4_dual_sse2,
|
||||||
|
&vpx_highbd_lpf_vertical_4_dual_c, 10),
|
||||||
|
make_tuple(&vpx_highbd_lpf_vertical_8_dual_sse2,
|
||||||
|
&vpx_highbd_lpf_vertical_8_dual_c, 10),
|
||||||
|
make_tuple(&vpx_highbd_lpf_horizontal_4_dual_sse2,
|
||||||
|
&vpx_highbd_lpf_horizontal_4_dual_c, 12),
|
||||||
|
make_tuple(&vpx_highbd_lpf_horizontal_8_dual_sse2,
|
||||||
|
&vpx_highbd_lpf_horizontal_8_dual_c, 12),
|
||||||
|
make_tuple(&vpx_highbd_lpf_vertical_4_dual_sse2,
|
||||||
|
&vpx_highbd_lpf_vertical_4_dual_c, 12),
|
||||||
|
make_tuple(&vpx_highbd_lpf_vertical_8_dual_sse2,
|
||||||
|
&vpx_highbd_lpf_vertical_8_dual_c, 12)));
|
||||||
|
#else
|
||||||
|
INSTANTIATE_TEST_CASE_P(
|
||||||
|
SSE2, Loop8Test9Param,
|
||||||
|
::testing::Values(make_tuple(&vpx_lpf_horizontal_4_dual_sse2,
|
||||||
|
&vpx_lpf_horizontal_4_dual_c, 8),
|
||||||
|
make_tuple(&vpx_lpf_horizontal_8_dual_sse2,
|
||||||
|
&vpx_lpf_horizontal_8_dual_c, 8),
|
||||||
|
make_tuple(&vpx_lpf_vertical_4_dual_sse2,
|
||||||
|
&vpx_lpf_vertical_4_dual_c, 8),
|
||||||
|
make_tuple(&vpx_lpf_vertical_8_dual_sse2,
|
||||||
|
&vpx_lpf_vertical_8_dual_c, 8)));
|
||||||
|
#endif // CONFIG_VP9_HIGHBITDEPTH
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if HAVE_NEON
|
||||||
|
#if CONFIG_VP9_HIGHBITDEPTH
|
||||||
|
INSTANTIATE_TEST_CASE_P(
|
||||||
|
NEON, Loop8Test6Param,
|
||||||
|
::testing::Values(make_tuple(&vpx_highbd_lpf_horizontal_4_neon,
|
||||||
|
&vpx_highbd_lpf_horizontal_4_c, 8),
|
||||||
|
make_tuple(&vpx_highbd_lpf_horizontal_4_neon,
|
||||||
|
&vpx_highbd_lpf_horizontal_4_c, 10),
|
||||||
|
make_tuple(&vpx_highbd_lpf_horizontal_4_neon,
|
||||||
|
&vpx_highbd_lpf_horizontal_4_c, 12),
|
||||||
|
make_tuple(&vpx_highbd_lpf_horizontal_8_neon,
|
||||||
|
&vpx_highbd_lpf_horizontal_8_c, 8),
|
||||||
|
make_tuple(&vpx_highbd_lpf_horizontal_8_neon,
|
||||||
|
&vpx_highbd_lpf_horizontal_8_c, 10),
|
||||||
|
make_tuple(&vpx_highbd_lpf_horizontal_8_neon,
|
||||||
|
&vpx_highbd_lpf_horizontal_8_c, 12),
|
||||||
|
make_tuple(&vpx_highbd_lpf_horizontal_16_neon,
|
||||||
|
&vpx_highbd_lpf_horizontal_16_c, 8),
|
||||||
|
make_tuple(&vpx_highbd_lpf_horizontal_16_neon,
|
||||||
|
&vpx_highbd_lpf_horizontal_16_c, 10),
|
||||||
|
make_tuple(&vpx_highbd_lpf_horizontal_16_neon,
|
||||||
|
&vpx_highbd_lpf_horizontal_16_c, 12),
|
||||||
|
make_tuple(&vpx_highbd_lpf_horizontal_16_dual_neon,
|
||||||
|
&vpx_highbd_lpf_horizontal_16_dual_c, 8),
|
||||||
|
make_tuple(&vpx_highbd_lpf_horizontal_16_dual_neon,
|
||||||
|
&vpx_highbd_lpf_horizontal_16_dual_c, 10),
|
||||||
|
make_tuple(&vpx_highbd_lpf_horizontal_16_dual_neon,
|
||||||
|
&vpx_highbd_lpf_horizontal_16_dual_c, 12),
|
||||||
|
make_tuple(&vpx_highbd_lpf_vertical_4_neon,
|
||||||
|
&vpx_highbd_lpf_vertical_4_c, 8),
|
||||||
|
make_tuple(&vpx_highbd_lpf_vertical_4_neon,
|
||||||
|
&vpx_highbd_lpf_vertical_4_c, 10),
|
||||||
|
make_tuple(&vpx_highbd_lpf_vertical_4_neon,
|
||||||
|
&vpx_highbd_lpf_vertical_4_c, 12),
|
||||||
|
make_tuple(&vpx_highbd_lpf_vertical_8_neon,
|
||||||
|
&vpx_highbd_lpf_vertical_8_c, 8),
|
||||||
|
make_tuple(&vpx_highbd_lpf_vertical_8_neon,
|
||||||
|
&vpx_highbd_lpf_vertical_8_c, 10),
|
||||||
|
make_tuple(&vpx_highbd_lpf_vertical_8_neon,
|
||||||
|
&vpx_highbd_lpf_vertical_8_c, 12),
|
||||||
|
make_tuple(&vpx_highbd_lpf_vertical_16_neon,
|
||||||
|
&vpx_highbd_lpf_vertical_16_c, 8),
|
||||||
|
make_tuple(&vpx_highbd_lpf_vertical_16_neon,
|
||||||
|
&vpx_highbd_lpf_vertical_16_c, 10),
|
||||||
|
make_tuple(&vpx_highbd_lpf_vertical_16_neon,
|
||||||
|
&vpx_highbd_lpf_vertical_16_c, 12),
|
||||||
|
make_tuple(&vpx_highbd_lpf_vertical_16_dual_neon,
|
||||||
|
&vpx_highbd_lpf_vertical_16_dual_c, 8),
|
||||||
|
make_tuple(&vpx_highbd_lpf_vertical_16_dual_neon,
|
||||||
|
&vpx_highbd_lpf_vertical_16_dual_c, 10),
|
||||||
|
make_tuple(&vpx_highbd_lpf_vertical_16_dual_neon,
|
||||||
|
&vpx_highbd_lpf_vertical_16_dual_c, 12)));
|
||||||
|
INSTANTIATE_TEST_CASE_P(
|
||||||
|
NEON, Loop8Test9Param,
|
||||||
|
::testing::Values(make_tuple(&vpx_highbd_lpf_horizontal_4_dual_neon,
|
||||||
|
&vpx_highbd_lpf_horizontal_4_dual_c, 8),
|
||||||
|
make_tuple(&vpx_highbd_lpf_horizontal_4_dual_neon,
|
||||||
|
&vpx_highbd_lpf_horizontal_4_dual_c, 10),
|
||||||
|
make_tuple(&vpx_highbd_lpf_horizontal_4_dual_neon,
|
||||||
|
&vpx_highbd_lpf_horizontal_4_dual_c, 12),
|
||||||
|
make_tuple(&vpx_highbd_lpf_horizontal_8_dual_neon,
|
||||||
|
&vpx_highbd_lpf_horizontal_8_dual_c, 8),
|
||||||
|
make_tuple(&vpx_highbd_lpf_horizontal_8_dual_neon,
|
||||||
|
&vpx_highbd_lpf_horizontal_8_dual_c, 10),
|
||||||
|
make_tuple(&vpx_highbd_lpf_horizontal_8_dual_neon,
|
||||||
|
&vpx_highbd_lpf_horizontal_8_dual_c, 12),
|
||||||
|
make_tuple(&vpx_highbd_lpf_vertical_4_dual_neon,
|
||||||
|
&vpx_highbd_lpf_vertical_4_dual_c, 8),
|
||||||
|
make_tuple(&vpx_highbd_lpf_vertical_4_dual_neon,
|
||||||
|
&vpx_highbd_lpf_vertical_4_dual_c, 10),
|
||||||
|
make_tuple(&vpx_highbd_lpf_vertical_4_dual_neon,
|
||||||
|
&vpx_highbd_lpf_vertical_4_dual_c, 12),
|
||||||
|
make_tuple(&vpx_highbd_lpf_vertical_8_dual_neon,
|
||||||
|
&vpx_highbd_lpf_vertical_8_dual_c, 8),
|
||||||
|
make_tuple(&vpx_highbd_lpf_vertical_8_dual_neon,
|
||||||
|
&vpx_highbd_lpf_vertical_8_dual_c, 10),
|
||||||
|
make_tuple(&vpx_highbd_lpf_vertical_8_dual_neon,
|
||||||
|
&vpx_highbd_lpf_vertical_8_dual_c, 12)));
|
||||||
|
#else
|
||||||
|
INSTANTIATE_TEST_CASE_P(
|
||||||
|
NEON, Loop8Test6Param,
|
||||||
|
::testing::Values(
|
||||||
|
make_tuple(&vpx_lpf_horizontal_16_neon, &vpx_lpf_horizontal_16_c, 8),
|
||||||
|
make_tuple(&vpx_lpf_horizontal_16_dual_neon,
|
||||||
|
&vpx_lpf_horizontal_16_dual_c, 8),
|
||||||
|
make_tuple(&vpx_lpf_vertical_16_neon, &vpx_lpf_vertical_16_c, 8),
|
||||||
|
make_tuple(&vpx_lpf_vertical_16_dual_neon, &vpx_lpf_vertical_16_dual_c,
|
||||||
|
8),
|
||||||
|
make_tuple(&vpx_lpf_horizontal_8_neon, &vpx_lpf_horizontal_8_c, 8),
|
||||||
|
make_tuple(&vpx_lpf_vertical_8_neon, &vpx_lpf_vertical_8_c, 8),
|
||||||
|
make_tuple(&vpx_lpf_horizontal_4_neon, &vpx_lpf_horizontal_4_c, 8),
|
||||||
|
make_tuple(&vpx_lpf_vertical_4_neon, &vpx_lpf_vertical_4_c, 8)));
|
||||||
|
INSTANTIATE_TEST_CASE_P(
|
||||||
|
NEON, Loop8Test9Param,
|
||||||
|
::testing::Values(make_tuple(&vpx_lpf_horizontal_8_dual_neon,
|
||||||
|
&vpx_lpf_horizontal_8_dual_c, 8),
|
||||||
|
make_tuple(&vpx_lpf_vertical_8_dual_neon,
|
||||||
|
&vpx_lpf_vertical_8_dual_c, 8),
|
||||||
|
make_tuple(&vpx_lpf_horizontal_4_dual_neon,
|
||||||
|
&vpx_lpf_horizontal_4_dual_c, 8),
|
||||||
|
make_tuple(&vpx_lpf_vertical_4_dual_neon,
|
||||||
|
&vpx_lpf_vertical_4_dual_c, 8)));
|
||||||
|
#endif // CONFIG_VP9_HIGHBITDEPTH
|
||||||
|
#endif // HAVE_NEON
|
||||||
|
|
||||||
|
#if HAVE_DSPR2 && !CONFIG_VP9_HIGHBITDEPTH
|
||||||
|
INSTANTIATE_TEST_CASE_P(
|
||||||
|
DSPR2, Loop8Test6Param,
|
||||||
|
::testing::Values(
|
||||||
|
make_tuple(&vpx_lpf_horizontal_4_dspr2, &vpx_lpf_horizontal_4_c, 8),
|
||||||
|
make_tuple(&vpx_lpf_horizontal_8_dspr2, &vpx_lpf_horizontal_8_c, 8),
|
||||||
|
make_tuple(&vpx_lpf_horizontal_16_dspr2, &vpx_lpf_horizontal_16_c, 8),
|
||||||
|
make_tuple(&vpx_lpf_horizontal_16_dual_dspr2,
|
||||||
|
&vpx_lpf_horizontal_16_dual_c, 8),
|
||||||
|
make_tuple(&vpx_lpf_vertical_4_dspr2, &vpx_lpf_vertical_4_c, 8),
|
||||||
|
make_tuple(&vpx_lpf_vertical_8_dspr2, &vpx_lpf_vertical_8_c, 8),
|
||||||
|
make_tuple(&vpx_lpf_vertical_16_dspr2, &vpx_lpf_vertical_16_c, 8),
|
||||||
|
make_tuple(&vpx_lpf_vertical_16_dual_dspr2, &vpx_lpf_vertical_16_dual_c,
|
||||||
|
8)));
|
||||||
|
|
||||||
|
INSTANTIATE_TEST_CASE_P(
|
||||||
|
DSPR2, Loop8Test9Param,
|
||||||
|
::testing::Values(make_tuple(&vpx_lpf_horizontal_4_dual_dspr2,
|
||||||
|
&vpx_lpf_horizontal_4_dual_c, 8),
|
||||||
|
make_tuple(&vpx_lpf_horizontal_8_dual_dspr2,
|
||||||
|
&vpx_lpf_horizontal_8_dual_c, 8),
|
||||||
|
make_tuple(&vpx_lpf_vertical_4_dual_dspr2,
|
||||||
|
&vpx_lpf_vertical_4_dual_c, 8),
|
||||||
|
make_tuple(&vpx_lpf_vertical_8_dual_dspr2,
|
||||||
|
&vpx_lpf_vertical_8_dual_c, 8)));
|
||||||
|
#endif // HAVE_DSPR2 && !CONFIG_VP9_HIGHBITDEPTH
|
||||||
|
|
||||||
|
#if HAVE_MSA && (!CONFIG_VP9_HIGHBITDEPTH)
|
||||||
|
INSTANTIATE_TEST_CASE_P(
|
||||||
|
MSA, Loop8Test6Param,
|
||||||
|
::testing::Values(
|
||||||
|
make_tuple(&vpx_lpf_horizontal_4_msa, &vpx_lpf_horizontal_4_c, 8),
|
||||||
|
make_tuple(&vpx_lpf_horizontal_8_msa, &vpx_lpf_horizontal_8_c, 8),
|
||||||
|
make_tuple(&vpx_lpf_horizontal_16_msa, &vpx_lpf_horizontal_16_c, 8),
|
||||||
|
make_tuple(&vpx_lpf_horizontal_16_dual_msa,
|
||||||
|
&vpx_lpf_horizontal_16_dual_c, 8),
|
||||||
|
make_tuple(&vpx_lpf_vertical_4_msa, &vpx_lpf_vertical_4_c, 8),
|
||||||
|
make_tuple(&vpx_lpf_vertical_8_msa, &vpx_lpf_vertical_8_c, 8),
|
||||||
|
make_tuple(&vpx_lpf_vertical_16_msa, &vpx_lpf_vertical_16_c, 8)));
|
||||||
|
|
||||||
|
INSTANTIATE_TEST_CASE_P(
|
||||||
|
MSA, Loop8Test9Param,
|
||||||
|
::testing::Values(make_tuple(&vpx_lpf_horizontal_4_dual_msa,
|
||||||
|
&vpx_lpf_horizontal_4_dual_c, 8),
|
||||||
|
make_tuple(&vpx_lpf_horizontal_8_dual_msa,
|
||||||
|
&vpx_lpf_horizontal_8_dual_c, 8),
|
||||||
|
make_tuple(&vpx_lpf_vertical_4_dual_msa,
|
||||||
|
&vpx_lpf_vertical_4_dual_c, 8),
|
||||||
|
make_tuple(&vpx_lpf_vertical_8_dual_msa,
|
||||||
|
&vpx_lpf_vertical_8_dual_c, 8)));
|
||||||
|
#endif // HAVE_MSA && (!CONFIG_VP9_HIGHBITDEPTH)
|
||||||
|
|
||||||
|
} // namespace
|
||||||
@@ -17,9 +17,7 @@
|
|||||||
namespace libvpx_test {
|
namespace libvpx_test {
|
||||||
class MD5 {
|
class MD5 {
|
||||||
public:
|
public:
|
||||||
MD5() {
|
MD5() { MD5Init(&md5_); }
|
||||||
MD5Init(&md5_);
|
|
||||||
}
|
|
||||||
|
|
||||||
void Add(const vpx_image_t *img) {
|
void Add(const vpx_image_t *img) {
|
||||||
for (int plane = 0; plane < 3; ++plane) {
|
for (int plane = 0; plane < 3; ++plane) {
|
||||||
@@ -30,10 +28,13 @@ class MD5 {
|
|||||||
// This works only for chroma_shift of 0 and 1.
|
// This works only for chroma_shift of 0 and 1.
|
||||||
const int bytes_per_sample =
|
const int bytes_per_sample =
|
||||||
(img->fmt & VPX_IMG_FMT_HIGHBITDEPTH) ? 2 : 1;
|
(img->fmt & VPX_IMG_FMT_HIGHBITDEPTH) ? 2 : 1;
|
||||||
const int h = plane ? (img->d_h + img->y_chroma_shift) >>
|
const int h =
|
||||||
img->y_chroma_shift : img->d_h;
|
plane ? (img->d_h + img->y_chroma_shift) >> img->y_chroma_shift
|
||||||
const int w = (plane ? (img->d_w + img->x_chroma_shift) >>
|
: img->d_h;
|
||||||
img->x_chroma_shift : img->d_w) * bytes_per_sample;
|
const int w =
|
||||||
|
(plane ? (img->d_w + img->x_chroma_shift) >> img->x_chroma_shift
|
||||||
|
: img->d_w) *
|
||||||
|
bytes_per_sample;
|
||||||
|
|
||||||
for (int y = 0; y < h; ++y) {
|
for (int y = 0; y < h; ++y) {
|
||||||
MD5Update(&md5_, buf, w);
|
MD5Update(&md5_, buf, w);
|
||||||
|
|||||||
@@ -23,9 +23,8 @@ namespace {
|
|||||||
|
|
||||||
using ::libvpx_test::ACMRandom;
|
using ::libvpx_test::ACMRandom;
|
||||||
|
|
||||||
typedef void (*MinMaxFunc)(const uint8_t *a, int a_stride,
|
typedef void (*MinMaxFunc)(const uint8_t *a, int a_stride, const uint8_t *b,
|
||||||
const uint8_t *b, int b_stride,
|
int b_stride, int *min, int *max);
|
||||||
int *min, int *max);
|
|
||||||
|
|
||||||
class MinMaxTest : public ::testing::TestWithParam<MinMaxFunc> {
|
class MinMaxTest : public ::testing::TestWithParam<MinMaxFunc> {
|
||||||
public:
|
public:
|
||||||
@@ -39,9 +38,8 @@ class MinMaxTest : public ::testing::TestWithParam<MinMaxFunc> {
|
|||||||
ACMRandom rnd_;
|
ACMRandom rnd_;
|
||||||
};
|
};
|
||||||
|
|
||||||
void reference_minmax(const uint8_t *a, int a_stride,
|
void reference_minmax(const uint8_t *a, int a_stride, const uint8_t *b,
|
||||||
const uint8_t *b, int b_stride,
|
int b_stride, int *min_ret, int *max_ret) {
|
||||||
int *min_ret, int *max_ret) {
|
|
||||||
int min = 255;
|
int min = 255;
|
||||||
int max = 0;
|
int max = 0;
|
||||||
for (int i = 0; i < 8; i++) {
|
for (int i = 0; i < 8; i++) {
|
||||||
@@ -110,9 +108,9 @@ TEST_P(MinMaxTest, CompareReferenceAndVaryStride) {
|
|||||||
reference_minmax(a, a_stride, b, b_stride, &min_ref, &max_ref);
|
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));
|
ASM_REGISTER_STATE_CHECK(mm_func_(a, a_stride, b, b_stride, &min, &max));
|
||||||
EXPECT_EQ(max_ref, max) << "when a_stride = " << a_stride
|
EXPECT_EQ(max_ref, max) << "when a_stride = " << a_stride
|
||||||
<< " and b_stride = " << b_stride;;
|
<< " and b_stride = " << b_stride;
|
||||||
EXPECT_EQ(min_ref, min) << "when a_stride = " << a_stride
|
EXPECT_EQ(min_ref, min) << "when a_stride = " << a_stride
|
||||||
<< " and b_stride = " << b_stride;;
|
<< " and b_stride = " << b_stride;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -12,6 +12,8 @@
|
|||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
|
#include <limits>
|
||||||
|
|
||||||
#include "third_party/googletest/src/include/gtest/gtest.h"
|
#include "third_party/googletest/src/include/gtest/gtest.h"
|
||||||
|
|
||||||
#include "./vp9_rtcd.h"
|
#include "./vp9_rtcd.h"
|
||||||
@@ -23,321 +25,668 @@
|
|||||||
#include "vp9/common/vp9_blockd.h"
|
#include "vp9/common/vp9_blockd.h"
|
||||||
#include "vp9/common/vp9_scan.h"
|
#include "vp9/common/vp9_scan.h"
|
||||||
#include "vpx/vpx_integer.h"
|
#include "vpx/vpx_integer.h"
|
||||||
|
#include "vpx_ports/vpx_timer.h"
|
||||||
|
|
||||||
using libvpx_test::ACMRandom;
|
using libvpx_test::ACMRandom;
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
|
|
||||||
typedef void (*FwdTxfmFunc)(const int16_t *in, tran_low_t *out, int stride);
|
typedef void (*FwdTxfmFunc)(const int16_t *in, tran_low_t *out, int stride);
|
||||||
typedef void (*InvTxfmFunc)(const tran_low_t *in, uint8_t *out, int stride);
|
typedef void (*InvTxfmFunc)(const tran_low_t *in, uint8_t *out, int stride);
|
||||||
typedef std::tr1::tuple<FwdTxfmFunc,
|
typedef void (*InvTxfmWithBdFunc)(const tran_low_t *in, uint8_t *out,
|
||||||
InvTxfmFunc,
|
int stride, int bd);
|
||||||
InvTxfmFunc,
|
|
||||||
TX_SIZE, int> PartialInvTxfmParam;
|
template <InvTxfmFunc fn>
|
||||||
|
void wrapper(const tran_low_t *in, uint8_t *out, int stride, int bd) {
|
||||||
|
(void)bd;
|
||||||
|
fn(in, out, stride);
|
||||||
|
}
|
||||||
|
|
||||||
|
#if CONFIG_VP9_HIGHBITDEPTH
|
||||||
|
template <InvTxfmWithBdFunc fn>
|
||||||
|
void highbd_wrapper(const tran_low_t *in, uint8_t *out, int stride, int bd) {
|
||||||
|
fn(in, CONVERT_TO_BYTEPTR(out), stride, bd);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
typedef std::tr1::tuple<FwdTxfmFunc, InvTxfmWithBdFunc, InvTxfmWithBdFunc,
|
||||||
|
TX_SIZE, int, int, int>
|
||||||
|
PartialInvTxfmParam;
|
||||||
const int kMaxNumCoeffs = 1024;
|
const int kMaxNumCoeffs = 1024;
|
||||||
|
const int kCountTestBlock = 1000;
|
||||||
|
|
||||||
|
// https://bugs.chromium.org/p/webm/issues/detail?id=1332
|
||||||
|
// The functions specified do not pass with INT16_MIN/MAX. They fail at the
|
||||||
|
// value specified, but pass when 1 is added/subtracted.
|
||||||
|
int16_t MaxSupportedCoeff(InvTxfmWithBdFunc a) {
|
||||||
|
#if HAVE_SSSE3 && ARCH_X86_64 && !CONFIG_EMULATE_HARDWARE
|
||||||
|
if (a == &wrapper<vpx_idct8x8_64_add_ssse3> ||
|
||||||
|
a == &wrapper<vpx_idct8x8_12_add_ssse3>) {
|
||||||
|
return 23625 - 1;
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
(void)a;
|
||||||
|
#endif
|
||||||
|
return std::numeric_limits<int16_t>::max();
|
||||||
|
}
|
||||||
|
|
||||||
|
int16_t MinSupportedCoeff(InvTxfmWithBdFunc a) {
|
||||||
|
#if HAVE_SSSE3 && ARCH_X86_64 && !CONFIG_EMULATE_HARDWARE
|
||||||
|
if (a == &wrapper<vpx_idct8x8_64_add_ssse3> ||
|
||||||
|
a == &wrapper<vpx_idct8x8_12_add_ssse3>) {
|
||||||
|
return -23625 + 1;
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
(void)a;
|
||||||
|
#endif
|
||||||
|
return std::numeric_limits<int16_t>::min();
|
||||||
|
}
|
||||||
|
|
||||||
class PartialIDctTest : public ::testing::TestWithParam<PartialInvTxfmParam> {
|
class PartialIDctTest : public ::testing::TestWithParam<PartialInvTxfmParam> {
|
||||||
public:
|
public:
|
||||||
virtual ~PartialIDctTest() {}
|
virtual ~PartialIDctTest() {}
|
||||||
virtual void SetUp() {
|
virtual void SetUp() {
|
||||||
|
rnd_.Reset(ACMRandom::DeterministicSeed());
|
||||||
ftxfm_ = GET_PARAM(0);
|
ftxfm_ = GET_PARAM(0);
|
||||||
full_itxfm_ = GET_PARAM(1);
|
full_itxfm_ = GET_PARAM(1);
|
||||||
partial_itxfm_ = GET_PARAM(2);
|
partial_itxfm_ = GET_PARAM(2);
|
||||||
tx_size_ = GET_PARAM(3);
|
tx_size_ = GET_PARAM(3);
|
||||||
last_nonzero_ = GET_PARAM(4);
|
last_nonzero_ = GET_PARAM(4);
|
||||||
|
bit_depth_ = GET_PARAM(5);
|
||||||
|
pixel_size_ = GET_PARAM(6);
|
||||||
|
mask_ = (1 << bit_depth_) - 1;
|
||||||
|
|
||||||
|
switch (tx_size_) {
|
||||||
|
case TX_4X4: size_ = 4; break;
|
||||||
|
case TX_8X8: size_ = 8; break;
|
||||||
|
case TX_16X16: size_ = 16; break;
|
||||||
|
case TX_32X32: size_ = 32; break;
|
||||||
|
default: FAIL() << "Wrong Size!"; break;
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual void TearDown() { libvpx_test::ClearSystemState(); }
|
// Randomize stride_ to a value less than or equal to 1024
|
||||||
|
stride_ = rnd_(1024) + 1;
|
||||||
|
if (stride_ < size_) {
|
||||||
|
stride_ = size_;
|
||||||
|
}
|
||||||
|
// Align stride_ to 16 if it's bigger than 16.
|
||||||
|
if (stride_ > 16) {
|
||||||
|
stride_ &= ~15;
|
||||||
|
}
|
||||||
|
|
||||||
|
input_block_size_ = size_ * size_;
|
||||||
|
output_block_size_ = size_ * stride_;
|
||||||
|
|
||||||
|
input_block_ = reinterpret_cast<tran_low_t *>(
|
||||||
|
vpx_memalign(16, sizeof(*input_block_) * input_block_size_));
|
||||||
|
output_block_ = reinterpret_cast<uint8_t *>(
|
||||||
|
vpx_memalign(16, pixel_size_ * output_block_size_));
|
||||||
|
output_block_ref_ = reinterpret_cast<uint8_t *>(
|
||||||
|
vpx_memalign(16, pixel_size_ * output_block_size_));
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual void TearDown() {
|
||||||
|
vpx_free(input_block_);
|
||||||
|
input_block_ = NULL;
|
||||||
|
vpx_free(output_block_);
|
||||||
|
output_block_ = NULL;
|
||||||
|
vpx_free(output_block_ref_);
|
||||||
|
output_block_ref_ = NULL;
|
||||||
|
libvpx_test::ClearSystemState();
|
||||||
|
}
|
||||||
|
|
||||||
|
void InitMem() {
|
||||||
|
memset(input_block_, 0, sizeof(*input_block_) * input_block_size_);
|
||||||
|
if (pixel_size_ == 1) {
|
||||||
|
for (int j = 0; j < output_block_size_; ++j) {
|
||||||
|
output_block_[j] = output_block_ref_[j] = rnd_.Rand16() & mask_;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
ASSERT_EQ(2, pixel_size_);
|
||||||
|
uint16_t *const output = reinterpret_cast<uint16_t *>(output_block_);
|
||||||
|
uint16_t *const output_ref =
|
||||||
|
reinterpret_cast<uint16_t *>(output_block_ref_);
|
||||||
|
for (int j = 0; j < output_block_size_; ++j) {
|
||||||
|
output[j] = output_ref[j] = rnd_.Rand16() & mask_;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void InitInput() {
|
||||||
|
const int max_coeff = 32766 / 4;
|
||||||
|
int max_energy_leftover = max_coeff * max_coeff;
|
||||||
|
for (int j = 0; j < last_nonzero_; ++j) {
|
||||||
|
int16_t coeff = static_cast<int16_t>(sqrt(1.0 * max_energy_leftover) *
|
||||||
|
(rnd_.Rand16() - 32768) / 65536);
|
||||||
|
max_energy_leftover -= coeff * coeff;
|
||||||
|
if (max_energy_leftover < 0) {
|
||||||
|
max_energy_leftover = 0;
|
||||||
|
coeff = 0;
|
||||||
|
}
|
||||||
|
input_block_[vp9_default_scan_orders[tx_size_].scan[j]] = coeff;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
int last_nonzero_;
|
int last_nonzero_;
|
||||||
TX_SIZE tx_size_;
|
TX_SIZE tx_size_;
|
||||||
|
tran_low_t *input_block_;
|
||||||
|
uint8_t *output_block_;
|
||||||
|
uint8_t *output_block_ref_;
|
||||||
|
int size_;
|
||||||
|
int stride_;
|
||||||
|
int pixel_size_;
|
||||||
|
int input_block_size_;
|
||||||
|
int output_block_size_;
|
||||||
|
int bit_depth_;
|
||||||
|
int mask_;
|
||||||
FwdTxfmFunc ftxfm_;
|
FwdTxfmFunc ftxfm_;
|
||||||
InvTxfmFunc full_itxfm_;
|
InvTxfmWithBdFunc full_itxfm_;
|
||||||
InvTxfmFunc partial_itxfm_;
|
InvTxfmWithBdFunc partial_itxfm_;
|
||||||
|
ACMRandom rnd_;
|
||||||
};
|
};
|
||||||
|
|
||||||
TEST_P(PartialIDctTest, RunQuantCheck) {
|
TEST_P(PartialIDctTest, RunQuantCheck) {
|
||||||
ACMRandom rnd(ACMRandom::DeterministicSeed());
|
|
||||||
int size;
|
|
||||||
switch (tx_size_) {
|
|
||||||
case TX_4X4:
|
|
||||||
size = 4;
|
|
||||||
break;
|
|
||||||
case TX_8X8:
|
|
||||||
size = 8;
|
|
||||||
break;
|
|
||||||
case TX_16X16:
|
|
||||||
size = 16;
|
|
||||||
break;
|
|
||||||
case TX_32X32:
|
|
||||||
size = 32;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
FAIL() << "Wrong Size!";
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
DECLARE_ALIGNED(16, tran_low_t, test_coef_block1[kMaxNumCoeffs]);
|
|
||||||
DECLARE_ALIGNED(16, tran_low_t, test_coef_block2[kMaxNumCoeffs]);
|
|
||||||
DECLARE_ALIGNED(16, uint8_t, dst1[kMaxNumCoeffs]);
|
|
||||||
DECLARE_ALIGNED(16, uint8_t, dst2[kMaxNumCoeffs]);
|
|
||||||
|
|
||||||
const int count_test_block = 1000;
|
|
||||||
const int block_size = size * size;
|
|
||||||
|
|
||||||
DECLARE_ALIGNED(16, int16_t, input_extreme_block[kMaxNumCoeffs]);
|
DECLARE_ALIGNED(16, int16_t, input_extreme_block[kMaxNumCoeffs]);
|
||||||
DECLARE_ALIGNED(16, tran_low_t, output_ref_block[kMaxNumCoeffs]);
|
DECLARE_ALIGNED(16, tran_low_t, output_ref_block[kMaxNumCoeffs]);
|
||||||
|
|
||||||
int max_error = 0;
|
InitMem();
|
||||||
for (int i = 0; i < count_test_block; ++i) {
|
for (int i = 0; i < kCountTestBlock * kCountTestBlock; ++i) {
|
||||||
// clear out destination buffer
|
// Initialize a test block with input range [-mask_, mask_].
|
||||||
memset(dst1, 0, sizeof(*dst1) * block_size);
|
|
||||||
memset(dst2, 0, sizeof(*dst2) * block_size);
|
|
||||||
memset(test_coef_block1, 0, sizeof(*test_coef_block1) * block_size);
|
|
||||||
memset(test_coef_block2, 0, sizeof(*test_coef_block2) * block_size);
|
|
||||||
|
|
||||||
ACMRandom rnd(ACMRandom::DeterministicSeed());
|
|
||||||
|
|
||||||
for (int i = 0; i < count_test_block; ++i) {
|
|
||||||
// Initialize a test block with input range [-255, 255].
|
|
||||||
if (i == 0) {
|
if (i == 0) {
|
||||||
for (int j = 0; j < block_size; ++j)
|
for (int k = 0; k < input_block_size_; ++k) {
|
||||||
input_extreme_block[j] = 255;
|
input_extreme_block[k] = mask_;
|
||||||
|
}
|
||||||
} else if (i == 1) {
|
} else if (i == 1) {
|
||||||
for (int j = 0; j < block_size; ++j)
|
for (int k = 0; k < input_block_size_; ++k) {
|
||||||
input_extreme_block[j] = -255;
|
input_extreme_block[k] = -mask_;
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
for (int j = 0; j < block_size; ++j) {
|
for (int k = 0; k < input_block_size_; ++k) {
|
||||||
input_extreme_block[j] = rnd.Rand8() % 2 ? 255 : -255;
|
input_extreme_block[k] = rnd_.Rand8() % 2 ? mask_ : -mask_;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ftxfm_(input_extreme_block, output_ref_block, size);
|
ftxfm_(input_extreme_block, output_ref_block, size_);
|
||||||
|
|
||||||
// quantization with maximum allowed step sizes
|
// quantization with minimum allowed step sizes
|
||||||
test_coef_block1[0] = (output_ref_block[0] / 1336) * 1336;
|
input_block_[0] = (output_ref_block[0] / 4) * 4;
|
||||||
for (int j = 1; j < last_nonzero_; ++j)
|
for (int k = 1; k < last_nonzero_; ++k) {
|
||||||
test_coef_block1[vp9_default_scan_orders[tx_size_].scan[j]]
|
const int pos = vp9_default_scan_orders[tx_size_].scan[k];
|
||||||
= (output_ref_block[j] / 1828) * 1828;
|
input_block_[pos] = (output_ref_block[pos] / 4) * 4;
|
||||||
}
|
}
|
||||||
|
|
||||||
ASM_REGISTER_STATE_CHECK(full_itxfm_(test_coef_block1, dst1, size));
|
ASM_REGISTER_STATE_CHECK(
|
||||||
ASM_REGISTER_STATE_CHECK(partial_itxfm_(test_coef_block1, dst2, size));
|
full_itxfm_(input_block_, output_block_ref_, stride_, bit_depth_));
|
||||||
|
ASM_REGISTER_STATE_CHECK(
|
||||||
for (int j = 0; j < block_size; ++j) {
|
partial_itxfm_(input_block_, output_block_, stride_, bit_depth_));
|
||||||
const int diff = dst1[j] - dst2[j];
|
ASSERT_EQ(0, memcmp(output_block_ref_, output_block_,
|
||||||
const int error = diff * diff;
|
pixel_size_ * output_block_size_))
|
||||||
if (max_error < error)
|
|
||||||
max_error = error;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
EXPECT_EQ(0, max_error)
|
|
||||||
<< "Error: partial inverse transform produces different results";
|
<< "Error: partial inverse transform produces different results";
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
TEST_P(PartialIDctTest, ResultsMatch) {
|
TEST_P(PartialIDctTest, ResultsMatch) {
|
||||||
ACMRandom rnd(ACMRandom::DeterministicSeed());
|
for (int i = 0; i < kCountTestBlock; ++i) {
|
||||||
int size;
|
InitMem();
|
||||||
switch (tx_size_) {
|
InitInput();
|
||||||
case TX_4X4:
|
|
||||||
size = 4;
|
|
||||||
break;
|
|
||||||
case TX_8X8:
|
|
||||||
size = 8;
|
|
||||||
break;
|
|
||||||
case TX_16X16:
|
|
||||||
size = 16;
|
|
||||||
break;
|
|
||||||
case TX_32X32:
|
|
||||||
size = 32;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
FAIL() << "Wrong Size!";
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
DECLARE_ALIGNED(16, tran_low_t, test_coef_block1[kMaxNumCoeffs]);
|
|
||||||
DECLARE_ALIGNED(16, tran_low_t, test_coef_block2[kMaxNumCoeffs]);
|
|
||||||
DECLARE_ALIGNED(16, uint8_t, dst1[kMaxNumCoeffs]);
|
|
||||||
DECLARE_ALIGNED(16, uint8_t, dst2[kMaxNumCoeffs]);
|
|
||||||
const int count_test_block = 1000;
|
|
||||||
const int max_coeff = 32766 / 4;
|
|
||||||
const int block_size = size * size;
|
|
||||||
int max_error = 0;
|
|
||||||
for (int i = 0; i < count_test_block; ++i) {
|
|
||||||
// clear out destination buffer
|
|
||||||
memset(dst1, 0, sizeof(*dst1) * block_size);
|
|
||||||
memset(dst2, 0, sizeof(*dst2) * block_size);
|
|
||||||
memset(test_coef_block1, 0, sizeof(*test_coef_block1) * block_size);
|
|
||||||
memset(test_coef_block2, 0, sizeof(*test_coef_block2) * block_size);
|
|
||||||
int max_energy_leftover = max_coeff * max_coeff;
|
|
||||||
for (int j = 0; j < last_nonzero_; ++j) {
|
|
||||||
int16_t coef = static_cast<int16_t>(sqrt(1.0 * max_energy_leftover) *
|
|
||||||
(rnd.Rand16() - 32768) / 65536);
|
|
||||||
max_energy_leftover -= coef * coef;
|
|
||||||
if (max_energy_leftover < 0) {
|
|
||||||
max_energy_leftover = 0;
|
|
||||||
coef = 0;
|
|
||||||
}
|
|
||||||
test_coef_block1[vp9_default_scan_orders[tx_size_].scan[j]] = coef;
|
|
||||||
}
|
|
||||||
|
|
||||||
memcpy(test_coef_block2, test_coef_block1,
|
ASM_REGISTER_STATE_CHECK(
|
||||||
sizeof(*test_coef_block2) * block_size);
|
full_itxfm_(input_block_, output_block_ref_, stride_, bit_depth_));
|
||||||
|
ASM_REGISTER_STATE_CHECK(
|
||||||
ASM_REGISTER_STATE_CHECK(full_itxfm_(test_coef_block1, dst1, size));
|
partial_itxfm_(input_block_, output_block_, stride_, bit_depth_));
|
||||||
ASM_REGISTER_STATE_CHECK(partial_itxfm_(test_coef_block2, dst2, size));
|
ASSERT_EQ(0, memcmp(output_block_ref_, output_block_,
|
||||||
|
pixel_size_ * output_block_size_))
|
||||||
for (int j = 0; j < block_size; ++j) {
|
|
||||||
const int diff = dst1[j] - dst2[j];
|
|
||||||
const int error = diff * diff;
|
|
||||||
if (max_error < error)
|
|
||||||
max_error = error;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
EXPECT_EQ(0, max_error)
|
|
||||||
<< "Error: partial inverse transform produces different results";
|
<< "Error: partial inverse transform produces different results";
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_P(PartialIDctTest, AddOutputBlock) {
|
||||||
|
for (int i = 0; i < kCountTestBlock; ++i) {
|
||||||
|
InitMem();
|
||||||
|
for (int j = 0; j < last_nonzero_; ++j) {
|
||||||
|
input_block_[vp9_default_scan_orders[tx_size_].scan[j]] = 10;
|
||||||
|
}
|
||||||
|
|
||||||
|
ASM_REGISTER_STATE_CHECK(
|
||||||
|
full_itxfm_(input_block_, output_block_ref_, stride_, bit_depth_));
|
||||||
|
ASM_REGISTER_STATE_CHECK(
|
||||||
|
partial_itxfm_(input_block_, output_block_, stride_, bit_depth_));
|
||||||
|
ASSERT_EQ(0, memcmp(output_block_ref_, output_block_,
|
||||||
|
pixel_size_ * output_block_size_))
|
||||||
|
<< "Error: Transform results are not correctly added to output.";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_P(PartialIDctTest, SingleExtremeCoeff) {
|
||||||
|
const int16_t max_coeff = MaxSupportedCoeff(partial_itxfm_);
|
||||||
|
const int16_t min_coeff = MinSupportedCoeff(partial_itxfm_);
|
||||||
|
for (int i = 0; i < last_nonzero_; ++i) {
|
||||||
|
memset(input_block_, 0, sizeof(*input_block_) * input_block_size_);
|
||||||
|
// Run once for min and once for max.
|
||||||
|
for (int j = 0; j < 2; ++j) {
|
||||||
|
const int coeff = j ? min_coeff : max_coeff;
|
||||||
|
|
||||||
|
memset(output_block_, 0, pixel_size_ * output_block_size_);
|
||||||
|
memset(output_block_ref_, 0, pixel_size_ * output_block_size_);
|
||||||
|
input_block_[vp9_default_scan_orders[tx_size_].scan[i]] = coeff;
|
||||||
|
|
||||||
|
ASM_REGISTER_STATE_CHECK(
|
||||||
|
full_itxfm_(input_block_, output_block_ref_, stride_, bit_depth_));
|
||||||
|
ASM_REGISTER_STATE_CHECK(
|
||||||
|
partial_itxfm_(input_block_, output_block_, stride_, bit_depth_));
|
||||||
|
ASSERT_EQ(0, memcmp(output_block_ref_, output_block_,
|
||||||
|
pixel_size_ * output_block_size_))
|
||||||
|
<< "Error: Fails with single coeff of " << coeff << " at " << i
|
||||||
|
<< ".";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_P(PartialIDctTest, DISABLED_Speed) {
|
||||||
|
// Keep runtime stable with transform size.
|
||||||
|
const int kCountSpeedTestBlock = 500000000 / input_block_size_;
|
||||||
|
InitMem();
|
||||||
|
InitInput();
|
||||||
|
|
||||||
|
for (int i = 0; i < kCountSpeedTestBlock; ++i) {
|
||||||
|
ASM_REGISTER_STATE_CHECK(
|
||||||
|
full_itxfm_(input_block_, output_block_ref_, stride_, bit_depth_));
|
||||||
|
}
|
||||||
|
vpx_usec_timer timer;
|
||||||
|
vpx_usec_timer_start(&timer);
|
||||||
|
for (int i = 0; i < kCountSpeedTestBlock; ++i) {
|
||||||
|
partial_itxfm_(input_block_, output_block_, stride_, bit_depth_);
|
||||||
|
}
|
||||||
|
libvpx_test::ClearSystemState();
|
||||||
|
vpx_usec_timer_mark(&timer);
|
||||||
|
const int elapsed_time =
|
||||||
|
static_cast<int>(vpx_usec_timer_elapsed(&timer) / 1000);
|
||||||
|
printf("idct%dx%d_%d (bitdepth %d) time: %5d ms ", size_, size_,
|
||||||
|
last_nonzero_, bit_depth_, elapsed_time);
|
||||||
|
|
||||||
|
ASSERT_EQ(0, memcmp(output_block_ref_, output_block_,
|
||||||
|
pixel_size_ * output_block_size_))
|
||||||
|
<< "Error: partial inverse transform produces different results";
|
||||||
|
}
|
||||||
|
|
||||||
using std::tr1::make_tuple;
|
using std::tr1::make_tuple;
|
||||||
|
|
||||||
INSTANTIATE_TEST_CASE_P(
|
const PartialInvTxfmParam c_partial_idct_tests[] = {
|
||||||
C, PartialIDctTest,
|
#if CONFIG_VP9_HIGHBITDEPTH
|
||||||
::testing::Values(
|
make_tuple(
|
||||||
make_tuple(&vpx_fdct32x32_c,
|
&vpx_highbd_fdct32x32_c, &highbd_wrapper<vpx_highbd_idct32x32_1024_add_c>,
|
||||||
&vpx_idct32x32_1024_add_c,
|
&highbd_wrapper<vpx_highbd_idct32x32_1024_add_c>, TX_32X32, 1024, 8, 2),
|
||||||
&vpx_idct32x32_34_add_c,
|
make_tuple(
|
||||||
TX_32X32, 34),
|
&vpx_highbd_fdct32x32_c, &highbd_wrapper<vpx_highbd_idct32x32_1024_add_c>,
|
||||||
make_tuple(&vpx_fdct32x32_c,
|
&highbd_wrapper<vpx_highbd_idct32x32_1024_add_c>, TX_32X32, 1024, 10, 2),
|
||||||
&vpx_idct32x32_1024_add_c,
|
make_tuple(
|
||||||
&vpx_idct32x32_1_add_c,
|
&vpx_highbd_fdct32x32_c, &highbd_wrapper<vpx_highbd_idct32x32_1024_add_c>,
|
||||||
TX_32X32, 1),
|
&highbd_wrapper<vpx_highbd_idct32x32_1024_add_c>, TX_32X32, 1024, 12, 2),
|
||||||
make_tuple(&vpx_fdct16x16_c,
|
make_tuple(
|
||||||
&vpx_idct16x16_256_add_c,
|
&vpx_highbd_fdct32x32_c, &highbd_wrapper<vpx_highbd_idct32x32_1024_add_c>,
|
||||||
&vpx_idct16x16_10_add_c,
|
&highbd_wrapper<vpx_highbd_idct32x32_34_add_c>, TX_32X32, 34, 8, 2),
|
||||||
TX_16X16, 10),
|
make_tuple(
|
||||||
make_tuple(&vpx_fdct16x16_c,
|
&vpx_highbd_fdct32x32_c, &highbd_wrapper<vpx_highbd_idct32x32_1024_add_c>,
|
||||||
&vpx_idct16x16_256_add_c,
|
&highbd_wrapper<vpx_highbd_idct32x32_34_add_c>, TX_32X32, 34, 10, 2),
|
||||||
&vpx_idct16x16_1_add_c,
|
make_tuple(
|
||||||
TX_16X16, 1),
|
&vpx_highbd_fdct32x32_c, &highbd_wrapper<vpx_highbd_idct32x32_1024_add_c>,
|
||||||
make_tuple(&vpx_fdct8x8_c,
|
&highbd_wrapper<vpx_highbd_idct32x32_34_add_c>, TX_32X32, 34, 12, 2),
|
||||||
&vpx_idct8x8_64_add_c,
|
make_tuple(&vpx_highbd_fdct32x32_c,
|
||||||
&vpx_idct8x8_12_add_c,
|
&highbd_wrapper<vpx_highbd_idct32x32_1024_add_c>,
|
||||||
TX_8X8, 12),
|
&highbd_wrapper<vpx_highbd_idct32x32_1_add_c>, TX_32X32, 1, 8, 2),
|
||||||
make_tuple(&vpx_fdct8x8_c,
|
make_tuple(&vpx_highbd_fdct32x32_c,
|
||||||
&vpx_idct8x8_64_add_c,
|
&highbd_wrapper<vpx_highbd_idct32x32_1024_add_c>,
|
||||||
&vpx_idct8x8_1_add_c,
|
&highbd_wrapper<vpx_highbd_idct32x32_1_add_c>, TX_32X32, 1, 10, 2),
|
||||||
TX_8X8, 1),
|
make_tuple(&vpx_highbd_fdct32x32_c,
|
||||||
make_tuple(&vpx_fdct4x4_c,
|
&highbd_wrapper<vpx_highbd_idct32x32_1024_add_c>,
|
||||||
&vpx_idct4x4_16_add_c,
|
&highbd_wrapper<vpx_highbd_idct32x32_1_add_c>, TX_32X32, 1, 12, 2),
|
||||||
&vpx_idct4x4_1_add_c,
|
make_tuple(
|
||||||
TX_4X4, 1)));
|
&vpx_highbd_fdct16x16_c, &highbd_wrapper<vpx_highbd_idct16x16_256_add_c>,
|
||||||
|
&highbd_wrapper<vpx_highbd_idct16x16_256_add_c>, TX_16X16, 256, 8, 2),
|
||||||
|
make_tuple(
|
||||||
|
&vpx_highbd_fdct16x16_c, &highbd_wrapper<vpx_highbd_idct16x16_256_add_c>,
|
||||||
|
&highbd_wrapper<vpx_highbd_idct16x16_256_add_c>, TX_16X16, 256, 10, 2),
|
||||||
|
make_tuple(
|
||||||
|
&vpx_highbd_fdct16x16_c, &highbd_wrapper<vpx_highbd_idct16x16_256_add_c>,
|
||||||
|
&highbd_wrapper<vpx_highbd_idct16x16_256_add_c>, TX_16X16, 256, 12, 2),
|
||||||
|
make_tuple(
|
||||||
|
&vpx_highbd_fdct16x16_c, &highbd_wrapper<vpx_highbd_idct16x16_256_add_c>,
|
||||||
|
&highbd_wrapper<vpx_highbd_idct16x16_10_add_c>, TX_16X16, 10, 8, 2),
|
||||||
|
make_tuple(
|
||||||
|
&vpx_highbd_fdct16x16_c, &highbd_wrapper<vpx_highbd_idct16x16_256_add_c>,
|
||||||
|
&highbd_wrapper<vpx_highbd_idct16x16_10_add_c>, TX_16X16, 10, 10, 2),
|
||||||
|
make_tuple(
|
||||||
|
&vpx_highbd_fdct16x16_c, &highbd_wrapper<vpx_highbd_idct16x16_256_add_c>,
|
||||||
|
&highbd_wrapper<vpx_highbd_idct16x16_10_add_c>, TX_16X16, 10, 12, 2),
|
||||||
|
make_tuple(&vpx_highbd_fdct16x16_c,
|
||||||
|
&highbd_wrapper<vpx_highbd_idct16x16_256_add_c>,
|
||||||
|
&highbd_wrapper<vpx_highbd_idct16x16_1_add_c>, TX_16X16, 1, 8, 2),
|
||||||
|
make_tuple(&vpx_highbd_fdct16x16_c,
|
||||||
|
&highbd_wrapper<vpx_highbd_idct16x16_256_add_c>,
|
||||||
|
&highbd_wrapper<vpx_highbd_idct16x16_1_add_c>, TX_16X16, 1, 10, 2),
|
||||||
|
make_tuple(&vpx_highbd_fdct16x16_c,
|
||||||
|
&highbd_wrapper<vpx_highbd_idct16x16_256_add_c>,
|
||||||
|
&highbd_wrapper<vpx_highbd_idct16x16_1_add_c>, TX_16X16, 1, 12, 2),
|
||||||
|
make_tuple(&vpx_highbd_fdct8x8_c,
|
||||||
|
&highbd_wrapper<vpx_highbd_idct8x8_64_add_c>,
|
||||||
|
&highbd_wrapper<vpx_highbd_idct8x8_64_add_c>, TX_8X8, 64, 8, 2),
|
||||||
|
make_tuple(&vpx_highbd_fdct8x8_c,
|
||||||
|
&highbd_wrapper<vpx_highbd_idct8x8_64_add_c>,
|
||||||
|
&highbd_wrapper<vpx_highbd_idct8x8_64_add_c>, TX_8X8, 64, 10, 2),
|
||||||
|
make_tuple(&vpx_highbd_fdct8x8_c,
|
||||||
|
&highbd_wrapper<vpx_highbd_idct8x8_64_add_c>,
|
||||||
|
&highbd_wrapper<vpx_highbd_idct8x8_64_add_c>, TX_8X8, 64, 12, 2),
|
||||||
|
make_tuple(&vpx_highbd_fdct8x8_c,
|
||||||
|
&highbd_wrapper<vpx_highbd_idct8x8_64_add_c>,
|
||||||
|
&highbd_wrapper<vpx_highbd_idct8x8_12_add_c>, TX_8X8, 12, 8, 2),
|
||||||
|
make_tuple(&vpx_highbd_fdct8x8_c,
|
||||||
|
&highbd_wrapper<vpx_highbd_idct8x8_64_add_c>,
|
||||||
|
&highbd_wrapper<vpx_highbd_idct8x8_12_add_c>, TX_8X8, 12, 10, 2),
|
||||||
|
make_tuple(&vpx_highbd_fdct8x8_c,
|
||||||
|
&highbd_wrapper<vpx_highbd_idct8x8_64_add_c>,
|
||||||
|
&highbd_wrapper<vpx_highbd_idct8x8_12_add_c>, TX_8X8, 12, 12, 2),
|
||||||
|
make_tuple(&vpx_highbd_fdct8x8_c,
|
||||||
|
&highbd_wrapper<vpx_highbd_idct8x8_64_add_c>,
|
||||||
|
&highbd_wrapper<vpx_highbd_idct8x8_1_add_c>, TX_8X8, 1, 8, 2),
|
||||||
|
make_tuple(&vpx_highbd_fdct8x8_c,
|
||||||
|
&highbd_wrapper<vpx_highbd_idct8x8_64_add_c>,
|
||||||
|
&highbd_wrapper<vpx_highbd_idct8x8_1_add_c>, TX_8X8, 1, 10, 2),
|
||||||
|
make_tuple(&vpx_highbd_fdct8x8_c,
|
||||||
|
&highbd_wrapper<vpx_highbd_idct8x8_64_add_c>,
|
||||||
|
&highbd_wrapper<vpx_highbd_idct8x8_1_add_c>, TX_8X8, 1, 12, 2),
|
||||||
|
make_tuple(&vpx_highbd_fdct4x4_c,
|
||||||
|
&highbd_wrapper<vpx_highbd_idct4x4_16_add_c>,
|
||||||
|
&highbd_wrapper<vpx_highbd_idct4x4_16_add_c>, TX_4X4, 16, 8, 2),
|
||||||
|
make_tuple(&vpx_highbd_fdct4x4_c,
|
||||||
|
&highbd_wrapper<vpx_highbd_idct4x4_16_add_c>,
|
||||||
|
&highbd_wrapper<vpx_highbd_idct4x4_16_add_c>, TX_4X4, 16, 10, 2),
|
||||||
|
make_tuple(&vpx_highbd_fdct4x4_c,
|
||||||
|
&highbd_wrapper<vpx_highbd_idct4x4_16_add_c>,
|
||||||
|
&highbd_wrapper<vpx_highbd_idct4x4_16_add_c>, TX_4X4, 16, 12, 2),
|
||||||
|
make_tuple(&vpx_highbd_fdct4x4_c,
|
||||||
|
&highbd_wrapper<vpx_highbd_idct4x4_16_add_c>,
|
||||||
|
&highbd_wrapper<vpx_highbd_idct4x4_1_add_c>, TX_4X4, 1, 8, 2),
|
||||||
|
make_tuple(&vpx_highbd_fdct4x4_c,
|
||||||
|
&highbd_wrapper<vpx_highbd_idct4x4_16_add_c>,
|
||||||
|
&highbd_wrapper<vpx_highbd_idct4x4_1_add_c>, TX_4X4, 1, 10, 2),
|
||||||
|
make_tuple(&vpx_highbd_fdct4x4_c,
|
||||||
|
&highbd_wrapper<vpx_highbd_idct4x4_16_add_c>,
|
||||||
|
&highbd_wrapper<vpx_highbd_idct4x4_1_add_c>, TX_4X4, 1, 12, 2),
|
||||||
|
#endif // CONFIG_VP9_HIGHBITDEPTH
|
||||||
|
make_tuple(&vpx_fdct32x32_c, &wrapper<vpx_idct32x32_1024_add_c>,
|
||||||
|
&wrapper<vpx_idct32x32_1024_add_c>, TX_32X32, 1024, 8, 1),
|
||||||
|
make_tuple(&vpx_fdct32x32_c, &wrapper<vpx_idct32x32_1024_add_c>,
|
||||||
|
&wrapper<vpx_idct32x32_135_add_c>, TX_32X32, 135, 8, 1),
|
||||||
|
make_tuple(&vpx_fdct32x32_c, &wrapper<vpx_idct32x32_1024_add_c>,
|
||||||
|
&wrapper<vpx_idct32x32_34_add_c>, TX_32X32, 34, 8, 1),
|
||||||
|
make_tuple(&vpx_fdct32x32_c, &wrapper<vpx_idct32x32_1024_add_c>,
|
||||||
|
&wrapper<vpx_idct32x32_1_add_c>, TX_32X32, 1, 8, 1),
|
||||||
|
make_tuple(&vpx_fdct16x16_c, &wrapper<vpx_idct16x16_256_add_c>,
|
||||||
|
&wrapper<vpx_idct16x16_256_add_c>, TX_16X16, 256, 8, 1),
|
||||||
|
make_tuple(&vpx_fdct16x16_c, &wrapper<vpx_idct16x16_256_add_c>,
|
||||||
|
&wrapper<vpx_idct16x16_10_add_c>, TX_16X16, 10, 8, 1),
|
||||||
|
make_tuple(&vpx_fdct16x16_c, &wrapper<vpx_idct16x16_256_add_c>,
|
||||||
|
&wrapper<vpx_idct16x16_1_add_c>, TX_16X16, 1, 8, 1),
|
||||||
|
make_tuple(&vpx_fdct8x8_c, &wrapper<vpx_idct8x8_64_add_c>,
|
||||||
|
&wrapper<vpx_idct8x8_64_add_c>, TX_8X8, 64, 8, 1),
|
||||||
|
make_tuple(&vpx_fdct8x8_c, &wrapper<vpx_idct8x8_64_add_c>,
|
||||||
|
&wrapper<vpx_idct8x8_12_add_c>, TX_8X8, 12, 8, 1),
|
||||||
|
make_tuple(&vpx_fdct8x8_c, &wrapper<vpx_idct8x8_64_add_c>,
|
||||||
|
&wrapper<vpx_idct8x8_1_add_c>, TX_8X8, 1, 8, 1),
|
||||||
|
make_tuple(&vpx_fdct4x4_c, &wrapper<vpx_idct4x4_16_add_c>,
|
||||||
|
&wrapper<vpx_idct4x4_16_add_c>, TX_4X4, 16, 8, 1),
|
||||||
|
make_tuple(&vpx_fdct4x4_c, &wrapper<vpx_idct4x4_16_add_c>,
|
||||||
|
&wrapper<vpx_idct4x4_1_add_c>, TX_4X4, 1, 8, 1)
|
||||||
|
};
|
||||||
|
|
||||||
#if HAVE_NEON && !CONFIG_VP9_HIGHBITDEPTH && !CONFIG_EMULATE_HARDWARE
|
INSTANTIATE_TEST_CASE_P(C, PartialIDctTest,
|
||||||
INSTANTIATE_TEST_CASE_P(
|
::testing::ValuesIn(c_partial_idct_tests));
|
||||||
NEON, PartialIDctTest,
|
|
||||||
::testing::Values(
|
|
||||||
make_tuple(&vpx_fdct32x32_c,
|
|
||||||
&vpx_idct32x32_1024_add_c,
|
|
||||||
&vpx_idct32x32_1_add_neon,
|
|
||||||
TX_32X32, 1),
|
|
||||||
make_tuple(&vpx_fdct16x16_c,
|
|
||||||
&vpx_idct16x16_256_add_c,
|
|
||||||
&vpx_idct16x16_10_add_neon,
|
|
||||||
TX_16X16, 10),
|
|
||||||
make_tuple(&vpx_fdct16x16_c,
|
|
||||||
&vpx_idct16x16_256_add_c,
|
|
||||||
&vpx_idct16x16_1_add_neon,
|
|
||||||
TX_16X16, 1),
|
|
||||||
make_tuple(&vpx_fdct8x8_c,
|
|
||||||
&vpx_idct8x8_64_add_c,
|
|
||||||
&vpx_idct8x8_12_add_neon,
|
|
||||||
TX_8X8, 12),
|
|
||||||
make_tuple(&vpx_fdct8x8_c,
|
|
||||||
&vpx_idct8x8_64_add_c,
|
|
||||||
&vpx_idct8x8_1_add_neon,
|
|
||||||
TX_8X8, 1),
|
|
||||||
make_tuple(&vpx_fdct4x4_c,
|
|
||||||
&vpx_idct4x4_16_add_c,
|
|
||||||
&vpx_idct4x4_1_add_neon,
|
|
||||||
TX_4X4, 1)));
|
|
||||||
#endif // HAVE_NEON && !CONFIG_VP9_HIGHBITDEPTH && !CONFIG_EMULATE_HARDWARE
|
|
||||||
|
|
||||||
#if HAVE_SSE2 && !CONFIG_VP9_HIGHBITDEPTH && !CONFIG_EMULATE_HARDWARE
|
#if HAVE_NEON && !CONFIG_EMULATE_HARDWARE
|
||||||
INSTANTIATE_TEST_CASE_P(
|
const PartialInvTxfmParam neon_partial_idct_tests[] = {
|
||||||
SSE2, PartialIDctTest,
|
#if CONFIG_VP9_HIGHBITDEPTH
|
||||||
::testing::Values(
|
make_tuple(&vpx_highbd_fdct8x8_c,
|
||||||
make_tuple(&vpx_fdct32x32_c,
|
&highbd_wrapper<vpx_highbd_idct8x8_64_add_c>,
|
||||||
&vpx_idct32x32_1024_add_c,
|
&highbd_wrapper<vpx_highbd_idct8x8_64_add_neon>, TX_8X8, 64, 8, 2),
|
||||||
&vpx_idct32x32_34_add_sse2,
|
make_tuple(
|
||||||
TX_32X32, 34),
|
&vpx_highbd_fdct8x8_c, &highbd_wrapper<vpx_highbd_idct8x8_64_add_c>,
|
||||||
make_tuple(&vpx_fdct32x32_c,
|
&highbd_wrapper<vpx_highbd_idct8x8_64_add_neon>, TX_8X8, 64, 10, 2),
|
||||||
&vpx_idct32x32_1024_add_c,
|
make_tuple(
|
||||||
&vpx_idct32x32_1_add_sse2,
|
&vpx_highbd_fdct8x8_c, &highbd_wrapper<vpx_highbd_idct8x8_64_add_c>,
|
||||||
TX_32X32, 1),
|
&highbd_wrapper<vpx_highbd_idct8x8_64_add_neon>, TX_8X8, 64, 12, 2),
|
||||||
make_tuple(&vpx_fdct16x16_c,
|
make_tuple(&vpx_highbd_fdct8x8_c,
|
||||||
&vpx_idct16x16_256_add_c,
|
&highbd_wrapper<vpx_highbd_idct8x8_12_add_c>,
|
||||||
&vpx_idct16x16_10_add_sse2,
|
&highbd_wrapper<vpx_highbd_idct8x8_12_add_neon>, TX_8X8, 12, 8, 2),
|
||||||
TX_16X16, 10),
|
make_tuple(
|
||||||
make_tuple(&vpx_fdct16x16_c,
|
&vpx_highbd_fdct8x8_c, &highbd_wrapper<vpx_highbd_idct8x8_12_add_c>,
|
||||||
&vpx_idct16x16_256_add_c,
|
&highbd_wrapper<vpx_highbd_idct8x8_12_add_neon>, TX_8X8, 12, 10, 2),
|
||||||
&vpx_idct16x16_1_add_sse2,
|
make_tuple(
|
||||||
TX_16X16, 1),
|
&vpx_highbd_fdct8x8_c, &highbd_wrapper<vpx_highbd_idct8x8_12_add_c>,
|
||||||
make_tuple(&vpx_fdct8x8_c,
|
&highbd_wrapper<vpx_highbd_idct8x8_12_add_neon>, TX_8X8, 12, 12, 2),
|
||||||
&vpx_idct8x8_64_add_c,
|
make_tuple(&vpx_highbd_fdct8x8_c, &highbd_wrapper<vpx_highbd_idct8x8_1_add_c>,
|
||||||
&vpx_idct8x8_12_add_sse2,
|
&highbd_wrapper<vpx_highbd_idct8x8_1_add_neon>, TX_8X8, 1, 8, 2),
|
||||||
TX_8X8, 12),
|
make_tuple(&vpx_highbd_fdct8x8_c, &highbd_wrapper<vpx_highbd_idct8x8_1_add_c>,
|
||||||
make_tuple(&vpx_fdct8x8_c,
|
&highbd_wrapper<vpx_highbd_idct8x8_1_add_neon>, TX_8X8, 1, 10, 2),
|
||||||
&vpx_idct8x8_64_add_c,
|
make_tuple(&vpx_highbd_fdct8x8_c, &highbd_wrapper<vpx_highbd_idct8x8_1_add_c>,
|
||||||
&vpx_idct8x8_1_add_sse2,
|
&highbd_wrapper<vpx_highbd_idct8x8_1_add_neon>, TX_8X8, 1, 12, 2),
|
||||||
TX_8X8, 1),
|
make_tuple(&vpx_highbd_fdct4x4_c,
|
||||||
make_tuple(&vpx_fdct4x4_c,
|
&highbd_wrapper<vpx_highbd_idct4x4_16_add_c>,
|
||||||
&vpx_idct4x4_16_add_c,
|
&highbd_wrapper<vpx_highbd_idct4x4_16_add_neon>, TX_4X4, 16, 8, 2),
|
||||||
&vpx_idct4x4_1_add_sse2,
|
make_tuple(
|
||||||
TX_4X4, 1)));
|
&vpx_highbd_fdct4x4_c, &highbd_wrapper<vpx_highbd_idct4x4_16_add_c>,
|
||||||
#endif
|
&highbd_wrapper<vpx_highbd_idct4x4_16_add_neon>, TX_4X4, 16, 10, 2),
|
||||||
|
make_tuple(
|
||||||
|
&vpx_highbd_fdct4x4_c, &highbd_wrapper<vpx_highbd_idct4x4_16_add_c>,
|
||||||
|
&highbd_wrapper<vpx_highbd_idct4x4_16_add_neon>, TX_4X4, 16, 12, 2),
|
||||||
|
make_tuple(&vpx_highbd_fdct4x4_c, &highbd_wrapper<vpx_highbd_idct4x4_1_add_c>,
|
||||||
|
&highbd_wrapper<vpx_highbd_idct4x4_1_add_neon>, TX_4X4, 1, 8, 2),
|
||||||
|
make_tuple(&vpx_highbd_fdct4x4_c, &highbd_wrapper<vpx_highbd_idct4x4_1_add_c>,
|
||||||
|
&highbd_wrapper<vpx_highbd_idct4x4_1_add_neon>, TX_4X4, 1, 10, 2),
|
||||||
|
make_tuple(&vpx_highbd_fdct4x4_c, &highbd_wrapper<vpx_highbd_idct4x4_1_add_c>,
|
||||||
|
&highbd_wrapper<vpx_highbd_idct4x4_1_add_neon>, TX_4X4, 1, 12, 2),
|
||||||
|
#endif // CONFIG_VP9_HIGHBITDEPTH
|
||||||
|
make_tuple(&vpx_fdct32x32_c, &wrapper<vpx_idct32x32_1024_add_c>,
|
||||||
|
&wrapper<vpx_idct32x32_1024_add_neon>, TX_32X32, 1024, 8, 1),
|
||||||
|
make_tuple(&vpx_fdct32x32_c, &wrapper<vpx_idct32x32_1024_add_c>,
|
||||||
|
&wrapper<vpx_idct32x32_135_add_neon>, TX_32X32, 135, 8, 1),
|
||||||
|
make_tuple(&vpx_fdct32x32_c, &wrapper<vpx_idct32x32_1024_add_c>,
|
||||||
|
&wrapper<vpx_idct32x32_34_add_neon>, TX_32X32, 34, 8, 1),
|
||||||
|
make_tuple(&vpx_fdct32x32_c, &wrapper<vpx_idct32x32_1024_add_c>,
|
||||||
|
&wrapper<vpx_idct32x32_1_add_neon>, TX_32X32, 1, 8, 1),
|
||||||
|
make_tuple(&vpx_fdct16x16_c, &wrapper<vpx_idct16x16_256_add_c>,
|
||||||
|
&wrapper<vpx_idct16x16_256_add_neon>, TX_16X16, 256, 8, 1),
|
||||||
|
make_tuple(&vpx_fdct16x16_c, &wrapper<vpx_idct16x16_256_add_c>,
|
||||||
|
&wrapper<vpx_idct16x16_10_add_neon>, TX_16X16, 10, 8, 1),
|
||||||
|
make_tuple(&vpx_fdct16x16_c, &wrapper<vpx_idct16x16_256_add_c>,
|
||||||
|
&wrapper<vpx_idct16x16_1_add_neon>, TX_16X16, 1, 8, 1),
|
||||||
|
make_tuple(&vpx_fdct8x8_c, &wrapper<vpx_idct8x8_64_add_c>,
|
||||||
|
&wrapper<vpx_idct8x8_64_add_neon>, TX_8X8, 64, 8, 1),
|
||||||
|
make_tuple(&vpx_fdct8x8_c, &wrapper<vpx_idct8x8_64_add_c>,
|
||||||
|
&wrapper<vpx_idct8x8_12_add_neon>, TX_8X8, 12, 8, 1),
|
||||||
|
make_tuple(&vpx_fdct8x8_c, &wrapper<vpx_idct8x8_64_add_c>,
|
||||||
|
&wrapper<vpx_idct8x8_1_add_neon>, TX_8X8, 1, 8, 1),
|
||||||
|
make_tuple(&vpx_fdct4x4_c, &wrapper<vpx_idct4x4_16_add_c>,
|
||||||
|
&wrapper<vpx_idct4x4_16_add_neon>, TX_4X4, 16, 8, 1),
|
||||||
|
make_tuple(&vpx_fdct4x4_c, &wrapper<vpx_idct4x4_16_add_c>,
|
||||||
|
&wrapper<vpx_idct4x4_1_add_neon>, TX_4X4, 1, 8, 1)
|
||||||
|
};
|
||||||
|
|
||||||
#if HAVE_SSSE3 && CONFIG_USE_X86INC && ARCH_X86_64 && \
|
INSTANTIATE_TEST_CASE_P(NEON, PartialIDctTest,
|
||||||
!CONFIG_VP9_HIGHBITDEPTH && !CONFIG_EMULATE_HARDWARE
|
::testing::ValuesIn(neon_partial_idct_tests));
|
||||||
INSTANTIATE_TEST_CASE_P(
|
#endif // HAVE_NEON && !CONFIG_EMULATE_HARDWARE
|
||||||
SSSE3_64, PartialIDctTest,
|
|
||||||
::testing::Values(
|
|
||||||
make_tuple(&vpx_fdct8x8_c,
|
|
||||||
&vpx_idct8x8_64_add_c,
|
|
||||||
&vpx_idct8x8_12_add_ssse3,
|
|
||||||
TX_8X8, 12)));
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if HAVE_MSA && !CONFIG_VP9_HIGHBITDEPTH && !CONFIG_EMULATE_HARDWARE
|
#if HAVE_SSE2 && !CONFIG_EMULATE_HARDWARE
|
||||||
INSTANTIATE_TEST_CASE_P(
|
// 32x32_135_ is implemented using the 1024 version.
|
||||||
MSA, PartialIDctTest,
|
const PartialInvTxfmParam sse2_partial_idct_tests[] = {
|
||||||
::testing::Values(
|
#if CONFIG_VP9_HIGHBITDEPTH
|
||||||
make_tuple(&vpx_fdct32x32_c,
|
make_tuple(
|
||||||
&vpx_idct32x32_1024_add_c,
|
&vpx_highbd_fdct32x32_c, &highbd_wrapper<vpx_highbd_idct32x32_1024_add_c>,
|
||||||
&vpx_idct32x32_34_add_msa,
|
&highbd_wrapper<vpx_highbd_idct32x32_1_add_sse2>, TX_32X32, 1, 8, 2),
|
||||||
TX_32X32, 34),
|
make_tuple(
|
||||||
make_tuple(&vpx_fdct32x32_c,
|
&vpx_highbd_fdct32x32_c, &highbd_wrapper<vpx_highbd_idct32x32_1024_add_c>,
|
||||||
&vpx_idct32x32_1024_add_c,
|
&highbd_wrapper<vpx_highbd_idct32x32_1_add_sse2>, TX_32X32, 1, 10, 2),
|
||||||
&vpx_idct32x32_1_add_msa,
|
make_tuple(
|
||||||
TX_32X32, 1),
|
&vpx_highbd_fdct32x32_c, &highbd_wrapper<vpx_highbd_idct32x32_1024_add_c>,
|
||||||
make_tuple(&vpx_fdct16x16_c,
|
&highbd_wrapper<vpx_highbd_idct32x32_1_add_sse2>, TX_32X32, 1, 12, 2),
|
||||||
&vpx_idct16x16_256_add_c,
|
make_tuple(
|
||||||
&vpx_idct16x16_10_add_msa,
|
&vpx_highbd_fdct16x16_c, &highbd_wrapper<vpx_highbd_idct16x16_256_add_c>,
|
||||||
TX_16X16, 10),
|
&highbd_wrapper<vpx_highbd_idct16x16_256_add_sse2>, TX_16X16, 256, 8, 2),
|
||||||
make_tuple(&vpx_fdct16x16_c,
|
make_tuple(
|
||||||
&vpx_idct16x16_256_add_c,
|
&vpx_highbd_fdct16x16_c, &highbd_wrapper<vpx_highbd_idct16x16_256_add_c>,
|
||||||
&vpx_idct16x16_1_add_msa,
|
&highbd_wrapper<vpx_highbd_idct16x16_256_add_sse2>, TX_16X16, 256, 10, 2),
|
||||||
TX_16X16, 1),
|
make_tuple(
|
||||||
make_tuple(&vpx_fdct8x8_c,
|
&vpx_highbd_fdct16x16_c, &highbd_wrapper<vpx_highbd_idct16x16_256_add_c>,
|
||||||
&vpx_idct8x8_64_add_c,
|
&highbd_wrapper<vpx_highbd_idct16x16_256_add_sse2>, TX_16X16, 256, 12, 2),
|
||||||
&vpx_idct8x8_12_add_msa,
|
make_tuple(
|
||||||
TX_8X8, 10),
|
&vpx_highbd_fdct16x16_c, &highbd_wrapper<vpx_highbd_idct16x16_256_add_c>,
|
||||||
make_tuple(&vpx_fdct8x8_c,
|
&highbd_wrapper<vpx_highbd_idct16x16_10_add_sse2>, TX_16X16, 10, 8, 2),
|
||||||
&vpx_idct8x8_64_add_c,
|
make_tuple(
|
||||||
&vpx_idct8x8_1_add_msa,
|
&vpx_highbd_fdct16x16_c, &highbd_wrapper<vpx_highbd_idct16x16_256_add_c>,
|
||||||
TX_8X8, 1),
|
&highbd_wrapper<vpx_highbd_idct16x16_10_add_sse2>, TX_16X16, 10, 10, 2),
|
||||||
make_tuple(&vpx_fdct4x4_c,
|
make_tuple(
|
||||||
&vpx_idct4x4_16_add_c,
|
&vpx_highbd_fdct16x16_c, &highbd_wrapper<vpx_highbd_idct16x16_256_add_c>,
|
||||||
&vpx_idct4x4_1_add_msa,
|
&highbd_wrapper<vpx_highbd_idct16x16_10_add_sse2>, TX_16X16, 10, 12, 2),
|
||||||
TX_4X4, 1)));
|
make_tuple(&vpx_highbd_fdct8x8_c,
|
||||||
#endif // HAVE_MSA && !CONFIG_VP9_HIGHBITDEPTH && !CONFIG_EMULATE_HARDWARE
|
&highbd_wrapper<vpx_highbd_idct8x8_64_add_c>,
|
||||||
|
&highbd_wrapper<vpx_highbd_idct8x8_64_add_sse2>, TX_8X8, 64, 8, 2),
|
||||||
|
make_tuple(
|
||||||
|
&vpx_highbd_fdct8x8_c, &highbd_wrapper<vpx_highbd_idct8x8_64_add_c>,
|
||||||
|
&highbd_wrapper<vpx_highbd_idct8x8_64_add_sse2>, TX_8X8, 64, 10, 2),
|
||||||
|
make_tuple(
|
||||||
|
&vpx_highbd_fdct8x8_c, &highbd_wrapper<vpx_highbd_idct8x8_64_add_c>,
|
||||||
|
&highbd_wrapper<vpx_highbd_idct8x8_64_add_sse2>, TX_8X8, 64, 12, 2),
|
||||||
|
make_tuple(&vpx_highbd_fdct8x8_c,
|
||||||
|
&highbd_wrapper<vpx_highbd_idct8x8_64_add_c>,
|
||||||
|
&highbd_wrapper<vpx_highbd_idct8x8_12_add_sse2>, TX_8X8, 12, 8, 2),
|
||||||
|
make_tuple(
|
||||||
|
&vpx_highbd_fdct8x8_c, &highbd_wrapper<vpx_highbd_idct8x8_64_add_c>,
|
||||||
|
&highbd_wrapper<vpx_highbd_idct8x8_12_add_sse2>, TX_8X8, 12, 10, 2),
|
||||||
|
make_tuple(
|
||||||
|
&vpx_highbd_fdct8x8_c, &highbd_wrapper<vpx_highbd_idct8x8_64_add_c>,
|
||||||
|
&highbd_wrapper<vpx_highbd_idct8x8_12_add_sse2>, TX_8X8, 12, 12, 2),
|
||||||
|
make_tuple(&vpx_highbd_fdct4x4_c,
|
||||||
|
&highbd_wrapper<vpx_highbd_idct4x4_16_add_c>,
|
||||||
|
&highbd_wrapper<vpx_highbd_idct4x4_16_add_sse2>, TX_4X4, 16, 8, 2),
|
||||||
|
make_tuple(
|
||||||
|
&vpx_highbd_fdct4x4_c, &highbd_wrapper<vpx_highbd_idct4x4_16_add_c>,
|
||||||
|
&highbd_wrapper<vpx_highbd_idct4x4_16_add_sse2>, TX_4X4, 16, 10, 2),
|
||||||
|
make_tuple(
|
||||||
|
&vpx_highbd_fdct4x4_c, &highbd_wrapper<vpx_highbd_idct4x4_16_add_c>,
|
||||||
|
&highbd_wrapper<vpx_highbd_idct4x4_16_add_sse2>, TX_4X4, 16, 12, 2),
|
||||||
|
#endif // CONFIG_VP9_HIGHBITDEPTH
|
||||||
|
make_tuple(&vpx_fdct32x32_c, &wrapper<vpx_idct32x32_1024_add_c>,
|
||||||
|
&wrapper<vpx_idct32x32_1024_add_sse2>, TX_32X32, 1024, 8, 1),
|
||||||
|
make_tuple(&vpx_fdct32x32_c, &wrapper<vpx_idct32x32_1024_add_c>,
|
||||||
|
&wrapper<vpx_idct32x32_1024_add_sse2>, TX_32X32, 135, 8, 1),
|
||||||
|
make_tuple(&vpx_fdct32x32_c, &wrapper<vpx_idct32x32_1024_add_c>,
|
||||||
|
&wrapper<vpx_idct32x32_34_add_sse2>, TX_32X32, 34, 8, 1),
|
||||||
|
make_tuple(&vpx_fdct32x32_c, &wrapper<vpx_idct32x32_1024_add_c>,
|
||||||
|
&wrapper<vpx_idct32x32_1_add_sse2>, TX_32X32, 1, 8, 1),
|
||||||
|
make_tuple(&vpx_fdct16x16_c, &wrapper<vpx_idct16x16_256_add_c>,
|
||||||
|
&wrapper<vpx_idct16x16_256_add_sse2>, TX_16X16, 256, 8, 1),
|
||||||
|
make_tuple(&vpx_fdct16x16_c, &wrapper<vpx_idct16x16_256_add_c>,
|
||||||
|
&wrapper<vpx_idct16x16_10_add_sse2>, TX_16X16, 10, 8, 1),
|
||||||
|
make_tuple(&vpx_fdct16x16_c, &wrapper<vpx_idct16x16_256_add_c>,
|
||||||
|
&wrapper<vpx_idct16x16_1_add_sse2>, TX_16X16, 1, 8, 1),
|
||||||
|
make_tuple(&vpx_fdct8x8_c, &wrapper<vpx_idct8x8_64_add_c>,
|
||||||
|
&wrapper<vpx_idct8x8_64_add_sse2>, TX_8X8, 64, 8, 1),
|
||||||
|
make_tuple(&vpx_fdct8x8_c, &wrapper<vpx_idct8x8_64_add_c>,
|
||||||
|
&wrapper<vpx_idct8x8_12_add_sse2>, TX_8X8, 12, 8, 1),
|
||||||
|
make_tuple(&vpx_fdct8x8_c, &wrapper<vpx_idct8x8_64_add_c>,
|
||||||
|
&wrapper<vpx_idct8x8_1_add_sse2>, TX_8X8, 1, 8, 1),
|
||||||
|
make_tuple(&vpx_fdct4x4_c, &wrapper<vpx_idct4x4_16_add_c>,
|
||||||
|
&wrapper<vpx_idct4x4_16_add_sse2>, TX_4X4, 16, 8, 1),
|
||||||
|
make_tuple(&vpx_fdct4x4_c, &wrapper<vpx_idct4x4_16_add_c>,
|
||||||
|
&wrapper<vpx_idct4x4_1_add_sse2>, TX_4X4, 1, 8, 1)
|
||||||
|
};
|
||||||
|
|
||||||
|
INSTANTIATE_TEST_CASE_P(SSE2, PartialIDctTest,
|
||||||
|
::testing::ValuesIn(sse2_partial_idct_tests));
|
||||||
|
|
||||||
|
#endif // HAVE_SSE2 && !CONFIG_EMULATE_HARDWARE
|
||||||
|
|
||||||
|
#if HAVE_SSSE3 && ARCH_X86_64 && !CONFIG_EMULATE_HARDWARE
|
||||||
|
const PartialInvTxfmParam ssse3_partial_idct_tests[] = {
|
||||||
|
make_tuple(&vpx_fdct32x32_c, &wrapper<vpx_idct32x32_1024_add_c>,
|
||||||
|
&wrapper<vpx_idct32x32_1024_add_ssse3>, TX_32X32, 1024, 8, 1),
|
||||||
|
make_tuple(&vpx_fdct32x32_c, &wrapper<vpx_idct32x32_1024_add_c>,
|
||||||
|
&wrapper<vpx_idct32x32_135_add_ssse3>, TX_32X32, 135, 8, 1),
|
||||||
|
make_tuple(&vpx_fdct32x32_c, &wrapper<vpx_idct32x32_1024_add_c>,
|
||||||
|
&wrapper<vpx_idct32x32_34_add_ssse3>, TX_32X32, 34, 8, 1),
|
||||||
|
make_tuple(&vpx_fdct8x8_c, &wrapper<vpx_idct8x8_64_add_c>,
|
||||||
|
&wrapper<vpx_idct8x8_64_add_ssse3>, TX_8X8, 64, 8, 1),
|
||||||
|
make_tuple(&vpx_fdct8x8_c, &wrapper<vpx_idct8x8_64_add_c>,
|
||||||
|
&wrapper<vpx_idct8x8_12_add_ssse3>, TX_8X8, 12, 8, 1)
|
||||||
|
};
|
||||||
|
|
||||||
|
INSTANTIATE_TEST_CASE_P(SSSE3, PartialIDctTest,
|
||||||
|
::testing::ValuesIn(ssse3_partial_idct_tests));
|
||||||
|
#endif // HAVE_SSSE3 && ARCH_X86_64 && !CONFIG_EMULATE_HARDWARE
|
||||||
|
|
||||||
|
#if HAVE_DSPR2 && !CONFIG_EMULATE_HARDWARE && !CONFIG_VP9_HIGHBITDEPTH
|
||||||
|
const PartialInvTxfmParam dspr2_partial_idct_tests[] = {
|
||||||
|
make_tuple(&vpx_fdct32x32_c, &wrapper<vpx_idct32x32_1024_add_c>,
|
||||||
|
&wrapper<vpx_idct32x32_1024_add_dspr2>, TX_32X32, 1024, 8, 1),
|
||||||
|
make_tuple(&vpx_fdct32x32_c, &wrapper<vpx_idct32x32_1024_add_c>,
|
||||||
|
&wrapper<vpx_idct32x32_1024_add_dspr2>, TX_32X32, 135, 8, 1),
|
||||||
|
make_tuple(&vpx_fdct32x32_c, &wrapper<vpx_idct32x32_1024_add_c>,
|
||||||
|
&wrapper<vpx_idct32x32_34_add_dspr2>, TX_32X32, 34, 8, 1),
|
||||||
|
make_tuple(&vpx_fdct32x32_c, &wrapper<vpx_idct32x32_1024_add_c>,
|
||||||
|
&wrapper<vpx_idct32x32_1_add_dspr2>, TX_32X32, 1, 8, 1),
|
||||||
|
make_tuple(&vpx_fdct16x16_c, &wrapper<vpx_idct16x16_256_add_c>,
|
||||||
|
&wrapper<vpx_idct16x16_256_add_dspr2>, TX_16X16, 256, 8, 1),
|
||||||
|
make_tuple(&vpx_fdct16x16_c, &wrapper<vpx_idct16x16_256_add_c>,
|
||||||
|
&wrapper<vpx_idct16x16_10_add_dspr2>, TX_16X16, 10, 8, 1),
|
||||||
|
make_tuple(&vpx_fdct16x16_c, &wrapper<vpx_idct16x16_256_add_c>,
|
||||||
|
&wrapper<vpx_idct16x16_1_add_dspr2>, TX_16X16, 1, 8, 1),
|
||||||
|
make_tuple(&vpx_fdct8x8_c, &wrapper<vpx_idct8x8_64_add_c>,
|
||||||
|
&wrapper<vpx_idct8x8_64_add_dspr2>, TX_8X8, 64, 8, 1),
|
||||||
|
make_tuple(&vpx_fdct8x8_c, &wrapper<vpx_idct8x8_64_add_c>,
|
||||||
|
&wrapper<vpx_idct8x8_12_add_dspr2>, TX_8X8, 12, 8, 1),
|
||||||
|
make_tuple(&vpx_fdct8x8_c, &wrapper<vpx_idct8x8_64_add_c>,
|
||||||
|
&wrapper<vpx_idct8x8_1_add_dspr2>, TX_8X8, 1, 8, 1),
|
||||||
|
make_tuple(&vpx_fdct4x4_c, &wrapper<vpx_idct4x4_16_add_c>,
|
||||||
|
&wrapper<vpx_idct4x4_16_add_dspr2>, TX_4X4, 16, 8, 1),
|
||||||
|
make_tuple(&vpx_fdct4x4_c, &wrapper<vpx_idct4x4_16_add_c>,
|
||||||
|
&wrapper<vpx_idct4x4_1_add_dspr2>, TX_4X4, 1, 8, 1)
|
||||||
|
};
|
||||||
|
|
||||||
|
INSTANTIATE_TEST_CASE_P(DSPR2, PartialIDctTest,
|
||||||
|
::testing::ValuesIn(dspr2_partial_idct_tests));
|
||||||
|
#endif // HAVE_DSPR2 && !CONFIG_EMULATE_HARDWARE && !CONFIG_VP9_HIGHBITDEPTH
|
||||||
|
|
||||||
|
#if HAVE_MSA && !CONFIG_EMULATE_HARDWARE && !CONFIG_VP9_HIGHBITDEPTH
|
||||||
|
// 32x32_135_ is implemented using the 1024 version.
|
||||||
|
const PartialInvTxfmParam msa_partial_idct_tests[] = {
|
||||||
|
make_tuple(&vpx_fdct32x32_c, &wrapper<vpx_idct32x32_1024_add_c>,
|
||||||
|
&wrapper<vpx_idct32x32_1024_add_msa>, TX_32X32, 1024, 8, 1),
|
||||||
|
make_tuple(&vpx_fdct32x32_c, &wrapper<vpx_idct32x32_1024_add_c>,
|
||||||
|
&wrapper<vpx_idct32x32_1024_add_msa>, TX_32X32, 135, 8, 1),
|
||||||
|
make_tuple(&vpx_fdct32x32_c, &wrapper<vpx_idct32x32_1024_add_c>,
|
||||||
|
&wrapper<vpx_idct32x32_34_add_msa>, TX_32X32, 34, 8, 1),
|
||||||
|
make_tuple(&vpx_fdct32x32_c, &wrapper<vpx_idct32x32_1024_add_c>,
|
||||||
|
&wrapper<vpx_idct32x32_1_add_msa>, TX_32X32, 1, 8, 1),
|
||||||
|
make_tuple(&vpx_fdct16x16_c, &wrapper<vpx_idct16x16_256_add_c>,
|
||||||
|
&wrapper<vpx_idct16x16_256_add_msa>, TX_16X16, 256, 8, 1),
|
||||||
|
make_tuple(&vpx_fdct16x16_c, &wrapper<vpx_idct16x16_256_add_c>,
|
||||||
|
&wrapper<vpx_idct16x16_10_add_msa>, TX_16X16, 10, 8, 1),
|
||||||
|
make_tuple(&vpx_fdct16x16_c, &wrapper<vpx_idct16x16_256_add_c>,
|
||||||
|
&wrapper<vpx_idct16x16_1_add_msa>, TX_16X16, 1, 8, 1),
|
||||||
|
make_tuple(&vpx_fdct8x8_c, &wrapper<vpx_idct8x8_64_add_c>,
|
||||||
|
&wrapper<vpx_idct8x8_64_add_msa>, TX_8X8, 64, 8, 1),
|
||||||
|
make_tuple(&vpx_fdct8x8_c, &wrapper<vpx_idct8x8_64_add_c>,
|
||||||
|
&wrapper<vpx_idct8x8_12_add_msa>, TX_8X8, 12, 8, 1),
|
||||||
|
make_tuple(&vpx_fdct8x8_c, &wrapper<vpx_idct8x8_64_add_c>,
|
||||||
|
&wrapper<vpx_idct8x8_1_add_msa>, TX_8X8, 1, 8, 1),
|
||||||
|
make_tuple(&vpx_fdct4x4_c, &wrapper<vpx_idct4x4_16_add_c>,
|
||||||
|
&wrapper<vpx_idct4x4_16_add_msa>, TX_4X4, 16, 8, 1),
|
||||||
|
make_tuple(&vpx_fdct4x4_c, &wrapper<vpx_idct4x4_16_add_c>,
|
||||||
|
&wrapper<vpx_idct4x4_1_add_msa>, TX_4X4, 1, 8, 1)
|
||||||
|
};
|
||||||
|
|
||||||
|
INSTANTIATE_TEST_CASE_P(MSA, PartialIDctTest,
|
||||||
|
::testing::ValuesIn(msa_partial_idct_tests));
|
||||||
|
#endif // HAVE_MSA && !CONFIG_EMULATE_HARDWARE && !CONFIG_VP9_HIGHBITDEPTH
|
||||||
|
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|||||||
@@ -7,36 +7,48 @@
|
|||||||
* in the file PATENTS. All contributing project authors may
|
* in the file PATENTS. All contributing project authors may
|
||||||
* be found in the AUTHORS file in the root of the source tree.
|
* be found in the AUTHORS file in the root of the source tree.
|
||||||
*/
|
*/
|
||||||
|
#include <limits.h>
|
||||||
|
#include "./vpx_config.h"
|
||||||
|
#include "./vpx_dsp_rtcd.h"
|
||||||
|
#include "test/acm_random.h"
|
||||||
#include "test/clear_system_state.h"
|
#include "test/clear_system_state.h"
|
||||||
#include "test/register_state_check.h"
|
#include "test/register_state_check.h"
|
||||||
#include "third_party/googletest/src/include/gtest/gtest.h"
|
#include "third_party/googletest/src/include/gtest/gtest.h"
|
||||||
#include "./vpx_config.h"
|
|
||||||
#include "./vp8_rtcd.h"
|
|
||||||
#include "vpx/vpx_integer.h"
|
#include "vpx/vpx_integer.h"
|
||||||
#include "vpx_mem/vpx_mem.h"
|
#include "vpx_mem/vpx_mem.h"
|
||||||
|
|
||||||
typedef void (*PostProcFunc)(unsigned char *src_ptr,
|
using libvpx_test::ACMRandom;
|
||||||
unsigned char *dst_ptr,
|
|
||||||
int src_pixels_per_line,
|
typedef void (*VpxPostProcDownAndAcrossMbRowFunc)(
|
||||||
int dst_pixels_per_line,
|
unsigned char *src_ptr, unsigned char *dst_ptr, int src_pixels_per_line,
|
||||||
int cols,
|
int dst_pixels_per_line, int cols, unsigned char *flimit, int size);
|
||||||
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 {
|
namespace {
|
||||||
|
|
||||||
class VP8PostProcessingFilterTest
|
// Compute the filter level used in post proc from the loop filter strength
|
||||||
: public ::testing::TestWithParam<PostProcFunc> {
|
int q2mbl(int x) {
|
||||||
public:
|
if (x < 20) x = 20;
|
||||||
virtual void TearDown() {
|
|
||||||
libvpx_test::ClearSystemState();
|
x = 50 + (x - 50) * 10 / 8;
|
||||||
|
return x * x / 3;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
class VpxPostProcDownAndAcrossMbRowTest
|
||||||
|
: public ::testing::TestWithParam<VpxPostProcDownAndAcrossMbRowFunc> {
|
||||||
|
public:
|
||||||
|
virtual void TearDown() { libvpx_test::ClearSystemState(); }
|
||||||
};
|
};
|
||||||
|
|
||||||
// Test routine for the VP8 post-processing function
|
// Test routine for the VPx post-processing function
|
||||||
// vp8_post_proc_down_and_across_mb_row_c.
|
// vpx_post_proc_down_and_across_mb_row_c.
|
||||||
|
|
||||||
TEST_P(VP8PostProcessingFilterTest, FilterOutputCheck) {
|
TEST_P(VpxPostProcDownAndAcrossMbRowTest, CheckFilterOutput) {
|
||||||
// Size of the underlying data block that will be filtered.
|
// Size of the underlying data block that will be filtered.
|
||||||
const int block_width = 16;
|
const int block_width = 16;
|
||||||
const int block_height = 16;
|
const int block_height = 16;
|
||||||
@@ -53,14 +65,20 @@ TEST_P(VP8PostProcessingFilterTest, FilterOutputCheck) {
|
|||||||
const int output_stride = output_width;
|
const int output_stride = output_width;
|
||||||
const int output_size = output_width * output_height;
|
const int output_size = output_width * output_height;
|
||||||
|
|
||||||
uint8_t *const src_image =
|
uint8_t *const src_image = new uint8_t[input_size];
|
||||||
reinterpret_cast<uint8_t*>(vpx_calloc(input_size, 1));
|
ASSERT_TRUE(src_image != NULL);
|
||||||
uint8_t *const dst_image =
|
|
||||||
reinterpret_cast<uint8_t*>(vpx_calloc(output_size, 1));
|
// Though the left padding is only 8 bytes, the assembly code tries to
|
||||||
|
// read 16 bytes before the pointer.
|
||||||
|
uint8_t *const dst_image = new uint8_t[output_size + 8];
|
||||||
|
ASSERT_TRUE(dst_image != NULL);
|
||||||
|
|
||||||
// Pointers to top-left pixel of block in the input and output images.
|
// 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 src_image_ptr = src_image + (input_stride << 1);
|
||||||
uint8_t *const dst_image_ptr = dst_image + 8;
|
|
||||||
|
// The assembly works in increments of 16. The first read may be offset by
|
||||||
|
// this amount.
|
||||||
|
uint8_t *const dst_image_ptr = dst_image + 16;
|
||||||
uint8_t *const flimits =
|
uint8_t *const flimits =
|
||||||
reinterpret_cast<uint8_t *>(vpx_memalign(16, block_width));
|
reinterpret_cast<uint8_t *>(vpx_memalign(16, block_width));
|
||||||
(void)memset(flimits, 255, block_width);
|
(void)memset(flimits, 255, block_width);
|
||||||
@@ -80,39 +98,518 @@ TEST_P(VP8PostProcessingFilterTest, FilterOutputCheck) {
|
|||||||
// Initialize pixels in the output to 99.
|
// Initialize pixels in the output to 99.
|
||||||
(void)memset(dst_image, 99, output_size);
|
(void)memset(dst_image, 99, output_size);
|
||||||
|
|
||||||
ASM_REGISTER_STATE_CHECK(
|
ASM_REGISTER_STATE_CHECK(GetParam()(src_image_ptr, dst_image_ptr,
|
||||||
GetParam()(src_image_ptr, dst_image_ptr, input_stride,
|
input_stride, output_stride, block_width,
|
||||||
output_stride, block_width, flimits, 16));
|
flimits, 16));
|
||||||
|
|
||||||
static const uint8_t expected_data[block_height] = {
|
static const uint8_t kExpectedOutput[block_height] = {
|
||||||
4, 3, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 3, 4
|
4, 3, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 3, 4
|
||||||
};
|
};
|
||||||
|
|
||||||
pixel_ptr = dst_image_ptr;
|
pixel_ptr = dst_image_ptr;
|
||||||
for (int i = 0; i < block_height; ++i) {
|
for (int i = 0; i < block_height; ++i) {
|
||||||
for (int j = 0; j < block_width; ++j) {
|
for (int j = 0; j < block_width; ++j) {
|
||||||
EXPECT_EQ(expected_data[i], pixel_ptr[j])
|
ASSERT_EQ(kExpectedOutput[i], pixel_ptr[j]) << "at (" << i << ", " << j
|
||||||
<< "VP8PostProcessingFilterTest failed with invalid filter output";
|
<< ")";
|
||||||
}
|
}
|
||||||
pixel_ptr += output_stride;
|
pixel_ptr += output_stride;
|
||||||
}
|
}
|
||||||
|
|
||||||
vpx_free(src_image);
|
delete[] src_image;
|
||||||
vpx_free(dst_image);
|
delete[] dst_image;
|
||||||
vpx_free(flimits);
|
vpx_free(flimits);
|
||||||
};
|
};
|
||||||
|
|
||||||
INSTANTIATE_TEST_CASE_P(C, VP8PostProcessingFilterTest,
|
TEST_P(VpxPostProcDownAndAcrossMbRowTest, CheckCvsAssembly) {
|
||||||
::testing::Values(vp8_post_proc_down_and_across_mb_row_c));
|
// 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.
|
||||||
|
const int input_width = block_width;
|
||||||
|
const int input_height = block_height + 4 + 8;
|
||||||
|
const int input_stride = input_width;
|
||||||
|
const int input_size = input_stride * input_height;
|
||||||
|
|
||||||
|
// Filter extends output block by 8 samples at left and right edges.
|
||||||
|
// SSE2 reads in blocks of 16. Pad an extra 8 in case the width is not %16.
|
||||||
|
const int output_width = block_width + 24;
|
||||||
|
const int output_height = block_height;
|
||||||
|
const int output_stride = output_width;
|
||||||
|
const int output_size = output_stride * output_height;
|
||||||
|
|
||||||
|
uint8_t *const src_image = new uint8_t[input_size];
|
||||||
|
ASSERT_TRUE(src_image != NULL);
|
||||||
|
|
||||||
|
// Though the left padding is only 8 bytes, the assembly code tries to
|
||||||
|
// read 16 bytes before the pointer.
|
||||||
|
uint8_t *const dst_image = new uint8_t[output_size + 8];
|
||||||
|
ASSERT_TRUE(dst_image != NULL);
|
||||||
|
uint8_t *const dst_image_ref = new uint8_t[output_size + 8];
|
||||||
|
ASSERT_TRUE(dst_image_ref != NULL);
|
||||||
|
|
||||||
|
// Pointers to top-left pixel of block in the input and output images.
|
||||||
|
uint8_t *const src_image_ptr = src_image + (input_stride << 1);
|
||||||
|
|
||||||
|
// The assembly works in increments of 16. The first read may be offset by
|
||||||
|
// this amount.
|
||||||
|
uint8_t *const dst_image_ptr = dst_image + 16;
|
||||||
|
uint8_t *const dst_image_ref_ptr = dst_image + 16;
|
||||||
|
|
||||||
|
// 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.
|
||||||
|
(void)memset(src_image, 10, input_size);
|
||||||
|
uint8_t *pixel_ptr = src_image_ptr;
|
||||||
|
for (int i = 0; i < block_height; ++i) {
|
||||||
|
for (int j = 0; j < block_width; ++j) {
|
||||||
|
pixel_ptr[j] = rnd.Rand8();
|
||||||
|
}
|
||||||
|
pixel_ptr += input_stride;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int blocks = 0; blocks < block_width; blocks += 8) {
|
||||||
|
(void)memset(flimits, 0, sizeof(*flimits) * flimits_width);
|
||||||
|
|
||||||
|
for (int f = 0; f < 255; f++) {
|
||||||
|
(void)memset(flimits + blocks, f, sizeof(*flimits) * 8);
|
||||||
|
|
||||||
|
(void)memset(dst_image, 0, output_size);
|
||||||
|
(void)memset(dst_image_ref, 0, output_size);
|
||||||
|
|
||||||
|
vpx_post_proc_down_and_across_mb_row_c(
|
||||||
|
src_image_ptr, dst_image_ref_ptr, input_stride, output_stride,
|
||||||
|
block_width, flimits, block_height);
|
||||||
|
ASM_REGISTER_STATE_CHECK(GetParam()(src_image_ptr, dst_image_ptr,
|
||||||
|
input_stride, output_stride,
|
||||||
|
block_width, flimits, 16));
|
||||||
|
|
||||||
|
for (int i = 0; i < block_height; ++i) {
|
||||||
|
for (int j = 0; j < block_width; ++j) {
|
||||||
|
ASSERT_EQ(dst_image_ref_ptr[j + i * output_stride],
|
||||||
|
dst_image_ptr[j + i * output_stride])
|
||||||
|
<< "at (" << i << ", " << j << ")";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
delete[] src_image;
|
||||||
|
delete[] dst_image;
|
||||||
|
delete[] 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;
|
||||||
|
const int src_left_padding = 8;
|
||||||
|
const int src_right_padding = 17;
|
||||||
|
const int src_width = cols + src_left_padding + src_right_padding;
|
||||||
|
const int src_size = rows * src_width;
|
||||||
|
|
||||||
|
unsigned char *const src = new unsigned char[src_size];
|
||||||
|
ASSERT_TRUE(src != NULL);
|
||||||
|
memset(src, 10, src_size);
|
||||||
|
unsigned char *const s = src + src_left_padding;
|
||||||
|
SetCols(s, rows, cols, src_width);
|
||||||
|
|
||||||
|
unsigned char *expected_output = new unsigned char[rows * cols];
|
||||||
|
ASSERT_TRUE(expected_output != NULL);
|
||||||
|
SetCols(expected_output, rows, cols, cols);
|
||||||
|
|
||||||
|
RunFilterLevel(s, rows, cols, src_width, q2mbl(0), expected_output);
|
||||||
|
delete[] src;
|
||||||
|
delete[] expected_output;
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_P(VpxMbPostProcAcrossIpTest, CheckMediumFilterOutput) {
|
||||||
|
const int rows = 16;
|
||||||
|
const int cols = 16;
|
||||||
|
const int src_left_padding = 8;
|
||||||
|
const int src_right_padding = 17;
|
||||||
|
const int src_width = cols + src_left_padding + src_right_padding;
|
||||||
|
const int src_size = rows * src_width;
|
||||||
|
|
||||||
|
unsigned char *const src = new unsigned char[src_size];
|
||||||
|
ASSERT_TRUE(src != NULL);
|
||||||
|
memset(src, 10, src_size);
|
||||||
|
unsigned char *const s = src + src_left_padding;
|
||||||
|
|
||||||
|
SetCols(s, rows, cols, src_width);
|
||||||
|
static const unsigned char kExpectedOutput[cols] = {
|
||||||
|
2, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 13
|
||||||
|
};
|
||||||
|
|
||||||
|
RunFilterLevel(s, rows, cols, src_width, q2mbl(70), kExpectedOutput);
|
||||||
|
|
||||||
|
delete[] src;
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_P(VpxMbPostProcAcrossIpTest, CheckHighFilterOutput) {
|
||||||
|
const int rows = 16;
|
||||||
|
const int cols = 16;
|
||||||
|
const int src_left_padding = 8;
|
||||||
|
const int src_right_padding = 17;
|
||||||
|
const int src_width = cols + src_left_padding + src_right_padding;
|
||||||
|
const int src_size = rows * src_width;
|
||||||
|
|
||||||
|
unsigned char *const src = new unsigned char[src_size];
|
||||||
|
ASSERT_TRUE(src != NULL);
|
||||||
|
unsigned char *const s = src + src_left_padding;
|
||||||
|
|
||||||
|
memset(src, 10, src_size);
|
||||||
|
SetCols(s, rows, cols, src_width);
|
||||||
|
static const unsigned char kExpectedOutput[cols] = {
|
||||||
|
2, 2, 3, 4, 4, 5, 6, 7, 8, 9, 10, 11, 11, 12, 13, 13
|
||||||
|
};
|
||||||
|
|
||||||
|
RunFilterLevel(s, rows, cols, src_width, INT_MAX, kExpectedOutput);
|
||||||
|
|
||||||
|
memset(src, 10, src_size);
|
||||||
|
SetCols(s, rows, cols, src_width);
|
||||||
|
RunFilterLevel(s, rows, cols, src_width, q2mbl(100), kExpectedOutput);
|
||||||
|
|
||||||
|
delete[] src;
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_P(VpxMbPostProcAcrossIpTest, CheckCvsAssembly) {
|
||||||
|
const int rows = 16;
|
||||||
|
const int cols = 16;
|
||||||
|
const int src_left_padding = 8;
|
||||||
|
const int src_right_padding = 17;
|
||||||
|
const int src_width = cols + src_left_padding + src_right_padding;
|
||||||
|
const int src_size = rows * src_width;
|
||||||
|
|
||||||
|
unsigned char *const c_mem = new unsigned char[src_size];
|
||||||
|
unsigned char *const asm_mem = new unsigned char[src_size];
|
||||||
|
ASSERT_TRUE(c_mem != NULL);
|
||||||
|
ASSERT_TRUE(asm_mem != NULL);
|
||||||
|
unsigned char *const src_c = c_mem + src_left_padding;
|
||||||
|
unsigned char *const src_asm = asm_mem + src_left_padding;
|
||||||
|
|
||||||
|
// When level >= 100, the filter behaves the same as the level = INT_MAX
|
||||||
|
// When level < 20, it behaves the same as the level = 0
|
||||||
|
for (int level = 0; level < 100; level++) {
|
||||||
|
memset(c_mem, 10, src_size);
|
||||||
|
memset(asm_mem, 10, src_size);
|
||||||
|
SetCols(src_c, rows, cols, src_width);
|
||||||
|
SetCols(src_asm, rows, cols, src_width);
|
||||||
|
|
||||||
|
vpx_mbpost_proc_across_ip_c(src_c, src_width, rows, cols, q2mbl(level));
|
||||||
|
ASM_REGISTER_STATE_CHECK(
|
||||||
|
GetParam()(src_asm, src_width, rows, cols, q2mbl(level)));
|
||||||
|
|
||||||
|
RunComparison(src_c, src_asm, rows, cols, src_width);
|
||||||
|
}
|
||||||
|
|
||||||
|
delete[] c_mem;
|
||||||
|
delete[] asm_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) {
|
||||||
|
for (int r = 0; r < rows; r++) {
|
||||||
|
memset(src_c, r, cols);
|
||||||
|
src_c += cols;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void SetRandom(unsigned char *src_c, unsigned char *src_asm, int rows,
|
||||||
|
int cols, int src_pitch) {
|
||||||
|
ACMRandom rnd;
|
||||||
|
rnd.Reset(ACMRandom::DeterministicSeed());
|
||||||
|
|
||||||
|
// Add some random noise to the input
|
||||||
|
for (int r = 0; r < rows; r++) {
|
||||||
|
for (int c = 0; c < cols; c++) {
|
||||||
|
const int noise = rnd(4);
|
||||||
|
src_c[c] = r + noise;
|
||||||
|
src_asm[c] = r + noise;
|
||||||
|
}
|
||||||
|
src_c += src_pitch;
|
||||||
|
src_asm += src_pitch;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void SetRandomSaturation(unsigned char *src_c, unsigned char *src_asm,
|
||||||
|
int rows, int cols, int src_pitch) {
|
||||||
|
ACMRandom rnd;
|
||||||
|
rnd.Reset(ACMRandom::DeterministicSeed());
|
||||||
|
|
||||||
|
// Add some random noise to the input
|
||||||
|
for (int r = 0; r < rows; r++) {
|
||||||
|
for (int c = 0; c < cols; c++) {
|
||||||
|
const int noise = 3 * rnd(2);
|
||||||
|
src_c[c] = r + noise;
|
||||||
|
src_asm[c] = r + noise;
|
||||||
|
}
|
||||||
|
src_c += src_pitch;
|
||||||
|
src_asm += src_pitch;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
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 RunComparison(unsigned char *src_c, unsigned char *src_asm, int rows,
|
||||||
|
int cols, int src_pitch) {
|
||||||
|
for (int r = 0; r < rows; r++) {
|
||||||
|
for (int c = 0; c < cols; c++) {
|
||||||
|
ASSERT_EQ(src_c[c], src_asm[c]) << "at (" << r << ", " << c << ")";
|
||||||
|
}
|
||||||
|
src_c += src_pitch;
|
||||||
|
src_asm += src_pitch;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void RunFilterLevel(unsigned char *s, int rows, int cols, int src_width,
|
||||||
|
int filter_level, const unsigned char *expected_output) {
|
||||||
|
ASM_REGISTER_STATE_CHECK(
|
||||||
|
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;
|
||||||
|
const int src_pitch = cols;
|
||||||
|
const int src_top_padding = 8;
|
||||||
|
const int src_bottom_padding = 17;
|
||||||
|
|
||||||
|
const int src_size = cols * (rows + src_top_padding + src_bottom_padding);
|
||||||
|
unsigned char *const c_mem = new unsigned char[src_size];
|
||||||
|
ASSERT_TRUE(c_mem != NULL);
|
||||||
|
memset(c_mem, 10, src_size);
|
||||||
|
unsigned char *const src_c = c_mem + src_top_padding * src_pitch;
|
||||||
|
|
||||||
|
SetRows(src_c, rows, cols);
|
||||||
|
|
||||||
|
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, rows, cols, src_pitch, INT_MAX, kExpectedOutput);
|
||||||
|
|
||||||
|
memset(c_mem, 10, src_size);
|
||||||
|
SetRows(src_c, rows, cols);
|
||||||
|
RunFilterLevel(src_c, rows, cols, src_pitch, q2mbl(100), kExpectedOutput);
|
||||||
|
|
||||||
|
delete[] c_mem;
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_P(VpxMbPostProcDownTest, CheckMediumFilterOutput) {
|
||||||
|
const int rows = 16;
|
||||||
|
const int cols = 16;
|
||||||
|
const int src_pitch = cols;
|
||||||
|
const int src_top_padding = 8;
|
||||||
|
const int src_bottom_padding = 17;
|
||||||
|
|
||||||
|
const int src_size = cols * (rows + src_top_padding + src_bottom_padding);
|
||||||
|
unsigned char *const c_mem = new unsigned char[src_size];
|
||||||
|
ASSERT_TRUE(c_mem != NULL);
|
||||||
|
memset(c_mem, 10, src_size);
|
||||||
|
unsigned char *const src_c = c_mem + src_top_padding * src_pitch;
|
||||||
|
|
||||||
|
SetRows(src_c, rows, cols);
|
||||||
|
|
||||||
|
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, rows, cols, src_pitch, q2mbl(70), kExpectedOutput);
|
||||||
|
|
||||||
|
delete[] c_mem;
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_P(VpxMbPostProcDownTest, CheckLowFilterOutput) {
|
||||||
|
const int rows = 16;
|
||||||
|
const int cols = 16;
|
||||||
|
const int src_pitch = cols;
|
||||||
|
const int src_top_padding = 8;
|
||||||
|
const int src_bottom_padding = 17;
|
||||||
|
|
||||||
|
const int src_size = cols * (rows + src_top_padding + src_bottom_padding);
|
||||||
|
unsigned char *const c_mem = new unsigned char[src_size];
|
||||||
|
ASSERT_TRUE(c_mem != NULL);
|
||||||
|
memset(c_mem, 10, src_size);
|
||||||
|
unsigned char *const src_c = c_mem + src_top_padding * src_pitch;
|
||||||
|
|
||||||
|
SetRows(src_c, rows, cols);
|
||||||
|
|
||||||
|
unsigned char *expected_output = new unsigned char[rows * cols];
|
||||||
|
ASSERT_TRUE(expected_output != NULL);
|
||||||
|
SetRows(expected_output, rows, cols);
|
||||||
|
|
||||||
|
RunFilterLevel(src_c, rows, cols, src_pitch, q2mbl(0), expected_output);
|
||||||
|
|
||||||
|
delete[] c_mem;
|
||||||
|
delete[] expected_output;
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_P(VpxMbPostProcDownTest, CheckCvsAssembly) {
|
||||||
|
const int rows = 16;
|
||||||
|
const int cols = 16;
|
||||||
|
const int src_pitch = cols;
|
||||||
|
const int src_top_padding = 8;
|
||||||
|
const int src_bottom_padding = 17;
|
||||||
|
const int src_size = cols * (rows + src_top_padding + src_bottom_padding);
|
||||||
|
unsigned char *const c_mem = new unsigned char[src_size];
|
||||||
|
unsigned char *const asm_mem = new unsigned char[src_size];
|
||||||
|
ASSERT_TRUE(c_mem != NULL);
|
||||||
|
ASSERT_TRUE(asm_mem != NULL);
|
||||||
|
unsigned char *const src_c = c_mem + src_top_padding * src_pitch;
|
||||||
|
unsigned char *const src_asm = asm_mem + src_top_padding * src_pitch;
|
||||||
|
|
||||||
|
for (int level = 0; level < 100; level++) {
|
||||||
|
memset(c_mem, 10, src_size);
|
||||||
|
memset(asm_mem, 10, src_size);
|
||||||
|
SetRandom(src_c, src_asm, rows, cols, src_pitch);
|
||||||
|
vpx_mbpost_proc_down_c(src_c, src_pitch, rows, cols, q2mbl(level));
|
||||||
|
ASM_REGISTER_STATE_CHECK(
|
||||||
|
GetParam()(src_asm, src_pitch, rows, cols, q2mbl(level)));
|
||||||
|
RunComparison(src_c, src_asm, rows, cols, src_pitch);
|
||||||
|
|
||||||
|
memset(c_mem, 10, src_size);
|
||||||
|
memset(asm_mem, 10, src_size);
|
||||||
|
SetRandomSaturation(src_c, src_asm, rows, cols, src_pitch);
|
||||||
|
vpx_mbpost_proc_down_c(src_c, src_pitch, rows, cols, q2mbl(level));
|
||||||
|
ASM_REGISTER_STATE_CHECK(
|
||||||
|
GetParam()(src_asm, src_pitch, rows, cols, q2mbl(level)));
|
||||||
|
RunComparison(src_c, src_asm, rows, cols, src_pitch);
|
||||||
|
}
|
||||||
|
|
||||||
|
delete[] c_mem;
|
||||||
|
delete[] asm_mem;
|
||||||
|
}
|
||||||
|
|
||||||
|
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
|
#if HAVE_SSE2
|
||||||
INSTANTIATE_TEST_CASE_P(SSE2, VP8PostProcessingFilterTest,
|
INSTANTIATE_TEST_CASE_P(
|
||||||
::testing::Values(vp8_post_proc_down_and_across_mb_row_sse2));
|
SSE2, VpxPostProcDownAndAcrossMbRowTest,
|
||||||
#endif
|
::testing::Values(vpx_post_proc_down_and_across_mb_row_sse2));
|
||||||
|
|
||||||
|
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));
|
||||||
|
#endif // HAVE_NEON
|
||||||
|
|
||||||
#if HAVE_MSA
|
#if HAVE_MSA
|
||||||
INSTANTIATE_TEST_CASE_P(MSA, VP8PostProcessingFilterTest,
|
INSTANTIATE_TEST_CASE_P(
|
||||||
::testing::Values(vp8_post_proc_down_and_across_mb_row_msa));
|
MSA, VpxPostProcDownAndAcrossMbRowTest,
|
||||||
#endif
|
::testing::Values(vpx_post_proc_down_and_across_mb_row_msa));
|
||||||
|
|
||||||
|
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
|
} // namespace
|
||||||
|
|||||||
376
test/predict_test.cc
Normal file
376
test/predict_test.cc
Normal file
@@ -0,0 +1,376 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2013 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 <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
#include "third_party/googletest/src/include/gtest/gtest.h"
|
||||||
|
|
||||||
|
#include "./vp8_rtcd.h"
|
||||||
|
#include "./vpx_config.h"
|
||||||
|
#include "test/acm_random.h"
|
||||||
|
#include "test/clear_system_state.h"
|
||||||
|
#include "test/register_state_check.h"
|
||||||
|
#include "test/util.h"
|
||||||
|
#include "vpx/vpx_integer.h"
|
||||||
|
#include "vpx_mem/vpx_mem.h"
|
||||||
|
|
||||||
|
namespace {
|
||||||
|
|
||||||
|
using libvpx_test::ACMRandom;
|
||||||
|
using std::tr1::make_tuple;
|
||||||
|
|
||||||
|
typedef void (*PredictFunc)(uint8_t *src_ptr, int src_pixels_per_line,
|
||||||
|
int xoffset, int yoffset, uint8_t *dst_ptr,
|
||||||
|
int dst_pitch);
|
||||||
|
|
||||||
|
typedef std::tr1::tuple<int, int, PredictFunc> PredictParam;
|
||||||
|
|
||||||
|
class PredictTestBase : public ::testing::TestWithParam<PredictParam> {
|
||||||
|
public:
|
||||||
|
PredictTestBase()
|
||||||
|
: width_(GET_PARAM(0)), height_(GET_PARAM(1)), predict_(GET_PARAM(2)),
|
||||||
|
src_(NULL), padded_dst_(NULL), dst_(NULL), dst_c_(NULL) {}
|
||||||
|
|
||||||
|
virtual void SetUp() {
|
||||||
|
src_ = new uint8_t[kSrcSize];
|
||||||
|
ASSERT_TRUE(src_ != NULL);
|
||||||
|
|
||||||
|
// padded_dst_ provides a buffer of kBorderSize around the destination
|
||||||
|
// memory to facilitate detecting out of bounds writes.
|
||||||
|
dst_stride_ = kBorderSize + width_ + kBorderSize;
|
||||||
|
padded_dst_size_ = dst_stride_ * (kBorderSize + height_ + kBorderSize);
|
||||||
|
padded_dst_ =
|
||||||
|
reinterpret_cast<uint8_t *>(vpx_memalign(16, padded_dst_size_));
|
||||||
|
ASSERT_TRUE(padded_dst_ != NULL);
|
||||||
|
dst_ = padded_dst_ + (kBorderSize * dst_stride_) + kBorderSize;
|
||||||
|
|
||||||
|
dst_c_ = new uint8_t[16 * 16];
|
||||||
|
ASSERT_TRUE(dst_c_ != NULL);
|
||||||
|
|
||||||
|
memset(src_, 0, kSrcSize);
|
||||||
|
memset(padded_dst_, 128, padded_dst_size_);
|
||||||
|
memset(dst_c_, 0, 16 * 16);
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual void TearDown() {
|
||||||
|
delete[] src_;
|
||||||
|
src_ = NULL;
|
||||||
|
vpx_free(padded_dst_);
|
||||||
|
padded_dst_ = NULL;
|
||||||
|
dst_ = NULL;
|
||||||
|
delete[] dst_c_;
|
||||||
|
dst_c_ = NULL;
|
||||||
|
libvpx_test::ClearSystemState();
|
||||||
|
}
|
||||||
|
|
||||||
|
protected:
|
||||||
|
// Make reference arrays big enough for 16x16 functions. Six-tap filters need
|
||||||
|
// 5 extra pixels outside of the macroblock.
|
||||||
|
static const int kSrcStride = 21;
|
||||||
|
static const int kSrcSize = kSrcStride * kSrcStride;
|
||||||
|
static const int kBorderSize = 16;
|
||||||
|
|
||||||
|
int width_;
|
||||||
|
int height_;
|
||||||
|
PredictFunc predict_;
|
||||||
|
uint8_t *src_;
|
||||||
|
uint8_t *padded_dst_;
|
||||||
|
uint8_t *dst_;
|
||||||
|
int padded_dst_size_;
|
||||||
|
uint8_t *dst_c_;
|
||||||
|
int dst_stride_;
|
||||||
|
|
||||||
|
bool CompareBuffers(const uint8_t *a, int a_stride, const uint8_t *b,
|
||||||
|
int b_stride) const {
|
||||||
|
for (int height = 0; height < height_; ++height) {
|
||||||
|
EXPECT_EQ(0, memcmp(a + height * a_stride, b + height * b_stride,
|
||||||
|
sizeof(*a) * width_))
|
||||||
|
<< "Row " << height << " does not match.";
|
||||||
|
}
|
||||||
|
|
||||||
|
return !HasFailure();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Given a block of memory 'a' with size 'a_size', determine if all regions
|
||||||
|
// excepting block 'b' described by 'b_stride', 'b_height', and 'b_width'
|
||||||
|
// match pixel value 'c'.
|
||||||
|
bool CheckBorder(const uint8_t *a, int a_size, const uint8_t *b, int b_width,
|
||||||
|
int b_height, int b_stride, uint8_t c) const {
|
||||||
|
const uint8_t *a_end = a + a_size;
|
||||||
|
const int b_size = (b_stride * b_height) + b_width;
|
||||||
|
const uint8_t *b_end = b + b_size;
|
||||||
|
const int left_border = (b_stride - b_width) / 2;
|
||||||
|
const int right_border = left_border + ((b_stride - b_width) % 2);
|
||||||
|
|
||||||
|
EXPECT_GE(b - left_border, a) << "'b' does not start within 'a'";
|
||||||
|
EXPECT_LE(b_end + right_border, a_end) << "'b' does not end within 'a'";
|
||||||
|
|
||||||
|
// Top border.
|
||||||
|
for (int pixel = 0; pixel < b - a - left_border; ++pixel) {
|
||||||
|
EXPECT_EQ(c, a[pixel]) << "Mismatch at " << pixel << " in top border.";
|
||||||
|
}
|
||||||
|
|
||||||
|
// Left border.
|
||||||
|
for (int height = 0; height < b_height; ++height) {
|
||||||
|
for (int width = left_border; width > 0; --width) {
|
||||||
|
EXPECT_EQ(c, b[height * b_stride - width])
|
||||||
|
<< "Mismatch at row " << height << " column " << left_border - width
|
||||||
|
<< " in left border.";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Right border.
|
||||||
|
for (int height = 0; height < b_height; ++height) {
|
||||||
|
for (int width = b_width; width < b_width + right_border; ++width) {
|
||||||
|
EXPECT_EQ(c, b[height * b_stride + width])
|
||||||
|
<< "Mismatch at row " << height << " column " << width - b_width
|
||||||
|
<< " in right border.";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Bottom border.
|
||||||
|
for (int pixel = static_cast<int>(b - a + b_size); pixel < a_size;
|
||||||
|
++pixel) {
|
||||||
|
EXPECT_EQ(c, a[pixel]) << "Mismatch at " << pixel << " in bottom border.";
|
||||||
|
}
|
||||||
|
|
||||||
|
return !HasFailure();
|
||||||
|
}
|
||||||
|
|
||||||
|
void TestWithRandomData(PredictFunc reference) {
|
||||||
|
ACMRandom rnd(ACMRandom::DeterministicSeed());
|
||||||
|
|
||||||
|
// Run tests for almost all possible offsets.
|
||||||
|
for (int xoffset = 0; xoffset < 8; ++xoffset) {
|
||||||
|
for (int yoffset = 0; yoffset < 8; ++yoffset) {
|
||||||
|
if (xoffset == 0 && yoffset == 0) {
|
||||||
|
// This represents a copy which is not required to be handled by this
|
||||||
|
// module.
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int i = 0; i < kSrcSize; ++i) {
|
||||||
|
src_[i] = rnd.Rand8();
|
||||||
|
}
|
||||||
|
reference(&src_[kSrcStride * 2 + 2], kSrcStride, xoffset, yoffset,
|
||||||
|
dst_c_, 16);
|
||||||
|
|
||||||
|
ASM_REGISTER_STATE_CHECK(predict_(&src_[kSrcStride * 2 + 2], kSrcStride,
|
||||||
|
xoffset, yoffset, dst_, dst_stride_));
|
||||||
|
|
||||||
|
ASSERT_TRUE(CompareBuffers(dst_c_, 16, dst_, dst_stride_));
|
||||||
|
ASSERT_TRUE(CheckBorder(padded_dst_, padded_dst_size_, dst_, width_,
|
||||||
|
height_, dst_stride_, 128));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void TestWithUnalignedDst(PredictFunc reference) {
|
||||||
|
ACMRandom rnd(ACMRandom::DeterministicSeed());
|
||||||
|
|
||||||
|
// Only the 4x4 need to be able to handle unaligned writes.
|
||||||
|
if (width_ == 4 && height_ == 4) {
|
||||||
|
for (int xoffset = 0; xoffset < 8; ++xoffset) {
|
||||||
|
for (int yoffset = 0; yoffset < 8; ++yoffset) {
|
||||||
|
if (xoffset == 0 && yoffset == 0) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
for (int i = 0; i < kSrcSize; ++i) {
|
||||||
|
src_[i] = rnd.Rand8();
|
||||||
|
}
|
||||||
|
reference(&src_[kSrcStride * 2 + 2], kSrcStride, xoffset, yoffset,
|
||||||
|
dst_c_, 16);
|
||||||
|
|
||||||
|
for (int i = 1; i < 4; ++i) {
|
||||||
|
memset(padded_dst_, 128, padded_dst_size_);
|
||||||
|
|
||||||
|
ASM_REGISTER_STATE_CHECK(predict_(&src_[kSrcStride * 2 + 2],
|
||||||
|
kSrcStride, xoffset, yoffset,
|
||||||
|
dst_ + i, dst_stride_ + i));
|
||||||
|
|
||||||
|
ASSERT_TRUE(CompareBuffers(dst_c_, 16, dst_ + i, dst_stride_ + i));
|
||||||
|
ASSERT_TRUE(CheckBorder(padded_dst_, padded_dst_size_, dst_ + i,
|
||||||
|
width_, height_, dst_stride_ + i, 128));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
class SixtapPredictTest : public PredictTestBase {};
|
||||||
|
|
||||||
|
TEST_P(SixtapPredictTest, TestWithRandomData) {
|
||||||
|
TestWithRandomData(vp8_sixtap_predict16x16_c);
|
||||||
|
}
|
||||||
|
TEST_P(SixtapPredictTest, TestWithUnalignedDst) {
|
||||||
|
TestWithUnalignedDst(vp8_sixtap_predict16x16_c);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_P(SixtapPredictTest, TestWithPresetData) {
|
||||||
|
// Test input
|
||||||
|
static const uint8_t kTestData[kSrcSize] = {
|
||||||
|
184, 4, 191, 82, 92, 41, 0, 1, 226, 236, 172, 20, 182, 42, 226,
|
||||||
|
177, 79, 94, 77, 179, 203, 206, 198, 22, 192, 19, 75, 17, 192, 44,
|
||||||
|
233, 120, 48, 168, 203, 141, 210, 203, 143, 180, 184, 59, 201, 110, 102,
|
||||||
|
171, 32, 182, 10, 109, 105, 213, 60, 47, 236, 253, 67, 55, 14, 3,
|
||||||
|
99, 247, 124, 148, 159, 71, 34, 114, 19, 177, 38, 203, 237, 239, 58,
|
||||||
|
83, 155, 91, 10, 166, 201, 115, 124, 5, 163, 104, 2, 231, 160, 16,
|
||||||
|
234, 4, 8, 103, 153, 167, 174, 187, 26, 193, 109, 64, 141, 90, 48,
|
||||||
|
200, 174, 204, 36, 184, 114, 237, 43, 238, 242, 207, 86, 245, 182, 247,
|
||||||
|
6, 161, 251, 14, 8, 148, 182, 182, 79, 208, 120, 188, 17, 6, 23,
|
||||||
|
65, 206, 197, 13, 242, 126, 128, 224, 170, 110, 211, 121, 197, 200, 47,
|
||||||
|
188, 207, 208, 184, 221, 216, 76, 148, 143, 156, 100, 8, 89, 117, 14,
|
||||||
|
112, 183, 221, 54, 197, 208, 180, 69, 176, 94, 180, 131, 215, 121, 76,
|
||||||
|
7, 54, 28, 216, 238, 249, 176, 58, 142, 64, 215, 242, 72, 49, 104,
|
||||||
|
87, 161, 32, 52, 216, 230, 4, 141, 44, 181, 235, 224, 57, 195, 89,
|
||||||
|
134, 203, 144, 162, 163, 126, 156, 84, 185, 42, 148, 145, 29, 221, 194,
|
||||||
|
134, 52, 100, 166, 105, 60, 140, 110, 201, 184, 35, 181, 153, 93, 121,
|
||||||
|
243, 227, 68, 131, 134, 232, 2, 35, 60, 187, 77, 209, 76, 106, 174,
|
||||||
|
15, 241, 227, 115, 151, 77, 175, 36, 187, 121, 221, 223, 47, 118, 61,
|
||||||
|
168, 105, 32, 237, 236, 167, 213, 238, 202, 17, 170, 24, 226, 247, 131,
|
||||||
|
145, 6, 116, 117, 121, 11, 194, 41, 48, 126, 162, 13, 93, 209, 131,
|
||||||
|
154, 122, 237, 187, 103, 217, 99, 60, 200, 45, 78, 115, 69, 49, 106,
|
||||||
|
200, 194, 112, 60, 56, 234, 72, 251, 19, 120, 121, 182, 134, 215, 135,
|
||||||
|
10, 114, 2, 247, 46, 105, 209, 145, 165, 153, 191, 243, 12, 5, 36,
|
||||||
|
119, 206, 231, 231, 11, 32, 209, 83, 27, 229, 204, 149, 155, 83, 109,
|
||||||
|
35, 93, 223, 37, 84, 14, 142, 37, 160, 52, 191, 96, 40, 204, 101,
|
||||||
|
77, 67, 52, 53, 43, 63, 85, 253, 147, 113, 226, 96, 6, 125, 179,
|
||||||
|
115, 161, 17, 83, 198, 101, 98, 85, 139, 3, 137, 75, 99, 178, 23,
|
||||||
|
201, 255, 91, 253, 52, 134, 60, 138, 131, 208, 251, 101, 48, 2, 227,
|
||||||
|
228, 118, 132, 245, 202, 75, 91, 44, 160, 231, 47, 41, 50, 147, 220,
|
||||||
|
74, 92, 219, 165, 89, 16
|
||||||
|
};
|
||||||
|
|
||||||
|
// Expected results for xoffset = 2 and yoffset = 2.
|
||||||
|
static const int kExpectedDstStride = 16;
|
||||||
|
static const uint8_t kExpectedDst[256] = {
|
||||||
|
117, 102, 74, 135, 42, 98, 175, 206, 70, 73, 222, 197, 50, 24, 39,
|
||||||
|
49, 38, 105, 90, 47, 169, 40, 171, 215, 200, 73, 109, 141, 53, 85,
|
||||||
|
177, 164, 79, 208, 124, 89, 212, 18, 81, 145, 151, 164, 217, 153, 91,
|
||||||
|
154, 102, 102, 159, 75, 164, 152, 136, 51, 213, 219, 186, 116, 193, 224,
|
||||||
|
186, 36, 231, 208, 84, 211, 155, 167, 35, 59, 42, 76, 216, 149, 73,
|
||||||
|
201, 78, 149, 184, 100, 96, 196, 189, 198, 188, 235, 195, 117, 129, 120,
|
||||||
|
129, 49, 25, 133, 113, 69, 221, 114, 70, 143, 99, 157, 108, 189, 140,
|
||||||
|
78, 6, 55, 65, 240, 255, 245, 184, 72, 90, 100, 116, 131, 39, 60,
|
||||||
|
234, 167, 33, 160, 88, 185, 200, 157, 159, 176, 127, 151, 138, 102, 168,
|
||||||
|
106, 170, 86, 82, 219, 189, 76, 33, 115, 197, 106, 96, 198, 136, 97,
|
||||||
|
141, 237, 151, 98, 137, 191, 185, 2, 57, 95, 142, 91, 255, 185, 97,
|
||||||
|
137, 76, 162, 94, 173, 131, 193, 161, 81, 106, 72, 135, 222, 234, 137,
|
||||||
|
66, 137, 106, 243, 210, 147, 95, 15, 137, 110, 85, 66, 16, 96, 167,
|
||||||
|
147, 150, 173, 203, 140, 118, 196, 84, 147, 160, 19, 95, 101, 123, 74,
|
||||||
|
132, 202, 82, 166, 12, 131, 166, 189, 170, 159, 85, 79, 66, 57, 152,
|
||||||
|
132, 203, 194, 0, 1, 56, 146, 180, 224, 156, 28, 83, 181, 79, 76,
|
||||||
|
80, 46, 160, 175, 59, 106, 43, 87, 75, 136, 85, 189, 46, 71, 200,
|
||||||
|
90
|
||||||
|
};
|
||||||
|
|
||||||
|
ASM_REGISTER_STATE_CHECK(
|
||||||
|
predict_(const_cast<uint8_t *>(kTestData) + kSrcStride * 2 + 2,
|
||||||
|
kSrcStride, 2, 2, dst_, dst_stride_));
|
||||||
|
|
||||||
|
ASSERT_TRUE(
|
||||||
|
CompareBuffers(kExpectedDst, kExpectedDstStride, dst_, dst_stride_));
|
||||||
|
}
|
||||||
|
|
||||||
|
INSTANTIATE_TEST_CASE_P(
|
||||||
|
C, SixtapPredictTest,
|
||||||
|
::testing::Values(make_tuple(16, 16, &vp8_sixtap_predict16x16_c),
|
||||||
|
make_tuple(8, 8, &vp8_sixtap_predict8x8_c),
|
||||||
|
make_tuple(8, 4, &vp8_sixtap_predict8x4_c),
|
||||||
|
make_tuple(4, 4, &vp8_sixtap_predict4x4_c)));
|
||||||
|
#if HAVE_NEON
|
||||||
|
INSTANTIATE_TEST_CASE_P(
|
||||||
|
NEON, SixtapPredictTest,
|
||||||
|
::testing::Values(make_tuple(16, 16, &vp8_sixtap_predict16x16_neon),
|
||||||
|
make_tuple(8, 8, &vp8_sixtap_predict8x8_neon),
|
||||||
|
make_tuple(8, 4, &vp8_sixtap_predict8x4_neon),
|
||||||
|
make_tuple(4, 4, &vp8_sixtap_predict4x4_neon)));
|
||||||
|
#endif
|
||||||
|
#if HAVE_MMX
|
||||||
|
INSTANTIATE_TEST_CASE_P(
|
||||||
|
MMX, SixtapPredictTest,
|
||||||
|
::testing::Values(make_tuple(4, 4, &vp8_sixtap_predict4x4_mmx)));
|
||||||
|
#endif
|
||||||
|
#if HAVE_SSE2
|
||||||
|
INSTANTIATE_TEST_CASE_P(
|
||||||
|
SSE2, SixtapPredictTest,
|
||||||
|
::testing::Values(make_tuple(16, 16, &vp8_sixtap_predict16x16_sse2),
|
||||||
|
make_tuple(8, 8, &vp8_sixtap_predict8x8_sse2),
|
||||||
|
make_tuple(8, 4, &vp8_sixtap_predict8x4_sse2)));
|
||||||
|
#endif
|
||||||
|
#if HAVE_SSSE3
|
||||||
|
INSTANTIATE_TEST_CASE_P(
|
||||||
|
SSSE3, SixtapPredictTest,
|
||||||
|
::testing::Values(make_tuple(16, 16, &vp8_sixtap_predict16x16_ssse3),
|
||||||
|
make_tuple(8, 8, &vp8_sixtap_predict8x8_ssse3),
|
||||||
|
make_tuple(8, 4, &vp8_sixtap_predict8x4_ssse3),
|
||||||
|
make_tuple(4, 4, &vp8_sixtap_predict4x4_ssse3)));
|
||||||
|
#endif
|
||||||
|
#if HAVE_MSA
|
||||||
|
INSTANTIATE_TEST_CASE_P(
|
||||||
|
MSA, SixtapPredictTest,
|
||||||
|
::testing::Values(make_tuple(16, 16, &vp8_sixtap_predict16x16_msa),
|
||||||
|
make_tuple(8, 8, &vp8_sixtap_predict8x8_msa),
|
||||||
|
make_tuple(8, 4, &vp8_sixtap_predict8x4_msa),
|
||||||
|
make_tuple(4, 4, &vp8_sixtap_predict4x4_msa)));
|
||||||
|
#endif
|
||||||
|
|
||||||
|
class BilinearPredictTest : public PredictTestBase {};
|
||||||
|
|
||||||
|
TEST_P(BilinearPredictTest, TestWithRandomData) {
|
||||||
|
TestWithRandomData(vp8_bilinear_predict16x16_c);
|
||||||
|
}
|
||||||
|
TEST_P(BilinearPredictTest, TestWithUnalignedDst) {
|
||||||
|
TestWithUnalignedDst(vp8_bilinear_predict16x16_c);
|
||||||
|
}
|
||||||
|
|
||||||
|
INSTANTIATE_TEST_CASE_P(
|
||||||
|
C, BilinearPredictTest,
|
||||||
|
::testing::Values(make_tuple(16, 16, &vp8_bilinear_predict16x16_c),
|
||||||
|
make_tuple(8, 8, &vp8_bilinear_predict8x8_c),
|
||||||
|
make_tuple(8, 4, &vp8_bilinear_predict8x4_c),
|
||||||
|
make_tuple(4, 4, &vp8_bilinear_predict4x4_c)));
|
||||||
|
#if HAVE_NEON
|
||||||
|
INSTANTIATE_TEST_CASE_P(
|
||||||
|
NEON, BilinearPredictTest,
|
||||||
|
::testing::Values(make_tuple(16, 16, &vp8_bilinear_predict16x16_neon),
|
||||||
|
make_tuple(8, 8, &vp8_bilinear_predict8x8_neon),
|
||||||
|
make_tuple(8, 4, &vp8_bilinear_predict8x4_neon),
|
||||||
|
make_tuple(4, 4, &vp8_bilinear_predict4x4_neon)));
|
||||||
|
#endif
|
||||||
|
#if HAVE_MMX
|
||||||
|
INSTANTIATE_TEST_CASE_P(
|
||||||
|
MMX, BilinearPredictTest,
|
||||||
|
::testing::Values(make_tuple(8, 4, &vp8_bilinear_predict8x4_mmx),
|
||||||
|
make_tuple(4, 4, &vp8_bilinear_predict4x4_mmx)));
|
||||||
|
#endif
|
||||||
|
#if HAVE_SSE2
|
||||||
|
INSTANTIATE_TEST_CASE_P(
|
||||||
|
SSE2, BilinearPredictTest,
|
||||||
|
::testing::Values(make_tuple(16, 16, &vp8_bilinear_predict16x16_sse2),
|
||||||
|
make_tuple(8, 8, &vp8_bilinear_predict8x8_sse2)));
|
||||||
|
#endif
|
||||||
|
#if HAVE_SSSE3
|
||||||
|
INSTANTIATE_TEST_CASE_P(
|
||||||
|
SSSE3, BilinearPredictTest,
|
||||||
|
::testing::Values(make_tuple(16, 16, &vp8_bilinear_predict16x16_ssse3),
|
||||||
|
make_tuple(8, 8, &vp8_bilinear_predict8x8_ssse3)));
|
||||||
|
#endif
|
||||||
|
#if HAVE_MSA
|
||||||
|
INSTANTIATE_TEST_CASE_P(
|
||||||
|
MSA, BilinearPredictTest,
|
||||||
|
::testing::Values(make_tuple(16, 16, &vp8_bilinear_predict16x16_msa),
|
||||||
|
make_tuple(8, 8, &vp8_bilinear_predict8x8_msa),
|
||||||
|
make_tuple(8, 4, &vp8_bilinear_predict8x4_msa),
|
||||||
|
make_tuple(4, 4, &vp8_bilinear_predict4x4_msa)));
|
||||||
|
#endif
|
||||||
|
} // namespace
|
||||||
63
test/realtime_test.cc
Normal file
63
test/realtime_test.cc
Normal file
@@ -0,0 +1,63 @@
|
|||||||
|
/*
|
||||||
|
* 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 "test/codec_factory.h"
|
||||||
|
#include "test/encode_test_driver.h"
|
||||||
|
#include "test/util.h"
|
||||||
|
#include "test/video_source.h"
|
||||||
|
#include "third_party/googletest/src/include/gtest/gtest.h"
|
||||||
|
|
||||||
|
namespace {
|
||||||
|
|
||||||
|
const int kVideoSourceWidth = 320;
|
||||||
|
const int kVideoSourceHeight = 240;
|
||||||
|
const int kFramesToEncode = 2;
|
||||||
|
|
||||||
|
class RealtimeTest
|
||||||
|
: public ::libvpx_test::EncoderTest,
|
||||||
|
public ::libvpx_test::CodecTestWithParam<libvpx_test::TestMode> {
|
||||||
|
protected:
|
||||||
|
RealtimeTest() : EncoderTest(GET_PARAM(0)), frame_packets_(0) {}
|
||||||
|
virtual ~RealtimeTest() {}
|
||||||
|
|
||||||
|
virtual void SetUp() {
|
||||||
|
InitializeConfig();
|
||||||
|
cfg_.g_lag_in_frames = 0;
|
||||||
|
SetMode(::libvpx_test::kRealTime);
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual void BeginPassHook(unsigned int /*pass*/) {
|
||||||
|
// TODO(tomfinegan): We're changing the pass value here to make sure
|
||||||
|
// we get frames when real time mode is combined with |g_pass| set to
|
||||||
|
// VPX_RC_FIRST_PASS. This is necessary because EncoderTest::RunLoop() sets
|
||||||
|
// the pass value based on the mode passed into EncoderTest::SetMode(),
|
||||||
|
// which overrides the one specified in SetUp() above.
|
||||||
|
cfg_.g_pass = VPX_RC_FIRST_PASS;
|
||||||
|
}
|
||||||
|
virtual void FramePktHook(const vpx_codec_cx_pkt_t * /*pkt*/) {
|
||||||
|
frame_packets_++;
|
||||||
|
}
|
||||||
|
|
||||||
|
int frame_packets_;
|
||||||
|
};
|
||||||
|
|
||||||
|
TEST_P(RealtimeTest, RealtimeFirstPassProducesFrames) {
|
||||||
|
::libvpx_test::RandomVideoSource video;
|
||||||
|
video.SetSize(kVideoSourceWidth, kVideoSourceHeight);
|
||||||
|
video.set_limit(kFramesToEncode);
|
||||||
|
ASSERT_NO_FATAL_FAILURE(RunLoop(&video));
|
||||||
|
EXPECT_EQ(kFramesToEncode, frame_packets_);
|
||||||
|
}
|
||||||
|
|
||||||
|
VP8_INSTANTIATE_TEST_CASE(RealtimeTest,
|
||||||
|
::testing::Values(::libvpx_test::kRealTime));
|
||||||
|
VP9_INSTANTIATE_TEST_CASE(RealtimeTest,
|
||||||
|
::testing::Values(::libvpx_test::kRealTime));
|
||||||
|
|
||||||
|
} // namespace
|
||||||
@@ -32,7 +32,9 @@
|
|||||||
|
|
||||||
#undef NOMINMAX
|
#undef NOMINMAX
|
||||||
#define NOMINMAX
|
#define NOMINMAX
|
||||||
|
#ifndef WIN32_LEAN_AND_MEAN
|
||||||
#define WIN32_LEAN_AND_MEAN
|
#define WIN32_LEAN_AND_MEAN
|
||||||
|
#endif
|
||||||
#include <windows.h>
|
#include <windows.h>
|
||||||
#include <winnt.h>
|
#include <winnt.h>
|
||||||
|
|
||||||
@@ -48,7 +50,7 @@ namespace libvpx_test {
|
|||||||
class RegisterStateCheck {
|
class RegisterStateCheck {
|
||||||
public:
|
public:
|
||||||
RegisterStateCheck() { initialized_ = StoreRegisters(&pre_context_); }
|
RegisterStateCheck() { initialized_ = StoreRegisters(&pre_context_); }
|
||||||
~RegisterStateCheck() { EXPECT_TRUE(Check()); }
|
~RegisterStateCheck() { Check(); }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
static bool StoreRegisters(CONTEXT *const context) {
|
static bool StoreRegisters(CONTEXT *const context) {
|
||||||
@@ -61,10 +63,10 @@ class RegisterStateCheck {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Compares the register state. Returns true if the states match.
|
// Compares the register state. Returns true if the states match.
|
||||||
bool Check() const {
|
void Check() const {
|
||||||
if (!initialized_) return false;
|
ASSERT_TRUE(initialized_);
|
||||||
CONTEXT post_context;
|
CONTEXT post_context;
|
||||||
if (!StoreRegisters(&post_context)) return false;
|
ASSERT_TRUE(StoreRegisters(&post_context));
|
||||||
|
|
||||||
const M128A *xmm_pre = &pre_context_.Xmm6;
|
const M128A *xmm_pre = &pre_context_.Xmm6;
|
||||||
const M128A *xmm_post = &post_context.Xmm6;
|
const M128A *xmm_post = &post_context.Xmm6;
|
||||||
@@ -73,22 +75,22 @@ class RegisterStateCheck {
|
|||||||
++xmm_pre;
|
++xmm_pre;
|
||||||
++xmm_post;
|
++xmm_post;
|
||||||
}
|
}
|
||||||
return !testing::Test::HasNonfatalFailure();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool initialized_;
|
bool initialized_;
|
||||||
CONTEXT pre_context_;
|
CONTEXT pre_context_;
|
||||||
};
|
};
|
||||||
|
|
||||||
#define ASM_REGISTER_STATE_CHECK(statement) do { \
|
#define ASM_REGISTER_STATE_CHECK(statement) \
|
||||||
|
do { \
|
||||||
libvpx_test::RegisterStateCheck reg_check; \
|
libvpx_test::RegisterStateCheck reg_check; \
|
||||||
statement; \
|
statement; \
|
||||||
} while (false)
|
} while (false)
|
||||||
|
|
||||||
} // namespace libvpx_test
|
} // namespace libvpx_test
|
||||||
|
|
||||||
#elif defined(CONFIG_SHARED) && defined(HAVE_NEON_ASM) && defined(CONFIG_VP9) \
|
#elif defined(CONFIG_SHARED) && defined(HAVE_NEON_ASM) && \
|
||||||
&& !CONFIG_SHARED && HAVE_NEON_ASM && CONFIG_VP9
|
defined(CONFIG_VP9) && !CONFIG_SHARED && HAVE_NEON_ASM && CONFIG_VP9
|
||||||
|
|
||||||
extern "C" {
|
extern "C" {
|
||||||
// Save the d8-d15 registers into store.
|
// Save the d8-d15 registers into store.
|
||||||
@@ -102,32 +104,25 @@ namespace libvpx_test {
|
|||||||
// arm platform.
|
// arm platform.
|
||||||
class RegisterStateCheck {
|
class RegisterStateCheck {
|
||||||
public:
|
public:
|
||||||
RegisterStateCheck() { initialized_ = StoreRegisters(pre_store_); }
|
RegisterStateCheck() { vpx_push_neon(pre_store_); }
|
||||||
~RegisterStateCheck() { EXPECT_TRUE(Check()); }
|
~RegisterStateCheck() { Check(); }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
static bool StoreRegisters(int64_t store[8]) {
|
|
||||||
vpx_push_neon(store);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Compares the register state. Returns true if the states match.
|
// Compares the register state. Returns true if the states match.
|
||||||
bool Check() const {
|
void Check() const {
|
||||||
if (!initialized_) return false;
|
|
||||||
int64_t post_store[8];
|
int64_t post_store[8];
|
||||||
vpx_push_neon(post_store);
|
vpx_push_neon(post_store);
|
||||||
for (int i = 0; i < 8; ++i) {
|
for (int i = 0; i < 8; ++i) {
|
||||||
EXPECT_EQ(pre_store_[i], post_store[i]) << "d"
|
EXPECT_EQ(pre_store_[i], post_store[i]) << "d" << i + 8
|
||||||
<< i + 8 << " has been modified";
|
<< " has been modified";
|
||||||
}
|
}
|
||||||
return !testing::Test::HasNonfatalFailure();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool initialized_;
|
|
||||||
int64_t pre_store_[8];
|
int64_t pre_store_[8];
|
||||||
};
|
};
|
||||||
|
|
||||||
#define ASM_REGISTER_STATE_CHECK(statement) do { \
|
#define ASM_REGISTER_STATE_CHECK(statement) \
|
||||||
|
do { \
|
||||||
libvpx_test::RegisterStateCheck reg_check; \
|
libvpx_test::RegisterStateCheck reg_check; \
|
||||||
statement; \
|
statement; \
|
||||||
} while (false)
|
} while (false)
|
||||||
@@ -156,12 +151,12 @@ class RegisterStateCheckMMX {
|
|||||||
RegisterStateCheckMMX() {
|
RegisterStateCheckMMX() {
|
||||||
__asm__ volatile("fstenv %0" : "=rm"(pre_fpu_env_));
|
__asm__ volatile("fstenv %0" : "=rm"(pre_fpu_env_));
|
||||||
}
|
}
|
||||||
~RegisterStateCheckMMX() { EXPECT_TRUE(Check()); }
|
~RegisterStateCheckMMX() { Check(); }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
// Checks the FPU tag word pre/post execution, returning false if not cleared
|
// Checks the FPU tag word pre/post execution, returning false if not cleared
|
||||||
// to 0xffff.
|
// to 0xffff.
|
||||||
bool Check() const {
|
void Check() const {
|
||||||
EXPECT_EQ(0xffff, pre_fpu_env_[4])
|
EXPECT_EQ(0xffff, pre_fpu_env_[4])
|
||||||
<< "FPU was in an inconsistent state prior to call";
|
<< "FPU was in an inconsistent state prior to call";
|
||||||
|
|
||||||
@@ -169,13 +164,13 @@ class RegisterStateCheckMMX {
|
|||||||
__asm__ volatile("fstenv %0" : "=rm"(post_fpu_env));
|
__asm__ volatile("fstenv %0" : "=rm"(post_fpu_env));
|
||||||
EXPECT_EQ(0xffff, post_fpu_env[4])
|
EXPECT_EQ(0xffff, post_fpu_env[4])
|
||||||
<< "FPU was left in an inconsistent state after call";
|
<< "FPU was left in an inconsistent state after call";
|
||||||
return !testing::Test::HasNonfatalFailure();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
uint16_t pre_fpu_env_[14];
|
uint16_t pre_fpu_env_[14];
|
||||||
};
|
};
|
||||||
|
|
||||||
#define API_REGISTER_STATE_CHECK(statement) do { \
|
#define API_REGISTER_STATE_CHECK(statement) \
|
||||||
|
do { \
|
||||||
libvpx_test::RegisterStateCheckMMX reg_check; \
|
libvpx_test::RegisterStateCheckMMX reg_check; \
|
||||||
ASM_REGISTER_STATE_CHECK(statement); \
|
ASM_REGISTER_STATE_CHECK(statement); \
|
||||||
} while (false)
|
} while (false)
|
||||||
|
|||||||
@@ -68,8 +68,7 @@ static void write_ivf_frame_header(const vpx_codec_cx_pkt_t *const pkt,
|
|||||||
char header[12];
|
char header[12];
|
||||||
vpx_codec_pts_t pts;
|
vpx_codec_pts_t pts;
|
||||||
|
|
||||||
if (pkt->kind != VPX_CODEC_CX_FRAME_PKT)
|
if (pkt->kind != VPX_CODEC_CX_FRAME_PKT) return;
|
||||||
return;
|
|
||||||
|
|
||||||
pts = pkt->data.frame.pts;
|
pts = pkt->data.frame.pts;
|
||||||
mem_put_le32(header, static_cast<unsigned int>(pkt->data.frame.sz));
|
mem_put_le32(header, static_cast<unsigned int>(pkt->data.frame.sz));
|
||||||
@@ -92,12 +91,9 @@ struct FrameInfo {
|
|||||||
unsigned int h;
|
unsigned int h;
|
||||||
};
|
};
|
||||||
|
|
||||||
void ScaleForFrameNumber(unsigned int frame,
|
void ScaleForFrameNumber(unsigned int frame, unsigned int initial_w,
|
||||||
unsigned int initial_w,
|
unsigned int initial_h, unsigned int *w,
|
||||||
unsigned int initial_h,
|
unsigned int *h, int flag_codec) {
|
||||||
unsigned int *w,
|
|
||||||
unsigned int *h,
|
|
||||||
int flag_codec) {
|
|
||||||
if (frame < 10) {
|
if (frame < 10) {
|
||||||
*w = initial_w;
|
*w = initial_w;
|
||||||
*h = initial_h;
|
*h = initial_h;
|
||||||
@@ -268,7 +264,8 @@ class ResizingVideoSource : public ::libvpx_test::DummyVideoSource {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
class ResizeTest : public ::libvpx_test::EncoderTest,
|
class ResizeTest
|
||||||
|
: public ::libvpx_test::EncoderTest,
|
||||||
public ::libvpx_test::CodecTestWithParam<libvpx_test::TestMode> {
|
public ::libvpx_test::CodecTestWithParam<libvpx_test::TestMode> {
|
||||||
protected:
|
protected:
|
||||||
ResizeTest() : EncoderTest(GET_PARAM(0)) {}
|
ResizeTest() : EncoderTest(GET_PARAM(0)) {}
|
||||||
@@ -299,12 +296,12 @@ TEST_P(ResizeTest, TestExternalResizeWorks) {
|
|||||||
const unsigned int frame = static_cast<unsigned>(info->pts);
|
const unsigned int frame = static_cast<unsigned>(info->pts);
|
||||||
unsigned int expected_w;
|
unsigned int expected_w;
|
||||||
unsigned int expected_h;
|
unsigned int expected_h;
|
||||||
ScaleForFrameNumber(frame, kInitialWidth, kInitialHeight,
|
ScaleForFrameNumber(frame, kInitialWidth, kInitialHeight, &expected_w,
|
||||||
&expected_w, &expected_h, 0);
|
&expected_h, 0);
|
||||||
EXPECT_EQ(expected_w, info->w)
|
EXPECT_EQ(expected_w, info->w) << "Frame " << frame
|
||||||
<< "Frame " << frame << " had unexpected width";
|
<< " had unexpected width";
|
||||||
EXPECT_EQ(expected_h, info->h)
|
EXPECT_EQ(expected_h, info->h) << "Frame " << frame
|
||||||
<< "Frame " << frame << " had unexpected height";
|
<< " had unexpected height";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -315,10 +312,7 @@ class ResizeInternalTest : public ResizeTest {
|
|||||||
protected:
|
protected:
|
||||||
#if WRITE_COMPRESSED_STREAM
|
#if WRITE_COMPRESSED_STREAM
|
||||||
ResizeInternalTest()
|
ResizeInternalTest()
|
||||||
: ResizeTest(),
|
: ResizeTest(), frame0_psnr_(0.0), outfile_(NULL), out_frames_(0) {}
|
||||||
frame0_psnr_(0.0),
|
|
||||||
outfile_(NULL),
|
|
||||||
out_frames_(0) {}
|
|
||||||
#else
|
#else
|
||||||
ResizeInternalTest() : ResizeTest(), frame0_psnr_(0.0) {}
|
ResizeInternalTest() : ResizeTest(), frame0_psnr_(0.0) {}
|
||||||
#endif
|
#endif
|
||||||
@@ -369,8 +363,7 @@ class ResizeInternalTest : public ResizeTest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
virtual void PSNRPktHook(const vpx_codec_cx_pkt_t *pkt) {
|
virtual void PSNRPktHook(const vpx_codec_cx_pkt_t *pkt) {
|
||||||
if (!frame0_psnr_)
|
if (frame0_psnr_ == 0.) frame0_psnr_ = pkt->data.psnr.psnr[0];
|
||||||
frame0_psnr_ = pkt->data.psnr.psnr[0];
|
|
||||||
EXPECT_NEAR(pkt->data.psnr.psnr[0], frame0_psnr_, 2.0);
|
EXPECT_NEAR(pkt->data.psnr.psnr[0], frame0_psnr_, 2.0);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -379,8 +372,7 @@ class ResizeInternalTest : public ResizeTest {
|
|||||||
++out_frames_;
|
++out_frames_;
|
||||||
|
|
||||||
// Write initial file header if first frame.
|
// Write initial file header if first frame.
|
||||||
if (pkt->data.frame.pts == 0)
|
if (pkt->data.frame.pts == 0) write_ivf_file_header(&cfg_, 0, outfile_);
|
||||||
write_ivf_file_header(&cfg_, 0, outfile_);
|
|
||||||
|
|
||||||
// Write frame header and data.
|
// Write frame header and data.
|
||||||
write_ivf_frame_header(pkt, outfile_);
|
write_ivf_frame_header(pkt, outfile_);
|
||||||
@@ -434,7 +426,8 @@ TEST_P(ResizeInternalTest, TestInternalResizeChangeConfig) {
|
|||||||
ASSERT_NO_FATAL_FAILURE(RunLoop(&video));
|
ASSERT_NO_FATAL_FAILURE(RunLoop(&video));
|
||||||
}
|
}
|
||||||
|
|
||||||
class ResizeRealtimeTest : public ::libvpx_test::EncoderTest,
|
class ResizeRealtimeTest
|
||||||
|
: public ::libvpx_test::EncoderTest,
|
||||||
public ::libvpx_test::CodecTestWith2Params<libvpx_test::TestMode, int> {
|
public ::libvpx_test::CodecTestWith2Params<libvpx_test::TestMode, int> {
|
||||||
protected:
|
protected:
|
||||||
ResizeRealtimeTest() : EncoderTest(GET_PARAM(0)) {}
|
ResizeRealtimeTest() : EncoderTest(GET_PARAM(0)) {}
|
||||||
@@ -465,16 +458,13 @@ class ResizeRealtimeTest : public ::libvpx_test::EncoderTest,
|
|||||||
frame_info_list_.push_back(FrameInfo(pts, img.d_w, img.d_h));
|
frame_info_list_.push_back(FrameInfo(pts, img.d_w, img.d_h));
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual void MismatchHook(const vpx_image_t *img1,
|
virtual void MismatchHook(const vpx_image_t *img1, const vpx_image_t *img2) {
|
||||||
const vpx_image_t *img2) {
|
|
||||||
double mismatch_psnr = compute_psnr(img1, img2);
|
double mismatch_psnr = compute_psnr(img1, img2);
|
||||||
mismatch_psnr_ += mismatch_psnr;
|
mismatch_psnr_ += mismatch_psnr;
|
||||||
++mismatch_nframes_;
|
++mismatch_nframes_;
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned int GetMismatchFrames() {
|
unsigned int GetMismatchFrames() { return mismatch_nframes_; }
|
||||||
return mismatch_nframes_;
|
|
||||||
}
|
|
||||||
|
|
||||||
void DefaultConfig() {
|
void DefaultConfig() {
|
||||||
cfg_.rc_buf_initial_sz = 500;
|
cfg_.rc_buf_initial_sz = 500;
|
||||||
@@ -521,12 +511,12 @@ TEST_P(ResizeRealtimeTest, TestExternalResizeWorks) {
|
|||||||
const unsigned int frame = static_cast<unsigned>(info->pts);
|
const unsigned int frame = static_cast<unsigned>(info->pts);
|
||||||
unsigned int expected_w;
|
unsigned int expected_w;
|
||||||
unsigned int expected_h;
|
unsigned int expected_h;
|
||||||
ScaleForFrameNumber(frame, kInitialWidth, kInitialHeight,
|
ScaleForFrameNumber(frame, kInitialWidth, kInitialHeight, &expected_w,
|
||||||
&expected_w, &expected_h, 1);
|
&expected_h, 1);
|
||||||
EXPECT_EQ(expected_w, info->w)
|
EXPECT_EQ(expected_w, info->w) << "Frame " << frame
|
||||||
<< "Frame " << frame << " had unexpected width";
|
<< " had unexpected width";
|
||||||
EXPECT_EQ(expected_h, info->h)
|
EXPECT_EQ(expected_h, info->h) << "Frame " << frame
|
||||||
<< "Frame " << frame << " had unexpected height";
|
<< " had unexpected height";
|
||||||
EXPECT_EQ(static_cast<unsigned int>(0), GetMismatchFrames());
|
EXPECT_EQ(static_cast<unsigned int>(0), GetMismatchFrames());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -618,10 +608,8 @@ TEST_P(ResizeRealtimeTest, TestInternalResizeDownUpChangeBitRate) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
vpx_img_fmt_t CspForFrameNumber(int frame) {
|
vpx_img_fmt_t CspForFrameNumber(int frame) {
|
||||||
if (frame < 10)
|
if (frame < 10) return VPX_IMG_FMT_I420;
|
||||||
return VPX_IMG_FMT_I420;
|
if (frame < 20) return VPX_IMG_FMT_I444;
|
||||||
if (frame < 20)
|
|
||||||
return VPX_IMG_FMT_I444;
|
|
||||||
return VPX_IMG_FMT_I420;
|
return VPX_IMG_FMT_I420;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -629,10 +617,7 @@ class ResizeCspTest : public ResizeTest {
|
|||||||
protected:
|
protected:
|
||||||
#if WRITE_COMPRESSED_STREAM
|
#if WRITE_COMPRESSED_STREAM
|
||||||
ResizeCspTest()
|
ResizeCspTest()
|
||||||
: ResizeTest(),
|
: ResizeTest(), frame0_psnr_(0.0), outfile_(NULL), out_frames_(0) {}
|
||||||
frame0_psnr_(0.0),
|
|
||||||
outfile_(NULL),
|
|
||||||
out_frames_(0) {}
|
|
||||||
#else
|
#else
|
||||||
ResizeCspTest() : ResizeTest(), frame0_psnr_(0.0) {}
|
ResizeCspTest() : ResizeTest(), frame0_psnr_(0.0) {}
|
||||||
#endif
|
#endif
|
||||||
@@ -671,8 +656,7 @@ class ResizeCspTest : public ResizeTest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
virtual void PSNRPktHook(const vpx_codec_cx_pkt_t *pkt) {
|
virtual void PSNRPktHook(const vpx_codec_cx_pkt_t *pkt) {
|
||||||
if (!frame0_psnr_)
|
if (frame0_psnr_ == 0.) frame0_psnr_ = pkt->data.psnr.psnr[0];
|
||||||
frame0_psnr_ = pkt->data.psnr.psnr[0];
|
|
||||||
EXPECT_NEAR(pkt->data.psnr.psnr[0], frame0_psnr_, 2.0);
|
EXPECT_NEAR(pkt->data.psnr.psnr[0], frame0_psnr_, 2.0);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -681,8 +665,7 @@ class ResizeCspTest : public ResizeTest {
|
|||||||
++out_frames_;
|
++out_frames_;
|
||||||
|
|
||||||
// Write initial file header if first frame.
|
// Write initial file header if first frame.
|
||||||
if (pkt->data.frame.pts == 0)
|
if (pkt->data.frame.pts == 0) write_ivf_file_header(&cfg_, 0, outfile_);
|
||||||
write_ivf_file_header(&cfg_, 0, outfile_);
|
|
||||||
|
|
||||||
// Write frame header and data.
|
// Write frame header and data.
|
||||||
write_ivf_frame_header(pkt, outfile_);
|
write_ivf_frame_header(pkt, outfile_);
|
||||||
|
|||||||
957
test/sad_test.cc
957
test/sad_test.cc
File diff suppressed because it is too large
Load Diff
@@ -8,7 +8,6 @@
|
|||||||
* be found in the AUTHORS file in the root of the source tree.
|
* be found in the AUTHORS file in the root of the source tree.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
#include <math.h>
|
#include <math.h>
|
||||||
#include <stddef.h>
|
#include <stddef.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
@@ -33,14 +32,10 @@ TEST(VP8RoiMapTest, ParameterCheck) {
|
|||||||
unsigned int threshold[MAX_MB_SEGMENTS] = { 0, 100, 200, 300 };
|
unsigned int threshold[MAX_MB_SEGMENTS] = { 0, 100, 200, 300 };
|
||||||
|
|
||||||
const int internalq_trans[] = {
|
const int internalq_trans[] = {
|
||||||
0, 1, 2, 3, 4, 5, 7, 8,
|
0, 1, 2, 3, 4, 5, 7, 8, 9, 10, 12, 13, 15, 17, 18, 19,
|
||||||
9, 10, 12, 13, 15, 17, 18, 19,
|
20, 21, 23, 24, 25, 26, 27, 28, 29, 30, 31, 33, 35, 37, 39, 41,
|
||||||
20, 21, 23, 24, 25, 26, 27, 28,
|
43, 45, 47, 49, 51, 53, 55, 57, 59, 61, 64, 67, 70, 73, 76, 79,
|
||||||
29, 30, 31, 33, 35, 37, 39, 41,
|
82, 85, 88, 91, 94, 97, 100, 103, 106, 109, 112, 115, 118, 121, 124, 127,
|
||||||
43, 45, 47, 49, 51, 53, 55, 57,
|
|
||||||
59, 61, 64, 67, 70, 73, 76, 79,
|
|
||||||
82, 85, 88, 91, 94, 97, 100, 103,
|
|
||||||
106, 109, 112, 115, 118, 121, 124, 127,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
// Initialize elements of cpi with valid defaults.
|
// Initialize elements of cpi with valid defaults.
|
||||||
@@ -66,9 +61,9 @@ TEST(VP8RoiMapTest, ParameterCheck) {
|
|||||||
memset(&roi_map[mbs - (mbs >> 2)], 3, (mbs >> 2));
|
memset(&roi_map[mbs - (mbs >> 2)], 3, (mbs >> 2));
|
||||||
|
|
||||||
// Do a test call with valid parameters.
|
// Do a test call with valid parameters.
|
||||||
int roi_retval = vp8_set_roimap(&cpi, roi_map, cpi.common.mb_rows,
|
int roi_retval =
|
||||||
cpi.common.mb_cols, delta_q, delta_lf,
|
vp8_set_roimap(&cpi, roi_map, cpi.common.mb_rows, cpi.common.mb_cols,
|
||||||
threshold);
|
delta_q, delta_lf, threshold);
|
||||||
EXPECT_EQ(0, roi_retval)
|
EXPECT_EQ(0, roi_retval)
|
||||||
<< "vp8_set_roimap roi failed with default test parameters";
|
<< "vp8_set_roimap roi failed with default test parameters";
|
||||||
|
|
||||||
@@ -104,8 +99,7 @@ TEST(VP8RoiMapTest, ParameterCheck) {
|
|||||||
static_cast<unsigned int>(cpi.segment_encode_breakout[i]);
|
static_cast<unsigned int>(cpi.segment_encode_breakout[i]);
|
||||||
|
|
||||||
if (threshold[i] != breakout) {
|
if (threshold[i] != breakout) {
|
||||||
EXPECT_EQ(threshold[i], breakout)
|
EXPECT_EQ(threshold[i], breakout) << "breakout threshold error";
|
||||||
<< "breakout threshold error";
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -118,7 +112,6 @@ TEST(VP8RoiMapTest, ParameterCheck) {
|
|||||||
EXPECT_EQ(1, cpi.mb.e_mbd.update_mb_segmentation_data)
|
EXPECT_EQ(1, cpi.mb.e_mbd.update_mb_segmentation_data)
|
||||||
<< "update_mb_segmentation_data error";
|
<< "update_mb_segmentation_data error";
|
||||||
|
|
||||||
|
|
||||||
// Try a range of delta q and lf parameters (some legal, some not)
|
// Try a range of delta q and lf parameters (some legal, some not)
|
||||||
for (int i = 0; i < 1000; ++i) {
|
for (int i = 0; i < 1000; ++i) {
|
||||||
int rand_deltas[4];
|
int rand_deltas[4];
|
||||||
@@ -128,57 +121,54 @@ TEST(VP8RoiMapTest, ParameterCheck) {
|
|||||||
rand_deltas[2] = rnd(160) - 80;
|
rand_deltas[2] = rnd(160) - 80;
|
||||||
rand_deltas[3] = rnd(160) - 80;
|
rand_deltas[3] = rnd(160) - 80;
|
||||||
|
|
||||||
deltas_valid = ((abs(rand_deltas[0]) <= 63) &&
|
deltas_valid =
|
||||||
(abs(rand_deltas[1]) <= 63) &&
|
((abs(rand_deltas[0]) <= 63) && (abs(rand_deltas[1]) <= 63) &&
|
||||||
(abs(rand_deltas[2]) <= 63) &&
|
(abs(rand_deltas[2]) <= 63) && (abs(rand_deltas[3]) <= 63))
|
||||||
(abs(rand_deltas[3]) <= 63)) ? 0 : -1;
|
? 0
|
||||||
|
: -1;
|
||||||
|
|
||||||
// Test with random delta q values.
|
// Test with random delta q values.
|
||||||
roi_retval = vp8_set_roimap(&cpi, roi_map, cpi.common.mb_rows,
|
roi_retval =
|
||||||
cpi.common.mb_cols, rand_deltas,
|
vp8_set_roimap(&cpi, roi_map, cpi.common.mb_rows, cpi.common.mb_cols,
|
||||||
delta_lf, threshold);
|
rand_deltas, delta_lf, threshold);
|
||||||
EXPECT_EQ(deltas_valid, roi_retval) << "dq range check error";
|
EXPECT_EQ(deltas_valid, roi_retval) << "dq range check error";
|
||||||
|
|
||||||
// One delta_q error shown at a time
|
// One delta_q error shown at a time
|
||||||
if (deltas_valid != roi_retval)
|
if (deltas_valid != roi_retval) break;
|
||||||
break;
|
|
||||||
|
|
||||||
// Test with random loop filter values.
|
// Test with random loop filter values.
|
||||||
roi_retval = vp8_set_roimap(&cpi, roi_map, cpi.common.mb_rows,
|
roi_retval =
|
||||||
cpi.common.mb_cols, delta_q,
|
vp8_set_roimap(&cpi, roi_map, cpi.common.mb_rows, cpi.common.mb_cols,
|
||||||
rand_deltas, threshold);
|
delta_q, rand_deltas, threshold);
|
||||||
EXPECT_EQ(deltas_valid, roi_retval) << "dlf range check error";
|
EXPECT_EQ(deltas_valid, roi_retval) << "dlf range check error";
|
||||||
|
|
||||||
// One delta loop filter error shown at a time
|
// One delta loop filter error shown at a time
|
||||||
if (deltas_valid != roi_retval)
|
if (deltas_valid != roi_retval) break;
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Test that we report and error if cyclic refresh is enabled.
|
// Test that we report and error if cyclic refresh is enabled.
|
||||||
cpi.cyclic_refresh_mode_enabled = 1;
|
cpi.cyclic_refresh_mode_enabled = 1;
|
||||||
roi_retval = vp8_set_roimap(&cpi, roi_map, cpi.common.mb_rows,
|
roi_retval =
|
||||||
cpi.common.mb_cols, delta_q,
|
vp8_set_roimap(&cpi, roi_map, cpi.common.mb_rows, cpi.common.mb_cols,
|
||||||
delta_lf, threshold);
|
delta_q, delta_lf, threshold);
|
||||||
EXPECT_EQ(-1, roi_retval) << "cyclic refresh check error";
|
EXPECT_EQ(-1, roi_retval) << "cyclic refresh check error";
|
||||||
cpi.cyclic_refresh_mode_enabled = 0;
|
cpi.cyclic_refresh_mode_enabled = 0;
|
||||||
|
|
||||||
// Test invalid number of rows or colums.
|
// Test invalid number of rows or colums.
|
||||||
roi_retval = vp8_set_roimap(&cpi, roi_map, cpi.common.mb_rows + 1,
|
roi_retval =
|
||||||
cpi.common.mb_cols, delta_q,
|
vp8_set_roimap(&cpi, roi_map, cpi.common.mb_rows + 1,
|
||||||
delta_lf, threshold);
|
cpi.common.mb_cols, delta_q, delta_lf, threshold);
|
||||||
EXPECT_EQ(-1, roi_retval) << "MB rows bounds check error";
|
EXPECT_EQ(-1, roi_retval) << "MB rows bounds check error";
|
||||||
|
|
||||||
roi_retval = vp8_set_roimap(&cpi, roi_map, cpi.common.mb_rows,
|
roi_retval =
|
||||||
cpi.common.mb_cols - 1, delta_q,
|
vp8_set_roimap(&cpi, roi_map, cpi.common.mb_rows,
|
||||||
delta_lf, threshold);
|
cpi.common.mb_cols - 1, delta_q, delta_lf, threshold);
|
||||||
EXPECT_EQ(-1, roi_retval) << "MB cols bounds check error";
|
EXPECT_EQ(-1, roi_retval) << "MB cols bounds check error";
|
||||||
}
|
}
|
||||||
|
|
||||||
// Free allocated memory
|
// Free allocated memory
|
||||||
if (cpi.segmentation_map)
|
if (cpi.segmentation_map) vpx_free(cpi.segmentation_map);
|
||||||
vpx_free(cpi.segmentation_map);
|
if (roi_map) vpx_free(roi_map);
|
||||||
if (roi_map)
|
|
||||||
vpx_free(roi_map);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|||||||
@@ -23,7 +23,7 @@ simple_encoder_verify_environment() {
|
|||||||
fi
|
fi
|
||||||
}
|
}
|
||||||
|
|
||||||
# Runs simple_encoder using the codec specified by $1.
|
# Runs simple_encoder using the codec specified by $1 with a frame limit of 100.
|
||||||
simple_encoder() {
|
simple_encoder() {
|
||||||
local encoder="${LIBVPX_BIN_PATH}/simple_encoder${VPX_TEST_EXE_SUFFIX}"
|
local encoder="${LIBVPX_BIN_PATH}/simple_encoder${VPX_TEST_EXE_SUFFIX}"
|
||||||
local codec="$1"
|
local codec="$1"
|
||||||
@@ -35,7 +35,7 @@ simple_encoder() {
|
|||||||
fi
|
fi
|
||||||
|
|
||||||
eval "${VPX_TEST_PREFIX}" "${encoder}" "${codec}" "${YUV_RAW_INPUT_WIDTH}" \
|
eval "${VPX_TEST_PREFIX}" "${encoder}" "${codec}" "${YUV_RAW_INPUT_WIDTH}" \
|
||||||
"${YUV_RAW_INPUT_HEIGHT}" "${YUV_RAW_INPUT}" "${output_file}" 9999 \
|
"${YUV_RAW_INPUT_HEIGHT}" "${YUV_RAW_INPUT}" "${output_file}" 9999 0 100 \
|
||||||
${devnull}
|
${devnull}
|
||||||
|
|
||||||
[ -e "${output_file}" ] || return 1
|
[ -e "${output_file}" ] || return 1
|
||||||
@@ -47,16 +47,13 @@ simple_encoder_vp8() {
|
|||||||
fi
|
fi
|
||||||
}
|
}
|
||||||
|
|
||||||
# TODO(tomfinegan): Add a frame limit param to simple_encoder and enable this
|
simple_encoder_vp9() {
|
||||||
# test. VP9 is just too slow right now: This test takes 4m30s+ on a fast
|
|
||||||
# machine.
|
|
||||||
DISABLED_simple_encoder_vp9() {
|
|
||||||
if [ "$(vp9_encode_available)" = "yes" ]; then
|
if [ "$(vp9_encode_available)" = "yes" ]; then
|
||||||
simple_encoder vp9 || return 1
|
simple_encoder vp9 || return 1
|
||||||
fi
|
fi
|
||||||
}
|
}
|
||||||
|
|
||||||
simple_encoder_tests="simple_encoder_vp8
|
simple_encoder_tests="simple_encoder_vp8
|
||||||
DISABLED_simple_encoder_vp9"
|
simple_encoder_vp9"
|
||||||
|
|
||||||
run_tests simple_encoder_verify_environment "${simple_encoder_tests}"
|
run_tests simple_encoder_verify_environment "${simple_encoder_tests}"
|
||||||
|
|||||||
@@ -1,233 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (c) 2013 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 "./vpx_config.h"
|
|
||||||
#include "./vp8_rtcd.h"
|
|
||||||
#include "test/acm_random.h"
|
|
||||||
#include "test/clear_system_state.h"
|
|
||||||
#include "test/register_state_check.h"
|
|
||||||
#include "test/util.h"
|
|
||||||
#include "vpx/vpx_integer.h"
|
|
||||||
#include "vpx_mem/vpx_mem.h"
|
|
||||||
|
|
||||||
namespace {
|
|
||||||
|
|
||||||
typedef void (*SixtapPredictFunc)(uint8_t *src_ptr,
|
|
||||||
int src_pixels_per_line,
|
|
||||||
int xoffset,
|
|
||||||
int yoffset,
|
|
||||||
uint8_t *dst_ptr,
|
|
||||||
int dst_pitch);
|
|
||||||
|
|
||||||
typedef std::tr1::tuple<int, int, SixtapPredictFunc> SixtapPredictParam;
|
|
||||||
|
|
||||||
class SixtapPredictTest
|
|
||||||
: public ::testing::TestWithParam<SixtapPredictParam> {
|
|
||||||
public:
|
|
||||||
static void SetUpTestCase() {
|
|
||||||
src_ = reinterpret_cast<uint8_t*>(vpx_memalign(kDataAlignment, kSrcSize));
|
|
||||||
dst_ = reinterpret_cast<uint8_t*>(vpx_memalign(kDataAlignment, kDstSize));
|
|
||||||
dst_c_ = reinterpret_cast<uint8_t*>(vpx_memalign(kDataAlignment, kDstSize));
|
|
||||||
}
|
|
||||||
|
|
||||||
static void TearDownTestCase() {
|
|
||||||
vpx_free(src_);
|
|
||||||
src_ = NULL;
|
|
||||||
vpx_free(dst_);
|
|
||||||
dst_ = NULL;
|
|
||||||
vpx_free(dst_c_);
|
|
||||||
dst_c_ = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
virtual void TearDown() {
|
|
||||||
libvpx_test::ClearSystemState();
|
|
||||||
}
|
|
||||||
|
|
||||||
protected:
|
|
||||||
// Make test arrays big enough for 16x16 functions. Six-tap filters
|
|
||||||
// need 5 extra pixels outside of the macroblock.
|
|
||||||
static const int kSrcStride = 21;
|
|
||||||
static const int kDstStride = 16;
|
|
||||||
static const int kDataAlignment = 16;
|
|
||||||
static const int kSrcSize = kSrcStride * kSrcStride + 1;
|
|
||||||
static const int kDstSize = kDstStride * kDstStride;
|
|
||||||
|
|
||||||
virtual void SetUp() {
|
|
||||||
width_ = GET_PARAM(0);
|
|
||||||
height_ = GET_PARAM(1);
|
|
||||||
sixtap_predict_ = GET_PARAM(2);
|
|
||||||
memset(src_, 0, kSrcSize);
|
|
||||||
memset(dst_, 0, kDstSize);
|
|
||||||
memset(dst_c_, 0, kDstSize);
|
|
||||||
}
|
|
||||||
|
|
||||||
int width_;
|
|
||||||
int height_;
|
|
||||||
SixtapPredictFunc sixtap_predict_;
|
|
||||||
// The src stores the macroblock we will filter on, and makes it 1 byte larger
|
|
||||||
// in order to test unaligned access. The result is stored in dst and dst_c(c
|
|
||||||
// reference code result).
|
|
||||||
static uint8_t* src_;
|
|
||||||
static uint8_t* dst_;
|
|
||||||
static uint8_t* dst_c_;
|
|
||||||
};
|
|
||||||
|
|
||||||
uint8_t* SixtapPredictTest::src_ = NULL;
|
|
||||||
uint8_t* SixtapPredictTest::dst_ = NULL;
|
|
||||||
uint8_t* SixtapPredictTest::dst_c_ = NULL;
|
|
||||||
|
|
||||||
TEST_P(SixtapPredictTest, TestWithPresetData) {
|
|
||||||
// Test input
|
|
||||||
static const uint8_t test_data[kSrcSize] = {
|
|
||||||
216, 184, 4, 191, 82, 92, 41, 0, 1, 226, 236, 172, 20, 182, 42, 226, 177,
|
|
||||||
79, 94, 77, 179, 203, 206, 198, 22, 192, 19, 75, 17, 192, 44, 233, 120,
|
|
||||||
48, 168, 203, 141, 210, 203, 143, 180, 184, 59, 201, 110, 102, 171, 32,
|
|
||||||
182, 10, 109, 105, 213, 60, 47, 236, 253, 67, 55, 14, 3, 99, 247, 124,
|
|
||||||
148, 159, 71, 34, 114, 19, 177, 38, 203, 237, 239, 58, 83, 155, 91, 10,
|
|
||||||
166, 201, 115, 124, 5, 163, 104, 2, 231, 160, 16, 234, 4, 8, 103, 153,
|
|
||||||
167, 174, 187, 26, 193, 109, 64, 141, 90, 48, 200, 174, 204, 36, 184,
|
|
||||||
114, 237, 43, 238, 242, 207, 86, 245, 182, 247, 6, 161, 251, 14, 8, 148,
|
|
||||||
182, 182, 79, 208, 120, 188, 17, 6, 23, 65, 206, 197, 13, 242, 126, 128,
|
|
||||||
224, 170, 110, 211, 121, 197, 200, 47, 188, 207, 208, 184, 221, 216, 76,
|
|
||||||
148, 143, 156, 100, 8, 89, 117, 14, 112, 183, 221, 54, 197, 208, 180, 69,
|
|
||||||
176, 94, 180, 131, 215, 121, 76, 7, 54, 28, 216, 238, 249, 176, 58, 142,
|
|
||||||
64, 215, 242, 72, 49, 104, 87, 161, 32, 52, 216, 230, 4, 141, 44, 181,
|
|
||||||
235, 224, 57, 195, 89, 134, 203, 144, 162, 163, 126, 156, 84, 185, 42,
|
|
||||||
148, 145, 29, 221, 194, 134, 52, 100, 166, 105, 60, 140, 110, 201, 184,
|
|
||||||
35, 181, 153, 93, 121, 243, 227, 68, 131, 134, 232, 2, 35, 60, 187, 77,
|
|
||||||
209, 76, 106, 174, 15, 241, 227, 115, 151, 77, 175, 36, 187, 121, 221,
|
|
||||||
223, 47, 118, 61, 168, 105, 32, 237, 236, 167, 213, 238, 202, 17, 170,
|
|
||||||
24, 226, 247, 131, 145, 6, 116, 117, 121, 11, 194, 41, 48, 126, 162, 13,
|
|
||||||
93, 209, 131, 154, 122, 237, 187, 103, 217, 99, 60, 200, 45, 78, 115, 69,
|
|
||||||
49, 106, 200, 194, 112, 60, 56, 234, 72, 251, 19, 120, 121, 182, 134, 215,
|
|
||||||
135, 10, 114, 2, 247, 46, 105, 209, 145, 165, 153, 191, 243, 12, 5, 36,
|
|
||||||
119, 206, 231, 231, 11, 32, 209, 83, 27, 229, 204, 149, 155, 83, 109, 35,
|
|
||||||
93, 223, 37, 84, 14, 142, 37, 160, 52, 191, 96, 40, 204, 101, 77, 67, 52,
|
|
||||||
53, 43, 63, 85, 253, 147, 113, 226, 96, 6, 125, 179, 115, 161, 17, 83,
|
|
||||||
198, 101, 98, 85, 139, 3, 137, 75, 99, 178, 23, 201, 255, 91, 253, 52,
|
|
||||||
134, 60, 138, 131, 208, 251, 101, 48, 2, 227, 228, 118, 132, 245, 202,
|
|
||||||
75, 91, 44, 160, 231, 47, 41, 50, 147, 220, 74, 92, 219, 165, 89, 16
|
|
||||||
};
|
|
||||||
|
|
||||||
// Expected result
|
|
||||||
static const uint8_t expected_dst[kDstSize] = {
|
|
||||||
117, 102, 74, 135, 42, 98, 175, 206, 70, 73, 222, 197, 50, 24, 39, 49, 38,
|
|
||||||
105, 90, 47, 169, 40, 171, 215, 200, 73, 109, 141, 53, 85, 177, 164, 79,
|
|
||||||
208, 124, 89, 212, 18, 81, 145, 151, 164, 217, 153, 91, 154, 102, 102,
|
|
||||||
159, 75, 164, 152, 136, 51, 213, 219, 186, 116, 193, 224, 186, 36, 231,
|
|
||||||
208, 84, 211, 155, 167, 35, 59, 42, 76, 216, 149, 73, 201, 78, 149, 184,
|
|
||||||
100, 96, 196, 189, 198, 188, 235, 195, 117, 129, 120, 129, 49, 25, 133,
|
|
||||||
113, 69, 221, 114, 70, 143, 99, 157, 108, 189, 140, 78, 6, 55, 65, 240,
|
|
||||||
255, 245, 184, 72, 90, 100, 116, 131, 39, 60, 234, 167, 33, 160, 88, 185,
|
|
||||||
200, 157, 159, 176, 127, 151, 138, 102, 168, 106, 170, 86, 82, 219, 189,
|
|
||||||
76, 33, 115, 197, 106, 96, 198, 136, 97, 141, 237, 151, 98, 137, 191,
|
|
||||||
185, 2, 57, 95, 142, 91, 255, 185, 97, 137, 76, 162, 94, 173, 131, 193,
|
|
||||||
161, 81, 106, 72, 135, 222, 234, 137, 66, 137, 106, 243, 210, 147, 95,
|
|
||||||
15, 137, 110, 85, 66, 16, 96, 167, 147, 150, 173, 203, 140, 118, 196,
|
|
||||||
84, 147, 160, 19, 95, 101, 123, 74, 132, 202, 82, 166, 12, 131, 166,
|
|
||||||
189, 170, 159, 85, 79, 66, 57, 152, 132, 203, 194, 0, 1, 56, 146, 180,
|
|
||||||
224, 156, 28, 83, 181, 79, 76, 80, 46, 160, 175, 59, 106, 43, 87, 75,
|
|
||||||
136, 85, 189, 46, 71, 200, 90
|
|
||||||
};
|
|
||||||
|
|
||||||
uint8_t *src = const_cast<uint8_t*>(test_data);
|
|
||||||
|
|
||||||
ASM_REGISTER_STATE_CHECK(
|
|
||||||
sixtap_predict_(&src[kSrcStride * 2 + 2 + 1], kSrcStride,
|
|
||||||
2, 2, dst_, kDstStride));
|
|
||||||
|
|
||||||
for (int i = 0; i < height_; ++i)
|
|
||||||
for (int j = 0; j < width_; ++j)
|
|
||||||
ASSERT_EQ(expected_dst[i * kDstStride + j], dst_[i * kDstStride + j])
|
|
||||||
<< "i==" << (i * width_ + j);
|
|
||||||
}
|
|
||||||
|
|
||||||
using libvpx_test::ACMRandom;
|
|
||||||
|
|
||||||
TEST_P(SixtapPredictTest, TestWithRandomData) {
|
|
||||||
ACMRandom rnd(ACMRandom::DeterministicSeed());
|
|
||||||
for (int i = 0; i < kSrcSize; ++i)
|
|
||||||
src_[i] = rnd.Rand8();
|
|
||||||
|
|
||||||
// Run tests for all possible offsets.
|
|
||||||
for (int xoffset = 0; xoffset < 8; ++xoffset) {
|
|
||||||
for (int yoffset = 0; yoffset < 8; ++yoffset) {
|
|
||||||
// Call c reference function.
|
|
||||||
// Move start point to next pixel to test if the function reads
|
|
||||||
// unaligned data correctly.
|
|
||||||
vp8_sixtap_predict16x16_c(&src_[kSrcStride * 2 + 2 + 1], kSrcStride,
|
|
||||||
xoffset, yoffset, dst_c_, kDstStride);
|
|
||||||
|
|
||||||
// Run test.
|
|
||||||
ASM_REGISTER_STATE_CHECK(
|
|
||||||
sixtap_predict_(&src_[kSrcStride * 2 + 2 + 1], kSrcStride,
|
|
||||||
xoffset, yoffset, dst_, kDstStride));
|
|
||||||
|
|
||||||
for (int i = 0; i < height_; ++i)
|
|
||||||
for (int j = 0; j < width_; ++j)
|
|
||||||
ASSERT_EQ(dst_c_[i * kDstStride + j], dst_[i * kDstStride + j])
|
|
||||||
<< "i==" << (i * width_ + j);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
using std::tr1::make_tuple;
|
|
||||||
|
|
||||||
INSTANTIATE_TEST_CASE_P(
|
|
||||||
C, SixtapPredictTest, ::testing::Values(
|
|
||||||
make_tuple(16, 16, &vp8_sixtap_predict16x16_c),
|
|
||||||
make_tuple(8, 8, &vp8_sixtap_predict8x8_c),
|
|
||||||
make_tuple(8, 4, &vp8_sixtap_predict8x4_c),
|
|
||||||
make_tuple(4, 4, &vp8_sixtap_predict4x4_c)));
|
|
||||||
#if HAVE_NEON
|
|
||||||
INSTANTIATE_TEST_CASE_P(
|
|
||||||
NEON, SixtapPredictTest, ::testing::Values(
|
|
||||||
make_tuple(16, 16, &vp8_sixtap_predict16x16_neon),
|
|
||||||
make_tuple(8, 8, &vp8_sixtap_predict8x8_neon),
|
|
||||||
make_tuple(8, 4, &vp8_sixtap_predict8x4_neon)));
|
|
||||||
#endif
|
|
||||||
#if HAVE_MMX
|
|
||||||
INSTANTIATE_TEST_CASE_P(
|
|
||||||
MMX, SixtapPredictTest, ::testing::Values(
|
|
||||||
make_tuple(16, 16, &vp8_sixtap_predict16x16_mmx),
|
|
||||||
make_tuple(8, 8, &vp8_sixtap_predict8x8_mmx),
|
|
||||||
make_tuple(8, 4, &vp8_sixtap_predict8x4_mmx),
|
|
||||||
make_tuple(4, 4, &vp8_sixtap_predict4x4_mmx)));
|
|
||||||
#endif
|
|
||||||
#if HAVE_SSE2
|
|
||||||
INSTANTIATE_TEST_CASE_P(
|
|
||||||
SSE2, SixtapPredictTest, ::testing::Values(
|
|
||||||
make_tuple(16, 16, &vp8_sixtap_predict16x16_sse2),
|
|
||||||
make_tuple(8, 8, &vp8_sixtap_predict8x8_sse2),
|
|
||||||
make_tuple(8, 4, &vp8_sixtap_predict8x4_sse2)));
|
|
||||||
#endif
|
|
||||||
#if HAVE_SSSE3
|
|
||||||
INSTANTIATE_TEST_CASE_P(
|
|
||||||
SSSE3, SixtapPredictTest, ::testing::Values(
|
|
||||||
make_tuple(16, 16, &vp8_sixtap_predict16x16_ssse3),
|
|
||||||
make_tuple(8, 8, &vp8_sixtap_predict8x8_ssse3),
|
|
||||||
make_tuple(8, 4, &vp8_sixtap_predict8x4_ssse3),
|
|
||||||
make_tuple(4, 4, &vp8_sixtap_predict4x4_ssse3)));
|
|
||||||
#endif
|
|
||||||
#if HAVE_MSA
|
|
||||||
INSTANTIATE_TEST_CASE_P(
|
|
||||||
MSA, SixtapPredictTest, ::testing::Values(
|
|
||||||
make_tuple(16, 16, &vp8_sixtap_predict16x16_msa),
|
|
||||||
make_tuple(8, 8, &vp8_sixtap_predict8x8_msa),
|
|
||||||
make_tuple(8, 4, &vp8_sixtap_predict8x4_msa),
|
|
||||||
make_tuple(4, 4, &vp8_sixtap_predict4x4_msa)));
|
|
||||||
#endif
|
|
||||||
} // namespace
|
|
||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user