Compare commits
940 Commits
nextgenv2
...
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 | ||
|
|
5c29ee726e | ||
|
|
50d3629c61 | ||
|
|
67edc5e83b |
44
.gitignore
vendored
44
.gitignore
vendored
@@ -29,36 +29,40 @@
|
||||
/examples/decode_with_drops
|
||||
/examples/decode_with_partial_drops
|
||||
/examples/example_xma
|
||||
/examples/lossless_encoder
|
||||
/examples/postproc
|
||||
/examples/resize_util
|
||||
/examples/set_maps
|
||||
/examples/simple_decoder
|
||||
/examples/simple_encoder
|
||||
/examples/twopass_encoder
|
||||
/examples/aom_cx_set_ref
|
||||
/examples/av1_spatial_scalable_encoder
|
||||
/examples/aom_temporal_scalable_patterns
|
||||
/examples/aom_temporal_svc_encoder
|
||||
/examples/vp8_multi_resolution_encoder
|
||||
/examples/vp8cx_set_ref
|
||||
/examples/vp9cx_set_ref
|
||||
/examples/vp9_lossless_encoder
|
||||
/examples/vp9_spatial_svc_encoder
|
||||
/examples/vpx_temporal_svc_encoder
|
||||
/ivfdec
|
||||
/ivfdec.dox
|
||||
/ivfenc
|
||||
/ivfenc.dox
|
||||
/libaom.so*
|
||||
/libaom.ver
|
||||
/libvpx.so*
|
||||
/libvpx.ver
|
||||
/samples.dox
|
||||
/test_intra_pred_speed
|
||||
/test_libaom
|
||||
/aom_api1_migration.dox
|
||||
/av1_rtcd.h
|
||||
/aom.pc
|
||||
/aom_config.c
|
||||
/aom_config.h
|
||||
/aom_dsp_rtcd.h
|
||||
/aom_scale_rtcd.h
|
||||
/aom_version.h
|
||||
/aomdec
|
||||
/aomdec.dox
|
||||
/aomenc
|
||||
/aomenc.dox
|
||||
/test_libvpx
|
||||
/tools.dox
|
||||
/tools/*.dox
|
||||
/tools/tiny_ssim
|
||||
/vp8_api1_migration.dox
|
||||
/vp[89x]_rtcd.h
|
||||
/vpx.pc
|
||||
/vpx_config.c
|
||||
/vpx_config.h
|
||||
/vpx_dsp_rtcd.h
|
||||
/vpx_scale_rtcd.h
|
||||
/vpx_version.h
|
||||
/vpxdec
|
||||
/vpxdec.dox
|
||||
/vpxenc
|
||||
/vpxenc.dox
|
||||
TAGS
|
||||
|
||||
7
.mailmap
7
.mailmap
@@ -3,6 +3,7 @@ Aℓex Converse <aconverse@google.com>
|
||||
Aℓex Converse <aconverse@google.com> <alex.converse@gmail.com>
|
||||
Alexis Ballier <aballier@gentoo.org> <alexis.ballier@gmail.com>
|
||||
Alpha Lam <hclam@google.com> <hclam@chromium.org>
|
||||
Daniele Castagna <dcastagna@chromium.org> <dcastagna@google.com>
|
||||
Deb Mukherjee <debargha@google.com>
|
||||
Erik Niemeyer <erik.a.niemeyer@intel.com> <erik.a.niemeyer@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@duck.com>
|
||||
Johann Koenig <johannkoenig@google.com> <johann.koenig@gmail.com>
|
||||
Johann Koenig <johannkoenig@google.com> <johannkoenig@chromium.org>
|
||||
John Koleszar <jkoleszar@google.com>
|
||||
Joshua Litt <joshualitt@google.com> <joshualitt@chromium.org>
|
||||
Marco Paniconi <marpan@google.com>
|
||||
Marco Paniconi <marpan@google.com> <marpan@chromium.org>
|
||||
Pascal Massimino <pascal.massimino@gmail.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@mozilla.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> <levytamar82@gmail.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> <tomfinegan@chromium.org>
|
||||
Yaowu Xu <yaowu@google.com> <yaowu@xuyaowu.com>
|
||||
Yaowu Xu <yaowu@google.com> <Yaowu Xu>
|
||||
|
||||
31
AUTHORS
31
AUTHORS
@@ -7,6 +7,8 @@ Adam Xu <adam@xuyaowu.com>
|
||||
Adrian Grange <agrange@google.com>
|
||||
Aℓex Converse <aconverse@google.com>
|
||||
Ahmad Sharif <asharif@google.com>
|
||||
Aleksey Vasenev <margtu-fivt@ya.ru>
|
||||
Alexander Potapenko <glider@google.com>
|
||||
Alexander Voronov <avoronov@graphics.cs.msu.ru>
|
||||
Alexis Ballier <aballier@gentoo.org>
|
||||
Alok Ahuja <waveletcoeff@gmail.com>
|
||||
@@ -24,8 +26,10 @@ changjun.yang <changjun.yang@intel.com>
|
||||
Charles 'Buck' Krasic <ckrasic@google.com>
|
||||
chm <chm@rock-chips.com>
|
||||
Christian Duvivier <cduvivier@google.com>
|
||||
Daniele Castagna <dcastagna@chromium.org>
|
||||
Daniel Kang <ddkang@google.com>
|
||||
Deb Mukherjee <debargha@google.com>
|
||||
Deepa K G <deepa.kg@ittiam.com>
|
||||
Dim Temp <dimtemp0@gmail.com>
|
||||
Dmitry Kovalev <dkovalev@google.com>
|
||||
Dragan Mrdjan <dmrdjan@mips.com>
|
||||
@@ -36,6 +40,7 @@ Fabio Pedretti <fabio.ped@libero.it>
|
||||
Frank Galligan <fgalligan@google.com>
|
||||
Fredrik Söderquist <fs@opera.com>
|
||||
Fritz Koenig <frkoenig@google.com>
|
||||
Gabriel Marin <gmx@chromium.org>
|
||||
Gaute Strokkenes <gaute.strokkenes@broadcom.com>
|
||||
Geza Lore <gezalore@gmail.com>
|
||||
Ghislain MARY <ghislainmary2@gmail.com>
|
||||
@@ -47,6 +52,7 @@ Hangyu Kuang <hkuang@google.com>
|
||||
Hanno Böck <hanno@hboeck.de>
|
||||
Henrik Lundin <hlundin@google.com>
|
||||
Hui Su <huisu@google.com>
|
||||
Ivan Krasin <krasin@chromium.org>
|
||||
Ivan Maltz <ivanmaltz@google.com>
|
||||
Jacek Caban <cjacek@gmail.com>
|
||||
Jacky Chen <jackychen@google.com>
|
||||
@@ -56,16 +62,16 @@ James Zern <jzern@google.com>
|
||||
Jan Gerber <j@mailb.org>
|
||||
Jan Kratochvil <jan.kratochvil@redhat.com>
|
||||
Janne Salonen <jsalonen@google.com>
|
||||
Jean-Marc Valin <jmvalin@jmvalin.ca>
|
||||
Jean-Yves Avenard <jyavenard@mozilla.com>
|
||||
Jeff Faust <jfaust@google.com>
|
||||
Jeff Muizelaar <jmuizelaar@mozilla.com>
|
||||
Jeff Petkau <jpet@chromium.org>
|
||||
Jerome Jiang <jianj@google.com>
|
||||
Jia Jia <jia.jia@linaro.org>
|
||||
Jian Zhou <zhoujian@google.com>
|
||||
Jim Bankoski <jimbankoski@google.com>
|
||||
Jingning Han <jingning@google.com>
|
||||
Joey Parrish <joeyparrish@google.com>
|
||||
Johann Koenig <johannkoenig@chromium.org>
|
||||
Johann Koenig <johannkoenig@google.com>
|
||||
John Koleszar <jkoleszar@google.com>
|
||||
Johnny Klonaris <google@jawknee.com>
|
||||
@@ -75,8 +81,10 @@ Joshua Litt <joshualitt@google.com>
|
||||
Julia Robson <juliamrobson@gmail.com>
|
||||
Justin Clift <justin@salasaga.org>
|
||||
Justin Lebar <justin.lebar@gmail.com>
|
||||
Kaustubh Raste <kaustubh.raste@imgtec.com>
|
||||
KO Myung-Hun <komh@chollian.net>
|
||||
Lawrence Velázquez <larryv@macports.org>
|
||||
Linfeng Zhang <linfengz@google.com>
|
||||
Lou Quillio <louquillio@google.com>
|
||||
Luca Barbato <lu_zero@gentoo.org>
|
||||
Makoto Kato <makoto.kt@gmail.com>
|
||||
@@ -90,9 +98,11 @@ Michael Kohler <michaelkohler@live.com>
|
||||
Mike Frysinger <vapier@chromium.org>
|
||||
Mike Hommey <mhommey@mozilla.com>
|
||||
Mikhal Shemer <mikhal@google.com>
|
||||
Min Chen <chenm003@gmail.com>
|
||||
Minghai Shang <minghai@google.com>
|
||||
Min Ye <yeemmi@google.com>
|
||||
Morton Jonuschat <yabawock@gmail.com>
|
||||
Nathan E. Egge <negge@dgql.org>
|
||||
Nathan E. Egge <negge@mozilla.com>
|
||||
Nico Weber <thakis@chromium.org>
|
||||
Parag Salasakar <img.mips1@gmail.com>
|
||||
Pascal Massimino <pascal.massimino@gmail.com>
|
||||
@@ -101,17 +111,19 @@ Paul Wilkins <paulwilkins@google.com>
|
||||
Pavol Rusnak <stick@gk2.sk>
|
||||
Paweł Hajdan <phajdan@google.com>
|
||||
Pengchong Jin <pengchong@google.com>
|
||||
Peter de Rivaz <peter.derivaz@argondesign.com>
|
||||
Peter Boström <pbos@google.com>
|
||||
Peter de Rivaz <peter.derivaz@gmail.com>
|
||||
Philip Jägenstedt <philipj@opera.com>
|
||||
Priit Laes <plaes@plaes.org>
|
||||
Rafael Ávila de Espíndola <rafael.espindola@gmail.com>
|
||||
Rafaël Carré <funman@videolan.org>
|
||||
Ralph Giles <giles@xiph.org>
|
||||
Ranjit Kumar Tulabandu <ranjit.tulabandu@ittiam.com>
|
||||
Rob Bradford <rob@linux.intel.com>
|
||||
Ronald S. Bultje <rsbultje@gmail.com>
|
||||
Rui Ueyama <ruiu@google.com>
|
||||
Sami Pietilä <samipietila@google.com>
|
||||
Sarah Parker <sarahparker@google.com>
|
||||
Sasi Inguva <isasi@google.com>
|
||||
Scott Graham <scottmg@chromium.org>
|
||||
Scott LaVarnway <slavarnway@google.com>
|
||||
@@ -121,7 +133,6 @@ Sergey Ulanov <sergeyu@chromium.org>
|
||||
Shimon Doodkin <helpmepro1@gmail.com>
|
||||
Shunyao Li <shunyaoli@google.com>
|
||||
Stefan Holmer <holmer@google.com>
|
||||
Steinar Midtskogen <stemidts@cisco.com>
|
||||
Suman Sunkara <sunkaras@google.com>
|
||||
Taekhyun Kim <takim@nvidia.com>
|
||||
Takanori MATSUURA <t.matsuu@gmail.com>
|
||||
@@ -129,16 +140,18 @@ Tamar Levy <tamar.levy@intel.com>
|
||||
Tao Bai <michaelbai@chromium.org>
|
||||
Tero Rintaluoma <teror@google.com>
|
||||
Thijs Vermeir <thijsvermeir@gmail.com>
|
||||
Thomas Daede <tdaede@mozilla.com>
|
||||
Thomas Davies <thdavies@cisco.com>
|
||||
Thomas <thdavies@cisco.com>
|
||||
Tim Kopp <tkopp@google.com>
|
||||
Timothy B. Terriberry <tterribe@xiph.org>
|
||||
Tom Finegan <tomfinegan@google.com>
|
||||
Tristan Matthews <le.businessman@gmail.com>
|
||||
Tristan Matthews <tmatth@videolan.org>
|
||||
Urvang Joshi <urvang@google.com>
|
||||
Vignesh Venkatasubramanian <vigneshv@google.com>
|
||||
Yaowu Xu <yaowu@google.com>
|
||||
Yi Luo <luoyi@google.com>
|
||||
Yongzhe Wang <yongzhe@google.com>
|
||||
Yunqing Wang <yunqingwang@google.com>
|
||||
Yury Gitman <yuryg@google.com>
|
||||
Zoe Liu <zoeliu@google.com>
|
||||
Google Inc.
|
||||
The Mozilla Foundation
|
||||
The Xiph.Org Foundation
|
||||
|
||||
50
CHANGELOG
50
CHANGELOG
@@ -1,9 +1,49 @@
|
||||
Next Release
|
||||
- Incompatible changes:
|
||||
The AV1 encoder's default keyframe interval changed to 128 from 9999.
|
||||
2017-01-09 v1.6.1 "Long Tailed Duck"
|
||||
This release improves upon the VP9 encoder and speeds up the encoding and
|
||||
decoding processes.
|
||||
|
||||
- Upgrading:
|
||||
This release is ABI compatible with 1.6.0.
|
||||
|
||||
- Enhancements:
|
||||
Faster VP9 encoding and decoding.
|
||||
High bit depth builds now provide similar speed for 8 bit encode and decode
|
||||
for x86 targets. Other platforms and higher bit depth improvements are in
|
||||
progress.
|
||||
|
||||
- Bug Fixes:
|
||||
A variety of fuzzing issues.
|
||||
|
||||
2016-07-20 v1.6.0 "Khaki Campbell Duck"
|
||||
This release improves upon the VP9 encoder and speeds up the encoding and
|
||||
decoding processes.
|
||||
|
||||
- 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.
|
||||
|
||||
2016-04-07 v0.1.0 "AOMedia Codec 1"
|
||||
This release is the first Alliance for Open Media codec.
|
||||
2015-11-09 v1.5.0 "Javan Whistling Duck"
|
||||
This release improves upon the VP9 encoder and speeds up the encoding and
|
||||
decoding processes.
|
||||
|
||||
270
CMakeLists.txt
270
CMakeLists.txt
@@ -1,270 +0,0 @@
|
||||
##
|
||||
## Copyright (c) 2016, Alliance for Open Media. All rights reserved
|
||||
##
|
||||
## This source code is subject to the terms of the BSD 2 Clause License and
|
||||
## the Alliance for Open Media Patent License 1.0. If the BSD 2 Clause License
|
||||
## was not distributed with this source code in the LICENSE file, you can
|
||||
## obtain it at www.aomedia.org/license/software. If the Alliance for Open
|
||||
## Media Patent License 1.0 was not distributed with this source code in the
|
||||
## PATENTS file, you can obtain it at www.aomedia.org/license/patent.
|
||||
##
|
||||
cmake_minimum_required(VERSION 3.2)
|
||||
project(AOM C CXX)
|
||||
|
||||
set(AOM_ROOT "${CMAKE_CURRENT_SOURCE_DIR}")
|
||||
set(AOM_CONFIG_DIR "${CMAKE_CURRENT_BINARY_DIR}")
|
||||
include("${AOM_ROOT}/build/cmake/aom_configure.cmake")
|
||||
|
||||
set(AOM_SRCS
|
||||
"${AOM_CONFIG_DIR}/aom_config.c"
|
||||
"${AOM_CONFIG_DIR}/aom_config.h"
|
||||
"${AOM_ROOT}/aom/aom.h"
|
||||
"${AOM_ROOT}/aom/aom_codec.h"
|
||||
"${AOM_ROOT}/aom/aom_decoder.h"
|
||||
"${AOM_ROOT}/aom/aom_encoder.h"
|
||||
"${AOM_ROOT}/aom/aom_frame_buffer.h"
|
||||
"${AOM_ROOT}/aom/aom_image.h"
|
||||
"${AOM_ROOT}/aom/aom_integer.h"
|
||||
"${AOM_ROOT}/aom/aomcx.h"
|
||||
"${AOM_ROOT}/aom/aomdx.h"
|
||||
"${AOM_ROOT}/aom/internal/aom_codec_internal.h"
|
||||
"${AOM_ROOT}/aom/src/aom_codec.c"
|
||||
"${AOM_ROOT}/aom/src/aom_decoder.c"
|
||||
"${AOM_ROOT}/aom/src/aom_encoder.c"
|
||||
"${AOM_ROOT}/aom/src/aom_image.c")
|
||||
|
||||
set(AOM_DSP_SRCS
|
||||
"${AOM_ROOT}/aom_dsp/aom_convolve.c"
|
||||
"${AOM_ROOT}/aom_dsp/aom_convolve.h"
|
||||
"${AOM_ROOT}/aom_dsp/aom_dsp_common.h"
|
||||
"${AOM_ROOT}/aom_dsp/aom_dsp_rtcd.c"
|
||||
"${AOM_ROOT}/aom_dsp/aom_filter.h"
|
||||
"${AOM_ROOT}/aom_dsp/aom_simd.c"
|
||||
"${AOM_ROOT}/aom_dsp/aom_simd.h"
|
||||
"${AOM_ROOT}/aom_dsp/aom_simd_inline.h"
|
||||
"${AOM_ROOT}/aom_dsp/avg.c"
|
||||
"${AOM_ROOT}/aom_dsp/bitreader.h"
|
||||
"${AOM_ROOT}/aom_dsp/bitreader_buffer.c"
|
||||
"${AOM_ROOT}/aom_dsp/bitreader_buffer.h"
|
||||
"${AOM_ROOT}/aom_dsp/bitwriter.h"
|
||||
"${AOM_ROOT}/aom_dsp/bitwriter_buffer.c"
|
||||
"${AOM_ROOT}/aom_dsp/bitwriter_buffer.h"
|
||||
"${AOM_ROOT}/aom_dsp/blend.h"
|
||||
"${AOM_ROOT}/aom_dsp/blend_a64_hmask.c"
|
||||
"${AOM_ROOT}/aom_dsp/blend_a64_mask.c"
|
||||
"${AOM_ROOT}/aom_dsp/blend_a64_vmask.c"
|
||||
"${AOM_ROOT}/aom_dsp/dkboolreader.c"
|
||||
"${AOM_ROOT}/aom_dsp/dkboolreader.h"
|
||||
"${AOM_ROOT}/aom_dsp/dkboolwriter.c"
|
||||
"${AOM_ROOT}/aom_dsp/dkboolwriter.h"
|
||||
"${AOM_ROOT}/aom_dsp/fwd_txfm.c"
|
||||
"${AOM_ROOT}/aom_dsp/fwd_txfm.h"
|
||||
"${AOM_ROOT}/aom_dsp/intrapred.c"
|
||||
"${AOM_ROOT}/aom_dsp/inv_txfm.c"
|
||||
"${AOM_ROOT}/aom_dsp/inv_txfm.h"
|
||||
"${AOM_ROOT}/aom_dsp/loopfilter.c"
|
||||
"${AOM_ROOT}/aom_dsp/prob.c"
|
||||
"${AOM_ROOT}/aom_dsp/prob.h"
|
||||
"${AOM_ROOT}/aom_dsp/psnr.c"
|
||||
"${AOM_ROOT}/aom_dsp/psnr.h"
|
||||
"${AOM_ROOT}/aom_dsp/quantize.c"
|
||||
"${AOM_ROOT}/aom_dsp/quantize.h"
|
||||
"${AOM_ROOT}/aom_dsp/sad.c"
|
||||
"${AOM_ROOT}/aom_dsp/simd/v128_intrinsics.h"
|
||||
"${AOM_ROOT}/aom_dsp/simd/v128_intrinsics_c.h"
|
||||
"${AOM_ROOT}/aom_dsp/simd/v256_intrinsics.h"
|
||||
"${AOM_ROOT}/aom_dsp/simd/v256_intrinsics_c.h"
|
||||
"${AOM_ROOT}/aom_dsp/simd/v64_intrinsics.h"
|
||||
"${AOM_ROOT}/aom_dsp/simd/v64_intrinsics_c.h"
|
||||
"${AOM_ROOT}/aom_dsp/subtract.c"
|
||||
"${AOM_ROOT}/aom_dsp/txfm_common.h"
|
||||
"${AOM_ROOT}/aom_dsp/variance.c"
|
||||
"${AOM_ROOT}/aom_dsp/variance.h")
|
||||
|
||||
set(AOM_MEM_SRCS
|
||||
"${AOM_ROOT}/aom_mem/aom_mem.c"
|
||||
"${AOM_ROOT}/aom_mem/aom_mem.h"
|
||||
"${AOM_ROOT}/aom_mem/include/aom_mem_intrnl.h")
|
||||
|
||||
set(AOM_SCALE_SRCS
|
||||
"${AOM_ROOT}/aom_scale/aom_scale.h"
|
||||
"${AOM_ROOT}/aom_scale/aom_scale_rtcd.c"
|
||||
"${AOM_ROOT}/aom_scale/generic/aom_scale.c"
|
||||
"${AOM_ROOT}/aom_scale/generic/gen_scalers.c"
|
||||
"${AOM_ROOT}/aom_scale/generic/yv12config.c"
|
||||
"${AOM_ROOT}/aom_scale/generic/yv12extend.c"
|
||||
"${AOM_ROOT}/aom_scale/yv12config.h")
|
||||
|
||||
# TODO(tomfinegan): Extract aom_ports from aom_util if possible.
|
||||
set(AOM_UTIL_SRCS
|
||||
"${AOM_ROOT}/aom_ports/aom_once.h"
|
||||
"${AOM_ROOT}/aom_ports/aom_timer.h"
|
||||
"${AOM_ROOT}/aom_ports/bitops.h"
|
||||
"${AOM_ROOT}/aom_ports/emmintrin_compat.h"
|
||||
"${AOM_ROOT}/aom_ports/mem.h"
|
||||
"${AOM_ROOT}/aom_ports/mem_ops.h"
|
||||
"${AOM_ROOT}/aom_ports/mem_ops_aligned.h"
|
||||
"${AOM_ROOT}/aom_ports/msvc.h"
|
||||
"${AOM_ROOT}/aom_ports/system_state.h"
|
||||
"${AOM_ROOT}/aom_util/aom_thread.c"
|
||||
"${AOM_ROOT}/aom_util/aom_thread.h"
|
||||
"${AOM_ROOT}/aom_util/endian_inl.h")
|
||||
|
||||
set(AOM_AV1_COMMON_SRCS
|
||||
"${AOM_ROOT}/av1/av1_iface_common.h"
|
||||
"${AOM_ROOT}/av1/common/alloccommon.c"
|
||||
"${AOM_ROOT}/av1/common/alloccommon.h"
|
||||
"${AOM_ROOT}/av1/common/av1_fwd_txfm.c"
|
||||
"${AOM_ROOT}/av1/common/av1_fwd_txfm.h"
|
||||
"${AOM_ROOT}/av1/common/av1_inv_txfm.c"
|
||||
"${AOM_ROOT}/av1/common/av1_inv_txfm.h"
|
||||
"${AOM_ROOT}/av1/common/av1_rtcd.c"
|
||||
"${AOM_ROOT}/av1/common/blockd.c"
|
||||
"${AOM_ROOT}/av1/common/blockd.h"
|
||||
"${AOM_ROOT}/av1/common/common.h"
|
||||
"${AOM_ROOT}/av1/common/common_data.h"
|
||||
"${AOM_ROOT}/av1/common/convolve.c"
|
||||
"${AOM_ROOT}/av1/common/convolve.h"
|
||||
"${AOM_ROOT}/av1/common/debugmodes.c"
|
||||
"${AOM_ROOT}/av1/common/entropy.c"
|
||||
"${AOM_ROOT}/av1/common/entropy.h"
|
||||
"${AOM_ROOT}/av1/common/entropymode.c"
|
||||
"${AOM_ROOT}/av1/common/entropymode.h"
|
||||
"${AOM_ROOT}/av1/common/entropymv.c"
|
||||
"${AOM_ROOT}/av1/common/entropymv.h"
|
||||
"${AOM_ROOT}/av1/common/enums.h"
|
||||
"${AOM_ROOT}/av1/common/filter.c"
|
||||
"${AOM_ROOT}/av1/common/filter.h"
|
||||
"${AOM_ROOT}/av1/common/frame_buffers.c"
|
||||
"${AOM_ROOT}/av1/common/frame_buffers.h"
|
||||
"${AOM_ROOT}/av1/common/idct.c"
|
||||
"${AOM_ROOT}/av1/common/idct.h"
|
||||
"${AOM_ROOT}/av1/common/loopfilter.c"
|
||||
"${AOM_ROOT}/av1/common/loopfilter.h"
|
||||
"${AOM_ROOT}/av1/common/mv.h"
|
||||
"${AOM_ROOT}/av1/common/mvref_common.c"
|
||||
"${AOM_ROOT}/av1/common/mvref_common.h"
|
||||
"${AOM_ROOT}/av1/common/odintrin.c"
|
||||
"${AOM_ROOT}/av1/common/odintrin.h"
|
||||
"${AOM_ROOT}/av1/common/onyxc_int.h"
|
||||
"${AOM_ROOT}/av1/common/pred_common.c"
|
||||
"${AOM_ROOT}/av1/common/pred_common.h"
|
||||
"${AOM_ROOT}/av1/common/quant_common.c"
|
||||
"${AOM_ROOT}/av1/common/quant_common.h"
|
||||
"${AOM_ROOT}/av1/common/reconinter.c"
|
||||
"${AOM_ROOT}/av1/common/reconinter.h"
|
||||
"${AOM_ROOT}/av1/common/reconintra.c"
|
||||
"${AOM_ROOT}/av1/common/reconintra.h"
|
||||
"${AOM_ROOT}/av1/common/scale.c"
|
||||
"${AOM_ROOT}/av1/common/scale.h"
|
||||
"${AOM_ROOT}/av1/common/scan.c"
|
||||
"${AOM_ROOT}/av1/common/scan.h"
|
||||
"${AOM_ROOT}/av1/common/seg_common.c"
|
||||
"${AOM_ROOT}/av1/common/seg_common.h"
|
||||
"${AOM_ROOT}/av1/common/thread_common.c"
|
||||
"${AOM_ROOT}/av1/common/thread_common.h"
|
||||
"${AOM_ROOT}/av1/common/tile_common.c"
|
||||
"${AOM_ROOT}/av1/common/tile_common.h")
|
||||
|
||||
set(AOM_AV1_DECODER_SRCS
|
||||
"${AOM_ROOT}/av1/av1_dx_iface.c"
|
||||
"${AOM_ROOT}/av1/decoder/decodeframe.c"
|
||||
"${AOM_ROOT}/av1/decoder/decodeframe.h"
|
||||
"${AOM_ROOT}/av1/decoder/decodemv.c"
|
||||
"${AOM_ROOT}/av1/decoder/decodemv.h"
|
||||
"${AOM_ROOT}/av1/decoder/decoder.c"
|
||||
"${AOM_ROOT}/av1/decoder/decoder.h"
|
||||
"${AOM_ROOT}/av1/decoder/detokenize.c"
|
||||
"${AOM_ROOT}/av1/decoder/detokenize.h"
|
||||
"${AOM_ROOT}/av1/decoder/dsubexp.c"
|
||||
"${AOM_ROOT}/av1/decoder/dsubexp.h"
|
||||
"${AOM_ROOT}/av1/decoder/dthread.c"
|
||||
"${AOM_ROOT}/av1/decoder/dthread.h")
|
||||
|
||||
set(AOM_AV1_ENCODER_SRCS
|
||||
"${AOM_ROOT}/av1/av1_cx_iface.c"
|
||||
"${AOM_ROOT}/av1/encoder/aq_complexity.c"
|
||||
"${AOM_ROOT}/av1/encoder/aq_complexity.h"
|
||||
"${AOM_ROOT}/av1/encoder/aq_cyclicrefresh.c"
|
||||
"${AOM_ROOT}/av1/encoder/aq_cyclicrefresh.h"
|
||||
"${AOM_ROOT}/av1/encoder/aq_variance.c"
|
||||
"${AOM_ROOT}/av1/encoder/aq_variance.h"
|
||||
"${AOM_ROOT}/av1/encoder/bitstream.c"
|
||||
"${AOM_ROOT}/av1/encoder/bitstream.h"
|
||||
"${AOM_ROOT}/av1/encoder/block.h"
|
||||
"${AOM_ROOT}/av1/encoder/context_tree.c"
|
||||
"${AOM_ROOT}/av1/encoder/context_tree.h"
|
||||
"${AOM_ROOT}/av1/encoder/cost.c"
|
||||
"${AOM_ROOT}/av1/encoder/cost.h"
|
||||
"${AOM_ROOT}/av1/encoder/dct.c"
|
||||
"${AOM_ROOT}/av1/encoder/encodeframe.c"
|
||||
"${AOM_ROOT}/av1/encoder/encodeframe.h"
|
||||
"${AOM_ROOT}/av1/encoder/encodemb.c"
|
||||
"${AOM_ROOT}/av1/encoder/encodemb.h"
|
||||
"${AOM_ROOT}/av1/encoder/encodemv.c"
|
||||
"${AOM_ROOT}/av1/encoder/encodemv.h"
|
||||
"${AOM_ROOT}/av1/encoder/encoder.c"
|
||||
"${AOM_ROOT}/av1/encoder/encoder.h"
|
||||
"${AOM_ROOT}/av1/encoder/ethread.c"
|
||||
"${AOM_ROOT}/av1/encoder/ethread.h"
|
||||
"${AOM_ROOT}/av1/encoder/extend.c"
|
||||
"${AOM_ROOT}/av1/encoder/extend.h"
|
||||
"${AOM_ROOT}/av1/encoder/firstpass.c"
|
||||
"${AOM_ROOT}/av1/encoder/firstpass.h"
|
||||
"${AOM_ROOT}/av1/encoder/hybrid_fwd_txfm.c"
|
||||
"${AOM_ROOT}/av1/encoder/hybrid_fwd_txfm.h"
|
||||
"${AOM_ROOT}/av1/encoder/lookahead.c"
|
||||
"${AOM_ROOT}/av1/encoder/lookahead.h"
|
||||
"${AOM_ROOT}/av1/encoder/mbgraph.c"
|
||||
"${AOM_ROOT}/av1/encoder/mbgraph.h"
|
||||
"${AOM_ROOT}/av1/encoder/mcomp.c"
|
||||
"${AOM_ROOT}/av1/encoder/mcomp.h"
|
||||
"${AOM_ROOT}/av1/encoder/picklpf.c"
|
||||
"${AOM_ROOT}/av1/encoder/picklpf.h"
|
||||
"${AOM_ROOT}/av1/encoder/quantize.c"
|
||||
"${AOM_ROOT}/av1/encoder/quantize.h"
|
||||
"${AOM_ROOT}/av1/encoder/ratectrl.c"
|
||||
"${AOM_ROOT}/av1/encoder/ratectrl.h"
|
||||
"${AOM_ROOT}/av1/encoder/rd.c"
|
||||
"${AOM_ROOT}/av1/encoder/rd.h"
|
||||
"${AOM_ROOT}/av1/encoder/rdopt.c"
|
||||
"${AOM_ROOT}/av1/encoder/rdopt.h"
|
||||
"${AOM_ROOT}/av1/encoder/resize.c"
|
||||
"${AOM_ROOT}/av1/encoder/resize.h"
|
||||
"${AOM_ROOT}/av1/encoder/segmentation.c"
|
||||
"${AOM_ROOT}/av1/encoder/segmentation.h"
|
||||
"${AOM_ROOT}/av1/encoder/speed_features.c"
|
||||
"${AOM_ROOT}/av1/encoder/speed_features.h"
|
||||
"${AOM_ROOT}/av1/encoder/subexp.c"
|
||||
"${AOM_ROOT}/av1/encoder/subexp.h"
|
||||
"${AOM_ROOT}/av1/encoder/temporal_filter.c"
|
||||
"${AOM_ROOT}/av1/encoder/temporal_filter.h"
|
||||
"${AOM_ROOT}/av1/encoder/tokenize.c"
|
||||
"${AOM_ROOT}/av1/encoder/tokenize.h"
|
||||
"${AOM_ROOT}/av1/encoder/treewriter.c"
|
||||
"${AOM_ROOT}/av1/encoder/treewriter.h")
|
||||
|
||||
# Targets
|
||||
add_library(aom_dsp ${AOM_DSP_SRCS})
|
||||
include_directories(${AOM_ROOT} ${AOM_CONFIG_DIR})
|
||||
add_library(aom_mem ${AOM_MEM_SRCS})
|
||||
add_library(aom_scale ${AOM_SCALE_SRCS})
|
||||
include_directories(${AOM_ROOT} ${AOM_CONFIG_DIR})
|
||||
add_library(aom_util ${AOM_UTIL_SRCS})
|
||||
add_library(aom_av1_decoder ${AOM_AV1_DECODER_SRCS})
|
||||
add_library(aom_av1_encoder ${AOM_AV1_ENCODER_SRCS})
|
||||
add_library(aom ${AOM_SRCS})
|
||||
target_link_libraries(aom LINK_PUBLIC
|
||||
aom_dsp
|
||||
aom_mem
|
||||
aom_scale
|
||||
aom_util
|
||||
aom_av1_decoder
|
||||
aom_av1_encoder)
|
||||
add_executable(simple_decoder examples/simple_decoder.c)
|
||||
include_directories(${AOM_ROOT})
|
||||
target_link_libraries(simple_decoder LINK_PUBLIC aom)
|
||||
add_executable(simple_encoder examples/simple_encoder.c)
|
||||
include_directories(${AOM_ROOT})
|
||||
target_link_libraries(simple_encoder LINK_PUBLIC aom)
|
||||
|
||||
42
LICENSE
42
LICENSE
@@ -1,27 +1,31 @@
|
||||
Copyright (c) 2016, Alliance for Open Media. All rights reserved.
|
||||
Copyright (c) 2010, The WebM Project authors. All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions
|
||||
are met:
|
||||
modification, are permitted provided that the following conditions are
|
||||
met:
|
||||
|
||||
1. Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
* Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
|
||||
2. Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in
|
||||
the documentation and/or other materials provided with the
|
||||
distribution.
|
||||
* Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in
|
||||
the documentation and/or other materials provided with the
|
||||
distribution.
|
||||
|
||||
* Neither the name of Google, nor the WebM Project, nor the names
|
||||
of its contributors may be used to endorse or promote products
|
||||
derived from this software without specific prior written
|
||||
permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||
FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||
COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||
BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
||||
ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGE.
|
||||
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
|
||||
127
PATENTS
127
PATENTS
@@ -1,108 +1,23 @@
|
||||
Alliance for Open Media Patent License 1.0
|
||||
Additional IP Rights Grant (Patents)
|
||||
------------------------------------
|
||||
|
||||
1. License Terms.
|
||||
|
||||
1.1. Patent License. Subject to the terms and conditions of this License, each
|
||||
Licensor, on behalf of itself and successors in interest and assigns,
|
||||
grants Licensee a non-sublicensable, perpetual, worldwide, non-exclusive,
|
||||
no-charge, royalty-free, irrevocable (except as expressly stated in this
|
||||
License) patent license to its Necessary Claims to make, use, sell, offer
|
||||
for sale, import or distribute any Implementation.
|
||||
|
||||
1.2. Conditions.
|
||||
|
||||
1.2.1. Availability. As a condition to the grant of rights to Licensee to make,
|
||||
sell, offer for sale, import or distribute an Implementation under
|
||||
Section 1.1, Licensee must make its Necessary Claims available under
|
||||
this License, and must reproduce this License with any Implementation
|
||||
as follows:
|
||||
|
||||
a. For distribution in source code, by including this License in the
|
||||
root directory of the source code with its Implementation.
|
||||
|
||||
b. For distribution in any other form (including binary, object form,
|
||||
and/or hardware description code (e.g., HDL, RTL, Gate Level Netlist,
|
||||
GDSII, etc.)), by including this License in the documentation, legal
|
||||
notices, and/or other written materials provided with the
|
||||
Implementation.
|
||||
|
||||
1.2.2. Additional Conditions. This license is directly from Licensor to
|
||||
Licensee. Licensee acknowledges as a condition of benefiting from it
|
||||
that no rights from Licensor are received from suppliers, distributors,
|
||||
or otherwise in connection with this License.
|
||||
|
||||
1.3. Defensive Termination. If any Licensee, its Affiliates, or its agents
|
||||
initiates patent litigation or files, maintains, or voluntarily
|
||||
participates in a lawsuit against another entity or any person asserting
|
||||
that any Implementation infringes Necessary Claims, any patent licenses
|
||||
granted under this License directly to the Licensee are immediately
|
||||
terminated as of the date of the initiation of action unless 1) that suit
|
||||
was in response to a corresponding suit regarding an Implementation first
|
||||
brought against an initiating entity, or 2) that suit was brought to
|
||||
enforce the terms of this License (including intervention in a third-party
|
||||
action by a Licensee).
|
||||
|
||||
1.4. Disclaimers. The Reference Implementation and Specification are provided
|
||||
"AS IS" and without warranty. The entire risk as to implementing or
|
||||
otherwise using the Reference Implementation or Specification is assumed
|
||||
by the implementer and user. Licensor expressly disclaims any warranties
|
||||
(express, implied, or otherwise), including implied warranties of
|
||||
merchantability, non-infringement, fitness for a particular purpose, or
|
||||
title, related to the material. IN NO EVENT WILL LICENSOR BE LIABLE TO
|
||||
ANY OTHER PARTY FOR LOST PROFITS OR ANY FORM OF INDIRECT, SPECIAL,
|
||||
INCIDENTAL, OR CONSEQUENTIAL DAMAGES OF ANY CHARACTER FROM ANY CAUSES OF
|
||||
ACTION OF ANY KIND WITH RESPECT TO THIS LICENSE, WHETHER BASED ON BREACH
|
||||
OF CONTRACT, TORT (INCLUDING NEGLIGENCE), OR OTHERWISE, AND WHETHER OR
|
||||
NOT THE OTHER PARTRY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
2. Definitions.
|
||||
|
||||
2.1. Affiliate. <20>Affiliate<74> means an entity that directly or indirectly
|
||||
Controls, is Controlled by, or is under common Control of that party.
|
||||
|
||||
2.2. Control. <20>Control<6F> means direct or indirect control of more than 50% of
|
||||
the voting power to elect directors of that corporation, or for any other
|
||||
entity, the power to direct management of such entity.
|
||||
|
||||
2.3. Decoder. "Decoder" means any decoder that conforms fully with all
|
||||
non-optional portions of the Specification.
|
||||
|
||||
2.4. Encoder. "Encoder" means any encoder that produces a bitstream that can
|
||||
be decoded by a Decoder only to the extent it produces such a bitstream.
|
||||
|
||||
2.5. Final Deliverable. <20>Final Deliverable<6C> means the final version of a
|
||||
deliverable approved by the Alliance for Open Media as a Final
|
||||
Deliverable.
|
||||
|
||||
2.6. Implementation. "Implementation" means any implementation, including the
|
||||
Reference Implementation, that is an Encoder and/or a Decoder. An
|
||||
Implementation also includes components of an Implementation only to the
|
||||
extent they are used as part of an Implementation.
|
||||
|
||||
2.7. License. <20>License<73> means this license.
|
||||
|
||||
2.8. Licensee. <20>Licensee<65> means any person or entity who exercises patent
|
||||
rights granted under this License.
|
||||
|
||||
2.9. Licensor. "Licensor" means (i) any Licensee that makes, sells, offers
|
||||
for sale, imports or distributes any Implementation, or (ii) a person
|
||||
or entity that has a licensing obligation to the Implementation as a
|
||||
result of its membership and/or participation in the Alliance for Open
|
||||
Media working group that developed the Specification.
|
||||
|
||||
2.10. Necessary Claims. "Necessary Claims" means all claims of patents or
|
||||
patent applications, (a) that currently or at any time in the future,
|
||||
are owned or controlled by the Licensor, and (b) (i) would be an
|
||||
Essential Claim as defined by the W3C Policy as of February 5, 2004
|
||||
(https://www.w3.org/Consortium/Patent-Policy-20040205/#def-essential)
|
||||
as if the Specification was a W3C Recommendation; or (ii) are infringed
|
||||
by the Reference Implementation.
|
||||
|
||||
2.11. Reference Implementation. <20>Reference Implementation<6F> means an Encoder
|
||||
and/or Decoder released by the Alliance for Open Media as a Final
|
||||
Deliverable.
|
||||
|
||||
2.12. Specification. <20>Specification<6F> means the specification designated by
|
||||
the Alliance for Open Media as a Final Deliverable for which this
|
||||
License was issued.
|
||||
"These implementations" means the copyrightable works that implement the WebM
|
||||
codecs distributed by Google as part of the WebM Project.
|
||||
|
||||
Google hereby grants to you a perpetual, worldwide, non-exclusive, no-charge,
|
||||
royalty-free, irrevocable (except as stated in this section) patent license to
|
||||
make, have made, use, offer to sell, sell, import, transfer, and otherwise
|
||||
run, modify and propagate the contents of these implementations of WebM, where
|
||||
such license applies only to those patent claims, both currently owned by
|
||||
Google and acquired in the future, licensable by Google that are necessarily
|
||||
infringed by these implementations of WebM. This grant does not include claims
|
||||
that would be infringed only as a consequence of further modification of these
|
||||
implementations. If you or your agent or exclusive licensee institute or order
|
||||
or agree to the institution of patent litigation or any other patent
|
||||
enforcement activity against any entity (including a cross-claim or
|
||||
counterclaim in a lawsuit) alleging that any of these implementations of WebM
|
||||
or any code incorporated within any of these implementations of WebM
|
||||
constitute direct or contributory patent infringement, or inducement of
|
||||
patent infringement, then any patent rights granted to you under this License
|
||||
for these implementations of WebM shall terminate as of the date such
|
||||
litigation is filed.
|
||||
|
||||
26
README
26
README
@@ -1,6 +1,6 @@
|
||||
README - 23 March 2015
|
||||
README - 9 January 2017
|
||||
|
||||
Welcome to the WebM VP8/AV1 Codec SDK!
|
||||
Welcome to the WebM VP8/VP9 Codec SDK!
|
||||
|
||||
COMPILING THE APPLICATIONS/LIBRARIES:
|
||||
The build system used is similar to autotools. Building generally consists of
|
||||
@@ -33,13 +33,13 @@ COMPILING THE APPLICATIONS/LIBRARIES:
|
||||
|
||||
$ mkdir build
|
||||
$ cd build
|
||||
$ ../libaom/configure <options>
|
||||
$ ../libvpx/configure <options>
|
||||
$ make
|
||||
|
||||
3. Configuration options
|
||||
The 'configure' script supports a number of options. The --help option can be
|
||||
used to get a list of supported options:
|
||||
$ ../libaom/configure --help
|
||||
$ ../libvpx/configure --help
|
||||
|
||||
4. Cross development
|
||||
For cross development, the most notable option is the --target option. The
|
||||
@@ -47,10 +47,9 @@ COMPILING THE APPLICATIONS/LIBRARIES:
|
||||
--help output of the configure script. As of this writing, the list of
|
||||
available targets is:
|
||||
|
||||
armv6-linux-rvct
|
||||
armv6-linux-gcc
|
||||
armv6-none-rvct
|
||||
arm64-android-gcc
|
||||
arm64-darwin-gcc
|
||||
arm64-linux-gcc
|
||||
armv7-android-gcc
|
||||
armv7-darwin-gcc
|
||||
armv7-linux-rvct
|
||||
@@ -60,6 +59,7 @@ COMPILING THE APPLICATIONS/LIBRARIES:
|
||||
armv7-win32-vs12
|
||||
armv7-win32-vs14
|
||||
armv7s-darwin-gcc
|
||||
armv8-linux-gcc
|
||||
mips32-linux-gcc
|
||||
mips64-linux-gcc
|
||||
sparc-solaris-gcc
|
||||
@@ -73,6 +73,7 @@ COMPILING THE APPLICATIONS/LIBRARIES:
|
||||
x86-darwin12-gcc
|
||||
x86-darwin13-gcc
|
||||
x86-darwin14-gcc
|
||||
x86-darwin15-gcc
|
||||
x86-iphonesimulator-gcc
|
||||
x86-linux-gcc
|
||||
x86-linux-icc
|
||||
@@ -90,6 +91,7 @@ COMPILING THE APPLICATIONS/LIBRARIES:
|
||||
x86_64-darwin12-gcc
|
||||
x86_64-darwin13-gcc
|
||||
x86_64-darwin14-gcc
|
||||
x86_64-darwin15-gcc
|
||||
x86_64-iphonesimulator-gcc
|
||||
x86_64-linux-gcc
|
||||
x86_64-linux-icc
|
||||
@@ -108,7 +110,7 @@ COMPILING THE APPLICATIONS/LIBRARIES:
|
||||
toolchain, the following command could be used (note, POSIX SH syntax, adapt
|
||||
to your shell as necessary):
|
||||
|
||||
$ CROSS=mipsel-linux-uclibc- ../libaom/configure
|
||||
$ CROSS=mipsel-linux-uclibc- ../libvpx/configure
|
||||
|
||||
In addition, the executables to be invoked can be overridden by specifying the
|
||||
environment variables: CC, AR, LD, AS, STRIP, NM. Additional flags can be
|
||||
@@ -119,13 +121,13 @@ COMPILING THE APPLICATIONS/LIBRARIES:
|
||||
This defaults to config.log. This should give a good indication of what went
|
||||
wrong. If not, contact us for support.
|
||||
|
||||
VP8/AV1 TEST VECTORS:
|
||||
VP8/VP9 TEST VECTORS:
|
||||
The test vectors can be downloaded and verified using the build system after
|
||||
running configure. To specify an alternate directory the
|
||||
LIBAOM_TEST_DATA_PATH environment variable can be used.
|
||||
LIBVPX_TEST_DATA_PATH environment variable can be used.
|
||||
|
||||
$ ./configure --enable-unit-tests
|
||||
$ LIBAOM_TEST_DATA_PATH=../-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
|
||||
@@ -144,5 +146,5 @@ CODE STYLE:
|
||||
|
||||
SUPPORT
|
||||
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.
|
||||
|
||||
|
||||
160
aom/aom.h
160
aom/aom.h
@@ -1,160 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2016, Alliance for Open Media. All rights reserved
|
||||
*
|
||||
* This source code is subject to the terms of the BSD 2 Clause License and
|
||||
* the Alliance for Open Media Patent License 1.0. If the BSD 2 Clause License
|
||||
* was not distributed with this source code in the LICENSE file, you can
|
||||
* obtain it at www.aomedia.org/license/software. If the Alliance for Open
|
||||
* Media Patent License 1.0 was not distributed with this source code in the
|
||||
* PATENTS file, you can obtain it at www.aomedia.org/license/patent.
|
||||
*/
|
||||
|
||||
/*!\defgroup aom AOM
|
||||
* \ingroup codecs
|
||||
* AOM is aom's newest video compression algorithm that uses motion
|
||||
* compensated prediction, Discrete Cosine Transform (DCT) coding of the
|
||||
* prediction error signal and context dependent entropy coding techniques
|
||||
* based on arithmetic principles. It features:
|
||||
* - YUV 4:2:0 image format
|
||||
* - Macro-block based coding (16x16 luma plus two 8x8 chroma)
|
||||
* - 1/4 (1/8) pixel accuracy motion compensated prediction
|
||||
* - 4x4 DCT transform
|
||||
* - 128 level linear quantizer
|
||||
* - In loop deblocking filter
|
||||
* - Context-based entropy coding
|
||||
*
|
||||
* @{
|
||||
*/
|
||||
/*!\file
|
||||
* \brief Provides controls common to both the AOM encoder and decoder.
|
||||
*/
|
||||
#ifndef AOM_AOM_H_
|
||||
#define AOM_AOM_H_
|
||||
|
||||
#include "./aom_codec.h"
|
||||
#include "./aom_image.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/*!\brief Control functions
|
||||
*
|
||||
* The set of macros define the control functions of AOM interface
|
||||
*/
|
||||
enum aom_com_control_id {
|
||||
/*!\brief pass in an external frame into decoder to be used as reference frame
|
||||
*/
|
||||
AOM_SET_REFERENCE = 1,
|
||||
AOM_COPY_REFERENCE = 2, /**< get a copy of reference frame from the decoder */
|
||||
AOM_SET_POSTPROC = 3, /**< set the decoder's post processing settings */
|
||||
AOM_SET_DBG_COLOR_REF_FRAME =
|
||||
4, /**< set the reference frames to color for each macroblock */
|
||||
AOM_SET_DBG_COLOR_MB_MODES = 5, /**< set which macro block modes to color */
|
||||
AOM_SET_DBG_COLOR_B_MODES = 6, /**< set which blocks modes to color */
|
||||
AOM_SET_DBG_DISPLAY_MV = 7, /**< set which motion vector modes to draw */
|
||||
|
||||
/* TODO(jkoleszar): The encoder incorrectly reuses some of these values (5+)
|
||||
* for its control ids. These should be migrated to something like the
|
||||
* AOM_DECODER_CTRL_ID_START range next time we're ready to break the ABI.
|
||||
*/
|
||||
AV1_GET_REFERENCE = 128, /**< get a pointer to a reference frame */
|
||||
AOM_COMMON_CTRL_ID_MAX,
|
||||
|
||||
AV1_GET_NEW_FRAME_IMAGE = 192, /**< get a pointer to the new frame */
|
||||
|
||||
AOM_DECODER_CTRL_ID_START = 256
|
||||
};
|
||||
|
||||
/*!\brief post process flags
|
||||
*
|
||||
* The set of macros define AOM decoder post processing flags
|
||||
*/
|
||||
enum aom_postproc_level {
|
||||
AOM_NOFILTERING = 0,
|
||||
AOM_DEBLOCK = 1 << 0,
|
||||
AOM_DEMACROBLOCK = 1 << 1,
|
||||
AOM_ADDNOISE = 1 << 2,
|
||||
AOM_DEBUG_TXT_FRAME_INFO = 1 << 3, /**< print frame information */
|
||||
AOM_DEBUG_TXT_MBLK_MODES =
|
||||
1 << 4, /**< print macro block modes over each macro block */
|
||||
AOM_DEBUG_TXT_DC_DIFF = 1 << 5, /**< print dc diff for each macro block */
|
||||
AOM_DEBUG_TXT_RATE_INFO = 1 << 6, /**< print video rate info (encoder only) */
|
||||
AOM_MFQE = 1 << 10
|
||||
};
|
||||
|
||||
/*!\brief post process flags
|
||||
*
|
||||
* This define a structure that describe the post processing settings. For
|
||||
* the best objective measure (using the PSNR metric) set post_proc_flag
|
||||
* to AOM_DEBLOCK and deblocking_level to 1.
|
||||
*/
|
||||
|
||||
typedef struct aom_postproc_cfg {
|
||||
/*!\brief the types of post processing to be done, should be combination of
|
||||
* "aom_postproc_level" */
|
||||
int post_proc_flag;
|
||||
int deblocking_level; /**< the strength of deblocking, valid range [0, 16] */
|
||||
int noise_level; /**< the strength of additive noise, valid range [0, 16] */
|
||||
} aom_postproc_cfg_t;
|
||||
|
||||
/*!\brief reference frame type
|
||||
*
|
||||
* The set of macros define the type of AOM reference frames
|
||||
*/
|
||||
typedef enum aom_ref_frame_type {
|
||||
AOM_LAST_FRAME = 1,
|
||||
AOM_GOLD_FRAME = 2,
|
||||
AOM_ALTR_FRAME = 4
|
||||
} aom_ref_frame_type_t;
|
||||
|
||||
/*!\brief reference frame data struct
|
||||
*
|
||||
* Define the data struct to access aom reference frames.
|
||||
*/
|
||||
typedef struct aom_ref_frame {
|
||||
aom_ref_frame_type_t frame_type; /**< which reference frame */
|
||||
aom_image_t img; /**< reference frame data in image format */
|
||||
} aom_ref_frame_t;
|
||||
|
||||
/*!\brief AV1 specific reference frame data struct
|
||||
*
|
||||
* Define the data struct to access av1 reference frames.
|
||||
*/
|
||||
typedef struct av1_ref_frame {
|
||||
int idx; /**< frame index to get (input) */
|
||||
aom_image_t img; /**< img structure to populate (output) */
|
||||
} av1_ref_frame_t;
|
||||
|
||||
/*!\cond */
|
||||
/*!\brief aom decoder control function parameter type
|
||||
*
|
||||
* defines the data type for each of AOM decoder control function requires
|
||||
*/
|
||||
AOM_CTRL_USE_TYPE(AOM_SET_REFERENCE, aom_ref_frame_t *)
|
||||
#define AOM_CTRL_AOM_SET_REFERENCE
|
||||
AOM_CTRL_USE_TYPE(AOM_COPY_REFERENCE, aom_ref_frame_t *)
|
||||
#define AOM_CTRL_AOM_COPY_REFERENCE
|
||||
AOM_CTRL_USE_TYPE(AOM_SET_POSTPROC, aom_postproc_cfg_t *)
|
||||
#define AOM_CTRL_AOM_SET_POSTPROC
|
||||
AOM_CTRL_USE_TYPE(AOM_SET_DBG_COLOR_REF_FRAME, int)
|
||||
#define AOM_CTRL_AOM_SET_DBG_COLOR_REF_FRAME
|
||||
AOM_CTRL_USE_TYPE(AOM_SET_DBG_COLOR_MB_MODES, int)
|
||||
#define AOM_CTRL_AOM_SET_DBG_COLOR_MB_MODES
|
||||
AOM_CTRL_USE_TYPE(AOM_SET_DBG_COLOR_B_MODES, int)
|
||||
#define AOM_CTRL_AOM_SET_DBG_COLOR_B_MODES
|
||||
AOM_CTRL_USE_TYPE(AOM_SET_DBG_DISPLAY_MV, int)
|
||||
#define AOM_CTRL_AOM_SET_DBG_DISPLAY_MV
|
||||
AOM_CTRL_USE_TYPE(AV1_GET_REFERENCE, av1_ref_frame_t *)
|
||||
#define AOM_CTRL_AV1_GET_REFERENCE
|
||||
AOM_CTRL_USE_TYPE(AV1_GET_NEW_FRAME_IMAGE, aom_image_t *)
|
||||
#define AOM_CTRL_AV1_GET_NEW_FRAME_IMAGE
|
||||
|
||||
/*!\endcond */
|
||||
/*! @} - end defgroup aom */
|
||||
|
||||
#ifdef __cplusplus
|
||||
} // extern "C"
|
||||
#endif
|
||||
|
||||
#endif // AOM_AOM_H_
|
||||
@@ -1,42 +0,0 @@
|
||||
##
|
||||
## Copyright (c) 2016, Alliance for Open Media. All rights reserved
|
||||
##
|
||||
## This source code is subject to the terms of the BSD 2 Clause License and
|
||||
## the Alliance for Open Media Patent License 1.0. If the BSD 2 Clause License
|
||||
## was not distributed with this source code in the LICENSE file, you can
|
||||
## obtain it at www.aomedia.org/license/software. If the Alliance for Open
|
||||
## Media Patent License 1.0 was not distributed with this source code in the
|
||||
## PATENTS file, you can obtain it at www.aomedia.org/license/patent.
|
||||
##
|
||||
|
||||
|
||||
API_EXPORTS += exports
|
||||
|
||||
API_SRCS-$(CONFIG_AV1_ENCODER) += aom.h
|
||||
API_SRCS-$(CONFIG_AV1_ENCODER) += aomcx.h
|
||||
API_DOC_SRCS-$(CONFIG_AV1_ENCODER) += aom.h
|
||||
API_DOC_SRCS-$(CONFIG_AV1_ENCODER) += aomcx.h
|
||||
|
||||
API_SRCS-$(CONFIG_AV1_DECODER) += aom.h
|
||||
API_SRCS-$(CONFIG_AV1_DECODER) += aomdx.h
|
||||
API_DOC_SRCS-$(CONFIG_AV1_DECODER) += aom.h
|
||||
API_DOC_SRCS-$(CONFIG_AV1_DECODER) += aomdx.h
|
||||
|
||||
API_DOC_SRCS-yes += aom_codec.h
|
||||
API_DOC_SRCS-yes += aom_decoder.h
|
||||
API_DOC_SRCS-yes += aom_encoder.h
|
||||
API_DOC_SRCS-yes += aom_frame_buffer.h
|
||||
API_DOC_SRCS-yes += aom_image.h
|
||||
|
||||
API_SRCS-yes += src/aom_decoder.c
|
||||
API_SRCS-yes += aom_decoder.h
|
||||
API_SRCS-yes += src/aom_encoder.c
|
||||
API_SRCS-yes += aom_encoder.h
|
||||
API_SRCS-yes += internal/aom_codec_internal.h
|
||||
API_SRCS-yes += src/aom_codec.c
|
||||
API_SRCS-yes += src/aom_image.c
|
||||
API_SRCS-yes += aom_codec.h
|
||||
API_SRCS-yes += aom_codec.mk
|
||||
API_SRCS-yes += aom_frame_buffer.h
|
||||
API_SRCS-yes += aom_image.h
|
||||
API_SRCS-yes += aom_integer.h
|
||||
759
aom/aomcx.h
759
aom/aomcx.h
@@ -1,759 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2016, Alliance for Open Media. All rights reserved
|
||||
*
|
||||
* This source code is subject to the terms of the BSD 2 Clause License and
|
||||
* the Alliance for Open Media Patent License 1.0. If the BSD 2 Clause License
|
||||
* was not distributed with this source code in the LICENSE file, you can
|
||||
* obtain it at www.aomedia.org/license/software. If the Alliance for Open
|
||||
* Media Patent License 1.0 was not distributed with this source code in the
|
||||
* PATENTS file, you can obtain it at www.aomedia.org/license/patent.
|
||||
*/
|
||||
#ifndef AOM_AOMCX_H_
|
||||
#define AOM_AOMCX_H_
|
||||
|
||||
/*!\defgroup aom_encoder AOMedia AOM/AV1 Encoder
|
||||
* \ingroup aom
|
||||
*
|
||||
* @{
|
||||
*/
|
||||
#include "./aom.h"
|
||||
#include "./aom_encoder.h"
|
||||
|
||||
/*!\file
|
||||
* \brief Provides definitions for using AOM or AV1 encoder algorithm within the
|
||||
* aom Codec Interface.
|
||||
*/
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/*!\name Algorithm interface for AV1
|
||||
*
|
||||
* This interface provides the capability to encode raw AV1 streams.
|
||||
* @{
|
||||
*/
|
||||
extern aom_codec_iface_t aom_codec_av1_cx_algo;
|
||||
extern aom_codec_iface_t *aom_codec_av1_cx(void);
|
||||
/*!@} - end algorithm interface member group*/
|
||||
|
||||
/*
|
||||
* Algorithm Flags
|
||||
*/
|
||||
|
||||
/*!\brief Don't reference the last frame
|
||||
*
|
||||
* When this flag is set, the encoder will not use the last frame as a
|
||||
* predictor. When not set, the encoder will choose whether to use the
|
||||
* last frame or not automatically.
|
||||
*/
|
||||
#define AOM_EFLAG_NO_REF_LAST (1 << 16)
|
||||
|
||||
/*!\brief Don't reference the golden frame
|
||||
*
|
||||
* When this flag is set, the encoder will not use the golden frame as a
|
||||
* predictor. When not set, the encoder will choose whether to use the
|
||||
* golden frame or not automatically.
|
||||
*/
|
||||
#define AOM_EFLAG_NO_REF_GF (1 << 17)
|
||||
|
||||
/*!\brief Don't reference the alternate reference frame
|
||||
*
|
||||
* When this flag is set, the encoder will not use the alt ref frame as a
|
||||
* predictor. When not set, the encoder will choose whether to use the
|
||||
* alt ref frame or not automatically.
|
||||
*/
|
||||
#define AOM_EFLAG_NO_REF_ARF (1 << 21)
|
||||
|
||||
/*!\brief Don't update the last frame
|
||||
*
|
||||
* When this flag is set, the encoder will not update the last frame with
|
||||
* the contents of the current frame.
|
||||
*/
|
||||
#define AOM_EFLAG_NO_UPD_LAST (1 << 18)
|
||||
|
||||
/*!\brief Don't update the golden frame
|
||||
*
|
||||
* When this flag is set, the encoder will not update the golden frame with
|
||||
* the contents of the current frame.
|
||||
*/
|
||||
#define AOM_EFLAG_NO_UPD_GF (1 << 22)
|
||||
|
||||
/*!\brief Don't update the alternate reference frame
|
||||
*
|
||||
* When this flag is set, the encoder will not update the alt ref frame with
|
||||
* the contents of the current frame.
|
||||
*/
|
||||
#define AOM_EFLAG_NO_UPD_ARF (1 << 23)
|
||||
|
||||
/*!\brief Force golden frame update
|
||||
*
|
||||
* When this flag is set, the encoder copy the contents of the current frame
|
||||
* to the golden frame buffer.
|
||||
*/
|
||||
#define AOM_EFLAG_FORCE_GF (1 << 19)
|
||||
|
||||
/*!\brief Force alternate reference frame update
|
||||
*
|
||||
* When this flag is set, the encoder copy the contents of the current frame
|
||||
* to the alternate reference frame buffer.
|
||||
*/
|
||||
#define AOM_EFLAG_FORCE_ARF (1 << 24)
|
||||
|
||||
/*!\brief Disable entropy update
|
||||
*
|
||||
* When this flag is set, the encoder will not update its internal entropy
|
||||
* model based on the entropy of this frame.
|
||||
*/
|
||||
#define AOM_EFLAG_NO_UPD_ENTROPY (1 << 20)
|
||||
|
||||
/*!\brief AVx encoder control functions
|
||||
*
|
||||
* This set of macros define the control functions available for AVx
|
||||
* encoder interface.
|
||||
*
|
||||
* \sa #aom_codec_control
|
||||
*/
|
||||
enum aome_enc_control_id {
|
||||
/*!\brief Codec control function to set which reference frame encoder can use.
|
||||
*
|
||||
* Supported in codecs: VP8, AV1
|
||||
*/
|
||||
AOME_USE_REFERENCE = 7,
|
||||
|
||||
/*!\brief Codec control function to pass an ROI map to encoder.
|
||||
*
|
||||
* Supported in codecs: VP8, AV1
|
||||
*/
|
||||
AOME_SET_ROI_MAP = 8,
|
||||
|
||||
/*!\brief Codec control function to pass an Active map to encoder.
|
||||
*
|
||||
* Supported in codecs: VP8, AV1
|
||||
*/
|
||||
AOME_SET_ACTIVEMAP,
|
||||
|
||||
/*!\brief Codec control function to set encoder scaling mode.
|
||||
*
|
||||
* Supported in codecs: VP8, AV1
|
||||
*/
|
||||
AOME_SET_SCALEMODE = 11,
|
||||
|
||||
/*!\brief Codec control function to set encoder internal speed settings.
|
||||
*
|
||||
* Changes in this value influences, among others, the encoder's selection
|
||||
* of motion estimation methods. Values greater than 0 will increase encoder
|
||||
* speed at the expense of quality.
|
||||
*
|
||||
* \note Valid range for VP8: -16..16
|
||||
* \note Valid range for AV1: -8..8
|
||||
*
|
||||
* Supported in codecs: VP8, AV1
|
||||
*/
|
||||
AOME_SET_CPUUSED = 13,
|
||||
|
||||
/*!\brief Codec control function to enable automatic set and use alf frames.
|
||||
*
|
||||
* Supported in codecs: VP8, AV1
|
||||
*/
|
||||
AOME_SET_ENABLEAUTOALTREF,
|
||||
|
||||
#if CONFIG_EXT_REFS
|
||||
/*!\brief Codec control function to enable automatic set and use
|
||||
* bwd-pred frames.
|
||||
*
|
||||
* Supported in codecs: AV1
|
||||
*/
|
||||
AOME_SET_ENABLEAUTOBWDREF,
|
||||
#endif // CONFIG_EXT_REFS
|
||||
|
||||
/*!\brief control function to set noise sensitivity
|
||||
*
|
||||
* 0: off, 1: OnYOnly, 2: OnYUV,
|
||||
* 3: OnYUVAggressive, 4: Adaptive
|
||||
*
|
||||
* Supported in codecs: VP8
|
||||
*/
|
||||
AOME_SET_NOISE_SENSITIVITY,
|
||||
|
||||
/*!\brief Codec control function to set sharpness.
|
||||
*
|
||||
* Supported in codecs: VP8, AV1
|
||||
*/
|
||||
AOME_SET_SHARPNESS,
|
||||
|
||||
/*!\brief Codec control function to set the threshold for MBs treated static.
|
||||
*
|
||||
* Supported in codecs: VP8, AV1
|
||||
*/
|
||||
AOME_SET_STATIC_THRESHOLD,
|
||||
|
||||
/*!\brief Codec control function to set the number of token partitions.
|
||||
*
|
||||
* Supported in codecs: VP8
|
||||
*/
|
||||
AOME_SET_TOKEN_PARTITIONS,
|
||||
|
||||
/*!\brief Codec control function to get last quantizer chosen by the encoder.
|
||||
*
|
||||
* Return value uses internal quantizer scale defined by the codec.
|
||||
*
|
||||
* Supported in codecs: VP8, AV1
|
||||
*/
|
||||
AOME_GET_LAST_QUANTIZER,
|
||||
|
||||
/*!\brief Codec control function to get last quantizer chosen by the encoder.
|
||||
*
|
||||
* Return value uses the 0..63 scale as used by the rc_*_quantizer config
|
||||
* parameters.
|
||||
*
|
||||
* Supported in codecs: VP8, AV1
|
||||
*/
|
||||
AOME_GET_LAST_QUANTIZER_64,
|
||||
|
||||
/*!\brief Codec control function to set the max no of frames to create arf.
|
||||
*
|
||||
* Supported in codecs: VP8, AV1
|
||||
*/
|
||||
AOME_SET_ARNR_MAXFRAMES,
|
||||
|
||||
/*!\brief Codec control function to set the filter strength for the arf.
|
||||
*
|
||||
* Supported in codecs: VP8, AV1
|
||||
*/
|
||||
AOME_SET_ARNR_STRENGTH,
|
||||
|
||||
/*!\deprecated control function to set the filter type to use for the arf. */
|
||||
AOME_SET_ARNR_TYPE,
|
||||
|
||||
/*!\brief Codec control function to set visual tuning.
|
||||
*
|
||||
* Supported in codecs: VP8, AV1
|
||||
*/
|
||||
AOME_SET_TUNING,
|
||||
|
||||
/*!\brief Codec control function to set constrained quality level.
|
||||
*
|
||||
* \attention For this value to be used aom_codec_enc_cfg_t::g_usage must be
|
||||
* set to #AOM_CQ.
|
||||
* \note Valid range: 0..63
|
||||
*
|
||||
* Supported in codecs: VP8, AV1
|
||||
*/
|
||||
AOME_SET_CQ_LEVEL,
|
||||
|
||||
/*!\brief Codec control function to set Max data rate for Intra frames.
|
||||
*
|
||||
* This value controls additional clamping on the maximum size of a
|
||||
* keyframe. It is expressed as a percentage of the average
|
||||
* per-frame bitrate, with the special (and default) value 0 meaning
|
||||
* unlimited, or no additional clamping beyond the codec's built-in
|
||||
* algorithm.
|
||||
*
|
||||
* For example, to allocate no more than 4.5 frames worth of bitrate
|
||||
* to a keyframe, set this to 450.
|
||||
*
|
||||
* Supported in codecs: VP8, AV1
|
||||
*/
|
||||
AOME_SET_MAX_INTRA_BITRATE_PCT,
|
||||
|
||||
/*!\brief Codec control function to set reference and update frame flags.
|
||||
*
|
||||
* Supported in codecs: VP8
|
||||
*/
|
||||
AOME_SET_FRAME_FLAGS,
|
||||
|
||||
/*!\brief Codec control function to set max data rate for Inter frames.
|
||||
*
|
||||
* This value controls additional clamping on the maximum size of an
|
||||
* inter frame. It is expressed as a percentage of the average
|
||||
* per-frame bitrate, with the special (and default) value 0 meaning
|
||||
* unlimited, or no additional clamping beyond the codec's built-in
|
||||
* algorithm.
|
||||
*
|
||||
* For example, to allow no more than 4.5 frames worth of bitrate
|
||||
* to an inter frame, set this to 450.
|
||||
*
|
||||
* Supported in codecs: AV1
|
||||
*/
|
||||
AV1E_SET_MAX_INTER_BITRATE_PCT,
|
||||
|
||||
/*!\brief Boost percentage for Golden Frame in CBR mode.
|
||||
*
|
||||
* This value controls the amount of boost given to Golden Frame in
|
||||
* CBR mode. It is expressed as a percentage of the average
|
||||
* per-frame bitrate, with the special (and default) value 0 meaning
|
||||
* the feature is off, i.e., no golden frame boost in CBR mode and
|
||||
* average bitrate target is used.
|
||||
*
|
||||
* For example, to allow 100% more bits, i.e, 2X, in a golden frame
|
||||
* than average frame, set this to 100.
|
||||
*
|
||||
* Supported in codecs: AV1
|
||||
*/
|
||||
AV1E_SET_GF_CBR_BOOST_PCT,
|
||||
|
||||
/*!\brief Codec control function to set encoder screen content mode.
|
||||
*
|
||||
* 0: off, 1: On, 2: On with more aggressive rate control.
|
||||
*
|
||||
* Supported in codecs: VP8
|
||||
*/
|
||||
AOME_SET_SCREEN_CONTENT_MODE,
|
||||
|
||||
/*!\brief Codec control function to set lossless encoding mode.
|
||||
*
|
||||
* AV1 can operate in lossless encoding mode, in which the bitstream
|
||||
* produced will be able to decode and reconstruct a perfect copy of
|
||||
* input source. This control function provides a mean to switch encoder
|
||||
* into lossless coding mode(1) or normal coding mode(0) that may be lossy.
|
||||
* 0 = lossy coding mode
|
||||
* 1 = lossless coding mode
|
||||
*
|
||||
* By default, encoder operates in normal coding mode (maybe lossy).
|
||||
*
|
||||
* Supported in codecs: AV1
|
||||
*/
|
||||
AV1E_SET_LOSSLESS,
|
||||
#if CONFIG_AOM_QM
|
||||
/*!\brief Codec control function to encode with quantisation matrices.
|
||||
*
|
||||
* AOM can operate with default quantisation matrices dependent on
|
||||
* quantisation level and block type.
|
||||
* 0 = do not use quantisation matrices
|
||||
* 1 = use quantisation matrices
|
||||
*
|
||||
* By default, the encoder operates without quantisation matrices.
|
||||
*
|
||||
* Supported in codecs: AOM
|
||||
*/
|
||||
|
||||
AV1E_SET_ENABLE_QM,
|
||||
|
||||
/*!\brief Codec control function to set the min quant matrix flatness.
|
||||
*
|
||||
* AOM can operate with different ranges of quantisation matrices.
|
||||
* As quantisation levels increase, the matrices get flatter. This
|
||||
* control sets the minimum level of flatness from which the matrices
|
||||
* are determined.
|
||||
*
|
||||
* By default, the encoder sets this minimum at half the available
|
||||
* range.
|
||||
*
|
||||
* Supported in codecs: AOM
|
||||
*/
|
||||
AV1E_SET_QM_MIN,
|
||||
|
||||
/*!\brief Codec control function to set the max quant matrix flatness.
|
||||
*
|
||||
* AOM can operate with different ranges of quantisation matrices.
|
||||
* As quantisation levels increase, the matrices get flatter. This
|
||||
* control sets the maximum level of flatness possible.
|
||||
*
|
||||
* By default, the encoder sets this maximum at the top of the
|
||||
* available range.
|
||||
*
|
||||
* Supported in codecs: AOM
|
||||
*/
|
||||
AV1E_SET_QM_MAX,
|
||||
#endif
|
||||
|
||||
/*!\brief Codec control function to set number of tile columns.
|
||||
*
|
||||
* In encoding and decoding, AV1 allows an input image frame be partitioned
|
||||
* into separated vertical tile columns, which can be encoded or decoded
|
||||
* independently. This enables easy implementation of parallel encoding and
|
||||
* decoding. This control requests the encoder to use column tiles in
|
||||
* encoding an input frame, with number of tile columns (in Log2 unit) as
|
||||
* the parameter:
|
||||
* 0 = 1 tile column
|
||||
* 1 = 2 tile columns
|
||||
* 2 = 4 tile columns
|
||||
* .....
|
||||
* n = 2**n tile columns
|
||||
* The requested tile columns will be capped by encoder based on image size
|
||||
* limitation (The minimum width of a tile column is 256 pixel, the maximum
|
||||
* is 4096).
|
||||
*
|
||||
* By default, the value is 0, i.e. one single column tile for entire image.
|
||||
*
|
||||
* Supported in codecs: AV1
|
||||
*/
|
||||
AV1E_SET_TILE_COLUMNS,
|
||||
|
||||
/*!\brief Codec control function to set number of tile rows.
|
||||
*
|
||||
* In encoding and decoding, AV1 allows an input image frame be partitioned
|
||||
* into separated horizontal tile rows. Tile rows are encoded or decoded
|
||||
* sequentially. Even though encoding/decoding of later tile rows depends on
|
||||
* earlier ones, this allows the encoder to output data packets for tile rows
|
||||
* prior to completely processing all tile rows in a frame, thereby reducing
|
||||
* the latency in processing between input and output. The parameter
|
||||
* for this control describes the number of tile rows, which has a valid
|
||||
* range [0, 2]:
|
||||
* 0 = 1 tile row
|
||||
* 1 = 2 tile rows
|
||||
* 2 = 4 tile rows
|
||||
*
|
||||
* By default, the value is 0, i.e. one single row tile for entire image.
|
||||
*
|
||||
* Supported in codecs: AV1
|
||||
*/
|
||||
AV1E_SET_TILE_ROWS,
|
||||
|
||||
/*!\brief Codec control function to enable frame parallel decoding feature.
|
||||
*
|
||||
* AV1 has a bitstream feature to reduce decoding dependency between frames
|
||||
* by turning off backward update of probability context used in encoding
|
||||
* and decoding. This allows staged parallel processing of more than one
|
||||
* video frames in the decoder. This control function provides a mean to
|
||||
* turn this feature on or off for bitstreams produced by encoder.
|
||||
*
|
||||
* By default, this feature is off.
|
||||
*
|
||||
* Supported in codecs: AV1
|
||||
*/
|
||||
AV1E_SET_FRAME_PARALLEL_DECODING,
|
||||
|
||||
/*!\brief Codec control function to set adaptive quantization mode.
|
||||
*
|
||||
* AV1 has a segment based feature that allows encoder to adaptively change
|
||||
* quantization parameter for each segment within a frame to improve the
|
||||
* subjective quality. This control makes encoder operate in one of the
|
||||
* several AQ_modes supported.
|
||||
*
|
||||
* By default, encoder operates with AQ_Mode 0(adaptive quantization off).
|
||||
*
|
||||
* Supported in codecs: AV1
|
||||
*/
|
||||
AV1E_SET_AQ_MODE,
|
||||
|
||||
/*!\brief Codec control function to enable/disable periodic Q boost.
|
||||
*
|
||||
* One AV1 encoder speed feature is to enable quality boost by lowering
|
||||
* frame level Q periodically. This control function provides a mean to
|
||||
* turn on/off this feature.
|
||||
* 0 = off
|
||||
* 1 = on
|
||||
*
|
||||
* By default, the encoder is allowed to use this feature for appropriate
|
||||
* encoding modes.
|
||||
*
|
||||
* Supported in codecs: AV1
|
||||
*/
|
||||
AV1E_SET_FRAME_PERIODIC_BOOST,
|
||||
|
||||
/*!\brief Codec control function to set noise sensitivity.
|
||||
*
|
||||
* 0: off, 1: On(YOnly)
|
||||
*
|
||||
* Supported in codecs: AV1
|
||||
*/
|
||||
AV1E_SET_NOISE_SENSITIVITY,
|
||||
|
||||
/*!\brief Codec control function to set content type.
|
||||
* \note Valid parameter range:
|
||||
* AOM_CONTENT_DEFAULT = Regular video content (Default)
|
||||
* AOM_CONTENT_SCREEN = Screen capture content
|
||||
*
|
||||
* Supported in codecs: AV1
|
||||
*/
|
||||
AV1E_SET_TUNE_CONTENT,
|
||||
|
||||
/*!\brief Codec control function to set color space info.
|
||||
* \note Valid ranges: 0..7, default is "UNKNOWN".
|
||||
* 0 = UNKNOWN,
|
||||
* 1 = BT_601
|
||||
* 2 = BT_709
|
||||
* 3 = SMPTE_170
|
||||
* 4 = SMPTE_240
|
||||
* 5 = BT_2020
|
||||
* 6 = RESERVED
|
||||
* 7 = SRGB
|
||||
*
|
||||
* Supported in codecs: AV1
|
||||
*/
|
||||
AV1E_SET_COLOR_SPACE,
|
||||
|
||||
/*!\brief Codec control function to set minimum interval between GF/ARF frames
|
||||
*
|
||||
* By default the value is set as 4.
|
||||
*
|
||||
* Supported in codecs: AV1
|
||||
*/
|
||||
AV1E_SET_MIN_GF_INTERVAL,
|
||||
|
||||
/*!\brief Codec control function to set minimum interval between GF/ARF frames
|
||||
*
|
||||
* By default the value is set as 16.
|
||||
*
|
||||
* Supported in codecs: AV1
|
||||
*/
|
||||
AV1E_SET_MAX_GF_INTERVAL,
|
||||
|
||||
/*!\brief Codec control function to get an Active map back from the encoder.
|
||||
*
|
||||
* Supported in codecs: AV1
|
||||
*/
|
||||
AV1E_GET_ACTIVEMAP,
|
||||
|
||||
/*!\brief Codec control function to set color range bit.
|
||||
* \note Valid ranges: 0..1, default is 0
|
||||
* 0 = Limited range (16..235 or HBD equivalent)
|
||||
* 1 = Full range (0..255 or HBD equivalent)
|
||||
*
|
||||
* Supported in codecs: AV1
|
||||
*/
|
||||
AV1E_SET_COLOR_RANGE,
|
||||
|
||||
/*!\brief Codec control function to set intended rendering image size.
|
||||
*
|
||||
* By default, this is identical to the image size in pixels.
|
||||
*
|
||||
* Supported in codecs: AV1
|
||||
*/
|
||||
AV1E_SET_RENDER_SIZE,
|
||||
|
||||
/*!\brief Codec control function to set target level.
|
||||
*
|
||||
* 255: off (default); 0: only keep level stats; 10: target for level 1.0;
|
||||
* 11: target for level 1.1; ... 62: target for level 6.2
|
||||
*
|
||||
* Supported in codecs: AV1
|
||||
*/
|
||||
AV1E_SET_TARGET_LEVEL,
|
||||
|
||||
/*!\brief Codec control function to get bitstream level.
|
||||
*
|
||||
* Supported in codecs: AV1
|
||||
*/
|
||||
AV1E_GET_LEVEL,
|
||||
|
||||
/*!\brief Codec control function to set intended superblock size.
|
||||
*
|
||||
* By default, the superblock size is determined separately for each
|
||||
* frame by the encoder.
|
||||
*
|
||||
* Supported in codecs: AV1
|
||||
*/
|
||||
AV1E_SET_SUPERBLOCK_SIZE,
|
||||
};
|
||||
|
||||
/*!\brief aom 1-D scaling mode
|
||||
*
|
||||
* This set of constants define 1-D aom scaling modes
|
||||
*/
|
||||
typedef enum aom_scaling_mode_1d {
|
||||
AOME_NORMAL = 0,
|
||||
AOME_FOURFIVE = 1,
|
||||
AOME_THREEFIVE = 2,
|
||||
AOME_ONETWO = 3
|
||||
} AOM_SCALING_MODE;
|
||||
|
||||
/*!\brief aom region of interest map
|
||||
*
|
||||
* These defines the data structures for the region of interest map
|
||||
*
|
||||
*/
|
||||
|
||||
typedef struct aom_roi_map {
|
||||
/*! An id between 0 and 3 for each 16x16 region within a frame. */
|
||||
unsigned char *roi_map;
|
||||
unsigned int rows; /**< Number of rows. */
|
||||
unsigned int cols; /**< Number of columns. */
|
||||
// TODO(paulwilkins): broken for AV1 which has 8 segments
|
||||
// q and loop filter deltas for each segment
|
||||
// (see MAX_MB_SEGMENTS)
|
||||
int delta_q[4]; /**< Quantizer deltas. */
|
||||
int delta_lf[4]; /**< Loop filter deltas. */
|
||||
/*! Static breakout threshold for each segment. */
|
||||
unsigned int static_threshold[4];
|
||||
} aom_roi_map_t;
|
||||
|
||||
/*!\brief aom active region map
|
||||
*
|
||||
* These defines the data structures for active region map
|
||||
*
|
||||
*/
|
||||
|
||||
typedef struct aom_active_map {
|
||||
/*!\brief specify an on (1) or off (0) each 16x16 region within a frame */
|
||||
unsigned char *active_map;
|
||||
unsigned int rows; /**< number of rows */
|
||||
unsigned int cols; /**< number of cols */
|
||||
} aom_active_map_t;
|
||||
|
||||
/*!\brief aom image scaling mode
|
||||
*
|
||||
* This defines the data structure for image scaling mode
|
||||
*
|
||||
*/
|
||||
typedef struct aom_scaling_mode {
|
||||
AOM_SCALING_MODE h_scaling_mode; /**< horizontal scaling mode */
|
||||
AOM_SCALING_MODE v_scaling_mode; /**< vertical scaling mode */
|
||||
} aom_scaling_mode_t;
|
||||
|
||||
/*!\brief VP8 token partition mode
|
||||
*
|
||||
* This defines VP8 partitioning mode for compressed data, i.e., the number of
|
||||
* sub-streams in the bitstream. Used for parallelized decoding.
|
||||
*
|
||||
*/
|
||||
|
||||
typedef enum {
|
||||
AOM_ONE_TOKENPARTITION = 0,
|
||||
AOM_TWO_TOKENPARTITION = 1,
|
||||
AOM_FOUR_TOKENPARTITION = 2,
|
||||
AOM_EIGHT_TOKENPARTITION = 3
|
||||
} aome_token_partitions;
|
||||
|
||||
/*!brief AV1 encoder content type */
|
||||
typedef enum {
|
||||
AOM_CONTENT_DEFAULT,
|
||||
AOM_CONTENT_SCREEN,
|
||||
AOM_CONTENT_INVALID
|
||||
} aom_tune_content;
|
||||
|
||||
/*!\brief VP8 model tuning parameters
|
||||
*
|
||||
* Changes the encoder to tune for certain types of input material.
|
||||
*
|
||||
*/
|
||||
typedef enum { AOM_TUNE_PSNR, AOM_TUNE_SSIM } aom_tune_metric;
|
||||
|
||||
/*!\cond */
|
||||
/*!\brief VP8 encoder control function parameter type
|
||||
*
|
||||
* Defines the data types that VP8E control functions take. Note that
|
||||
* additional common controls are defined in aom.h
|
||||
*
|
||||
*/
|
||||
|
||||
AOM_CTRL_USE_TYPE_DEPRECATED(AOME_USE_REFERENCE, int)
|
||||
#define AOM_CTRL_AOME_USE_REFERENCE
|
||||
AOM_CTRL_USE_TYPE(AOME_SET_FRAME_FLAGS, int)
|
||||
#define AOM_CTRL_AOME_SET_FRAME_FLAGS
|
||||
AOM_CTRL_USE_TYPE(AOME_SET_ROI_MAP, aom_roi_map_t *)
|
||||
#define AOM_CTRL_AOME_SET_ROI_MAP
|
||||
AOM_CTRL_USE_TYPE(AOME_SET_ACTIVEMAP, aom_active_map_t *)
|
||||
#define AOM_CTRL_AOME_SET_ACTIVEMAP
|
||||
AOM_CTRL_USE_TYPE(AOME_SET_SCALEMODE, aom_scaling_mode_t *)
|
||||
#define AOM_CTRL_AOME_SET_SCALEMODE
|
||||
|
||||
AOM_CTRL_USE_TYPE(AOME_SET_CPUUSED, int)
|
||||
#define AOM_CTRL_AOME_SET_CPUUSED
|
||||
AOM_CTRL_USE_TYPE(AOME_SET_ENABLEAUTOALTREF, unsigned int)
|
||||
#define AOM_CTRL_AOME_SET_ENABLEAUTOALTREF
|
||||
|
||||
#if CONFIG_EXT_REFS
|
||||
AOM_CTRL_USE_TYPE(AOME_SET_ENABLEAUTOBWDREF, unsigned int)
|
||||
#define AOM_CTRL_AOME_SET_ENABLEAUTOBWDREF
|
||||
#endif // CONFIG_EXT_REFS
|
||||
|
||||
AOM_CTRL_USE_TYPE(AOME_SET_NOISE_SENSITIVITY, unsigned int)
|
||||
#define AOM_CTRL_AOME_SET_NOISE_SENSITIVITY
|
||||
AOM_CTRL_USE_TYPE(AOME_SET_SHARPNESS, unsigned int)
|
||||
#define AOM_CTRL_AOME_SET_SHARPNESS
|
||||
AOM_CTRL_USE_TYPE(AOME_SET_STATIC_THRESHOLD, unsigned int)
|
||||
#define AOM_CTRL_AOME_SET_STATIC_THRESHOLD
|
||||
AOM_CTRL_USE_TYPE(AOME_SET_TOKEN_PARTITIONS, int) /* aome_token_partitions */
|
||||
#define AOM_CTRL_AOME_SET_TOKEN_PARTITIONS
|
||||
|
||||
AOM_CTRL_USE_TYPE(AOME_SET_ARNR_MAXFRAMES, unsigned int)
|
||||
#define AOM_CTRL_AOME_SET_ARNR_MAXFRAMES
|
||||
AOM_CTRL_USE_TYPE(AOME_SET_ARNR_STRENGTH, unsigned int)
|
||||
#define AOM_CTRL_AOME_SET_ARNR_STRENGTH
|
||||
AOM_CTRL_USE_TYPE_DEPRECATED(AOME_SET_ARNR_TYPE, unsigned int)
|
||||
#define AOM_CTRL_AOME_SET_ARNR_TYPE
|
||||
AOM_CTRL_USE_TYPE(AOME_SET_TUNING, int) /* aom_tune_metric */
|
||||
#define AOM_CTRL_AOME_SET_TUNING
|
||||
AOM_CTRL_USE_TYPE(AOME_SET_CQ_LEVEL, unsigned int)
|
||||
#define AOM_CTRL_AOME_SET_CQ_LEVEL
|
||||
|
||||
AOM_CTRL_USE_TYPE(AV1E_SET_TILE_COLUMNS, int)
|
||||
#define AOM_CTRL_AV1E_SET_TILE_COLUMNS
|
||||
AOM_CTRL_USE_TYPE(AV1E_SET_TILE_ROWS, int)
|
||||
#define AOM_CTRL_AV1E_SET_TILE_ROWS
|
||||
|
||||
AOM_CTRL_USE_TYPE(AOME_GET_LAST_QUANTIZER, int *)
|
||||
#define AOM_CTRL_AOME_GET_LAST_QUANTIZER
|
||||
AOM_CTRL_USE_TYPE(AOME_GET_LAST_QUANTIZER_64, int *)
|
||||
#define AOM_CTRL_AOME_GET_LAST_QUANTIZER_64
|
||||
|
||||
AOM_CTRL_USE_TYPE(AOME_SET_MAX_INTRA_BITRATE_PCT, unsigned int)
|
||||
#define AOM_CTRL_AOME_SET_MAX_INTRA_BITRATE_PCT
|
||||
AOM_CTRL_USE_TYPE(AOME_SET_MAX_INTER_BITRATE_PCT, unsigned int)
|
||||
#define AOM_CTRL_AOME_SET_MAX_INTER_BITRATE_PCT
|
||||
|
||||
AOM_CTRL_USE_TYPE(AOME_SET_SCREEN_CONTENT_MODE, unsigned int)
|
||||
#define AOM_CTRL_AOME_SET_SCREEN_CONTENT_MODE
|
||||
|
||||
AOM_CTRL_USE_TYPE(AV1E_SET_GF_CBR_BOOST_PCT, unsigned int)
|
||||
#define AOM_CTRL_AV1E_SET_GF_CBR_BOOST_PCT
|
||||
|
||||
AOM_CTRL_USE_TYPE(AV1E_SET_LOSSLESS, unsigned int)
|
||||
#define AOM_CTRL_AV1E_SET_LOSSLESS
|
||||
|
||||
#if CONFIG_AOM_QM
|
||||
AOM_CTRL_USE_TYPE(AV1E_SET_ENABLE_QM, unsigned int)
|
||||
#define AOM_CTRL_AV1E_SET_ENABLE_QM
|
||||
|
||||
AOM_CTRL_USE_TYPE(AV1E_SET_QM_MIN, unsigned int)
|
||||
#define AOM_CTRL_AV1E_SET_QM_MIN
|
||||
|
||||
AOM_CTRL_USE_TYPE(AV1E_SET_QM_MAX, unsigned int)
|
||||
#define AOM_CTRL_AV1E_SET_QM_MAX
|
||||
#endif
|
||||
|
||||
AOM_CTRL_USE_TYPE(AV1E_SET_FRAME_PARALLEL_DECODING, unsigned int)
|
||||
#define AOM_CTRL_AV1E_SET_FRAME_PARALLEL_DECODING
|
||||
|
||||
AOM_CTRL_USE_TYPE(AV1E_SET_AQ_MODE, unsigned int)
|
||||
#define AOM_CTRL_AV1E_SET_AQ_MODE
|
||||
|
||||
AOM_CTRL_USE_TYPE(AV1E_SET_FRAME_PERIODIC_BOOST, unsigned int)
|
||||
#define AOM_CTRL_AV1E_SET_FRAME_PERIODIC_BOOST
|
||||
|
||||
AOM_CTRL_USE_TYPE(AV1E_SET_NOISE_SENSITIVITY, unsigned int)
|
||||
#define AOM_CTRL_AV1E_SET_NOISE_SENSITIVITY
|
||||
|
||||
AOM_CTRL_USE_TYPE(AV1E_SET_TUNE_CONTENT, int) /* aom_tune_content */
|
||||
#define AOM_CTRL_AV1E_SET_TUNE_CONTENT
|
||||
|
||||
AOM_CTRL_USE_TYPE(AV1E_SET_COLOR_SPACE, int)
|
||||
#define AOM_CTRL_AV1E_SET_COLOR_SPACE
|
||||
|
||||
AOM_CTRL_USE_TYPE(AV1E_SET_MIN_GF_INTERVAL, unsigned int)
|
||||
#define AOM_CTRL_AV1E_SET_MIN_GF_INTERVAL
|
||||
|
||||
AOM_CTRL_USE_TYPE(AV1E_SET_MAX_GF_INTERVAL, unsigned int)
|
||||
#define AOM_CTRL_AV1E_SET_MAX_GF_INTERVAL
|
||||
|
||||
AOM_CTRL_USE_TYPE(AV1E_GET_ACTIVEMAP, aom_active_map_t *)
|
||||
#define AOM_CTRL_AV1E_GET_ACTIVEMAP
|
||||
|
||||
AOM_CTRL_USE_TYPE(AV1E_SET_COLOR_RANGE, int)
|
||||
#define AOM_CTRL_AV1E_SET_COLOR_RANGE
|
||||
|
||||
/*!\brief
|
||||
*
|
||||
* TODO(rbultje) : add support of the control in ffmpeg
|
||||
*/
|
||||
#define AOM_CTRL_AV1E_SET_RENDER_SIZE
|
||||
AOM_CTRL_USE_TYPE(AV1E_SET_RENDER_SIZE, int *)
|
||||
|
||||
AOM_CTRL_USE_TYPE(AV1E_SET_SUPERBLOCK_SIZE, unsigned int)
|
||||
#define AOM_CTRL_AV1E_SET_SUPERBLOCK_SIZE
|
||||
|
||||
AOM_CTRL_USE_TYPE(AV1E_SET_TARGET_LEVEL, unsigned int)
|
||||
#define AOM_CTRL_AV1E_SET_TARGET_LEVEL
|
||||
|
||||
AOM_CTRL_USE_TYPE(AV1E_GET_LEVEL, int *)
|
||||
#define AOM_CTRL_AV1E_GET_LEVEL
|
||||
/*!\endcond */
|
||||
/*! @} - end defgroup vp8_encoder */
|
||||
#ifdef __cplusplus
|
||||
} // extern "C"
|
||||
#endif
|
||||
|
||||
#endif // AOM_AOMCX_H_
|
||||
191
aom/aomdx.h
191
aom/aomdx.h
@@ -1,191 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2016, Alliance for Open Media. All rights reserved
|
||||
*
|
||||
* This source code is subject to the terms of the BSD 2 Clause License and
|
||||
* the Alliance for Open Media Patent License 1.0. If the BSD 2 Clause License
|
||||
* was not distributed with this source code in the LICENSE file, you can
|
||||
* obtain it at www.aomedia.org/license/software. If the Alliance for Open
|
||||
* Media Patent License 1.0 was not distributed with this source code in the
|
||||
* PATENTS file, you can obtain it at www.aomedia.org/license/patent.
|
||||
*/
|
||||
|
||||
/*!\defgroup aom_decoder AOMedia AOM/AV1 Decoder
|
||||
* \ingroup aom
|
||||
*
|
||||
* @{
|
||||
*/
|
||||
/*!\file
|
||||
* \brief Provides definitions for using AOM or AV1 within the aom Decoder
|
||||
* interface.
|
||||
*/
|
||||
#ifndef AOM_AOMDX_H_
|
||||
#define AOM_AOMDX_H_
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* Include controls common to both the encoder and decoder */
|
||||
#include "./aom.h"
|
||||
|
||||
/*!\name Algorithm interface for AV1
|
||||
*
|
||||
* This interface provides the capability to decode AV1 streams.
|
||||
* @{
|
||||
*/
|
||||
extern aom_codec_iface_t aom_codec_av1_dx_algo;
|
||||
extern aom_codec_iface_t *aom_codec_av1_dx(void);
|
||||
/*!@} - end algorithm interface member group*/
|
||||
|
||||
/** Data structure that stores bit accounting for debug
|
||||
*/
|
||||
typedef struct Accounting Accounting;
|
||||
|
||||
/*!\enum aom_dec_control_id
|
||||
* \brief AOM decoder control functions
|
||||
*
|
||||
* This set of macros define the control functions available for the AOM
|
||||
* decoder interface.
|
||||
*
|
||||
* \sa #aom_codec_control
|
||||
*/
|
||||
enum aom_dec_control_id {
|
||||
/** control function to get info on which reference frames were updated
|
||||
* by the last decode
|
||||
*/
|
||||
AOMD_GET_LAST_REF_UPDATES = AOM_DECODER_CTRL_ID_START,
|
||||
|
||||
/** check if the indicated frame is corrupted */
|
||||
AOMD_GET_FRAME_CORRUPTED,
|
||||
|
||||
/** control function to get info on which reference frames were used
|
||||
* by the last decode
|
||||
*/
|
||||
AOMD_GET_LAST_REF_USED,
|
||||
|
||||
/** decryption function to decrypt encoded buffer data immediately
|
||||
* before decoding. Takes a aom_decrypt_init, which contains
|
||||
* a callback function and opaque context pointer.
|
||||
*/
|
||||
AOMD_SET_DECRYPTOR,
|
||||
// AOMD_SET_DECRYPTOR = AOMD_SET_DECRYPTOR,
|
||||
|
||||
/** control function to get the dimensions that the current frame is decoded
|
||||
* at. This may be different to the intended display size for the frame as
|
||||
* specified in the wrapper or frame header (see AV1D_GET_DISPLAY_SIZE). */
|
||||
AV1D_GET_FRAME_SIZE,
|
||||
|
||||
/** control function to get the current frame's intended display dimensions
|
||||
* (as specified in the wrapper or frame header). This may be different to
|
||||
* the decoded dimensions of this frame (see AV1D_GET_FRAME_SIZE). */
|
||||
AV1D_GET_DISPLAY_SIZE,
|
||||
|
||||
/** control function to get the bit depth of the stream. */
|
||||
AV1D_GET_BIT_DEPTH,
|
||||
|
||||
/** control function to set the byte alignment of the planes in the reference
|
||||
* buffers. Valid values are power of 2, from 32 to 1024. A value of 0 sets
|
||||
* legacy alignment. I.e. Y plane is aligned to 32 bytes, U plane directly
|
||||
* follows Y plane, and V plane directly follows U plane. Default value is 0.
|
||||
*/
|
||||
AV1_SET_BYTE_ALIGNMENT,
|
||||
|
||||
/** control function to invert the decoding order to from right to left. The
|
||||
* function is used in a test to confirm the decoding independence of tile
|
||||
* columns. The function may be used in application where this order
|
||||
* of decoding is desired.
|
||||
*
|
||||
* TODO(yaowu): Rework the unit test that uses this control, and in a future
|
||||
* release, this test-only control shall be removed.
|
||||
*/
|
||||
AV1_INVERT_TILE_DECODE_ORDER,
|
||||
|
||||
/** control function to set the skip loop filter flag. Valid values are
|
||||
* integers. The decoder will skip the loop filter when its value is set to
|
||||
* nonzero. If the loop filter is skipped the decoder may accumulate decode
|
||||
* artifacts. The default value is 0.
|
||||
*/
|
||||
AV1_SET_SKIP_LOOP_FILTER,
|
||||
|
||||
/** control function to retrieve a pointer to the Accounting struct. When
|
||||
* compiled without --enable-accounting, this returns AOM_CODEC_INCAPABLE.
|
||||
* If called before a frame has been decoded, this returns AOM_CODEC_ERROR.
|
||||
* The caller should ensure that AOM_CODEC_OK is returned before attempting
|
||||
* to dereference the Accounting pointer.
|
||||
*/
|
||||
AV1_GET_ACCOUNTING,
|
||||
|
||||
AOM_DECODER_CTRL_ID_MAX,
|
||||
|
||||
/** control function to set the range of tile decoding. A value that is
|
||||
* greater and equal to zero indicates only the specific row/column is
|
||||
* decoded. A value that is -1 indicates the whole row/column is decoded.
|
||||
* A special case is both values are -1 that means the whole frame is
|
||||
* decoded.
|
||||
*/
|
||||
AV1_SET_DECODE_TILE_ROW,
|
||||
AV1_SET_DECODE_TILE_COL
|
||||
};
|
||||
|
||||
/** Decrypt n bytes of data from input -> output, using the decrypt_state
|
||||
* passed in AOMD_SET_DECRYPTOR.
|
||||
*/
|
||||
typedef void (*aom_decrypt_cb)(void *decrypt_state, const unsigned char *input,
|
||||
unsigned char *output, int count);
|
||||
|
||||
/*!\brief Structure to hold decryption state
|
||||
*
|
||||
* Defines a structure to hold the decryption state and access function.
|
||||
*/
|
||||
typedef struct aom_decrypt_init {
|
||||
/*! Decrypt callback. */
|
||||
aom_decrypt_cb decrypt_cb;
|
||||
|
||||
/*! Decryption state. */
|
||||
void *decrypt_state;
|
||||
} aom_decrypt_init;
|
||||
|
||||
/*!\brief A deprecated alias for aom_decrypt_init.
|
||||
*/
|
||||
typedef aom_decrypt_init aom_decrypt_init;
|
||||
|
||||
/*!\cond */
|
||||
/*!\brief AOM decoder control function parameter type
|
||||
*
|
||||
* Defines the data types that AOMD control functions take. Note that
|
||||
* additional common controls are defined in aom.h
|
||||
*
|
||||
*/
|
||||
|
||||
AOM_CTRL_USE_TYPE(AOMD_GET_LAST_REF_UPDATES, int *)
|
||||
#define AOM_CTRL_AOMD_GET_LAST_REF_UPDATES
|
||||
AOM_CTRL_USE_TYPE(AOMD_GET_FRAME_CORRUPTED, int *)
|
||||
#define AOM_CTRL_AOMD_GET_FRAME_CORRUPTED
|
||||
AOM_CTRL_USE_TYPE(AOMD_GET_LAST_REF_USED, int *)
|
||||
#define AOM_CTRL_AOMD_GET_LAST_REF_USED
|
||||
AOM_CTRL_USE_TYPE(AOMD_SET_DECRYPTOR, aom_decrypt_init *)
|
||||
#define AOM_CTRL_AOMD_SET_DECRYPTOR
|
||||
// AOM_CTRL_USE_TYPE(AOMD_SET_DECRYPTOR, aom_decrypt_init *)
|
||||
//#define AOM_CTRL_AOMD_SET_DECRYPTOR
|
||||
AOM_CTRL_USE_TYPE(AV1D_GET_DISPLAY_SIZE, int *)
|
||||
#define AOM_CTRL_AV1D_GET_DISPLAY_SIZE
|
||||
AOM_CTRL_USE_TYPE(AV1D_GET_BIT_DEPTH, unsigned int *)
|
||||
#define AOM_CTRL_AV1D_GET_BIT_DEPTH
|
||||
AOM_CTRL_USE_TYPE(AV1D_GET_FRAME_SIZE, int *)
|
||||
#define AOM_CTRL_AV1D_GET_FRAME_SIZE
|
||||
AOM_CTRL_USE_TYPE(AV1_INVERT_TILE_DECODE_ORDER, int)
|
||||
#define AOM_CTRL_AV1_INVERT_TILE_DECODE_ORDER
|
||||
AOM_CTRL_USE_TYPE(AV1_GET_ACCOUNTING, Accounting **)
|
||||
#define AOM_CTRL_AV1_GET_ACCOUNTING
|
||||
AOM_CTRL_USE_TYPE(AV1_SET_DECODE_TILE_ROW, int)
|
||||
#define AOM_CTRL_AV1_SET_DECODE_TILE_ROW
|
||||
AOM_CTRL_USE_TYPE(AV1_SET_DECODE_TILE_COL, int)
|
||||
#define AOM_CTRL_AV1_SET_DECODE_TILE_COL
|
||||
/*!\endcond */
|
||||
/*! @} - end defgroup aom_decoder */
|
||||
|
||||
#ifdef __cplusplus
|
||||
} // extern "C"
|
||||
#endif
|
||||
|
||||
#endif // AOM_AOMDX_H_
|
||||
@@ -1,16 +0,0 @@
|
||||
text aom_codec_build_config
|
||||
text aom_codec_control_
|
||||
text aom_codec_destroy
|
||||
text aom_codec_err_to_string
|
||||
text aom_codec_error
|
||||
text aom_codec_error_detail
|
||||
text aom_codec_get_caps
|
||||
text aom_codec_iface_name
|
||||
text aom_codec_version
|
||||
text aom_codec_version_extra_str
|
||||
text aom_codec_version_str
|
||||
text aom_img_alloc
|
||||
text aom_img_flip
|
||||
text aom_img_free
|
||||
text aom_img_set_rect
|
||||
text aom_img_wrap
|
||||
@@ -1,8 +0,0 @@
|
||||
text aom_codec_dec_init_ver
|
||||
text aom_codec_decode
|
||||
text aom_codec_get_frame
|
||||
text aom_codec_get_stream_info
|
||||
text aom_codec_peek_stream_info
|
||||
text aom_codec_register_put_frame_cb
|
||||
text aom_codec_register_put_slice_cb
|
||||
text aom_codec_set_frame_buffer_functions
|
||||
@@ -1,9 +0,0 @@
|
||||
text aom_codec_enc_config_default
|
||||
text aom_codec_enc_config_set
|
||||
text aom_codec_enc_init_multi_ver
|
||||
text aom_codec_enc_init_ver
|
||||
text aom_codec_encode
|
||||
text aom_codec_get_cx_data
|
||||
text aom_codec_get_global_headers
|
||||
text aom_codec_get_preview_frame
|
||||
text aom_codec_set_cx_data_buf
|
||||
@@ -1,134 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2016, Alliance for Open Media. All rights reserved
|
||||
*
|
||||
* This source code is subject to the terms of the BSD 2 Clause License and
|
||||
* the Alliance for Open Media Patent License 1.0. If the BSD 2 Clause License
|
||||
* was not distributed with this source code in the LICENSE file, you can
|
||||
* obtain it at www.aomedia.org/license/software. If the Alliance for Open
|
||||
* Media Patent License 1.0 was not distributed with this source code in the
|
||||
* PATENTS file, you can obtain it at www.aomedia.org/license/patent.
|
||||
*/
|
||||
|
||||
/*!\file
|
||||
* \brief Provides the high level interface to wrap decoder algorithms.
|
||||
*
|
||||
*/
|
||||
#include <stdarg.h>
|
||||
#include <stdlib.h>
|
||||
#include "aom/aom_integer.h"
|
||||
#include "aom/internal/aom_codec_internal.h"
|
||||
#include "aom_version.h"
|
||||
|
||||
#define SAVE_STATUS(ctx, var) (ctx ? (ctx->err = var) : var)
|
||||
|
||||
int aom_codec_version(void) { return VERSION_PACKED; }
|
||||
|
||||
const char *aom_codec_version_str(void) { return VERSION_STRING_NOSP; }
|
||||
|
||||
const char *aom_codec_version_extra_str(void) { return VERSION_EXTRA; }
|
||||
|
||||
const char *aom_codec_iface_name(aom_codec_iface_t *iface) {
|
||||
return iface ? iface->name : "<invalid interface>";
|
||||
}
|
||||
|
||||
const char *aom_codec_err_to_string(aom_codec_err_t err) {
|
||||
switch (err) {
|
||||
case AOM_CODEC_OK: return "Success";
|
||||
case AOM_CODEC_ERROR: return "Unspecified internal error";
|
||||
case AOM_CODEC_MEM_ERROR: return "Memory allocation error";
|
||||
case AOM_CODEC_ABI_MISMATCH: return "ABI version mismatch";
|
||||
case AOM_CODEC_INCAPABLE:
|
||||
return "Codec does not implement requested capability";
|
||||
case AOM_CODEC_UNSUP_BITSTREAM:
|
||||
return "Bitstream not supported by this decoder";
|
||||
case AOM_CODEC_UNSUP_FEATURE:
|
||||
return "Bitstream required feature not supported by this decoder";
|
||||
case AOM_CODEC_CORRUPT_FRAME: return "Corrupt frame detected";
|
||||
case AOM_CODEC_INVALID_PARAM: return "Invalid parameter";
|
||||
case AOM_CODEC_LIST_END: return "End of iterated list";
|
||||
}
|
||||
|
||||
return "Unrecognized error code";
|
||||
}
|
||||
|
||||
const char *aom_codec_error(aom_codec_ctx_t *ctx) {
|
||||
return (ctx) ? aom_codec_err_to_string(ctx->err)
|
||||
: aom_codec_err_to_string(AOM_CODEC_INVALID_PARAM);
|
||||
}
|
||||
|
||||
const char *aom_codec_error_detail(aom_codec_ctx_t *ctx) {
|
||||
if (ctx && ctx->err)
|
||||
return ctx->priv ? ctx->priv->err_detail : ctx->err_detail;
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
aom_codec_err_t aom_codec_destroy(aom_codec_ctx_t *ctx) {
|
||||
aom_codec_err_t res;
|
||||
|
||||
if (!ctx)
|
||||
res = AOM_CODEC_INVALID_PARAM;
|
||||
else if (!ctx->iface || !ctx->priv)
|
||||
res = AOM_CODEC_ERROR;
|
||||
else {
|
||||
ctx->iface->destroy((aom_codec_alg_priv_t *)ctx->priv);
|
||||
|
||||
ctx->iface = NULL;
|
||||
ctx->name = NULL;
|
||||
ctx->priv = NULL;
|
||||
res = AOM_CODEC_OK;
|
||||
}
|
||||
|
||||
return SAVE_STATUS(ctx, res);
|
||||
}
|
||||
|
||||
aom_codec_caps_t aom_codec_get_caps(aom_codec_iface_t *iface) {
|
||||
return (iface) ? iface->caps : 0;
|
||||
}
|
||||
|
||||
aom_codec_err_t aom_codec_control_(aom_codec_ctx_t *ctx, int ctrl_id, ...) {
|
||||
aom_codec_err_t res;
|
||||
|
||||
if (!ctx || !ctrl_id)
|
||||
res = AOM_CODEC_INVALID_PARAM;
|
||||
else if (!ctx->iface || !ctx->priv || !ctx->iface->ctrl_maps)
|
||||
res = AOM_CODEC_ERROR;
|
||||
else {
|
||||
aom_codec_ctrl_fn_map_t *entry;
|
||||
|
||||
res = AOM_CODEC_ERROR;
|
||||
|
||||
for (entry = ctx->iface->ctrl_maps; entry && entry->fn; entry++) {
|
||||
if (!entry->ctrl_id || entry->ctrl_id == ctrl_id) {
|
||||
va_list ap;
|
||||
|
||||
va_start(ap, ctrl_id);
|
||||
res = entry->fn((aom_codec_alg_priv_t *)ctx->priv, ap);
|
||||
va_end(ap);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return SAVE_STATUS(ctx, res);
|
||||
}
|
||||
|
||||
void aom_internal_error(struct aom_internal_error_info *info,
|
||||
aom_codec_err_t error, const char *fmt, ...) {
|
||||
va_list ap;
|
||||
|
||||
info->error_code = error;
|
||||
info->has_detail = 0;
|
||||
|
||||
if (fmt) {
|
||||
size_t sz = sizeof(info->detail);
|
||||
|
||||
info->has_detail = 1;
|
||||
va_start(ap, fmt);
|
||||
vsnprintf(info->detail, sz - 1, fmt, ap);
|
||||
va_end(ap);
|
||||
info->detail[sz - 1] = '\0';
|
||||
}
|
||||
|
||||
if (info->setjmp) longjmp(info->jmp, info->error_code);
|
||||
}
|
||||
@@ -1,189 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2016, Alliance for Open Media. All rights reserved
|
||||
*
|
||||
* This source code is subject to the terms of the BSD 2 Clause License and
|
||||
* the Alliance for Open Media Patent License 1.0. If the BSD 2 Clause License
|
||||
* was not distributed with this source code in the LICENSE file, you can
|
||||
* obtain it at www.aomedia.org/license/software. If the Alliance for Open
|
||||
* Media Patent License 1.0 was not distributed with this source code in the
|
||||
* PATENTS file, you can obtain it at www.aomedia.org/license/patent.
|
||||
*/
|
||||
|
||||
/*!\file
|
||||
* \brief Provides the high level interface to wrap decoder algorithms.
|
||||
*
|
||||
*/
|
||||
#include <string.h>
|
||||
#include "aom/internal/aom_codec_internal.h"
|
||||
|
||||
#define SAVE_STATUS(ctx, var) (ctx ? (ctx->err = var) : var)
|
||||
|
||||
static aom_codec_alg_priv_t *get_alg_priv(aom_codec_ctx_t *ctx) {
|
||||
return (aom_codec_alg_priv_t *)ctx->priv;
|
||||
}
|
||||
|
||||
aom_codec_err_t aom_codec_dec_init_ver(aom_codec_ctx_t *ctx,
|
||||
aom_codec_iface_t *iface,
|
||||
const aom_codec_dec_cfg_t *cfg,
|
||||
aom_codec_flags_t flags, int ver) {
|
||||
aom_codec_err_t res;
|
||||
|
||||
if (ver != AOM_DECODER_ABI_VERSION)
|
||||
res = AOM_CODEC_ABI_MISMATCH;
|
||||
else if (!ctx || !iface)
|
||||
res = AOM_CODEC_INVALID_PARAM;
|
||||
else if (iface->abi_version != AOM_CODEC_INTERNAL_ABI_VERSION)
|
||||
res = AOM_CODEC_ABI_MISMATCH;
|
||||
else if ((flags & AOM_CODEC_USE_POSTPROC) &&
|
||||
!(iface->caps & AOM_CODEC_CAP_POSTPROC))
|
||||
res = AOM_CODEC_INCAPABLE;
|
||||
else if ((flags & AOM_CODEC_USE_ERROR_CONCEALMENT) &&
|
||||
!(iface->caps & AOM_CODEC_CAP_ERROR_CONCEALMENT))
|
||||
res = AOM_CODEC_INCAPABLE;
|
||||
else if ((flags & AOM_CODEC_USE_INPUT_FRAGMENTS) &&
|
||||
!(iface->caps & AOM_CODEC_CAP_INPUT_FRAGMENTS))
|
||||
res = AOM_CODEC_INCAPABLE;
|
||||
else if (!(iface->caps & AOM_CODEC_CAP_DECODER))
|
||||
res = AOM_CODEC_INCAPABLE;
|
||||
else {
|
||||
memset(ctx, 0, sizeof(*ctx));
|
||||
ctx->iface = iface;
|
||||
ctx->name = iface->name;
|
||||
ctx->priv = NULL;
|
||||
ctx->init_flags = flags;
|
||||
ctx->config.dec = cfg;
|
||||
|
||||
res = ctx->iface->init(ctx, NULL);
|
||||
if (res) {
|
||||
ctx->err_detail = ctx->priv ? ctx->priv->err_detail : NULL;
|
||||
aom_codec_destroy(ctx);
|
||||
}
|
||||
}
|
||||
|
||||
return SAVE_STATUS(ctx, res);
|
||||
}
|
||||
|
||||
aom_codec_err_t aom_codec_peek_stream_info(aom_codec_iface_t *iface,
|
||||
const uint8_t *data,
|
||||
unsigned int data_sz,
|
||||
aom_codec_stream_info_t *si) {
|
||||
aom_codec_err_t res;
|
||||
|
||||
if (!iface || !data || !data_sz || !si ||
|
||||
si->sz < sizeof(aom_codec_stream_info_t))
|
||||
res = AOM_CODEC_INVALID_PARAM;
|
||||
else {
|
||||
/* Set default/unknown values */
|
||||
si->w = 0;
|
||||
si->h = 0;
|
||||
|
||||
res = iface->dec.peek_si(data, data_sz, si);
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
aom_codec_err_t aom_codec_get_stream_info(aom_codec_ctx_t *ctx,
|
||||
aom_codec_stream_info_t *si) {
|
||||
aom_codec_err_t res;
|
||||
|
||||
if (!ctx || !si || si->sz < sizeof(aom_codec_stream_info_t))
|
||||
res = AOM_CODEC_INVALID_PARAM;
|
||||
else if (!ctx->iface || !ctx->priv)
|
||||
res = AOM_CODEC_ERROR;
|
||||
else {
|
||||
/* Set default/unknown values */
|
||||
si->w = 0;
|
||||
si->h = 0;
|
||||
|
||||
res = ctx->iface->dec.get_si(get_alg_priv(ctx), si);
|
||||
}
|
||||
|
||||
return SAVE_STATUS(ctx, res);
|
||||
}
|
||||
|
||||
aom_codec_err_t aom_codec_decode(aom_codec_ctx_t *ctx, const uint8_t *data,
|
||||
unsigned int data_sz, void *user_priv,
|
||||
long deadline) {
|
||||
aom_codec_err_t res;
|
||||
|
||||
/* Sanity checks */
|
||||
/* NULL data ptr allowed if data_sz is 0 too */
|
||||
if (!ctx || (!data && data_sz) || (data && !data_sz))
|
||||
res = AOM_CODEC_INVALID_PARAM;
|
||||
else if (!ctx->iface || !ctx->priv)
|
||||
res = AOM_CODEC_ERROR;
|
||||
else {
|
||||
res = ctx->iface->dec.decode(get_alg_priv(ctx), data, data_sz, user_priv,
|
||||
deadline);
|
||||
}
|
||||
|
||||
return SAVE_STATUS(ctx, res);
|
||||
}
|
||||
|
||||
aom_image_t *aom_codec_get_frame(aom_codec_ctx_t *ctx, aom_codec_iter_t *iter) {
|
||||
aom_image_t *img;
|
||||
|
||||
if (!ctx || !iter || !ctx->iface || !ctx->priv)
|
||||
img = NULL;
|
||||
else
|
||||
img = ctx->iface->dec.get_frame(get_alg_priv(ctx), iter);
|
||||
|
||||
return img;
|
||||
}
|
||||
|
||||
aom_codec_err_t aom_codec_register_put_frame_cb(aom_codec_ctx_t *ctx,
|
||||
aom_codec_put_frame_cb_fn_t cb,
|
||||
void *user_priv) {
|
||||
aom_codec_err_t res;
|
||||
|
||||
if (!ctx || !cb)
|
||||
res = AOM_CODEC_INVALID_PARAM;
|
||||
else if (!ctx->iface || !ctx->priv ||
|
||||
!(ctx->iface->caps & AOM_CODEC_CAP_PUT_FRAME))
|
||||
res = AOM_CODEC_ERROR;
|
||||
else {
|
||||
ctx->priv->dec.put_frame_cb.u.put_frame = cb;
|
||||
ctx->priv->dec.put_frame_cb.user_priv = user_priv;
|
||||
res = AOM_CODEC_OK;
|
||||
}
|
||||
|
||||
return SAVE_STATUS(ctx, res);
|
||||
}
|
||||
|
||||
aom_codec_err_t aom_codec_register_put_slice_cb(aom_codec_ctx_t *ctx,
|
||||
aom_codec_put_slice_cb_fn_t cb,
|
||||
void *user_priv) {
|
||||
aom_codec_err_t res;
|
||||
|
||||
if (!ctx || !cb)
|
||||
res = AOM_CODEC_INVALID_PARAM;
|
||||
else if (!ctx->iface || !ctx->priv ||
|
||||
!(ctx->iface->caps & AOM_CODEC_CAP_PUT_SLICE))
|
||||
res = AOM_CODEC_ERROR;
|
||||
else {
|
||||
ctx->priv->dec.put_slice_cb.u.put_slice = cb;
|
||||
ctx->priv->dec.put_slice_cb.user_priv = user_priv;
|
||||
res = AOM_CODEC_OK;
|
||||
}
|
||||
|
||||
return SAVE_STATUS(ctx, res);
|
||||
}
|
||||
|
||||
aom_codec_err_t aom_codec_set_frame_buffer_functions(
|
||||
aom_codec_ctx_t *ctx, aom_get_frame_buffer_cb_fn_t cb_get,
|
||||
aom_release_frame_buffer_cb_fn_t cb_release, void *cb_priv) {
|
||||
aom_codec_err_t res;
|
||||
|
||||
if (!ctx || !cb_get || !cb_release) {
|
||||
res = AOM_CODEC_INVALID_PARAM;
|
||||
} else if (!ctx->iface || !ctx->priv ||
|
||||
!(ctx->iface->caps & AOM_CODEC_CAP_EXTERNAL_FRAME_BUFFER)) {
|
||||
res = AOM_CODEC_ERROR;
|
||||
} else {
|
||||
res = ctx->iface->dec.set_fb_fn(get_alg_priv(ctx), cb_get, cb_release,
|
||||
cb_priv);
|
||||
}
|
||||
|
||||
return SAVE_STATUS(ctx, res);
|
||||
}
|
||||
@@ -1,240 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2016, Alliance for Open Media. All rights reserved
|
||||
*
|
||||
* This source code is subject to the terms of the BSD 2 Clause License and
|
||||
* the Alliance for Open Media Patent License 1.0. If the BSD 2 Clause License
|
||||
* was not distributed with this source code in the LICENSE file, you can
|
||||
* obtain it at www.aomedia.org/license/software. If the Alliance for Open
|
||||
* Media Patent License 1.0 was not distributed with this source code in the
|
||||
* PATENTS file, you can obtain it at www.aomedia.org/license/patent.
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "aom/aom_image.h"
|
||||
#include "aom/aom_integer.h"
|
||||
#include "aom_mem/aom_mem.h"
|
||||
|
||||
static aom_image_t *img_alloc_helper(aom_image_t *img, aom_img_fmt_t fmt,
|
||||
unsigned int d_w, unsigned int d_h,
|
||||
unsigned int buf_align,
|
||||
unsigned int stride_align,
|
||||
unsigned char *img_data) {
|
||||
unsigned int h, w, s, xcs, ycs, bps;
|
||||
unsigned int stride_in_bytes;
|
||||
int align;
|
||||
|
||||
/* Treat align==0 like align==1 */
|
||||
if (!buf_align) buf_align = 1;
|
||||
|
||||
/* Validate alignment (must be power of 2) */
|
||||
if (buf_align & (buf_align - 1)) goto fail;
|
||||
|
||||
/* Treat align==0 like align==1 */
|
||||
if (!stride_align) stride_align = 1;
|
||||
|
||||
/* Validate alignment (must be power of 2) */
|
||||
if (stride_align & (stride_align - 1)) goto fail;
|
||||
|
||||
/* Get sample size for this format */
|
||||
switch (fmt) {
|
||||
case AOM_IMG_FMT_RGB32:
|
||||
case AOM_IMG_FMT_RGB32_LE:
|
||||
case AOM_IMG_FMT_ARGB:
|
||||
case AOM_IMG_FMT_ARGB_LE: bps = 32; break;
|
||||
case AOM_IMG_FMT_RGB24:
|
||||
case AOM_IMG_FMT_BGR24: bps = 24; break;
|
||||
case AOM_IMG_FMT_RGB565:
|
||||
case AOM_IMG_FMT_RGB565_LE:
|
||||
case AOM_IMG_FMT_RGB555:
|
||||
case AOM_IMG_FMT_RGB555_LE:
|
||||
case AOM_IMG_FMT_UYVY:
|
||||
case AOM_IMG_FMT_YUY2:
|
||||
case AOM_IMG_FMT_YVYU: bps = 16; break;
|
||||
case AOM_IMG_FMT_I420:
|
||||
case AOM_IMG_FMT_YV12:
|
||||
case AOM_IMG_FMT_AOMI420:
|
||||
case AOM_IMG_FMT_AOMYV12: bps = 12; break;
|
||||
case AOM_IMG_FMT_I422:
|
||||
case AOM_IMG_FMT_I440: bps = 16; break;
|
||||
case AOM_IMG_FMT_I444: bps = 24; break;
|
||||
case AOM_IMG_FMT_I42016: bps = 24; break;
|
||||
case AOM_IMG_FMT_I42216:
|
||||
case AOM_IMG_FMT_I44016: bps = 32; break;
|
||||
case AOM_IMG_FMT_I44416: bps = 48; break;
|
||||
default: bps = 16; break;
|
||||
}
|
||||
|
||||
/* Get chroma shift values for this format */
|
||||
switch (fmt) {
|
||||
case AOM_IMG_FMT_I420:
|
||||
case AOM_IMG_FMT_YV12:
|
||||
case AOM_IMG_FMT_AOMI420:
|
||||
case AOM_IMG_FMT_AOMYV12:
|
||||
case AOM_IMG_FMT_I422:
|
||||
case AOM_IMG_FMT_I42016:
|
||||
case AOM_IMG_FMT_I42216: xcs = 1; break;
|
||||
default: xcs = 0; break;
|
||||
}
|
||||
|
||||
switch (fmt) {
|
||||
case AOM_IMG_FMT_I420:
|
||||
case AOM_IMG_FMT_I440:
|
||||
case AOM_IMG_FMT_YV12:
|
||||
case AOM_IMG_FMT_AOMI420:
|
||||
case AOM_IMG_FMT_AOMYV12:
|
||||
case AOM_IMG_FMT_I42016:
|
||||
case AOM_IMG_FMT_I44016: ycs = 1; break;
|
||||
default: ycs = 0; break;
|
||||
}
|
||||
|
||||
/* Calculate storage sizes given the chroma subsampling */
|
||||
align = (1 << xcs) - 1;
|
||||
w = (d_w + align) & ~align;
|
||||
align = (1 << ycs) - 1;
|
||||
h = (d_h + align) & ~align;
|
||||
s = (fmt & AOM_IMG_FMT_PLANAR) ? w : bps * w / 8;
|
||||
s = (s + stride_align - 1) & ~(stride_align - 1);
|
||||
stride_in_bytes = (fmt & AOM_IMG_FMT_HIGHBITDEPTH) ? s * 2 : s;
|
||||
|
||||
/* Allocate the new image */
|
||||
if (!img) {
|
||||
img = (aom_image_t *)calloc(1, sizeof(aom_image_t));
|
||||
|
||||
if (!img) goto fail;
|
||||
|
||||
img->self_allocd = 1;
|
||||
} else {
|
||||
memset(img, 0, sizeof(aom_image_t));
|
||||
}
|
||||
|
||||
img->img_data = img_data;
|
||||
|
||||
if (!img_data) {
|
||||
const uint64_t alloc_size = (fmt & AOM_IMG_FMT_PLANAR)
|
||||
? (uint64_t)h * s * bps / 8
|
||||
: (uint64_t)h * s;
|
||||
|
||||
if (alloc_size != (size_t)alloc_size) goto fail;
|
||||
|
||||
img->img_data = (uint8_t *)aom_memalign(buf_align, (size_t)alloc_size);
|
||||
img->img_data_owner = 1;
|
||||
}
|
||||
|
||||
if (!img->img_data) goto fail;
|
||||
|
||||
img->fmt = fmt;
|
||||
img->bit_depth = (fmt & AOM_IMG_FMT_HIGHBITDEPTH) ? 16 : 8;
|
||||
img->w = w;
|
||||
img->h = h;
|
||||
img->x_chroma_shift = xcs;
|
||||
img->y_chroma_shift = ycs;
|
||||
img->bps = bps;
|
||||
|
||||
/* Calculate strides */
|
||||
img->stride[AOM_PLANE_Y] = img->stride[AOM_PLANE_ALPHA] = stride_in_bytes;
|
||||
img->stride[AOM_PLANE_U] = img->stride[AOM_PLANE_V] = stride_in_bytes >> xcs;
|
||||
|
||||
/* Default viewport to entire image */
|
||||
if (!aom_img_set_rect(img, 0, 0, d_w, d_h)) return img;
|
||||
|
||||
fail:
|
||||
aom_img_free(img);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
aom_image_t *aom_img_alloc(aom_image_t *img, aom_img_fmt_t fmt,
|
||||
unsigned int d_w, unsigned int d_h,
|
||||
unsigned int align) {
|
||||
return img_alloc_helper(img, fmt, d_w, d_h, align, align, NULL);
|
||||
}
|
||||
|
||||
aom_image_t *aom_img_wrap(aom_image_t *img, aom_img_fmt_t fmt, unsigned int d_w,
|
||||
unsigned int d_h, unsigned int stride_align,
|
||||
unsigned char *img_data) {
|
||||
/* By setting buf_align = 1, we don't change buffer alignment in this
|
||||
* function. */
|
||||
return img_alloc_helper(img, fmt, d_w, d_h, 1, stride_align, img_data);
|
||||
}
|
||||
|
||||
int aom_img_set_rect(aom_image_t *img, unsigned int x, unsigned int y,
|
||||
unsigned int w, unsigned int h) {
|
||||
unsigned char *data;
|
||||
|
||||
if (x + w <= img->w && y + h <= img->h) {
|
||||
img->d_w = w;
|
||||
img->d_h = h;
|
||||
|
||||
/* Calculate plane pointers */
|
||||
if (!(img->fmt & AOM_IMG_FMT_PLANAR)) {
|
||||
img->planes[AOM_PLANE_PACKED] =
|
||||
img->img_data + x * img->bps / 8 + y * img->stride[AOM_PLANE_PACKED];
|
||||
} else {
|
||||
const int bytes_per_sample =
|
||||
(img->fmt & AOM_IMG_FMT_HIGHBITDEPTH) ? 2 : 1;
|
||||
data = img->img_data;
|
||||
|
||||
if (img->fmt & AOM_IMG_FMT_HAS_ALPHA) {
|
||||
img->planes[AOM_PLANE_ALPHA] =
|
||||
data + x * bytes_per_sample + y * img->stride[AOM_PLANE_ALPHA];
|
||||
data += img->h * img->stride[AOM_PLANE_ALPHA];
|
||||
}
|
||||
|
||||
img->planes[AOM_PLANE_Y] =
|
||||
data + x * bytes_per_sample + y * img->stride[AOM_PLANE_Y];
|
||||
data += img->h * img->stride[AOM_PLANE_Y];
|
||||
|
||||
if (!(img->fmt & AOM_IMG_FMT_UV_FLIP)) {
|
||||
img->planes[AOM_PLANE_U] =
|
||||
data + (x >> img->x_chroma_shift) * bytes_per_sample +
|
||||
(y >> img->y_chroma_shift) * img->stride[AOM_PLANE_U];
|
||||
data += (img->h >> img->y_chroma_shift) * img->stride[AOM_PLANE_U];
|
||||
img->planes[AOM_PLANE_V] =
|
||||
data + (x >> img->x_chroma_shift) * bytes_per_sample +
|
||||
(y >> img->y_chroma_shift) * img->stride[AOM_PLANE_V];
|
||||
} else {
|
||||
img->planes[AOM_PLANE_V] =
|
||||
data + (x >> img->x_chroma_shift) * bytes_per_sample +
|
||||
(y >> img->y_chroma_shift) * img->stride[AOM_PLANE_V];
|
||||
data += (img->h >> img->y_chroma_shift) * img->stride[AOM_PLANE_V];
|
||||
img->planes[AOM_PLANE_U] =
|
||||
data + (x >> img->x_chroma_shift) * bytes_per_sample +
|
||||
(y >> img->y_chroma_shift) * img->stride[AOM_PLANE_U];
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
void aom_img_flip(aom_image_t *img) {
|
||||
/* Note: In the calculation pointer adjustment calculation, we want the
|
||||
* rhs to be promoted to a signed type. Section 6.3.1.8 of the ISO C99
|
||||
* standard indicates that if the adjustment parameter is unsigned, the
|
||||
* stride parameter will be promoted to unsigned, causing errors when
|
||||
* the lhs is a larger type than the rhs.
|
||||
*/
|
||||
img->planes[AOM_PLANE_Y] += (signed)(img->d_h - 1) * img->stride[AOM_PLANE_Y];
|
||||
img->stride[AOM_PLANE_Y] = -img->stride[AOM_PLANE_Y];
|
||||
|
||||
img->planes[AOM_PLANE_U] += (signed)((img->d_h >> img->y_chroma_shift) - 1) *
|
||||
img->stride[AOM_PLANE_U];
|
||||
img->stride[AOM_PLANE_U] = -img->stride[AOM_PLANE_U];
|
||||
|
||||
img->planes[AOM_PLANE_V] += (signed)((img->d_h >> img->y_chroma_shift) - 1) *
|
||||
img->stride[AOM_PLANE_V];
|
||||
img->stride[AOM_PLANE_V] = -img->stride[AOM_PLANE_V];
|
||||
|
||||
img->planes[AOM_PLANE_ALPHA] +=
|
||||
(signed)(img->d_h - 1) * img->stride[AOM_PLANE_ALPHA];
|
||||
img->stride[AOM_PLANE_ALPHA] = -img->stride[AOM_PLANE_ALPHA];
|
||||
}
|
||||
|
||||
void aom_img_free(aom_image_t *img) {
|
||||
if (img) {
|
||||
if (img->img_data && img->img_data_owner) aom_free(img->img_data);
|
||||
|
||||
if (img->self_allocd) free(img);
|
||||
}
|
||||
}
|
||||
@@ -1,64 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2016, Alliance for Open Media. All rights reserved
|
||||
*
|
||||
* This source code is subject to the terms of the BSD 2 Clause License and
|
||||
* the Alliance for Open Media Patent License 1.0. If the BSD 2 Clause License
|
||||
* was not distributed with this source code in the LICENSE file, you can
|
||||
* obtain it at www.aomedia.org/license/software. If the Alliance for Open
|
||||
* Media Patent License 1.0 was not distributed with this source code in the
|
||||
* PATENTS file, you can obtain it at www.aomedia.org/license/patent.
|
||||
*/
|
||||
|
||||
#include <assert.h>
|
||||
#include "./aom_config.h"
|
||||
#include "aom/aom_integer.h"
|
||||
#include "aom_dsp/ans.h"
|
||||
#include "aom_dsp/prob.h"
|
||||
|
||||
static int find_largest(const aom_cdf_prob *const pdf_tab, int num_syms) {
|
||||
int largest_idx = -1;
|
||||
int largest_p = -1;
|
||||
int i;
|
||||
for (i = 0; i < num_syms; ++i) {
|
||||
int p = pdf_tab[i];
|
||||
if (p > largest_p) {
|
||||
largest_p = p;
|
||||
largest_idx = i;
|
||||
}
|
||||
}
|
||||
return largest_idx;
|
||||
}
|
||||
|
||||
void aom_rans_merge_prob8_pdf(aom_cdf_prob *const out_pdf,
|
||||
const AnsP8 node_prob,
|
||||
const aom_cdf_prob *const src_pdf, int in_syms) {
|
||||
int i;
|
||||
int adjustment = RANS_PRECISION;
|
||||
const int round_fact = ANS_P8_PRECISION >> 1;
|
||||
const AnsP8 p1 = ANS_P8_PRECISION - node_prob;
|
||||
const int out_syms = in_syms + 1;
|
||||
assert(src_pdf != out_pdf);
|
||||
|
||||
out_pdf[0] = node_prob << (RANS_PROB_BITS - ANS_P8_SHIFT);
|
||||
adjustment -= out_pdf[0];
|
||||
for (i = 0; i < in_syms; ++i) {
|
||||
int p = (p1 * src_pdf[i] + round_fact) >> ANS_P8_SHIFT;
|
||||
p = AOMMIN(p, (int)RANS_PRECISION - in_syms);
|
||||
p = AOMMAX(p, 1);
|
||||
out_pdf[i + 1] = p;
|
||||
adjustment -= p;
|
||||
}
|
||||
|
||||
// Adjust probabilities so they sum to the total probability
|
||||
if (adjustment > 0) {
|
||||
i = find_largest(out_pdf, out_syms);
|
||||
out_pdf[i] += adjustment;
|
||||
} else {
|
||||
while (adjustment < 0) {
|
||||
i = find_largest(out_pdf, out_syms);
|
||||
--out_pdf[i];
|
||||
assert(out_pdf[i] > 0);
|
||||
adjustment++;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,44 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2016, Alliance for Open Media. All rights reserved
|
||||
*
|
||||
* This source code is subject to the terms of the BSD 2 Clause License and
|
||||
* the Alliance for Open Media Patent License 1.0. If the BSD 2 Clause License
|
||||
* was not distributed with this source code in the LICENSE file, you can
|
||||
* obtain it at www.aomedia.org/license/software. If the Alliance for Open
|
||||
* Media Patent License 1.0 was not distributed with this source code in the
|
||||
* PATENTS file, you can obtain it at www.aomedia.org/license/patent.
|
||||
*/
|
||||
|
||||
#ifndef AOM_DSP_ANS_H_
|
||||
#define AOM_DSP_ANS_H_
|
||||
// Constants, types and utilities for Asymmetric Numeral Systems
|
||||
// http://arxiv.org/abs/1311.2540v2
|
||||
|
||||
#include <assert.h>
|
||||
#include "./aom_config.h"
|
||||
#include "aom/aom_integer.h"
|
||||
#include "aom_dsp/prob.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif // __cplusplus
|
||||
|
||||
typedef uint8_t AnsP8;
|
||||
#define ANS_P8_PRECISION 256u
|
||||
#define ANS_P8_SHIFT 8
|
||||
#define RANS_PROB_BITS 15
|
||||
#define RANS_PRECISION (1u << RANS_PROB_BITS)
|
||||
|
||||
// L_BASE % PRECISION must be 0. Increasing L_BASE beyond 2**15 will cause uabs
|
||||
// to overflow.
|
||||
#define L_BASE (RANS_PRECISION)
|
||||
#define IO_BASE 256
|
||||
// Range I = { L_BASE, L_BASE + 1, ..., L_BASE * IO_BASE - 1 }
|
||||
|
||||
void aom_rans_merge_prob8_pdf(aom_cdf_prob *const out_pdf,
|
||||
const AnsP8 node_prob,
|
||||
const aom_cdf_prob *const src_pdf, int in_syms);
|
||||
#ifdef __cplusplus
|
||||
} // extern "C"
|
||||
#endif // __cplusplus
|
||||
#endif // AOM_DSP_ANS_H_
|
||||
@@ -1,146 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2016, Alliance for Open Media. All rights reserved
|
||||
*
|
||||
* This source code is subject to the terms of the BSD 2 Clause License and
|
||||
* the Alliance for Open Media Patent License 1.0. If the BSD 2 Clause License
|
||||
* was not distributed with this source code in the LICENSE file, you can
|
||||
* obtain it at www.aomedia.org/license/software. If the Alliance for Open
|
||||
* Media Patent License 1.0 was not distributed with this source code in the
|
||||
* PATENTS file, you can obtain it at www.aomedia.org/license/patent.
|
||||
*/
|
||||
|
||||
#ifndef AOM_DSP_ANSREADER_H_
|
||||
#define AOM_DSP_ANSREADER_H_
|
||||
// A uABS and rANS decoder implementation of Asymmetric Numeral Systems
|
||||
// http://arxiv.org/abs/1311.2540v2
|
||||
|
||||
#include <assert.h>
|
||||
#include "./aom_config.h"
|
||||
#include "aom/aom_integer.h"
|
||||
#include "aom_dsp/prob.h"
|
||||
#include "aom_dsp/ans.h"
|
||||
#include "aom_ports/mem_ops.h"
|
||||
#if CONFIG_ACCOUNTING
|
||||
#include "av1/common/accounting.h"
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif // __cplusplus
|
||||
|
||||
struct AnsDecoder {
|
||||
const uint8_t *buf;
|
||||
int buf_offset;
|
||||
uint32_t state;
|
||||
#if CONFIG_ACCOUNTING
|
||||
Accounting *accounting;
|
||||
#endif
|
||||
};
|
||||
|
||||
static INLINE int uabs_read(struct AnsDecoder *ans, AnsP8 p0) {
|
||||
AnsP8 p = ANS_P8_PRECISION - p0;
|
||||
int s;
|
||||
unsigned xp, sp;
|
||||
unsigned state = ans->state;
|
||||
while (state < L_BASE && ans->buf_offset > 0) {
|
||||
state = state * IO_BASE + ans->buf[--ans->buf_offset];
|
||||
}
|
||||
sp = state * p;
|
||||
xp = sp / ANS_P8_PRECISION;
|
||||
s = (sp & 0xFF) >= p0;
|
||||
if (s)
|
||||
ans->state = xp;
|
||||
else
|
||||
ans->state = state - xp;
|
||||
return s;
|
||||
}
|
||||
|
||||
static INLINE int uabs_read_bit(struct AnsDecoder *ans) {
|
||||
int s;
|
||||
unsigned state = ans->state;
|
||||
while (state < L_BASE && ans->buf_offset > 0) {
|
||||
state = state * IO_BASE + ans->buf[--ans->buf_offset];
|
||||
}
|
||||
s = (int)(state & 1);
|
||||
ans->state = state >> 1;
|
||||
return s;
|
||||
}
|
||||
|
||||
struct rans_dec_sym {
|
||||
uint8_t val;
|
||||
aom_cdf_prob prob;
|
||||
aom_cdf_prob cum_prob; // not-inclusive
|
||||
};
|
||||
|
||||
static INLINE void fetch_sym(struct rans_dec_sym *out, const aom_cdf_prob *cdf,
|
||||
aom_cdf_prob rem) {
|
||||
int i;
|
||||
aom_cdf_prob cum_prob = 0, top_prob;
|
||||
// TODO(skal): if critical, could be a binary search.
|
||||
// Or, better, an O(1) alias-table.
|
||||
for (i = 0; rem >= (top_prob = cdf[i]); ++i) {
|
||||
cum_prob = top_prob;
|
||||
}
|
||||
out->val = i;
|
||||
out->prob = top_prob - cum_prob;
|
||||
out->cum_prob = cum_prob;
|
||||
}
|
||||
|
||||
static INLINE int rans_read(struct AnsDecoder *ans, const aom_cdf_prob *tab) {
|
||||
unsigned rem;
|
||||
unsigned quo;
|
||||
struct rans_dec_sym sym;
|
||||
while (ans->state < L_BASE && ans->buf_offset > 0) {
|
||||
ans->state = ans->state * IO_BASE + ans->buf[--ans->buf_offset];
|
||||
}
|
||||
quo = ans->state / RANS_PRECISION;
|
||||
rem = ans->state % RANS_PRECISION;
|
||||
fetch_sym(&sym, tab, rem);
|
||||
ans->state = quo * sym.prob + rem - sym.cum_prob;
|
||||
return sym.val;
|
||||
}
|
||||
|
||||
static INLINE int ans_read_init(struct AnsDecoder *const ans,
|
||||
const uint8_t *const buf, int offset) {
|
||||
unsigned x;
|
||||
if (offset < 1) return 1;
|
||||
ans->buf = buf;
|
||||
x = buf[offset - 1] >> 6;
|
||||
if (x == 0) {
|
||||
ans->buf_offset = offset - 1;
|
||||
ans->state = buf[offset - 1] & 0x3F;
|
||||
} else if (x == 1) {
|
||||
if (offset < 2) return 1;
|
||||
ans->buf_offset = offset - 2;
|
||||
ans->state = mem_get_le16(buf + offset - 2) & 0x3FFF;
|
||||
} else if (x == 2) {
|
||||
if (offset < 3) return 1;
|
||||
ans->buf_offset = offset - 3;
|
||||
ans->state = mem_get_le24(buf + offset - 3) & 0x3FFFFF;
|
||||
} else if ((buf[offset - 1] & 0xE0) == 0xE0) {
|
||||
if (offset < 4) return 1;
|
||||
ans->buf_offset = offset - 4;
|
||||
ans->state = mem_get_le32(buf + offset - 4) & 0x1FFFFFFF;
|
||||
} else {
|
||||
// 110xxxxx implies this byte is a superframe marker
|
||||
return 1;
|
||||
}
|
||||
#if CONFIG_ACCOUNTING
|
||||
ans->accounting = NULL;
|
||||
#endif
|
||||
ans->state += L_BASE;
|
||||
if (ans->state >= L_BASE * IO_BASE) return 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static INLINE int ans_read_end(struct AnsDecoder *const ans) {
|
||||
return ans->state == L_BASE;
|
||||
}
|
||||
|
||||
static INLINE int ans_reader_has_error(const struct AnsDecoder *const ans) {
|
||||
return ans->state < L_BASE && ans->buf_offset == 0;
|
||||
}
|
||||
#ifdef __cplusplus
|
||||
} // extern "C"
|
||||
#endif // __cplusplus
|
||||
#endif // AOM_DSP_ANSREADER_H_
|
||||
@@ -1,120 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2016, Alliance for Open Media. All rights reserved
|
||||
*
|
||||
* This source code is subject to the terms of the BSD 2 Clause License and
|
||||
* the Alliance for Open Media Patent License 1.0. If the BSD 2 Clause License
|
||||
* was not distributed with this source code in the LICENSE file, you can
|
||||
* obtain it at www.aomedia.org/license/software. If the Alliance for Open
|
||||
* Media Patent License 1.0 was not distributed with this source code in the
|
||||
* PATENTS file, you can obtain it at www.aomedia.org/license/patent.
|
||||
*/
|
||||
|
||||
#ifndef AOM_DSP_ANSWRITER_H_
|
||||
#define AOM_DSP_ANSWRITER_H_
|
||||
// A uABS and rANS encoder implementation of Asymmetric Numeral Systems
|
||||
// http://arxiv.org/abs/1311.2540v2
|
||||
|
||||
#include <assert.h>
|
||||
#include "./aom_config.h"
|
||||
#include "aom/aom_integer.h"
|
||||
#include "aom_dsp/ans.h"
|
||||
#include "aom_dsp/prob.h"
|
||||
#include "aom_ports/mem_ops.h"
|
||||
#include "av1/common/odintrin.h"
|
||||
|
||||
#if RANS_PRECISION <= OD_DIVU_DMAX
|
||||
#define ANS_DIVREM(quotient, remainder, dividend, divisor) \
|
||||
do { \
|
||||
quotient = OD_DIVU_SMALL((dividend), (divisor)); \
|
||||
remainder = (dividend) - (quotient) * (divisor); \
|
||||
} while (0)
|
||||
#else
|
||||
#define ANS_DIVREM(quotient, remainder, dividend, divisor) \
|
||||
do { \
|
||||
quotient = (dividend) / (divisor); \
|
||||
remainder = (dividend) % (divisor); \
|
||||
} while (0)
|
||||
#endif
|
||||
|
||||
#define ANS_DIV8(dividend, divisor) OD_DIVU_SMALL((dividend), (divisor))
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif // __cplusplus
|
||||
|
||||
struct AnsCoder {
|
||||
uint8_t *buf;
|
||||
int buf_offset;
|
||||
uint32_t state;
|
||||
};
|
||||
|
||||
static INLINE void ans_write_init(struct AnsCoder *const ans,
|
||||
uint8_t *const buf) {
|
||||
ans->buf = buf;
|
||||
ans->buf_offset = 0;
|
||||
ans->state = L_BASE;
|
||||
}
|
||||
|
||||
static INLINE int ans_write_end(struct AnsCoder *const ans) {
|
||||
uint32_t state;
|
||||
assert(ans->state >= L_BASE);
|
||||
assert(ans->state < L_BASE * IO_BASE);
|
||||
state = ans->state - L_BASE;
|
||||
if (state < (1 << 6)) {
|
||||
ans->buf[ans->buf_offset] = (0x00 << 6) + state;
|
||||
return ans->buf_offset + 1;
|
||||
} else if (state < (1 << 14)) {
|
||||
mem_put_le16(ans->buf + ans->buf_offset, (0x01 << 14) + state);
|
||||
return ans->buf_offset + 2;
|
||||
} else if (state < (1 << 22)) {
|
||||
mem_put_le24(ans->buf + ans->buf_offset, (0x02 << 22) + state);
|
||||
return ans->buf_offset + 3;
|
||||
} else if (state < (1 << 29)) {
|
||||
mem_put_le32(ans->buf + ans->buf_offset, (0x07 << 29) + state);
|
||||
return ans->buf_offset + 4;
|
||||
} else {
|
||||
assert(0 && "State is too large to be serialized");
|
||||
return ans->buf_offset;
|
||||
}
|
||||
}
|
||||
|
||||
// uABS with normalization
|
||||
static INLINE void uabs_write(struct AnsCoder *ans, int val, AnsP8 p0) {
|
||||
AnsP8 p = ANS_P8_PRECISION - p0;
|
||||
const unsigned l_s = val ? p : p0;
|
||||
while (ans->state >= L_BASE / ANS_P8_PRECISION * IO_BASE * l_s) {
|
||||
ans->buf[ans->buf_offset++] = ans->state % IO_BASE;
|
||||
ans->state /= IO_BASE;
|
||||
}
|
||||
if (!val)
|
||||
ans->state = ANS_DIV8(ans->state * ANS_P8_PRECISION, p0);
|
||||
else
|
||||
ans->state = ANS_DIV8((ans->state + 1) * ANS_P8_PRECISION + p - 1, p) - 1;
|
||||
}
|
||||
|
||||
struct rans_sym {
|
||||
aom_cdf_prob prob;
|
||||
aom_cdf_prob cum_prob; // not-inclusive
|
||||
};
|
||||
|
||||
// rANS with normalization
|
||||
// sym->prob takes the place of l_s from the paper
|
||||
// ANS_P10_PRECISION is m
|
||||
static INLINE void rans_write(struct AnsCoder *ans,
|
||||
const struct rans_sym *const sym) {
|
||||
const aom_cdf_prob p = sym->prob;
|
||||
unsigned quot, rem;
|
||||
while (ans->state >= L_BASE / RANS_PRECISION * IO_BASE * p) {
|
||||
ans->buf[ans->buf_offset++] = ans->state % IO_BASE;
|
||||
ans->state /= IO_BASE;
|
||||
}
|
||||
ANS_DIVREM(quot, rem, ans->state, p);
|
||||
ans->state = quot * RANS_PRECISION + rem + sym->cum_prob;
|
||||
}
|
||||
|
||||
#undef ANS_DIV8
|
||||
#undef ANS_DIVREM
|
||||
#ifdef __cplusplus
|
||||
} // extern "C"
|
||||
#endif // __cplusplus
|
||||
#endif // AOM_DSP_ANSWRITER_H_
|
||||
@@ -1,57 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2016, Alliance for Open Media. All rights reserved
|
||||
*
|
||||
* This source code is subject to the terms of the BSD 2 Clause License and
|
||||
* the Alliance for Open Media Patent License 1.0. If the BSD 2 Clause License
|
||||
* was not distributed with this source code in the LICENSE file, you can
|
||||
* obtain it at www.aomedia.org/license/software. If the Alliance for Open
|
||||
* Media Patent License 1.0 was not distributed with this source code in the
|
||||
* PATENTS file, you can obtain it at www.aomedia.org/license/patent.
|
||||
*/
|
||||
#ifndef AOM_DSP_AOM_CONVOLVE_H_
|
||||
#define AOM_DSP_AOM_CONVOLVE_H_
|
||||
|
||||
#include "./aom_config.h"
|
||||
#include "aom/aom_integer.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
// Note: Fixed size intermediate buffers, place limits on parameters
|
||||
// of some functions. 2d filtering proceeds in 2 steps:
|
||||
// (1) Interpolate horizontally into an intermediate buffer, temp.
|
||||
// (2) Interpolate temp vertically to derive the sub-pixel result.
|
||||
// Deriving the maximum number of rows in the temp buffer (135):
|
||||
// --Smallest scaling factor is x1/2 ==> y_step_q4 = 32 (Normative).
|
||||
// --Largest block size is 64x64 pixels.
|
||||
// --64 rows in the downscaled frame span a distance of (64 - 1) * 32 in the
|
||||
// original frame (in 1/16th pixel units).
|
||||
// --Must round-up because block may be located at sub-pixel position.
|
||||
// --Require an additional SUBPEL_TAPS rows for the 8-tap filter tails.
|
||||
// --((64 - 1) * 32 + 15) >> 4 + 8 = 135.
|
||||
#if CONFIG_AV1 && CONFIG_EXT_PARTITION
|
||||
#define MAX_EXT_SIZE 263
|
||||
#else
|
||||
#define MAX_EXT_SIZE 135
|
||||
#endif // CONFIG_AV1 && CONFIG_EXT_PARTITION
|
||||
|
||||
typedef void (*convolve_fn_t)(const uint8_t *src, ptrdiff_t src_stride,
|
||||
uint8_t *dst, ptrdiff_t dst_stride,
|
||||
const int16_t *filter_x, int x_step_q4,
|
||||
const int16_t *filter_y, int y_step_q4, int w,
|
||||
int h);
|
||||
|
||||
#if CONFIG_AOM_HIGHBITDEPTH
|
||||
typedef void (*highbd_convolve_fn_t)(const uint8_t *src, ptrdiff_t src_stride,
|
||||
uint8_t *dst, ptrdiff_t dst_stride,
|
||||
const int16_t *filter_x, int x_step_q4,
|
||||
const int16_t *filter_y, int y_step_q4,
|
||||
int w, int h, int bd);
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
} // extern "C"
|
||||
#endif
|
||||
|
||||
#endif // AOM_DSP_AOM_CONVOLVE_H_
|
||||
@@ -1,426 +0,0 @@
|
||||
##
|
||||
## Copyright (c) 2016, Alliance for Open Media. All rights reserved
|
||||
##
|
||||
## This source code is subject to the terms of the BSD 2 Clause License and
|
||||
## the Alliance for Open Media Patent License 1.0. If the BSD 2 Clause License
|
||||
## was not distributed with this source code in the LICENSE file, you can
|
||||
## obtain it at www.aomedia.org/license/software. If the Alliance for Open
|
||||
## Media Patent License 1.0 was not distributed with this source code in the
|
||||
## PATENTS file, you can obtain it at www.aomedia.org/license/patent.
|
||||
##
|
||||
|
||||
|
||||
DSP_SRCS-yes += aom_dsp.mk
|
||||
DSP_SRCS-yes += aom_dsp_common.h
|
||||
|
||||
DSP_SRCS-$(HAVE_MSA) += mips/macros_msa.h
|
||||
|
||||
DSP_SRCS-$(ARCH_X86)$(ARCH_X86_64) += x86/synonyms.h
|
||||
|
||||
# bit reader
|
||||
DSP_SRCS-yes += prob.h
|
||||
DSP_SRCS-yes += prob.c
|
||||
DSP_SRCS-$(CONFIG_ANS) += ans.h
|
||||
DSP_SRCS-$(CONFIG_ANS) += ans.c
|
||||
|
||||
ifeq ($(CONFIG_ENCODERS),yes)
|
||||
DSP_SRCS-$(CONFIG_ANS) += answriter.h
|
||||
DSP_SRCS-yes += bitwriter.h
|
||||
DSP_SRCS-yes += dkboolwriter.h
|
||||
DSP_SRCS-yes += dkboolwriter.c
|
||||
DSP_SRCS-yes += bitwriter_buffer.c
|
||||
DSP_SRCS-yes += bitwriter_buffer.h
|
||||
DSP_SRCS-yes += psnr.c
|
||||
DSP_SRCS-yes += psnr.h
|
||||
DSP_SRCS-$(CONFIG_ANS) += buf_ans.h
|
||||
DSP_SRCS-$(CONFIG_ANS) += buf_ans.c
|
||||
DSP_SRCS-$(CONFIG_INTERNAL_STATS) += ssim.c
|
||||
DSP_SRCS-$(CONFIG_INTERNAL_STATS) += ssim.h
|
||||
DSP_SRCS-$(CONFIG_INTERNAL_STATS) += psnrhvs.c
|
||||
DSP_SRCS-$(CONFIG_INTERNAL_STATS) += fastssim.c
|
||||
endif
|
||||
|
||||
ifeq ($(CONFIG_DECODERS),yes)
|
||||
DSP_SRCS-$(CONFIG_ANS) += ansreader.h
|
||||
DSP_SRCS-yes += bitreader.h
|
||||
DSP_SRCS-yes += dkboolreader.h
|
||||
DSP_SRCS-yes += dkboolreader.c
|
||||
DSP_SRCS-yes += bitreader_buffer.c
|
||||
DSP_SRCS-yes += bitreader_buffer.h
|
||||
endif
|
||||
|
||||
# intra predictions
|
||||
DSP_SRCS-yes += intrapred.c
|
||||
|
||||
ifeq ($(CONFIG_DAALA_EC),yes)
|
||||
DSP_SRCS-yes += entenc.c
|
||||
DSP_SRCS-yes += entenc.h
|
||||
DSP_SRCS-yes += entdec.c
|
||||
DSP_SRCS-yes += entdec.h
|
||||
DSP_SRCS-yes += entcode.c
|
||||
DSP_SRCS-yes += entcode.h
|
||||
DSP_SRCS-yes += daalaboolreader.c
|
||||
DSP_SRCS-yes += daalaboolreader.h
|
||||
DSP_SRCS-yes += daalaboolwriter.c
|
||||
DSP_SRCS-yes += daalaboolwriter.h
|
||||
endif
|
||||
|
||||
DSP_SRCS-$(HAVE_SSE) += x86/intrapred_sse2.asm
|
||||
DSP_SRCS-$(HAVE_SSE2) += x86/intrapred_sse2.asm
|
||||
DSP_SRCS-$(HAVE_SSSE3) += x86/intrapred_ssse3.asm
|
||||
DSP_SRCS-$(HAVE_SSSE3) += x86/aom_subpixel_8t_ssse3.asm
|
||||
|
||||
ifeq ($(CONFIG_AOM_HIGHBITDEPTH),yes)
|
||||
DSP_SRCS-$(HAVE_SSE) += x86/highbd_intrapred_sse2.asm
|
||||
DSP_SRCS-$(HAVE_SSE2) += x86/highbd_intrapred_sse2.asm
|
||||
endif # CONFIG_AOM_HIGHBITDEPTH
|
||||
|
||||
DSP_SRCS-$(HAVE_NEON_ASM) += arm/intrapred_neon_asm$(ASM)
|
||||
DSP_SRCS-$(HAVE_NEON) += arm/intrapred_neon.c
|
||||
DSP_SRCS-$(HAVE_MSA) += mips/intrapred_msa.c
|
||||
DSP_SRCS-$(HAVE_DSPR2) += mips/intrapred4_dspr2.c
|
||||
DSP_SRCS-$(HAVE_DSPR2) += mips/intrapred8_dspr2.c
|
||||
DSP_SRCS-$(HAVE_DSPR2) += mips/intrapred16_dspr2.c
|
||||
|
||||
DSP_SRCS-$(HAVE_DSPR2) += mips/common_dspr2.h
|
||||
DSP_SRCS-$(HAVE_DSPR2) += mips/common_dspr2.c
|
||||
|
||||
# inter predictions
|
||||
DSP_SRCS-yes += blend.h
|
||||
DSP_SRCS-yes += blend_a64_mask.c
|
||||
DSP_SRCS-yes += blend_a64_hmask.c
|
||||
DSP_SRCS-yes += blend_a64_vmask.c
|
||||
DSP_SRCS-$(HAVE_SSE4_1) += x86/blend_sse4.h
|
||||
DSP_SRCS-$(HAVE_SSE4_1) += x86/blend_a64_mask_sse4.c
|
||||
DSP_SRCS-$(HAVE_SSE4_1) += x86/blend_a64_hmask_sse4.c
|
||||
DSP_SRCS-$(HAVE_SSE4_1) += x86/blend_a64_vmask_sse4.c
|
||||
|
||||
# interpolation filters
|
||||
DSP_SRCS-yes += aom_convolve.c
|
||||
DSP_SRCS-yes += aom_convolve.h
|
||||
DSP_SRCS-yes += aom_filter.h
|
||||
|
||||
DSP_SRCS-$(ARCH_X86)$(ARCH_X86_64) += x86/convolve.h
|
||||
DSP_SRCS-$(ARCH_X86)$(ARCH_X86_64) += x86/aom_asm_stubs.c
|
||||
DSP_SRCS-$(HAVE_SSE2) += x86/aom_subpixel_8t_sse2.asm
|
||||
DSP_SRCS-$(HAVE_SSE2) += x86/aom_subpixel_bilinear_sse2.asm
|
||||
DSP_SRCS-$(HAVE_SSSE3) += x86/aom_subpixel_8t_ssse3.asm
|
||||
DSP_SRCS-$(HAVE_SSSE3) += x86/aom_subpixel_bilinear_ssse3.asm
|
||||
DSP_SRCS-$(HAVE_AVX2) += x86/aom_subpixel_8t_intrin_avx2.c
|
||||
DSP_SRCS-$(HAVE_SSSE3) += x86/aom_subpixel_8t_intrin_ssse3.c
|
||||
ifeq ($(CONFIG_AOM_HIGHBITDEPTH),yes)
|
||||
DSP_SRCS-$(HAVE_SSE2) += x86/aom_high_subpixel_8t_sse2.asm
|
||||
DSP_SRCS-$(HAVE_SSE2) += x86/aom_high_subpixel_bilinear_sse2.asm
|
||||
endif
|
||||
DSP_SRCS-$(HAVE_SSE2) += x86/aom_convolve_copy_sse2.asm
|
||||
|
||||
ifeq ($(HAVE_NEON_ASM),yes)
|
||||
DSP_SRCS-yes += arm/aom_convolve_copy_neon_asm$(ASM)
|
||||
DSP_SRCS-yes += arm/aom_convolve8_avg_neon_asm$(ASM)
|
||||
DSP_SRCS-yes += arm/aom_convolve8_neon_asm$(ASM)
|
||||
DSP_SRCS-yes += arm/aom_convolve_avg_neon_asm$(ASM)
|
||||
DSP_SRCS-yes += arm/aom_convolve_neon.c
|
||||
else
|
||||
ifeq ($(HAVE_NEON),yes)
|
||||
DSP_SRCS-yes += arm/aom_convolve_copy_neon.c
|
||||
DSP_SRCS-yes += arm/aom_convolve8_avg_neon.c
|
||||
DSP_SRCS-yes += arm/aom_convolve8_neon.c
|
||||
DSP_SRCS-yes += arm/aom_convolve_avg_neon.c
|
||||
DSP_SRCS-yes += arm/aom_convolve_neon.c
|
||||
endif # HAVE_NEON
|
||||
endif # HAVE_NEON_ASM
|
||||
|
||||
# common (msa)
|
||||
DSP_SRCS-$(HAVE_MSA) += mips/aom_convolve8_avg_horiz_msa.c
|
||||
DSP_SRCS-$(HAVE_MSA) += mips/aom_convolve8_avg_msa.c
|
||||
DSP_SRCS-$(HAVE_MSA) += mips/aom_convolve8_avg_vert_msa.c
|
||||
DSP_SRCS-$(HAVE_MSA) += mips/aom_convolve8_horiz_msa.c
|
||||
DSP_SRCS-$(HAVE_MSA) += mips/aom_convolve8_msa.c
|
||||
DSP_SRCS-$(HAVE_MSA) += mips/aom_convolve8_vert_msa.c
|
||||
DSP_SRCS-$(HAVE_MSA) += mips/aom_convolve_avg_msa.c
|
||||
DSP_SRCS-$(HAVE_MSA) += mips/aom_convolve_copy_msa.c
|
||||
DSP_SRCS-$(HAVE_MSA) += mips/aom_convolve_msa.h
|
||||
|
||||
# common (dspr2)
|
||||
DSP_SRCS-$(HAVE_DSPR2) += mips/convolve_common_dspr2.h
|
||||
DSP_SRCS-$(HAVE_DSPR2) += mips/convolve2_avg_dspr2.c
|
||||
DSP_SRCS-$(HAVE_DSPR2) += mips/convolve2_avg_horiz_dspr2.c
|
||||
DSP_SRCS-$(HAVE_DSPR2) += mips/convolve2_dspr2.c
|
||||
DSP_SRCS-$(HAVE_DSPR2) += mips/convolve2_horiz_dspr2.c
|
||||
DSP_SRCS-$(HAVE_DSPR2) += mips/convolve2_vert_dspr2.c
|
||||
DSP_SRCS-$(HAVE_DSPR2) += mips/convolve8_avg_dspr2.c
|
||||
DSP_SRCS-$(HAVE_DSPR2) += mips/convolve8_avg_horiz_dspr2.c
|
||||
DSP_SRCS-$(HAVE_DSPR2) += mips/convolve8_dspr2.c
|
||||
DSP_SRCS-$(HAVE_DSPR2) += mips/convolve8_horiz_dspr2.c
|
||||
DSP_SRCS-$(HAVE_DSPR2) += mips/convolve8_vert_dspr2.c
|
||||
|
||||
# loop filters
|
||||
DSP_SRCS-yes += loopfilter.c
|
||||
|
||||
DSP_SRCS-$(ARCH_X86)$(ARCH_X86_64) += x86/loopfilter_sse2.c
|
||||
DSP_SRCS-$(HAVE_AVX2) += x86/loopfilter_avx2.c
|
||||
|
||||
DSP_SRCS-$(HAVE_NEON) += arm/loopfilter_neon.c
|
||||
ifeq ($(HAVE_NEON_ASM),yes)
|
||||
DSP_SRCS-yes += arm/loopfilter_mb_neon$(ASM)
|
||||
DSP_SRCS-yes += arm/loopfilter_16_neon$(ASM)
|
||||
DSP_SRCS-yes += arm/loopfilter_8_neon$(ASM)
|
||||
DSP_SRCS-yes += arm/loopfilter_4_neon$(ASM)
|
||||
else
|
||||
ifeq ($(HAVE_NEON),yes)
|
||||
DSP_SRCS-yes += arm/loopfilter_16_neon.c
|
||||
DSP_SRCS-yes += arm/loopfilter_8_neon.c
|
||||
DSP_SRCS-yes += arm/loopfilter_4_neon.c
|
||||
endif # HAVE_NEON
|
||||
endif # HAVE_NEON_ASM
|
||||
|
||||
DSP_SRCS-$(HAVE_MSA) += mips/loopfilter_msa.h
|
||||
DSP_SRCS-$(HAVE_MSA) += mips/loopfilter_16_msa.c
|
||||
DSP_SRCS-$(HAVE_MSA) += mips/loopfilter_8_msa.c
|
||||
DSP_SRCS-$(HAVE_MSA) += mips/loopfilter_4_msa.c
|
||||
DSP_SRCS-$(HAVE_DSPR2) += mips/loopfilter_filters_dspr2.h
|
||||
DSP_SRCS-$(HAVE_DSPR2) += mips/loopfilter_filters_dspr2.c
|
||||
DSP_SRCS-$(HAVE_DSPR2) += mips/loopfilter_macros_dspr2.h
|
||||
DSP_SRCS-$(HAVE_DSPR2) += mips/loopfilter_masks_dspr2.h
|
||||
DSP_SRCS-$(HAVE_DSPR2) += mips/loopfilter_mb_dspr2.c
|
||||
DSP_SRCS-$(HAVE_DSPR2) += mips/loopfilter_mb_horiz_dspr2.c
|
||||
DSP_SRCS-$(HAVE_DSPR2) += mips/loopfilter_mb_vert_dspr2.c
|
||||
|
||||
ifeq ($(CONFIG_AOM_HIGHBITDEPTH),yes)
|
||||
DSP_SRCS-$(HAVE_SSE2) += x86/highbd_loopfilter_sse2.c
|
||||
endif # CONFIG_AOM_HIGHBITDEPTH
|
||||
|
||||
DSP_SRCS-yes += txfm_common.h
|
||||
DSP_SRCS-yes += x86/txfm_common_intrin.h
|
||||
DSP_SRCS-$(HAVE_SSE2) += x86/txfm_common_sse2.h
|
||||
DSP_SRCS-$(HAVE_MSA) += mips/txfm_macros_msa.h
|
||||
# forward transform
|
||||
ifeq ($(CONFIG_AV1),yes)
|
||||
DSP_SRCS-yes += fwd_txfm.c
|
||||
DSP_SRCS-yes += fwd_txfm.h
|
||||
DSP_SRCS-$(HAVE_SSE2) += x86/fwd_txfm_sse2.h
|
||||
DSP_SRCS-$(HAVE_SSE2) += x86/fwd_txfm_sse2.c
|
||||
DSP_SRCS-$(HAVE_SSE2) += x86/fwd_dct32_8cols_sse2.c
|
||||
DSP_SRCS-$(HAVE_SSE2) += x86/fwd_txfm_impl_sse2.h
|
||||
DSP_SRCS-$(HAVE_SSE2) += x86/fwd_dct32x32_impl_sse2.h
|
||||
ifeq ($(ARCH_X86_64),yes)
|
||||
DSP_SRCS-$(HAVE_SSSE3) += x86/fwd_txfm_ssse3_x86_64.asm
|
||||
endif
|
||||
DSP_SRCS-$(HAVE_AVX2) += x86/fwd_txfm_avx2.h
|
||||
DSP_SRCS-$(HAVE_AVX2) += x86/fwd_txfm_avx2.c
|
||||
DSP_SRCS-$(HAVE_AVX2) += x86/txfm_common_avx2.h
|
||||
DSP_SRCS-$(HAVE_AVX2) += x86/fwd_dct32x32_impl_avx2.h
|
||||
DSP_SRCS-$(HAVE_NEON) += arm/fwd_txfm_neon.c
|
||||
DSP_SRCS-$(HAVE_MSA) += mips/fwd_txfm_msa.h
|
||||
DSP_SRCS-$(HAVE_MSA) += mips/fwd_txfm_msa.c
|
||||
DSP_SRCS-$(HAVE_MSA) += mips/fwd_dct32x32_msa.c
|
||||
endif # CONFIG_AV1_ENCODER
|
||||
|
||||
ifeq ($(CONFIG_PVQ),yes)
|
||||
DSP_SRCS-yes += fwd_txfm.c
|
||||
DSP_SRCS-yes += fwd_txfm.h
|
||||
DSP_SRCS-$(HAVE_SSE2) += x86/fwd_txfm_sse2.h
|
||||
DSP_SRCS-$(HAVE_SSE2) += x86/fwd_txfm_sse2.c
|
||||
DSP_SRCS-$(HAVE_SSE2) += x86/fwd_txfm_impl_sse2.h
|
||||
DSP_SRCS-$(HAVE_SSE2) += x86/fwd_dct32x32_impl_sse2.h
|
||||
ifeq ($(ARCH_X86_64),yes)
|
||||
DSP_SRCS-$(HAVE_SSSE3) += x86/fwd_txfm_ssse3_x86_64.asm
|
||||
endif
|
||||
DSP_SRCS-$(HAVE_AVX2) += x86/fwd_txfm_avx2.c
|
||||
DSP_SRCS-$(HAVE_AVX2) += x86/fwd_dct32x32_impl_avx2.h
|
||||
DSP_SRCS-$(HAVE_NEON) += arm/fwd_txfm_neon.c
|
||||
DSP_SRCS-$(HAVE_MSA) += mips/fwd_txfm_msa.h
|
||||
DSP_SRCS-$(HAVE_MSA) += mips/fwd_txfm_msa.c
|
||||
DSP_SRCS-$(HAVE_MSA) += mips/fwd_dct32x32_msa.c
|
||||
endif # CONFIG_PVQ
|
||||
|
||||
# inverse transform
|
||||
ifeq ($(CONFIG_AV1), yes)
|
||||
DSP_SRCS-yes += inv_txfm.h
|
||||
DSP_SRCS-yes += inv_txfm.c
|
||||
DSP_SRCS-$(HAVE_SSE2) += x86/inv_txfm_sse2.h
|
||||
DSP_SRCS-$(HAVE_SSE2) += x86/inv_txfm_sse2.c
|
||||
DSP_SRCS-$(HAVE_SSE2) += x86/inv_wht_sse2.asm
|
||||
ifeq ($(ARCH_X86_64),yes)
|
||||
DSP_SRCS-$(HAVE_SSSE3) += x86/inv_txfm_ssse3_x86_64.asm
|
||||
endif # ARCH_X86_64
|
||||
|
||||
ifeq ($(HAVE_NEON_ASM),yes)
|
||||
DSP_SRCS-yes += arm/save_reg_neon$(ASM)
|
||||
DSP_SRCS-yes += arm/idct4x4_1_add_neon$(ASM)
|
||||
DSP_SRCS-yes += arm/idct4x4_add_neon$(ASM)
|
||||
DSP_SRCS-yes += arm/idct8x8_1_add_neon$(ASM)
|
||||
DSP_SRCS-yes += arm/idct8x8_add_neon$(ASM)
|
||||
DSP_SRCS-yes += arm/idct16x16_1_add_neon$(ASM)
|
||||
DSP_SRCS-yes += arm/idct16x16_add_neon$(ASM)
|
||||
DSP_SRCS-yes += arm/idct32x32_1_add_neon$(ASM)
|
||||
DSP_SRCS-yes += arm/idct32x32_add_neon$(ASM)
|
||||
else
|
||||
ifeq ($(HAVE_NEON),yes)
|
||||
DSP_SRCS-yes += arm/idct4x4_1_add_neon.c
|
||||
DSP_SRCS-yes += arm/idct4x4_add_neon.c
|
||||
DSP_SRCS-yes += arm/idct8x8_1_add_neon.c
|
||||
DSP_SRCS-yes += arm/idct8x8_add_neon.c
|
||||
DSP_SRCS-yes += arm/idct16x16_1_add_neon.c
|
||||
DSP_SRCS-yes += arm/idct16x16_add_neon.c
|
||||
DSP_SRCS-yes += arm/idct32x32_1_add_neon.c
|
||||
DSP_SRCS-yes += arm/idct32x32_add_neon.c
|
||||
endif # HAVE_NEON
|
||||
endif # HAVE_NEON_ASM
|
||||
DSP_SRCS-$(HAVE_NEON) += arm/idct16x16_neon.c
|
||||
|
||||
DSP_SRCS-$(HAVE_MSA) += mips/inv_txfm_msa.h
|
||||
DSP_SRCS-$(HAVE_MSA) += mips/idct4x4_msa.c
|
||||
DSP_SRCS-$(HAVE_MSA) += mips/idct8x8_msa.c
|
||||
DSP_SRCS-$(HAVE_MSA) += mips/idct16x16_msa.c
|
||||
DSP_SRCS-$(HAVE_MSA) += mips/idct32x32_msa.c
|
||||
|
||||
ifneq ($(CONFIG_AOM_HIGHBITDEPTH),yes)
|
||||
DSP_SRCS-$(HAVE_DSPR2) += mips/inv_txfm_dspr2.h
|
||||
DSP_SRCS-$(HAVE_DSPR2) += mips/itrans4_dspr2.c
|
||||
DSP_SRCS-$(HAVE_DSPR2) += mips/itrans8_dspr2.c
|
||||
DSP_SRCS-$(HAVE_DSPR2) += mips/itrans16_dspr2.c
|
||||
DSP_SRCS-$(HAVE_DSPR2) += mips/itrans32_dspr2.c
|
||||
DSP_SRCS-$(HAVE_DSPR2) += mips/itrans32_cols_dspr2.c
|
||||
endif # CONFIG_AOM_HIGHBITDEPTH
|
||||
endif # CONFIG_AV1
|
||||
|
||||
# quantization
|
||||
ifneq ($(filter yes,$(CONFIG_AV1_ENCODER)),)
|
||||
DSP_SRCS-yes += quantize.c
|
||||
DSP_SRCS-yes += quantize.h
|
||||
|
||||
DSP_SRCS-$(HAVE_SSE2) += x86/quantize_sse2.c
|
||||
ifeq ($(CONFIG_AOM_HIGHBITDEPTH),yes)
|
||||
DSP_SRCS-$(HAVE_SSE2) += x86/highbd_quantize_intrin_sse2.c
|
||||
endif
|
||||
ifeq ($(ARCH_X86_64),yes)
|
||||
DSP_SRCS-$(HAVE_SSSE3) += x86/quantize_ssse3_x86_64.asm
|
||||
DSP_SRCS-$(HAVE_AVX) += x86/quantize_avx_x86_64.asm
|
||||
endif
|
||||
|
||||
# avg
|
||||
DSP_SRCS-yes += avg.c
|
||||
DSP_SRCS-$(HAVE_SSE2) += x86/avg_intrin_sse2.c
|
||||
DSP_SRCS-$(HAVE_NEON) += arm/avg_neon.c
|
||||
DSP_SRCS-$(HAVE_MSA) += mips/avg_msa.c
|
||||
DSP_SRCS-$(HAVE_NEON) += arm/hadamard_neon.c
|
||||
ifeq ($(ARCH_X86_64),yes)
|
||||
DSP_SRCS-$(HAVE_SSSE3) += x86/avg_ssse3_x86_64.asm
|
||||
endif
|
||||
|
||||
# high bit depth subtract
|
||||
ifeq ($(CONFIG_AOM_HIGHBITDEPTH),yes)
|
||||
DSP_SRCS-$(HAVE_SSE2) += x86/highbd_subtract_sse2.c
|
||||
endif
|
||||
|
||||
endif # CONFIG_AV1_ENCODER
|
||||
|
||||
ifeq ($(CONFIG_AV1_ENCODER),yes)
|
||||
DSP_SRCS-yes += sum_squares.c
|
||||
|
||||
DSP_SRCS-$(HAVE_SSE2) += x86/sum_squares_sse2.c
|
||||
endif # CONFIG_AV1_ENCODER
|
||||
|
||||
ifeq ($(CONFIG_ENCODERS),yes)
|
||||
DSP_SRCS-yes += sad.c
|
||||
DSP_SRCS-yes += subtract.c
|
||||
|
||||
DSP_SRCS-$(HAVE_MEDIA) += arm/sad_media$(ASM)
|
||||
DSP_SRCS-$(HAVE_NEON) += arm/sad4d_neon.c
|
||||
DSP_SRCS-$(HAVE_NEON) += arm/sad_neon.c
|
||||
DSP_SRCS-$(HAVE_NEON) += arm/subtract_neon.c
|
||||
|
||||
DSP_SRCS-$(HAVE_MSA) += mips/sad_msa.c
|
||||
DSP_SRCS-$(HAVE_MSA) += mips/subtract_msa.c
|
||||
|
||||
DSP_SRCS-$(HAVE_SSE3) += x86/sad_sse3.asm
|
||||
DSP_SRCS-$(HAVE_SSSE3) += x86/sad_ssse3.asm
|
||||
DSP_SRCS-$(HAVE_SSE4_1) += x86/sad_sse4.asm
|
||||
DSP_SRCS-$(HAVE_AVX2) += x86/sad4d_avx2.c
|
||||
DSP_SRCS-$(HAVE_AVX2) += x86/sad_avx2.c
|
||||
|
||||
ifeq ($(CONFIG_AV1_ENCODER),yes)
|
||||
ifeq ($(CONFIG_EXT_INTER),yes)
|
||||
DSP_SRCS-$(HAVE_SSSE3) += x86/masked_sad_intrin_ssse3.c
|
||||
DSP_SRCS-$(HAVE_SSSE3) += x86/masked_variance_intrin_ssse3.c
|
||||
endif #CONFIG_EXT_INTER
|
||||
ifeq ($(CONFIG_MOTION_VAR),yes)
|
||||
DSP_SRCS-$(HAVE_SSE4_1) += x86/obmc_sad_sse4.c
|
||||
DSP_SRCS-$(HAVE_SSE4_1) += x86/obmc_variance_sse4.c
|
||||
endif #CONFIG_MOTION_VAR
|
||||
endif #CONFIG_AV1_ENCODER
|
||||
|
||||
DSP_SRCS-$(HAVE_SSE) += x86/sad4d_sse2.asm
|
||||
DSP_SRCS-$(HAVE_SSE) += x86/sad_sse2.asm
|
||||
DSP_SRCS-$(HAVE_SSE2) += x86/sad4d_sse2.asm
|
||||
DSP_SRCS-$(HAVE_SSE2) += x86/sad_sse2.asm
|
||||
DSP_SRCS-$(HAVE_SSE2) += x86/subtract_sse2.asm
|
||||
|
||||
ifeq ($(CONFIG_AOM_HIGHBITDEPTH),yes)
|
||||
DSP_SRCS-$(HAVE_SSE2) += x86/highbd_sad4d_sse2.asm
|
||||
DSP_SRCS-$(HAVE_SSE2) += x86/highbd_sad_sse2.asm
|
||||
endif # CONFIG_AOM_HIGHBITDEPTH
|
||||
|
||||
endif # CONFIG_ENCODERS
|
||||
|
||||
ifneq ($(filter yes,$(CONFIG_ENCODERS)),)
|
||||
DSP_SRCS-yes += variance.c
|
||||
DSP_SRCS-yes += variance.h
|
||||
|
||||
DSP_SRCS-$(HAVE_MEDIA) += arm/bilinear_filter_media$(ASM)
|
||||
DSP_SRCS-$(HAVE_MEDIA) += arm/subpel_variance_media.c
|
||||
DSP_SRCS-$(HAVE_MEDIA) += arm/variance_halfpixvar16x16_h_media$(ASM)
|
||||
DSP_SRCS-$(HAVE_MEDIA) += arm/variance_halfpixvar16x16_hv_media$(ASM)
|
||||
DSP_SRCS-$(HAVE_MEDIA) += arm/variance_halfpixvar16x16_v_media$(ASM)
|
||||
DSP_SRCS-$(HAVE_MEDIA) += arm/variance_media$(ASM)
|
||||
DSP_SRCS-$(HAVE_NEON) += arm/subpel_variance_neon.c
|
||||
DSP_SRCS-$(HAVE_NEON) += arm/variance_neon.c
|
||||
|
||||
DSP_SRCS-$(HAVE_MSA) += mips/variance_msa.c
|
||||
DSP_SRCS-$(HAVE_MSA) += mips/sub_pixel_variance_msa.c
|
||||
|
||||
DSP_SRCS-$(HAVE_SSE) += x86/variance_sse2.c
|
||||
DSP_SRCS-$(HAVE_SSE2) += x86/variance_sse2.c # Contains SSE2 and SSSE3
|
||||
DSP_SRCS-$(HAVE_SSE2) += x86/halfpix_variance_sse2.c
|
||||
DSP_SRCS-$(HAVE_SSE2) += x86/halfpix_variance_impl_sse2.asm
|
||||
DSP_SRCS-$(HAVE_AVX2) += x86/variance_avx2.c
|
||||
DSP_SRCS-$(HAVE_AVX2) += x86/variance_impl_avx2.c
|
||||
|
||||
ifeq ($(ARCH_X86_64),yes)
|
||||
DSP_SRCS-$(HAVE_SSE2) += x86/ssim_opt_x86_64.asm
|
||||
endif # ARCH_X86_64
|
||||
|
||||
DSP_SRCS-$(HAVE_SSE) += x86/subpel_variance_sse2.asm
|
||||
DSP_SRCS-$(HAVE_SSE2) += x86/subpel_variance_sse2.asm # Contains SSE2 and SSSE3
|
||||
|
||||
ifeq ($(CONFIG_AOM_HIGHBITDEPTH),yes)
|
||||
DSP_SRCS-$(HAVE_SSE2) += x86/highbd_variance_sse2.c
|
||||
DSP_SRCS-$(HAVE_SSE4_1) += x86/highbd_variance_sse4.c
|
||||
DSP_SRCS-$(HAVE_SSE2) += x86/highbd_variance_impl_sse2.asm
|
||||
DSP_SRCS-$(HAVE_SSE2) += x86/highbd_subpel_variance_impl_sse2.asm
|
||||
endif # CONFIG_AOM_HIGHBITDEPTH
|
||||
endif # CONFIG_ENCODERS
|
||||
|
||||
DSP_SRCS-no += $(DSP_SRCS_REMOVE-yes)
|
||||
|
||||
DSP_SRCS-yes += aom_dsp_rtcd.c
|
||||
DSP_SRCS-yes += aom_dsp_rtcd_defs.pl
|
||||
|
||||
DSP_SRCS-yes += aom_simd.c
|
||||
DSP_SRCS-yes += aom_simd.h
|
||||
DSP_SRCS-yes += aom_simd_inline.h
|
||||
DSP_SRCS-yes += simd/v64_intrinsics.h
|
||||
DSP_SRCS-yes += simd/v64_intrinsics_c.h
|
||||
DSP_SRCS-yes += simd/v128_intrinsics.h
|
||||
DSP_SRCS-yes += simd/v128_intrinsics_c.h
|
||||
DSP_SRCS-yes += simd/v256_intrinsics.h
|
||||
DSP_SRCS-yes += simd/v256_intrinsics_c.h
|
||||
DSP_SRCS-$(HAVE_SSE2) += simd/v64_intrinsics_x86.h
|
||||
DSP_SRCS-$(HAVE_SSE2) += simd/v128_intrinsics_x86.h
|
||||
DSP_SRCS-$(HAVE_SSE2) += simd/v256_intrinsics_x86.h
|
||||
DSP_SRCS-$(HAVE_NEON) += simd/v64_intrinsics_arm.h
|
||||
DSP_SRCS-$(HAVE_NEON) += simd/v128_intrinsics_arm.h
|
||||
DSP_SRCS-$(HAVE_NEON) += simd/v256_intrinsics_arm.h
|
||||
|
||||
$(eval $(call rtcd_h_template,aom_dsp_rtcd,aom_dsp/aom_dsp_rtcd_defs.pl))
|
||||
@@ -1,102 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2016, Alliance for Open Media. All rights reserved
|
||||
*
|
||||
* This source code is subject to the terms of the BSD 2 Clause License and
|
||||
* the Alliance for Open Media Patent License 1.0. If the BSD 2 Clause License
|
||||
* was not distributed with this source code in the LICENSE file, you can
|
||||
* obtain it at www.aomedia.org/license/software. If the Alliance for Open
|
||||
* Media Patent License 1.0 was not distributed with this source code in the
|
||||
* PATENTS file, you can obtain it at www.aomedia.org/license/patent.
|
||||
*/
|
||||
|
||||
#ifndef AOM_DSP_AOM_DSP_COMMON_H_
|
||||
#define AOM_DSP_AOM_DSP_COMMON_H_
|
||||
|
||||
#include "./aom_config.h"
|
||||
#include "aom/aom_integer.h"
|
||||
#include "aom_ports/mem.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#ifndef MAX_SB_SIZE
|
||||
#if CONFIG_AV1 && CONFIG_EXT_PARTITION
|
||||
#define MAX_SB_SIZE 128
|
||||
#else
|
||||
#define MAX_SB_SIZE 64
|
||||
#endif // CONFIG_AV1 && CONFIG_EXT_PARTITION
|
||||
#endif // ndef MAX_SB_SIZE
|
||||
|
||||
#define AOMMIN(x, y) (((x) < (y)) ? (x) : (y))
|
||||
#define AOMMAX(x, y) (((x) > (y)) ? (x) : (y))
|
||||
|
||||
#define IMPLIES(a, b) (!(a) || (b)) // Logical 'a implies b' (or 'a -> b')
|
||||
|
||||
#define IS_POWER_OF_TWO(x) (((x) & ((x)-1)) == 0)
|
||||
|
||||
// These can be used to give a hint about branch outcomes.
|
||||
// This can have an effect, even if your target processor has a
|
||||
// good branch predictor, as these hints can affect basic block
|
||||
// ordering by the compiler.
|
||||
#ifdef __GNUC__
|
||||
#define LIKELY(v) __builtin_expect(v, 1)
|
||||
#define UNLIKELY(v) __builtin_expect(v, 0)
|
||||
#else
|
||||
#define LIKELY(v) (v)
|
||||
#define UNLIKELY(v) (v)
|
||||
#endif
|
||||
|
||||
#define AOM_SWAP(type, a, b) \
|
||||
do { \
|
||||
type c = (b); \
|
||||
b = a; \
|
||||
a = c; \
|
||||
} while (0)
|
||||
|
||||
#if CONFIG_AOM_QM
|
||||
typedef uint16_t qm_val_t;
|
||||
#define AOM_QM_BITS 6
|
||||
#endif
|
||||
#if CONFIG_AOM_HIGHBITDEPTH
|
||||
// Note:
|
||||
// tran_low_t is the datatype used for final transform coefficients.
|
||||
// tran_high_t is the datatype used for intermediate transform stages.
|
||||
typedef int64_t tran_high_t;
|
||||
typedef int32_t tran_low_t;
|
||||
#else
|
||||
// Note:
|
||||
// tran_low_t is the datatype used for final transform coefficients.
|
||||
// tran_high_t is the datatype used for intermediate transform stages.
|
||||
typedef int32_t tran_high_t;
|
||||
typedef int16_t tran_low_t;
|
||||
#endif // CONFIG_AOM_HIGHBITDEPTH
|
||||
|
||||
static INLINE uint8_t clip_pixel(int val) {
|
||||
return (val > 255) ? 255 : (val < 0) ? 0 : val;
|
||||
}
|
||||
|
||||
static INLINE int clamp(int value, int low, int high) {
|
||||
return value < low ? low : (value > high ? high : value);
|
||||
}
|
||||
|
||||
static INLINE double fclamp(double value, double low, double high) {
|
||||
return value < low ? low : (value > high ? high : value);
|
||||
}
|
||||
|
||||
#if CONFIG_AOM_HIGHBITDEPTH
|
||||
static INLINE uint16_t clip_pixel_highbd(int val, int bd) {
|
||||
switch (bd) {
|
||||
case 8:
|
||||
default: return (uint16_t)clamp(val, 0, 255);
|
||||
case 10: return (uint16_t)clamp(val, 0, 1023);
|
||||
case 12: return (uint16_t)clamp(val, 0, 4095);
|
||||
}
|
||||
}
|
||||
#endif // CONFIG_AOM_HIGHBITDEPTH
|
||||
|
||||
#ifdef __cplusplus
|
||||
} // extern "C"
|
||||
#endif
|
||||
|
||||
#endif // AOM_DSP_AOM_DSP_COMMON_H_
|
||||
@@ -1,16 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2016, Alliance for Open Media. All rights reserved
|
||||
*
|
||||
* This source code is subject to the terms of the BSD 2 Clause License and
|
||||
* the Alliance for Open Media Patent License 1.0. If the BSD 2 Clause License
|
||||
* was not distributed with this source code in the LICENSE file, you can
|
||||
* obtain it at www.aomedia.org/license/software. If the Alliance for Open
|
||||
* Media Patent License 1.0 was not distributed with this source code in the
|
||||
* PATENTS file, you can obtain it at www.aomedia.org/license/patent.
|
||||
*/
|
||||
#include "./aom_config.h"
|
||||
#define RTCD_C
|
||||
#include "./aom_dsp_rtcd.h"
|
||||
#include "aom_ports/aom_once.h"
|
||||
|
||||
void aom_dsp_rtcd() { once(setup_rtcd_internal); }
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,43 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2016, Alliance for Open Media. All rights reserved
|
||||
*
|
||||
* This source code is subject to the terms of the BSD 2 Clause License and
|
||||
* the Alliance for Open Media Patent License 1.0. If the BSD 2 Clause License
|
||||
* was not distributed with this source code in the LICENSE file, you can
|
||||
* obtain it at www.aomedia.org/license/software. If the Alliance for Open
|
||||
* Media Patent License 1.0 was not distributed with this source code in the
|
||||
* PATENTS file, you can obtain it at www.aomedia.org/license/patent.
|
||||
*/
|
||||
|
||||
#ifndef AOM_DSP_AOM_FILTER_H_
|
||||
#define AOM_DSP_AOM_FILTER_H_
|
||||
|
||||
#include "aom/aom_integer.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#define FILTER_BITS 7
|
||||
|
||||
#define SUBPEL_BITS 4
|
||||
#define SUBPEL_MASK ((1 << SUBPEL_BITS) - 1)
|
||||
#define SUBPEL_SHIFTS (1 << SUBPEL_BITS)
|
||||
#define SUBPEL_TAPS 8
|
||||
|
||||
typedef int16_t InterpKernel[SUBPEL_TAPS];
|
||||
|
||||
#define BIL_SUBPEL_BITS 3
|
||||
#define BIL_SUBPEL_SHIFTS (1 << BIL_SUBPEL_BITS)
|
||||
|
||||
// 2 tap bilinear filters
|
||||
static const uint8_t bilinear_filters_2t[BIL_SUBPEL_SHIFTS][2] = {
|
||||
{ 128, 0 }, { 112, 16 }, { 96, 32 }, { 80, 48 },
|
||||
{ 64, 64 }, { 48, 80 }, { 32, 96 }, { 16, 112 },
|
||||
};
|
||||
|
||||
#ifdef __cplusplus
|
||||
} // extern "C"
|
||||
#endif
|
||||
|
||||
#endif // AOM_DSP_AOM_FILTER_H_
|
||||
@@ -1,13 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2016, Alliance for Open Media. All rights reserved
|
||||
*
|
||||
* This source code is subject to the terms of the BSD 2 Clause License and
|
||||
* the Alliance for Open Media Patent License 1.0. If the BSD 2 Clause License
|
||||
* was not distributed with this source code in the LICENSE file, you can
|
||||
* obtain it at www.aomedia.org/license/software. If the Alliance for Open
|
||||
* Media Patent License 1.0 was not distributed with this source code in the
|
||||
* PATENTS file, you can obtain it at www.aomedia.org/license/patent.
|
||||
*/
|
||||
|
||||
// Set to 1 to add some sanity checks in the fallback C code
|
||||
const int simd_check = 1;
|
||||
@@ -1,32 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2016, Alliance for Open Media. All rights reserved
|
||||
*
|
||||
* This source code is subject to the terms of the BSD 2 Clause License and
|
||||
* the Alliance for Open Media Patent License 1.0. If the BSD 2 Clause License
|
||||
* was not distributed with this source code in the LICENSE file, you can
|
||||
* obtain it at www.aomedia.org/license/software. If the Alliance for Open
|
||||
* Media Patent License 1.0 was not distributed with this source code in the
|
||||
* PATENTS file, you can obtain it at www.aomedia.org/license/patent.
|
||||
*/
|
||||
|
||||
#ifndef AOM_DSP_AOM_AOM_SIMD_H_
|
||||
#define AOM_DSP_AOM_AOM_SIMD_H_
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#if defined(_WIN32)
|
||||
#include <intrin.h>
|
||||
#endif
|
||||
|
||||
#include "./aom_config.h"
|
||||
#include "./aom_simd_inline.h"
|
||||
|
||||
#if HAVE_NEON
|
||||
#include "simd/v256_intrinsics_arm.h"
|
||||
#elif HAVE_SSE2
|
||||
#include "simd/v256_intrinsics_x86.h"
|
||||
#else
|
||||
#include "simd/v256_intrinsics.h"
|
||||
#endif
|
||||
|
||||
#endif // AOM_DSP_AOM_AOM_SIMD_H_
|
||||
@@ -1,21 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2016, Alliance for Open Media. All rights reserved
|
||||
*
|
||||
* This source code is subject to the terms of the BSD 2 Clause License and
|
||||
* the Alliance for Open Media Patent License 1.0. If the BSD 2 Clause License
|
||||
* was not distributed with this source code in the LICENSE file, you can
|
||||
* obtain it at www.aomedia.org/license/software. If the Alliance for Open
|
||||
* Media Patent License 1.0 was not distributed with this source code in the
|
||||
* PATENTS file, you can obtain it at www.aomedia.org/license/patent.
|
||||
*/
|
||||
|
||||
#ifndef AOM_DSP_AOM_SIMD_INLINE_H_
|
||||
#define AOM_DSP_AOM_SIMD_INLINE_H_
|
||||
|
||||
#include "aom/aom_integer.h"
|
||||
|
||||
#ifndef SIMD_INLINE
|
||||
#define SIMD_INLINE static AOM_FORCE_INLINE
|
||||
#endif
|
||||
|
||||
#endif // AOM_DSP_AOM_SIMD_INLINE_H_
|
||||
@@ -1,364 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2016, Alliance for Open Media. All rights reserved
|
||||
*
|
||||
* This source code is subject to the terms of the BSD 2 Clause License and
|
||||
* the Alliance for Open Media Patent License 1.0. If the BSD 2 Clause License
|
||||
* was not distributed with this source code in the LICENSE file, you can
|
||||
* obtain it at www.aomedia.org/license/software. If the Alliance for Open
|
||||
* Media Patent License 1.0 was not distributed with this source code in the
|
||||
* PATENTS file, you can obtain it at www.aomedia.org/license/patent.
|
||||
*/
|
||||
|
||||
#include <arm_neon.h>
|
||||
#include <assert.h>
|
||||
|
||||
#include "./aom_config.h"
|
||||
#include "./aom_dsp_rtcd.h"
|
||||
#include "aom/aom_integer.h"
|
||||
#include "aom_ports/mem.h"
|
||||
|
||||
static INLINE int32x4_t MULTIPLY_BY_Q0(int16x4_t dsrc0, int16x4_t dsrc1,
|
||||
int16x4_t dsrc2, int16x4_t dsrc3,
|
||||
int16x4_t dsrc4, int16x4_t dsrc5,
|
||||
int16x4_t dsrc6, int16x4_t dsrc7,
|
||||
int16x8_t q0s16) {
|
||||
int32x4_t qdst;
|
||||
int16x4_t d0s16, d1s16;
|
||||
|
||||
d0s16 = vget_low_s16(q0s16);
|
||||
d1s16 = vget_high_s16(q0s16);
|
||||
|
||||
qdst = vmull_lane_s16(dsrc0, d0s16, 0);
|
||||
qdst = vmlal_lane_s16(qdst, dsrc1, d0s16, 1);
|
||||
qdst = vmlal_lane_s16(qdst, dsrc2, d0s16, 2);
|
||||
qdst = vmlal_lane_s16(qdst, dsrc3, d0s16, 3);
|
||||
qdst = vmlal_lane_s16(qdst, dsrc4, d1s16, 0);
|
||||
qdst = vmlal_lane_s16(qdst, dsrc5, d1s16, 1);
|
||||
qdst = vmlal_lane_s16(qdst, dsrc6, d1s16, 2);
|
||||
qdst = vmlal_lane_s16(qdst, dsrc7, d1s16, 3);
|
||||
return qdst;
|
||||
}
|
||||
|
||||
void aom_convolve8_avg_horiz_neon(const uint8_t *src, ptrdiff_t src_stride,
|
||||
uint8_t *dst, ptrdiff_t dst_stride,
|
||||
const int16_t *filter_x, int x_step_q4,
|
||||
const int16_t *filter_y, // unused
|
||||
int y_step_q4, // unused
|
||||
int w, int h) {
|
||||
int width;
|
||||
const uint8_t *s;
|
||||
uint8_t *d;
|
||||
uint8x8_t d2u8, d3u8, d24u8, d25u8, d26u8, d27u8, d28u8, d29u8;
|
||||
uint32x2_t d2u32, d3u32, d6u32, d7u32, d28u32, d29u32, d30u32, d31u32;
|
||||
uint8x16_t q1u8, q3u8, q12u8, q13u8, q14u8, q15u8;
|
||||
int16x4_t d16s16, d17s16, d18s16, d19s16, d20s16, d22s16, d23s16;
|
||||
int16x4_t d24s16, d25s16, d26s16, d27s16;
|
||||
uint16x4_t d2u16, d3u16, d4u16, d5u16, d16u16, d17u16, d18u16, d19u16;
|
||||
int16x8_t q0s16;
|
||||
uint16x8_t q1u16, q2u16, q8u16, q9u16, q10u16, q11u16, q12u16, q13u16;
|
||||
int32x4_t q1s32, q2s32, q14s32, q15s32;
|
||||
uint16x8x2_t q0x2u16;
|
||||
uint8x8x2_t d0x2u8, d1x2u8;
|
||||
uint32x2x2_t d0x2u32;
|
||||
uint16x4x2_t d0x2u16, d1x2u16;
|
||||
uint32x4x2_t q0x2u32;
|
||||
|
||||
assert(x_step_q4 == 16);
|
||||
|
||||
(void)x_step_q4;
|
||||
(void)y_step_q4;
|
||||
(void)filter_y;
|
||||
|
||||
q0s16 = vld1q_s16(filter_x);
|
||||
|
||||
src -= 3; // adjust for taps
|
||||
for (; h > 0; h -= 4) { // loop_horiz_v
|
||||
s = src;
|
||||
d24u8 = vld1_u8(s);
|
||||
s += src_stride;
|
||||
d25u8 = vld1_u8(s);
|
||||
s += src_stride;
|
||||
d26u8 = vld1_u8(s);
|
||||
s += src_stride;
|
||||
d27u8 = vld1_u8(s);
|
||||
|
||||
q12u8 = vcombine_u8(d24u8, d25u8);
|
||||
q13u8 = vcombine_u8(d26u8, d27u8);
|
||||
|
||||
q0x2u16 =
|
||||
vtrnq_u16(vreinterpretq_u16_u8(q12u8), vreinterpretq_u16_u8(q13u8));
|
||||
d24u8 = vreinterpret_u8_u16(vget_low_u16(q0x2u16.val[0]));
|
||||
d25u8 = vreinterpret_u8_u16(vget_high_u16(q0x2u16.val[0]));
|
||||
d26u8 = vreinterpret_u8_u16(vget_low_u16(q0x2u16.val[1]));
|
||||
d27u8 = vreinterpret_u8_u16(vget_high_u16(q0x2u16.val[1]));
|
||||
d0x2u8 = vtrn_u8(d24u8, d25u8);
|
||||
d1x2u8 = vtrn_u8(d26u8, d27u8);
|
||||
|
||||
__builtin_prefetch(src + src_stride * 4);
|
||||
__builtin_prefetch(src + src_stride * 5);
|
||||
|
||||
q8u16 = vmovl_u8(d0x2u8.val[0]);
|
||||
q9u16 = vmovl_u8(d0x2u8.val[1]);
|
||||
q10u16 = vmovl_u8(d1x2u8.val[0]);
|
||||
q11u16 = vmovl_u8(d1x2u8.val[1]);
|
||||
|
||||
src += 7;
|
||||
d16u16 = vget_low_u16(q8u16);
|
||||
d17u16 = vget_high_u16(q8u16);
|
||||
d18u16 = vget_low_u16(q9u16);
|
||||
d19u16 = vget_high_u16(q9u16);
|
||||
q8u16 = vcombine_u16(d16u16, d18u16); // vswp 17 18
|
||||
q9u16 = vcombine_u16(d17u16, d19u16);
|
||||
|
||||
d20s16 = vreinterpret_s16_u16(vget_low_u16(q10u16));
|
||||
d23s16 = vreinterpret_s16_u16(vget_high_u16(q10u16)); // vmov 23 21
|
||||
for (width = w; width > 0; width -= 4, src += 4, dst += 4) { // loop_horiz
|
||||
s = src;
|
||||
d28u32 = vld1_dup_u32((const uint32_t *)s);
|
||||
s += src_stride;
|
||||
d29u32 = vld1_dup_u32((const uint32_t *)s);
|
||||
s += src_stride;
|
||||
d31u32 = vld1_dup_u32((const uint32_t *)s);
|
||||
s += src_stride;
|
||||
d30u32 = vld1_dup_u32((const uint32_t *)s);
|
||||
|
||||
__builtin_prefetch(src + 64);
|
||||
|
||||
d0x2u16 =
|
||||
vtrn_u16(vreinterpret_u16_u32(d28u32), vreinterpret_u16_u32(d31u32));
|
||||
d1x2u16 =
|
||||
vtrn_u16(vreinterpret_u16_u32(d29u32), vreinterpret_u16_u32(d30u32));
|
||||
d0x2u8 = vtrn_u8(vreinterpret_u8_u16(d0x2u16.val[0]), // d28
|
||||
vreinterpret_u8_u16(d1x2u16.val[0])); // d29
|
||||
d1x2u8 = vtrn_u8(vreinterpret_u8_u16(d0x2u16.val[1]), // d31
|
||||
vreinterpret_u8_u16(d1x2u16.val[1])); // d30
|
||||
|
||||
__builtin_prefetch(src + 64 + src_stride);
|
||||
|
||||
q14u8 = vcombine_u8(d0x2u8.val[0], d0x2u8.val[1]);
|
||||
q15u8 = vcombine_u8(d1x2u8.val[1], d1x2u8.val[0]);
|
||||
q0x2u32 =
|
||||
vtrnq_u32(vreinterpretq_u32_u8(q14u8), vreinterpretq_u32_u8(q15u8));
|
||||
|
||||
d28u8 = vreinterpret_u8_u32(vget_low_u32(q0x2u32.val[0]));
|
||||
d29u8 = vreinterpret_u8_u32(vget_high_u32(q0x2u32.val[0]));
|
||||
q12u16 = vmovl_u8(d28u8);
|
||||
q13u16 = vmovl_u8(d29u8);
|
||||
|
||||
__builtin_prefetch(src + 64 + src_stride * 2);
|
||||
|
||||
d = dst;
|
||||
d6u32 = vld1_lane_u32((const uint32_t *)d, d6u32, 0);
|
||||
d += dst_stride;
|
||||
d7u32 = vld1_lane_u32((const uint32_t *)d, d7u32, 0);
|
||||
d += dst_stride;
|
||||
d6u32 = vld1_lane_u32((const uint32_t *)d, d6u32, 1);
|
||||
d += dst_stride;
|
||||
d7u32 = vld1_lane_u32((const uint32_t *)d, d7u32, 1);
|
||||
|
||||
d16s16 = vreinterpret_s16_u16(vget_low_u16(q8u16));
|
||||
d17s16 = vreinterpret_s16_u16(vget_high_u16(q8u16));
|
||||
d18s16 = vreinterpret_s16_u16(vget_low_u16(q9u16));
|
||||
d19s16 = vreinterpret_s16_u16(vget_high_u16(q9u16));
|
||||
d22s16 = vreinterpret_s16_u16(vget_low_u16(q11u16));
|
||||
d24s16 = vreinterpret_s16_u16(vget_low_u16(q12u16));
|
||||
d25s16 = vreinterpret_s16_u16(vget_high_u16(q12u16));
|
||||
d26s16 = vreinterpret_s16_u16(vget_low_u16(q13u16));
|
||||
d27s16 = vreinterpret_s16_u16(vget_high_u16(q13u16));
|
||||
|
||||
q1s32 = MULTIPLY_BY_Q0(d16s16, d17s16, d20s16, d22s16, d18s16, d19s16,
|
||||
d23s16, d24s16, q0s16);
|
||||
q2s32 = MULTIPLY_BY_Q0(d17s16, d20s16, d22s16, d18s16, d19s16, d23s16,
|
||||
d24s16, d26s16, q0s16);
|
||||
q14s32 = MULTIPLY_BY_Q0(d20s16, d22s16, d18s16, d19s16, d23s16, d24s16,
|
||||
d26s16, d27s16, q0s16);
|
||||
q15s32 = MULTIPLY_BY_Q0(d22s16, d18s16, d19s16, d23s16, d24s16, d26s16,
|
||||
d27s16, d25s16, q0s16);
|
||||
|
||||
__builtin_prefetch(src + 64 + src_stride * 3);
|
||||
|
||||
d2u16 = vqrshrun_n_s32(q1s32, 7);
|
||||
d3u16 = vqrshrun_n_s32(q2s32, 7);
|
||||
d4u16 = vqrshrun_n_s32(q14s32, 7);
|
||||
d5u16 = vqrshrun_n_s32(q15s32, 7);
|
||||
|
||||
q1u16 = vcombine_u16(d2u16, d3u16);
|
||||
q2u16 = vcombine_u16(d4u16, d5u16);
|
||||
|
||||
d2u8 = vqmovn_u16(q1u16);
|
||||
d3u8 = vqmovn_u16(q2u16);
|
||||
|
||||
d0x2u16 = vtrn_u16(vreinterpret_u16_u8(d2u8), vreinterpret_u16_u8(d3u8));
|
||||
d0x2u32 = vtrn_u32(vreinterpret_u32_u16(d0x2u16.val[0]),
|
||||
vreinterpret_u32_u16(d0x2u16.val[1]));
|
||||
d0x2u8 = vtrn_u8(vreinterpret_u8_u32(d0x2u32.val[0]),
|
||||
vreinterpret_u8_u32(d0x2u32.val[1]));
|
||||
|
||||
q1u8 = vcombine_u8(d0x2u8.val[0], d0x2u8.val[1]);
|
||||
q3u8 = vreinterpretq_u8_u32(vcombine_u32(d6u32, d7u32));
|
||||
|
||||
q1u8 = vrhaddq_u8(q1u8, q3u8);
|
||||
|
||||
d2u32 = vreinterpret_u32_u8(vget_low_u8(q1u8));
|
||||
d3u32 = vreinterpret_u32_u8(vget_high_u8(q1u8));
|
||||
|
||||
d = dst;
|
||||
vst1_lane_u32((uint32_t *)d, d2u32, 0);
|
||||
d += dst_stride;
|
||||
vst1_lane_u32((uint32_t *)d, d3u32, 0);
|
||||
d += dst_stride;
|
||||
vst1_lane_u32((uint32_t *)d, d2u32, 1);
|
||||
d += dst_stride;
|
||||
vst1_lane_u32((uint32_t *)d, d3u32, 1);
|
||||
|
||||
q8u16 = q9u16;
|
||||
d20s16 = d23s16;
|
||||
q11u16 = q12u16;
|
||||
q9u16 = q13u16;
|
||||
d23s16 = vreinterpret_s16_u16(vget_high_u16(q11u16));
|
||||
}
|
||||
src += src_stride * 4 - w - 7;
|
||||
dst += dst_stride * 4 - w;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
void aom_convolve8_avg_vert_neon(const uint8_t *src, ptrdiff_t src_stride,
|
||||
uint8_t *dst, ptrdiff_t dst_stride,
|
||||
const int16_t *filter_x, // unused
|
||||
int x_step_q4, // unused
|
||||
const int16_t *filter_y, int y_step_q4, int w,
|
||||
int h) {
|
||||
int height;
|
||||
const uint8_t *s;
|
||||
uint8_t *d;
|
||||
uint8x8_t d2u8, d3u8;
|
||||
uint32x2_t d2u32, d3u32, d6u32, d7u32;
|
||||
uint32x2_t d16u32, d18u32, d20u32, d22u32, d24u32, d26u32;
|
||||
uint8x16_t q1u8, q3u8;
|
||||
int16x4_t d16s16, d17s16, d18s16, d19s16, d20s16, d21s16, d22s16;
|
||||
int16x4_t d24s16, d25s16, d26s16, d27s16;
|
||||
uint16x4_t d2u16, d3u16, d4u16, d5u16;
|
||||
int16x8_t q0s16;
|
||||
uint16x8_t q1u16, q2u16, q8u16, q9u16, q10u16, q11u16, q12u16, q13u16;
|
||||
int32x4_t q1s32, q2s32, q14s32, q15s32;
|
||||
|
||||
assert(y_step_q4 == 16);
|
||||
|
||||
(void)x_step_q4;
|
||||
(void)y_step_q4;
|
||||
(void)filter_x;
|
||||
|
||||
src -= src_stride * 3;
|
||||
q0s16 = vld1q_s16(filter_y);
|
||||
for (; w > 0; w -= 4, src += 4, dst += 4) { // loop_vert_h
|
||||
s = src;
|
||||
d16u32 = vld1_lane_u32((const uint32_t *)s, d16u32, 0);
|
||||
s += src_stride;
|
||||
d16u32 = vld1_lane_u32((const uint32_t *)s, d16u32, 1);
|
||||
s += src_stride;
|
||||
d18u32 = vld1_lane_u32((const uint32_t *)s, d18u32, 0);
|
||||
s += src_stride;
|
||||
d18u32 = vld1_lane_u32((const uint32_t *)s, d18u32, 1);
|
||||
s += src_stride;
|
||||
d20u32 = vld1_lane_u32((const uint32_t *)s, d20u32, 0);
|
||||
s += src_stride;
|
||||
d20u32 = vld1_lane_u32((const uint32_t *)s, d20u32, 1);
|
||||
s += src_stride;
|
||||
d22u32 = vld1_lane_u32((const uint32_t *)s, d22u32, 0);
|
||||
s += src_stride;
|
||||
|
||||
q8u16 = vmovl_u8(vreinterpret_u8_u32(d16u32));
|
||||
q9u16 = vmovl_u8(vreinterpret_u8_u32(d18u32));
|
||||
q10u16 = vmovl_u8(vreinterpret_u8_u32(d20u32));
|
||||
q11u16 = vmovl_u8(vreinterpret_u8_u32(d22u32));
|
||||
|
||||
d18s16 = vreinterpret_s16_u16(vget_low_u16(q9u16));
|
||||
d19s16 = vreinterpret_s16_u16(vget_high_u16(q9u16));
|
||||
d22s16 = vreinterpret_s16_u16(vget_low_u16(q11u16));
|
||||
d = dst;
|
||||
for (height = h; height > 0; height -= 4) { // loop_vert
|
||||
d24u32 = vld1_lane_u32((const uint32_t *)s, d24u32, 0);
|
||||
s += src_stride;
|
||||
d26u32 = vld1_lane_u32((const uint32_t *)s, d26u32, 0);
|
||||
s += src_stride;
|
||||
d26u32 = vld1_lane_u32((const uint32_t *)s, d26u32, 1);
|
||||
s += src_stride;
|
||||
d24u32 = vld1_lane_u32((const uint32_t *)s, d24u32, 1);
|
||||
s += src_stride;
|
||||
|
||||
q12u16 = vmovl_u8(vreinterpret_u8_u32(d24u32));
|
||||
q13u16 = vmovl_u8(vreinterpret_u8_u32(d26u32));
|
||||
|
||||
d6u32 = vld1_lane_u32((const uint32_t *)d, d6u32, 0);
|
||||
d += dst_stride;
|
||||
d6u32 = vld1_lane_u32((const uint32_t *)d, d6u32, 1);
|
||||
d += dst_stride;
|
||||
d7u32 = vld1_lane_u32((const uint32_t *)d, d7u32, 0);
|
||||
d += dst_stride;
|
||||
d7u32 = vld1_lane_u32((const uint32_t *)d, d7u32, 1);
|
||||
d -= dst_stride * 3;
|
||||
|
||||
d16s16 = vreinterpret_s16_u16(vget_low_u16(q8u16));
|
||||
d17s16 = vreinterpret_s16_u16(vget_high_u16(q8u16));
|
||||
d20s16 = vreinterpret_s16_u16(vget_low_u16(q10u16));
|
||||
d21s16 = vreinterpret_s16_u16(vget_high_u16(q10u16));
|
||||
d24s16 = vreinterpret_s16_u16(vget_low_u16(q12u16));
|
||||
d25s16 = vreinterpret_s16_u16(vget_high_u16(q12u16));
|
||||
d26s16 = vreinterpret_s16_u16(vget_low_u16(q13u16));
|
||||
d27s16 = vreinterpret_s16_u16(vget_high_u16(q13u16));
|
||||
|
||||
__builtin_prefetch(s);
|
||||
__builtin_prefetch(s + src_stride);
|
||||
q1s32 = MULTIPLY_BY_Q0(d16s16, d17s16, d18s16, d19s16, d20s16, d21s16,
|
||||
d22s16, d24s16, q0s16);
|
||||
__builtin_prefetch(s + src_stride * 2);
|
||||
__builtin_prefetch(s + src_stride * 3);
|
||||
q2s32 = MULTIPLY_BY_Q0(d17s16, d18s16, d19s16, d20s16, d21s16, d22s16,
|
||||
d24s16, d26s16, q0s16);
|
||||
__builtin_prefetch(d);
|
||||
__builtin_prefetch(d + dst_stride);
|
||||
q14s32 = MULTIPLY_BY_Q0(d18s16, d19s16, d20s16, d21s16, d22s16, d24s16,
|
||||
d26s16, d27s16, q0s16);
|
||||
__builtin_prefetch(d + dst_stride * 2);
|
||||
__builtin_prefetch(d + dst_stride * 3);
|
||||
q15s32 = MULTIPLY_BY_Q0(d19s16, d20s16, d21s16, d22s16, d24s16, d26s16,
|
||||
d27s16, d25s16, q0s16);
|
||||
|
||||
d2u16 = vqrshrun_n_s32(q1s32, 7);
|
||||
d3u16 = vqrshrun_n_s32(q2s32, 7);
|
||||
d4u16 = vqrshrun_n_s32(q14s32, 7);
|
||||
d5u16 = vqrshrun_n_s32(q15s32, 7);
|
||||
|
||||
q1u16 = vcombine_u16(d2u16, d3u16);
|
||||
q2u16 = vcombine_u16(d4u16, d5u16);
|
||||
|
||||
d2u8 = vqmovn_u16(q1u16);
|
||||
d3u8 = vqmovn_u16(q2u16);
|
||||
|
||||
q1u8 = vcombine_u8(d2u8, d3u8);
|
||||
q3u8 = vreinterpretq_u8_u32(vcombine_u32(d6u32, d7u32));
|
||||
|
||||
q1u8 = vrhaddq_u8(q1u8, q3u8);
|
||||
|
||||
d2u32 = vreinterpret_u32_u8(vget_low_u8(q1u8));
|
||||
d3u32 = vreinterpret_u32_u8(vget_high_u8(q1u8));
|
||||
|
||||
vst1_lane_u32((uint32_t *)d, d2u32, 0);
|
||||
d += dst_stride;
|
||||
vst1_lane_u32((uint32_t *)d, d2u32, 1);
|
||||
d += dst_stride;
|
||||
vst1_lane_u32((uint32_t *)d, d3u32, 0);
|
||||
d += dst_stride;
|
||||
vst1_lane_u32((uint32_t *)d, d3u32, 1);
|
||||
d += dst_stride;
|
||||
|
||||
q8u16 = q10u16;
|
||||
d18s16 = d22s16;
|
||||
d19s16 = d24s16;
|
||||
q10u16 = q13u16;
|
||||
d22s16 = d25s16;
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
@@ -1,331 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2016, Alliance for Open Media. All rights reserved
|
||||
*
|
||||
* This source code is subject to the terms of the BSD 2 Clause License and
|
||||
* the Alliance for Open Media Patent License 1.0. If the BSD 2 Clause License
|
||||
* was not distributed with this source code in the LICENSE file, you can
|
||||
* obtain it at www.aomedia.org/license/software. If the Alliance for Open
|
||||
* Media Patent License 1.0 was not distributed with this source code in the
|
||||
* PATENTS file, you can obtain it at www.aomedia.org/license/patent.
|
||||
*/
|
||||
|
||||
#include <arm_neon.h>
|
||||
#include <assert.h>
|
||||
|
||||
#include "./aom_config.h"
|
||||
#include "./aom_dsp_rtcd.h"
|
||||
#include "aom/aom_integer.h"
|
||||
#include "aom_ports/mem.h"
|
||||
|
||||
static INLINE int32x4_t MULTIPLY_BY_Q0(int16x4_t dsrc0, int16x4_t dsrc1,
|
||||
int16x4_t dsrc2, int16x4_t dsrc3,
|
||||
int16x4_t dsrc4, int16x4_t dsrc5,
|
||||
int16x4_t dsrc6, int16x4_t dsrc7,
|
||||
int16x8_t q0s16) {
|
||||
int32x4_t qdst;
|
||||
int16x4_t d0s16, d1s16;
|
||||
|
||||
d0s16 = vget_low_s16(q0s16);
|
||||
d1s16 = vget_high_s16(q0s16);
|
||||
|
||||
qdst = vmull_lane_s16(dsrc0, d0s16, 0);
|
||||
qdst = vmlal_lane_s16(qdst, dsrc1, d0s16, 1);
|
||||
qdst = vmlal_lane_s16(qdst, dsrc2, d0s16, 2);
|
||||
qdst = vmlal_lane_s16(qdst, dsrc3, d0s16, 3);
|
||||
qdst = vmlal_lane_s16(qdst, dsrc4, d1s16, 0);
|
||||
qdst = vmlal_lane_s16(qdst, dsrc5, d1s16, 1);
|
||||
qdst = vmlal_lane_s16(qdst, dsrc6, d1s16, 2);
|
||||
qdst = vmlal_lane_s16(qdst, dsrc7, d1s16, 3);
|
||||
return qdst;
|
||||
}
|
||||
|
||||
void aom_convolve8_horiz_neon(const uint8_t *src, ptrdiff_t src_stride,
|
||||
uint8_t *dst, ptrdiff_t dst_stride,
|
||||
const int16_t *filter_x, int x_step_q4,
|
||||
const int16_t *filter_y, // unused
|
||||
int y_step_q4, // unused
|
||||
int w, int h) {
|
||||
int width;
|
||||
const uint8_t *s, *psrc;
|
||||
uint8_t *d, *pdst;
|
||||
uint8x8_t d2u8, d3u8, d24u8, d25u8, d26u8, d27u8, d28u8, d29u8;
|
||||
uint32x2_t d2u32, d3u32, d28u32, d29u32, d30u32, d31u32;
|
||||
uint8x16_t q12u8, q13u8, q14u8, q15u8;
|
||||
int16x4_t d16s16, d17s16, d18s16, d19s16, d20s16, d22s16, d23s16;
|
||||
int16x4_t d24s16, d25s16, d26s16, d27s16;
|
||||
uint16x4_t d2u16, d3u16, d4u16, d5u16, d16u16, d17u16, d18u16, d19u16;
|
||||
int16x8_t q0s16;
|
||||
uint16x8_t q1u16, q2u16, q8u16, q9u16, q10u16, q11u16, q12u16, q13u16;
|
||||
int32x4_t q1s32, q2s32, q14s32, q15s32;
|
||||
uint16x8x2_t q0x2u16;
|
||||
uint8x8x2_t d0x2u8, d1x2u8;
|
||||
uint32x2x2_t d0x2u32;
|
||||
uint16x4x2_t d0x2u16, d1x2u16;
|
||||
uint32x4x2_t q0x2u32;
|
||||
|
||||
assert(x_step_q4 == 16);
|
||||
|
||||
(void)x_step_q4;
|
||||
(void)y_step_q4;
|
||||
(void)filter_y;
|
||||
|
||||
q0s16 = vld1q_s16(filter_x);
|
||||
|
||||
src -= 3; // adjust for taps
|
||||
for (; h > 0; h -= 4, src += src_stride * 4,
|
||||
dst += dst_stride * 4) { // loop_horiz_v
|
||||
s = src;
|
||||
d24u8 = vld1_u8(s);
|
||||
s += src_stride;
|
||||
d25u8 = vld1_u8(s);
|
||||
s += src_stride;
|
||||
d26u8 = vld1_u8(s);
|
||||
s += src_stride;
|
||||
d27u8 = vld1_u8(s);
|
||||
|
||||
q12u8 = vcombine_u8(d24u8, d25u8);
|
||||
q13u8 = vcombine_u8(d26u8, d27u8);
|
||||
|
||||
q0x2u16 =
|
||||
vtrnq_u16(vreinterpretq_u16_u8(q12u8), vreinterpretq_u16_u8(q13u8));
|
||||
d24u8 = vreinterpret_u8_u16(vget_low_u16(q0x2u16.val[0]));
|
||||
d25u8 = vreinterpret_u8_u16(vget_high_u16(q0x2u16.val[0]));
|
||||
d26u8 = vreinterpret_u8_u16(vget_low_u16(q0x2u16.val[1]));
|
||||
d27u8 = vreinterpret_u8_u16(vget_high_u16(q0x2u16.val[1]));
|
||||
d0x2u8 = vtrn_u8(d24u8, d25u8);
|
||||
d1x2u8 = vtrn_u8(d26u8, d27u8);
|
||||
|
||||
__builtin_prefetch(src + src_stride * 4);
|
||||
__builtin_prefetch(src + src_stride * 5);
|
||||
__builtin_prefetch(src + src_stride * 6);
|
||||
|
||||
q8u16 = vmovl_u8(d0x2u8.val[0]);
|
||||
q9u16 = vmovl_u8(d0x2u8.val[1]);
|
||||
q10u16 = vmovl_u8(d1x2u8.val[0]);
|
||||
q11u16 = vmovl_u8(d1x2u8.val[1]);
|
||||
|
||||
d16u16 = vget_low_u16(q8u16);
|
||||
d17u16 = vget_high_u16(q8u16);
|
||||
d18u16 = vget_low_u16(q9u16);
|
||||
d19u16 = vget_high_u16(q9u16);
|
||||
q8u16 = vcombine_u16(d16u16, d18u16); // vswp 17 18
|
||||
q9u16 = vcombine_u16(d17u16, d19u16);
|
||||
|
||||
d20s16 = vreinterpret_s16_u16(vget_low_u16(q10u16));
|
||||
d23s16 = vreinterpret_s16_u16(vget_high_u16(q10u16)); // vmov 23 21
|
||||
for (width = w, psrc = src + 7, pdst = dst; width > 0;
|
||||
width -= 4, psrc += 4, pdst += 4) { // loop_horiz
|
||||
s = psrc;
|
||||
d28u32 = vld1_dup_u32((const uint32_t *)s);
|
||||
s += src_stride;
|
||||
d29u32 = vld1_dup_u32((const uint32_t *)s);
|
||||
s += src_stride;
|
||||
d31u32 = vld1_dup_u32((const uint32_t *)s);
|
||||
s += src_stride;
|
||||
d30u32 = vld1_dup_u32((const uint32_t *)s);
|
||||
|
||||
__builtin_prefetch(psrc + 64);
|
||||
|
||||
d0x2u16 =
|
||||
vtrn_u16(vreinterpret_u16_u32(d28u32), vreinterpret_u16_u32(d31u32));
|
||||
d1x2u16 =
|
||||
vtrn_u16(vreinterpret_u16_u32(d29u32), vreinterpret_u16_u32(d30u32));
|
||||
d0x2u8 = vtrn_u8(vreinterpret_u8_u16(d0x2u16.val[0]), // d28
|
||||
vreinterpret_u8_u16(d1x2u16.val[0])); // d29
|
||||
d1x2u8 = vtrn_u8(vreinterpret_u8_u16(d0x2u16.val[1]), // d31
|
||||
vreinterpret_u8_u16(d1x2u16.val[1])); // d30
|
||||
|
||||
__builtin_prefetch(psrc + 64 + src_stride);
|
||||
|
||||
q14u8 = vcombine_u8(d0x2u8.val[0], d0x2u8.val[1]);
|
||||
q15u8 = vcombine_u8(d1x2u8.val[1], d1x2u8.val[0]);
|
||||
q0x2u32 =
|
||||
vtrnq_u32(vreinterpretq_u32_u8(q14u8), vreinterpretq_u32_u8(q15u8));
|
||||
|
||||
d28u8 = vreinterpret_u8_u32(vget_low_u32(q0x2u32.val[0]));
|
||||
d29u8 = vreinterpret_u8_u32(vget_high_u32(q0x2u32.val[0]));
|
||||
q12u16 = vmovl_u8(d28u8);
|
||||
q13u16 = vmovl_u8(d29u8);
|
||||
|
||||
__builtin_prefetch(psrc + 64 + src_stride * 2);
|
||||
|
||||
d16s16 = vreinterpret_s16_u16(vget_low_u16(q8u16));
|
||||
d17s16 = vreinterpret_s16_u16(vget_high_u16(q8u16));
|
||||
d18s16 = vreinterpret_s16_u16(vget_low_u16(q9u16));
|
||||
d19s16 = vreinterpret_s16_u16(vget_high_u16(q9u16));
|
||||
d22s16 = vreinterpret_s16_u16(vget_low_u16(q11u16));
|
||||
d24s16 = vreinterpret_s16_u16(vget_low_u16(q12u16));
|
||||
d25s16 = vreinterpret_s16_u16(vget_high_u16(q12u16));
|
||||
d26s16 = vreinterpret_s16_u16(vget_low_u16(q13u16));
|
||||
d27s16 = vreinterpret_s16_u16(vget_high_u16(q13u16));
|
||||
|
||||
q1s32 = MULTIPLY_BY_Q0(d16s16, d17s16, d20s16, d22s16, d18s16, d19s16,
|
||||
d23s16, d24s16, q0s16);
|
||||
q2s32 = MULTIPLY_BY_Q0(d17s16, d20s16, d22s16, d18s16, d19s16, d23s16,
|
||||
d24s16, d26s16, q0s16);
|
||||
q14s32 = MULTIPLY_BY_Q0(d20s16, d22s16, d18s16, d19s16, d23s16, d24s16,
|
||||
d26s16, d27s16, q0s16);
|
||||
q15s32 = MULTIPLY_BY_Q0(d22s16, d18s16, d19s16, d23s16, d24s16, d26s16,
|
||||
d27s16, d25s16, q0s16);
|
||||
|
||||
__builtin_prefetch(psrc + 60 + src_stride * 3);
|
||||
|
||||
d2u16 = vqrshrun_n_s32(q1s32, 7);
|
||||
d3u16 = vqrshrun_n_s32(q2s32, 7);
|
||||
d4u16 = vqrshrun_n_s32(q14s32, 7);
|
||||
d5u16 = vqrshrun_n_s32(q15s32, 7);
|
||||
|
||||
q1u16 = vcombine_u16(d2u16, d3u16);
|
||||
q2u16 = vcombine_u16(d4u16, d5u16);
|
||||
|
||||
d2u8 = vqmovn_u16(q1u16);
|
||||
d3u8 = vqmovn_u16(q2u16);
|
||||
|
||||
d0x2u16 = vtrn_u16(vreinterpret_u16_u8(d2u8), vreinterpret_u16_u8(d3u8));
|
||||
d0x2u32 = vtrn_u32(vreinterpret_u32_u16(d0x2u16.val[0]),
|
||||
vreinterpret_u32_u16(d0x2u16.val[1]));
|
||||
d0x2u8 = vtrn_u8(vreinterpret_u8_u32(d0x2u32.val[0]),
|
||||
vreinterpret_u8_u32(d0x2u32.val[1]));
|
||||
|
||||
d2u32 = vreinterpret_u32_u8(d0x2u8.val[0]);
|
||||
d3u32 = vreinterpret_u32_u8(d0x2u8.val[1]);
|
||||
|
||||
d = pdst;
|
||||
vst1_lane_u32((uint32_t *)d, d2u32, 0);
|
||||
d += dst_stride;
|
||||
vst1_lane_u32((uint32_t *)d, d3u32, 0);
|
||||
d += dst_stride;
|
||||
vst1_lane_u32((uint32_t *)d, d2u32, 1);
|
||||
d += dst_stride;
|
||||
vst1_lane_u32((uint32_t *)d, d3u32, 1);
|
||||
|
||||
q8u16 = q9u16;
|
||||
d20s16 = d23s16;
|
||||
q11u16 = q12u16;
|
||||
q9u16 = q13u16;
|
||||
d23s16 = vreinterpret_s16_u16(vget_high_u16(q11u16));
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
void aom_convolve8_vert_neon(const uint8_t *src, ptrdiff_t src_stride,
|
||||
uint8_t *dst, ptrdiff_t dst_stride,
|
||||
const int16_t *filter_x, // unused
|
||||
int x_step_q4, // unused
|
||||
const int16_t *filter_y, int y_step_q4, int w,
|
||||
int h) {
|
||||
int height;
|
||||
const uint8_t *s;
|
||||
uint8_t *d;
|
||||
uint32x2_t d2u32, d3u32;
|
||||
uint32x2_t d16u32, d18u32, d20u32, d22u32, d24u32, d26u32;
|
||||
int16x4_t d16s16, d17s16, d18s16, d19s16, d20s16, d21s16, d22s16;
|
||||
int16x4_t d24s16, d25s16, d26s16, d27s16;
|
||||
uint16x4_t d2u16, d3u16, d4u16, d5u16;
|
||||
int16x8_t q0s16;
|
||||
uint16x8_t q1u16, q2u16, q8u16, q9u16, q10u16, q11u16, q12u16, q13u16;
|
||||
int32x4_t q1s32, q2s32, q14s32, q15s32;
|
||||
|
||||
assert(y_step_q4 == 16);
|
||||
|
||||
(void)x_step_q4;
|
||||
(void)y_step_q4;
|
||||
(void)filter_x;
|
||||
|
||||
src -= src_stride * 3;
|
||||
q0s16 = vld1q_s16(filter_y);
|
||||
for (; w > 0; w -= 4, src += 4, dst += 4) { // loop_vert_h
|
||||
s = src;
|
||||
d16u32 = vld1_lane_u32((const uint32_t *)s, d16u32, 0);
|
||||
s += src_stride;
|
||||
d16u32 = vld1_lane_u32((const uint32_t *)s, d16u32, 1);
|
||||
s += src_stride;
|
||||
d18u32 = vld1_lane_u32((const uint32_t *)s, d18u32, 0);
|
||||
s += src_stride;
|
||||
d18u32 = vld1_lane_u32((const uint32_t *)s, d18u32, 1);
|
||||
s += src_stride;
|
||||
d20u32 = vld1_lane_u32((const uint32_t *)s, d20u32, 0);
|
||||
s += src_stride;
|
||||
d20u32 = vld1_lane_u32((const uint32_t *)s, d20u32, 1);
|
||||
s += src_stride;
|
||||
d22u32 = vld1_lane_u32((const uint32_t *)s, d22u32, 0);
|
||||
s += src_stride;
|
||||
|
||||
q8u16 = vmovl_u8(vreinterpret_u8_u32(d16u32));
|
||||
q9u16 = vmovl_u8(vreinterpret_u8_u32(d18u32));
|
||||
q10u16 = vmovl_u8(vreinterpret_u8_u32(d20u32));
|
||||
q11u16 = vmovl_u8(vreinterpret_u8_u32(d22u32));
|
||||
|
||||
d18s16 = vreinterpret_s16_u16(vget_low_u16(q9u16));
|
||||
d19s16 = vreinterpret_s16_u16(vget_high_u16(q9u16));
|
||||
d22s16 = vreinterpret_s16_u16(vget_low_u16(q11u16));
|
||||
d = dst;
|
||||
for (height = h; height > 0; height -= 4) { // loop_vert
|
||||
d24u32 = vld1_lane_u32((const uint32_t *)s, d24u32, 0);
|
||||
s += src_stride;
|
||||
d26u32 = vld1_lane_u32((const uint32_t *)s, d26u32, 0);
|
||||
s += src_stride;
|
||||
d26u32 = vld1_lane_u32((const uint32_t *)s, d26u32, 1);
|
||||
s += src_stride;
|
||||
d24u32 = vld1_lane_u32((const uint32_t *)s, d24u32, 1);
|
||||
s += src_stride;
|
||||
|
||||
q12u16 = vmovl_u8(vreinterpret_u8_u32(d24u32));
|
||||
q13u16 = vmovl_u8(vreinterpret_u8_u32(d26u32));
|
||||
|
||||
d16s16 = vreinterpret_s16_u16(vget_low_u16(q8u16));
|
||||
d17s16 = vreinterpret_s16_u16(vget_high_u16(q8u16));
|
||||
d20s16 = vreinterpret_s16_u16(vget_low_u16(q10u16));
|
||||
d21s16 = vreinterpret_s16_u16(vget_high_u16(q10u16));
|
||||
d24s16 = vreinterpret_s16_u16(vget_low_u16(q12u16));
|
||||
d25s16 = vreinterpret_s16_u16(vget_high_u16(q12u16));
|
||||
d26s16 = vreinterpret_s16_u16(vget_low_u16(q13u16));
|
||||
d27s16 = vreinterpret_s16_u16(vget_high_u16(q13u16));
|
||||
|
||||
__builtin_prefetch(d);
|
||||
__builtin_prefetch(d + dst_stride);
|
||||
q1s32 = MULTIPLY_BY_Q0(d16s16, d17s16, d18s16, d19s16, d20s16, d21s16,
|
||||
d22s16, d24s16, q0s16);
|
||||
__builtin_prefetch(d + dst_stride * 2);
|
||||
__builtin_prefetch(d + dst_stride * 3);
|
||||
q2s32 = MULTIPLY_BY_Q0(d17s16, d18s16, d19s16, d20s16, d21s16, d22s16,
|
||||
d24s16, d26s16, q0s16);
|
||||
__builtin_prefetch(s);
|
||||
__builtin_prefetch(s + src_stride);
|
||||
q14s32 = MULTIPLY_BY_Q0(d18s16, d19s16, d20s16, d21s16, d22s16, d24s16,
|
||||
d26s16, d27s16, q0s16);
|
||||
__builtin_prefetch(s + src_stride * 2);
|
||||
__builtin_prefetch(s + src_stride * 3);
|
||||
q15s32 = MULTIPLY_BY_Q0(d19s16, d20s16, d21s16, d22s16, d24s16, d26s16,
|
||||
d27s16, d25s16, q0s16);
|
||||
|
||||
d2u16 = vqrshrun_n_s32(q1s32, 7);
|
||||
d3u16 = vqrshrun_n_s32(q2s32, 7);
|
||||
d4u16 = vqrshrun_n_s32(q14s32, 7);
|
||||
d5u16 = vqrshrun_n_s32(q15s32, 7);
|
||||
|
||||
q1u16 = vcombine_u16(d2u16, d3u16);
|
||||
q2u16 = vcombine_u16(d4u16, d5u16);
|
||||
|
||||
d2u32 = vreinterpret_u32_u8(vqmovn_u16(q1u16));
|
||||
d3u32 = vreinterpret_u32_u8(vqmovn_u16(q2u16));
|
||||
|
||||
vst1_lane_u32((uint32_t *)d, d2u32, 0);
|
||||
d += dst_stride;
|
||||
vst1_lane_u32((uint32_t *)d, d2u32, 1);
|
||||
d += dst_stride;
|
||||
vst1_lane_u32((uint32_t *)d, d3u32, 0);
|
||||
d += dst_stride;
|
||||
vst1_lane_u32((uint32_t *)d, d3u32, 1);
|
||||
d += dst_stride;
|
||||
|
||||
q8u16 = q10u16;
|
||||
d18s16 = d22s16;
|
||||
d19s16 = d24s16;
|
||||
q10u16 = q13u16;
|
||||
d22s16 = d25s16;
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
@@ -1,145 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2016, Alliance for Open Media. All rights reserved
|
||||
*
|
||||
* This source code is subject to the terms of the BSD 2 Clause License and
|
||||
* the Alliance for Open Media Patent License 1.0. If the BSD 2 Clause License
|
||||
* was not distributed with this source code in the LICENSE file, you can
|
||||
* obtain it at www.aomedia.org/license/software. If the Alliance for Open
|
||||
* Media Patent License 1.0 was not distributed with this source code in the
|
||||
* PATENTS file, you can obtain it at www.aomedia.org/license/patent.
|
||||
*/
|
||||
|
||||
#include <arm_neon.h>
|
||||
|
||||
#include "./aom_dsp_rtcd.h"
|
||||
#include "aom/aom_integer.h"
|
||||
|
||||
void aom_convolve_avg_neon(const uint8_t *src, // r0
|
||||
ptrdiff_t src_stride, // r1
|
||||
uint8_t *dst, // r2
|
||||
ptrdiff_t dst_stride, // r3
|
||||
const int16_t *filter_x, int filter_x_stride,
|
||||
const int16_t *filter_y, int filter_y_stride, int w,
|
||||
int h) {
|
||||
uint8_t *d;
|
||||
uint8x8_t d0u8, d1u8, d2u8, d3u8;
|
||||
uint32x2_t d0u32, d2u32;
|
||||
uint8x16_t q0u8, q1u8, q2u8, q3u8, q8u8, q9u8, q10u8, q11u8;
|
||||
(void)filter_x;
|
||||
(void)filter_x_stride;
|
||||
(void)filter_y;
|
||||
(void)filter_y_stride;
|
||||
|
||||
d = dst;
|
||||
if (w > 32) { // avg64
|
||||
for (; h > 0; h -= 1) {
|
||||
q0u8 = vld1q_u8(src);
|
||||
q1u8 = vld1q_u8(src + 16);
|
||||
q2u8 = vld1q_u8(src + 32);
|
||||
q3u8 = vld1q_u8(src + 48);
|
||||
src += src_stride;
|
||||
q8u8 = vld1q_u8(d);
|
||||
q9u8 = vld1q_u8(d + 16);
|
||||
q10u8 = vld1q_u8(d + 32);
|
||||
q11u8 = vld1q_u8(d + 48);
|
||||
d += dst_stride;
|
||||
|
||||
q0u8 = vrhaddq_u8(q0u8, q8u8);
|
||||
q1u8 = vrhaddq_u8(q1u8, q9u8);
|
||||
q2u8 = vrhaddq_u8(q2u8, q10u8);
|
||||
q3u8 = vrhaddq_u8(q3u8, q11u8);
|
||||
|
||||
vst1q_u8(dst, q0u8);
|
||||
vst1q_u8(dst + 16, q1u8);
|
||||
vst1q_u8(dst + 32, q2u8);
|
||||
vst1q_u8(dst + 48, q3u8);
|
||||
dst += dst_stride;
|
||||
}
|
||||
} else if (w == 32) { // avg32
|
||||
for (; h > 0; h -= 2) {
|
||||
q0u8 = vld1q_u8(src);
|
||||
q1u8 = vld1q_u8(src + 16);
|
||||
src += src_stride;
|
||||
q2u8 = vld1q_u8(src);
|
||||
q3u8 = vld1q_u8(src + 16);
|
||||
src += src_stride;
|
||||
q8u8 = vld1q_u8(d);
|
||||
q9u8 = vld1q_u8(d + 16);
|
||||
d += dst_stride;
|
||||
q10u8 = vld1q_u8(d);
|
||||
q11u8 = vld1q_u8(d + 16);
|
||||
d += dst_stride;
|
||||
|
||||
q0u8 = vrhaddq_u8(q0u8, q8u8);
|
||||
q1u8 = vrhaddq_u8(q1u8, q9u8);
|
||||
q2u8 = vrhaddq_u8(q2u8, q10u8);
|
||||
q3u8 = vrhaddq_u8(q3u8, q11u8);
|
||||
|
||||
vst1q_u8(dst, q0u8);
|
||||
vst1q_u8(dst + 16, q1u8);
|
||||
dst += dst_stride;
|
||||
vst1q_u8(dst, q2u8);
|
||||
vst1q_u8(dst + 16, q3u8);
|
||||
dst += dst_stride;
|
||||
}
|
||||
} else if (w > 8) { // avg16
|
||||
for (; h > 0; h -= 2) {
|
||||
q0u8 = vld1q_u8(src);
|
||||
src += src_stride;
|
||||
q1u8 = vld1q_u8(src);
|
||||
src += src_stride;
|
||||
q2u8 = vld1q_u8(d);
|
||||
d += dst_stride;
|
||||
q3u8 = vld1q_u8(d);
|
||||
d += dst_stride;
|
||||
|
||||
q0u8 = vrhaddq_u8(q0u8, q2u8);
|
||||
q1u8 = vrhaddq_u8(q1u8, q3u8);
|
||||
|
||||
vst1q_u8(dst, q0u8);
|
||||
dst += dst_stride;
|
||||
vst1q_u8(dst, q1u8);
|
||||
dst += dst_stride;
|
||||
}
|
||||
} else if (w == 8) { // avg8
|
||||
for (; h > 0; h -= 2) {
|
||||
d0u8 = vld1_u8(src);
|
||||
src += src_stride;
|
||||
d1u8 = vld1_u8(src);
|
||||
src += src_stride;
|
||||
d2u8 = vld1_u8(d);
|
||||
d += dst_stride;
|
||||
d3u8 = vld1_u8(d);
|
||||
d += dst_stride;
|
||||
|
||||
q0u8 = vcombine_u8(d0u8, d1u8);
|
||||
q1u8 = vcombine_u8(d2u8, d3u8);
|
||||
q0u8 = vrhaddq_u8(q0u8, q1u8);
|
||||
|
||||
vst1_u8(dst, vget_low_u8(q0u8));
|
||||
dst += dst_stride;
|
||||
vst1_u8(dst, vget_high_u8(q0u8));
|
||||
dst += dst_stride;
|
||||
}
|
||||
} else { // avg4
|
||||
for (; h > 0; h -= 2) {
|
||||
d0u32 = vld1_lane_u32((const uint32_t *)src, d0u32, 0);
|
||||
src += src_stride;
|
||||
d0u32 = vld1_lane_u32((const uint32_t *)src, d0u32, 1);
|
||||
src += src_stride;
|
||||
d2u32 = vld1_lane_u32((const uint32_t *)d, d2u32, 0);
|
||||
d += dst_stride;
|
||||
d2u32 = vld1_lane_u32((const uint32_t *)d, d2u32, 1);
|
||||
d += dst_stride;
|
||||
|
||||
d0u8 = vrhadd_u8(vreinterpret_u8_u32(d0u32), vreinterpret_u8_u32(d2u32));
|
||||
|
||||
d0u32 = vreinterpret_u32_u8(d0u8);
|
||||
vst1_lane_u32((uint32_t *)dst, d0u32, 0);
|
||||
dst += dst_stride;
|
||||
vst1_lane_u32((uint32_t *)dst, d0u32, 1);
|
||||
dst += dst_stride;
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
@@ -1,93 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2016, Alliance for Open Media. All rights reserved
|
||||
*
|
||||
* This source code is subject to the terms of the BSD 2 Clause License and
|
||||
* the Alliance for Open Media Patent License 1.0. If the BSD 2 Clause License
|
||||
* was not distributed with this source code in the LICENSE file, you can
|
||||
* obtain it at www.aomedia.org/license/software. If the Alliance for Open
|
||||
* Media Patent License 1.0 was not distributed with this source code in the
|
||||
* PATENTS file, you can obtain it at www.aomedia.org/license/patent.
|
||||
*/
|
||||
|
||||
#include <arm_neon.h>
|
||||
|
||||
#include "./aom_dsp_rtcd.h"
|
||||
#include "aom/aom_integer.h"
|
||||
|
||||
void aom_convolve_copy_neon(const uint8_t *src, // r0
|
||||
ptrdiff_t src_stride, // r1
|
||||
uint8_t *dst, // r2
|
||||
ptrdiff_t dst_stride, // r3
|
||||
const int16_t *filter_x, int filter_x_stride,
|
||||
const int16_t *filter_y, int filter_y_stride, int w,
|
||||
int h) {
|
||||
uint8x8_t d0u8, d2u8;
|
||||
uint8x16_t q0u8, q1u8, q2u8, q3u8;
|
||||
(void)filter_x;
|
||||
(void)filter_x_stride;
|
||||
(void)filter_y;
|
||||
(void)filter_y_stride;
|
||||
|
||||
if (w > 32) { // copy64
|
||||
for (; h > 0; h--) {
|
||||
q0u8 = vld1q_u8(src);
|
||||
q1u8 = vld1q_u8(src + 16);
|
||||
q2u8 = vld1q_u8(src + 32);
|
||||
q3u8 = vld1q_u8(src + 48);
|
||||
src += src_stride;
|
||||
|
||||
vst1q_u8(dst, q0u8);
|
||||
vst1q_u8(dst + 16, q1u8);
|
||||
vst1q_u8(dst + 32, q2u8);
|
||||
vst1q_u8(dst + 48, q3u8);
|
||||
dst += dst_stride;
|
||||
}
|
||||
} else if (w == 32) { // copy32
|
||||
for (; h > 0; h -= 2) {
|
||||
q0u8 = vld1q_u8(src);
|
||||
q1u8 = vld1q_u8(src + 16);
|
||||
src += src_stride;
|
||||
q2u8 = vld1q_u8(src);
|
||||
q3u8 = vld1q_u8(src + 16);
|
||||
src += src_stride;
|
||||
|
||||
vst1q_u8(dst, q0u8);
|
||||
vst1q_u8(dst + 16, q1u8);
|
||||
dst += dst_stride;
|
||||
vst1q_u8(dst, q2u8);
|
||||
vst1q_u8(dst + 16, q3u8);
|
||||
dst += dst_stride;
|
||||
}
|
||||
} else if (w > 8) { // copy16
|
||||
for (; h > 0; h -= 2) {
|
||||
q0u8 = vld1q_u8(src);
|
||||
src += src_stride;
|
||||
q1u8 = vld1q_u8(src);
|
||||
src += src_stride;
|
||||
|
||||
vst1q_u8(dst, q0u8);
|
||||
dst += dst_stride;
|
||||
vst1q_u8(dst, q1u8);
|
||||
dst += dst_stride;
|
||||
}
|
||||
} else if (w == 8) { // copy8
|
||||
for (; h > 0; h -= 2) {
|
||||
d0u8 = vld1_u8(src);
|
||||
src += src_stride;
|
||||
d2u8 = vld1_u8(src);
|
||||
src += src_stride;
|
||||
|
||||
vst1_u8(dst, d0u8);
|
||||
dst += dst_stride;
|
||||
vst1_u8(dst, d2u8);
|
||||
dst += dst_stride;
|
||||
}
|
||||
} else { // copy4
|
||||
for (; h > 0; h--) {
|
||||
*(uint32_t *)dst = *(const uint32_t *)src;
|
||||
src += src_stride;
|
||||
dst += dst_stride;
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
@@ -1,240 +0,0 @@
|
||||
;
|
||||
; Copyright (c) 2016, Alliance for Open Media. All rights reserved
|
||||
;
|
||||
; This source code is subject to the terms of the BSD 2 Clause License and
|
||||
; the Alliance for Open Media Patent License 1.0. If the BSD 2 Clause License
|
||||
; was not distributed with this source code in the LICENSE file, you can
|
||||
; obtain it at www.aomedia.org/license/software. If the Alliance for Open
|
||||
; Media Patent License 1.0 was not distributed with this source code in the
|
||||
; PATENTS file, you can obtain it at www.aomedia.org/license/patent.
|
||||
;
|
||||
|
||||
;
|
||||
|
||||
|
||||
EXPORT |aom_filter_block2d_bil_first_pass_media|
|
||||
EXPORT |aom_filter_block2d_bil_second_pass_media|
|
||||
|
||||
AREA |.text|, CODE, READONLY ; name this block of code
|
||||
|
||||
;-------------------------------------
|
||||
; r0 unsigned char *src_ptr,
|
||||
; r1 unsigned short *dst_ptr,
|
||||
; r2 unsigned int src_pitch,
|
||||
; r3 unsigned int height,
|
||||
; stack unsigned int width,
|
||||
; stack const short *aom_filter
|
||||
;-------------------------------------
|
||||
; The output is transposed stroed in output array to make it easy for second pass filtering.
|
||||
|aom_filter_block2d_bil_first_pass_media| PROC
|
||||
stmdb sp!, {r4 - r11, lr}
|
||||
|
||||
ldr r11, [sp, #40] ; aom_filter address
|
||||
ldr r4, [sp, #36] ; width
|
||||
|
||||
mov r12, r3 ; outer-loop counter
|
||||
|
||||
add r7, r2, r4 ; preload next row
|
||||
pld [r0, r7]
|
||||
|
||||
sub r2, r2, r4 ; src increment for height loop
|
||||
|
||||
ldr r5, [r11] ; load up filter coefficients
|
||||
|
||||
mov r3, r3, lsl #1 ; height*2
|
||||
add r3, r3, #2 ; plus 2 to make output buffer 4-bit aligned since height is actually (height+1)
|
||||
|
||||
mov r11, r1 ; save dst_ptr for each row
|
||||
|
||||
cmp r5, #128 ; if filter coef = 128, then skip the filter
|
||||
beq bil_null_1st_filter
|
||||
|
||||
|bil_height_loop_1st_v6|
|
||||
ldrb r6, [r0] ; load source data
|
||||
ldrb r7, [r0, #1]
|
||||
ldrb r8, [r0, #2]
|
||||
mov lr, r4, lsr #2 ; 4-in-parellel loop counter
|
||||
|
||||
|bil_width_loop_1st_v6|
|
||||
ldrb r9, [r0, #3]
|
||||
ldrb r10, [r0, #4]
|
||||
|
||||
pkhbt r6, r6, r7, lsl #16 ; src[1] | src[0]
|
||||
pkhbt r7, r7, r8, lsl #16 ; src[2] | src[1]
|
||||
|
||||
smuad r6, r6, r5 ; apply the filter
|
||||
pkhbt r8, r8, r9, lsl #16 ; src[3] | src[2]
|
||||
smuad r7, r7, r5
|
||||
pkhbt r9, r9, r10, lsl #16 ; src[4] | src[3]
|
||||
|
||||
smuad r8, r8, r5
|
||||
smuad r9, r9, r5
|
||||
|
||||
add r0, r0, #4
|
||||
subs lr, lr, #1
|
||||
|
||||
add r6, r6, #0x40 ; round_shift_and_clamp
|
||||
add r7, r7, #0x40
|
||||
usat r6, #16, r6, asr #7
|
||||
usat r7, #16, r7, asr #7
|
||||
|
||||
strh r6, [r1], r3 ; result is transposed and stored
|
||||
|
||||
add r8, r8, #0x40 ; round_shift_and_clamp
|
||||
strh r7, [r1], r3
|
||||
add r9, r9, #0x40
|
||||
usat r8, #16, r8, asr #7
|
||||
usat r9, #16, r9, asr #7
|
||||
|
||||
strh r8, [r1], r3 ; result is transposed and stored
|
||||
|
||||
ldrneb r6, [r0] ; load source data
|
||||
strh r9, [r1], r3
|
||||
|
||||
ldrneb r7, [r0, #1]
|
||||
ldrneb r8, [r0, #2]
|
||||
|
||||
bne bil_width_loop_1st_v6
|
||||
|
||||
add r0, r0, r2 ; move to next input row
|
||||
subs r12, r12, #1
|
||||
|
||||
add r9, r2, r4, lsl #1 ; adding back block width
|
||||
pld [r0, r9] ; preload next row
|
||||
|
||||
add r11, r11, #2 ; move over to next column
|
||||
mov r1, r11
|
||||
|
||||
bne bil_height_loop_1st_v6
|
||||
|
||||
ldmia sp!, {r4 - r11, pc}
|
||||
|
||||
|bil_null_1st_filter|
|
||||
|bil_height_loop_null_1st|
|
||||
mov lr, r4, lsr #2 ; loop counter
|
||||
|
||||
|bil_width_loop_null_1st|
|
||||
ldrb r6, [r0] ; load data
|
||||
ldrb r7, [r0, #1]
|
||||
ldrb r8, [r0, #2]
|
||||
ldrb r9, [r0, #3]
|
||||
|
||||
strh r6, [r1], r3 ; store it to immediate buffer
|
||||
add r0, r0, #4
|
||||
strh r7, [r1], r3
|
||||
subs lr, lr, #1
|
||||
strh r8, [r1], r3
|
||||
strh r9, [r1], r3
|
||||
|
||||
bne bil_width_loop_null_1st
|
||||
|
||||
subs r12, r12, #1
|
||||
add r0, r0, r2 ; move to next input line
|
||||
add r11, r11, #2 ; move over to next column
|
||||
mov r1, r11
|
||||
|
||||
bne bil_height_loop_null_1st
|
||||
|
||||
ldmia sp!, {r4 - r11, pc}
|
||||
|
||||
ENDP ; |aom_filter_block2d_bil_first_pass_media|
|
||||
|
||||
|
||||
;---------------------------------
|
||||
; r0 unsigned short *src_ptr,
|
||||
; r1 unsigned char *dst_ptr,
|
||||
; r2 int dst_pitch,
|
||||
; r3 unsigned int height,
|
||||
; stack unsigned int width,
|
||||
; stack const short *aom_filter
|
||||
;---------------------------------
|
||||
|aom_filter_block2d_bil_second_pass_media| PROC
|
||||
stmdb sp!, {r4 - r11, lr}
|
||||
|
||||
ldr r11, [sp, #40] ; aom_filter address
|
||||
ldr r4, [sp, #36] ; width
|
||||
|
||||
ldr r5, [r11] ; load up filter coefficients
|
||||
mov r12, r4 ; outer-loop counter = width, since we work on transposed data matrix
|
||||
mov r11, r1
|
||||
|
||||
cmp r5, #128 ; if filter coef = 128, then skip the filter
|
||||
beq bil_null_2nd_filter
|
||||
|
||||
|bil_height_loop_2nd|
|
||||
ldr r6, [r0] ; load the data
|
||||
ldr r8, [r0, #4]
|
||||
ldrh r10, [r0, #8]
|
||||
mov lr, r3, lsr #2 ; loop counter
|
||||
|
||||
|bil_width_loop_2nd|
|
||||
pkhtb r7, r6, r8 ; src[1] | src[2]
|
||||
pkhtb r9, r8, r10 ; src[3] | src[4]
|
||||
|
||||
smuad r6, r6, r5 ; apply filter
|
||||
smuad r8, r8, r5 ; apply filter
|
||||
|
||||
subs lr, lr, #1
|
||||
|
||||
smuadx r7, r7, r5 ; apply filter
|
||||
smuadx r9, r9, r5 ; apply filter
|
||||
|
||||
add r0, r0, #8
|
||||
|
||||
add r6, r6, #0x40 ; round_shift_and_clamp
|
||||
add r7, r7, #0x40
|
||||
usat r6, #8, r6, asr #7
|
||||
usat r7, #8, r7, asr #7
|
||||
strb r6, [r1], r2 ; the result is transposed back and stored
|
||||
|
||||
add r8, r8, #0x40 ; round_shift_and_clamp
|
||||
strb r7, [r1], r2
|
||||
add r9, r9, #0x40
|
||||
usat r8, #8, r8, asr #7
|
||||
usat r9, #8, r9, asr #7
|
||||
strb r8, [r1], r2 ; the result is transposed back and stored
|
||||
|
||||
ldrne r6, [r0] ; load data
|
||||
strb r9, [r1], r2
|
||||
ldrne r8, [r0, #4]
|
||||
ldrneh r10, [r0, #8]
|
||||
|
||||
bne bil_width_loop_2nd
|
||||
|
||||
subs r12, r12, #1
|
||||
add r0, r0, #4 ; update src for next row
|
||||
add r11, r11, #1
|
||||
mov r1, r11
|
||||
|
||||
bne bil_height_loop_2nd
|
||||
ldmia sp!, {r4 - r11, pc}
|
||||
|
||||
|bil_null_2nd_filter|
|
||||
|bil_height_loop_null_2nd|
|
||||
mov lr, r3, lsr #2
|
||||
|
||||
|bil_width_loop_null_2nd|
|
||||
ldr r6, [r0], #4 ; load data
|
||||
subs lr, lr, #1
|
||||
ldr r8, [r0], #4
|
||||
|
||||
strb r6, [r1], r2 ; store data
|
||||
mov r7, r6, lsr #16
|
||||
strb r7, [r1], r2
|
||||
mov r9, r8, lsr #16
|
||||
strb r8, [r1], r2
|
||||
strb r9, [r1], r2
|
||||
|
||||
bne bil_width_loop_null_2nd
|
||||
|
||||
subs r12, r12, #1
|
||||
add r0, r0, #4
|
||||
add r11, r11, #1
|
||||
mov r1, r11
|
||||
|
||||
bne bil_height_loop_null_2nd
|
||||
|
||||
ldmia sp!, {r4 - r11, pc}
|
||||
ENDP ; |aom_filter_block2d_second_pass_media|
|
||||
|
||||
END
|
||||
@@ -1,199 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2016 The WebM project authors. All Rights Reserved.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license
|
||||
* that can be found in the LICENSE file in the root of the source
|
||||
* tree. An additional intellectual property rights grant can be found
|
||||
* in the file PATENTS. All contributing project authors may
|
||||
* be found in the AUTHORS file in the root of the source tree.
|
||||
*/
|
||||
|
||||
#include <arm_neon.h>
|
||||
|
||||
#include "./aom_dsp_rtcd.h"
|
||||
|
||||
static void hadamard8x8_one_pass(int16x8_t *a0, int16x8_t *a1, int16x8_t *a2,
|
||||
int16x8_t *a3, int16x8_t *a4, int16x8_t *a5,
|
||||
int16x8_t *a6, int16x8_t *a7) {
|
||||
const int16x8_t b0 = vaddq_s16(*a0, *a1);
|
||||
const int16x8_t b1 = vsubq_s16(*a0, *a1);
|
||||
const int16x8_t b2 = vaddq_s16(*a2, *a3);
|
||||
const int16x8_t b3 = vsubq_s16(*a2, *a3);
|
||||
const int16x8_t b4 = vaddq_s16(*a4, *a5);
|
||||
const int16x8_t b5 = vsubq_s16(*a4, *a5);
|
||||
const int16x8_t b6 = vaddq_s16(*a6, *a7);
|
||||
const int16x8_t b7 = vsubq_s16(*a6, *a7);
|
||||
|
||||
const int16x8_t c0 = vaddq_s16(b0, b2);
|
||||
const int16x8_t c1 = vaddq_s16(b1, b3);
|
||||
const int16x8_t c2 = vsubq_s16(b0, b2);
|
||||
const int16x8_t c3 = vsubq_s16(b1, b3);
|
||||
const int16x8_t c4 = vaddq_s16(b4, b6);
|
||||
const int16x8_t c5 = vaddq_s16(b5, b7);
|
||||
const int16x8_t c6 = vsubq_s16(b4, b6);
|
||||
const int16x8_t c7 = vsubq_s16(b5, b7);
|
||||
|
||||
*a0 = vaddq_s16(c0, c4);
|
||||
*a1 = vsubq_s16(c2, c6);
|
||||
*a2 = vsubq_s16(c0, c4);
|
||||
*a3 = vaddq_s16(c2, c6);
|
||||
*a4 = vaddq_s16(c3, c7);
|
||||
*a5 = vsubq_s16(c3, c7);
|
||||
*a6 = vsubq_s16(c1, c5);
|
||||
*a7 = vaddq_s16(c1, c5);
|
||||
}
|
||||
|
||||
// TODO(johannkoenig): Make a transpose library and dedup with idct. Consider
|
||||
// reversing transpose order which may make it easier for the compiler to
|
||||
// reconcile the vtrn.64 moves.
|
||||
static void transpose8x8(int16x8_t *a0, int16x8_t *a1, int16x8_t *a2,
|
||||
int16x8_t *a3, int16x8_t *a4, int16x8_t *a5,
|
||||
int16x8_t *a6, int16x8_t *a7) {
|
||||
// Swap 64 bit elements. Goes from:
|
||||
// a0: 00 01 02 03 04 05 06 07
|
||||
// a1: 08 09 10 11 12 13 14 15
|
||||
// a2: 16 17 18 19 20 21 22 23
|
||||
// a3: 24 25 26 27 28 29 30 31
|
||||
// a4: 32 33 34 35 36 37 38 39
|
||||
// a5: 40 41 42 43 44 45 46 47
|
||||
// a6: 48 49 50 51 52 53 54 55
|
||||
// a7: 56 57 58 59 60 61 62 63
|
||||
// to:
|
||||
// a04_lo: 00 01 02 03 32 33 34 35
|
||||
// a15_lo: 08 09 10 11 40 41 42 43
|
||||
// a26_lo: 16 17 18 19 48 49 50 51
|
||||
// a37_lo: 24 25 26 27 56 57 58 59
|
||||
// a04_hi: 04 05 06 07 36 37 38 39
|
||||
// a15_hi: 12 13 14 15 44 45 46 47
|
||||
// a26_hi: 20 21 22 23 52 53 54 55
|
||||
// a37_hi: 28 29 30 31 60 61 62 63
|
||||
const int16x8_t a04_lo = vcombine_s16(vget_low_s16(*a0), vget_low_s16(*a4));
|
||||
const int16x8_t a15_lo = vcombine_s16(vget_low_s16(*a1), vget_low_s16(*a5));
|
||||
const int16x8_t a26_lo = vcombine_s16(vget_low_s16(*a2), vget_low_s16(*a6));
|
||||
const int16x8_t a37_lo = vcombine_s16(vget_low_s16(*a3), vget_low_s16(*a7));
|
||||
const int16x8_t a04_hi = vcombine_s16(vget_high_s16(*a0), vget_high_s16(*a4));
|
||||
const int16x8_t a15_hi = vcombine_s16(vget_high_s16(*a1), vget_high_s16(*a5));
|
||||
const int16x8_t a26_hi = vcombine_s16(vget_high_s16(*a2), vget_high_s16(*a6));
|
||||
const int16x8_t a37_hi = vcombine_s16(vget_high_s16(*a3), vget_high_s16(*a7));
|
||||
|
||||
// Swap 32 bit elements resulting in:
|
||||
// a0246_lo:
|
||||
// 00 01 16 17 32 33 48 49
|
||||
// 02 03 18 19 34 35 50 51
|
||||
// a1357_lo:
|
||||
// 08 09 24 25 40 41 56 57
|
||||
// 10 11 26 27 42 43 58 59
|
||||
// a0246_hi:
|
||||
// 04 05 20 21 36 37 52 53
|
||||
// 06 07 22 23 38 39 54 55
|
||||
// a1657_hi:
|
||||
// 12 13 28 29 44 45 60 61
|
||||
// 14 15 30 31 46 47 62 63
|
||||
const int32x4x2_t a0246_lo =
|
||||
vtrnq_s32(vreinterpretq_s32_s16(a04_lo), vreinterpretq_s32_s16(a26_lo));
|
||||
const int32x4x2_t a1357_lo =
|
||||
vtrnq_s32(vreinterpretq_s32_s16(a15_lo), vreinterpretq_s32_s16(a37_lo));
|
||||
const int32x4x2_t a0246_hi =
|
||||
vtrnq_s32(vreinterpretq_s32_s16(a04_hi), vreinterpretq_s32_s16(a26_hi));
|
||||
const int32x4x2_t a1357_hi =
|
||||
vtrnq_s32(vreinterpretq_s32_s16(a15_hi), vreinterpretq_s32_s16(a37_hi));
|
||||
|
||||
// Swap 16 bit elements resulting in:
|
||||
// b0:
|
||||
// 00 08 16 24 32 40 48 56
|
||||
// 01 09 17 25 33 41 49 57
|
||||
// b1:
|
||||
// 02 10 18 26 34 42 50 58
|
||||
// 03 11 19 27 35 43 51 59
|
||||
// b2:
|
||||
// 04 12 20 28 36 44 52 60
|
||||
// 05 13 21 29 37 45 53 61
|
||||
// b3:
|
||||
// 06 14 22 30 38 46 54 62
|
||||
// 07 15 23 31 39 47 55 63
|
||||
const int16x8x2_t b0 = vtrnq_s16(vreinterpretq_s16_s32(a0246_lo.val[0]),
|
||||
vreinterpretq_s16_s32(a1357_lo.val[0]));
|
||||
const int16x8x2_t b1 = vtrnq_s16(vreinterpretq_s16_s32(a0246_lo.val[1]),
|
||||
vreinterpretq_s16_s32(a1357_lo.val[1]));
|
||||
const int16x8x2_t b2 = vtrnq_s16(vreinterpretq_s16_s32(a0246_hi.val[0]),
|
||||
vreinterpretq_s16_s32(a1357_hi.val[0]));
|
||||
const int16x8x2_t b3 = vtrnq_s16(vreinterpretq_s16_s32(a0246_hi.val[1]),
|
||||
vreinterpretq_s16_s32(a1357_hi.val[1]));
|
||||
|
||||
*a0 = b0.val[0];
|
||||
*a1 = b0.val[1];
|
||||
*a2 = b1.val[0];
|
||||
*a3 = b1.val[1];
|
||||
*a4 = b2.val[0];
|
||||
*a5 = b2.val[1];
|
||||
*a6 = b3.val[0];
|
||||
*a7 = b3.val[1];
|
||||
}
|
||||
|
||||
void aom_hadamard_8x8_neon(const int16_t *src_diff, int src_stride,
|
||||
int16_t *coeff) {
|
||||
int16x8_t a0 = vld1q_s16(src_diff);
|
||||
int16x8_t a1 = vld1q_s16(src_diff + src_stride);
|
||||
int16x8_t a2 = vld1q_s16(src_diff + 2 * src_stride);
|
||||
int16x8_t a3 = vld1q_s16(src_diff + 3 * src_stride);
|
||||
int16x8_t a4 = vld1q_s16(src_diff + 4 * src_stride);
|
||||
int16x8_t a5 = vld1q_s16(src_diff + 5 * src_stride);
|
||||
int16x8_t a6 = vld1q_s16(src_diff + 6 * src_stride);
|
||||
int16x8_t a7 = vld1q_s16(src_diff + 7 * src_stride);
|
||||
|
||||
hadamard8x8_one_pass(&a0, &a1, &a2, &a3, &a4, &a5, &a6, &a7);
|
||||
|
||||
transpose8x8(&a0, &a1, &a2, &a3, &a4, &a5, &a6, &a7);
|
||||
|
||||
hadamard8x8_one_pass(&a0, &a1, &a2, &a3, &a4, &a5, &a6, &a7);
|
||||
|
||||
// Skip the second transpose because it is not required.
|
||||
|
||||
vst1q_s16(coeff + 0, a0);
|
||||
vst1q_s16(coeff + 8, a1);
|
||||
vst1q_s16(coeff + 16, a2);
|
||||
vst1q_s16(coeff + 24, a3);
|
||||
vst1q_s16(coeff + 32, a4);
|
||||
vst1q_s16(coeff + 40, a5);
|
||||
vst1q_s16(coeff + 48, a6);
|
||||
vst1q_s16(coeff + 56, a7);
|
||||
}
|
||||
|
||||
void aom_hadamard_16x16_neon(const int16_t *src_diff, int src_stride,
|
||||
int16_t *coeff) {
|
||||
int i;
|
||||
|
||||
/* Rearrange 16x16 to 8x32 and remove stride.
|
||||
* Top left first. */
|
||||
aom_hadamard_8x8_neon(src_diff + 0 + 0 * src_stride, src_stride, coeff + 0);
|
||||
/* Top right. */
|
||||
aom_hadamard_8x8_neon(src_diff + 8 + 0 * src_stride, src_stride, coeff + 64);
|
||||
/* Bottom left. */
|
||||
aom_hadamard_8x8_neon(src_diff + 0 + 8 * src_stride, src_stride, coeff + 128);
|
||||
/* Bottom right. */
|
||||
aom_hadamard_8x8_neon(src_diff + 8 + 8 * src_stride, src_stride, coeff + 192);
|
||||
|
||||
for (i = 0; i < 64; i += 8) {
|
||||
const int16x8_t a0 = vld1q_s16(coeff + 0);
|
||||
const int16x8_t a1 = vld1q_s16(coeff + 64);
|
||||
const int16x8_t a2 = vld1q_s16(coeff + 128);
|
||||
const int16x8_t a3 = vld1q_s16(coeff + 192);
|
||||
|
||||
const int16x8_t b0 = vhaddq_s16(a0, a1);
|
||||
const int16x8_t b1 = vhsubq_s16(a0, a1);
|
||||
const int16x8_t b2 = vhaddq_s16(a2, a3);
|
||||
const int16x8_t b3 = vhsubq_s16(a2, a3);
|
||||
|
||||
const int16x8_t c0 = vaddq_s16(b0, b2);
|
||||
const int16x8_t c1 = vaddq_s16(b1, b3);
|
||||
const int16x8_t c2 = vsubq_s16(b0, b2);
|
||||
const int16x8_t c3 = vsubq_s16(b1, b3);
|
||||
|
||||
vst1q_s16(coeff + 0, c0);
|
||||
vst1q_s16(coeff + 64, c1);
|
||||
vst1q_s16(coeff + 128, c2);
|
||||
vst1q_s16(coeff + 192, c3);
|
||||
|
||||
coeff += 8;
|
||||
}
|
||||
}
|
||||
@@ -1,59 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2016, Alliance for Open Media. All rights reserved
|
||||
*
|
||||
* This source code is subject to the terms of the BSD 2 Clause License and
|
||||
* the Alliance for Open Media Patent License 1.0. If the BSD 2 Clause License
|
||||
* was not distributed with this source code in the LICENSE file, you can
|
||||
* obtain it at www.aomedia.org/license/software. If the Alliance for Open
|
||||
* Media Patent License 1.0 was not distributed with this source code in the
|
||||
* PATENTS file, you can obtain it at www.aomedia.org/license/patent.
|
||||
*/
|
||||
|
||||
#include <arm_neon.h>
|
||||
|
||||
#include "aom_dsp/inv_txfm.h"
|
||||
#include "aom_ports/mem.h"
|
||||
|
||||
void aom_idct16x16_1_add_neon(int16_t *input, uint8_t *dest, int dest_stride) {
|
||||
uint8x8_t d2u8, d3u8, d30u8, d31u8;
|
||||
uint64x1_t d2u64, d3u64, d4u64, d5u64;
|
||||
uint16x8_t q0u16, q9u16, q10u16, q11u16, q12u16;
|
||||
int16x8_t q0s16;
|
||||
uint8_t *d1, *d2;
|
||||
int16_t i, j, a1;
|
||||
int16_t out = dct_const_round_shift(input[0] * cospi_16_64);
|
||||
out = dct_const_round_shift(out * cospi_16_64);
|
||||
a1 = ROUND_POWER_OF_TWO(out, 6);
|
||||
|
||||
q0s16 = vdupq_n_s16(a1);
|
||||
q0u16 = vreinterpretq_u16_s16(q0s16);
|
||||
|
||||
for (d1 = d2 = dest, i = 0; i < 4; i++) {
|
||||
for (j = 0; j < 2; j++) {
|
||||
d2u64 = vld1_u64((const uint64_t *)d1);
|
||||
d3u64 = vld1_u64((const uint64_t *)(d1 + 8));
|
||||
d1 += dest_stride;
|
||||
d4u64 = vld1_u64((const uint64_t *)d1);
|
||||
d5u64 = vld1_u64((const uint64_t *)(d1 + 8));
|
||||
d1 += dest_stride;
|
||||
|
||||
q9u16 = vaddw_u8(q0u16, vreinterpret_u8_u64(d2u64));
|
||||
q10u16 = vaddw_u8(q0u16, vreinterpret_u8_u64(d3u64));
|
||||
q11u16 = vaddw_u8(q0u16, vreinterpret_u8_u64(d4u64));
|
||||
q12u16 = vaddw_u8(q0u16, vreinterpret_u8_u64(d5u64));
|
||||
|
||||
d2u8 = vqmovun_s16(vreinterpretq_s16_u16(q9u16));
|
||||
d3u8 = vqmovun_s16(vreinterpretq_s16_u16(q10u16));
|
||||
d30u8 = vqmovun_s16(vreinterpretq_s16_u16(q11u16));
|
||||
d31u8 = vqmovun_s16(vreinterpretq_s16_u16(q12u16));
|
||||
|
||||
vst1_u64((uint64_t *)d2, vreinterpret_u64_u8(d2u8));
|
||||
vst1_u64((uint64_t *)(d2 + 8), vreinterpret_u64_u8(d3u8));
|
||||
d2 += dest_stride;
|
||||
vst1_u64((uint64_t *)d2, vreinterpret_u64_u8(d30u8));
|
||||
vst1_u64((uint64_t *)(d2 + 8), vreinterpret_u64_u8(d31u8));
|
||||
d2 += dest_stride;
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
@@ -1,147 +0,0 @@
|
||||
;
|
||||
; Copyright (c) 2016, Alliance for Open Media. All rights reserved
|
||||
;
|
||||
; This source code is subject to the terms of the BSD 2 Clause License and
|
||||
; the Alliance for Open Media Patent License 1.0. If the BSD 2 Clause License
|
||||
; was not distributed with this source code in the LICENSE file, you can
|
||||
; obtain it at www.aomedia.org/license/software. If the Alliance for Open
|
||||
; Media Patent License 1.0 was not distributed with this source code in the
|
||||
; PATENTS file, you can obtain it at www.aomedia.org/license/patent.
|
||||
;
|
||||
|
||||
|
||||
EXPORT |aom_idct32x32_1_add_neon|
|
||||
ARM
|
||||
REQUIRE8
|
||||
PRESERVE8
|
||||
|
||||
AREA ||.text||, CODE, READONLY, ALIGN=2
|
||||
|
||||
;TODO(hkuang): put the following macros in a seperate
|
||||
;file so other idct function could also use them.
|
||||
MACRO
|
||||
LD_16x8 $src, $stride
|
||||
vld1.8 {q8}, [$src], $stride
|
||||
vld1.8 {q9}, [$src], $stride
|
||||
vld1.8 {q10}, [$src], $stride
|
||||
vld1.8 {q11}, [$src], $stride
|
||||
vld1.8 {q12}, [$src], $stride
|
||||
vld1.8 {q13}, [$src], $stride
|
||||
vld1.8 {q14}, [$src], $stride
|
||||
vld1.8 {q15}, [$src], $stride
|
||||
MEND
|
||||
|
||||
MACRO
|
||||
ADD_DIFF_16x8 $diff
|
||||
vqadd.u8 q8, q8, $diff
|
||||
vqadd.u8 q9, q9, $diff
|
||||
vqadd.u8 q10, q10, $diff
|
||||
vqadd.u8 q11, q11, $diff
|
||||
vqadd.u8 q12, q12, $diff
|
||||
vqadd.u8 q13, q13, $diff
|
||||
vqadd.u8 q14, q14, $diff
|
||||
vqadd.u8 q15, q15, $diff
|
||||
MEND
|
||||
|
||||
MACRO
|
||||
SUB_DIFF_16x8 $diff
|
||||
vqsub.u8 q8, q8, $diff
|
||||
vqsub.u8 q9, q9, $diff
|
||||
vqsub.u8 q10, q10, $diff
|
||||
vqsub.u8 q11, q11, $diff
|
||||
vqsub.u8 q12, q12, $diff
|
||||
vqsub.u8 q13, q13, $diff
|
||||
vqsub.u8 q14, q14, $diff
|
||||
vqsub.u8 q15, q15, $diff
|
||||
MEND
|
||||
|
||||
MACRO
|
||||
ST_16x8 $dst, $stride
|
||||
vst1.8 {q8}, [$dst], $stride
|
||||
vst1.8 {q9}, [$dst], $stride
|
||||
vst1.8 {q10},[$dst], $stride
|
||||
vst1.8 {q11},[$dst], $stride
|
||||
vst1.8 {q12},[$dst], $stride
|
||||
vst1.8 {q13},[$dst], $stride
|
||||
vst1.8 {q14},[$dst], $stride
|
||||
vst1.8 {q15},[$dst], $stride
|
||||
MEND
|
||||
|
||||
;void aom_idct32x32_1_add_neon(int16_t *input, uint8_t *dest,
|
||||
; int dest_stride)
|
||||
;
|
||||
; r0 int16_t input
|
||||
; r1 uint8_t *dest
|
||||
; r2 int dest_stride
|
||||
|
||||
|aom_idct32x32_1_add_neon| PROC
|
||||
push {lr}
|
||||
pld [r1]
|
||||
add r3, r1, #16 ; r3 dest + 16 for second loop
|
||||
ldrsh r0, [r0]
|
||||
|
||||
; generate cospi_16_64 = 11585
|
||||
mov r12, #0x2d00
|
||||
add r12, #0x41
|
||||
|
||||
; out = dct_const_round_shift(input[0] * cospi_16_64)
|
||||
mul r0, r0, r12 ; input[0] * cospi_16_64
|
||||
add r0, r0, #0x2000 ; +(1 << ((DCT_CONST_BITS) - 1))
|
||||
asr r0, r0, #14 ; >> DCT_CONST_BITS
|
||||
|
||||
; out = dct_const_round_shift(out * cospi_16_64)
|
||||
mul r0, r0, r12 ; out * cospi_16_64
|
||||
mov r12, r1 ; save dest
|
||||
add r0, r0, #0x2000 ; +(1 << ((DCT_CONST_BITS) - 1))
|
||||
asr r0, r0, #14 ; >> DCT_CONST_BITS
|
||||
|
||||
; a1 = ROUND_POWER_OF_TWO(out, 6)
|
||||
add r0, r0, #32 ; + (1 <<((6) - 1))
|
||||
asrs r0, r0, #6 ; >> 6
|
||||
bge diff_positive_32_32
|
||||
|
||||
diff_negative_32_32
|
||||
neg r0, r0
|
||||
usat r0, #8, r0
|
||||
vdup.u8 q0, r0
|
||||
mov r0, #4
|
||||
|
||||
diff_negative_32_32_loop
|
||||
sub r0, #1
|
||||
LD_16x8 r1, r2
|
||||
SUB_DIFF_16x8 q0
|
||||
ST_16x8 r12, r2
|
||||
|
||||
LD_16x8 r1, r2
|
||||
SUB_DIFF_16x8 q0
|
||||
ST_16x8 r12, r2
|
||||
cmp r0, #2
|
||||
moveq r1, r3
|
||||
moveq r12, r3
|
||||
cmp r0, #0
|
||||
bne diff_negative_32_32_loop
|
||||
pop {pc}
|
||||
|
||||
diff_positive_32_32
|
||||
usat r0, #8, r0
|
||||
vdup.u8 q0, r0
|
||||
mov r0, #4
|
||||
|
||||
diff_positive_32_32_loop
|
||||
sub r0, #1
|
||||
LD_16x8 r1, r2
|
||||
ADD_DIFF_16x8 q0
|
||||
ST_16x8 r12, r2
|
||||
|
||||
LD_16x8 r1, r2
|
||||
ADD_DIFF_16x8 q0
|
||||
ST_16x8 r12, r2
|
||||
cmp r0, #2
|
||||
moveq r1, r3
|
||||
moveq r12, r3
|
||||
cmp r0, #0
|
||||
bne diff_positive_32_32_loop
|
||||
pop {pc}
|
||||
|
||||
ENDP ; |aom_idct32x32_1_add_neon|
|
||||
END
|
||||
@@ -1,141 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2016, Alliance for Open Media. All rights reserved
|
||||
*
|
||||
* This source code is subject to the terms of the BSD 2 Clause License and
|
||||
* the Alliance for Open Media Patent License 1.0. If the BSD 2 Clause License
|
||||
* was not distributed with this source code in the LICENSE file, you can
|
||||
* obtain it at www.aomedia.org/license/software. If the Alliance for Open
|
||||
* Media Patent License 1.0 was not distributed with this source code in the
|
||||
* PATENTS file, you can obtain it at www.aomedia.org/license/patent.
|
||||
*/
|
||||
|
||||
#include <arm_neon.h>
|
||||
|
||||
#include "./aom_config.h"
|
||||
|
||||
#include "aom_dsp/inv_txfm.h"
|
||||
#include "aom_ports/mem.h"
|
||||
|
||||
static INLINE void LD_16x8(uint8_t *d, int d_stride, uint8x16_t *q8u8,
|
||||
uint8x16_t *q9u8, uint8x16_t *q10u8,
|
||||
uint8x16_t *q11u8, uint8x16_t *q12u8,
|
||||
uint8x16_t *q13u8, uint8x16_t *q14u8,
|
||||
uint8x16_t *q15u8) {
|
||||
*q8u8 = vld1q_u8(d);
|
||||
d += d_stride;
|
||||
*q9u8 = vld1q_u8(d);
|
||||
d += d_stride;
|
||||
*q10u8 = vld1q_u8(d);
|
||||
d += d_stride;
|
||||
*q11u8 = vld1q_u8(d);
|
||||
d += d_stride;
|
||||
*q12u8 = vld1q_u8(d);
|
||||
d += d_stride;
|
||||
*q13u8 = vld1q_u8(d);
|
||||
d += d_stride;
|
||||
*q14u8 = vld1q_u8(d);
|
||||
d += d_stride;
|
||||
*q15u8 = vld1q_u8(d);
|
||||
return;
|
||||
}
|
||||
|
||||
static INLINE void ADD_DIFF_16x8(uint8x16_t qdiffu8, uint8x16_t *q8u8,
|
||||
uint8x16_t *q9u8, uint8x16_t *q10u8,
|
||||
uint8x16_t *q11u8, uint8x16_t *q12u8,
|
||||
uint8x16_t *q13u8, uint8x16_t *q14u8,
|
||||
uint8x16_t *q15u8) {
|
||||
*q8u8 = vqaddq_u8(*q8u8, qdiffu8);
|
||||
*q9u8 = vqaddq_u8(*q9u8, qdiffu8);
|
||||
*q10u8 = vqaddq_u8(*q10u8, qdiffu8);
|
||||
*q11u8 = vqaddq_u8(*q11u8, qdiffu8);
|
||||
*q12u8 = vqaddq_u8(*q12u8, qdiffu8);
|
||||
*q13u8 = vqaddq_u8(*q13u8, qdiffu8);
|
||||
*q14u8 = vqaddq_u8(*q14u8, qdiffu8);
|
||||
*q15u8 = vqaddq_u8(*q15u8, qdiffu8);
|
||||
return;
|
||||
}
|
||||
|
||||
static INLINE void SUB_DIFF_16x8(uint8x16_t qdiffu8, uint8x16_t *q8u8,
|
||||
uint8x16_t *q9u8, uint8x16_t *q10u8,
|
||||
uint8x16_t *q11u8, uint8x16_t *q12u8,
|
||||
uint8x16_t *q13u8, uint8x16_t *q14u8,
|
||||
uint8x16_t *q15u8) {
|
||||
*q8u8 = vqsubq_u8(*q8u8, qdiffu8);
|
||||
*q9u8 = vqsubq_u8(*q9u8, qdiffu8);
|
||||
*q10u8 = vqsubq_u8(*q10u8, qdiffu8);
|
||||
*q11u8 = vqsubq_u8(*q11u8, qdiffu8);
|
||||
*q12u8 = vqsubq_u8(*q12u8, qdiffu8);
|
||||
*q13u8 = vqsubq_u8(*q13u8, qdiffu8);
|
||||
*q14u8 = vqsubq_u8(*q14u8, qdiffu8);
|
||||
*q15u8 = vqsubq_u8(*q15u8, qdiffu8);
|
||||
return;
|
||||
}
|
||||
|
||||
static INLINE void ST_16x8(uint8_t *d, int d_stride, uint8x16_t *q8u8,
|
||||
uint8x16_t *q9u8, uint8x16_t *q10u8,
|
||||
uint8x16_t *q11u8, uint8x16_t *q12u8,
|
||||
uint8x16_t *q13u8, uint8x16_t *q14u8,
|
||||
uint8x16_t *q15u8) {
|
||||
vst1q_u8(d, *q8u8);
|
||||
d += d_stride;
|
||||
vst1q_u8(d, *q9u8);
|
||||
d += d_stride;
|
||||
vst1q_u8(d, *q10u8);
|
||||
d += d_stride;
|
||||
vst1q_u8(d, *q11u8);
|
||||
d += d_stride;
|
||||
vst1q_u8(d, *q12u8);
|
||||
d += d_stride;
|
||||
vst1q_u8(d, *q13u8);
|
||||
d += d_stride;
|
||||
vst1q_u8(d, *q14u8);
|
||||
d += d_stride;
|
||||
vst1q_u8(d, *q15u8);
|
||||
return;
|
||||
}
|
||||
|
||||
void aom_idct32x32_1_add_neon(int16_t *input, uint8_t *dest, int dest_stride) {
|
||||
uint8x16_t q0u8, q8u8, q9u8, q10u8, q11u8, q12u8, q13u8, q14u8, q15u8;
|
||||
int i, j, dest_stride8;
|
||||
uint8_t *d;
|
||||
int16_t a1;
|
||||
int16_t out = dct_const_round_shift(input[0] * cospi_16_64);
|
||||
|
||||
out = dct_const_round_shift(out * cospi_16_64);
|
||||
a1 = ROUND_POWER_OF_TWO(out, 6);
|
||||
|
||||
dest_stride8 = dest_stride * 8;
|
||||
if (a1 >= 0) { // diff_positive_32_32
|
||||
a1 = a1 < 0 ? 0 : a1 > 255 ? 255 : a1;
|
||||
q0u8 = vdupq_n_u8(a1);
|
||||
for (i = 0; i < 2; i++, dest += 16) { // diff_positive_32_32_loop
|
||||
d = dest;
|
||||
for (j = 0; j < 4; j++) {
|
||||
LD_16x8(d, dest_stride, &q8u8, &q9u8, &q10u8, &q11u8, &q12u8, &q13u8,
|
||||
&q14u8, &q15u8);
|
||||
ADD_DIFF_16x8(q0u8, &q8u8, &q9u8, &q10u8, &q11u8, &q12u8, &q13u8,
|
||||
&q14u8, &q15u8);
|
||||
ST_16x8(d, dest_stride, &q8u8, &q9u8, &q10u8, &q11u8, &q12u8, &q13u8,
|
||||
&q14u8, &q15u8);
|
||||
d += dest_stride8;
|
||||
}
|
||||
}
|
||||
} else { // diff_negative_32_32
|
||||
a1 = -a1;
|
||||
a1 = a1 < 0 ? 0 : a1 > 255 ? 255 : a1;
|
||||
q0u8 = vdupq_n_u8(a1);
|
||||
for (i = 0; i < 2; i++, dest += 16) { // diff_negative_32_32_loop
|
||||
d = dest;
|
||||
for (j = 0; j < 4; j++) {
|
||||
LD_16x8(d, dest_stride, &q8u8, &q9u8, &q10u8, &q11u8, &q12u8, &q13u8,
|
||||
&q14u8, &q15u8);
|
||||
SUB_DIFF_16x8(q0u8, &q8u8, &q9u8, &q10u8, &q11u8, &q12u8, &q13u8,
|
||||
&q14u8, &q15u8);
|
||||
ST_16x8(d, dest_stride, &q8u8, &q9u8, &q10u8, &q11u8, &q12u8, &q13u8,
|
||||
&q14u8, &q15u8);
|
||||
d += dest_stride8;
|
||||
}
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,47 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2016, Alliance for Open Media. All rights reserved
|
||||
*
|
||||
* This source code is subject to the terms of the BSD 2 Clause License and
|
||||
* the Alliance for Open Media Patent License 1.0. If the BSD 2 Clause License
|
||||
* was not distributed with this source code in the LICENSE file, you can
|
||||
* obtain it at www.aomedia.org/license/software. If the Alliance for Open
|
||||
* Media Patent License 1.0 was not distributed with this source code in the
|
||||
* PATENTS file, you can obtain it at www.aomedia.org/license/patent.
|
||||
*/
|
||||
|
||||
#include <arm_neon.h>
|
||||
|
||||
#include "aom_dsp/inv_txfm.h"
|
||||
#include "aom_ports/mem.h"
|
||||
|
||||
void aom_idct4x4_1_add_neon(int16_t *input, uint8_t *dest, int dest_stride) {
|
||||
uint8x8_t d6u8;
|
||||
uint32x2_t d2u32 = vdup_n_u32(0);
|
||||
uint16x8_t q8u16;
|
||||
int16x8_t q0s16;
|
||||
uint8_t *d1, *d2;
|
||||
int16_t i, a1;
|
||||
int16_t out = dct_const_round_shift(input[0] * cospi_16_64);
|
||||
out = dct_const_round_shift(out * cospi_16_64);
|
||||
a1 = ROUND_POWER_OF_TWO(out, 4);
|
||||
|
||||
q0s16 = vdupq_n_s16(a1);
|
||||
|
||||
// dc_only_idct_add
|
||||
d1 = d2 = dest;
|
||||
for (i = 0; i < 2; i++) {
|
||||
d2u32 = vld1_lane_u32((const uint32_t *)d1, d2u32, 0);
|
||||
d1 += dest_stride;
|
||||
d2u32 = vld1_lane_u32((const uint32_t *)d1, d2u32, 1);
|
||||
d1 += dest_stride;
|
||||
|
||||
q8u16 = vaddw_u8(vreinterpretq_u16_s16(q0s16), vreinterpret_u8_u32(d2u32));
|
||||
d6u8 = vqmovun_s16(vreinterpretq_s16_u16(q8u16));
|
||||
|
||||
vst1_lane_u32((uint32_t *)d2, vreinterpret_u32_u8(d6u8), 0);
|
||||
d2 += dest_stride;
|
||||
vst1_lane_u32((uint32_t *)d2, vreinterpret_u32_u8(d6u8), 1);
|
||||
d2 += dest_stride;
|
||||
}
|
||||
return;
|
||||
}
|
||||
@@ -1,146 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2016, Alliance for Open Media. All rights reserved
|
||||
*
|
||||
* This source code is subject to the terms of the BSD 2 Clause License and
|
||||
* the Alliance for Open Media Patent License 1.0. If the BSD 2 Clause License
|
||||
* was not distributed with this source code in the LICENSE file, you can
|
||||
* obtain it at www.aomedia.org/license/software. If the Alliance for Open
|
||||
* Media Patent License 1.0 was not distributed with this source code in the
|
||||
* PATENTS file, you can obtain it at www.aomedia.org/license/patent.
|
||||
*/
|
||||
|
||||
#include <arm_neon.h>
|
||||
|
||||
#include "aom_dsp/txfm_common.h"
|
||||
|
||||
void aom_idct4x4_16_add_neon(int16_t *input, uint8_t *dest, int dest_stride) {
|
||||
uint8x8_t d26u8, d27u8;
|
||||
uint32x2_t d26u32, d27u32;
|
||||
uint16x8_t q8u16, q9u16;
|
||||
int16x4_t d16s16, d17s16, d18s16, d19s16, d20s16, d21s16;
|
||||
int16x4_t d22s16, d23s16, d24s16, d26s16, d27s16, d28s16, d29s16;
|
||||
int16x8_t q8s16, q9s16, q13s16, q14s16;
|
||||
int32x4_t q1s32, q13s32, q14s32, q15s32;
|
||||
int16x4x2_t d0x2s16, d1x2s16;
|
||||
int32x4x2_t q0x2s32;
|
||||
uint8_t *d;
|
||||
|
||||
d26u32 = d27u32 = vdup_n_u32(0);
|
||||
|
||||
q8s16 = vld1q_s16(input);
|
||||
q9s16 = vld1q_s16(input + 8);
|
||||
|
||||
d16s16 = vget_low_s16(q8s16);
|
||||
d17s16 = vget_high_s16(q8s16);
|
||||
d18s16 = vget_low_s16(q9s16);
|
||||
d19s16 = vget_high_s16(q9s16);
|
||||
|
||||
d0x2s16 = vtrn_s16(d16s16, d17s16);
|
||||
d1x2s16 = vtrn_s16(d18s16, d19s16);
|
||||
q8s16 = vcombine_s16(d0x2s16.val[0], d0x2s16.val[1]);
|
||||
q9s16 = vcombine_s16(d1x2s16.val[0], d1x2s16.val[1]);
|
||||
|
||||
d20s16 = vdup_n_s16((int16_t)cospi_8_64);
|
||||
d21s16 = vdup_n_s16((int16_t)cospi_16_64);
|
||||
|
||||
q0x2s32 =
|
||||
vtrnq_s32(vreinterpretq_s32_s16(q8s16), vreinterpretq_s32_s16(q9s16));
|
||||
d16s16 = vget_low_s16(vreinterpretq_s16_s32(q0x2s32.val[0]));
|
||||
d17s16 = vget_high_s16(vreinterpretq_s16_s32(q0x2s32.val[0]));
|
||||
d18s16 = vget_low_s16(vreinterpretq_s16_s32(q0x2s32.val[1]));
|
||||
d19s16 = vget_high_s16(vreinterpretq_s16_s32(q0x2s32.val[1]));
|
||||
|
||||
d22s16 = vdup_n_s16((int16_t)cospi_24_64);
|
||||
|
||||
// stage 1
|
||||
d23s16 = vadd_s16(d16s16, d18s16);
|
||||
d24s16 = vsub_s16(d16s16, d18s16);
|
||||
|
||||
q15s32 = vmull_s16(d17s16, d22s16);
|
||||
q1s32 = vmull_s16(d17s16, d20s16);
|
||||
q13s32 = vmull_s16(d23s16, d21s16);
|
||||
q14s32 = vmull_s16(d24s16, d21s16);
|
||||
|
||||
q15s32 = vmlsl_s16(q15s32, d19s16, d20s16);
|
||||
q1s32 = vmlal_s16(q1s32, d19s16, d22s16);
|
||||
|
||||
d26s16 = vqrshrn_n_s32(q13s32, 14);
|
||||
d27s16 = vqrshrn_n_s32(q14s32, 14);
|
||||
d29s16 = vqrshrn_n_s32(q15s32, 14);
|
||||
d28s16 = vqrshrn_n_s32(q1s32, 14);
|
||||
q13s16 = vcombine_s16(d26s16, d27s16);
|
||||
q14s16 = vcombine_s16(d28s16, d29s16);
|
||||
|
||||
// stage 2
|
||||
q8s16 = vaddq_s16(q13s16, q14s16);
|
||||
q9s16 = vsubq_s16(q13s16, q14s16);
|
||||
|
||||
d16s16 = vget_low_s16(q8s16);
|
||||
d17s16 = vget_high_s16(q8s16);
|
||||
d18s16 = vget_high_s16(q9s16); // vswp d18 d19
|
||||
d19s16 = vget_low_s16(q9s16);
|
||||
|
||||
d0x2s16 = vtrn_s16(d16s16, d17s16);
|
||||
d1x2s16 = vtrn_s16(d18s16, d19s16);
|
||||
q8s16 = vcombine_s16(d0x2s16.val[0], d0x2s16.val[1]);
|
||||
q9s16 = vcombine_s16(d1x2s16.val[0], d1x2s16.val[1]);
|
||||
|
||||
q0x2s32 =
|
||||
vtrnq_s32(vreinterpretq_s32_s16(q8s16), vreinterpretq_s32_s16(q9s16));
|
||||
d16s16 = vget_low_s16(vreinterpretq_s16_s32(q0x2s32.val[0]));
|
||||
d17s16 = vget_high_s16(vreinterpretq_s16_s32(q0x2s32.val[0]));
|
||||
d18s16 = vget_low_s16(vreinterpretq_s16_s32(q0x2s32.val[1]));
|
||||
d19s16 = vget_high_s16(vreinterpretq_s16_s32(q0x2s32.val[1]));
|
||||
|
||||
// do the transform on columns
|
||||
// stage 1
|
||||
d23s16 = vadd_s16(d16s16, d18s16);
|
||||
d24s16 = vsub_s16(d16s16, d18s16);
|
||||
|
||||
q15s32 = vmull_s16(d17s16, d22s16);
|
||||
q1s32 = vmull_s16(d17s16, d20s16);
|
||||
q13s32 = vmull_s16(d23s16, d21s16);
|
||||
q14s32 = vmull_s16(d24s16, d21s16);
|
||||
|
||||
q15s32 = vmlsl_s16(q15s32, d19s16, d20s16);
|
||||
q1s32 = vmlal_s16(q1s32, d19s16, d22s16);
|
||||
|
||||
d26s16 = vqrshrn_n_s32(q13s32, 14);
|
||||
d27s16 = vqrshrn_n_s32(q14s32, 14);
|
||||
d29s16 = vqrshrn_n_s32(q15s32, 14);
|
||||
d28s16 = vqrshrn_n_s32(q1s32, 14);
|
||||
q13s16 = vcombine_s16(d26s16, d27s16);
|
||||
q14s16 = vcombine_s16(d28s16, d29s16);
|
||||
|
||||
// stage 2
|
||||
q8s16 = vaddq_s16(q13s16, q14s16);
|
||||
q9s16 = vsubq_s16(q13s16, q14s16);
|
||||
|
||||
q8s16 = vrshrq_n_s16(q8s16, 4);
|
||||
q9s16 = vrshrq_n_s16(q9s16, 4);
|
||||
|
||||
d = dest;
|
||||
d26u32 = vld1_lane_u32((const uint32_t *)d, d26u32, 0);
|
||||
d += dest_stride;
|
||||
d26u32 = vld1_lane_u32((const uint32_t *)d, d26u32, 1);
|
||||
d += dest_stride;
|
||||
d27u32 = vld1_lane_u32((const uint32_t *)d, d27u32, 1);
|
||||
d += dest_stride;
|
||||
d27u32 = vld1_lane_u32((const uint32_t *)d, d27u32, 0);
|
||||
|
||||
q8u16 = vaddw_u8(vreinterpretq_u16_s16(q8s16), vreinterpret_u8_u32(d26u32));
|
||||
q9u16 = vaddw_u8(vreinterpretq_u16_s16(q9s16), vreinterpret_u8_u32(d27u32));
|
||||
|
||||
d26u8 = vqmovun_s16(vreinterpretq_s16_u16(q8u16));
|
||||
d27u8 = vqmovun_s16(vreinterpretq_s16_u16(q9u16));
|
||||
|
||||
d = dest;
|
||||
vst1_lane_u32((uint32_t *)d, vreinterpret_u32_u8(d26u8), 0);
|
||||
d += dest_stride;
|
||||
vst1_lane_u32((uint32_t *)d, vreinterpret_u32_u8(d26u8), 1);
|
||||
d += dest_stride;
|
||||
vst1_lane_u32((uint32_t *)d, vreinterpret_u32_u8(d27u8), 1);
|
||||
d += dest_stride;
|
||||
vst1_lane_u32((uint32_t *)d, vreinterpret_u32_u8(d27u8), 0);
|
||||
return;
|
||||
}
|
||||
@@ -1,62 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2016, Alliance for Open Media. All rights reserved
|
||||
*
|
||||
* This source code is subject to the terms of the BSD 2 Clause License and
|
||||
* the Alliance for Open Media Patent License 1.0. If the BSD 2 Clause License
|
||||
* was not distributed with this source code in the LICENSE file, you can
|
||||
* obtain it at www.aomedia.org/license/software. If the Alliance for Open
|
||||
* Media Patent License 1.0 was not distributed with this source code in the
|
||||
* PATENTS file, you can obtain it at www.aomedia.org/license/patent.
|
||||
*/
|
||||
|
||||
#include <arm_neon.h>
|
||||
|
||||
#include "aom_dsp/inv_txfm.h"
|
||||
#include "aom_ports/mem.h"
|
||||
|
||||
void aom_idct8x8_1_add_neon(int16_t *input, uint8_t *dest, int dest_stride) {
|
||||
uint8x8_t d2u8, d3u8, d30u8, d31u8;
|
||||
uint64x1_t d2u64, d3u64, d4u64, d5u64;
|
||||
uint16x8_t q0u16, q9u16, q10u16, q11u16, q12u16;
|
||||
int16x8_t q0s16;
|
||||
uint8_t *d1, *d2;
|
||||
int16_t i, a1;
|
||||
int16_t out = dct_const_round_shift(input[0] * cospi_16_64);
|
||||
out = dct_const_round_shift(out * cospi_16_64);
|
||||
a1 = ROUND_POWER_OF_TWO(out, 5);
|
||||
|
||||
q0s16 = vdupq_n_s16(a1);
|
||||
q0u16 = vreinterpretq_u16_s16(q0s16);
|
||||
|
||||
d1 = d2 = dest;
|
||||
for (i = 0; i < 2; i++) {
|
||||
d2u64 = vld1_u64((const uint64_t *)d1);
|
||||
d1 += dest_stride;
|
||||
d3u64 = vld1_u64((const uint64_t *)d1);
|
||||
d1 += dest_stride;
|
||||
d4u64 = vld1_u64((const uint64_t *)d1);
|
||||
d1 += dest_stride;
|
||||
d5u64 = vld1_u64((const uint64_t *)d1);
|
||||
d1 += dest_stride;
|
||||
|
||||
q9u16 = vaddw_u8(q0u16, vreinterpret_u8_u64(d2u64));
|
||||
q10u16 = vaddw_u8(q0u16, vreinterpret_u8_u64(d3u64));
|
||||
q11u16 = vaddw_u8(q0u16, vreinterpret_u8_u64(d4u64));
|
||||
q12u16 = vaddw_u8(q0u16, vreinterpret_u8_u64(d5u64));
|
||||
|
||||
d2u8 = vqmovun_s16(vreinterpretq_s16_u16(q9u16));
|
||||
d3u8 = vqmovun_s16(vreinterpretq_s16_u16(q10u16));
|
||||
d30u8 = vqmovun_s16(vreinterpretq_s16_u16(q11u16));
|
||||
d31u8 = vqmovun_s16(vreinterpretq_s16_u16(q12u16));
|
||||
|
||||
vst1_u64((uint64_t *)d2, vreinterpret_u64_u8(d2u8));
|
||||
d2 += dest_stride;
|
||||
vst1_u64((uint64_t *)d2, vreinterpret_u64_u8(d3u8));
|
||||
d2 += dest_stride;
|
||||
vst1_u64((uint64_t *)d2, vreinterpret_u64_u8(d30u8));
|
||||
d2 += dest_stride;
|
||||
vst1_u64((uint64_t *)d2, vreinterpret_u64_u8(d31u8));
|
||||
d2 += dest_stride;
|
||||
}
|
||||
return;
|
||||
}
|
||||
@@ -1,509 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2016, Alliance for Open Media. All rights reserved
|
||||
*
|
||||
* This source code is subject to the terms of the BSD 2 Clause License and
|
||||
* the Alliance for Open Media Patent License 1.0. If the BSD 2 Clause License
|
||||
* was not distributed with this source code in the LICENSE file, you can
|
||||
* obtain it at www.aomedia.org/license/software. If the Alliance for Open
|
||||
* Media Patent License 1.0 was not distributed with this source code in the
|
||||
* PATENTS file, you can obtain it at www.aomedia.org/license/patent.
|
||||
*/
|
||||
|
||||
#include <arm_neon.h>
|
||||
|
||||
#include "./aom_config.h"
|
||||
#include "aom_dsp/txfm_common.h"
|
||||
|
||||
static INLINE void TRANSPOSE8X8(int16x8_t *q8s16, int16x8_t *q9s16,
|
||||
int16x8_t *q10s16, int16x8_t *q11s16,
|
||||
int16x8_t *q12s16, int16x8_t *q13s16,
|
||||
int16x8_t *q14s16, int16x8_t *q15s16) {
|
||||
int16x4_t d16s16, d17s16, d18s16, d19s16, d20s16, d21s16, d22s16, d23s16;
|
||||
int16x4_t d24s16, d25s16, d26s16, d27s16, d28s16, d29s16, d30s16, d31s16;
|
||||
int32x4x2_t q0x2s32, q1x2s32, q2x2s32, q3x2s32;
|
||||
int16x8x2_t q0x2s16, q1x2s16, q2x2s16, q3x2s16;
|
||||
|
||||
d16s16 = vget_low_s16(*q8s16);
|
||||
d17s16 = vget_high_s16(*q8s16);
|
||||
d18s16 = vget_low_s16(*q9s16);
|
||||
d19s16 = vget_high_s16(*q9s16);
|
||||
d20s16 = vget_low_s16(*q10s16);
|
||||
d21s16 = vget_high_s16(*q10s16);
|
||||
d22s16 = vget_low_s16(*q11s16);
|
||||
d23s16 = vget_high_s16(*q11s16);
|
||||
d24s16 = vget_low_s16(*q12s16);
|
||||
d25s16 = vget_high_s16(*q12s16);
|
||||
d26s16 = vget_low_s16(*q13s16);
|
||||
d27s16 = vget_high_s16(*q13s16);
|
||||
d28s16 = vget_low_s16(*q14s16);
|
||||
d29s16 = vget_high_s16(*q14s16);
|
||||
d30s16 = vget_low_s16(*q15s16);
|
||||
d31s16 = vget_high_s16(*q15s16);
|
||||
|
||||
*q8s16 = vcombine_s16(d16s16, d24s16); // vswp d17, d24
|
||||
*q9s16 = vcombine_s16(d18s16, d26s16); // vswp d19, d26
|
||||
*q10s16 = vcombine_s16(d20s16, d28s16); // vswp d21, d28
|
||||
*q11s16 = vcombine_s16(d22s16, d30s16); // vswp d23, d30
|
||||
*q12s16 = vcombine_s16(d17s16, d25s16);
|
||||
*q13s16 = vcombine_s16(d19s16, d27s16);
|
||||
*q14s16 = vcombine_s16(d21s16, d29s16);
|
||||
*q15s16 = vcombine_s16(d23s16, d31s16);
|
||||
|
||||
q0x2s32 =
|
||||
vtrnq_s32(vreinterpretq_s32_s16(*q8s16), vreinterpretq_s32_s16(*q10s16));
|
||||
q1x2s32 =
|
||||
vtrnq_s32(vreinterpretq_s32_s16(*q9s16), vreinterpretq_s32_s16(*q11s16));
|
||||
q2x2s32 =
|
||||
vtrnq_s32(vreinterpretq_s32_s16(*q12s16), vreinterpretq_s32_s16(*q14s16));
|
||||
q3x2s32 =
|
||||
vtrnq_s32(vreinterpretq_s32_s16(*q13s16), vreinterpretq_s32_s16(*q15s16));
|
||||
|
||||
q0x2s16 = vtrnq_s16(vreinterpretq_s16_s32(q0x2s32.val[0]), // q8
|
||||
vreinterpretq_s16_s32(q1x2s32.val[0])); // q9
|
||||
q1x2s16 = vtrnq_s16(vreinterpretq_s16_s32(q0x2s32.val[1]), // q10
|
||||
vreinterpretq_s16_s32(q1x2s32.val[1])); // q11
|
||||
q2x2s16 = vtrnq_s16(vreinterpretq_s16_s32(q2x2s32.val[0]), // q12
|
||||
vreinterpretq_s16_s32(q3x2s32.val[0])); // q13
|
||||
q3x2s16 = vtrnq_s16(vreinterpretq_s16_s32(q2x2s32.val[1]), // q14
|
||||
vreinterpretq_s16_s32(q3x2s32.val[1])); // q15
|
||||
|
||||
*q8s16 = q0x2s16.val[0];
|
||||
*q9s16 = q0x2s16.val[1];
|
||||
*q10s16 = q1x2s16.val[0];
|
||||
*q11s16 = q1x2s16.val[1];
|
||||
*q12s16 = q2x2s16.val[0];
|
||||
*q13s16 = q2x2s16.val[1];
|
||||
*q14s16 = q3x2s16.val[0];
|
||||
*q15s16 = q3x2s16.val[1];
|
||||
return;
|
||||
}
|
||||
|
||||
static INLINE void IDCT8x8_1D(int16x8_t *q8s16, int16x8_t *q9s16,
|
||||
int16x8_t *q10s16, int16x8_t *q11s16,
|
||||
int16x8_t *q12s16, int16x8_t *q13s16,
|
||||
int16x8_t *q14s16, int16x8_t *q15s16) {
|
||||
int16x4_t d0s16, d1s16, d2s16, d3s16;
|
||||
int16x4_t d8s16, d9s16, d10s16, d11s16, d12s16, d13s16, d14s16, d15s16;
|
||||
int16x4_t d16s16, d17s16, d18s16, d19s16, d20s16, d21s16, d22s16, d23s16;
|
||||
int16x4_t d24s16, d25s16, d26s16, d27s16, d28s16, d29s16, d30s16, d31s16;
|
||||
int16x8_t q0s16, q1s16, q2s16, q3s16, q4s16, q5s16, q6s16, q7s16;
|
||||
int32x4_t q2s32, q3s32, q5s32, q6s32, q8s32, q9s32;
|
||||
int32x4_t q10s32, q11s32, q12s32, q13s32, q15s32;
|
||||
|
||||
d0s16 = vdup_n_s16((int16_t)cospi_28_64);
|
||||
d1s16 = vdup_n_s16((int16_t)cospi_4_64);
|
||||
d2s16 = vdup_n_s16((int16_t)cospi_12_64);
|
||||
d3s16 = vdup_n_s16((int16_t)cospi_20_64);
|
||||
|
||||
d16s16 = vget_low_s16(*q8s16);
|
||||
d17s16 = vget_high_s16(*q8s16);
|
||||
d18s16 = vget_low_s16(*q9s16);
|
||||
d19s16 = vget_high_s16(*q9s16);
|
||||
d20s16 = vget_low_s16(*q10s16);
|
||||
d21s16 = vget_high_s16(*q10s16);
|
||||
d22s16 = vget_low_s16(*q11s16);
|
||||
d23s16 = vget_high_s16(*q11s16);
|
||||
d24s16 = vget_low_s16(*q12s16);
|
||||
d25s16 = vget_high_s16(*q12s16);
|
||||
d26s16 = vget_low_s16(*q13s16);
|
||||
d27s16 = vget_high_s16(*q13s16);
|
||||
d28s16 = vget_low_s16(*q14s16);
|
||||
d29s16 = vget_high_s16(*q14s16);
|
||||
d30s16 = vget_low_s16(*q15s16);
|
||||
d31s16 = vget_high_s16(*q15s16);
|
||||
|
||||
q2s32 = vmull_s16(d18s16, d0s16);
|
||||
q3s32 = vmull_s16(d19s16, d0s16);
|
||||
q5s32 = vmull_s16(d26s16, d2s16);
|
||||
q6s32 = vmull_s16(d27s16, d2s16);
|
||||
|
||||
q2s32 = vmlsl_s16(q2s32, d30s16, d1s16);
|
||||
q3s32 = vmlsl_s16(q3s32, d31s16, d1s16);
|
||||
q5s32 = vmlsl_s16(q5s32, d22s16, d3s16);
|
||||
q6s32 = vmlsl_s16(q6s32, d23s16, d3s16);
|
||||
|
||||
d8s16 = vqrshrn_n_s32(q2s32, 14);
|
||||
d9s16 = vqrshrn_n_s32(q3s32, 14);
|
||||
d10s16 = vqrshrn_n_s32(q5s32, 14);
|
||||
d11s16 = vqrshrn_n_s32(q6s32, 14);
|
||||
q4s16 = vcombine_s16(d8s16, d9s16);
|
||||
q5s16 = vcombine_s16(d10s16, d11s16);
|
||||
|
||||
q2s32 = vmull_s16(d18s16, d1s16);
|
||||
q3s32 = vmull_s16(d19s16, d1s16);
|
||||
q9s32 = vmull_s16(d26s16, d3s16);
|
||||
q13s32 = vmull_s16(d27s16, d3s16);
|
||||
|
||||
q2s32 = vmlal_s16(q2s32, d30s16, d0s16);
|
||||
q3s32 = vmlal_s16(q3s32, d31s16, d0s16);
|
||||
q9s32 = vmlal_s16(q9s32, d22s16, d2s16);
|
||||
q13s32 = vmlal_s16(q13s32, d23s16, d2s16);
|
||||
|
||||
d14s16 = vqrshrn_n_s32(q2s32, 14);
|
||||
d15s16 = vqrshrn_n_s32(q3s32, 14);
|
||||
d12s16 = vqrshrn_n_s32(q9s32, 14);
|
||||
d13s16 = vqrshrn_n_s32(q13s32, 14);
|
||||
q6s16 = vcombine_s16(d12s16, d13s16);
|
||||
q7s16 = vcombine_s16(d14s16, d15s16);
|
||||
|
||||
d0s16 = vdup_n_s16((int16_t)cospi_16_64);
|
||||
|
||||
q2s32 = vmull_s16(d16s16, d0s16);
|
||||
q3s32 = vmull_s16(d17s16, d0s16);
|
||||
q13s32 = vmull_s16(d16s16, d0s16);
|
||||
q15s32 = vmull_s16(d17s16, d0s16);
|
||||
|
||||
q2s32 = vmlal_s16(q2s32, d24s16, d0s16);
|
||||
q3s32 = vmlal_s16(q3s32, d25s16, d0s16);
|
||||
q13s32 = vmlsl_s16(q13s32, d24s16, d0s16);
|
||||
q15s32 = vmlsl_s16(q15s32, d25s16, d0s16);
|
||||
|
||||
d0s16 = vdup_n_s16((int16_t)cospi_24_64);
|
||||
d1s16 = vdup_n_s16((int16_t)cospi_8_64);
|
||||
|
||||
d18s16 = vqrshrn_n_s32(q2s32, 14);
|
||||
d19s16 = vqrshrn_n_s32(q3s32, 14);
|
||||
d22s16 = vqrshrn_n_s32(q13s32, 14);
|
||||
d23s16 = vqrshrn_n_s32(q15s32, 14);
|
||||
*q9s16 = vcombine_s16(d18s16, d19s16);
|
||||
*q11s16 = vcombine_s16(d22s16, d23s16);
|
||||
|
||||
q2s32 = vmull_s16(d20s16, d0s16);
|
||||
q3s32 = vmull_s16(d21s16, d0s16);
|
||||
q8s32 = vmull_s16(d20s16, d1s16);
|
||||
q12s32 = vmull_s16(d21s16, d1s16);
|
||||
|
||||
q2s32 = vmlsl_s16(q2s32, d28s16, d1s16);
|
||||
q3s32 = vmlsl_s16(q3s32, d29s16, d1s16);
|
||||
q8s32 = vmlal_s16(q8s32, d28s16, d0s16);
|
||||
q12s32 = vmlal_s16(q12s32, d29s16, d0s16);
|
||||
|
||||
d26s16 = vqrshrn_n_s32(q2s32, 14);
|
||||
d27s16 = vqrshrn_n_s32(q3s32, 14);
|
||||
d30s16 = vqrshrn_n_s32(q8s32, 14);
|
||||
d31s16 = vqrshrn_n_s32(q12s32, 14);
|
||||
*q13s16 = vcombine_s16(d26s16, d27s16);
|
||||
*q15s16 = vcombine_s16(d30s16, d31s16);
|
||||
|
||||
q0s16 = vaddq_s16(*q9s16, *q15s16);
|
||||
q1s16 = vaddq_s16(*q11s16, *q13s16);
|
||||
q2s16 = vsubq_s16(*q11s16, *q13s16);
|
||||
q3s16 = vsubq_s16(*q9s16, *q15s16);
|
||||
|
||||
*q13s16 = vsubq_s16(q4s16, q5s16);
|
||||
q4s16 = vaddq_s16(q4s16, q5s16);
|
||||
*q14s16 = vsubq_s16(q7s16, q6s16);
|
||||
q7s16 = vaddq_s16(q7s16, q6s16);
|
||||
d26s16 = vget_low_s16(*q13s16);
|
||||
d27s16 = vget_high_s16(*q13s16);
|
||||
d28s16 = vget_low_s16(*q14s16);
|
||||
d29s16 = vget_high_s16(*q14s16);
|
||||
|
||||
d16s16 = vdup_n_s16((int16_t)cospi_16_64);
|
||||
|
||||
q9s32 = vmull_s16(d28s16, d16s16);
|
||||
q10s32 = vmull_s16(d29s16, d16s16);
|
||||
q11s32 = vmull_s16(d28s16, d16s16);
|
||||
q12s32 = vmull_s16(d29s16, d16s16);
|
||||
|
||||
q9s32 = vmlsl_s16(q9s32, d26s16, d16s16);
|
||||
q10s32 = vmlsl_s16(q10s32, d27s16, d16s16);
|
||||
q11s32 = vmlal_s16(q11s32, d26s16, d16s16);
|
||||
q12s32 = vmlal_s16(q12s32, d27s16, d16s16);
|
||||
|
||||
d10s16 = vqrshrn_n_s32(q9s32, 14);
|
||||
d11s16 = vqrshrn_n_s32(q10s32, 14);
|
||||
d12s16 = vqrshrn_n_s32(q11s32, 14);
|
||||
d13s16 = vqrshrn_n_s32(q12s32, 14);
|
||||
q5s16 = vcombine_s16(d10s16, d11s16);
|
||||
q6s16 = vcombine_s16(d12s16, d13s16);
|
||||
|
||||
*q8s16 = vaddq_s16(q0s16, q7s16);
|
||||
*q9s16 = vaddq_s16(q1s16, q6s16);
|
||||
*q10s16 = vaddq_s16(q2s16, q5s16);
|
||||
*q11s16 = vaddq_s16(q3s16, q4s16);
|
||||
*q12s16 = vsubq_s16(q3s16, q4s16);
|
||||
*q13s16 = vsubq_s16(q2s16, q5s16);
|
||||
*q14s16 = vsubq_s16(q1s16, q6s16);
|
||||
*q15s16 = vsubq_s16(q0s16, q7s16);
|
||||
return;
|
||||
}
|
||||
|
||||
void aom_idct8x8_64_add_neon(int16_t *input, uint8_t *dest, int dest_stride) {
|
||||
uint8_t *d1, *d2;
|
||||
uint8x8_t d0u8, d1u8, d2u8, d3u8;
|
||||
uint64x1_t d0u64, d1u64, d2u64, d3u64;
|
||||
int16x8_t q8s16, q9s16, q10s16, q11s16, q12s16, q13s16, q14s16, q15s16;
|
||||
uint16x8_t q8u16, q9u16, q10u16, q11u16;
|
||||
|
||||
q8s16 = vld1q_s16(input);
|
||||
q9s16 = vld1q_s16(input + 8);
|
||||
q10s16 = vld1q_s16(input + 16);
|
||||
q11s16 = vld1q_s16(input + 24);
|
||||
q12s16 = vld1q_s16(input + 32);
|
||||
q13s16 = vld1q_s16(input + 40);
|
||||
q14s16 = vld1q_s16(input + 48);
|
||||
q15s16 = vld1q_s16(input + 56);
|
||||
|
||||
TRANSPOSE8X8(&q8s16, &q9s16, &q10s16, &q11s16, &q12s16, &q13s16, &q14s16,
|
||||
&q15s16);
|
||||
|
||||
IDCT8x8_1D(&q8s16, &q9s16, &q10s16, &q11s16, &q12s16, &q13s16, &q14s16,
|
||||
&q15s16);
|
||||
|
||||
TRANSPOSE8X8(&q8s16, &q9s16, &q10s16, &q11s16, &q12s16, &q13s16, &q14s16,
|
||||
&q15s16);
|
||||
|
||||
IDCT8x8_1D(&q8s16, &q9s16, &q10s16, &q11s16, &q12s16, &q13s16, &q14s16,
|
||||
&q15s16);
|
||||
|
||||
q8s16 = vrshrq_n_s16(q8s16, 5);
|
||||
q9s16 = vrshrq_n_s16(q9s16, 5);
|
||||
q10s16 = vrshrq_n_s16(q10s16, 5);
|
||||
q11s16 = vrshrq_n_s16(q11s16, 5);
|
||||
q12s16 = vrshrq_n_s16(q12s16, 5);
|
||||
q13s16 = vrshrq_n_s16(q13s16, 5);
|
||||
q14s16 = vrshrq_n_s16(q14s16, 5);
|
||||
q15s16 = vrshrq_n_s16(q15s16, 5);
|
||||
|
||||
d1 = d2 = dest;
|
||||
|
||||
d0u64 = vld1_u64((uint64_t *)d1);
|
||||
d1 += dest_stride;
|
||||
d1u64 = vld1_u64((uint64_t *)d1);
|
||||
d1 += dest_stride;
|
||||
d2u64 = vld1_u64((uint64_t *)d1);
|
||||
d1 += dest_stride;
|
||||
d3u64 = vld1_u64((uint64_t *)d1);
|
||||
d1 += dest_stride;
|
||||
|
||||
q8u16 = vaddw_u8(vreinterpretq_u16_s16(q8s16), vreinterpret_u8_u64(d0u64));
|
||||
q9u16 = vaddw_u8(vreinterpretq_u16_s16(q9s16), vreinterpret_u8_u64(d1u64));
|
||||
q10u16 = vaddw_u8(vreinterpretq_u16_s16(q10s16), vreinterpret_u8_u64(d2u64));
|
||||
q11u16 = vaddw_u8(vreinterpretq_u16_s16(q11s16), vreinterpret_u8_u64(d3u64));
|
||||
|
||||
d0u8 = vqmovun_s16(vreinterpretq_s16_u16(q8u16));
|
||||
d1u8 = vqmovun_s16(vreinterpretq_s16_u16(q9u16));
|
||||
d2u8 = vqmovun_s16(vreinterpretq_s16_u16(q10u16));
|
||||
d3u8 = vqmovun_s16(vreinterpretq_s16_u16(q11u16));
|
||||
|
||||
vst1_u64((uint64_t *)d2, vreinterpret_u64_u8(d0u8));
|
||||
d2 += dest_stride;
|
||||
vst1_u64((uint64_t *)d2, vreinterpret_u64_u8(d1u8));
|
||||
d2 += dest_stride;
|
||||
vst1_u64((uint64_t *)d2, vreinterpret_u64_u8(d2u8));
|
||||
d2 += dest_stride;
|
||||
vst1_u64((uint64_t *)d2, vreinterpret_u64_u8(d3u8));
|
||||
d2 += dest_stride;
|
||||
|
||||
q8s16 = q12s16;
|
||||
q9s16 = q13s16;
|
||||
q10s16 = q14s16;
|
||||
q11s16 = q15s16;
|
||||
|
||||
d0u64 = vld1_u64((uint64_t *)d1);
|
||||
d1 += dest_stride;
|
||||
d1u64 = vld1_u64((uint64_t *)d1);
|
||||
d1 += dest_stride;
|
||||
d2u64 = vld1_u64((uint64_t *)d1);
|
||||
d1 += dest_stride;
|
||||
d3u64 = vld1_u64((uint64_t *)d1);
|
||||
d1 += dest_stride;
|
||||
|
||||
q8u16 = vaddw_u8(vreinterpretq_u16_s16(q8s16), vreinterpret_u8_u64(d0u64));
|
||||
q9u16 = vaddw_u8(vreinterpretq_u16_s16(q9s16), vreinterpret_u8_u64(d1u64));
|
||||
q10u16 = vaddw_u8(vreinterpretq_u16_s16(q10s16), vreinterpret_u8_u64(d2u64));
|
||||
q11u16 = vaddw_u8(vreinterpretq_u16_s16(q11s16), vreinterpret_u8_u64(d3u64));
|
||||
|
||||
d0u8 = vqmovun_s16(vreinterpretq_s16_u16(q8u16));
|
||||
d1u8 = vqmovun_s16(vreinterpretq_s16_u16(q9u16));
|
||||
d2u8 = vqmovun_s16(vreinterpretq_s16_u16(q10u16));
|
||||
d3u8 = vqmovun_s16(vreinterpretq_s16_u16(q11u16));
|
||||
|
||||
vst1_u64((uint64_t *)d2, vreinterpret_u64_u8(d0u8));
|
||||
d2 += dest_stride;
|
||||
vst1_u64((uint64_t *)d2, vreinterpret_u64_u8(d1u8));
|
||||
d2 += dest_stride;
|
||||
vst1_u64((uint64_t *)d2, vreinterpret_u64_u8(d2u8));
|
||||
d2 += dest_stride;
|
||||
vst1_u64((uint64_t *)d2, vreinterpret_u64_u8(d3u8));
|
||||
d2 += dest_stride;
|
||||
return;
|
||||
}
|
||||
|
||||
void aom_idct8x8_12_add_neon(int16_t *input, uint8_t *dest, int dest_stride) {
|
||||
uint8_t *d1, *d2;
|
||||
uint8x8_t d0u8, d1u8, d2u8, d3u8;
|
||||
int16x4_t d10s16, d11s16, d12s16, d13s16, d16s16;
|
||||
int16x4_t d26s16, d27s16, d28s16, d29s16;
|
||||
uint64x1_t d0u64, d1u64, d2u64, d3u64;
|
||||
int16x8_t q0s16, q1s16, q2s16, q3s16, q4s16, q5s16, q6s16, q7s16;
|
||||
int16x8_t q8s16, q9s16, q10s16, q11s16, q12s16, q13s16, q14s16, q15s16;
|
||||
uint16x8_t q8u16, q9u16, q10u16, q11u16;
|
||||
int32x4_t q9s32, q10s32, q11s32, q12s32;
|
||||
|
||||
q8s16 = vld1q_s16(input);
|
||||
q9s16 = vld1q_s16(input + 8);
|
||||
q10s16 = vld1q_s16(input + 16);
|
||||
q11s16 = vld1q_s16(input + 24);
|
||||
q12s16 = vld1q_s16(input + 32);
|
||||
q13s16 = vld1q_s16(input + 40);
|
||||
q14s16 = vld1q_s16(input + 48);
|
||||
q15s16 = vld1q_s16(input + 56);
|
||||
|
||||
TRANSPOSE8X8(&q8s16, &q9s16, &q10s16, &q11s16, &q12s16, &q13s16, &q14s16,
|
||||
&q15s16);
|
||||
|
||||
// First transform rows
|
||||
// stage 1
|
||||
q0s16 = vdupq_n_s16((int16_t)cospi_28_64 * 2);
|
||||
q1s16 = vdupq_n_s16((int16_t)cospi_4_64 * 2);
|
||||
|
||||
q4s16 = vqrdmulhq_s16(q9s16, q0s16);
|
||||
|
||||
q0s16 = vdupq_n_s16(-(int16_t)cospi_20_64 * 2);
|
||||
|
||||
q7s16 = vqrdmulhq_s16(q9s16, q1s16);
|
||||
|
||||
q1s16 = vdupq_n_s16((int16_t)cospi_12_64 * 2);
|
||||
|
||||
q5s16 = vqrdmulhq_s16(q11s16, q0s16);
|
||||
|
||||
q0s16 = vdupq_n_s16((int16_t)cospi_16_64 * 2);
|
||||
|
||||
q6s16 = vqrdmulhq_s16(q11s16, q1s16);
|
||||
|
||||
// stage 2 & stage 3 - even half
|
||||
q1s16 = vdupq_n_s16((int16_t)cospi_24_64 * 2);
|
||||
|
||||
q9s16 = vqrdmulhq_s16(q8s16, q0s16);
|
||||
|
||||
q0s16 = vdupq_n_s16((int16_t)cospi_8_64 * 2);
|
||||
|
||||
q13s16 = vqrdmulhq_s16(q10s16, q1s16);
|
||||
|
||||
q15s16 = vqrdmulhq_s16(q10s16, q0s16);
|
||||
|
||||
// stage 3 -odd half
|
||||
q0s16 = vaddq_s16(q9s16, q15s16);
|
||||
q1s16 = vaddq_s16(q9s16, q13s16);
|
||||
q2s16 = vsubq_s16(q9s16, q13s16);
|
||||
q3s16 = vsubq_s16(q9s16, q15s16);
|
||||
|
||||
// stage 2 - odd half
|
||||
q13s16 = vsubq_s16(q4s16, q5s16);
|
||||
q4s16 = vaddq_s16(q4s16, q5s16);
|
||||
q14s16 = vsubq_s16(q7s16, q6s16);
|
||||
q7s16 = vaddq_s16(q7s16, q6s16);
|
||||
d26s16 = vget_low_s16(q13s16);
|
||||
d27s16 = vget_high_s16(q13s16);
|
||||
d28s16 = vget_low_s16(q14s16);
|
||||
d29s16 = vget_high_s16(q14s16);
|
||||
|
||||
d16s16 = vdup_n_s16((int16_t)cospi_16_64);
|
||||
q9s32 = vmull_s16(d28s16, d16s16);
|
||||
q10s32 = vmull_s16(d29s16, d16s16);
|
||||
q11s32 = vmull_s16(d28s16, d16s16);
|
||||
q12s32 = vmull_s16(d29s16, d16s16);
|
||||
|
||||
q9s32 = vmlsl_s16(q9s32, d26s16, d16s16);
|
||||
q10s32 = vmlsl_s16(q10s32, d27s16, d16s16);
|
||||
q11s32 = vmlal_s16(q11s32, d26s16, d16s16);
|
||||
q12s32 = vmlal_s16(q12s32, d27s16, d16s16);
|
||||
|
||||
d10s16 = vqrshrn_n_s32(q9s32, 14);
|
||||
d11s16 = vqrshrn_n_s32(q10s32, 14);
|
||||
d12s16 = vqrshrn_n_s32(q11s32, 14);
|
||||
d13s16 = vqrshrn_n_s32(q12s32, 14);
|
||||
q5s16 = vcombine_s16(d10s16, d11s16);
|
||||
q6s16 = vcombine_s16(d12s16, d13s16);
|
||||
|
||||
// stage 4
|
||||
q8s16 = vaddq_s16(q0s16, q7s16);
|
||||
q9s16 = vaddq_s16(q1s16, q6s16);
|
||||
q10s16 = vaddq_s16(q2s16, q5s16);
|
||||
q11s16 = vaddq_s16(q3s16, q4s16);
|
||||
q12s16 = vsubq_s16(q3s16, q4s16);
|
||||
q13s16 = vsubq_s16(q2s16, q5s16);
|
||||
q14s16 = vsubq_s16(q1s16, q6s16);
|
||||
q15s16 = vsubq_s16(q0s16, q7s16);
|
||||
|
||||
TRANSPOSE8X8(&q8s16, &q9s16, &q10s16, &q11s16, &q12s16, &q13s16, &q14s16,
|
||||
&q15s16);
|
||||
|
||||
IDCT8x8_1D(&q8s16, &q9s16, &q10s16, &q11s16, &q12s16, &q13s16, &q14s16,
|
||||
&q15s16);
|
||||
|
||||
q8s16 = vrshrq_n_s16(q8s16, 5);
|
||||
q9s16 = vrshrq_n_s16(q9s16, 5);
|
||||
q10s16 = vrshrq_n_s16(q10s16, 5);
|
||||
q11s16 = vrshrq_n_s16(q11s16, 5);
|
||||
q12s16 = vrshrq_n_s16(q12s16, 5);
|
||||
q13s16 = vrshrq_n_s16(q13s16, 5);
|
||||
q14s16 = vrshrq_n_s16(q14s16, 5);
|
||||
q15s16 = vrshrq_n_s16(q15s16, 5);
|
||||
|
||||
d1 = d2 = dest;
|
||||
|
||||
d0u64 = vld1_u64((uint64_t *)d1);
|
||||
d1 += dest_stride;
|
||||
d1u64 = vld1_u64((uint64_t *)d1);
|
||||
d1 += dest_stride;
|
||||
d2u64 = vld1_u64((uint64_t *)d1);
|
||||
d1 += dest_stride;
|
||||
d3u64 = vld1_u64((uint64_t *)d1);
|
||||
d1 += dest_stride;
|
||||
|
||||
q8u16 = vaddw_u8(vreinterpretq_u16_s16(q8s16), vreinterpret_u8_u64(d0u64));
|
||||
q9u16 = vaddw_u8(vreinterpretq_u16_s16(q9s16), vreinterpret_u8_u64(d1u64));
|
||||
q10u16 = vaddw_u8(vreinterpretq_u16_s16(q10s16), vreinterpret_u8_u64(d2u64));
|
||||
q11u16 = vaddw_u8(vreinterpretq_u16_s16(q11s16), vreinterpret_u8_u64(d3u64));
|
||||
|
||||
d0u8 = vqmovun_s16(vreinterpretq_s16_u16(q8u16));
|
||||
d1u8 = vqmovun_s16(vreinterpretq_s16_u16(q9u16));
|
||||
d2u8 = vqmovun_s16(vreinterpretq_s16_u16(q10u16));
|
||||
d3u8 = vqmovun_s16(vreinterpretq_s16_u16(q11u16));
|
||||
|
||||
vst1_u64((uint64_t *)d2, vreinterpret_u64_u8(d0u8));
|
||||
d2 += dest_stride;
|
||||
vst1_u64((uint64_t *)d2, vreinterpret_u64_u8(d1u8));
|
||||
d2 += dest_stride;
|
||||
vst1_u64((uint64_t *)d2, vreinterpret_u64_u8(d2u8));
|
||||
d2 += dest_stride;
|
||||
vst1_u64((uint64_t *)d2, vreinterpret_u64_u8(d3u8));
|
||||
d2 += dest_stride;
|
||||
|
||||
q8s16 = q12s16;
|
||||
q9s16 = q13s16;
|
||||
q10s16 = q14s16;
|
||||
q11s16 = q15s16;
|
||||
|
||||
d0u64 = vld1_u64((uint64_t *)d1);
|
||||
d1 += dest_stride;
|
||||
d1u64 = vld1_u64((uint64_t *)d1);
|
||||
d1 += dest_stride;
|
||||
d2u64 = vld1_u64((uint64_t *)d1);
|
||||
d1 += dest_stride;
|
||||
d3u64 = vld1_u64((uint64_t *)d1);
|
||||
d1 += dest_stride;
|
||||
|
||||
q8u16 = vaddw_u8(vreinterpretq_u16_s16(q8s16), vreinterpret_u8_u64(d0u64));
|
||||
q9u16 = vaddw_u8(vreinterpretq_u16_s16(q9s16), vreinterpret_u8_u64(d1u64));
|
||||
q10u16 = vaddw_u8(vreinterpretq_u16_s16(q10s16), vreinterpret_u8_u64(d2u64));
|
||||
q11u16 = vaddw_u8(vreinterpretq_u16_s16(q11s16), vreinterpret_u8_u64(d3u64));
|
||||
|
||||
d0u8 = vqmovun_s16(vreinterpretq_s16_u16(q8u16));
|
||||
d1u8 = vqmovun_s16(vreinterpretq_s16_u16(q9u16));
|
||||
d2u8 = vqmovun_s16(vreinterpretq_s16_u16(q10u16));
|
||||
d3u8 = vqmovun_s16(vreinterpretq_s16_u16(q11u16));
|
||||
|
||||
vst1_u64((uint64_t *)d2, vreinterpret_u64_u8(d0u8));
|
||||
d2 += dest_stride;
|
||||
vst1_u64((uint64_t *)d2, vreinterpret_u64_u8(d1u8));
|
||||
d2 += dest_stride;
|
||||
vst1_u64((uint64_t *)d2, vreinterpret_u64_u8(d2u8));
|
||||
d2 += dest_stride;
|
||||
vst1_u64((uint64_t *)d2, vreinterpret_u64_u8(d3u8));
|
||||
d2 += dest_stride;
|
||||
return;
|
||||
}
|
||||
@@ -1,819 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2016, Alliance for Open Media. All rights reserved
|
||||
*
|
||||
* This source code is subject to the terms of the BSD 2 Clause License and
|
||||
* the Alliance for Open Media Patent License 1.0. If the BSD 2 Clause License
|
||||
* was not distributed with this source code in the LICENSE file, you can
|
||||
* obtain it at www.aomedia.org/license/software. If the Alliance for Open
|
||||
* Media Patent License 1.0 was not distributed with this source code in the
|
||||
* PATENTS file, you can obtain it at www.aomedia.org/license/patent.
|
||||
*/
|
||||
|
||||
#include <arm_neon.h>
|
||||
|
||||
#include "./aom_config.h"
|
||||
#include "./aom_dsp_rtcd.h"
|
||||
#include "aom/aom_integer.h"
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// DC 4x4
|
||||
|
||||
// 'do_above' and 'do_left' facilitate branch removal when inlined.
|
||||
static INLINE void dc_4x4(uint8_t *dst, ptrdiff_t stride, const uint8_t *above,
|
||||
const uint8_t *left, int do_above, int do_left) {
|
||||
uint16x8_t sum_top;
|
||||
uint16x8_t sum_left;
|
||||
uint8x8_t dc0;
|
||||
|
||||
if (do_above) {
|
||||
const uint8x8_t A = vld1_u8(above); // top row
|
||||
const uint16x4_t p0 = vpaddl_u8(A); // cascading summation of the top
|
||||
const uint16x4_t p1 = vpadd_u16(p0, p0);
|
||||
sum_top = vcombine_u16(p1, p1);
|
||||
}
|
||||
|
||||
if (do_left) {
|
||||
const uint8x8_t L = vld1_u8(left); // left border
|
||||
const uint16x4_t p0 = vpaddl_u8(L); // cascading summation of the left
|
||||
const uint16x4_t p1 = vpadd_u16(p0, p0);
|
||||
sum_left = vcombine_u16(p1, p1);
|
||||
}
|
||||
|
||||
if (do_above && do_left) {
|
||||
const uint16x8_t sum = vaddq_u16(sum_left, sum_top);
|
||||
dc0 = vrshrn_n_u16(sum, 3);
|
||||
} else if (do_above) {
|
||||
dc0 = vrshrn_n_u16(sum_top, 2);
|
||||
} else if (do_left) {
|
||||
dc0 = vrshrn_n_u16(sum_left, 2);
|
||||
} else {
|
||||
dc0 = vdup_n_u8(0x80);
|
||||
}
|
||||
|
||||
{
|
||||
const uint8x8_t dc = vdup_lane_u8(dc0, 0);
|
||||
int i;
|
||||
for (i = 0; i < 4; ++i) {
|
||||
vst1_lane_u32((uint32_t *)(dst + i * stride), vreinterpret_u32_u8(dc), 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void aom_dc_predictor_4x4_neon(uint8_t *dst, ptrdiff_t stride,
|
||||
const uint8_t *above, const uint8_t *left) {
|
||||
dc_4x4(dst, stride, above, left, 1, 1);
|
||||
}
|
||||
|
||||
void aom_dc_left_predictor_4x4_neon(uint8_t *dst, ptrdiff_t stride,
|
||||
const uint8_t *above, const uint8_t *left) {
|
||||
(void)above;
|
||||
dc_4x4(dst, stride, NULL, left, 0, 1);
|
||||
}
|
||||
|
||||
void aom_dc_top_predictor_4x4_neon(uint8_t *dst, ptrdiff_t stride,
|
||||
const uint8_t *above, const uint8_t *left) {
|
||||
(void)left;
|
||||
dc_4x4(dst, stride, above, NULL, 1, 0);
|
||||
}
|
||||
|
||||
void aom_dc_128_predictor_4x4_neon(uint8_t *dst, ptrdiff_t stride,
|
||||
const uint8_t *above, const uint8_t *left) {
|
||||
(void)above;
|
||||
(void)left;
|
||||
dc_4x4(dst, stride, NULL, NULL, 0, 0);
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// DC 8x8
|
||||
|
||||
// 'do_above' and 'do_left' facilitate branch removal when inlined.
|
||||
static INLINE void dc_8x8(uint8_t *dst, ptrdiff_t stride, const uint8_t *above,
|
||||
const uint8_t *left, int do_above, int do_left) {
|
||||
uint16x8_t sum_top;
|
||||
uint16x8_t sum_left;
|
||||
uint8x8_t dc0;
|
||||
|
||||
if (do_above) {
|
||||
const uint8x8_t A = vld1_u8(above); // top row
|
||||
const uint16x4_t p0 = vpaddl_u8(A); // cascading summation of the top
|
||||
const uint16x4_t p1 = vpadd_u16(p0, p0);
|
||||
const uint16x4_t p2 = vpadd_u16(p1, p1);
|
||||
sum_top = vcombine_u16(p2, p2);
|
||||
}
|
||||
|
||||
if (do_left) {
|
||||
const uint8x8_t L = vld1_u8(left); // left border
|
||||
const uint16x4_t p0 = vpaddl_u8(L); // cascading summation of the left
|
||||
const uint16x4_t p1 = vpadd_u16(p0, p0);
|
||||
const uint16x4_t p2 = vpadd_u16(p1, p1);
|
||||
sum_left = vcombine_u16(p2, p2);
|
||||
}
|
||||
|
||||
if (do_above && do_left) {
|
||||
const uint16x8_t sum = vaddq_u16(sum_left, sum_top);
|
||||
dc0 = vrshrn_n_u16(sum, 4);
|
||||
} else if (do_above) {
|
||||
dc0 = vrshrn_n_u16(sum_top, 3);
|
||||
} else if (do_left) {
|
||||
dc0 = vrshrn_n_u16(sum_left, 3);
|
||||
} else {
|
||||
dc0 = vdup_n_u8(0x80);
|
||||
}
|
||||
|
||||
{
|
||||
const uint8x8_t dc = vdup_lane_u8(dc0, 0);
|
||||
int i;
|
||||
for (i = 0; i < 8; ++i) {
|
||||
vst1_u32((uint32_t *)(dst + i * stride), vreinterpret_u32_u8(dc));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void aom_dc_predictor_8x8_neon(uint8_t *dst, ptrdiff_t stride,
|
||||
const uint8_t *above, const uint8_t *left) {
|
||||
dc_8x8(dst, stride, above, left, 1, 1);
|
||||
}
|
||||
|
||||
void aom_dc_left_predictor_8x8_neon(uint8_t *dst, ptrdiff_t stride,
|
||||
const uint8_t *above, const uint8_t *left) {
|
||||
(void)above;
|
||||
dc_8x8(dst, stride, NULL, left, 0, 1);
|
||||
}
|
||||
|
||||
void aom_dc_top_predictor_8x8_neon(uint8_t *dst, ptrdiff_t stride,
|
||||
const uint8_t *above, const uint8_t *left) {
|
||||
(void)left;
|
||||
dc_8x8(dst, stride, above, NULL, 1, 0);
|
||||
}
|
||||
|
||||
void aom_dc_128_predictor_8x8_neon(uint8_t *dst, ptrdiff_t stride,
|
||||
const uint8_t *above, const uint8_t *left) {
|
||||
(void)above;
|
||||
(void)left;
|
||||
dc_8x8(dst, stride, NULL, NULL, 0, 0);
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// DC 16x16
|
||||
|
||||
// 'do_above' and 'do_left' facilitate branch removal when inlined.
|
||||
static INLINE void dc_16x16(uint8_t *dst, ptrdiff_t stride,
|
||||
const uint8_t *above, const uint8_t *left,
|
||||
int do_above, int do_left) {
|
||||
uint16x8_t sum_top;
|
||||
uint16x8_t sum_left;
|
||||
uint8x8_t dc0;
|
||||
|
||||
if (do_above) {
|
||||
const uint8x16_t A = vld1q_u8(above); // top row
|
||||
const uint16x8_t p0 = vpaddlq_u8(A); // cascading summation of the top
|
||||
const uint16x4_t p1 = vadd_u16(vget_low_u16(p0), vget_high_u16(p0));
|
||||
const uint16x4_t p2 = vpadd_u16(p1, p1);
|
||||
const uint16x4_t p3 = vpadd_u16(p2, p2);
|
||||
sum_top = vcombine_u16(p3, p3);
|
||||
}
|
||||
|
||||
if (do_left) {
|
||||
const uint8x16_t L = vld1q_u8(left); // left row
|
||||
const uint16x8_t p0 = vpaddlq_u8(L); // cascading summation of the left
|
||||
const uint16x4_t p1 = vadd_u16(vget_low_u16(p0), vget_high_u16(p0));
|
||||
const uint16x4_t p2 = vpadd_u16(p1, p1);
|
||||
const uint16x4_t p3 = vpadd_u16(p2, p2);
|
||||
sum_left = vcombine_u16(p3, p3);
|
||||
}
|
||||
|
||||
if (do_above && do_left) {
|
||||
const uint16x8_t sum = vaddq_u16(sum_left, sum_top);
|
||||
dc0 = vrshrn_n_u16(sum, 5);
|
||||
} else if (do_above) {
|
||||
dc0 = vrshrn_n_u16(sum_top, 4);
|
||||
} else if (do_left) {
|
||||
dc0 = vrshrn_n_u16(sum_left, 4);
|
||||
} else {
|
||||
dc0 = vdup_n_u8(0x80);
|
||||
}
|
||||
|
||||
{
|
||||
const uint8x16_t dc = vdupq_lane_u8(dc0, 0);
|
||||
int i;
|
||||
for (i = 0; i < 16; ++i) {
|
||||
vst1q_u8(dst + i * stride, dc);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void aom_dc_predictor_16x16_neon(uint8_t *dst, ptrdiff_t stride,
|
||||
const uint8_t *above, const uint8_t *left) {
|
||||
dc_16x16(dst, stride, above, left, 1, 1);
|
||||
}
|
||||
|
||||
void aom_dc_left_predictor_16x16_neon(uint8_t *dst, ptrdiff_t stride,
|
||||
const uint8_t *above,
|
||||
const uint8_t *left) {
|
||||
(void)above;
|
||||
dc_16x16(dst, stride, NULL, left, 0, 1);
|
||||
}
|
||||
|
||||
void aom_dc_top_predictor_16x16_neon(uint8_t *dst, ptrdiff_t stride,
|
||||
const uint8_t *above,
|
||||
const uint8_t *left) {
|
||||
(void)left;
|
||||
dc_16x16(dst, stride, above, NULL, 1, 0);
|
||||
}
|
||||
|
||||
void aom_dc_128_predictor_16x16_neon(uint8_t *dst, ptrdiff_t stride,
|
||||
const uint8_t *above,
|
||||
const uint8_t *left) {
|
||||
(void)above;
|
||||
(void)left;
|
||||
dc_16x16(dst, stride, NULL, NULL, 0, 0);
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// DC 32x32
|
||||
|
||||
// 'do_above' and 'do_left' facilitate branch removal when inlined.
|
||||
static INLINE void dc_32x32(uint8_t *dst, ptrdiff_t stride,
|
||||
const uint8_t *above, const uint8_t *left,
|
||||
int do_above, int do_left) {
|
||||
uint16x8_t sum_top;
|
||||
uint16x8_t sum_left;
|
||||
uint8x8_t dc0;
|
||||
|
||||
if (do_above) {
|
||||
const uint8x16_t A0 = vld1q_u8(above); // top row
|
||||
const uint8x16_t A1 = vld1q_u8(above + 16);
|
||||
const uint16x8_t p0 = vpaddlq_u8(A0); // cascading summation of the top
|
||||
const uint16x8_t p1 = vpaddlq_u8(A1);
|
||||
const uint16x8_t p2 = vaddq_u16(p0, p1);
|
||||
const uint16x4_t p3 = vadd_u16(vget_low_u16(p2), vget_high_u16(p2));
|
||||
const uint16x4_t p4 = vpadd_u16(p3, p3);
|
||||
const uint16x4_t p5 = vpadd_u16(p4, p4);
|
||||
sum_top = vcombine_u16(p5, p5);
|
||||
}
|
||||
|
||||
if (do_left) {
|
||||
const uint8x16_t L0 = vld1q_u8(left); // left row
|
||||
const uint8x16_t L1 = vld1q_u8(left + 16);
|
||||
const uint16x8_t p0 = vpaddlq_u8(L0); // cascading summation of the left
|
||||
const uint16x8_t p1 = vpaddlq_u8(L1);
|
||||
const uint16x8_t p2 = vaddq_u16(p0, p1);
|
||||
const uint16x4_t p3 = vadd_u16(vget_low_u16(p2), vget_high_u16(p2));
|
||||
const uint16x4_t p4 = vpadd_u16(p3, p3);
|
||||
const uint16x4_t p5 = vpadd_u16(p4, p4);
|
||||
sum_left = vcombine_u16(p5, p5);
|
||||
}
|
||||
|
||||
if (do_above && do_left) {
|
||||
const uint16x8_t sum = vaddq_u16(sum_left, sum_top);
|
||||
dc0 = vrshrn_n_u16(sum, 6);
|
||||
} else if (do_above) {
|
||||
dc0 = vrshrn_n_u16(sum_top, 5);
|
||||
} else if (do_left) {
|
||||
dc0 = vrshrn_n_u16(sum_left, 5);
|
||||
} else {
|
||||
dc0 = vdup_n_u8(0x80);
|
||||
}
|
||||
|
||||
{
|
||||
const uint8x16_t dc = vdupq_lane_u8(dc0, 0);
|
||||
int i;
|
||||
for (i = 0; i < 32; ++i) {
|
||||
vst1q_u8(dst + i * stride, dc);
|
||||
vst1q_u8(dst + i * stride + 16, dc);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void aom_dc_predictor_32x32_neon(uint8_t *dst, ptrdiff_t stride,
|
||||
const uint8_t *above, const uint8_t *left) {
|
||||
dc_32x32(dst, stride, above, left, 1, 1);
|
||||
}
|
||||
|
||||
void aom_dc_left_predictor_32x32_neon(uint8_t *dst, ptrdiff_t stride,
|
||||
const uint8_t *above,
|
||||
const uint8_t *left) {
|
||||
(void)above;
|
||||
dc_32x32(dst, stride, NULL, left, 0, 1);
|
||||
}
|
||||
|
||||
void aom_dc_top_predictor_32x32_neon(uint8_t *dst, ptrdiff_t stride,
|
||||
const uint8_t *above,
|
||||
const uint8_t *left) {
|
||||
(void)left;
|
||||
dc_32x32(dst, stride, above, NULL, 1, 0);
|
||||
}
|
||||
|
||||
void aom_dc_128_predictor_32x32_neon(uint8_t *dst, ptrdiff_t stride,
|
||||
const uint8_t *above,
|
||||
const uint8_t *left) {
|
||||
(void)above;
|
||||
(void)left;
|
||||
dc_32x32(dst, stride, NULL, NULL, 0, 0);
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
void aom_d45_predictor_4x4_neon(uint8_t *dst, ptrdiff_t stride,
|
||||
const uint8_t *above, const uint8_t *left) {
|
||||
const uint64x1_t A0 = vreinterpret_u64_u8(vld1_u8(above)); // top row
|
||||
const uint64x1_t A1 = vshr_n_u64(A0, 8);
|
||||
const uint64x1_t A2 = vshr_n_u64(A0, 16);
|
||||
const uint8x8_t ABCDEFGH = vreinterpret_u8_u64(A0);
|
||||
const uint8x8_t BCDEFGH0 = vreinterpret_u8_u64(A1);
|
||||
const uint8x8_t CDEFGH00 = vreinterpret_u8_u64(A2);
|
||||
const uint8x8_t avg1 = vhadd_u8(ABCDEFGH, CDEFGH00);
|
||||
const uint8x8_t avg2 = vrhadd_u8(avg1, BCDEFGH0);
|
||||
const uint64x1_t avg2_u64 = vreinterpret_u64_u8(avg2);
|
||||
const uint32x2_t r0 = vreinterpret_u32_u8(avg2);
|
||||
const uint32x2_t r1 = vreinterpret_u32_u64(vshr_n_u64(avg2_u64, 8));
|
||||
const uint32x2_t r2 = vreinterpret_u32_u64(vshr_n_u64(avg2_u64, 16));
|
||||
const uint32x2_t r3 = vreinterpret_u32_u64(vshr_n_u64(avg2_u64, 24));
|
||||
(void)left;
|
||||
vst1_lane_u32((uint32_t *)(dst + 0 * stride), r0, 0);
|
||||
vst1_lane_u32((uint32_t *)(dst + 1 * stride), r1, 0);
|
||||
vst1_lane_u32((uint32_t *)(dst + 2 * stride), r2, 0);
|
||||
vst1_lane_u32((uint32_t *)(dst + 3 * stride), r3, 0);
|
||||
dst[3 * stride + 3] = above[7];
|
||||
}
|
||||
|
||||
void aom_d45_predictor_8x8_neon(uint8_t *dst, ptrdiff_t stride,
|
||||
const uint8_t *above, const uint8_t *left) {
|
||||
static const uint8_t shuffle1[8] = { 1, 2, 3, 4, 5, 6, 7, 7 };
|
||||
static const uint8_t shuffle2[8] = { 2, 3, 4, 5, 6, 7, 7, 7 };
|
||||
const uint8x8_t sh_12345677 = vld1_u8(shuffle1);
|
||||
const uint8x8_t sh_23456777 = vld1_u8(shuffle2);
|
||||
const uint8x8_t A0 = vld1_u8(above); // top row
|
||||
const uint8x8_t A1 = vtbl1_u8(A0, sh_12345677);
|
||||
const uint8x8_t A2 = vtbl1_u8(A0, sh_23456777);
|
||||
const uint8x8_t avg1 = vhadd_u8(A0, A2);
|
||||
uint8x8_t row = vrhadd_u8(avg1, A1);
|
||||
int i;
|
||||
(void)left;
|
||||
for (i = 0; i < 7; ++i) {
|
||||
vst1_u8(dst + i * stride, row);
|
||||
row = vtbl1_u8(row, sh_12345677);
|
||||
}
|
||||
vst1_u8(dst + i * stride, row);
|
||||
}
|
||||
|
||||
void aom_d45_predictor_16x16_neon(uint8_t *dst, ptrdiff_t stride,
|
||||
const uint8_t *above, const uint8_t *left) {
|
||||
const uint8x16_t A0 = vld1q_u8(above); // top row
|
||||
const uint8x16_t above_right = vld1q_dup_u8(above + 15);
|
||||
const uint8x16_t A1 = vextq_u8(A0, above_right, 1);
|
||||
const uint8x16_t A2 = vextq_u8(A0, above_right, 2);
|
||||
const uint8x16_t avg1 = vhaddq_u8(A0, A2);
|
||||
uint8x16_t row = vrhaddq_u8(avg1, A1);
|
||||
int i;
|
||||
(void)left;
|
||||
for (i = 0; i < 15; ++i) {
|
||||
vst1q_u8(dst + i * stride, row);
|
||||
row = vextq_u8(row, above_right, 1);
|
||||
}
|
||||
vst1q_u8(dst + i * stride, row);
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
void aom_d135_predictor_4x4_neon(uint8_t *dst, ptrdiff_t stride,
|
||||
const uint8_t *above, const uint8_t *left) {
|
||||
const uint8x8_t XABCD_u8 = vld1_u8(above - 1);
|
||||
const uint64x1_t XABCD = vreinterpret_u64_u8(XABCD_u8);
|
||||
const uint64x1_t ____XABC = vshl_n_u64(XABCD, 32);
|
||||
const uint32x2_t zero = vdup_n_u32(0);
|
||||
const uint32x2_t IJKL = vld1_lane_u32((const uint32_t *)left, zero, 0);
|
||||
const uint8x8_t IJKL_u8 = vreinterpret_u8_u32(IJKL);
|
||||
const uint64x1_t LKJI____ = vreinterpret_u64_u8(vrev32_u8(IJKL_u8));
|
||||
const uint64x1_t LKJIXABC = vorr_u64(LKJI____, ____XABC);
|
||||
const uint8x8_t KJIXABC_ = vreinterpret_u8_u64(vshr_n_u64(LKJIXABC, 8));
|
||||
const uint8x8_t JIXABC__ = vreinterpret_u8_u64(vshr_n_u64(LKJIXABC, 16));
|
||||
const uint8_t D = vget_lane_u8(XABCD_u8, 4);
|
||||
const uint8x8_t JIXABCD_ = vset_lane_u8(D, JIXABC__, 6);
|
||||
const uint8x8_t LKJIXABC_u8 = vreinterpret_u8_u64(LKJIXABC);
|
||||
const uint8x8_t avg1 = vhadd_u8(JIXABCD_, LKJIXABC_u8);
|
||||
const uint8x8_t avg2 = vrhadd_u8(avg1, KJIXABC_);
|
||||
const uint64x1_t avg2_u64 = vreinterpret_u64_u8(avg2);
|
||||
const uint32x2_t r3 = vreinterpret_u32_u8(avg2);
|
||||
const uint32x2_t r2 = vreinterpret_u32_u64(vshr_n_u64(avg2_u64, 8));
|
||||
const uint32x2_t r1 = vreinterpret_u32_u64(vshr_n_u64(avg2_u64, 16));
|
||||
const uint32x2_t r0 = vreinterpret_u32_u64(vshr_n_u64(avg2_u64, 24));
|
||||
vst1_lane_u32((uint32_t *)(dst + 0 * stride), r0, 0);
|
||||
vst1_lane_u32((uint32_t *)(dst + 1 * stride), r1, 0);
|
||||
vst1_lane_u32((uint32_t *)(dst + 2 * stride), r2, 0);
|
||||
vst1_lane_u32((uint32_t *)(dst + 3 * stride), r3, 0);
|
||||
}
|
||||
|
||||
#if !HAVE_NEON_ASM
|
||||
|
||||
void aom_v_predictor_4x4_neon(uint8_t *dst, ptrdiff_t stride,
|
||||
const uint8_t *above, const uint8_t *left) {
|
||||
int i;
|
||||
uint32x2_t d0u32 = vdup_n_u32(0);
|
||||
(void)left;
|
||||
|
||||
d0u32 = vld1_lane_u32((const uint32_t *)above, d0u32, 0);
|
||||
for (i = 0; i < 4; i++, dst += stride)
|
||||
vst1_lane_u32((uint32_t *)dst, d0u32, 0);
|
||||
}
|
||||
|
||||
void aom_v_predictor_8x8_neon(uint8_t *dst, ptrdiff_t stride,
|
||||
const uint8_t *above, const uint8_t *left) {
|
||||
int i;
|
||||
uint8x8_t d0u8 = vdup_n_u8(0);
|
||||
(void)left;
|
||||
|
||||
d0u8 = vld1_u8(above);
|
||||
for (i = 0; i < 8; i++, dst += stride) vst1_u8(dst, d0u8);
|
||||
}
|
||||
|
||||
void aom_v_predictor_16x16_neon(uint8_t *dst, ptrdiff_t stride,
|
||||
const uint8_t *above, const uint8_t *left) {
|
||||
int i;
|
||||
uint8x16_t q0u8 = vdupq_n_u8(0);
|
||||
(void)left;
|
||||
|
||||
q0u8 = vld1q_u8(above);
|
||||
for (i = 0; i < 16; i++, dst += stride) vst1q_u8(dst, q0u8);
|
||||
}
|
||||
|
||||
void aom_v_predictor_32x32_neon(uint8_t *dst, ptrdiff_t stride,
|
||||
const uint8_t *above, const uint8_t *left) {
|
||||
int i;
|
||||
uint8x16_t q0u8 = vdupq_n_u8(0);
|
||||
uint8x16_t q1u8 = vdupq_n_u8(0);
|
||||
(void)left;
|
||||
|
||||
q0u8 = vld1q_u8(above);
|
||||
q1u8 = vld1q_u8(above + 16);
|
||||
for (i = 0; i < 32; i++, dst += stride) {
|
||||
vst1q_u8(dst, q0u8);
|
||||
vst1q_u8(dst + 16, q1u8);
|
||||
}
|
||||
}
|
||||
|
||||
void aom_h_predictor_4x4_neon(uint8_t *dst, ptrdiff_t stride,
|
||||
const uint8_t *above, const uint8_t *left) {
|
||||
uint8x8_t d0u8 = vdup_n_u8(0);
|
||||
uint32x2_t d1u32 = vdup_n_u32(0);
|
||||
(void)above;
|
||||
|
||||
d1u32 = vld1_lane_u32((const uint32_t *)left, d1u32, 0);
|
||||
|
||||
d0u8 = vdup_lane_u8(vreinterpret_u8_u32(d1u32), 0);
|
||||
vst1_lane_u32((uint32_t *)dst, vreinterpret_u32_u8(d0u8), 0);
|
||||
dst += stride;
|
||||
d0u8 = vdup_lane_u8(vreinterpret_u8_u32(d1u32), 1);
|
||||
vst1_lane_u32((uint32_t *)dst, vreinterpret_u32_u8(d0u8), 0);
|
||||
dst += stride;
|
||||
d0u8 = vdup_lane_u8(vreinterpret_u8_u32(d1u32), 2);
|
||||
vst1_lane_u32((uint32_t *)dst, vreinterpret_u32_u8(d0u8), 0);
|
||||
dst += stride;
|
||||
d0u8 = vdup_lane_u8(vreinterpret_u8_u32(d1u32), 3);
|
||||
vst1_lane_u32((uint32_t *)dst, vreinterpret_u32_u8(d0u8), 0);
|
||||
}
|
||||
|
||||
void aom_h_predictor_8x8_neon(uint8_t *dst, ptrdiff_t stride,
|
||||
const uint8_t *above, const uint8_t *left) {
|
||||
uint8x8_t d0u8 = vdup_n_u8(0);
|
||||
uint64x1_t d1u64 = vdup_n_u64(0);
|
||||
(void)above;
|
||||
|
||||
d1u64 = vld1_u64((const uint64_t *)left);
|
||||
|
||||
d0u8 = vdup_lane_u8(vreinterpret_u8_u64(d1u64), 0);
|
||||
vst1_u8(dst, d0u8);
|
||||
dst += stride;
|
||||
d0u8 = vdup_lane_u8(vreinterpret_u8_u64(d1u64), 1);
|
||||
vst1_u8(dst, d0u8);
|
||||
dst += stride;
|
||||
d0u8 = vdup_lane_u8(vreinterpret_u8_u64(d1u64), 2);
|
||||
vst1_u8(dst, d0u8);
|
||||
dst += stride;
|
||||
d0u8 = vdup_lane_u8(vreinterpret_u8_u64(d1u64), 3);
|
||||
vst1_u8(dst, d0u8);
|
||||
dst += stride;
|
||||
d0u8 = vdup_lane_u8(vreinterpret_u8_u64(d1u64), 4);
|
||||
vst1_u8(dst, d0u8);
|
||||
dst += stride;
|
||||
d0u8 = vdup_lane_u8(vreinterpret_u8_u64(d1u64), 5);
|
||||
vst1_u8(dst, d0u8);
|
||||
dst += stride;
|
||||
d0u8 = vdup_lane_u8(vreinterpret_u8_u64(d1u64), 6);
|
||||
vst1_u8(dst, d0u8);
|
||||
dst += stride;
|
||||
d0u8 = vdup_lane_u8(vreinterpret_u8_u64(d1u64), 7);
|
||||
vst1_u8(dst, d0u8);
|
||||
}
|
||||
|
||||
void aom_h_predictor_16x16_neon(uint8_t *dst, ptrdiff_t stride,
|
||||
const uint8_t *above, const uint8_t *left) {
|
||||
int j;
|
||||
uint8x8_t d2u8 = vdup_n_u8(0);
|
||||
uint8x16_t q0u8 = vdupq_n_u8(0);
|
||||
uint8x16_t q1u8 = vdupq_n_u8(0);
|
||||
(void)above;
|
||||
|
||||
q1u8 = vld1q_u8(left);
|
||||
d2u8 = vget_low_u8(q1u8);
|
||||
for (j = 0; j < 2; j++, d2u8 = vget_high_u8(q1u8)) {
|
||||
q0u8 = vdupq_lane_u8(d2u8, 0);
|
||||
vst1q_u8(dst, q0u8);
|
||||
dst += stride;
|
||||
q0u8 = vdupq_lane_u8(d2u8, 1);
|
||||
vst1q_u8(dst, q0u8);
|
||||
dst += stride;
|
||||
q0u8 = vdupq_lane_u8(d2u8, 2);
|
||||
vst1q_u8(dst, q0u8);
|
||||
dst += stride;
|
||||
q0u8 = vdupq_lane_u8(d2u8, 3);
|
||||
vst1q_u8(dst, q0u8);
|
||||
dst += stride;
|
||||
q0u8 = vdupq_lane_u8(d2u8, 4);
|
||||
vst1q_u8(dst, q0u8);
|
||||
dst += stride;
|
||||
q0u8 = vdupq_lane_u8(d2u8, 5);
|
||||
vst1q_u8(dst, q0u8);
|
||||
dst += stride;
|
||||
q0u8 = vdupq_lane_u8(d2u8, 6);
|
||||
vst1q_u8(dst, q0u8);
|
||||
dst += stride;
|
||||
q0u8 = vdupq_lane_u8(d2u8, 7);
|
||||
vst1q_u8(dst, q0u8);
|
||||
dst += stride;
|
||||
}
|
||||
}
|
||||
|
||||
void aom_h_predictor_32x32_neon(uint8_t *dst, ptrdiff_t stride,
|
||||
const uint8_t *above, const uint8_t *left) {
|
||||
int j, k;
|
||||
uint8x8_t d2u8 = vdup_n_u8(0);
|
||||
uint8x16_t q0u8 = vdupq_n_u8(0);
|
||||
uint8x16_t q1u8 = vdupq_n_u8(0);
|
||||
(void)above;
|
||||
|
||||
for (k = 0; k < 2; k++, left += 16) {
|
||||
q1u8 = vld1q_u8(left);
|
||||
d2u8 = vget_low_u8(q1u8);
|
||||
for (j = 0; j < 2; j++, d2u8 = vget_high_u8(q1u8)) {
|
||||
q0u8 = vdupq_lane_u8(d2u8, 0);
|
||||
vst1q_u8(dst, q0u8);
|
||||
vst1q_u8(dst + 16, q0u8);
|
||||
dst += stride;
|
||||
q0u8 = vdupq_lane_u8(d2u8, 1);
|
||||
vst1q_u8(dst, q0u8);
|
||||
vst1q_u8(dst + 16, q0u8);
|
||||
dst += stride;
|
||||
q0u8 = vdupq_lane_u8(d2u8, 2);
|
||||
vst1q_u8(dst, q0u8);
|
||||
vst1q_u8(dst + 16, q0u8);
|
||||
dst += stride;
|
||||
q0u8 = vdupq_lane_u8(d2u8, 3);
|
||||
vst1q_u8(dst, q0u8);
|
||||
vst1q_u8(dst + 16, q0u8);
|
||||
dst += stride;
|
||||
q0u8 = vdupq_lane_u8(d2u8, 4);
|
||||
vst1q_u8(dst, q0u8);
|
||||
vst1q_u8(dst + 16, q0u8);
|
||||
dst += stride;
|
||||
q0u8 = vdupq_lane_u8(d2u8, 5);
|
||||
vst1q_u8(dst, q0u8);
|
||||
vst1q_u8(dst + 16, q0u8);
|
||||
dst += stride;
|
||||
q0u8 = vdupq_lane_u8(d2u8, 6);
|
||||
vst1q_u8(dst, q0u8);
|
||||
vst1q_u8(dst + 16, q0u8);
|
||||
dst += stride;
|
||||
q0u8 = vdupq_lane_u8(d2u8, 7);
|
||||
vst1q_u8(dst, q0u8);
|
||||
vst1q_u8(dst + 16, q0u8);
|
||||
dst += stride;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void aom_tm_predictor_4x4_neon(uint8_t *dst, ptrdiff_t stride,
|
||||
const uint8_t *above, const uint8_t *left) {
|
||||
int i;
|
||||
uint16x8_t q1u16, q3u16;
|
||||
int16x8_t q1s16;
|
||||
uint8x8_t d0u8 = vdup_n_u8(0);
|
||||
uint32x2_t d2u32 = vdup_n_u32(0);
|
||||
|
||||
d0u8 = vld1_dup_u8(above - 1);
|
||||
d2u32 = vld1_lane_u32((const uint32_t *)above, d2u32, 0);
|
||||
q3u16 = vsubl_u8(vreinterpret_u8_u32(d2u32), d0u8);
|
||||
for (i = 0; i < 4; i++, dst += stride) {
|
||||
q1u16 = vdupq_n_u16((uint16_t)left[i]);
|
||||
q1s16 =
|
||||
vaddq_s16(vreinterpretq_s16_u16(q1u16), vreinterpretq_s16_u16(q3u16));
|
||||
d0u8 = vqmovun_s16(q1s16);
|
||||
vst1_lane_u32((uint32_t *)dst, vreinterpret_u32_u8(d0u8), 0);
|
||||
}
|
||||
}
|
||||
|
||||
void aom_tm_predictor_8x8_neon(uint8_t *dst, ptrdiff_t stride,
|
||||
const uint8_t *above, const uint8_t *left) {
|
||||
int j;
|
||||
uint16x8_t q0u16, q3u16, q10u16;
|
||||
int16x8_t q0s16;
|
||||
uint16x4_t d20u16;
|
||||
uint8x8_t d0u8, d2u8, d30u8;
|
||||
|
||||
d0u8 = vld1_dup_u8(above - 1);
|
||||
d30u8 = vld1_u8(left);
|
||||
d2u8 = vld1_u8(above);
|
||||
q10u16 = vmovl_u8(d30u8);
|
||||
q3u16 = vsubl_u8(d2u8, d0u8);
|
||||
d20u16 = vget_low_u16(q10u16);
|
||||
for (j = 0; j < 2; j++, d20u16 = vget_high_u16(q10u16)) {
|
||||
q0u16 = vdupq_lane_u16(d20u16, 0);
|
||||
q0s16 =
|
||||
vaddq_s16(vreinterpretq_s16_u16(q3u16), vreinterpretq_s16_u16(q0u16));
|
||||
d0u8 = vqmovun_s16(q0s16);
|
||||
vst1_u64((uint64_t *)dst, vreinterpret_u64_u8(d0u8));
|
||||
dst += stride;
|
||||
q0u16 = vdupq_lane_u16(d20u16, 1);
|
||||
q0s16 =
|
||||
vaddq_s16(vreinterpretq_s16_u16(q3u16), vreinterpretq_s16_u16(q0u16));
|
||||
d0u8 = vqmovun_s16(q0s16);
|
||||
vst1_u64((uint64_t *)dst, vreinterpret_u64_u8(d0u8));
|
||||
dst += stride;
|
||||
q0u16 = vdupq_lane_u16(d20u16, 2);
|
||||
q0s16 =
|
||||
vaddq_s16(vreinterpretq_s16_u16(q3u16), vreinterpretq_s16_u16(q0u16));
|
||||
d0u8 = vqmovun_s16(q0s16);
|
||||
vst1_u64((uint64_t *)dst, vreinterpret_u64_u8(d0u8));
|
||||
dst += stride;
|
||||
q0u16 = vdupq_lane_u16(d20u16, 3);
|
||||
q0s16 =
|
||||
vaddq_s16(vreinterpretq_s16_u16(q3u16), vreinterpretq_s16_u16(q0u16));
|
||||
d0u8 = vqmovun_s16(q0s16);
|
||||
vst1_u64((uint64_t *)dst, vreinterpret_u64_u8(d0u8));
|
||||
dst += stride;
|
||||
}
|
||||
}
|
||||
|
||||
void aom_tm_predictor_16x16_neon(uint8_t *dst, ptrdiff_t stride,
|
||||
const uint8_t *above, const uint8_t *left) {
|
||||
int j, k;
|
||||
uint16x8_t q0u16, q2u16, q3u16, q8u16, q10u16;
|
||||
uint8x16_t q0u8, q1u8;
|
||||
int16x8_t q0s16, q1s16, q8s16, q11s16;
|
||||
uint16x4_t d20u16;
|
||||
uint8x8_t d2u8, d3u8, d18u8, d22u8, d23u8;
|
||||
|
||||
q0u8 = vld1q_dup_u8(above - 1);
|
||||
q1u8 = vld1q_u8(above);
|
||||
q2u16 = vsubl_u8(vget_low_u8(q1u8), vget_low_u8(q0u8));
|
||||
q3u16 = vsubl_u8(vget_high_u8(q1u8), vget_high_u8(q0u8));
|
||||
for (k = 0; k < 2; k++, left += 8) {
|
||||
d18u8 = vld1_u8(left);
|
||||
q10u16 = vmovl_u8(d18u8);
|
||||
d20u16 = vget_low_u16(q10u16);
|
||||
for (j = 0; j < 2; j++, d20u16 = vget_high_u16(q10u16)) {
|
||||
q0u16 = vdupq_lane_u16(d20u16, 0);
|
||||
q8u16 = vdupq_lane_u16(d20u16, 1);
|
||||
q1s16 =
|
||||
vaddq_s16(vreinterpretq_s16_u16(q0u16), vreinterpretq_s16_u16(q2u16));
|
||||
q0s16 =
|
||||
vaddq_s16(vreinterpretq_s16_u16(q0u16), vreinterpretq_s16_u16(q3u16));
|
||||
q11s16 =
|
||||
vaddq_s16(vreinterpretq_s16_u16(q8u16), vreinterpretq_s16_u16(q2u16));
|
||||
q8s16 =
|
||||
vaddq_s16(vreinterpretq_s16_u16(q8u16), vreinterpretq_s16_u16(q3u16));
|
||||
d2u8 = vqmovun_s16(q1s16);
|
||||
d3u8 = vqmovun_s16(q0s16);
|
||||
d22u8 = vqmovun_s16(q11s16);
|
||||
d23u8 = vqmovun_s16(q8s16);
|
||||
vst1_u64((uint64_t *)dst, vreinterpret_u64_u8(d2u8));
|
||||
vst1_u64((uint64_t *)(dst + 8), vreinterpret_u64_u8(d3u8));
|
||||
dst += stride;
|
||||
vst1_u64((uint64_t *)dst, vreinterpret_u64_u8(d22u8));
|
||||
vst1_u64((uint64_t *)(dst + 8), vreinterpret_u64_u8(d23u8));
|
||||
dst += stride;
|
||||
|
||||
q0u16 = vdupq_lane_u16(d20u16, 2);
|
||||
q8u16 = vdupq_lane_u16(d20u16, 3);
|
||||
q1s16 =
|
||||
vaddq_s16(vreinterpretq_s16_u16(q0u16), vreinterpretq_s16_u16(q2u16));
|
||||
q0s16 =
|
||||
vaddq_s16(vreinterpretq_s16_u16(q0u16), vreinterpretq_s16_u16(q3u16));
|
||||
q11s16 =
|
||||
vaddq_s16(vreinterpretq_s16_u16(q8u16), vreinterpretq_s16_u16(q2u16));
|
||||
q8s16 =
|
||||
vaddq_s16(vreinterpretq_s16_u16(q8u16), vreinterpretq_s16_u16(q3u16));
|
||||
d2u8 = vqmovun_s16(q1s16);
|
||||
d3u8 = vqmovun_s16(q0s16);
|
||||
d22u8 = vqmovun_s16(q11s16);
|
||||
d23u8 = vqmovun_s16(q8s16);
|
||||
vst1_u64((uint64_t *)dst, vreinterpret_u64_u8(d2u8));
|
||||
vst1_u64((uint64_t *)(dst + 8), vreinterpret_u64_u8(d3u8));
|
||||
dst += stride;
|
||||
vst1_u64((uint64_t *)dst, vreinterpret_u64_u8(d22u8));
|
||||
vst1_u64((uint64_t *)(dst + 8), vreinterpret_u64_u8(d23u8));
|
||||
dst += stride;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void aom_tm_predictor_32x32_neon(uint8_t *dst, ptrdiff_t stride,
|
||||
const uint8_t *above, const uint8_t *left) {
|
||||
int j, k;
|
||||
uint16x8_t q0u16, q3u16, q8u16, q9u16, q10u16, q11u16;
|
||||
uint8x16_t q0u8, q1u8, q2u8;
|
||||
int16x8_t q12s16, q13s16, q14s16, q15s16;
|
||||
uint16x4_t d6u16;
|
||||
uint8x8_t d0u8, d1u8, d2u8, d3u8, d26u8;
|
||||
|
||||
q0u8 = vld1q_dup_u8(above - 1);
|
||||
q1u8 = vld1q_u8(above);
|
||||
q2u8 = vld1q_u8(above + 16);
|
||||
q8u16 = vsubl_u8(vget_low_u8(q1u8), vget_low_u8(q0u8));
|
||||
q9u16 = vsubl_u8(vget_high_u8(q1u8), vget_high_u8(q0u8));
|
||||
q10u16 = vsubl_u8(vget_low_u8(q2u8), vget_low_u8(q0u8));
|
||||
q11u16 = vsubl_u8(vget_high_u8(q2u8), vget_high_u8(q0u8));
|
||||
for (k = 0; k < 4; k++, left += 8) {
|
||||
d26u8 = vld1_u8(left);
|
||||
q3u16 = vmovl_u8(d26u8);
|
||||
d6u16 = vget_low_u16(q3u16);
|
||||
for (j = 0; j < 2; j++, d6u16 = vget_high_u16(q3u16)) {
|
||||
q0u16 = vdupq_lane_u16(d6u16, 0);
|
||||
q12s16 =
|
||||
vaddq_s16(vreinterpretq_s16_u16(q0u16), vreinterpretq_s16_u16(q8u16));
|
||||
q13s16 =
|
||||
vaddq_s16(vreinterpretq_s16_u16(q0u16), vreinterpretq_s16_u16(q9u16));
|
||||
q14s16 = vaddq_s16(vreinterpretq_s16_u16(q0u16),
|
||||
vreinterpretq_s16_u16(q10u16));
|
||||
q15s16 = vaddq_s16(vreinterpretq_s16_u16(q0u16),
|
||||
vreinterpretq_s16_u16(q11u16));
|
||||
d0u8 = vqmovun_s16(q12s16);
|
||||
d1u8 = vqmovun_s16(q13s16);
|
||||
d2u8 = vqmovun_s16(q14s16);
|
||||
d3u8 = vqmovun_s16(q15s16);
|
||||
q0u8 = vcombine_u8(d0u8, d1u8);
|
||||
q1u8 = vcombine_u8(d2u8, d3u8);
|
||||
vst1q_u64((uint64_t *)dst, vreinterpretq_u64_u8(q0u8));
|
||||
vst1q_u64((uint64_t *)(dst + 16), vreinterpretq_u64_u8(q1u8));
|
||||
dst += stride;
|
||||
|
||||
q0u16 = vdupq_lane_u16(d6u16, 1);
|
||||
q12s16 =
|
||||
vaddq_s16(vreinterpretq_s16_u16(q0u16), vreinterpretq_s16_u16(q8u16));
|
||||
q13s16 =
|
||||
vaddq_s16(vreinterpretq_s16_u16(q0u16), vreinterpretq_s16_u16(q9u16));
|
||||
q14s16 = vaddq_s16(vreinterpretq_s16_u16(q0u16),
|
||||
vreinterpretq_s16_u16(q10u16));
|
||||
q15s16 = vaddq_s16(vreinterpretq_s16_u16(q0u16),
|
||||
vreinterpretq_s16_u16(q11u16));
|
||||
d0u8 = vqmovun_s16(q12s16);
|
||||
d1u8 = vqmovun_s16(q13s16);
|
||||
d2u8 = vqmovun_s16(q14s16);
|
||||
d3u8 = vqmovun_s16(q15s16);
|
||||
q0u8 = vcombine_u8(d0u8, d1u8);
|
||||
q1u8 = vcombine_u8(d2u8, d3u8);
|
||||
vst1q_u64((uint64_t *)dst, vreinterpretq_u64_u8(q0u8));
|
||||
vst1q_u64((uint64_t *)(dst + 16), vreinterpretq_u64_u8(q1u8));
|
||||
dst += stride;
|
||||
|
||||
q0u16 = vdupq_lane_u16(d6u16, 2);
|
||||
q12s16 =
|
||||
vaddq_s16(vreinterpretq_s16_u16(q0u16), vreinterpretq_s16_u16(q8u16));
|
||||
q13s16 =
|
||||
vaddq_s16(vreinterpretq_s16_u16(q0u16), vreinterpretq_s16_u16(q9u16));
|
||||
q14s16 = vaddq_s16(vreinterpretq_s16_u16(q0u16),
|
||||
vreinterpretq_s16_u16(q10u16));
|
||||
q15s16 = vaddq_s16(vreinterpretq_s16_u16(q0u16),
|
||||
vreinterpretq_s16_u16(q11u16));
|
||||
d0u8 = vqmovun_s16(q12s16);
|
||||
d1u8 = vqmovun_s16(q13s16);
|
||||
d2u8 = vqmovun_s16(q14s16);
|
||||
d3u8 = vqmovun_s16(q15s16);
|
||||
q0u8 = vcombine_u8(d0u8, d1u8);
|
||||
q1u8 = vcombine_u8(d2u8, d3u8);
|
||||
vst1q_u64((uint64_t *)dst, vreinterpretq_u64_u8(q0u8));
|
||||
vst1q_u64((uint64_t *)(dst + 16), vreinterpretq_u64_u8(q1u8));
|
||||
dst += stride;
|
||||
|
||||
q0u16 = vdupq_lane_u16(d6u16, 3);
|
||||
q12s16 =
|
||||
vaddq_s16(vreinterpretq_s16_u16(q0u16), vreinterpretq_s16_u16(q8u16));
|
||||
q13s16 =
|
||||
vaddq_s16(vreinterpretq_s16_u16(q0u16), vreinterpretq_s16_u16(q9u16));
|
||||
q14s16 = vaddq_s16(vreinterpretq_s16_u16(q0u16),
|
||||
vreinterpretq_s16_u16(q10u16));
|
||||
q15s16 = vaddq_s16(vreinterpretq_s16_u16(q0u16),
|
||||
vreinterpretq_s16_u16(q11u16));
|
||||
d0u8 = vqmovun_s16(q12s16);
|
||||
d1u8 = vqmovun_s16(q13s16);
|
||||
d2u8 = vqmovun_s16(q14s16);
|
||||
d3u8 = vqmovun_s16(q15s16);
|
||||
q0u8 = vcombine_u8(d0u8, d1u8);
|
||||
q1u8 = vcombine_u8(d2u8, d3u8);
|
||||
vst1q_u64((uint64_t *)dst, vreinterpretq_u64_u8(q0u8));
|
||||
vst1q_u64((uint64_t *)(dst + 16), vreinterpretq_u64_u8(q1u8));
|
||||
dst += stride;
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif // !HAVE_NEON_ASM
|
||||
@@ -1,202 +0,0 @@
|
||||
;
|
||||
; Copyright (c) 2016, Alliance for Open Media. All rights reserved
|
||||
;
|
||||
; This source code is subject to the terms of the BSD 2 Clause License and
|
||||
; the Alliance for Open Media Patent License 1.0. If the BSD 2 Clause License
|
||||
; was not distributed with this source code in the LICENSE file, you can
|
||||
; obtain it at www.aomedia.org/license/software. If the Alliance for Open
|
||||
; Media Patent License 1.0 was not distributed with this source code in the
|
||||
; PATENTS file, you can obtain it at www.aomedia.org/license/patent.
|
||||
;
|
||||
|
||||
;
|
||||
|
||||
EXPORT |aom_lpf_horizontal_4_dual_neon|
|
||||
ARM
|
||||
|
||||
AREA ||.text||, CODE, READONLY, ALIGN=2
|
||||
|
||||
;void aom_lpf_horizontal_4_dual_neon(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)
|
||||
; r0 uint8_t *s,
|
||||
; r1 int p,
|
||||
; r2 const uint8_t *blimit0,
|
||||
; r3 const uint8_t *limit0,
|
||||
; sp const uint8_t *thresh0,
|
||||
; sp+4 const uint8_t *blimit1,
|
||||
; sp+8 const uint8_t *limit1,
|
||||
; sp+12 const uint8_t *thresh1,
|
||||
|
||||
|aom_lpf_horizontal_4_dual_neon| PROC
|
||||
push {lr}
|
||||
|
||||
ldr r12, [sp, #4] ; load thresh0
|
||||
vld1.8 {d0}, [r2] ; load blimit0 to first half q
|
||||
vld1.8 {d2}, [r3] ; load limit0 to first half q
|
||||
|
||||
add r1, r1, r1 ; double pitch
|
||||
ldr r2, [sp, #8] ; load blimit1
|
||||
|
||||
vld1.8 {d4}, [r12] ; load thresh0 to first half q
|
||||
|
||||
ldr r3, [sp, #12] ; load limit1
|
||||
ldr r12, [sp, #16] ; load thresh1
|
||||
vld1.8 {d1}, [r2] ; load blimit1 to 2nd half q
|
||||
|
||||
sub r2, r0, r1, lsl #1 ; s[-4 * p]
|
||||
|
||||
vld1.8 {d3}, [r3] ; load limit1 to 2nd half q
|
||||
vld1.8 {d5}, [r12] ; load thresh1 to 2nd half q
|
||||
|
||||
vpush {d8-d15} ; save neon registers
|
||||
|
||||
add r3, r2, r1, lsr #1 ; s[-3 * p]
|
||||
|
||||
vld1.u8 {q3}, [r2@64], r1 ; p3
|
||||
vld1.u8 {q4}, [r3@64], r1 ; p2
|
||||
vld1.u8 {q5}, [r2@64], r1 ; p1
|
||||
vld1.u8 {q6}, [r3@64], r1 ; p0
|
||||
vld1.u8 {q7}, [r2@64], r1 ; q0
|
||||
vld1.u8 {q8}, [r3@64], r1 ; q1
|
||||
vld1.u8 {q9}, [r2@64] ; q2
|
||||
vld1.u8 {q10}, [r3@64] ; q3
|
||||
|
||||
sub r2, r2, r1, lsl #1
|
||||
sub r3, r3, r1, lsl #1
|
||||
|
||||
bl aom_loop_filter_neon_16
|
||||
|
||||
vst1.u8 {q5}, [r2@64], r1 ; store op1
|
||||
vst1.u8 {q6}, [r3@64], r1 ; store op0
|
||||
vst1.u8 {q7}, [r2@64], r1 ; store oq0
|
||||
vst1.u8 {q8}, [r3@64], r1 ; store oq1
|
||||
|
||||
vpop {d8-d15} ; restore neon registers
|
||||
|
||||
pop {pc}
|
||||
ENDP ; |aom_lpf_horizontal_4_dual_neon|
|
||||
|
||||
; void aom_loop_filter_neon_16();
|
||||
; This is a helper function for the loopfilters. The invidual functions do the
|
||||
; necessary load, transpose (if necessary) and store. This function uses
|
||||
; registers d8-d15, so the calling function must save those registers.
|
||||
;
|
||||
; r0-r3, r12 PRESERVE
|
||||
; q0 blimit
|
||||
; q1 limit
|
||||
; q2 thresh
|
||||
; q3 p3
|
||||
; q4 p2
|
||||
; q5 p1
|
||||
; q6 p0
|
||||
; q7 q0
|
||||
; q8 q1
|
||||
; q9 q2
|
||||
; q10 q3
|
||||
;
|
||||
; Outputs:
|
||||
; q5 op1
|
||||
; q6 op0
|
||||
; q7 oq0
|
||||
; q8 oq1
|
||||
|aom_loop_filter_neon_16| PROC
|
||||
|
||||
; filter_mask
|
||||
vabd.u8 q11, q3, q4 ; m1 = abs(p3 - p2)
|
||||
vabd.u8 q12, q4, q5 ; m2 = abs(p2 - p1)
|
||||
vabd.u8 q13, q5, q6 ; m3 = abs(p1 - p0)
|
||||
vabd.u8 q14, q8, q7 ; m4 = abs(q1 - q0)
|
||||
vabd.u8 q3, q9, q8 ; m5 = abs(q2 - q1)
|
||||
vabd.u8 q4, q10, q9 ; m6 = abs(q3 - q2)
|
||||
|
||||
; only compare the largest value to limit
|
||||
vmax.u8 q11, q11, q12 ; m7 = max(m1, m2)
|
||||
vmax.u8 q12, q13, q14 ; m8 = max(m3, m4)
|
||||
|
||||
vabd.u8 q9, q6, q7 ; abs(p0 - q0)
|
||||
|
||||
vmax.u8 q3, q3, q4 ; m9 = max(m5, m6)
|
||||
|
||||
vmov.u8 q10, #0x80
|
||||
|
||||
vmax.u8 q15, q11, q12 ; m10 = max(m7, m8)
|
||||
|
||||
vcgt.u8 q13, q13, q2 ; (abs(p1 - p0) > thresh)*-1
|
||||
vcgt.u8 q14, q14, q2 ; (abs(q1 - q0) > thresh)*-1
|
||||
vmax.u8 q15, q15, q3 ; m11 = max(m10, m9)
|
||||
|
||||
vabd.u8 q2, q5, q8 ; a = abs(p1 - q1)
|
||||
vqadd.u8 q9, q9, q9 ; b = abs(p0 - q0) * 2
|
||||
|
||||
veor q7, q7, q10 ; qs0
|
||||
|
||||
vcge.u8 q15, q1, q15 ; abs(m11) > limit
|
||||
|
||||
vshr.u8 q2, q2, #1 ; a = a / 2
|
||||
veor q6, q6, q10 ; ps0
|
||||
|
||||
veor q5, q5, q10 ; ps1
|
||||
vqadd.u8 q9, q9, q2 ; a = b + a
|
||||
|
||||
veor q8, q8, q10 ; qs1
|
||||
|
||||
vmov.u16 q4, #3
|
||||
|
||||
vsubl.s8 q2, d14, d12 ; ( qs0 - ps0)
|
||||
vsubl.s8 q11, d15, d13
|
||||
|
||||
vcge.u8 q9, q0, q9 ; a > blimit
|
||||
|
||||
vqsub.s8 q1, q5, q8 ; filter = clamp(ps1-qs1)
|
||||
vorr q14, q13, q14 ; hev
|
||||
|
||||
vmul.i16 q2, q2, q4 ; 3 * ( qs0 - ps0)
|
||||
vmul.i16 q11, q11, q4
|
||||
|
||||
vand q1, q1, q14 ; filter &= hev
|
||||
vand q15, q15, q9 ; mask
|
||||
|
||||
vmov.u8 q4, #3
|
||||
|
||||
vaddw.s8 q2, q2, d2 ; filter + 3 * (qs0 - ps0)
|
||||
vaddw.s8 q11, q11, d3
|
||||
|
||||
vmov.u8 q9, #4
|
||||
|
||||
; filter = clamp(filter + 3 * ( qs0 - ps0))
|
||||
vqmovn.s16 d2, q2
|
||||
vqmovn.s16 d3, q11
|
||||
vand q1, q1, q15 ; filter &= mask
|
||||
|
||||
vqadd.s8 q2, q1, q4 ; filter2 = clamp(filter+3)
|
||||
vqadd.s8 q1, q1, q9 ; filter1 = clamp(filter+4)
|
||||
vshr.s8 q2, q2, #3 ; filter2 >>= 3
|
||||
vshr.s8 q1, q1, #3 ; filter1 >>= 3
|
||||
|
||||
|
||||
vqadd.s8 q11, q6, q2 ; u = clamp(ps0 + filter2)
|
||||
vqsub.s8 q0, q7, q1 ; u = clamp(qs0 - filter1)
|
||||
|
||||
; outer tap adjustments
|
||||
vrshr.s8 q1, q1, #1 ; filter = ++filter1 >> 1
|
||||
|
||||
veor q7, q0, q10 ; *oq0 = u^0x80
|
||||
|
||||
vbic q1, q1, q14 ; filter &= ~hev
|
||||
|
||||
vqadd.s8 q13, q5, q1 ; u = clamp(ps1 + filter)
|
||||
vqsub.s8 q12, q8, q1 ; u = clamp(qs1 - filter)
|
||||
|
||||
veor q6, q11, q10 ; *op0 = u^0x80
|
||||
veor q5, q13, q10 ; *op1 = u^0x80
|
||||
veor q8, q12, q10 ; *oq1 = u^0x80
|
||||
|
||||
bx lr
|
||||
ENDP ; |aom_loop_filter_neon_16|
|
||||
|
||||
END
|
||||
@@ -1,174 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2016, Alliance for Open Media. All rights reserved
|
||||
*
|
||||
* This source code is subject to the terms of the BSD 2 Clause License and
|
||||
* the Alliance for Open Media Patent License 1.0. If the BSD 2 Clause License
|
||||
* was not distributed with this source code in the LICENSE file, you can
|
||||
* obtain it at www.aomedia.org/license/software. If the Alliance for Open
|
||||
* Media Patent License 1.0 was not distributed with this source code in the
|
||||
* PATENTS file, you can obtain it at www.aomedia.org/license/patent.
|
||||
*/
|
||||
|
||||
#include <arm_neon.h>
|
||||
|
||||
#include "./aom_dsp_rtcd.h"
|
||||
#include "./aom_config.h"
|
||||
#include "aom/aom_integer.h"
|
||||
|
||||
static INLINE void loop_filter_neon_16(uint8x16_t qblimit, // blimit
|
||||
uint8x16_t qlimit, // limit
|
||||
uint8x16_t qthresh, // thresh
|
||||
uint8x16_t q3, // p3
|
||||
uint8x16_t q4, // p2
|
||||
uint8x16_t q5, // p1
|
||||
uint8x16_t q6, // p0
|
||||
uint8x16_t q7, // q0
|
||||
uint8x16_t q8, // q1
|
||||
uint8x16_t q9, // q2
|
||||
uint8x16_t q10, // q3
|
||||
uint8x16_t *q5r, // p1
|
||||
uint8x16_t *q6r, // p0
|
||||
uint8x16_t *q7r, // q0
|
||||
uint8x16_t *q8r) { // q1
|
||||
uint8x16_t q1u8, q2u8, q11u8, q12u8, q13u8, q14u8, q15u8;
|
||||
int16x8_t q2s16, q11s16;
|
||||
uint16x8_t q4u16;
|
||||
int8x16_t q0s8, q1s8, q2s8, q11s8, q12s8, q13s8;
|
||||
int8x8_t d2s8, d3s8;
|
||||
|
||||
q11u8 = vabdq_u8(q3, q4);
|
||||
q12u8 = vabdq_u8(q4, q5);
|
||||
q13u8 = vabdq_u8(q5, q6);
|
||||
q14u8 = vabdq_u8(q8, q7);
|
||||
q3 = vabdq_u8(q9, q8);
|
||||
q4 = vabdq_u8(q10, q9);
|
||||
|
||||
q11u8 = vmaxq_u8(q11u8, q12u8);
|
||||
q12u8 = vmaxq_u8(q13u8, q14u8);
|
||||
q3 = vmaxq_u8(q3, q4);
|
||||
q15u8 = vmaxq_u8(q11u8, q12u8);
|
||||
|
||||
q9 = vabdq_u8(q6, q7);
|
||||
|
||||
// aom_hevmask
|
||||
q13u8 = vcgtq_u8(q13u8, qthresh);
|
||||
q14u8 = vcgtq_u8(q14u8, qthresh);
|
||||
q15u8 = vmaxq_u8(q15u8, q3);
|
||||
|
||||
q2u8 = vabdq_u8(q5, q8);
|
||||
q9 = vqaddq_u8(q9, q9);
|
||||
|
||||
q15u8 = vcgeq_u8(qlimit, q15u8);
|
||||
|
||||
// aom_filter() function
|
||||
// convert to signed
|
||||
q10 = vdupq_n_u8(0x80);
|
||||
q8 = veorq_u8(q8, q10);
|
||||
q7 = veorq_u8(q7, q10);
|
||||
q6 = veorq_u8(q6, q10);
|
||||
q5 = veorq_u8(q5, q10);
|
||||
|
||||
q2u8 = vshrq_n_u8(q2u8, 1);
|
||||
q9 = vqaddq_u8(q9, q2u8);
|
||||
|
||||
q2s16 = vsubl_s8(vget_low_s8(vreinterpretq_s8_u8(q7)),
|
||||
vget_low_s8(vreinterpretq_s8_u8(q6)));
|
||||
q11s16 = vsubl_s8(vget_high_s8(vreinterpretq_s8_u8(q7)),
|
||||
vget_high_s8(vreinterpretq_s8_u8(q6)));
|
||||
|
||||
q9 = vcgeq_u8(qblimit, q9);
|
||||
|
||||
q1s8 = vqsubq_s8(vreinterpretq_s8_u8(q5), vreinterpretq_s8_u8(q8));
|
||||
|
||||
q14u8 = vorrq_u8(q13u8, q14u8);
|
||||
|
||||
q4u16 = vdupq_n_u16(3);
|
||||
q2s16 = vmulq_s16(q2s16, vreinterpretq_s16_u16(q4u16));
|
||||
q11s16 = vmulq_s16(q11s16, vreinterpretq_s16_u16(q4u16));
|
||||
|
||||
q1u8 = vandq_u8(vreinterpretq_u8_s8(q1s8), q14u8);
|
||||
q15u8 = vandq_u8(q15u8, q9);
|
||||
|
||||
q1s8 = vreinterpretq_s8_u8(q1u8);
|
||||
q2s16 = vaddw_s8(q2s16, vget_low_s8(q1s8));
|
||||
q11s16 = vaddw_s8(q11s16, vget_high_s8(q1s8));
|
||||
|
||||
q4 = vdupq_n_u8(3);
|
||||
q9 = vdupq_n_u8(4);
|
||||
// aom_filter = clamp(aom_filter + 3 * ( qs0 - ps0))
|
||||
d2s8 = vqmovn_s16(q2s16);
|
||||
d3s8 = vqmovn_s16(q11s16);
|
||||
q1s8 = vcombine_s8(d2s8, d3s8);
|
||||
q1u8 = vandq_u8(vreinterpretq_u8_s8(q1s8), q15u8);
|
||||
q1s8 = vreinterpretq_s8_u8(q1u8);
|
||||
|
||||
q2s8 = vqaddq_s8(q1s8, vreinterpretq_s8_u8(q4));
|
||||
q1s8 = vqaddq_s8(q1s8, vreinterpretq_s8_u8(q9));
|
||||
q2s8 = vshrq_n_s8(q2s8, 3);
|
||||
q1s8 = vshrq_n_s8(q1s8, 3);
|
||||
|
||||
q11s8 = vqaddq_s8(vreinterpretq_s8_u8(q6), q2s8);
|
||||
q0s8 = vqsubq_s8(vreinterpretq_s8_u8(q7), q1s8);
|
||||
|
||||
q1s8 = vrshrq_n_s8(q1s8, 1);
|
||||
q1s8 = vbicq_s8(q1s8, vreinterpretq_s8_u8(q14u8));
|
||||
|
||||
q13s8 = vqaddq_s8(vreinterpretq_s8_u8(q5), q1s8);
|
||||
q12s8 = vqsubq_s8(vreinterpretq_s8_u8(q8), q1s8);
|
||||
|
||||
*q8r = veorq_u8(vreinterpretq_u8_s8(q12s8), q10);
|
||||
*q7r = veorq_u8(vreinterpretq_u8_s8(q0s8), q10);
|
||||
*q6r = veorq_u8(vreinterpretq_u8_s8(q11s8), q10);
|
||||
*q5r = veorq_u8(vreinterpretq_u8_s8(q13s8), q10);
|
||||
return;
|
||||
}
|
||||
|
||||
void aom_lpf_horizontal_4_dual_neon(
|
||||
uint8_t *s, int p /* pitch */, const uint8_t *blimit0,
|
||||
const uint8_t *limit0, const uint8_t *thresh0, const uint8_t *blimit1,
|
||||
const uint8_t *limit1, const uint8_t *thresh1) {
|
||||
uint8x8_t dblimit0, dlimit0, dthresh0, dblimit1, dlimit1, dthresh1;
|
||||
uint8x16_t qblimit, qlimit, qthresh;
|
||||
uint8x16_t q3u8, q4u8, q5u8, q6u8, q7u8, q8u8, q9u8, q10u8;
|
||||
|
||||
dblimit0 = vld1_u8(blimit0);
|
||||
dlimit0 = vld1_u8(limit0);
|
||||
dthresh0 = vld1_u8(thresh0);
|
||||
dblimit1 = vld1_u8(blimit1);
|
||||
dlimit1 = vld1_u8(limit1);
|
||||
dthresh1 = vld1_u8(thresh1);
|
||||
qblimit = vcombine_u8(dblimit0, dblimit1);
|
||||
qlimit = vcombine_u8(dlimit0, dlimit1);
|
||||
qthresh = vcombine_u8(dthresh0, dthresh1);
|
||||
|
||||
s -= (p << 2);
|
||||
|
||||
q3u8 = vld1q_u8(s);
|
||||
s += p;
|
||||
q4u8 = vld1q_u8(s);
|
||||
s += p;
|
||||
q5u8 = vld1q_u8(s);
|
||||
s += p;
|
||||
q6u8 = vld1q_u8(s);
|
||||
s += p;
|
||||
q7u8 = vld1q_u8(s);
|
||||
s += p;
|
||||
q8u8 = vld1q_u8(s);
|
||||
s += p;
|
||||
q9u8 = vld1q_u8(s);
|
||||
s += p;
|
||||
q10u8 = vld1q_u8(s);
|
||||
|
||||
loop_filter_neon_16(qblimit, qlimit, qthresh, q3u8, q4u8, q5u8, q6u8, q7u8,
|
||||
q8u8, q9u8, q10u8, &q5u8, &q6u8, &q7u8, &q8u8);
|
||||
|
||||
s -= (p * 5);
|
||||
vst1q_u8(s, q5u8);
|
||||
s += p;
|
||||
vst1q_u8(s, q6u8);
|
||||
s += p;
|
||||
vst1q_u8(s, q7u8);
|
||||
s += p;
|
||||
vst1q_u8(s, q8u8);
|
||||
return;
|
||||
}
|
||||
@@ -1,252 +0,0 @@
|
||||
;
|
||||
; Copyright (c) 2016, Alliance for Open Media. All rights reserved
|
||||
;
|
||||
; This source code is subject to the terms of the BSD 2 Clause License and
|
||||
; the Alliance for Open Media Patent License 1.0. If the BSD 2 Clause License
|
||||
; was not distributed with this source code in the LICENSE file, you can
|
||||
; obtain it at www.aomedia.org/license/software. If the Alliance for Open
|
||||
; Media Patent License 1.0 was not distributed with this source code in the
|
||||
; PATENTS file, you can obtain it at www.aomedia.org/license/patent.
|
||||
;
|
||||
|
||||
;
|
||||
|
||||
EXPORT |aom_lpf_horizontal_4_neon|
|
||||
EXPORT |aom_lpf_vertical_4_neon|
|
||||
ARM
|
||||
|
||||
AREA ||.text||, CODE, READONLY, ALIGN=2
|
||||
|
||||
; Currently aom only works on iterations 8 at a time. The aom loop filter
|
||||
; works on 16 iterations at a time.
|
||||
;
|
||||
; void aom_lpf_horizontal_4_neon(uint8_t *s,
|
||||
; int p /* pitch */,
|
||||
; const uint8_t *blimit,
|
||||
; const uint8_t *limit,
|
||||
; const uint8_t *thresh)
|
||||
;
|
||||
; r0 uint8_t *s,
|
||||
; r1 int p, /* pitch */
|
||||
; r2 const uint8_t *blimit,
|
||||
; r3 const uint8_t *limit,
|
||||
; sp const uint8_t *thresh,
|
||||
|aom_lpf_horizontal_4_neon| PROC
|
||||
push {lr}
|
||||
|
||||
vld1.8 {d0[]}, [r2] ; duplicate *blimit
|
||||
ldr r2, [sp, #4] ; load thresh
|
||||
add r1, r1, r1 ; double pitch
|
||||
|
||||
vld1.8 {d1[]}, [r3] ; duplicate *limit
|
||||
vld1.8 {d2[]}, [r2] ; duplicate *thresh
|
||||
|
||||
sub r2, r0, r1, lsl #1 ; move src pointer down by 4 lines
|
||||
add r3, r2, r1, lsr #1 ; set to 3 lines down
|
||||
|
||||
vld1.u8 {d3}, [r2@64], r1 ; p3
|
||||
vld1.u8 {d4}, [r3@64], r1 ; p2
|
||||
vld1.u8 {d5}, [r2@64], r1 ; p1
|
||||
vld1.u8 {d6}, [r3@64], r1 ; p0
|
||||
vld1.u8 {d7}, [r2@64], r1 ; q0
|
||||
vld1.u8 {d16}, [r3@64], r1 ; q1
|
||||
vld1.u8 {d17}, [r2@64] ; q2
|
||||
vld1.u8 {d18}, [r3@64] ; q3
|
||||
|
||||
sub r2, r2, r1, lsl #1
|
||||
sub r3, r3, r1, lsl #1
|
||||
|
||||
bl aom_loop_filter_neon
|
||||
|
||||
vst1.u8 {d4}, [r2@64], r1 ; store op1
|
||||
vst1.u8 {d5}, [r3@64], r1 ; store op0
|
||||
vst1.u8 {d6}, [r2@64], r1 ; store oq0
|
||||
vst1.u8 {d7}, [r3@64], r1 ; store oq1
|
||||
|
||||
pop {pc}
|
||||
ENDP ; |aom_lpf_horizontal_4_neon|
|
||||
|
||||
; Currently aom only works on iterations 8 at a time. The aom loop filter
|
||||
; works on 16 iterations at a time.
|
||||
;
|
||||
; void aom_lpf_vertical_4_neon(uint8_t *s,
|
||||
; int p /* pitch */,
|
||||
; const uint8_t *blimit,
|
||||
; const uint8_t *limit,
|
||||
; const uint8_t *thresh)
|
||||
;
|
||||
; r0 uint8_t *s,
|
||||
; r1 int p, /* pitch */
|
||||
; r2 const uint8_t *blimit,
|
||||
; r3 const uint8_t *limit,
|
||||
; sp const uint8_t *thresh,
|
||||
|aom_lpf_vertical_4_neon| PROC
|
||||
push {lr}
|
||||
|
||||
vld1.8 {d0[]}, [r2] ; duplicate *blimit
|
||||
vld1.8 {d1[]}, [r3] ; duplicate *limit
|
||||
|
||||
ldr r3, [sp, #4] ; load thresh
|
||||
sub r2, r0, #4 ; move s pointer down by 4 columns
|
||||
|
||||
vld1.8 {d2[]}, [r3] ; duplicate *thresh
|
||||
|
||||
vld1.u8 {d3}, [r2], r1 ; load s data
|
||||
vld1.u8 {d4}, [r2], r1
|
||||
vld1.u8 {d5}, [r2], r1
|
||||
vld1.u8 {d6}, [r2], r1
|
||||
vld1.u8 {d7}, [r2], r1
|
||||
vld1.u8 {d16}, [r2], r1
|
||||
vld1.u8 {d17}, [r2], r1
|
||||
vld1.u8 {d18}, [r2]
|
||||
|
||||
;transpose to 8x16 matrix
|
||||
vtrn.32 d3, d7
|
||||
vtrn.32 d4, d16
|
||||
vtrn.32 d5, d17
|
||||
vtrn.32 d6, d18
|
||||
|
||||
vtrn.16 d3, d5
|
||||
vtrn.16 d4, d6
|
||||
vtrn.16 d7, d17
|
||||
vtrn.16 d16, d18
|
||||
|
||||
vtrn.8 d3, d4
|
||||
vtrn.8 d5, d6
|
||||
vtrn.8 d7, d16
|
||||
vtrn.8 d17, d18
|
||||
|
||||
bl aom_loop_filter_neon
|
||||
|
||||
sub r0, r0, #2
|
||||
|
||||
;store op1, op0, oq0, oq1
|
||||
vst4.8 {d4[0], d5[0], d6[0], d7[0]}, [r0], r1
|
||||
vst4.8 {d4[1], d5[1], d6[1], d7[1]}, [r0], r1
|
||||
vst4.8 {d4[2], d5[2], d6[2], d7[2]}, [r0], r1
|
||||
vst4.8 {d4[3], d5[3], d6[3], d7[3]}, [r0], r1
|
||||
vst4.8 {d4[4], d5[4], d6[4], d7[4]}, [r0], r1
|
||||
vst4.8 {d4[5], d5[5], d6[5], d7[5]}, [r0], r1
|
||||
vst4.8 {d4[6], d5[6], d6[6], d7[6]}, [r0], r1
|
||||
vst4.8 {d4[7], d5[7], d6[7], d7[7]}, [r0]
|
||||
|
||||
pop {pc}
|
||||
ENDP ; |aom_lpf_vertical_4_neon|
|
||||
|
||||
; void aom_loop_filter_neon();
|
||||
; This is a helper function for the loopfilters. The invidual functions do the
|
||||
; necessary load, transpose (if necessary) and store. The function does not use
|
||||
; registers d8-d15.
|
||||
;
|
||||
; Inputs:
|
||||
; r0-r3, r12 PRESERVE
|
||||
; d0 blimit
|
||||
; d1 limit
|
||||
; d2 thresh
|
||||
; d3 p3
|
||||
; d4 p2
|
||||
; d5 p1
|
||||
; d6 p0
|
||||
; d7 q0
|
||||
; d16 q1
|
||||
; d17 q2
|
||||
; d18 q3
|
||||
;
|
||||
; Outputs:
|
||||
; d4 op1
|
||||
; d5 op0
|
||||
; d6 oq0
|
||||
; d7 oq1
|
||||
|aom_loop_filter_neon| PROC
|
||||
; filter_mask
|
||||
vabd.u8 d19, d3, d4 ; m1 = abs(p3 - p2)
|
||||
vabd.u8 d20, d4, d5 ; m2 = abs(p2 - p1)
|
||||
vabd.u8 d21, d5, d6 ; m3 = abs(p1 - p0)
|
||||
vabd.u8 d22, d16, d7 ; m4 = abs(q1 - q0)
|
||||
vabd.u8 d3, d17, d16 ; m5 = abs(q2 - q1)
|
||||
vabd.u8 d4, d18, d17 ; m6 = abs(q3 - q2)
|
||||
|
||||
; only compare the largest value to limit
|
||||
vmax.u8 d19, d19, d20 ; m1 = max(m1, m2)
|
||||
vmax.u8 d20, d21, d22 ; m2 = max(m3, m4)
|
||||
|
||||
vabd.u8 d17, d6, d7 ; abs(p0 - q0)
|
||||
|
||||
vmax.u8 d3, d3, d4 ; m3 = max(m5, m6)
|
||||
|
||||
vmov.u8 d18, #0x80
|
||||
|
||||
vmax.u8 d23, d19, d20 ; m1 = max(m1, m2)
|
||||
|
||||
; hevmask
|
||||
vcgt.u8 d21, d21, d2 ; (abs(p1 - p0) > thresh)*-1
|
||||
vcgt.u8 d22, d22, d2 ; (abs(q1 - q0) > thresh)*-1
|
||||
vmax.u8 d23, d23, d3 ; m1 = max(m1, m3)
|
||||
|
||||
vabd.u8 d28, d5, d16 ; a = abs(p1 - q1)
|
||||
vqadd.u8 d17, d17, d17 ; b = abs(p0 - q0) * 2
|
||||
|
||||
veor d7, d7, d18 ; qs0
|
||||
|
||||
vcge.u8 d23, d1, d23 ; abs(m1) > limit
|
||||
|
||||
; filter() function
|
||||
; convert to signed
|
||||
|
||||
vshr.u8 d28, d28, #1 ; a = a / 2
|
||||
veor d6, d6, d18 ; ps0
|
||||
|
||||
veor d5, d5, d18 ; ps1
|
||||
vqadd.u8 d17, d17, d28 ; a = b + a
|
||||
|
||||
veor d16, d16, d18 ; qs1
|
||||
|
||||
vmov.u8 d19, #3
|
||||
|
||||
vsub.s8 d28, d7, d6 ; ( qs0 - ps0)
|
||||
|
||||
vcge.u8 d17, d0, d17 ; a > blimit
|
||||
|
||||
vqsub.s8 d27, d5, d16 ; filter = clamp(ps1-qs1)
|
||||
vorr d22, d21, d22 ; hevmask
|
||||
|
||||
vmull.s8 q12, d28, d19 ; 3 * ( qs0 - ps0)
|
||||
|
||||
vand d27, d27, d22 ; filter &= hev
|
||||
vand d23, d23, d17 ; filter_mask
|
||||
|
||||
vaddw.s8 q12, q12, d27 ; filter + 3 * (qs0 - ps0)
|
||||
|
||||
vmov.u8 d17, #4
|
||||
|
||||
; filter = clamp(filter + 3 * ( qs0 - ps0))
|
||||
vqmovn.s16 d27, q12
|
||||
|
||||
vand d27, d27, d23 ; filter &= mask
|
||||
|
||||
vqadd.s8 d28, d27, d19 ; filter2 = clamp(filter+3)
|
||||
vqadd.s8 d27, d27, d17 ; filter1 = clamp(filter+4)
|
||||
vshr.s8 d28, d28, #3 ; filter2 >>= 3
|
||||
vshr.s8 d27, d27, #3 ; filter1 >>= 3
|
||||
|
||||
vqadd.s8 d19, d6, d28 ; u = clamp(ps0 + filter2)
|
||||
vqsub.s8 d26, d7, d27 ; u = clamp(qs0 - filter1)
|
||||
|
||||
; outer tap adjustments
|
||||
vrshr.s8 d27, d27, #1 ; filter = ++filter1 >> 1
|
||||
|
||||
veor d6, d26, d18 ; *oq0 = u^0x80
|
||||
|
||||
vbic d27, d27, d22 ; filter &= ~hev
|
||||
|
||||
vqadd.s8 d21, d5, d27 ; u = clamp(ps1 + filter)
|
||||
vqsub.s8 d20, d16, d27 ; u = clamp(qs1 - filter)
|
||||
|
||||
veor d5, d19, d18 ; *op0 = u^0x80
|
||||
veor d4, d21, d18 ; *op1 = u^0x80
|
||||
veor d7, d20, d18 ; *oq1 = u^0x80
|
||||
|
||||
bx lr
|
||||
ENDP ; |aom_loop_filter_neon|
|
||||
|
||||
END
|
||||
@@ -1,250 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2016, Alliance for Open Media. All rights reserved
|
||||
*
|
||||
* This source code is subject to the terms of the BSD 2 Clause License and
|
||||
* the Alliance for Open Media Patent License 1.0. If the BSD 2 Clause License
|
||||
* was not distributed with this source code in the LICENSE file, you can
|
||||
* obtain it at www.aomedia.org/license/software. If the Alliance for Open
|
||||
* Media Patent License 1.0 was not distributed with this source code in the
|
||||
* PATENTS file, you can obtain it at www.aomedia.org/license/patent.
|
||||
*/
|
||||
|
||||
#include <arm_neon.h>
|
||||
|
||||
#include "./aom_dsp_rtcd.h"
|
||||
|
||||
static INLINE void loop_filter_neon(uint8x8_t dblimit, // flimit
|
||||
uint8x8_t dlimit, // limit
|
||||
uint8x8_t dthresh, // thresh
|
||||
uint8x8_t d3u8, // p3
|
||||
uint8x8_t d4u8, // p2
|
||||
uint8x8_t d5u8, // p1
|
||||
uint8x8_t d6u8, // p0
|
||||
uint8x8_t d7u8, // q0
|
||||
uint8x8_t d16u8, // q1
|
||||
uint8x8_t d17u8, // q2
|
||||
uint8x8_t d18u8, // q3
|
||||
uint8x8_t *d4ru8, // p1
|
||||
uint8x8_t *d5ru8, // p0
|
||||
uint8x8_t *d6ru8, // q0
|
||||
uint8x8_t *d7ru8) { // q1
|
||||
uint8x8_t d19u8, d20u8, d21u8, d22u8, d23u8, d27u8, d28u8;
|
||||
int16x8_t q12s16;
|
||||
int8x8_t d19s8, d20s8, d21s8, d26s8, d27s8, d28s8;
|
||||
|
||||
d19u8 = vabd_u8(d3u8, d4u8);
|
||||
d20u8 = vabd_u8(d4u8, d5u8);
|
||||
d21u8 = vabd_u8(d5u8, d6u8);
|
||||
d22u8 = vabd_u8(d16u8, d7u8);
|
||||
d3u8 = vabd_u8(d17u8, d16u8);
|
||||
d4u8 = vabd_u8(d18u8, d17u8);
|
||||
|
||||
d19u8 = vmax_u8(d19u8, d20u8);
|
||||
d20u8 = vmax_u8(d21u8, d22u8);
|
||||
d3u8 = vmax_u8(d3u8, d4u8);
|
||||
d23u8 = vmax_u8(d19u8, d20u8);
|
||||
|
||||
d17u8 = vabd_u8(d6u8, d7u8);
|
||||
|
||||
d21u8 = vcgt_u8(d21u8, dthresh);
|
||||
d22u8 = vcgt_u8(d22u8, dthresh);
|
||||
d23u8 = vmax_u8(d23u8, d3u8);
|
||||
|
||||
d28u8 = vabd_u8(d5u8, d16u8);
|
||||
d17u8 = vqadd_u8(d17u8, d17u8);
|
||||
|
||||
d23u8 = vcge_u8(dlimit, d23u8);
|
||||
|
||||
d18u8 = vdup_n_u8(0x80);
|
||||
d5u8 = veor_u8(d5u8, d18u8);
|
||||
d6u8 = veor_u8(d6u8, d18u8);
|
||||
d7u8 = veor_u8(d7u8, d18u8);
|
||||
d16u8 = veor_u8(d16u8, d18u8);
|
||||
|
||||
d28u8 = vshr_n_u8(d28u8, 1);
|
||||
d17u8 = vqadd_u8(d17u8, d28u8);
|
||||
|
||||
d19u8 = vdup_n_u8(3);
|
||||
|
||||
d28s8 = vsub_s8(vreinterpret_s8_u8(d7u8), vreinterpret_s8_u8(d6u8));
|
||||
|
||||
d17u8 = vcge_u8(dblimit, d17u8);
|
||||
|
||||
d27s8 = vqsub_s8(vreinterpret_s8_u8(d5u8), vreinterpret_s8_u8(d16u8));
|
||||
|
||||
d22u8 = vorr_u8(d21u8, d22u8);
|
||||
|
||||
q12s16 = vmull_s8(d28s8, vreinterpret_s8_u8(d19u8));
|
||||
|
||||
d27u8 = vand_u8(vreinterpret_u8_s8(d27s8), d22u8);
|
||||
d23u8 = vand_u8(d23u8, d17u8);
|
||||
|
||||
q12s16 = vaddw_s8(q12s16, vreinterpret_s8_u8(d27u8));
|
||||
|
||||
d17u8 = vdup_n_u8(4);
|
||||
|
||||
d27s8 = vqmovn_s16(q12s16);
|
||||
d27u8 = vand_u8(vreinterpret_u8_s8(d27s8), d23u8);
|
||||
d27s8 = vreinterpret_s8_u8(d27u8);
|
||||
|
||||
d28s8 = vqadd_s8(d27s8, vreinterpret_s8_u8(d19u8));
|
||||
d27s8 = vqadd_s8(d27s8, vreinterpret_s8_u8(d17u8));
|
||||
d28s8 = vshr_n_s8(d28s8, 3);
|
||||
d27s8 = vshr_n_s8(d27s8, 3);
|
||||
|
||||
d19s8 = vqadd_s8(vreinterpret_s8_u8(d6u8), d28s8);
|
||||
d26s8 = vqsub_s8(vreinterpret_s8_u8(d7u8), d27s8);
|
||||
|
||||
d27s8 = vrshr_n_s8(d27s8, 1);
|
||||
d27s8 = vbic_s8(d27s8, vreinterpret_s8_u8(d22u8));
|
||||
|
||||
d21s8 = vqadd_s8(vreinterpret_s8_u8(d5u8), d27s8);
|
||||
d20s8 = vqsub_s8(vreinterpret_s8_u8(d16u8), d27s8);
|
||||
|
||||
*d4ru8 = veor_u8(vreinterpret_u8_s8(d21s8), d18u8);
|
||||
*d5ru8 = veor_u8(vreinterpret_u8_s8(d19s8), d18u8);
|
||||
*d6ru8 = veor_u8(vreinterpret_u8_s8(d26s8), d18u8);
|
||||
*d7ru8 = veor_u8(vreinterpret_u8_s8(d20s8), d18u8);
|
||||
return;
|
||||
}
|
||||
|
||||
void aom_lpf_horizontal_4_neon(uint8_t *src, int pitch, const uint8_t *blimit,
|
||||
const uint8_t *limit, const uint8_t *thresh) {
|
||||
int i;
|
||||
uint8_t *s, *psrc;
|
||||
uint8x8_t dblimit, dlimit, dthresh;
|
||||
uint8x8_t d3u8, d4u8, d5u8, d6u8, d7u8, d16u8, d17u8, d18u8;
|
||||
|
||||
dblimit = vld1_u8(blimit);
|
||||
dlimit = vld1_u8(limit);
|
||||
dthresh = vld1_u8(thresh);
|
||||
|
||||
psrc = src - (pitch << 2);
|
||||
for (i = 0; i < 1; i++) {
|
||||
s = psrc + i * 8;
|
||||
|
||||
d3u8 = vld1_u8(s);
|
||||
s += pitch;
|
||||
d4u8 = vld1_u8(s);
|
||||
s += pitch;
|
||||
d5u8 = vld1_u8(s);
|
||||
s += pitch;
|
||||
d6u8 = vld1_u8(s);
|
||||
s += pitch;
|
||||
d7u8 = vld1_u8(s);
|
||||
s += pitch;
|
||||
d16u8 = vld1_u8(s);
|
||||
s += pitch;
|
||||
d17u8 = vld1_u8(s);
|
||||
s += pitch;
|
||||
d18u8 = vld1_u8(s);
|
||||
|
||||
loop_filter_neon(dblimit, dlimit, dthresh, d3u8, d4u8, d5u8, d6u8, d7u8,
|
||||
d16u8, d17u8, d18u8, &d4u8, &d5u8, &d6u8, &d7u8);
|
||||
|
||||
s -= (pitch * 5);
|
||||
vst1_u8(s, d4u8);
|
||||
s += pitch;
|
||||
vst1_u8(s, d5u8);
|
||||
s += pitch;
|
||||
vst1_u8(s, d6u8);
|
||||
s += pitch;
|
||||
vst1_u8(s, d7u8);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
void aom_lpf_vertical_4_neon(uint8_t *src, int pitch, const uint8_t *blimit,
|
||||
const uint8_t *limit, const uint8_t *thresh) {
|
||||
int i, pitch8;
|
||||
uint8_t *s;
|
||||
uint8x8_t dblimit, dlimit, dthresh;
|
||||
uint8x8_t d3u8, d4u8, d5u8, d6u8, d7u8, d16u8, d17u8, d18u8;
|
||||
uint32x2x2_t d2tmp0, d2tmp1, d2tmp2, d2tmp3;
|
||||
uint16x4x2_t d2tmp4, d2tmp5, d2tmp6, d2tmp7;
|
||||
uint8x8x2_t d2tmp8, d2tmp9, d2tmp10, d2tmp11;
|
||||
uint8x8x4_t d4Result;
|
||||
|
||||
dblimit = vld1_u8(blimit);
|
||||
dlimit = vld1_u8(limit);
|
||||
dthresh = vld1_u8(thresh);
|
||||
|
||||
pitch8 = pitch * 8;
|
||||
for (i = 0; i < 1; i++, src += pitch8) {
|
||||
s = src - (i + 1) * 4;
|
||||
|
||||
d3u8 = vld1_u8(s);
|
||||
s += pitch;
|
||||
d4u8 = vld1_u8(s);
|
||||
s += pitch;
|
||||
d5u8 = vld1_u8(s);
|
||||
s += pitch;
|
||||
d6u8 = vld1_u8(s);
|
||||
s += pitch;
|
||||
d7u8 = vld1_u8(s);
|
||||
s += pitch;
|
||||
d16u8 = vld1_u8(s);
|
||||
s += pitch;
|
||||
d17u8 = vld1_u8(s);
|
||||
s += pitch;
|
||||
d18u8 = vld1_u8(s);
|
||||
|
||||
d2tmp0 = vtrn_u32(vreinterpret_u32_u8(d3u8), vreinterpret_u32_u8(d7u8));
|
||||
d2tmp1 = vtrn_u32(vreinterpret_u32_u8(d4u8), vreinterpret_u32_u8(d16u8));
|
||||
d2tmp2 = vtrn_u32(vreinterpret_u32_u8(d5u8), vreinterpret_u32_u8(d17u8));
|
||||
d2tmp3 = vtrn_u32(vreinterpret_u32_u8(d6u8), vreinterpret_u32_u8(d18u8));
|
||||
|
||||
d2tmp4 = vtrn_u16(vreinterpret_u16_u32(d2tmp0.val[0]),
|
||||
vreinterpret_u16_u32(d2tmp2.val[0]));
|
||||
d2tmp5 = vtrn_u16(vreinterpret_u16_u32(d2tmp1.val[0]),
|
||||
vreinterpret_u16_u32(d2tmp3.val[0]));
|
||||
d2tmp6 = vtrn_u16(vreinterpret_u16_u32(d2tmp0.val[1]),
|
||||
vreinterpret_u16_u32(d2tmp2.val[1]));
|
||||
d2tmp7 = vtrn_u16(vreinterpret_u16_u32(d2tmp1.val[1]),
|
||||
vreinterpret_u16_u32(d2tmp3.val[1]));
|
||||
|
||||
d2tmp8 = vtrn_u8(vreinterpret_u8_u16(d2tmp4.val[0]),
|
||||
vreinterpret_u8_u16(d2tmp5.val[0]));
|
||||
d2tmp9 = vtrn_u8(vreinterpret_u8_u16(d2tmp4.val[1]),
|
||||
vreinterpret_u8_u16(d2tmp5.val[1]));
|
||||
d2tmp10 = vtrn_u8(vreinterpret_u8_u16(d2tmp6.val[0]),
|
||||
vreinterpret_u8_u16(d2tmp7.val[0]));
|
||||
d2tmp11 = vtrn_u8(vreinterpret_u8_u16(d2tmp6.val[1]),
|
||||
vreinterpret_u8_u16(d2tmp7.val[1]));
|
||||
|
||||
d3u8 = d2tmp8.val[0];
|
||||
d4u8 = d2tmp8.val[1];
|
||||
d5u8 = d2tmp9.val[0];
|
||||
d6u8 = d2tmp9.val[1];
|
||||
d7u8 = d2tmp10.val[0];
|
||||
d16u8 = d2tmp10.val[1];
|
||||
d17u8 = d2tmp11.val[0];
|
||||
d18u8 = d2tmp11.val[1];
|
||||
|
||||
loop_filter_neon(dblimit, dlimit, dthresh, d3u8, d4u8, d5u8, d6u8, d7u8,
|
||||
d16u8, d17u8, d18u8, &d4u8, &d5u8, &d6u8, &d7u8);
|
||||
|
||||
d4Result.val[0] = d4u8;
|
||||
d4Result.val[1] = d5u8;
|
||||
d4Result.val[2] = d6u8;
|
||||
d4Result.val[3] = d7u8;
|
||||
|
||||
src -= 2;
|
||||
vst4_lane_u8(src, d4Result, 0);
|
||||
src += pitch;
|
||||
vst4_lane_u8(src, d4Result, 1);
|
||||
src += pitch;
|
||||
vst4_lane_u8(src, d4Result, 2);
|
||||
src += pitch;
|
||||
vst4_lane_u8(src, d4Result, 3);
|
||||
src += pitch;
|
||||
vst4_lane_u8(src, d4Result, 4);
|
||||
src += pitch;
|
||||
vst4_lane_u8(src, d4Result, 5);
|
||||
src += pitch;
|
||||
vst4_lane_u8(src, d4Result, 6);
|
||||
src += pitch;
|
||||
vst4_lane_u8(src, d4Result, 7);
|
||||
}
|
||||
return;
|
||||
}
|
||||
@@ -1,430 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2016, Alliance for Open Media. All rights reserved
|
||||
*
|
||||
* This source code is subject to the terms of the BSD 2 Clause License and
|
||||
* the Alliance for Open Media Patent License 1.0. If the BSD 2 Clause License
|
||||
* was not distributed with this source code in the LICENSE file, you can
|
||||
* obtain it at www.aomedia.org/license/software. If the Alliance for Open
|
||||
* Media Patent License 1.0 was not distributed with this source code in the
|
||||
* PATENTS file, you can obtain it at www.aomedia.org/license/patent.
|
||||
*/
|
||||
|
||||
#include <arm_neon.h>
|
||||
|
||||
#include "./aom_dsp_rtcd.h"
|
||||
|
||||
static INLINE void mbloop_filter_neon(uint8x8_t dblimit, // mblimit
|
||||
uint8x8_t dlimit, // limit
|
||||
uint8x8_t dthresh, // thresh
|
||||
uint8x8_t d3u8, // p2
|
||||
uint8x8_t d4u8, // p2
|
||||
uint8x8_t d5u8, // p1
|
||||
uint8x8_t d6u8, // p0
|
||||
uint8x8_t d7u8, // q0
|
||||
uint8x8_t d16u8, // q1
|
||||
uint8x8_t d17u8, // q2
|
||||
uint8x8_t d18u8, // q3
|
||||
uint8x8_t *d0ru8, // p1
|
||||
uint8x8_t *d1ru8, // p1
|
||||
uint8x8_t *d2ru8, // p0
|
||||
uint8x8_t *d3ru8, // q0
|
||||
uint8x8_t *d4ru8, // q1
|
||||
uint8x8_t *d5ru8) { // q1
|
||||
uint32_t flat;
|
||||
uint8x8_t d0u8, d1u8, d2u8, d19u8, d20u8, d21u8, d22u8, d23u8, d24u8;
|
||||
uint8x8_t d25u8, d26u8, d27u8, d28u8, d29u8, d30u8, d31u8;
|
||||
int16x8_t q15s16;
|
||||
uint16x8_t q10u16, q14u16;
|
||||
int8x8_t d21s8, d24s8, d25s8, d26s8, d28s8, d29s8, d30s8;
|
||||
|
||||
d19u8 = vabd_u8(d3u8, d4u8);
|
||||
d20u8 = vabd_u8(d4u8, d5u8);
|
||||
d21u8 = vabd_u8(d5u8, d6u8);
|
||||
d22u8 = vabd_u8(d16u8, d7u8);
|
||||
d23u8 = vabd_u8(d17u8, d16u8);
|
||||
d24u8 = vabd_u8(d18u8, d17u8);
|
||||
|
||||
d19u8 = vmax_u8(d19u8, d20u8);
|
||||
d20u8 = vmax_u8(d21u8, d22u8);
|
||||
|
||||
d25u8 = vabd_u8(d6u8, d4u8);
|
||||
|
||||
d23u8 = vmax_u8(d23u8, d24u8);
|
||||
|
||||
d26u8 = vabd_u8(d7u8, d17u8);
|
||||
|
||||
d19u8 = vmax_u8(d19u8, d20u8);
|
||||
|
||||
d24u8 = vabd_u8(d6u8, d7u8);
|
||||
d27u8 = vabd_u8(d3u8, d6u8);
|
||||
d28u8 = vabd_u8(d18u8, d7u8);
|
||||
|
||||
d19u8 = vmax_u8(d19u8, d23u8);
|
||||
|
||||
d23u8 = vabd_u8(d5u8, d16u8);
|
||||
d24u8 = vqadd_u8(d24u8, d24u8);
|
||||
|
||||
d19u8 = vcge_u8(dlimit, d19u8);
|
||||
|
||||
d25u8 = vmax_u8(d25u8, d26u8);
|
||||
d26u8 = vmax_u8(d27u8, d28u8);
|
||||
|
||||
d23u8 = vshr_n_u8(d23u8, 1);
|
||||
|
||||
d25u8 = vmax_u8(d25u8, d26u8);
|
||||
|
||||
d24u8 = vqadd_u8(d24u8, d23u8);
|
||||
|
||||
d20u8 = vmax_u8(d20u8, d25u8);
|
||||
|
||||
d23u8 = vdup_n_u8(1);
|
||||
d24u8 = vcge_u8(dblimit, d24u8);
|
||||
|
||||
d21u8 = vcgt_u8(d21u8, dthresh);
|
||||
|
||||
d20u8 = vcge_u8(d23u8, d20u8);
|
||||
|
||||
d19u8 = vand_u8(d19u8, d24u8);
|
||||
|
||||
d23u8 = vcgt_u8(d22u8, dthresh);
|
||||
|
||||
d20u8 = vand_u8(d20u8, d19u8);
|
||||
|
||||
d22u8 = vdup_n_u8(0x80);
|
||||
|
||||
d23u8 = vorr_u8(d21u8, d23u8);
|
||||
|
||||
q10u16 = vcombine_u16(vreinterpret_u16_u8(d20u8), vreinterpret_u16_u8(d21u8));
|
||||
|
||||
d30u8 = vshrn_n_u16(q10u16, 4);
|
||||
flat = vget_lane_u32(vreinterpret_u32_u8(d30u8), 0);
|
||||
|
||||
if (flat == 0xffffffff) { // Check for all 1's, power_branch_only
|
||||
d27u8 = vdup_n_u8(3);
|
||||
d21u8 = vdup_n_u8(2);
|
||||
q14u16 = vaddl_u8(d6u8, d7u8);
|
||||
q14u16 = vmlal_u8(q14u16, d3u8, d27u8);
|
||||
q14u16 = vmlal_u8(q14u16, d4u8, d21u8);
|
||||
q14u16 = vaddw_u8(q14u16, d5u8);
|
||||
*d0ru8 = vqrshrn_n_u16(q14u16, 3);
|
||||
|
||||
q14u16 = vsubw_u8(q14u16, d3u8);
|
||||
q14u16 = vsubw_u8(q14u16, d4u8);
|
||||
q14u16 = vaddw_u8(q14u16, d5u8);
|
||||
q14u16 = vaddw_u8(q14u16, d16u8);
|
||||
*d1ru8 = vqrshrn_n_u16(q14u16, 3);
|
||||
|
||||
q14u16 = vsubw_u8(q14u16, d3u8);
|
||||
q14u16 = vsubw_u8(q14u16, d5u8);
|
||||
q14u16 = vaddw_u8(q14u16, d6u8);
|
||||
q14u16 = vaddw_u8(q14u16, d17u8);
|
||||
*d2ru8 = vqrshrn_n_u16(q14u16, 3);
|
||||
|
||||
q14u16 = vsubw_u8(q14u16, d3u8);
|
||||
q14u16 = vsubw_u8(q14u16, d6u8);
|
||||
q14u16 = vaddw_u8(q14u16, d7u8);
|
||||
q14u16 = vaddw_u8(q14u16, d18u8);
|
||||
*d3ru8 = vqrshrn_n_u16(q14u16, 3);
|
||||
|
||||
q14u16 = vsubw_u8(q14u16, d4u8);
|
||||
q14u16 = vsubw_u8(q14u16, d7u8);
|
||||
q14u16 = vaddw_u8(q14u16, d16u8);
|
||||
q14u16 = vaddw_u8(q14u16, d18u8);
|
||||
*d4ru8 = vqrshrn_n_u16(q14u16, 3);
|
||||
|
||||
q14u16 = vsubw_u8(q14u16, d5u8);
|
||||
q14u16 = vsubw_u8(q14u16, d16u8);
|
||||
q14u16 = vaddw_u8(q14u16, d17u8);
|
||||
q14u16 = vaddw_u8(q14u16, d18u8);
|
||||
*d5ru8 = vqrshrn_n_u16(q14u16, 3);
|
||||
} else {
|
||||
d21u8 = veor_u8(d7u8, d22u8);
|
||||
d24u8 = veor_u8(d6u8, d22u8);
|
||||
d25u8 = veor_u8(d5u8, d22u8);
|
||||
d26u8 = veor_u8(d16u8, d22u8);
|
||||
|
||||
d27u8 = vdup_n_u8(3);
|
||||
|
||||
d28s8 = vsub_s8(vreinterpret_s8_u8(d21u8), vreinterpret_s8_u8(d24u8));
|
||||
d29s8 = vqsub_s8(vreinterpret_s8_u8(d25u8), vreinterpret_s8_u8(d26u8));
|
||||
|
||||
q15s16 = vmull_s8(d28s8, vreinterpret_s8_u8(d27u8));
|
||||
|
||||
d29s8 = vand_s8(d29s8, vreinterpret_s8_u8(d23u8));
|
||||
|
||||
q15s16 = vaddw_s8(q15s16, d29s8);
|
||||
|
||||
d29u8 = vdup_n_u8(4);
|
||||
|
||||
d28s8 = vqmovn_s16(q15s16);
|
||||
|
||||
d28s8 = vand_s8(d28s8, vreinterpret_s8_u8(d19u8));
|
||||
|
||||
d30s8 = vqadd_s8(d28s8, vreinterpret_s8_u8(d27u8));
|
||||
d29s8 = vqadd_s8(d28s8, vreinterpret_s8_u8(d29u8));
|
||||
d30s8 = vshr_n_s8(d30s8, 3);
|
||||
d29s8 = vshr_n_s8(d29s8, 3);
|
||||
|
||||
d24s8 = vqadd_s8(vreinterpret_s8_u8(d24u8), d30s8);
|
||||
d21s8 = vqsub_s8(vreinterpret_s8_u8(d21u8), d29s8);
|
||||
|
||||
d29s8 = vrshr_n_s8(d29s8, 1);
|
||||
d29s8 = vbic_s8(d29s8, vreinterpret_s8_u8(d23u8));
|
||||
|
||||
d25s8 = vqadd_s8(vreinterpret_s8_u8(d25u8), d29s8);
|
||||
d26s8 = vqsub_s8(vreinterpret_s8_u8(d26u8), d29s8);
|
||||
|
||||
if (flat == 0) { // filter_branch_only
|
||||
*d0ru8 = d4u8;
|
||||
*d1ru8 = veor_u8(vreinterpret_u8_s8(d25s8), d22u8);
|
||||
*d2ru8 = veor_u8(vreinterpret_u8_s8(d24s8), d22u8);
|
||||
*d3ru8 = veor_u8(vreinterpret_u8_s8(d21s8), d22u8);
|
||||
*d4ru8 = veor_u8(vreinterpret_u8_s8(d26s8), d22u8);
|
||||
*d5ru8 = d17u8;
|
||||
return;
|
||||
}
|
||||
|
||||
d21u8 = veor_u8(vreinterpret_u8_s8(d21s8), d22u8);
|
||||
d24u8 = veor_u8(vreinterpret_u8_s8(d24s8), d22u8);
|
||||
d25u8 = veor_u8(vreinterpret_u8_s8(d25s8), d22u8);
|
||||
d26u8 = veor_u8(vreinterpret_u8_s8(d26s8), d22u8);
|
||||
|
||||
d23u8 = vdup_n_u8(2);
|
||||
q14u16 = vaddl_u8(d6u8, d7u8);
|
||||
q14u16 = vmlal_u8(q14u16, d3u8, d27u8);
|
||||
q14u16 = vmlal_u8(q14u16, d4u8, d23u8);
|
||||
|
||||
d0u8 = vbsl_u8(d20u8, dblimit, d4u8);
|
||||
|
||||
q14u16 = vaddw_u8(q14u16, d5u8);
|
||||
|
||||
d1u8 = vbsl_u8(d20u8, dlimit, d25u8);
|
||||
|
||||
d30u8 = vqrshrn_n_u16(q14u16, 3);
|
||||
|
||||
q14u16 = vsubw_u8(q14u16, d3u8);
|
||||
q14u16 = vsubw_u8(q14u16, d4u8);
|
||||
q14u16 = vaddw_u8(q14u16, d5u8);
|
||||
q14u16 = vaddw_u8(q14u16, d16u8);
|
||||
|
||||
d2u8 = vbsl_u8(d20u8, dthresh, d24u8);
|
||||
|
||||
d31u8 = vqrshrn_n_u16(q14u16, 3);
|
||||
|
||||
q14u16 = vsubw_u8(q14u16, d3u8);
|
||||
q14u16 = vsubw_u8(q14u16, d5u8);
|
||||
q14u16 = vaddw_u8(q14u16, d6u8);
|
||||
q14u16 = vaddw_u8(q14u16, d17u8);
|
||||
|
||||
*d0ru8 = vbsl_u8(d20u8, d30u8, d0u8);
|
||||
|
||||
d23u8 = vqrshrn_n_u16(q14u16, 3);
|
||||
|
||||
q14u16 = vsubw_u8(q14u16, d3u8);
|
||||
q14u16 = vsubw_u8(q14u16, d6u8);
|
||||
q14u16 = vaddw_u8(q14u16, d7u8);
|
||||
|
||||
*d1ru8 = vbsl_u8(d20u8, d31u8, d1u8);
|
||||
|
||||
q14u16 = vaddw_u8(q14u16, d18u8);
|
||||
|
||||
*d2ru8 = vbsl_u8(d20u8, d23u8, d2u8);
|
||||
|
||||
d22u8 = vqrshrn_n_u16(q14u16, 3);
|
||||
|
||||
q14u16 = vsubw_u8(q14u16, d4u8);
|
||||
q14u16 = vsubw_u8(q14u16, d7u8);
|
||||
q14u16 = vaddw_u8(q14u16, d16u8);
|
||||
|
||||
d3u8 = vbsl_u8(d20u8, d3u8, d21u8);
|
||||
|
||||
q14u16 = vaddw_u8(q14u16, d18u8);
|
||||
|
||||
d4u8 = vbsl_u8(d20u8, d4u8, d26u8);
|
||||
|
||||
d6u8 = vqrshrn_n_u16(q14u16, 3);
|
||||
|
||||
q14u16 = vsubw_u8(q14u16, d5u8);
|
||||
q14u16 = vsubw_u8(q14u16, d16u8);
|
||||
q14u16 = vaddw_u8(q14u16, d17u8);
|
||||
q14u16 = vaddw_u8(q14u16, d18u8);
|
||||
|
||||
d5u8 = vbsl_u8(d20u8, d5u8, d17u8);
|
||||
|
||||
d7u8 = vqrshrn_n_u16(q14u16, 3);
|
||||
|
||||
*d3ru8 = vbsl_u8(d20u8, d22u8, d3u8);
|
||||
*d4ru8 = vbsl_u8(d20u8, d6u8, d4u8);
|
||||
*d5ru8 = vbsl_u8(d20u8, d7u8, d5u8);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
void aom_lpf_horizontal_8_neon(uint8_t *src, int pitch, const uint8_t *blimit,
|
||||
const uint8_t *limit, const uint8_t *thresh) {
|
||||
int i;
|
||||
uint8_t *s, *psrc;
|
||||
uint8x8_t dblimit, dlimit, dthresh;
|
||||
uint8x8_t d0u8, d1u8, d2u8, d3u8, d4u8, d5u8, d6u8, d7u8;
|
||||
uint8x8_t d16u8, d17u8, d18u8;
|
||||
|
||||
dblimit = vld1_u8(blimit);
|
||||
dlimit = vld1_u8(limit);
|
||||
dthresh = vld1_u8(thresh);
|
||||
|
||||
psrc = src - (pitch << 2);
|
||||
for (i = 0; i < 1; i++) {
|
||||
s = psrc + i * 8;
|
||||
|
||||
d3u8 = vld1_u8(s);
|
||||
s += pitch;
|
||||
d4u8 = vld1_u8(s);
|
||||
s += pitch;
|
||||
d5u8 = vld1_u8(s);
|
||||
s += pitch;
|
||||
d6u8 = vld1_u8(s);
|
||||
s += pitch;
|
||||
d7u8 = vld1_u8(s);
|
||||
s += pitch;
|
||||
d16u8 = vld1_u8(s);
|
||||
s += pitch;
|
||||
d17u8 = vld1_u8(s);
|
||||
s += pitch;
|
||||
d18u8 = vld1_u8(s);
|
||||
|
||||
mbloop_filter_neon(dblimit, dlimit, dthresh, d3u8, d4u8, d5u8, d6u8, d7u8,
|
||||
d16u8, d17u8, d18u8, &d0u8, &d1u8, &d2u8, &d3u8, &d4u8,
|
||||
&d5u8);
|
||||
|
||||
s -= (pitch * 6);
|
||||
vst1_u8(s, d0u8);
|
||||
s += pitch;
|
||||
vst1_u8(s, d1u8);
|
||||
s += pitch;
|
||||
vst1_u8(s, d2u8);
|
||||
s += pitch;
|
||||
vst1_u8(s, d3u8);
|
||||
s += pitch;
|
||||
vst1_u8(s, d4u8);
|
||||
s += pitch;
|
||||
vst1_u8(s, d5u8);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
void aom_lpf_vertical_8_neon(uint8_t *src, int pitch, const uint8_t *blimit,
|
||||
const uint8_t *limit, const uint8_t *thresh) {
|
||||
int i;
|
||||
uint8_t *s;
|
||||
uint8x8_t dblimit, dlimit, dthresh;
|
||||
uint8x8_t d0u8, d1u8, d2u8, d3u8, d4u8, d5u8, d6u8, d7u8;
|
||||
uint8x8_t d16u8, d17u8, d18u8;
|
||||
uint32x2x2_t d2tmp0, d2tmp1, d2tmp2, d2tmp3;
|
||||
uint16x4x2_t d2tmp4, d2tmp5, d2tmp6, d2tmp7;
|
||||
uint8x8x2_t d2tmp8, d2tmp9, d2tmp10, d2tmp11;
|
||||
uint8x8x4_t d4Result;
|
||||
uint8x8x2_t d2Result;
|
||||
|
||||
dblimit = vld1_u8(blimit);
|
||||
dlimit = vld1_u8(limit);
|
||||
dthresh = vld1_u8(thresh);
|
||||
|
||||
for (i = 0; i < 1; i++) {
|
||||
s = src + (i * (pitch << 3)) - 4;
|
||||
|
||||
d3u8 = vld1_u8(s);
|
||||
s += pitch;
|
||||
d4u8 = vld1_u8(s);
|
||||
s += pitch;
|
||||
d5u8 = vld1_u8(s);
|
||||
s += pitch;
|
||||
d6u8 = vld1_u8(s);
|
||||
s += pitch;
|
||||
d7u8 = vld1_u8(s);
|
||||
s += pitch;
|
||||
d16u8 = vld1_u8(s);
|
||||
s += pitch;
|
||||
d17u8 = vld1_u8(s);
|
||||
s += pitch;
|
||||
d18u8 = vld1_u8(s);
|
||||
|
||||
d2tmp0 = vtrn_u32(vreinterpret_u32_u8(d3u8), vreinterpret_u32_u8(d7u8));
|
||||
d2tmp1 = vtrn_u32(vreinterpret_u32_u8(d4u8), vreinterpret_u32_u8(d16u8));
|
||||
d2tmp2 = vtrn_u32(vreinterpret_u32_u8(d5u8), vreinterpret_u32_u8(d17u8));
|
||||
d2tmp3 = vtrn_u32(vreinterpret_u32_u8(d6u8), vreinterpret_u32_u8(d18u8));
|
||||
|
||||
d2tmp4 = vtrn_u16(vreinterpret_u16_u32(d2tmp0.val[0]),
|
||||
vreinterpret_u16_u32(d2tmp2.val[0]));
|
||||
d2tmp5 = vtrn_u16(vreinterpret_u16_u32(d2tmp1.val[0]),
|
||||
vreinterpret_u16_u32(d2tmp3.val[0]));
|
||||
d2tmp6 = vtrn_u16(vreinterpret_u16_u32(d2tmp0.val[1]),
|
||||
vreinterpret_u16_u32(d2tmp2.val[1]));
|
||||
d2tmp7 = vtrn_u16(vreinterpret_u16_u32(d2tmp1.val[1]),
|
||||
vreinterpret_u16_u32(d2tmp3.val[1]));
|
||||
|
||||
d2tmp8 = vtrn_u8(vreinterpret_u8_u16(d2tmp4.val[0]),
|
||||
vreinterpret_u8_u16(d2tmp5.val[0]));
|
||||
d2tmp9 = vtrn_u8(vreinterpret_u8_u16(d2tmp4.val[1]),
|
||||
vreinterpret_u8_u16(d2tmp5.val[1]));
|
||||
d2tmp10 = vtrn_u8(vreinterpret_u8_u16(d2tmp6.val[0]),
|
||||
vreinterpret_u8_u16(d2tmp7.val[0]));
|
||||
d2tmp11 = vtrn_u8(vreinterpret_u8_u16(d2tmp6.val[1]),
|
||||
vreinterpret_u8_u16(d2tmp7.val[1]));
|
||||
|
||||
d3u8 = d2tmp8.val[0];
|
||||
d4u8 = d2tmp8.val[1];
|
||||
d5u8 = d2tmp9.val[0];
|
||||
d6u8 = d2tmp9.val[1];
|
||||
d7u8 = d2tmp10.val[0];
|
||||
d16u8 = d2tmp10.val[1];
|
||||
d17u8 = d2tmp11.val[0];
|
||||
d18u8 = d2tmp11.val[1];
|
||||
|
||||
mbloop_filter_neon(dblimit, dlimit, dthresh, d3u8, d4u8, d5u8, d6u8, d7u8,
|
||||
d16u8, d17u8, d18u8, &d0u8, &d1u8, &d2u8, &d3u8, &d4u8,
|
||||
&d5u8);
|
||||
|
||||
d4Result.val[0] = d0u8;
|
||||
d4Result.val[1] = d1u8;
|
||||
d4Result.val[2] = d2u8;
|
||||
d4Result.val[3] = d3u8;
|
||||
|
||||
d2Result.val[0] = d4u8;
|
||||
d2Result.val[1] = d5u8;
|
||||
|
||||
s = src - 3;
|
||||
vst4_lane_u8(s, d4Result, 0);
|
||||
s += pitch;
|
||||
vst4_lane_u8(s, d4Result, 1);
|
||||
s += pitch;
|
||||
vst4_lane_u8(s, d4Result, 2);
|
||||
s += pitch;
|
||||
vst4_lane_u8(s, d4Result, 3);
|
||||
s += pitch;
|
||||
vst4_lane_u8(s, d4Result, 4);
|
||||
s += pitch;
|
||||
vst4_lane_u8(s, d4Result, 5);
|
||||
s += pitch;
|
||||
vst4_lane_u8(s, d4Result, 6);
|
||||
s += pitch;
|
||||
vst4_lane_u8(s, d4Result, 7);
|
||||
|
||||
s = src + 1;
|
||||
vst2_lane_u8(s, d2Result, 0);
|
||||
s += pitch;
|
||||
vst2_lane_u8(s, d2Result, 1);
|
||||
s += pitch;
|
||||
vst2_lane_u8(s, d2Result, 2);
|
||||
s += pitch;
|
||||
vst2_lane_u8(s, d2Result, 3);
|
||||
s += pitch;
|
||||
vst2_lane_u8(s, d2Result, 4);
|
||||
s += pitch;
|
||||
vst2_lane_u8(s, d2Result, 5);
|
||||
s += pitch;
|
||||
vst2_lane_u8(s, d2Result, 6);
|
||||
s += pitch;
|
||||
vst2_lane_u8(s, d2Result, 7);
|
||||
}
|
||||
return;
|
||||
}
|
||||
@@ -1,49 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2016, Alliance for Open Media. All rights reserved
|
||||
*
|
||||
* This source code is subject to the terms of the BSD 2 Clause License and
|
||||
* the Alliance for Open Media Patent License 1.0. If the BSD 2 Clause License
|
||||
* was not distributed with this source code in the LICENSE file, you can
|
||||
* obtain it at www.aomedia.org/license/software. If the Alliance for Open
|
||||
* Media Patent License 1.0 was not distributed with this source code in the
|
||||
* PATENTS file, you can obtain it at www.aomedia.org/license/patent.
|
||||
*/
|
||||
|
||||
#include <arm_neon.h>
|
||||
|
||||
#include "./aom_dsp_rtcd.h"
|
||||
#include "./aom_config.h"
|
||||
#include "aom/aom_integer.h"
|
||||
|
||||
void aom_lpf_vertical_4_dual_neon(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) {
|
||||
aom_lpf_vertical_4_neon(s, p, blimit0, limit0, thresh0);
|
||||
aom_lpf_vertical_4_neon(s + 8 * p, p, blimit1, limit1, thresh1);
|
||||
}
|
||||
|
||||
#if HAVE_NEON_ASM
|
||||
void aom_lpf_horizontal_8_dual_neon(
|
||||
uint8_t *s, int p /* pitch */, const uint8_t *blimit0,
|
||||
const uint8_t *limit0, const uint8_t *thresh0, const uint8_t *blimit1,
|
||||
const uint8_t *limit1, const uint8_t *thresh1) {
|
||||
aom_lpf_horizontal_8_neon(s, p, blimit0, limit0, thresh0);
|
||||
aom_lpf_horizontal_8_neon(s + 8, p, blimit1, limit1, thresh1);
|
||||
}
|
||||
|
||||
void aom_lpf_vertical_8_dual_neon(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) {
|
||||
aom_lpf_vertical_8_neon(s, p, blimit0, limit0, thresh0);
|
||||
aom_lpf_vertical_8_neon(s + 8 * p, p, blimit1, limit1, thresh1);
|
||||
}
|
||||
|
||||
void aom_lpf_vertical_16_dual_neon(uint8_t *s, int p, const uint8_t *blimit,
|
||||
const uint8_t *limit,
|
||||
const uint8_t *thresh) {
|
||||
aom_lpf_vertical_16_neon(s, p, blimit, limit, thresh);
|
||||
aom_lpf_vertical_16_neon(s + 8 * p, p, blimit, limit, thresh);
|
||||
}
|
||||
#endif // HAVE_NEON_ASM
|
||||
@@ -1,98 +0,0 @@
|
||||
;
|
||||
; Copyright (c) 2016, Alliance for Open Media. All rights reserved
|
||||
;
|
||||
; This source code is subject to the terms of the BSD 2 Clause License and
|
||||
; the Alliance for Open Media Patent License 1.0. If the BSD 2 Clause License
|
||||
; was not distributed with this source code in the LICENSE file, you can
|
||||
; obtain it at www.aomedia.org/license/software. If the Alliance for Open
|
||||
; Media Patent License 1.0 was not distributed with this source code in the
|
||||
; PATENTS file, you can obtain it at www.aomedia.org/license/patent.
|
||||
;
|
||||
|
||||
;
|
||||
|
||||
|
||||
EXPORT |aom_sad16x16_media|
|
||||
|
||||
ARM
|
||||
REQUIRE8
|
||||
PRESERVE8
|
||||
|
||||
AREA ||.text||, CODE, READONLY, ALIGN=2
|
||||
|
||||
; r0 const unsigned char *src_ptr
|
||||
; r1 int src_stride
|
||||
; r2 const unsigned char *ref_ptr
|
||||
; r3 int ref_stride
|
||||
|aom_sad16x16_media| PROC
|
||||
stmfd sp!, {r4-r12, lr}
|
||||
|
||||
pld [r0, r1, lsl #0]
|
||||
pld [r2, r3, lsl #0]
|
||||
pld [r0, r1, lsl #1]
|
||||
pld [r2, r3, lsl #1]
|
||||
|
||||
mov r4, #0 ; sad = 0;
|
||||
mov r5, #8 ; loop count
|
||||
|
||||
loop
|
||||
; 1st row
|
||||
ldr r6, [r0, #0x0] ; load 4 src pixels (1A)
|
||||
ldr r8, [r2, #0x0] ; load 4 ref pixels (1A)
|
||||
ldr r7, [r0, #0x4] ; load 4 src pixels (1A)
|
||||
ldr r9, [r2, #0x4] ; load 4 ref pixels (1A)
|
||||
ldr r10, [r0, #0x8] ; load 4 src pixels (1B)
|
||||
ldr r11, [r0, #0xC] ; load 4 src pixels (1B)
|
||||
|
||||
usada8 r4, r8, r6, r4 ; calculate sad for 4 pixels
|
||||
usad8 r8, r7, r9 ; calculate sad for 4 pixels
|
||||
|
||||
ldr r12, [r2, #0x8] ; load 4 ref pixels (1B)
|
||||
ldr lr, [r2, #0xC] ; load 4 ref pixels (1B)
|
||||
|
||||
add r0, r0, r1 ; set src pointer to next row
|
||||
add r2, r2, r3 ; set dst pointer to next row
|
||||
|
||||
pld [r0, r1, lsl #1]
|
||||
pld [r2, r3, lsl #1]
|
||||
|
||||
usada8 r4, r10, r12, r4 ; calculate sad for 4 pixels
|
||||
usada8 r8, r11, lr, r8 ; calculate sad for 4 pixels
|
||||
|
||||
ldr r6, [r0, #0x0] ; load 4 src pixels (2A)
|
||||
ldr r7, [r0, #0x4] ; load 4 src pixels (2A)
|
||||
add r4, r4, r8 ; add partial sad values
|
||||
|
||||
; 2nd row
|
||||
ldr r8, [r2, #0x0] ; load 4 ref pixels (2A)
|
||||
ldr r9, [r2, #0x4] ; load 4 ref pixels (2A)
|
||||
ldr r10, [r0, #0x8] ; load 4 src pixels (2B)
|
||||
ldr r11, [r0, #0xC] ; load 4 src pixels (2B)
|
||||
|
||||
usada8 r4, r6, r8, r4 ; calculate sad for 4 pixels
|
||||
usad8 r8, r7, r9 ; calculate sad for 4 pixels
|
||||
|
||||
ldr r12, [r2, #0x8] ; load 4 ref pixels (2B)
|
||||
ldr lr, [r2, #0xC] ; load 4 ref pixels (2B)
|
||||
|
||||
add r0, r0, r1 ; set src pointer to next row
|
||||
add r2, r2, r3 ; set dst pointer to next row
|
||||
|
||||
usada8 r4, r10, r12, r4 ; calculate sad for 4 pixels
|
||||
usada8 r8, r11, lr, r8 ; calculate sad for 4 pixels
|
||||
|
||||
pld [r0, r1, lsl #1]
|
||||
pld [r2, r3, lsl #1]
|
||||
|
||||
subs r5, r5, #1 ; decrement loop counter
|
||||
add r4, r4, r8 ; add partial sad values
|
||||
|
||||
bne loop
|
||||
|
||||
mov r0, r4 ; return sad
|
||||
ldmfd sp!, {r4-r12, pc}
|
||||
|
||||
ENDP
|
||||
|
||||
END
|
||||
|
||||
@@ -1,39 +0,0 @@
|
||||
;
|
||||
; Copyright (c) 2016, Alliance for Open Media. All rights reserved
|
||||
;
|
||||
; This source code is subject to the terms of the BSD 2 Clause License and
|
||||
; the Alliance for Open Media Patent License 1.0. If the BSD 2 Clause License
|
||||
; was not distributed with this source code in the LICENSE file, you can
|
||||
; obtain it at www.aomedia.org/license/software. If the Alliance for Open
|
||||
; Media Patent License 1.0 was not distributed with this source code in the
|
||||
; PATENTS file, you can obtain it at www.aomedia.org/license/patent.
|
||||
;
|
||||
|
||||
;
|
||||
|
||||
|
||||
EXPORT |aom_push_neon|
|
||||
EXPORT |aom_pop_neon|
|
||||
|
||||
ARM
|
||||
REQUIRE8
|
||||
PRESERVE8
|
||||
|
||||
AREA ||.text||, CODE, READONLY, ALIGN=2
|
||||
|
||||
|aom_push_neon| PROC
|
||||
vst1.i64 {d8, d9, d10, d11}, [r0]!
|
||||
vst1.i64 {d12, d13, d14, d15}, [r0]!
|
||||
bx lr
|
||||
|
||||
ENDP
|
||||
|
||||
|aom_pop_neon| PROC
|
||||
vld1.i64 {d8, d9, d10, d11}, [r0]!
|
||||
vld1.i64 {d12, d13, d14, d15}, [r0]!
|
||||
bx lr
|
||||
|
||||
ENDP
|
||||
|
||||
END
|
||||
|
||||
@@ -1,81 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2016, Alliance for Open Media. All rights reserved
|
||||
*
|
||||
* This source code is subject to the terms of the BSD 2 Clause License and
|
||||
* the Alliance for Open Media Patent License 1.0. If the BSD 2 Clause License
|
||||
* was not distributed with this source code in the LICENSE file, you can
|
||||
* obtain it at www.aomedia.org/license/software. If the Alliance for Open
|
||||
* Media Patent License 1.0 was not distributed with this source code in the
|
||||
* PATENTS file, you can obtain it at www.aomedia.org/license/patent.
|
||||
*/
|
||||
|
||||
#include "./aom_config.h"
|
||||
#include "./aom_dsp_rtcd.h"
|
||||
#include "aom/aom_integer.h"
|
||||
#include "aom_ports/mem.h"
|
||||
|
||||
#if HAVE_MEDIA
|
||||
static const int16_t bilinear_filters_media[8][2] = { { 128, 0 }, { 112, 16 },
|
||||
{ 96, 32 }, { 80, 48 },
|
||||
{ 64, 64 }, { 48, 80 },
|
||||
{ 32, 96 }, { 16, 112 } };
|
||||
|
||||
extern void aom_filter_block2d_bil_first_pass_media(
|
||||
const uint8_t *src_ptr, uint16_t *dst_ptr, uint32_t src_pitch,
|
||||
uint32_t height, uint32_t width, const int16_t *filter);
|
||||
|
||||
extern void aom_filter_block2d_bil_second_pass_media(
|
||||
const uint16_t *src_ptr, uint8_t *dst_ptr, int32_t src_pitch,
|
||||
uint32_t height, uint32_t width, const int16_t *filter);
|
||||
|
||||
unsigned int aom_sub_pixel_variance8x8_media(
|
||||
const uint8_t *src_ptr, int src_pixels_per_line, int xoffset, int yoffset,
|
||||
const uint8_t *dst_ptr, int dst_pixels_per_line, unsigned int *sse) {
|
||||
uint16_t first_pass[10 * 8];
|
||||
uint8_t second_pass[8 * 8];
|
||||
const int16_t *HFilter, *VFilter;
|
||||
|
||||
HFilter = bilinear_filters_media[xoffset];
|
||||
VFilter = bilinear_filters_media[yoffset];
|
||||
|
||||
aom_filter_block2d_bil_first_pass_media(src_ptr, first_pass,
|
||||
src_pixels_per_line, 9, 8, HFilter);
|
||||
aom_filter_block2d_bil_second_pass_media(first_pass, second_pass, 8, 8, 8,
|
||||
VFilter);
|
||||
|
||||
return aom_variance8x8_media(second_pass, 8, dst_ptr, dst_pixels_per_line,
|
||||
sse);
|
||||
}
|
||||
|
||||
unsigned int aom_sub_pixel_variance16x16_media(
|
||||
const uint8_t *src_ptr, int src_pixels_per_line, int xoffset, int yoffset,
|
||||
const uint8_t *dst_ptr, int dst_pixels_per_line, unsigned int *sse) {
|
||||
uint16_t first_pass[36 * 16];
|
||||
uint8_t second_pass[20 * 16];
|
||||
const int16_t *HFilter, *VFilter;
|
||||
unsigned int var;
|
||||
|
||||
if (xoffset == 4 && yoffset == 0) {
|
||||
var = aom_variance_halfpixvar16x16_h_media(
|
||||
src_ptr, src_pixels_per_line, dst_ptr, dst_pixels_per_line, sse);
|
||||
} else if (xoffset == 0 && yoffset == 4) {
|
||||
var = aom_variance_halfpixvar16x16_v_media(
|
||||
src_ptr, src_pixels_per_line, dst_ptr, dst_pixels_per_line, sse);
|
||||
} else if (xoffset == 4 && yoffset == 4) {
|
||||
var = aom_variance_halfpixvar16x16_hv_media(
|
||||
src_ptr, src_pixels_per_line, dst_ptr, dst_pixels_per_line, sse);
|
||||
} else {
|
||||
HFilter = bilinear_filters_media[xoffset];
|
||||
VFilter = bilinear_filters_media[yoffset];
|
||||
|
||||
aom_filter_block2d_bil_first_pass_media(
|
||||
src_ptr, first_pass, src_pixels_per_line, 17, 16, HFilter);
|
||||
aom_filter_block2d_bil_second_pass_media(first_pass, second_pass, 16, 16,
|
||||
16, VFilter);
|
||||
|
||||
var = aom_variance16x16_media(second_pass, 16, dst_ptr, dst_pixels_per_line,
|
||||
sse);
|
||||
}
|
||||
return var;
|
||||
}
|
||||
#endif // HAVE_MEDIA
|
||||
@@ -1,185 +0,0 @@
|
||||
;
|
||||
; Copyright (c) 2016, Alliance for Open Media. All rights reserved
|
||||
;
|
||||
; This source code is subject to the terms of the BSD 2 Clause License and
|
||||
; the Alliance for Open Media Patent License 1.0. If the BSD 2 Clause License
|
||||
; was not distributed with this source code in the LICENSE file, you can
|
||||
; obtain it at www.aomedia.org/license/software. If the Alliance for Open
|
||||
; Media Patent License 1.0 was not distributed with this source code in the
|
||||
; PATENTS file, you can obtain it at www.aomedia.org/license/patent.
|
||||
;
|
||||
|
||||
;
|
||||
|
||||
|
||||
EXPORT |aom_variance_halfpixvar16x16_h_media|
|
||||
|
||||
ARM
|
||||
REQUIRE8
|
||||
PRESERVE8
|
||||
|
||||
AREA ||.text||, CODE, READONLY, ALIGN=2
|
||||
|
||||
; r0 unsigned char *src_ptr
|
||||
; r1 int source_stride
|
||||
; r2 unsigned char *ref_ptr
|
||||
; r3 int recon_stride
|
||||
; stack unsigned int *sse
|
||||
|aom_variance_halfpixvar16x16_h_media| PROC
|
||||
|
||||
stmfd sp!, {r4-r12, lr}
|
||||
|
||||
pld [r0, r1, lsl #0]
|
||||
pld [r2, r3, lsl #0]
|
||||
|
||||
mov r8, #0 ; initialize sum = 0
|
||||
ldr r10, c80808080
|
||||
mov r11, #0 ; initialize sse = 0
|
||||
mov r12, #16 ; set loop counter to 16 (=block height)
|
||||
mov lr, #0 ; constant zero
|
||||
loop
|
||||
; 1st 4 pixels
|
||||
ldr r4, [r0, #0] ; load 4 src pixels
|
||||
ldr r6, [r0, #1] ; load 4 src pixels with 1 byte offset
|
||||
ldr r5, [r2, #0] ; load 4 ref pixels
|
||||
|
||||
; bilinear interpolation
|
||||
mvn r6, r6
|
||||
uhsub8 r4, r4, r6
|
||||
eor r4, r4, r10
|
||||
|
||||
usub8 r6, r4, r5 ; calculate difference
|
||||
pld [r0, r1, lsl #1]
|
||||
sel r7, r6, lr ; select bytes with positive difference
|
||||
usub8 r6, r5, r4 ; calculate difference with reversed operands
|
||||
pld [r2, r3, lsl #1]
|
||||
sel r6, r6, lr ; select bytes with negative difference
|
||||
|
||||
; calculate partial sums
|
||||
usad8 r4, r7, lr ; calculate sum of positive differences
|
||||
usad8 r5, r6, lr ; calculate sum of negative differences
|
||||
orr r6, r6, r7 ; differences of all 4 pixels
|
||||
; calculate total sum
|
||||
adds r8, r8, r4 ; add positive differences to sum
|
||||
subs r8, r8, r5 ; subtract negative differences from sum
|
||||
|
||||
; calculate sse
|
||||
uxtb16 r5, r6 ; byte (two pixels) to halfwords
|
||||
uxtb16 r7, r6, ror #8 ; another two pixels to halfwords
|
||||
smlad r11, r5, r5, r11 ; dual signed multiply, add and accumulate (1)
|
||||
|
||||
; 2nd 4 pixels
|
||||
ldr r4, [r0, #4] ; load 4 src pixels
|
||||
ldr r6, [r0, #5] ; load 4 src pixels with 1 byte offset
|
||||
ldr r5, [r2, #4] ; load 4 ref pixels
|
||||
|
||||
; bilinear interpolation
|
||||
mvn r6, r6
|
||||
uhsub8 r4, r4, r6
|
||||
eor r4, r4, r10
|
||||
|
||||
smlad r11, r7, r7, r11 ; dual signed multiply, add and accumulate (2)
|
||||
|
||||
usub8 r6, r4, r5 ; calculate difference
|
||||
sel r7, r6, lr ; select bytes with positive difference
|
||||
usub8 r6, r5, r4 ; calculate difference with reversed operands
|
||||
sel r6, r6, lr ; select bytes with negative difference
|
||||
|
||||
; calculate partial sums
|
||||
usad8 r4, r7, lr ; calculate sum of positive differences
|
||||
usad8 r5, r6, lr ; calculate sum of negative differences
|
||||
orr r6, r6, r7 ; differences of all 4 pixels
|
||||
|
||||
; calculate total sum
|
||||
add r8, r8, r4 ; add positive differences to sum
|
||||
sub r8, r8, r5 ; subtract negative differences from sum
|
||||
|
||||
; calculate sse
|
||||
uxtb16 r5, r6 ; byte (two pixels) to halfwords
|
||||
uxtb16 r7, r6, ror #8 ; another two pixels to halfwords
|
||||
smlad r11, r5, r5, r11 ; dual signed multiply, add and accumulate (1)
|
||||
|
||||
; 3rd 4 pixels
|
||||
ldr r4, [r0, #8] ; load 4 src pixels
|
||||
ldr r6, [r0, #9] ; load 4 src pixels with 1 byte offset
|
||||
ldr r5, [r2, #8] ; load 4 ref pixels
|
||||
|
||||
; bilinear interpolation
|
||||
mvn r6, r6
|
||||
uhsub8 r4, r4, r6
|
||||
eor r4, r4, r10
|
||||
|
||||
smlad r11, r7, r7, r11 ; dual signed multiply, add and accumulate (2)
|
||||
|
||||
usub8 r6, r4, r5 ; calculate difference
|
||||
sel r7, r6, lr ; select bytes with positive difference
|
||||
usub8 r6, r5, r4 ; calculate difference with reversed operands
|
||||
sel r6, r6, lr ; select bytes with negative difference
|
||||
|
||||
; calculate partial sums
|
||||
usad8 r4, r7, lr ; calculate sum of positive differences
|
||||
usad8 r5, r6, lr ; calculate sum of negative differences
|
||||
orr r6, r6, r7 ; differences of all 4 pixels
|
||||
|
||||
; calculate total sum
|
||||
add r8, r8, r4 ; add positive differences to sum
|
||||
sub r8, r8, r5 ; subtract negative differences from sum
|
||||
|
||||
; calculate sse
|
||||
uxtb16 r5, r6 ; byte (two pixels) to halfwords
|
||||
uxtb16 r7, r6, ror #8 ; another two pixels to halfwords
|
||||
smlad r11, r5, r5, r11 ; dual signed multiply, add and accumulate (1)
|
||||
|
||||
; 4th 4 pixels
|
||||
ldr r4, [r0, #12] ; load 4 src pixels
|
||||
ldr r6, [r0, #13] ; load 4 src pixels with 1 byte offset
|
||||
ldr r5, [r2, #12] ; load 4 ref pixels
|
||||
|
||||
; bilinear interpolation
|
||||
mvn r6, r6
|
||||
uhsub8 r4, r4, r6
|
||||
eor r4, r4, r10
|
||||
|
||||
smlad r11, r7, r7, r11 ; dual signed multiply, add and accumulate (2)
|
||||
|
||||
usub8 r6, r4, r5 ; calculate difference
|
||||
add r0, r0, r1 ; set src_ptr to next row
|
||||
sel r7, r6, lr ; select bytes with positive difference
|
||||
usub8 r6, r5, r4 ; calculate difference with reversed operands
|
||||
add r2, r2, r3 ; set dst_ptr to next row
|
||||
sel r6, r6, lr ; select bytes with negative difference
|
||||
|
||||
; calculate partial sums
|
||||
usad8 r4, r7, lr ; calculate sum of positive differences
|
||||
usad8 r5, r6, lr ; calculate sum of negative differences
|
||||
orr r6, r6, r7 ; differences of all 4 pixels
|
||||
|
||||
; calculate total sum
|
||||
add r8, r8, r4 ; add positive differences to sum
|
||||
sub r8, r8, r5 ; subtract negative differences from sum
|
||||
|
||||
; calculate sse
|
||||
uxtb16 r5, r6 ; byte (two pixels) to halfwords
|
||||
uxtb16 r7, r6, ror #8 ; another two pixels to halfwords
|
||||
smlad r11, r5, r5, r11 ; dual signed multiply, add and accumulate (1)
|
||||
smlad r11, r7, r7, r11 ; dual signed multiply, add and accumulate (2)
|
||||
|
||||
subs r12, r12, #1
|
||||
|
||||
bne loop
|
||||
|
||||
; return stuff
|
||||
ldr r6, [sp, #40] ; get address of sse
|
||||
mul r0, r8, r8 ; sum * sum
|
||||
str r11, [r6] ; store sse
|
||||
sub r0, r11, r0, lsr #8 ; return (sse - ((sum * sum) >> 8))
|
||||
|
||||
ldmfd sp!, {r4-r12, pc}
|
||||
|
||||
ENDP
|
||||
|
||||
c80808080
|
||||
DCD 0x80808080
|
||||
|
||||
END
|
||||
|
||||
@@ -1,225 +0,0 @@
|
||||
;
|
||||
; Copyright (c) 2016, Alliance for Open Media. All rights reserved
|
||||
;
|
||||
; This source code is subject to the terms of the BSD 2 Clause License and
|
||||
; the Alliance for Open Media Patent License 1.0. If the BSD 2 Clause License
|
||||
; was not distributed with this source code in the LICENSE file, you can
|
||||
; obtain it at www.aomedia.org/license/software. If the Alliance for Open
|
||||
; Media Patent License 1.0 was not distributed with this source code in the
|
||||
; PATENTS file, you can obtain it at www.aomedia.org/license/patent.
|
||||
;
|
||||
|
||||
;
|
||||
|
||||
|
||||
EXPORT |aom_variance_halfpixvar16x16_hv_media|
|
||||
|
||||
ARM
|
||||
REQUIRE8
|
||||
PRESERVE8
|
||||
|
||||
AREA ||.text||, CODE, READONLY, ALIGN=2
|
||||
|
||||
; r0 unsigned char *src_ptr
|
||||
; r1 int source_stride
|
||||
; r2 unsigned char *ref_ptr
|
||||
; r3 int recon_stride
|
||||
; stack unsigned int *sse
|
||||
|aom_variance_halfpixvar16x16_hv_media| PROC
|
||||
|
||||
stmfd sp!, {r4-r12, lr}
|
||||
|
||||
pld [r0, r1, lsl #0]
|
||||
pld [r2, r3, lsl #0]
|
||||
|
||||
mov r8, #0 ; initialize sum = 0
|
||||
ldr r10, c80808080
|
||||
mov r11, #0 ; initialize sse = 0
|
||||
mov r12, #16 ; set loop counter to 16 (=block height)
|
||||
mov lr, #0 ; constant zero
|
||||
loop
|
||||
add r9, r0, r1 ; pointer to pixels on the next row
|
||||
; 1st 4 pixels
|
||||
ldr r4, [r0, #0] ; load source pixels a, row N
|
||||
ldr r6, [r0, #1] ; load source pixels b, row N
|
||||
ldr r5, [r9, #0] ; load source pixels c, row N+1
|
||||
ldr r7, [r9, #1] ; load source pixels d, row N+1
|
||||
|
||||
; x = (a + b + 1) >> 1, interpolate pixels horizontally on row N
|
||||
mvn r6, r6
|
||||
uhsub8 r4, r4, r6
|
||||
eor r4, r4, r10
|
||||
; y = (c + d + 1) >> 1, interpolate pixels horizontally on row N+1
|
||||
mvn r7, r7
|
||||
uhsub8 r5, r5, r7
|
||||
eor r5, r5, r10
|
||||
; z = (x + y + 1) >> 1, interpolate half pixel values vertically
|
||||
mvn r5, r5
|
||||
uhsub8 r4, r4, r5
|
||||
ldr r5, [r2, #0] ; load 4 ref pixels
|
||||
eor r4, r4, r10
|
||||
|
||||
usub8 r6, r4, r5 ; calculate difference
|
||||
pld [r0, r1, lsl #1]
|
||||
sel r7, r6, lr ; select bytes with positive difference
|
||||
usub8 r6, r5, r4 ; calculate difference with reversed operands
|
||||
pld [r2, r3, lsl #1]
|
||||
sel r6, r6, lr ; select bytes with negative difference
|
||||
|
||||
; calculate partial sums
|
||||
usad8 r4, r7, lr ; calculate sum of positive differences
|
||||
usad8 r5, r6, lr ; calculate sum of negative differences
|
||||
orr r6, r6, r7 ; differences of all 4 pixels
|
||||
; calculate total sum
|
||||
adds r8, r8, r4 ; add positive differences to sum
|
||||
subs r8, r8, r5 ; subtract negative differences from sum
|
||||
|
||||
; calculate sse
|
||||
uxtb16 r5, r6 ; byte (two pixels) to halfwords
|
||||
uxtb16 r7, r6, ror #8 ; another two pixels to halfwords
|
||||
smlad r11, r5, r5, r11 ; dual signed multiply, add and accumulate (1)
|
||||
|
||||
; 2nd 4 pixels
|
||||
ldr r4, [r0, #4] ; load source pixels a, row N
|
||||
ldr r6, [r0, #5] ; load source pixels b, row N
|
||||
ldr r5, [r9, #4] ; load source pixels c, row N+1
|
||||
|
||||
smlad r11, r7, r7, r11 ; dual signed multiply, add and accumulate (2)
|
||||
|
||||
ldr r7, [r9, #5] ; load source pixels d, row N+1
|
||||
|
||||
; x = (a + b + 1) >> 1, interpolate pixels horizontally on row N
|
||||
mvn r6, r6
|
||||
uhsub8 r4, r4, r6
|
||||
eor r4, r4, r10
|
||||
; y = (c + d + 1) >> 1, interpolate pixels horizontally on row N+1
|
||||
mvn r7, r7
|
||||
uhsub8 r5, r5, r7
|
||||
eor r5, r5, r10
|
||||
; z = (x + y + 1) >> 1, interpolate half pixel values vertically
|
||||
mvn r5, r5
|
||||
uhsub8 r4, r4, r5
|
||||
ldr r5, [r2, #4] ; load 4 ref pixels
|
||||
eor r4, r4, r10
|
||||
|
||||
usub8 r6, r4, r5 ; calculate difference
|
||||
sel r7, r6, lr ; select bytes with positive difference
|
||||
usub8 r6, r5, r4 ; calculate difference with reversed operands
|
||||
sel r6, r6, lr ; select bytes with negative difference
|
||||
|
||||
; calculate partial sums
|
||||
usad8 r4, r7, lr ; calculate sum of positive differences
|
||||
usad8 r5, r6, lr ; calculate sum of negative differences
|
||||
orr r6, r6, r7 ; differences of all 4 pixels
|
||||
|
||||
; calculate total sum
|
||||
add r8, r8, r4 ; add positive differences to sum
|
||||
sub r8, r8, r5 ; subtract negative differences from sum
|
||||
|
||||
; calculate sse
|
||||
uxtb16 r5, r6 ; byte (two pixels) to halfwords
|
||||
uxtb16 r7, r6, ror #8 ; another two pixels to halfwords
|
||||
smlad r11, r5, r5, r11 ; dual signed multiply, add and accumulate (1)
|
||||
|
||||
; 3rd 4 pixels
|
||||
ldr r4, [r0, #8] ; load source pixels a, row N
|
||||
ldr r6, [r0, #9] ; load source pixels b, row N
|
||||
ldr r5, [r9, #8] ; load source pixels c, row N+1
|
||||
|
||||
smlad r11, r7, r7, r11 ; dual signed multiply, add and accumulate (2)
|
||||
|
||||
ldr r7, [r9, #9] ; load source pixels d, row N+1
|
||||
|
||||
; x = (a + b + 1) >> 1, interpolate pixels horizontally on row N
|
||||
mvn r6, r6
|
||||
uhsub8 r4, r4, r6
|
||||
eor r4, r4, r10
|
||||
; y = (c + d + 1) >> 1, interpolate pixels horizontally on row N+1
|
||||
mvn r7, r7
|
||||
uhsub8 r5, r5, r7
|
||||
eor r5, r5, r10
|
||||
; z = (x + y + 1) >> 1, interpolate half pixel values vertically
|
||||
mvn r5, r5
|
||||
uhsub8 r4, r4, r5
|
||||
ldr r5, [r2, #8] ; load 4 ref pixels
|
||||
eor r4, r4, r10
|
||||
|
||||
usub8 r6, r4, r5 ; calculate difference
|
||||
sel r7, r6, lr ; select bytes with positive difference
|
||||
usub8 r6, r5, r4 ; calculate difference with reversed operands
|
||||
sel r6, r6, lr ; select bytes with negative difference
|
||||
|
||||
; calculate partial sums
|
||||
usad8 r4, r7, lr ; calculate sum of positive differences
|
||||
usad8 r5, r6, lr ; calculate sum of negative differences
|
||||
orr r6, r6, r7 ; differences of all 4 pixels
|
||||
|
||||
; calculate total sum
|
||||
add r8, r8, r4 ; add positive differences to sum
|
||||
sub r8, r8, r5 ; subtract negative differences from sum
|
||||
|
||||
; calculate sse
|
||||
uxtb16 r5, r6 ; byte (two pixels) to halfwords
|
||||
uxtb16 r7, r6, ror #8 ; another two pixels to halfwords
|
||||
smlad r11, r5, r5, r11 ; dual signed multiply, add and accumulate (1)
|
||||
|
||||
; 4th 4 pixels
|
||||
ldr r4, [r0, #12] ; load source pixels a, row N
|
||||
ldr r6, [r0, #13] ; load source pixels b, row N
|
||||
ldr r5, [r9, #12] ; load source pixels c, row N+1
|
||||
smlad r11, r7, r7, r11 ; dual signed multiply, add and accumulate (2)
|
||||
ldr r7, [r9, #13] ; load source pixels d, row N+1
|
||||
|
||||
; x = (a + b + 1) >> 1, interpolate pixels horizontally on row N
|
||||
mvn r6, r6
|
||||
uhsub8 r4, r4, r6
|
||||
eor r4, r4, r10
|
||||
; y = (c + d + 1) >> 1, interpolate pixels horizontally on row N+1
|
||||
mvn r7, r7
|
||||
uhsub8 r5, r5, r7
|
||||
eor r5, r5, r10
|
||||
; z = (x + y + 1) >> 1, interpolate half pixel values vertically
|
||||
mvn r5, r5
|
||||
uhsub8 r4, r4, r5
|
||||
ldr r5, [r2, #12] ; load 4 ref pixels
|
||||
eor r4, r4, r10
|
||||
|
||||
usub8 r6, r4, r5 ; calculate difference
|
||||
add r0, r0, r1 ; set src_ptr to next row
|
||||
sel r7, r6, lr ; select bytes with positive difference
|
||||
usub8 r6, r5, r4 ; calculate difference with reversed operands
|
||||
add r2, r2, r3 ; set dst_ptr to next row
|
||||
sel r6, r6, lr ; select bytes with negative difference
|
||||
|
||||
; calculate partial sums
|
||||
usad8 r4, r7, lr ; calculate sum of positive differences
|
||||
usad8 r5, r6, lr ; calculate sum of negative differences
|
||||
orr r6, r6, r7 ; differences of all 4 pixels
|
||||
|
||||
; calculate total sum
|
||||
add r8, r8, r4 ; add positive differences to sum
|
||||
sub r8, r8, r5 ; subtract negative differences from sum
|
||||
|
||||
; calculate sse
|
||||
uxtb16 r5, r6 ; byte (two pixels) to halfwords
|
||||
uxtb16 r7, r6, ror #8 ; another two pixels to halfwords
|
||||
smlad r11, r5, r5, r11 ; dual signed multiply, add and accumulate (1)
|
||||
subs r12, r12, #1
|
||||
smlad r11, r7, r7, r11 ; dual signed multiply, add and accumulate (2)
|
||||
|
||||
bne loop
|
||||
|
||||
; return stuff
|
||||
ldr r6, [sp, #40] ; get address of sse
|
||||
mul r0, r8, r8 ; sum * sum
|
||||
str r11, [r6] ; store sse
|
||||
sub r0, r11, r0, lsr #8 ; return (sse - ((sum * sum) >> 8))
|
||||
|
||||
ldmfd sp!, {r4-r12, pc}
|
||||
|
||||
ENDP
|
||||
|
||||
c80808080
|
||||
DCD 0x80808080
|
||||
|
||||
END
|
||||
@@ -1,187 +0,0 @@
|
||||
;
|
||||
; Copyright (c) 2016, Alliance for Open Media. All rights reserved
|
||||
;
|
||||
; This source code is subject to the terms of the BSD 2 Clause License and
|
||||
; the Alliance for Open Media Patent License 1.0. If the BSD 2 Clause License
|
||||
; was not distributed with this source code in the LICENSE file, you can
|
||||
; obtain it at www.aomedia.org/license/software. If the Alliance for Open
|
||||
; Media Patent License 1.0 was not distributed with this source code in the
|
||||
; PATENTS file, you can obtain it at www.aomedia.org/license/patent.
|
||||
;
|
||||
|
||||
;
|
||||
|
||||
|
||||
EXPORT |aom_variance_halfpixvar16x16_v_media|
|
||||
|
||||
ARM
|
||||
REQUIRE8
|
||||
PRESERVE8
|
||||
|
||||
AREA ||.text||, CODE, READONLY, ALIGN=2
|
||||
|
||||
; r0 unsigned char *src_ptr
|
||||
; r1 int source_stride
|
||||
; r2 unsigned char *ref_ptr
|
||||
; r3 int recon_stride
|
||||
; stack unsigned int *sse
|
||||
|aom_variance_halfpixvar16x16_v_media| PROC
|
||||
|
||||
stmfd sp!, {r4-r12, lr}
|
||||
|
||||
pld [r0, r1, lsl #0]
|
||||
pld [r2, r3, lsl #0]
|
||||
|
||||
mov r8, #0 ; initialize sum = 0
|
||||
ldr r10, c80808080
|
||||
mov r11, #0 ; initialize sse = 0
|
||||
mov r12, #16 ; set loop counter to 16 (=block height)
|
||||
mov lr, #0 ; constant zero
|
||||
loop
|
||||
add r9, r0, r1 ; set src pointer to next row
|
||||
; 1st 4 pixels
|
||||
ldr r4, [r0, #0] ; load 4 src pixels
|
||||
ldr r6, [r9, #0] ; load 4 src pixels from next row
|
||||
ldr r5, [r2, #0] ; load 4 ref pixels
|
||||
|
||||
; bilinear interpolation
|
||||
mvn r6, r6
|
||||
uhsub8 r4, r4, r6
|
||||
eor r4, r4, r10
|
||||
|
||||
usub8 r6, r4, r5 ; calculate difference
|
||||
pld [r0, r1, lsl #1]
|
||||
sel r7, r6, lr ; select bytes with positive difference
|
||||
usub8 r6, r5, r4 ; calculate difference with reversed operands
|
||||
pld [r2, r3, lsl #1]
|
||||
sel r6, r6, lr ; select bytes with negative difference
|
||||
|
||||
; calculate partial sums
|
||||
usad8 r4, r7, lr ; calculate sum of positive differences
|
||||
usad8 r5, r6, lr ; calculate sum of negative differences
|
||||
orr r6, r6, r7 ; differences of all 4 pixels
|
||||
; calculate total sum
|
||||
adds r8, r8, r4 ; add positive differences to sum
|
||||
subs r8, r8, r5 ; subtract negative differences from sum
|
||||
|
||||
; calculate sse
|
||||
uxtb16 r5, r6 ; byte (two pixels) to halfwords
|
||||
uxtb16 r7, r6, ror #8 ; another two pixels to halfwords
|
||||
smlad r11, r5, r5, r11 ; dual signed multiply, add and accumulate (1)
|
||||
|
||||
; 2nd 4 pixels
|
||||
ldr r4, [r0, #4] ; load 4 src pixels
|
||||
ldr r6, [r9, #4] ; load 4 src pixels from next row
|
||||
ldr r5, [r2, #4] ; load 4 ref pixels
|
||||
|
||||
; bilinear interpolation
|
||||
mvn r6, r6
|
||||
uhsub8 r4, r4, r6
|
||||
eor r4, r4, r10
|
||||
|
||||
smlad r11, r7, r7, r11 ; dual signed multiply, add and accumulate (2)
|
||||
|
||||
usub8 r6, r4, r5 ; calculate difference
|
||||
sel r7, r6, lr ; select bytes with positive difference
|
||||
usub8 r6, r5, r4 ; calculate difference with reversed operands
|
||||
sel r6, r6, lr ; select bytes with negative difference
|
||||
|
||||
; calculate partial sums
|
||||
usad8 r4, r7, lr ; calculate sum of positive differences
|
||||
usad8 r5, r6, lr ; calculate sum of negative differences
|
||||
orr r6, r6, r7 ; differences of all 4 pixels
|
||||
|
||||
; calculate total sum
|
||||
add r8, r8, r4 ; add positive differences to sum
|
||||
sub r8, r8, r5 ; subtract negative differences from sum
|
||||
|
||||
; calculate sse
|
||||
uxtb16 r5, r6 ; byte (two pixels) to halfwords
|
||||
uxtb16 r7, r6, ror #8 ; another two pixels to halfwords
|
||||
smlad r11, r5, r5, r11 ; dual signed multiply, add and accumulate (1)
|
||||
|
||||
; 3rd 4 pixels
|
||||
ldr r4, [r0, #8] ; load 4 src pixels
|
||||
ldr r6, [r9, #8] ; load 4 src pixels from next row
|
||||
ldr r5, [r2, #8] ; load 4 ref pixels
|
||||
|
||||
; bilinear interpolation
|
||||
mvn r6, r6
|
||||
uhsub8 r4, r4, r6
|
||||
eor r4, r4, r10
|
||||
|
||||
smlad r11, r7, r7, r11 ; dual signed multiply, add and accumulate (2)
|
||||
|
||||
usub8 r6, r4, r5 ; calculate difference
|
||||
sel r7, r6, lr ; select bytes with positive difference
|
||||
usub8 r6, r5, r4 ; calculate difference with reversed operands
|
||||
sel r6, r6, lr ; select bytes with negative difference
|
||||
|
||||
; calculate partial sums
|
||||
usad8 r4, r7, lr ; calculate sum of positive differences
|
||||
usad8 r5, r6, lr ; calculate sum of negative differences
|
||||
orr r6, r6, r7 ; differences of all 4 pixels
|
||||
|
||||
; calculate total sum
|
||||
add r8, r8, r4 ; add positive differences to sum
|
||||
sub r8, r8, r5 ; subtract negative differences from sum
|
||||
|
||||
; calculate sse
|
||||
uxtb16 r5, r6 ; byte (two pixels) to halfwords
|
||||
uxtb16 r7, r6, ror #8 ; another two pixels to halfwords
|
||||
smlad r11, r5, r5, r11 ; dual signed multiply, add and accumulate (1)
|
||||
|
||||
; 4th 4 pixels
|
||||
ldr r4, [r0, #12] ; load 4 src pixels
|
||||
ldr r6, [r9, #12] ; load 4 src pixels from next row
|
||||
ldr r5, [r2, #12] ; load 4 ref pixels
|
||||
|
||||
; bilinear interpolation
|
||||
mvn r6, r6
|
||||
uhsub8 r4, r4, r6
|
||||
eor r4, r4, r10
|
||||
|
||||
smlad r11, r7, r7, r11 ; dual signed multiply, add and accumulate (2)
|
||||
|
||||
usub8 r6, r4, r5 ; calculate difference
|
||||
add r0, r0, r1 ; set src_ptr to next row
|
||||
sel r7, r6, lr ; select bytes with positive difference
|
||||
usub8 r6, r5, r4 ; calculate difference with reversed operands
|
||||
add r2, r2, r3 ; set dst_ptr to next row
|
||||
sel r6, r6, lr ; select bytes with negative difference
|
||||
|
||||
; calculate partial sums
|
||||
usad8 r4, r7, lr ; calculate sum of positive differences
|
||||
usad8 r5, r6, lr ; calculate sum of negative differences
|
||||
orr r6, r6, r7 ; differences of all 4 pixels
|
||||
|
||||
; calculate total sum
|
||||
add r8, r8, r4 ; add positive differences to sum
|
||||
sub r8, r8, r5 ; subtract negative differences from sum
|
||||
|
||||
; calculate sse
|
||||
uxtb16 r5, r6 ; byte (two pixels) to halfwords
|
||||
uxtb16 r7, r6, ror #8 ; another two pixels to halfwords
|
||||
smlad r11, r5, r5, r11 ; dual signed multiply, add and accumulate (1)
|
||||
smlad r11, r7, r7, r11 ; dual signed multiply, add and accumulate (2)
|
||||
|
||||
|
||||
subs r12, r12, #1
|
||||
|
||||
bne loop
|
||||
|
||||
; return stuff
|
||||
ldr r6, [sp, #40] ; get address of sse
|
||||
mul r0, r8, r8 ; sum * sum
|
||||
str r11, [r6] ; store sse
|
||||
sub r0, r11, r0, lsr #8 ; return (sse - ((sum * sum) >> 8))
|
||||
|
||||
ldmfd sp!, {r4-r12, pc}
|
||||
|
||||
ENDP
|
||||
|
||||
c80808080
|
||||
DCD 0x80808080
|
||||
|
||||
END
|
||||
|
||||
@@ -1,361 +0,0 @@
|
||||
;
|
||||
; Copyright (c) 2016, Alliance for Open Media. All rights reserved
|
||||
;
|
||||
; This source code is subject to the terms of the BSD 2 Clause License and
|
||||
; the Alliance for Open Media Patent License 1.0. If the BSD 2 Clause License
|
||||
; was not distributed with this source code in the LICENSE file, you can
|
||||
; obtain it at www.aomedia.org/license/software. If the Alliance for Open
|
||||
; Media Patent License 1.0 was not distributed with this source code in the
|
||||
; PATENTS file, you can obtain it at www.aomedia.org/license/patent.
|
||||
;
|
||||
|
||||
;
|
||||
|
||||
|
||||
EXPORT |aom_variance16x16_media|
|
||||
EXPORT |aom_variance8x8_media|
|
||||
EXPORT |aom_mse16x16_media|
|
||||
|
||||
ARM
|
||||
REQUIRE8
|
||||
PRESERVE8
|
||||
|
||||
AREA ||.text||, CODE, READONLY, ALIGN=2
|
||||
|
||||
; r0 unsigned char *src_ptr
|
||||
; r1 int source_stride
|
||||
; r2 unsigned char *ref_ptr
|
||||
; r3 int recon_stride
|
||||
; stack unsigned int *sse
|
||||
|aom_variance16x16_media| PROC
|
||||
|
||||
stmfd sp!, {r4-r12, lr}
|
||||
|
||||
pld [r0, r1, lsl #0]
|
||||
pld [r2, r3, lsl #0]
|
||||
|
||||
mov r8, #0 ; initialize sum = 0
|
||||
mov r11, #0 ; initialize sse = 0
|
||||
mov r12, #16 ; set loop counter to 16 (=block height)
|
||||
|
||||
loop16x16
|
||||
; 1st 4 pixels
|
||||
ldr r4, [r0, #0] ; load 4 src pixels
|
||||
ldr r5, [r2, #0] ; load 4 ref pixels
|
||||
|
||||
mov lr, #0 ; constant zero
|
||||
|
||||
usub8 r6, r4, r5 ; calculate difference
|
||||
pld [r0, r1, lsl #1]
|
||||
sel r7, r6, lr ; select bytes with positive difference
|
||||
usub8 r9, r5, r4 ; calculate difference with reversed operands
|
||||
pld [r2, r3, lsl #1]
|
||||
sel r6, r9, lr ; select bytes with negative difference
|
||||
|
||||
; calculate partial sums
|
||||
usad8 r4, r7, lr ; calculate sum of positive differences
|
||||
usad8 r5, r6, lr ; calculate sum of negative differences
|
||||
orr r6, r6, r7 ; differences of all 4 pixels
|
||||
; calculate total sum
|
||||
adds r8, r8, r4 ; add positive differences to sum
|
||||
subs r8, r8, r5 ; subtract negative differences from sum
|
||||
|
||||
; calculate sse
|
||||
uxtb16 r5, r6 ; byte (two pixels) to halfwords
|
||||
uxtb16 r10, r6, ror #8 ; another two pixels to halfwords
|
||||
smlad r11, r5, r5, r11 ; dual signed multiply, add and accumulate (1)
|
||||
|
||||
; 2nd 4 pixels
|
||||
ldr r4, [r0, #4] ; load 4 src pixels
|
||||
ldr r5, [r2, #4] ; load 4 ref pixels
|
||||
smlad r11, r10, r10, r11 ; dual signed multiply, add and accumulate (2)
|
||||
|
||||
usub8 r6, r4, r5 ; calculate difference
|
||||
sel r7, r6, lr ; select bytes with positive difference
|
||||
usub8 r9, r5, r4 ; calculate difference with reversed operands
|
||||
sel r6, r9, lr ; select bytes with negative difference
|
||||
|
||||
; calculate partial sums
|
||||
usad8 r4, r7, lr ; calculate sum of positive differences
|
||||
usad8 r5, r6, lr ; calculate sum of negative differences
|
||||
orr r6, r6, r7 ; differences of all 4 pixels
|
||||
|
||||
; calculate total sum
|
||||
add r8, r8, r4 ; add positive differences to sum
|
||||
sub r8, r8, r5 ; subtract negative differences from sum
|
||||
|
||||
; calculate sse
|
||||
uxtb16 r5, r6 ; byte (two pixels) to halfwords
|
||||
uxtb16 r10, r6, ror #8 ; another two pixels to halfwords
|
||||
smlad r11, r5, r5, r11 ; dual signed multiply, add and accumulate (1)
|
||||
|
||||
; 3rd 4 pixels
|
||||
ldr r4, [r0, #8] ; load 4 src pixels
|
||||
ldr r5, [r2, #8] ; load 4 ref pixels
|
||||
smlad r11, r10, r10, r11 ; dual signed multiply, add and accumulate (2)
|
||||
|
||||
usub8 r6, r4, r5 ; calculate difference
|
||||
sel r7, r6, lr ; select bytes with positive difference
|
||||
usub8 r9, r5, r4 ; calculate difference with reversed operands
|
||||
sel r6, r9, lr ; select bytes with negative difference
|
||||
|
||||
; calculate partial sums
|
||||
usad8 r4, r7, lr ; calculate sum of positive differences
|
||||
usad8 r5, r6, lr ; calculate sum of negative differences
|
||||
orr r6, r6, r7 ; differences of all 4 pixels
|
||||
|
||||
; calculate total sum
|
||||
add r8, r8, r4 ; add positive differences to sum
|
||||
sub r8, r8, r5 ; subtract negative differences from sum
|
||||
|
||||
; calculate sse
|
||||
uxtb16 r5, r6 ; byte (two pixels) to halfwords
|
||||
uxtb16 r10, r6, ror #8 ; another two pixels to halfwords
|
||||
smlad r11, r5, r5, r11 ; dual signed multiply, add and accumulate (1)
|
||||
|
||||
; 4th 4 pixels
|
||||
ldr r4, [r0, #12] ; load 4 src pixels
|
||||
ldr r5, [r2, #12] ; load 4 ref pixels
|
||||
smlad r11, r10, r10, r11 ; dual signed multiply, add and accumulate (2)
|
||||
|
||||
usub8 r6, r4, r5 ; calculate difference
|
||||
add r0, r0, r1 ; set src_ptr to next row
|
||||
sel r7, r6, lr ; select bytes with positive difference
|
||||
usub8 r9, r5, r4 ; calculate difference with reversed operands
|
||||
add r2, r2, r3 ; set dst_ptr to next row
|
||||
sel r6, r9, lr ; select bytes with negative difference
|
||||
|
||||
; calculate partial sums
|
||||
usad8 r4, r7, lr ; calculate sum of positive differences
|
||||
usad8 r5, r6, lr ; calculate sum of negative differences
|
||||
orr r6, r6, r7 ; differences of all 4 pixels
|
||||
|
||||
; calculate total sum
|
||||
add r8, r8, r4 ; add positive differences to sum
|
||||
sub r8, r8, r5 ; subtract negative differences from sum
|
||||
|
||||
; calculate sse
|
||||
uxtb16 r5, r6 ; byte (two pixels) to halfwords
|
||||
uxtb16 r10, r6, ror #8 ; another two pixels to halfwords
|
||||
smlad r11, r5, r5, r11 ; dual signed multiply, add and accumulate (1)
|
||||
smlad r11, r10, r10, r11 ; dual signed multiply, add and accumulate (2)
|
||||
|
||||
|
||||
subs r12, r12, #1
|
||||
|
||||
bne loop16x16
|
||||
|
||||
; return stuff
|
||||
ldr r6, [sp, #40] ; get address of sse
|
||||
mul r0, r8, r8 ; sum * sum
|
||||
str r11, [r6] ; store sse
|
||||
sub r0, r11, r0, lsr #8 ; return (sse - ((sum * sum) >> 8))
|
||||
|
||||
ldmfd sp!, {r4-r12, pc}
|
||||
|
||||
ENDP
|
||||
|
||||
; r0 unsigned char *src_ptr
|
||||
; r1 int source_stride
|
||||
; r2 unsigned char *ref_ptr
|
||||
; r3 int recon_stride
|
||||
; stack unsigned int *sse
|
||||
|aom_variance8x8_media| PROC
|
||||
|
||||
push {r4-r10, lr}
|
||||
|
||||
pld [r0, r1, lsl #0]
|
||||
pld [r2, r3, lsl #0]
|
||||
|
||||
mov r12, #8 ; set loop counter to 8 (=block height)
|
||||
mov r4, #0 ; initialize sum = 0
|
||||
mov r5, #0 ; initialize sse = 0
|
||||
|
||||
loop8x8
|
||||
; 1st 4 pixels
|
||||
ldr r6, [r0, #0x0] ; load 4 src pixels
|
||||
ldr r7, [r2, #0x0] ; load 4 ref pixels
|
||||
|
||||
mov lr, #0 ; constant zero
|
||||
|
||||
usub8 r8, r6, r7 ; calculate difference
|
||||
pld [r0, r1, lsl #1]
|
||||
sel r10, r8, lr ; select bytes with positive difference
|
||||
usub8 r9, r7, r6 ; calculate difference with reversed operands
|
||||
pld [r2, r3, lsl #1]
|
||||
sel r8, r9, lr ; select bytes with negative difference
|
||||
|
||||
; calculate partial sums
|
||||
usad8 r6, r10, lr ; calculate sum of positive differences
|
||||
usad8 r7, r8, lr ; calculate sum of negative differences
|
||||
orr r8, r8, r10 ; differences of all 4 pixels
|
||||
; calculate total sum
|
||||
add r4, r4, r6 ; add positive differences to sum
|
||||
sub r4, r4, r7 ; subtract negative differences from sum
|
||||
|
||||
; calculate sse
|
||||
uxtb16 r7, r8 ; byte (two pixels) to halfwords
|
||||
uxtb16 r10, r8, ror #8 ; another two pixels to halfwords
|
||||
smlad r5, r7, r7, r5 ; dual signed multiply, add and accumulate (1)
|
||||
|
||||
; 2nd 4 pixels
|
||||
ldr r6, [r0, #0x4] ; load 4 src pixels
|
||||
ldr r7, [r2, #0x4] ; load 4 ref pixels
|
||||
smlad r5, r10, r10, r5 ; dual signed multiply, add and accumulate (2)
|
||||
|
||||
usub8 r8, r6, r7 ; calculate difference
|
||||
add r0, r0, r1 ; set src_ptr to next row
|
||||
sel r10, r8, lr ; select bytes with positive difference
|
||||
usub8 r9, r7, r6 ; calculate difference with reversed operands
|
||||
add r2, r2, r3 ; set dst_ptr to next row
|
||||
sel r8, r9, lr ; select bytes with negative difference
|
||||
|
||||
; calculate partial sums
|
||||
usad8 r6, r10, lr ; calculate sum of positive differences
|
||||
usad8 r7, r8, lr ; calculate sum of negative differences
|
||||
orr r8, r8, r10 ; differences of all 4 pixels
|
||||
|
||||
; calculate total sum
|
||||
add r4, r4, r6 ; add positive differences to sum
|
||||
sub r4, r4, r7 ; subtract negative differences from sum
|
||||
|
||||
; calculate sse
|
||||
uxtb16 r7, r8 ; byte (two pixels) to halfwords
|
||||
uxtb16 r10, r8, ror #8 ; another two pixels to halfwords
|
||||
smlad r5, r7, r7, r5 ; dual signed multiply, add and accumulate (1)
|
||||
subs r12, r12, #1 ; next row
|
||||
smlad r5, r10, r10, r5 ; dual signed multiply, add and accumulate (2)
|
||||
|
||||
bne loop8x8
|
||||
|
||||
; return stuff
|
||||
ldr r8, [sp, #32] ; get address of sse
|
||||
mul r1, r4, r4 ; sum * sum
|
||||
str r5, [r8] ; store sse
|
||||
sub r0, r5, r1, ASR #6 ; return (sse - ((sum * sum) >> 6))
|
||||
|
||||
pop {r4-r10, pc}
|
||||
|
||||
ENDP
|
||||
|
||||
; r0 unsigned char *src_ptr
|
||||
; r1 int source_stride
|
||||
; r2 unsigned char *ref_ptr
|
||||
; r3 int recon_stride
|
||||
; stack unsigned int *sse
|
||||
;
|
||||
;note: Based on aom_variance16x16_media. In this function, sum is never used.
|
||||
; So, we can remove this part of calculation.
|
||||
|
||||
|aom_mse16x16_media| PROC
|
||||
|
||||
push {r4-r9, lr}
|
||||
|
||||
pld [r0, r1, lsl #0]
|
||||
pld [r2, r3, lsl #0]
|
||||
|
||||
mov r12, #16 ; set loop counter to 16 (=block height)
|
||||
mov r4, #0 ; initialize sse = 0
|
||||
|
||||
loopmse
|
||||
; 1st 4 pixels
|
||||
ldr r5, [r0, #0x0] ; load 4 src pixels
|
||||
ldr r6, [r2, #0x0] ; load 4 ref pixels
|
||||
|
||||
mov lr, #0 ; constant zero
|
||||
|
||||
usub8 r8, r5, r6 ; calculate difference
|
||||
pld [r0, r1, lsl #1]
|
||||
sel r7, r8, lr ; select bytes with positive difference
|
||||
usub8 r9, r6, r5 ; calculate difference with reversed operands
|
||||
pld [r2, r3, lsl #1]
|
||||
sel r8, r9, lr ; select bytes with negative difference
|
||||
|
||||
; calculate partial sums
|
||||
usad8 r5, r7, lr ; calculate sum of positive differences
|
||||
usad8 r6, r8, lr ; calculate sum of negative differences
|
||||
orr r8, r8, r7 ; differences of all 4 pixels
|
||||
|
||||
ldr r5, [r0, #0x4] ; load 4 src pixels
|
||||
|
||||
; calculate sse
|
||||
uxtb16 r6, r8 ; byte (two pixels) to halfwords
|
||||
uxtb16 r7, r8, ror #8 ; another two pixels to halfwords
|
||||
smlad r4, r6, r6, r4 ; dual signed multiply, add and accumulate (1)
|
||||
|
||||
; 2nd 4 pixels
|
||||
ldr r6, [r2, #0x4] ; load 4 ref pixels
|
||||
smlad r4, r7, r7, r4 ; dual signed multiply, add and accumulate (2)
|
||||
|
||||
usub8 r8, r5, r6 ; calculate difference
|
||||
sel r7, r8, lr ; select bytes with positive difference
|
||||
usub8 r9, r6, r5 ; calculate difference with reversed operands
|
||||
sel r8, r9, lr ; select bytes with negative difference
|
||||
|
||||
; calculate partial sums
|
||||
usad8 r5, r7, lr ; calculate sum of positive differences
|
||||
usad8 r6, r8, lr ; calculate sum of negative differences
|
||||
orr r8, r8, r7 ; differences of all 4 pixels
|
||||
ldr r5, [r0, #0x8] ; load 4 src pixels
|
||||
; calculate sse
|
||||
uxtb16 r6, r8 ; byte (two pixels) to halfwords
|
||||
uxtb16 r7, r8, ror #8 ; another two pixels to halfwords
|
||||
smlad r4, r6, r6, r4 ; dual signed multiply, add and accumulate (1)
|
||||
|
||||
; 3rd 4 pixels
|
||||
ldr r6, [r2, #0x8] ; load 4 ref pixels
|
||||
smlad r4, r7, r7, r4 ; dual signed multiply, add and accumulate (2)
|
||||
|
||||
usub8 r8, r5, r6 ; calculate difference
|
||||
sel r7, r8, lr ; select bytes with positive difference
|
||||
usub8 r9, r6, r5 ; calculate difference with reversed operands
|
||||
sel r8, r9, lr ; select bytes with negative difference
|
||||
|
||||
; calculate partial sums
|
||||
usad8 r5, r7, lr ; calculate sum of positive differences
|
||||
usad8 r6, r8, lr ; calculate sum of negative differences
|
||||
orr r8, r8, r7 ; differences of all 4 pixels
|
||||
|
||||
ldr r5, [r0, #0xc] ; load 4 src pixels
|
||||
|
||||
; calculate sse
|
||||
uxtb16 r6, r8 ; byte (two pixels) to halfwords
|
||||
uxtb16 r7, r8, ror #8 ; another two pixels to halfwords
|
||||
smlad r4, r6, r6, r4 ; dual signed multiply, add and accumulate (1)
|
||||
|
||||
; 4th 4 pixels
|
||||
ldr r6, [r2, #0xc] ; load 4 ref pixels
|
||||
smlad r4, r7, r7, r4 ; dual signed multiply, add and accumulate (2)
|
||||
|
||||
usub8 r8, r5, r6 ; calculate difference
|
||||
add r0, r0, r1 ; set src_ptr to next row
|
||||
sel r7, r8, lr ; select bytes with positive difference
|
||||
usub8 r9, r6, r5 ; calculate difference with reversed operands
|
||||
add r2, r2, r3 ; set dst_ptr to next row
|
||||
sel r8, r9, lr ; select bytes with negative difference
|
||||
|
||||
; calculate partial sums
|
||||
usad8 r5, r7, lr ; calculate sum of positive differences
|
||||
usad8 r6, r8, lr ; calculate sum of negative differences
|
||||
orr r8, r8, r7 ; differences of all 4 pixels
|
||||
|
||||
subs r12, r12, #1 ; next row
|
||||
|
||||
; calculate sse
|
||||
uxtb16 r6, r8 ; byte (two pixels) to halfwords
|
||||
uxtb16 r7, r8, ror #8 ; another two pixels to halfwords
|
||||
smlad r4, r6, r6, r4 ; dual signed multiply, add and accumulate (1)
|
||||
smlad r4, r7, r7, r4 ; dual signed multiply, add and accumulate (2)
|
||||
|
||||
bne loopmse
|
||||
|
||||
; return stuff
|
||||
ldr r1, [sp, #28] ; get address of sse
|
||||
mov r0, r4 ; return sse
|
||||
str r4, [r1] ; store sse
|
||||
|
||||
pop {r4-r9, pc}
|
||||
|
||||
ENDP
|
||||
|
||||
END
|
||||
@@ -1,240 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2016, Alliance for Open Media. All rights reserved
|
||||
*
|
||||
* This source code is subject to the terms of the BSD 2 Clause License and
|
||||
* the Alliance for Open Media Patent License 1.0. If the BSD 2 Clause License
|
||||
* was not distributed with this source code in the LICENSE file, you can
|
||||
* obtain it at www.aomedia.org/license/software. If the Alliance for Open
|
||||
* Media Patent License 1.0 was not distributed with this source code in the
|
||||
* PATENTS file, you can obtain it at www.aomedia.org/license/patent.
|
||||
*/
|
||||
|
||||
#ifndef AOM_DSP_BITREADER_H_
|
||||
#define AOM_DSP_BITREADER_H_
|
||||
|
||||
#include <assert.h>
|
||||
#include <limits.h>
|
||||
|
||||
#include "./aom_config.h"
|
||||
#if CONFIG_EC_ADAPT && !CONFIG_EC_MULTISYMBOL
|
||||
#error "CONFIG_EC_ADAPT is enabled without enabling CONFIG_EC_MULTISYMBOL."
|
||||
#endif
|
||||
|
||||
#include "aom/aomdx.h"
|
||||
#include "aom/aom_integer.h"
|
||||
#if CONFIG_ANS
|
||||
#include "aom_dsp/ansreader.h"
|
||||
#elif CONFIG_DAALA_EC
|
||||
#include "aom_dsp/daalaboolreader.h"
|
||||
#else
|
||||
#include "aom_dsp/dkboolreader.h"
|
||||
#endif
|
||||
#include "aom_dsp/prob.h"
|
||||
#include "av1/common/odintrin.h"
|
||||
|
||||
#if CONFIG_ACCOUNTING
|
||||
#include "av1/common/accounting.h"
|
||||
#define ACCT_STR_NAME acct_str
|
||||
#define ACCT_STR_PARAM , const char *ACCT_STR_NAME
|
||||
#define ACCT_STR_ARG(s) , s
|
||||
#else
|
||||
#define ACCT_STR_PARAM
|
||||
#define ACCT_STR_ARG(s)
|
||||
#endif
|
||||
|
||||
#define aom_read(r, prob, ACCT_STR_NAME) \
|
||||
aom_read_(r, prob ACCT_STR_ARG(ACCT_STR_NAME))
|
||||
#define aom_read_bit(r, ACCT_STR_NAME) \
|
||||
aom_read_bit_(r ACCT_STR_ARG(ACCT_STR_NAME))
|
||||
#define aom_read_tree(r, tree, probs, ACCT_STR_NAME) \
|
||||
aom_read_tree_(r, tree, probs ACCT_STR_ARG(ACCT_STR_NAME))
|
||||
#define aom_read_literal(r, bits, ACCT_STR_NAME) \
|
||||
aom_read_literal_(r, bits ACCT_STR_ARG(ACCT_STR_NAME))
|
||||
#define aom_read_tree_bits(r, tree, probs, ACCT_STR_NAME) \
|
||||
aom_read_tree_bits_(r, tree, probs ACCT_STR_ARG(ACCT_STR_NAME))
|
||||
#define aom_read_symbol(r, cdf, nsymbs, ACCT_STR_NAME) \
|
||||
aom_read_symbol_(r, cdf, nsymbs ACCT_STR_ARG(ACCT_STR_NAME))
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#if CONFIG_ANS
|
||||
typedef struct AnsDecoder aom_reader;
|
||||
#elif CONFIG_DAALA_EC
|
||||
typedef struct daala_reader aom_reader;
|
||||
#else
|
||||
typedef struct aom_dk_reader aom_reader;
|
||||
#endif
|
||||
|
||||
static INLINE int aom_reader_init(aom_reader *r, const uint8_t *buffer,
|
||||
size_t size, aom_decrypt_cb decrypt_cb,
|
||||
void *decrypt_state) {
|
||||
#if CONFIG_ANS
|
||||
(void)decrypt_cb;
|
||||
(void)decrypt_state;
|
||||
assert(size <= INT_MAX);
|
||||
return ans_read_init(r, buffer, size);
|
||||
#elif CONFIG_DAALA_EC
|
||||
(void)decrypt_cb;
|
||||
(void)decrypt_state;
|
||||
return aom_daala_reader_init(r, buffer, size);
|
||||
#else
|
||||
return aom_dk_reader_init(r, buffer, size, decrypt_cb, decrypt_state);
|
||||
#endif
|
||||
}
|
||||
|
||||
static INLINE const uint8_t *aom_reader_find_end(aom_reader *r) {
|
||||
#if CONFIG_ANS
|
||||
(void)r;
|
||||
assert(0 && "Use the raw buffer size with ANS");
|
||||
return NULL;
|
||||
#elif CONFIG_DAALA_EC
|
||||
return aom_daala_reader_find_end(r);
|
||||
#else
|
||||
return aom_dk_reader_find_end(r);
|
||||
#endif
|
||||
}
|
||||
|
||||
static INLINE int aom_reader_has_error(aom_reader *r) {
|
||||
#if CONFIG_ANS
|
||||
return ans_reader_has_error(r);
|
||||
#elif CONFIG_DAALA_EC
|
||||
return aom_daala_reader_has_error(r);
|
||||
#else
|
||||
return aom_dk_reader_has_error(r);
|
||||
#endif
|
||||
}
|
||||
|
||||
// Returns the position in the bit reader in bits.
|
||||
static INLINE uint32_t aom_reader_tell(const aom_reader *r) {
|
||||
#if CONFIG_ANS
|
||||
(void)r;
|
||||
assert(0 && "aom_reader_tell() is unimplemented for ANS");
|
||||
return 0;
|
||||
#elif CONFIG_DAALA_EC
|
||||
return aom_daala_reader_tell(r);
|
||||
#else
|
||||
return aom_dk_reader_tell(r);
|
||||
#endif
|
||||
}
|
||||
|
||||
// Returns the position in the bit reader in 1/8th bits.
|
||||
static INLINE uint32_t aom_reader_tell_frac(const aom_reader *r) {
|
||||
#if CONFIG_ANS
|
||||
(void)r;
|
||||
assert(0 && "aom_reader_tell_frac() is unimplemented for ANS");
|
||||
return 0;
|
||||
#elif CONFIG_DAALA_EC
|
||||
return aom_daala_reader_tell_frac(r);
|
||||
#else
|
||||
return aom_dk_reader_tell_frac(r);
|
||||
#endif
|
||||
}
|
||||
|
||||
#if CONFIG_ACCOUNTING
|
||||
static INLINE void aom_process_accounting(const aom_reader *r ACCT_STR_PARAM) {
|
||||
if (r->accounting != NULL) {
|
||||
uint32_t tell_frac;
|
||||
tell_frac = aom_reader_tell_frac(r);
|
||||
aom_accounting_record(r->accounting, ACCT_STR_NAME,
|
||||
tell_frac - r->accounting->last_tell_frac);
|
||||
r->accounting->last_tell_frac = tell_frac;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
static INLINE int aom_read_(aom_reader *r, int prob ACCT_STR_PARAM) {
|
||||
int ret;
|
||||
#if CONFIG_ANS
|
||||
ret = uabs_read(r, prob);
|
||||
#elif CONFIG_DAALA_EC
|
||||
ret = aom_daala_read(r, prob);
|
||||
#else
|
||||
ret = aom_dk_read(r, prob);
|
||||
#endif
|
||||
#if CONFIG_ACCOUNTING
|
||||
if (ACCT_STR_NAME) aom_process_accounting(r, ACCT_STR_NAME);
|
||||
#endif
|
||||
return ret;
|
||||
}
|
||||
|
||||
static INLINE int aom_read_bit_(aom_reader *r ACCT_STR_PARAM) {
|
||||
int ret;
|
||||
#if CONFIG_ANS
|
||||
ret = uabs_read_bit(r); // Non trivial optimization at half probability
|
||||
#else
|
||||
ret = aom_read(r, 128, NULL); // aom_prob_half
|
||||
#endif
|
||||
#if CONFIG_ACCOUNTING
|
||||
if (ACCT_STR_NAME) aom_process_accounting(r, ACCT_STR_NAME);
|
||||
#endif
|
||||
return ret;
|
||||
}
|
||||
|
||||
static INLINE int aom_read_literal_(aom_reader *r, int bits ACCT_STR_PARAM) {
|
||||
int literal = 0, bit;
|
||||
|
||||
for (bit = bits - 1; bit >= 0; bit--) literal |= aom_read_bit(r, NULL) << bit;
|
||||
#if CONFIG_ACCOUNTING
|
||||
if (ACCT_STR_NAME) aom_process_accounting(r, ACCT_STR_NAME);
|
||||
#endif
|
||||
return literal;
|
||||
}
|
||||
|
||||
static INLINE int aom_read_tree_bits_(aom_reader *r, const aom_tree_index *tree,
|
||||
const aom_prob *probs ACCT_STR_PARAM) {
|
||||
aom_tree_index i = 0;
|
||||
|
||||
while ((i = tree[i + aom_read(r, probs[i >> 1], NULL)]) > 0) continue;
|
||||
#if CONFIG_ACCOUNTING
|
||||
if (ACCT_STR_NAME) aom_process_accounting(r, ACCT_STR_NAME);
|
||||
#endif
|
||||
return -i;
|
||||
}
|
||||
|
||||
static INLINE int aom_read_tree_(aom_reader *r, const aom_tree_index *tree,
|
||||
const aom_prob *probs ACCT_STR_PARAM) {
|
||||
int ret;
|
||||
#if CONFIG_DAALA_EC
|
||||
ret = daala_read_tree_bits(r, tree, probs);
|
||||
#else
|
||||
ret = aom_read_tree_bits(r, tree, probs, NULL);
|
||||
#endif
|
||||
#if CONFIG_ACCOUNTING
|
||||
if (ACCT_STR_NAME) aom_process_accounting(r, ACCT_STR_NAME);
|
||||
#endif
|
||||
return ret;
|
||||
}
|
||||
|
||||
#if CONFIG_EC_MULTISYMBOL
|
||||
static INLINE int aom_read_symbol_(aom_reader *r, aom_cdf_prob *cdf,
|
||||
int nsymbs ACCT_STR_PARAM) {
|
||||
int ret;
|
||||
#if CONFIG_RANS
|
||||
(void)nsymbs;
|
||||
ret = rans_read(r, cdf);
|
||||
#elif CONFIG_DAALA_EC
|
||||
ret = daala_read_symbol(r, cdf, nsymbs);
|
||||
#else
|
||||
#error \
|
||||
"CONFIG_EC_MULTISYMBOL is selected without a valid backing entropy " \
|
||||
"coder. Enable daala_ec or ans for a valid configuration."
|
||||
#endif
|
||||
|
||||
#if CONFIG_EC_ADAPT
|
||||
update_cdf(cdf, ret, nsymbs);
|
||||
#endif
|
||||
|
||||
#if CONFIG_ACCOUNTING
|
||||
if (ACCT_STR_NAME) aom_process_accounting(r, ACCT_STR_NAME);
|
||||
#endif
|
||||
return ret;
|
||||
}
|
||||
#endif // CONFIG_EC_MULTISYMBOL
|
||||
|
||||
#ifdef __cplusplus
|
||||
} // extern "C"
|
||||
#endif
|
||||
|
||||
#endif // AOM_DSP_BITREADER_H_
|
||||
@@ -1,47 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2016, Alliance for Open Media. All rights reserved
|
||||
*
|
||||
* This source code is subject to the terms of the BSD 2 Clause License and
|
||||
* the Alliance for Open Media Patent License 1.0. If the BSD 2 Clause License
|
||||
* was not distributed with this source code in the LICENSE file, you can
|
||||
* obtain it at www.aomedia.org/license/software. If the Alliance for Open
|
||||
* Media Patent License 1.0 was not distributed with this source code in the
|
||||
* PATENTS file, you can obtain it at www.aomedia.org/license/patent.
|
||||
*/
|
||||
#include "./aom_config.h"
|
||||
#include "./bitreader_buffer.h"
|
||||
|
||||
size_t aom_rb_bytes_read(struct aom_read_bit_buffer *rb) {
|
||||
return (rb->bit_offset + 7) >> 3;
|
||||
}
|
||||
|
||||
int aom_rb_read_bit(struct aom_read_bit_buffer *rb) {
|
||||
const size_t off = rb->bit_offset;
|
||||
const size_t p = off >> 3;
|
||||
const int q = 7 - (int)(off & 0x7);
|
||||
if (rb->bit_buffer + p < rb->bit_buffer_end) {
|
||||
const int bit = (rb->bit_buffer[p] >> q) & 1;
|
||||
rb->bit_offset = off + 1;
|
||||
return bit;
|
||||
} else {
|
||||
rb->error_handler(rb->error_handler_data);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
int aom_rb_read_literal(struct aom_read_bit_buffer *rb, int bits) {
|
||||
int value = 0, bit;
|
||||
for (bit = bits - 1; bit >= 0; bit--) value |= aom_rb_read_bit(rb) << bit;
|
||||
return value;
|
||||
}
|
||||
|
||||
int aom_rb_read_signed_literal(struct aom_read_bit_buffer *rb, int bits) {
|
||||
const int value = aom_rb_read_literal(rb, bits);
|
||||
return aom_rb_read_bit(rb) ? -value : value;
|
||||
}
|
||||
|
||||
int aom_rb_read_inv_signed_literal(struct aom_read_bit_buffer *rb, int bits) {
|
||||
const int nbits = sizeof(unsigned) * 8 - bits - 1;
|
||||
const unsigned value = (unsigned)aom_rb_read_literal(rb, bits + 1) << nbits;
|
||||
return ((int)value) >> nbits;
|
||||
}
|
||||
@@ -1,48 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2016, Alliance for Open Media. All rights reserved
|
||||
*
|
||||
* This source code is subject to the terms of the BSD 2 Clause License and
|
||||
* the Alliance for Open Media Patent License 1.0. If the BSD 2 Clause License
|
||||
* was not distributed with this source code in the LICENSE file, you can
|
||||
* obtain it at www.aomedia.org/license/software. If the Alliance for Open
|
||||
* Media Patent License 1.0 was not distributed with this source code in the
|
||||
* PATENTS file, you can obtain it at www.aomedia.org/license/patent.
|
||||
*/
|
||||
|
||||
#ifndef AOM_DSP_BITREADER_BUFFER_H_
|
||||
#define AOM_DSP_BITREADER_BUFFER_H_
|
||||
|
||||
#include <limits.h>
|
||||
|
||||
#include "aom/aom_integer.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
typedef void (*aom_rb_error_handler)(void *data);
|
||||
|
||||
struct aom_read_bit_buffer {
|
||||
const uint8_t *bit_buffer;
|
||||
const uint8_t *bit_buffer_end;
|
||||
size_t bit_offset;
|
||||
|
||||
void *error_handler_data;
|
||||
aom_rb_error_handler error_handler;
|
||||
};
|
||||
|
||||
size_t aom_rb_bytes_read(struct aom_read_bit_buffer *rb);
|
||||
|
||||
int aom_rb_read_bit(struct aom_read_bit_buffer *rb);
|
||||
|
||||
int aom_rb_read_literal(struct aom_read_bit_buffer *rb, int bits);
|
||||
|
||||
int aom_rb_read_signed_literal(struct aom_read_bit_buffer *rb, int bits);
|
||||
|
||||
int aom_rb_read_inv_signed_literal(struct aom_read_bit_buffer *rb, int bits);
|
||||
|
||||
#ifdef __cplusplus
|
||||
} // extern "C"
|
||||
#endif
|
||||
|
||||
#endif // AOM_DSP_BITREADER_BUFFER_H_
|
||||
@@ -1,179 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2016, Alliance for Open Media. All rights reserved
|
||||
*
|
||||
* This source code is subject to the terms of the BSD 2 Clause License and
|
||||
* the Alliance for Open Media Patent License 1.0. If the BSD 2 Clause License
|
||||
* was not distributed with this source code in the LICENSE file, you can
|
||||
* obtain it at www.aomedia.org/license/software. If the Alliance for Open
|
||||
* Media Patent License 1.0 was not distributed with this source code in the
|
||||
* PATENTS file, you can obtain it at www.aomedia.org/license/patent.
|
||||
*/
|
||||
|
||||
#ifndef AOM_DSP_BITWRITER_H_
|
||||
#define AOM_DSP_BITWRITER_H_
|
||||
|
||||
#include <assert.h>
|
||||
#include "./aom_config.h"
|
||||
#if CONFIG_EC_ADAPT && !CONFIG_EC_MULTISYMBOL
|
||||
#error "CONFIG_EC_ADAPT is enabled without enabling CONFIG_EC_MULTISYMBOL"
|
||||
#endif
|
||||
|
||||
#if CONFIG_ANS
|
||||
#include "aom_dsp/buf_ans.h"
|
||||
#elif CONFIG_DAALA_EC
|
||||
#include "aom_dsp/daalaboolwriter.h"
|
||||
#else
|
||||
#include "aom_dsp/dkboolwriter.h"
|
||||
#endif
|
||||
#include "aom_dsp/prob.h"
|
||||
|
||||
#if CONFIG_RD_DEBUG
|
||||
#include "av1/encoder/cost.h"
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#if CONFIG_ANS
|
||||
typedef struct BufAnsCoder aom_writer;
|
||||
#elif CONFIG_DAALA_EC
|
||||
typedef struct daala_writer aom_writer;
|
||||
#else
|
||||
typedef struct aom_dk_writer aom_writer;
|
||||
#endif
|
||||
|
||||
typedef struct TOKEN_STATS { int64_t cost; } TOKEN_STATS;
|
||||
|
||||
static INLINE void aom_start_encode(aom_writer *bc, uint8_t *buffer) {
|
||||
#if CONFIG_ANS
|
||||
(void)bc;
|
||||
(void)buffer;
|
||||
assert(0 && "buf_ans requires a more complicated startup procedure");
|
||||
#elif CONFIG_DAALA_EC
|
||||
aom_daala_start_encode(bc, buffer);
|
||||
#else
|
||||
aom_dk_start_encode(bc, buffer);
|
||||
#endif
|
||||
}
|
||||
|
||||
static INLINE void aom_stop_encode(aom_writer *bc) {
|
||||
#if CONFIG_ANS
|
||||
(void)bc;
|
||||
assert(0 && "buf_ans requires a more complicated shutdown procedure");
|
||||
#elif CONFIG_DAALA_EC
|
||||
aom_daala_stop_encode(bc);
|
||||
#else
|
||||
aom_dk_stop_encode(bc);
|
||||
#endif
|
||||
}
|
||||
|
||||
static INLINE void aom_write(aom_writer *br, int bit, int probability) {
|
||||
#if CONFIG_ANS
|
||||
buf_uabs_write(br, bit, probability);
|
||||
#elif CONFIG_DAALA_EC
|
||||
aom_daala_write(br, bit, probability);
|
||||
#else
|
||||
aom_dk_write(br, bit, probability);
|
||||
#endif
|
||||
}
|
||||
|
||||
static INLINE void aom_write_record(aom_writer *br, int bit, int probability,
|
||||
TOKEN_STATS *token_stats) {
|
||||
aom_write(br, bit, probability);
|
||||
#if CONFIG_RD_DEBUG
|
||||
token_stats->cost += av1_cost_bit(probability, bit);
|
||||
#else
|
||||
(void)token_stats;
|
||||
#endif
|
||||
}
|
||||
|
||||
static INLINE void aom_write_bit(aom_writer *w, int bit) {
|
||||
aom_write(w, bit, 128); // aom_prob_half
|
||||
}
|
||||
|
||||
static INLINE void aom_write_bit_record(aom_writer *w, int bit,
|
||||
TOKEN_STATS *token_stats) {
|
||||
aom_write_record(w, bit, 128, token_stats); // aom_prob_half
|
||||
}
|
||||
|
||||
static INLINE void aom_write_literal(aom_writer *w, int data, int bits) {
|
||||
int bit;
|
||||
|
||||
for (bit = bits - 1; bit >= 0; bit--) aom_write_bit(w, 1 & (data >> bit));
|
||||
}
|
||||
|
||||
static INLINE void aom_write_tree_bits(aom_writer *w, const aom_tree_index *tr,
|
||||
const aom_prob *probs, int bits, int len,
|
||||
aom_tree_index i) {
|
||||
do {
|
||||
const int bit = (bits >> --len) & 1;
|
||||
aom_write(w, bit, probs[i >> 1]);
|
||||
i = tr[i + bit];
|
||||
} while (len);
|
||||
}
|
||||
|
||||
static INLINE void aom_write_tree_bits_record(aom_writer *w,
|
||||
const aom_tree_index *tr,
|
||||
const aom_prob *probs, int bits,
|
||||
int len, aom_tree_index i,
|
||||
TOKEN_STATS *token_stats) {
|
||||
do {
|
||||
const int bit = (bits >> --len) & 1;
|
||||
aom_write_record(w, bit, probs[i >> 1], token_stats);
|
||||
i = tr[i + bit];
|
||||
} while (len);
|
||||
}
|
||||
|
||||
static INLINE void aom_write_tree(aom_writer *w, const aom_tree_index *tree,
|
||||
const aom_prob *probs, int bits, int len,
|
||||
aom_tree_index i) {
|
||||
#if CONFIG_DAALA_EC
|
||||
daala_write_tree_bits(w, tree, probs, bits, len, i);
|
||||
#else
|
||||
aom_write_tree_bits(w, tree, probs, bits, len, i);
|
||||
#endif
|
||||
}
|
||||
|
||||
static INLINE void aom_write_tree_record(aom_writer *w,
|
||||
const aom_tree_index *tree,
|
||||
const aom_prob *probs, int bits,
|
||||
int len, aom_tree_index i,
|
||||
TOKEN_STATS *token_stats) {
|
||||
#if CONFIG_DAALA_EC
|
||||
(void)token_stats;
|
||||
daala_write_tree_bits(w, tree, probs, bits, len, i);
|
||||
#else
|
||||
aom_write_tree_bits_record(w, tree, probs, bits, len, i, token_stats);
|
||||
#endif
|
||||
}
|
||||
|
||||
#if CONFIG_EC_MULTISYMBOL
|
||||
static INLINE void aom_write_symbol(aom_writer *w, int symb, aom_cdf_prob *cdf,
|
||||
int nsymbs) {
|
||||
#if CONFIG_RANS
|
||||
struct rans_sym s;
|
||||
(void)nsymbs;
|
||||
assert(cdf);
|
||||
s.cum_prob = symb > 0 ? cdf[symb - 1] : 0;
|
||||
s.prob = cdf[symb] - s.cum_prob;
|
||||
buf_rans_write(w, &s);
|
||||
#elif CONFIG_DAALA_EC
|
||||
daala_write_symbol(w, symb, cdf, nsymbs);
|
||||
#else
|
||||
#error \
|
||||
"CONFIG_EC_MULTISYMBOL is selected without a valid backing entropy " \
|
||||
"coder. Enable daala_ec or ans for a valid configuration."
|
||||
#endif
|
||||
|
||||
#if CONFIG_EC_ADAPT
|
||||
update_cdf(cdf, symb, nsymbs);
|
||||
#endif
|
||||
}
|
||||
#endif // CONFIG_EC_MULTISYMBOL
|
||||
|
||||
#ifdef __cplusplus
|
||||
} // extern "C"
|
||||
#endif
|
||||
|
||||
#endif // AOM_DSP_BITWRITER_H_
|
||||
@@ -1,43 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2016, Alliance for Open Media. All rights reserved
|
||||
*
|
||||
* This source code is subject to the terms of the BSD 2 Clause License and
|
||||
* the Alliance for Open Media Patent License 1.0. If the BSD 2 Clause License
|
||||
* was not distributed with this source code in the LICENSE file, you can
|
||||
* obtain it at www.aomedia.org/license/software. If the Alliance for Open
|
||||
* Media Patent License 1.0 was not distributed with this source code in the
|
||||
* PATENTS file, you can obtain it at www.aomedia.org/license/patent.
|
||||
*/
|
||||
|
||||
#include <limits.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "./aom_config.h"
|
||||
#include "./bitwriter_buffer.h"
|
||||
|
||||
size_t aom_wb_bytes_written(const struct aom_write_bit_buffer *wb) {
|
||||
return wb->bit_offset / CHAR_BIT + (wb->bit_offset % CHAR_BIT > 0);
|
||||
}
|
||||
|
||||
void aom_wb_write_bit(struct aom_write_bit_buffer *wb, int bit) {
|
||||
const int off = (int)wb->bit_offset;
|
||||
const int p = off / CHAR_BIT;
|
||||
const int q = CHAR_BIT - 1 - off % CHAR_BIT;
|
||||
if (q == CHAR_BIT - 1) {
|
||||
wb->bit_buffer[p] = bit << q;
|
||||
} else {
|
||||
wb->bit_buffer[p] &= ~(1 << q);
|
||||
wb->bit_buffer[p] |= bit << q;
|
||||
}
|
||||
wb->bit_offset = off + 1;
|
||||
}
|
||||
|
||||
void aom_wb_write_literal(struct aom_write_bit_buffer *wb, int data, int bits) {
|
||||
int bit;
|
||||
for (bit = bits - 1; bit >= 0; bit--) aom_wb_write_bit(wb, (data >> bit) & 1);
|
||||
}
|
||||
|
||||
void aom_wb_write_inv_signed_literal(struct aom_write_bit_buffer *wb, int data,
|
||||
int bits) {
|
||||
aom_wb_write_literal(wb, data, bits + 1);
|
||||
}
|
||||
@@ -1,39 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2016, Alliance for Open Media. All rights reserved
|
||||
*
|
||||
* This source code is subject to the terms of the BSD 2 Clause License and
|
||||
* the Alliance for Open Media Patent License 1.0. If the BSD 2 Clause License
|
||||
* was not distributed with this source code in the LICENSE file, you can
|
||||
* obtain it at www.aomedia.org/license/software. If the Alliance for Open
|
||||
* Media Patent License 1.0 was not distributed with this source code in the
|
||||
* PATENTS file, you can obtain it at www.aomedia.org/license/patent.
|
||||
*/
|
||||
|
||||
#ifndef AOM_DSP_BITWRITER_BUFFER_H_
|
||||
#define AOM_DSP_BITWRITER_BUFFER_H_
|
||||
|
||||
#include "aom/aom_integer.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
struct aom_write_bit_buffer {
|
||||
uint8_t *bit_buffer;
|
||||
size_t bit_offset;
|
||||
};
|
||||
|
||||
size_t aom_wb_bytes_written(const struct aom_write_bit_buffer *wb);
|
||||
|
||||
void aom_wb_write_bit(struct aom_write_bit_buffer *wb, int bit);
|
||||
|
||||
void aom_wb_write_literal(struct aom_write_bit_buffer *wb, int data, int bits);
|
||||
|
||||
void aom_wb_write_inv_signed_literal(struct aom_write_bit_buffer *wb, int data,
|
||||
int bits);
|
||||
|
||||
#ifdef __cplusplus
|
||||
} // extern "C"
|
||||
#endif
|
||||
|
||||
#endif // AOM_DSP_BITWRITER_BUFFER_H_
|
||||
@@ -1,42 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2016, Alliance for Open Media. All rights reserved
|
||||
*
|
||||
* This source code is subject to the terms of the BSD 2 Clause License and
|
||||
* the Alliance for Open Media Patent License 1.0. If the BSD 2 Clause License
|
||||
* was not distributed with this source code in the LICENSE file, you can
|
||||
* obtain it at www.aomedia.org/license/software. If the Alliance for Open
|
||||
* Media Patent License 1.0 was not distributed with this source code in the
|
||||
* PATENTS file, you can obtain it at www.aomedia.org/license/patent.
|
||||
*/
|
||||
|
||||
#ifndef AOM_DSP_BLEND_H_
|
||||
#define AOM_DSP_BLEND_H_
|
||||
|
||||
#include "aom_ports/mem.h"
|
||||
|
||||
// Various blending functions and macros.
|
||||
// See also the aom_blend_* functions in aom_dsp_rtcd.h
|
||||
|
||||
// Alpha blending with alpha values from the range [0, 64], where 64
|
||||
// means use the first input and 0 means use the second input.
|
||||
|
||||
#define AOM_BLEND_A64_ROUND_BITS 6
|
||||
#define AOM_BLEND_A64_MAX_ALPHA (1 << AOM_BLEND_A64_ROUND_BITS) // 64
|
||||
|
||||
#define AOM_BLEND_A64(a, v0, v1) \
|
||||
ROUND_POWER_OF_TWO((a) * (v0) + (AOM_BLEND_A64_MAX_ALPHA - (a)) * (v1), \
|
||||
AOM_BLEND_A64_ROUND_BITS)
|
||||
|
||||
// Alpha blending with alpha values from the range [0, 256], where 256
|
||||
// means use the first input and 0 means use the second input.
|
||||
#define AOM_BLEND_A256_ROUND_BITS 8
|
||||
#define AOM_BLEND_A256_MAX_ALPHA (1 << AOM_BLEND_A256_ROUND_BITS) // 256
|
||||
|
||||
#define AOM_BLEND_A256(a, v0, v1) \
|
||||
ROUND_POWER_OF_TWO((a) * (v0) + (AOM_BLEND_A256_MAX_ALPHA - (a)) * (v1), \
|
||||
AOM_BLEND_A256_ROUND_BITS)
|
||||
|
||||
// Blending by averaging.
|
||||
#define AOM_BLEND_AVG(v0, v1) ROUND_POWER_OF_TWO((v0) + (v1), 1)
|
||||
|
||||
#endif // AOM_DSP_BLEND_H_
|
||||
@@ -1,71 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2016, Alliance for Open Media. All rights reserved
|
||||
*
|
||||
* This source code is subject to the terms of the BSD 2 Clause License and
|
||||
* the Alliance for Open Media Patent License 1.0. If the BSD 2 Clause License
|
||||
* was not distributed with this source code in the LICENSE file, you can
|
||||
* obtain it at www.aomedia.org/license/software. If the Alliance for Open
|
||||
* Media Patent License 1.0 was not distributed with this source code in the
|
||||
* PATENTS file, you can obtain it at www.aomedia.org/license/patent.
|
||||
*/
|
||||
|
||||
#include <assert.h>
|
||||
|
||||
#include "aom/aom_integer.h"
|
||||
#include "aom_ports/mem.h"
|
||||
#include "aom_dsp/aom_dsp_common.h"
|
||||
#include "aom_dsp/blend.h"
|
||||
|
||||
#include "./aom_dsp_rtcd.h"
|
||||
|
||||
void aom_blend_a64_hmask_c(uint8_t *dst, uint32_t dst_stride,
|
||||
const uint8_t *src0, uint32_t src0_stride,
|
||||
const uint8_t *src1, uint32_t src1_stride,
|
||||
const uint8_t *mask, int h, int w) {
|
||||
int i, j;
|
||||
|
||||
assert(IMPLIES(src0 == dst, src0_stride == dst_stride));
|
||||
assert(IMPLIES(src1 == dst, src1_stride == dst_stride));
|
||||
|
||||
assert(h >= 1);
|
||||
assert(w >= 1);
|
||||
assert(IS_POWER_OF_TWO(h));
|
||||
assert(IS_POWER_OF_TWO(w));
|
||||
|
||||
for (i = 0; i < h; ++i) {
|
||||
for (j = 0; j < w; ++j) {
|
||||
dst[i * dst_stride + j] = AOM_BLEND_A64(
|
||||
mask[j], src0[i * src0_stride + j], src1[i * src1_stride + j]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#if CONFIG_AOM_HIGHBITDEPTH
|
||||
void aom_highbd_blend_a64_hmask_c(uint8_t *dst_8, uint32_t dst_stride,
|
||||
const uint8_t *src0_8, uint32_t src0_stride,
|
||||
const uint8_t *src1_8, uint32_t src1_stride,
|
||||
const uint8_t *mask, int h, int w, int bd) {
|
||||
int i, j;
|
||||
uint16_t *dst = CONVERT_TO_SHORTPTR(dst_8);
|
||||
const uint16_t *src0 = CONVERT_TO_SHORTPTR(src0_8);
|
||||
const uint16_t *src1 = CONVERT_TO_SHORTPTR(src1_8);
|
||||
(void)bd;
|
||||
|
||||
assert(IMPLIES(src0 == dst, src0_stride == dst_stride));
|
||||
assert(IMPLIES(src1 == dst, src1_stride == dst_stride));
|
||||
|
||||
assert(h >= 1);
|
||||
assert(w >= 1);
|
||||
assert(IS_POWER_OF_TWO(h));
|
||||
assert(IS_POWER_OF_TWO(w));
|
||||
|
||||
assert(bd == 8 || bd == 10 || bd == 12);
|
||||
|
||||
for (i = 0; i < h; ++i) {
|
||||
for (j = 0; j < w; ++j) {
|
||||
dst[i * dst_stride + j] = AOM_BLEND_A64(
|
||||
mask[j], src0[i * src0_stride + j], src1[i * src1_stride + j]);
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif // CONFIG_AOM_HIGHBITDEPTH
|
||||
@@ -1,145 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2016, Alliance for Open Media. All rights reserved
|
||||
*
|
||||
* This source code is subject to the terms of the BSD 2 Clause License and
|
||||
* the Alliance for Open Media Patent License 1.0. If the BSD 2 Clause License
|
||||
* was not distributed with this source code in the LICENSE file, you can
|
||||
* obtain it at www.aomedia.org/license/software. If the Alliance for Open
|
||||
* Media Patent License 1.0 was not distributed with this source code in the
|
||||
* PATENTS file, you can obtain it at www.aomedia.org/license/patent.
|
||||
*/
|
||||
|
||||
#include <assert.h>
|
||||
|
||||
#include "aom/aom_integer.h"
|
||||
#include "aom_ports/mem.h"
|
||||
#include "aom_dsp/blend.h"
|
||||
#include "aom_dsp/aom_dsp_common.h"
|
||||
|
||||
#include "./aom_dsp_rtcd.h"
|
||||
|
||||
// Blending with alpha mask. Mask values come from the range [0, 64],
|
||||
// as described for AOM_BLEND_A64 in aom_dsp/blend.h. src0 or src1 can
|
||||
// be the same as dst, or dst can be different from both sources.
|
||||
|
||||
void aom_blend_a64_mask_c(uint8_t *dst, uint32_t dst_stride,
|
||||
const uint8_t *src0, uint32_t src0_stride,
|
||||
const uint8_t *src1, uint32_t src1_stride,
|
||||
const uint8_t *mask, uint32_t mask_stride, int h,
|
||||
int w, int subh, int subw) {
|
||||
int i, j;
|
||||
|
||||
assert(IMPLIES(src0 == dst, src0_stride == dst_stride));
|
||||
assert(IMPLIES(src1 == dst, src1_stride == dst_stride));
|
||||
|
||||
assert(h >= 1);
|
||||
assert(w >= 1);
|
||||
assert(IS_POWER_OF_TWO(h));
|
||||
assert(IS_POWER_OF_TWO(w));
|
||||
|
||||
if (subw == 0 && subh == 0) {
|
||||
for (i = 0; i < h; ++i) {
|
||||
for (j = 0; j < w; ++j) {
|
||||
const int m = mask[i * mask_stride + j];
|
||||
dst[i * dst_stride + j] = AOM_BLEND_A64(m, src0[i * src0_stride + j],
|
||||
src1[i * src1_stride + j]);
|
||||
}
|
||||
}
|
||||
} else if (subw == 1 && subh == 1) {
|
||||
for (i = 0; i < h; ++i) {
|
||||
for (j = 0; j < w; ++j) {
|
||||
const int m = ROUND_POWER_OF_TWO(
|
||||
mask[(2 * i) * mask_stride + (2 * j)] +
|
||||
mask[(2 * i + 1) * mask_stride + (2 * j)] +
|
||||
mask[(2 * i) * mask_stride + (2 * j + 1)] +
|
||||
mask[(2 * i + 1) * mask_stride + (2 * j + 1)],
|
||||
2);
|
||||
dst[i * dst_stride + j] = AOM_BLEND_A64(m, src0[i * src0_stride + j],
|
||||
src1[i * src1_stride + j]);
|
||||
}
|
||||
}
|
||||
} else if (subw == 1 && subh == 0) {
|
||||
for (i = 0; i < h; ++i) {
|
||||
for (j = 0; j < w; ++j) {
|
||||
const int m = AOM_BLEND_AVG(mask[i * mask_stride + (2 * j)],
|
||||
mask[i * mask_stride + (2 * j + 1)]);
|
||||
dst[i * dst_stride + j] = AOM_BLEND_A64(m, src0[i * src0_stride + j],
|
||||
src1[i * src1_stride + j]);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
for (i = 0; i < h; ++i) {
|
||||
for (j = 0; j < w; ++j) {
|
||||
const int m = AOM_BLEND_AVG(mask[(2 * i) * mask_stride + j],
|
||||
mask[(2 * i + 1) * mask_stride + j]);
|
||||
dst[i * dst_stride + j] = AOM_BLEND_A64(m, src0[i * src0_stride + j],
|
||||
src1[i * src1_stride + j]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#if CONFIG_AOM_HIGHBITDEPTH
|
||||
void aom_highbd_blend_a64_mask_c(uint8_t *dst_8, uint32_t dst_stride,
|
||||
const uint8_t *src0_8, uint32_t src0_stride,
|
||||
const uint8_t *src1_8, uint32_t src1_stride,
|
||||
const uint8_t *mask, uint32_t mask_stride,
|
||||
int h, int w, int subh, int subw, int bd) {
|
||||
int i, j;
|
||||
uint16_t *dst = CONVERT_TO_SHORTPTR(dst_8);
|
||||
const uint16_t *src0 = CONVERT_TO_SHORTPTR(src0_8);
|
||||
const uint16_t *src1 = CONVERT_TO_SHORTPTR(src1_8);
|
||||
(void)bd;
|
||||
|
||||
assert(IMPLIES(src0 == dst, src0_stride == dst_stride));
|
||||
assert(IMPLIES(src1 == dst, src1_stride == dst_stride));
|
||||
|
||||
assert(h >= 1);
|
||||
assert(w >= 1);
|
||||
assert(IS_POWER_OF_TWO(h));
|
||||
assert(IS_POWER_OF_TWO(w));
|
||||
|
||||
assert(bd == 8 || bd == 10 || bd == 12);
|
||||
|
||||
if (subw == 0 && subh == 0) {
|
||||
for (i = 0; i < h; ++i) {
|
||||
for (j = 0; j < w; ++j) {
|
||||
const int m = mask[i * mask_stride + j];
|
||||
dst[i * dst_stride + j] = AOM_BLEND_A64(m, src0[i * src0_stride + j],
|
||||
src1[i * src1_stride + j]);
|
||||
}
|
||||
}
|
||||
} else if (subw == 1 && subh == 1) {
|
||||
for (i = 0; i < h; ++i) {
|
||||
for (j = 0; j < w; ++j) {
|
||||
const int m = ROUND_POWER_OF_TWO(
|
||||
mask[(2 * i) * mask_stride + (2 * j)] +
|
||||
mask[(2 * i + 1) * mask_stride + (2 * j)] +
|
||||
mask[(2 * i) * mask_stride + (2 * j + 1)] +
|
||||
mask[(2 * i + 1) * mask_stride + (2 * j + 1)],
|
||||
2);
|
||||
dst[i * dst_stride + j] = AOM_BLEND_A64(m, src0[i * src0_stride + j],
|
||||
src1[i * src1_stride + j]);
|
||||
}
|
||||
}
|
||||
} else if (subw == 1 && subh == 0) {
|
||||
for (i = 0; i < h; ++i) {
|
||||
for (j = 0; j < w; ++j) {
|
||||
const int m = AOM_BLEND_AVG(mask[i * mask_stride + (2 * j)],
|
||||
mask[i * mask_stride + (2 * j + 1)]);
|
||||
dst[i * dst_stride + j] = AOM_BLEND_A64(m, src0[i * src0_stride + j],
|
||||
src1[i * src1_stride + j]);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
for (i = 0; i < h; ++i) {
|
||||
for (j = 0; j < w; ++j) {
|
||||
const int m = AOM_BLEND_AVG(mask[(2 * i) * mask_stride + j],
|
||||
mask[(2 * i + 1) * mask_stride + j]);
|
||||
dst[i * dst_stride + j] = AOM_BLEND_A64(m, src0[i * src0_stride + j],
|
||||
src1[i * src1_stride + j]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif // CONFIG_AOM_HIGHBITDEPTH
|
||||
@@ -1,73 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2016, Alliance for Open Media. All rights reserved
|
||||
*
|
||||
* This source code is subject to the terms of the BSD 2 Clause License and
|
||||
* the Alliance for Open Media Patent License 1.0. If the BSD 2 Clause License
|
||||
* was not distributed with this source code in the LICENSE file, you can
|
||||
* obtain it at www.aomedia.org/license/software. If the Alliance for Open
|
||||
* Media Patent License 1.0 was not distributed with this source code in the
|
||||
* PATENTS file, you can obtain it at www.aomedia.org/license/patent.
|
||||
*/
|
||||
|
||||
#include <assert.h>
|
||||
|
||||
#include "aom/aom_integer.h"
|
||||
#include "aom_ports/mem.h"
|
||||
#include "aom_dsp/aom_dsp_common.h"
|
||||
#include "aom_dsp/blend.h"
|
||||
|
||||
#include "./aom_dsp_rtcd.h"
|
||||
|
||||
void aom_blend_a64_vmask_c(uint8_t *dst, uint32_t dst_stride,
|
||||
const uint8_t *src0, uint32_t src0_stride,
|
||||
const uint8_t *src1, uint32_t src1_stride,
|
||||
const uint8_t *mask, int h, int w) {
|
||||
int i, j;
|
||||
|
||||
assert(IMPLIES(src0 == dst, src0_stride == dst_stride));
|
||||
assert(IMPLIES(src1 == dst, src1_stride == dst_stride));
|
||||
|
||||
assert(h >= 1);
|
||||
assert(w >= 1);
|
||||
assert(IS_POWER_OF_TWO(h));
|
||||
assert(IS_POWER_OF_TWO(w));
|
||||
|
||||
for (i = 0; i < h; ++i) {
|
||||
const int m = mask[i];
|
||||
for (j = 0; j < w; ++j) {
|
||||
dst[i * dst_stride + j] = AOM_BLEND_A64(m, src0[i * src0_stride + j],
|
||||
src1[i * src1_stride + j]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#if CONFIG_AOM_HIGHBITDEPTH
|
||||
void aom_highbd_blend_a64_vmask_c(uint8_t *dst_8, uint32_t dst_stride,
|
||||
const uint8_t *src0_8, uint32_t src0_stride,
|
||||
const uint8_t *src1_8, uint32_t src1_stride,
|
||||
const uint8_t *mask, int h, int w, int bd) {
|
||||
int i, j;
|
||||
uint16_t *dst = CONVERT_TO_SHORTPTR(dst_8);
|
||||
const uint16_t *src0 = CONVERT_TO_SHORTPTR(src0_8);
|
||||
const uint16_t *src1 = CONVERT_TO_SHORTPTR(src1_8);
|
||||
(void)bd;
|
||||
|
||||
assert(IMPLIES(src0 == dst, src0_stride == dst_stride));
|
||||
assert(IMPLIES(src1 == dst, src1_stride == dst_stride));
|
||||
|
||||
assert(h >= 1);
|
||||
assert(w >= 1);
|
||||
assert(IS_POWER_OF_TWO(h));
|
||||
assert(IS_POWER_OF_TWO(w));
|
||||
|
||||
assert(bd == 8 || bd == 10 || bd == 12);
|
||||
|
||||
for (i = 0; i < h; ++i) {
|
||||
const int m = mask[i];
|
||||
for (j = 0; j < w; ++j) {
|
||||
dst[i * dst_stride + j] = AOM_BLEND_A64(m, src0[i * src0_stride + j],
|
||||
src1[i * src1_stride + j]);
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif // CONFIG_AOM_HIGHBITDEPTH
|
||||
@@ -1,42 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2016, Alliance for Open Media. All rights reserved
|
||||
*
|
||||
* This source code is subject to the terms of the BSD 2 Clause License and
|
||||
* the Alliance for Open Media Patent License 1.0. If the BSD 2 Clause License
|
||||
* was not distributed with this source code in the LICENSE file, you can
|
||||
* obtain it at www.aomedia.org/license/software. If the Alliance for Open
|
||||
* Media Patent License 1.0 was not distributed with this source code in the
|
||||
* PATENTS file, you can obtain it at www.aomedia.org/license/patent.
|
||||
*/
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#include "aom_dsp/buf_ans.h"
|
||||
#include "aom_mem/aom_mem.h"
|
||||
#include "aom/internal/aom_codec_internal.h"
|
||||
|
||||
void aom_buf_ans_alloc(struct BufAnsCoder *c,
|
||||
struct aom_internal_error_info *error, int size_hint) {
|
||||
c->error = error;
|
||||
c->size = size_hint;
|
||||
AOM_CHECK_MEM_ERROR(error, c->buf, aom_malloc(c->size * sizeof(*c->buf)));
|
||||
// Initialize to overfull to trigger the assert in write.
|
||||
c->offset = c->size + 1;
|
||||
}
|
||||
|
||||
void aom_buf_ans_free(struct BufAnsCoder *c) {
|
||||
aom_free(c->buf);
|
||||
c->buf = NULL;
|
||||
c->size = 0;
|
||||
}
|
||||
|
||||
void aom_buf_ans_grow(struct BufAnsCoder *c) {
|
||||
struct buffered_ans_symbol *new_buf = NULL;
|
||||
int new_size = c->size * 2;
|
||||
AOM_CHECK_MEM_ERROR(c->error, new_buf,
|
||||
aom_malloc(new_size * sizeof(*new_buf)));
|
||||
memcpy(new_buf, c->buf, c->size * sizeof(*c->buf));
|
||||
aom_free(c->buf);
|
||||
c->buf = new_buf;
|
||||
c->size = new_size;
|
||||
}
|
||||
@@ -1,112 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2016, Alliance for Open Media. All rights reserved
|
||||
*
|
||||
* This source code is subject to the terms of the BSD 2 Clause License and
|
||||
* the Alliance for Open Media Patent License 1.0. If the BSD 2 Clause License
|
||||
* was not distributed with this source code in the LICENSE file, you can
|
||||
* obtain it at www.aomedia.org/license/software. If the Alliance for Open
|
||||
* Media Patent License 1.0 was not distributed with this source code in the
|
||||
* PATENTS file, you can obtain it at www.aomedia.org/license/patent.
|
||||
*/
|
||||
|
||||
#ifndef AOM_DSP_BUF_ANS_H_
|
||||
#define AOM_DSP_BUF_ANS_H_
|
||||
// Buffered forward ANS writer.
|
||||
// Symbols are written to the writer in forward (decode) order and serialized
|
||||
// backwards due to ANS's stack like behavior.
|
||||
|
||||
#include <assert.h>
|
||||
#include "./aom_config.h"
|
||||
#include "aom/aom_integer.h"
|
||||
#include "aom_dsp/ans.h"
|
||||
#include "aom_dsp/answriter.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif // __cplusplus
|
||||
|
||||
#define ANS_METHOD_UABS 0
|
||||
#define ANS_METHOD_RANS 1
|
||||
|
||||
struct buffered_ans_symbol {
|
||||
unsigned int method : 1; // one of ANS_METHOD_UABS or ANS_METHOD_RANS
|
||||
// TODO(aconverse): Should be possible to write this in terms of start for ABS
|
||||
unsigned int val_start : RANS_PROB_BITS; // Boolean value for ABS
|
||||
// start in symbol cycle for Rans
|
||||
unsigned int prob : RANS_PROB_BITS; // Probability of this symbol
|
||||
};
|
||||
|
||||
struct BufAnsCoder {
|
||||
struct aom_internal_error_info *error;
|
||||
struct buffered_ans_symbol *buf;
|
||||
int size;
|
||||
int offset;
|
||||
};
|
||||
|
||||
void aom_buf_ans_alloc(struct BufAnsCoder *c,
|
||||
struct aom_internal_error_info *error, int size_hint);
|
||||
|
||||
void aom_buf_ans_free(struct BufAnsCoder *c);
|
||||
|
||||
void aom_buf_ans_grow(struct BufAnsCoder *c);
|
||||
|
||||
static INLINE void buf_ans_write_reset(struct BufAnsCoder *const c) {
|
||||
c->offset = 0;
|
||||
}
|
||||
|
||||
static INLINE void buf_uabs_write(struct BufAnsCoder *const c, uint8_t val,
|
||||
AnsP8 prob) {
|
||||
assert(c->offset <= c->size);
|
||||
if (c->offset == c->size) {
|
||||
aom_buf_ans_grow(c);
|
||||
}
|
||||
c->buf[c->offset].method = ANS_METHOD_UABS;
|
||||
c->buf[c->offset].val_start = val;
|
||||
c->buf[c->offset].prob = prob;
|
||||
++c->offset;
|
||||
}
|
||||
|
||||
static INLINE void buf_rans_write(struct BufAnsCoder *const c,
|
||||
const struct rans_sym *const sym) {
|
||||
assert(c->offset <= c->size);
|
||||
if (c->offset == c->size) {
|
||||
aom_buf_ans_grow(c);
|
||||
}
|
||||
c->buf[c->offset].method = ANS_METHOD_RANS;
|
||||
c->buf[c->offset].val_start = sym->cum_prob;
|
||||
c->buf[c->offset].prob = sym->prob;
|
||||
++c->offset;
|
||||
}
|
||||
|
||||
static INLINE void buf_ans_flush(const struct BufAnsCoder *const c,
|
||||
struct AnsCoder *ans) {
|
||||
int offset;
|
||||
for (offset = c->offset - 1; offset >= 0; --offset) {
|
||||
if (c->buf[offset].method == ANS_METHOD_RANS) {
|
||||
struct rans_sym sym;
|
||||
sym.prob = c->buf[offset].prob;
|
||||
sym.cum_prob = c->buf[offset].val_start;
|
||||
rans_write(ans, &sym);
|
||||
} else {
|
||||
uabs_write(ans, (uint8_t)c->buf[offset].val_start,
|
||||
(AnsP8)c->buf[offset].prob);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static INLINE void buf_uabs_write_bit(struct BufAnsCoder *c, int bit) {
|
||||
buf_uabs_write(c, bit, 128);
|
||||
}
|
||||
|
||||
static INLINE void buf_uabs_write_literal(struct BufAnsCoder *c, int literal,
|
||||
int bits) {
|
||||
int bit;
|
||||
|
||||
assert(bits < 31);
|
||||
for (bit = bits - 1; bit >= 0; bit--)
|
||||
buf_uabs_write_bit(c, 1 & (literal >> bit));
|
||||
}
|
||||
#ifdef __cplusplus
|
||||
} // extern "C"
|
||||
#endif // __cplusplus
|
||||
#endif // AOM_DSP_BUF_ANS_H_
|
||||
@@ -1,37 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2016, Alliance for Open Media. All rights reserved
|
||||
*
|
||||
* This source code is subject to the terms of the BSD 2 Clause License and
|
||||
* the Alliance for Open Media Patent License 1.0. If the BSD 2 Clause License
|
||||
* was not distributed with this source code in the LICENSE file, you can
|
||||
* obtain it at www.aomedia.org/license/software. If the Alliance for Open
|
||||
* Media Patent License 1.0 was not distributed with this source code in the
|
||||
* PATENTS file, you can obtain it at www.aomedia.org/license/patent.
|
||||
*/
|
||||
|
||||
#include "aom_dsp/daalaboolreader.h"
|
||||
|
||||
int aom_daala_reader_init(daala_reader *r, const uint8_t *buffer, int size) {
|
||||
if (size && !buffer) {
|
||||
return 1;
|
||||
}
|
||||
r->buffer_end = buffer + size;
|
||||
r->buffer = buffer;
|
||||
od_ec_dec_init(&r->ec, buffer, size - 1);
|
||||
#if CONFIG_ACCOUNTING
|
||||
r->accounting = NULL;
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
||||
const uint8_t *aom_daala_reader_find_end(daala_reader *r) {
|
||||
return r->buffer_end;
|
||||
}
|
||||
|
||||
uint32_t aom_daala_reader_tell(const daala_reader *r) {
|
||||
return od_ec_dec_tell(&r->ec);
|
||||
}
|
||||
|
||||
uint32_t aom_daala_reader_tell_frac(const daala_reader *r) {
|
||||
return od_ec_dec_tell_frac(&r->ec);
|
||||
}
|
||||
@@ -1,87 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2016, Alliance for Open Media. All rights reserved
|
||||
*
|
||||
* This source code is subject to the terms of the BSD 2 Clause License and
|
||||
* the Alliance for Open Media Patent License 1.0. If the BSD 2 Clause License
|
||||
* was not distributed with this source code in the LICENSE file, you can
|
||||
* obtain it at www.aomedia.org/license/software. If the Alliance for Open
|
||||
* Media Patent License 1.0 was not distributed with this source code in the
|
||||
* PATENTS file, you can obtain it at www.aomedia.org/license/patent.
|
||||
*/
|
||||
|
||||
#ifndef AOM_DSP_DAALABOOLREADER_H_
|
||||
#define AOM_DSP_DAALABOOLREADER_H_
|
||||
|
||||
#include "aom/aom_integer.h"
|
||||
#include "aom_dsp/entdec.h"
|
||||
#include "aom_dsp/prob.h"
|
||||
#if CONFIG_ACCOUNTING
|
||||
#include "av1/common/accounting.h"
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
struct daala_reader {
|
||||
const uint8_t *buffer;
|
||||
const uint8_t *buffer_end;
|
||||
od_ec_dec ec;
|
||||
#if CONFIG_ACCOUNTING
|
||||
Accounting *accounting;
|
||||
#endif
|
||||
};
|
||||
|
||||
typedef struct daala_reader daala_reader;
|
||||
|
||||
int aom_daala_reader_init(daala_reader *r, const uint8_t *buffer, int size);
|
||||
const uint8_t *aom_daala_reader_find_end(daala_reader *r);
|
||||
uint32_t aom_daala_reader_tell(const daala_reader *r);
|
||||
uint32_t aom_daala_reader_tell_frac(const daala_reader *r);
|
||||
|
||||
static INLINE int aom_daala_read(daala_reader *r, int prob) {
|
||||
if (prob == 128) {
|
||||
return od_ec_dec_bits(&r->ec, 1, "aom_bits");
|
||||
} else {
|
||||
int p = ((prob << 15) + (256 - prob)) >> 8;
|
||||
return od_ec_decode_bool_q15(&r->ec, p);
|
||||
}
|
||||
}
|
||||
|
||||
static INLINE int aom_daala_read_bit(daala_reader *r) {
|
||||
return aom_daala_read(r, 128);
|
||||
}
|
||||
|
||||
static INLINE int aom_daala_reader_has_error(daala_reader *r) {
|
||||
return r->ec.error;
|
||||
}
|
||||
|
||||
static INLINE int daala_read_tree_bits(daala_reader *r,
|
||||
const aom_tree_index *tree,
|
||||
const aom_prob *probs) {
|
||||
aom_tree_index i = 0;
|
||||
do {
|
||||
aom_cdf_prob cdf[16];
|
||||
aom_tree_index index[16];
|
||||
int path[16];
|
||||
int dist[16];
|
||||
int nsymbs;
|
||||
int symb;
|
||||
nsymbs = tree_to_cdf(tree, probs, i, cdf, index, path, dist);
|
||||
symb = od_ec_decode_cdf_q15(&r->ec, cdf, nsymbs);
|
||||
OD_ASSERT(symb >= 0 && symb < nsymbs);
|
||||
i = index[symb];
|
||||
} while (i > 0);
|
||||
return -i;
|
||||
}
|
||||
|
||||
static INLINE int daala_read_symbol(daala_reader *r, const aom_cdf_prob *cdf,
|
||||
int nsymbs) {
|
||||
return od_ec_decode_cdf_q15(&r->ec, cdf, nsymbs);
|
||||
}
|
||||
|
||||
#ifdef __cplusplus
|
||||
} // extern "C"
|
||||
#endif
|
||||
|
||||
#endif
|
||||
@@ -1,32 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2016, Alliance for Open Media. All rights reserved
|
||||
*
|
||||
* This source code is subject to the terms of the BSD 2 Clause License and
|
||||
* the Alliance for Open Media Patent License 1.0. If the BSD 2 Clause License
|
||||
* was not distributed with this source code in the LICENSE file, you can
|
||||
* obtain it at www.aomedia.org/license/software. If the Alliance for Open
|
||||
* Media Patent License 1.0 was not distributed with this source code in the
|
||||
* PATENTS file, you can obtain it at www.aomedia.org/license/patent.
|
||||
*/
|
||||
|
||||
#include <string.h>
|
||||
#include "aom_dsp/daalaboolwriter.h"
|
||||
|
||||
void aom_daala_start_encode(daala_writer *br, uint8_t *source) {
|
||||
br->buffer = source;
|
||||
br->pos = 0;
|
||||
od_ec_enc_init(&br->ec, 62025);
|
||||
}
|
||||
|
||||
void aom_daala_stop_encode(daala_writer *br) {
|
||||
uint32_t daala_bytes;
|
||||
unsigned char *daala_data;
|
||||
daala_data = od_ec_enc_done(&br->ec, &daala_bytes);
|
||||
memcpy(br->buffer, daala_data, daala_bytes);
|
||||
br->pos = daala_bytes;
|
||||
/* Prevent ec bitstream from being detected as a superframe marker.
|
||||
Must always be added, so that rawbits knows the exact length of the
|
||||
bitstream. */
|
||||
br->buffer[br->pos++] = 0;
|
||||
od_ec_enc_clear(&br->ec);
|
||||
}
|
||||
@@ -1,90 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2016, Alliance for Open Media. All rights reserved
|
||||
*
|
||||
* This source code is subject to the terms of the BSD 2 Clause License and
|
||||
* the Alliance for Open Media Patent License 1.0. If the BSD 2 Clause License
|
||||
* was not distributed with this source code in the LICENSE file, you can
|
||||
* obtain it at www.aomedia.org/license/software. If the Alliance for Open
|
||||
* Media Patent License 1.0 was not distributed with this source code in the
|
||||
* PATENTS file, you can obtain it at www.aomedia.org/license/patent.
|
||||
*/
|
||||
|
||||
#ifndef AOM_DSP_DAALABOOLWRITER_H_
|
||||
#define AOM_DSP_DAALABOOLWRITER_H_
|
||||
|
||||
#include "aom_dsp/entenc.h"
|
||||
#include "aom_dsp/prob.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
struct daala_writer {
|
||||
unsigned int pos;
|
||||
uint8_t *buffer;
|
||||
od_ec_enc ec;
|
||||
};
|
||||
|
||||
typedef struct daala_writer daala_writer;
|
||||
|
||||
void aom_daala_start_encode(daala_writer *w, uint8_t *buffer);
|
||||
void aom_daala_stop_encode(daala_writer *w);
|
||||
|
||||
static INLINE void aom_daala_write(daala_writer *w, int bit, int prob) {
|
||||
if (prob == 128) {
|
||||
od_ec_enc_bits(&w->ec, bit, 1);
|
||||
} else {
|
||||
int p = ((prob << 15) + (256 - prob)) >> 8;
|
||||
od_ec_encode_bool_q15(&w->ec, bit, p);
|
||||
}
|
||||
}
|
||||
|
||||
static INLINE void daala_write_tree_bits(daala_writer *w,
|
||||
const aom_tree_index *tree,
|
||||
const aom_prob *probs, int bits,
|
||||
int len, aom_tree_index i) {
|
||||
aom_tree_index root;
|
||||
root = i;
|
||||
do {
|
||||
aom_cdf_prob cdf[16];
|
||||
aom_tree_index index[16];
|
||||
int path[16];
|
||||
int dist[16];
|
||||
int nsymbs;
|
||||
int symb;
|
||||
int j;
|
||||
/* Compute the CDF of the binary tree using the given probabilities. */
|
||||
nsymbs = tree_to_cdf(tree, probs, root, cdf, index, path, dist);
|
||||
/* Find the symbol to code. */
|
||||
symb = -1;
|
||||
for (j = 0; j < nsymbs; j++) {
|
||||
/* If this symbol codes a leaf node, */
|
||||
if (index[j] <= 0) {
|
||||
if (len == dist[j] && path[j] == bits) {
|
||||
symb = j;
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
if (len > dist[j] && path[j] == bits >> (len - dist[j])) {
|
||||
symb = j;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
OD_ASSERT(symb != -1);
|
||||
od_ec_encode_cdf_q15(&w->ec, symb, cdf, nsymbs);
|
||||
bits &= (1 << (len - dist[symb])) - 1;
|
||||
len -= dist[symb];
|
||||
} while (len);
|
||||
}
|
||||
|
||||
static INLINE void daala_write_symbol(daala_writer *w, int symb,
|
||||
const aom_cdf_prob *cdf, int nsymbs) {
|
||||
od_ec_encode_cdf_q15(&w->ec, symb, cdf, nsymbs);
|
||||
}
|
||||
|
||||
#ifdef __cplusplus
|
||||
} // extern "C"
|
||||
#endif
|
||||
|
||||
#endif
|
||||
@@ -1,180 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2016, Alliance for Open Media. All rights reserved
|
||||
*
|
||||
* This source code is subject to the terms of the BSD 2 Clause License and
|
||||
* the Alliance for Open Media Patent License 1.0. If the BSD 2 Clause License
|
||||
* was not distributed with this source code in the LICENSE file, you can
|
||||
* obtain it at www.aomedia.org/license/software. If the Alliance for Open
|
||||
* Media Patent License 1.0 was not distributed with this source code in the
|
||||
* PATENTS file, you can obtain it at www.aomedia.org/license/patent.
|
||||
*/
|
||||
|
||||
#ifndef AOM_DSP_DKBOOLREADER_H_
|
||||
#define AOM_DSP_DKBOOLREADER_H_
|
||||
|
||||
#include <assert.h>
|
||||
#include <stddef.h>
|
||||
#include <limits.h>
|
||||
|
||||
#include "./aom_config.h"
|
||||
#if CONFIG_BITSTREAM_DEBUG
|
||||
#include <assert.h>
|
||||
#include <stdio.h>
|
||||
#include "aom_util/debug_util.h"
|
||||
#endif // CONFIG_BITSTREAM_DEBUG
|
||||
|
||||
#include "aom_ports/mem.h"
|
||||
#include "aom/aomdx.h"
|
||||
#include "aom/aom_integer.h"
|
||||
#include "aom_dsp/prob.h"
|
||||
#if CONFIG_ACCOUNTING
|
||||
#include "av1/common/accounting.h"
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
typedef size_t BD_VALUE;
|
||||
|
||||
#define BD_VALUE_SIZE ((int)sizeof(BD_VALUE) * CHAR_BIT)
|
||||
|
||||
// This is meant to be a large, positive constant that can still be efficiently
|
||||
// loaded as an immediate (on platforms like ARM, for example).
|
||||
// Even relatively modest values like 100 would work fine.
|
||||
#define LOTS_OF_BITS 0x40000000
|
||||
|
||||
struct aom_dk_reader {
|
||||
// Be careful when reordering this struct, it may impact the cache negatively.
|
||||
BD_VALUE value;
|
||||
unsigned int range;
|
||||
int count;
|
||||
const uint8_t *buffer_start;
|
||||
const uint8_t *buffer_end;
|
||||
const uint8_t *buffer;
|
||||
aom_decrypt_cb decrypt_cb;
|
||||
void *decrypt_state;
|
||||
uint8_t clear_buffer[sizeof(BD_VALUE) + 1];
|
||||
#if CONFIG_ACCOUNTING
|
||||
Accounting *accounting;
|
||||
#endif
|
||||
};
|
||||
|
||||
int aom_dk_reader_init(struct aom_dk_reader *r, const uint8_t *buffer,
|
||||
size_t size, aom_decrypt_cb decrypt_cb,
|
||||
void *decrypt_state);
|
||||
|
||||
void aom_dk_reader_fill(struct aom_dk_reader *r);
|
||||
|
||||
const uint8_t *aom_dk_reader_find_end(struct aom_dk_reader *r);
|
||||
|
||||
static INLINE uint32_t aom_dk_reader_tell(const struct aom_dk_reader *r) {
|
||||
const uint32_t bits_read = (r->buffer - r->buffer_start) * CHAR_BIT;
|
||||
const int count =
|
||||
(r->count < LOTS_OF_BITS) ? r->count : r->count - LOTS_OF_BITS;
|
||||
assert(r->buffer >= r->buffer_start);
|
||||
return bits_read - (count + CHAR_BIT);
|
||||
}
|
||||
|
||||
/*The resolution of fractional-precision bit usage measurements, i.e.,
|
||||
3 => 1/8th bits.*/
|
||||
#define DK_BITRES (3)
|
||||
|
||||
static INLINE uint32_t aom_dk_reader_tell_frac(const struct aom_dk_reader *r) {
|
||||
uint32_t num_bits;
|
||||
uint32_t range;
|
||||
int l;
|
||||
int i;
|
||||
num_bits = aom_dk_reader_tell(r) << DK_BITRES;
|
||||
range = r->range;
|
||||
l = 0;
|
||||
for (i = DK_BITRES; i-- > 0;) {
|
||||
int b;
|
||||
range = range * range >> 7;
|
||||
b = (int)(range >> 8);
|
||||
l = l << 1 | b;
|
||||
range >>= b;
|
||||
}
|
||||
return num_bits - l;
|
||||
}
|
||||
|
||||
static INLINE int aom_dk_reader_has_error(struct aom_dk_reader *r) {
|
||||
// Check if we have reached the end of the buffer.
|
||||
//
|
||||
// Variable 'count' stores the number of bits in the 'value' buffer, minus
|
||||
// 8. The top byte is part of the algorithm, and the remainder is buffered
|
||||
// to be shifted into it. So if count == 8, the top 16 bits of 'value' are
|
||||
// occupied, 8 for the algorithm and 8 in the buffer.
|
||||
//
|
||||
// When reading a byte from the user's buffer, count is filled with 8 and
|
||||
// one byte is filled into the value buffer. When we reach the end of the
|
||||
// data, count is additionally filled with LOTS_OF_BITS. So when
|
||||
// count == LOTS_OF_BITS - 1, the user's data has been exhausted.
|
||||
//
|
||||
// 1 if we have tried to decode bits after the end of stream was encountered.
|
||||
// 0 No error.
|
||||
return r->count > BD_VALUE_SIZE && r->count < LOTS_OF_BITS;
|
||||
}
|
||||
|
||||
static INLINE int aom_dk_read(struct aom_dk_reader *r, int prob) {
|
||||
unsigned int bit = 0;
|
||||
BD_VALUE value;
|
||||
BD_VALUE bigsplit;
|
||||
int count;
|
||||
unsigned int range;
|
||||
unsigned int split = (r->range * prob + (256 - prob)) >> CHAR_BIT;
|
||||
|
||||
if (r->count < 0) aom_dk_reader_fill(r);
|
||||
|
||||
value = r->value;
|
||||
count = r->count;
|
||||
|
||||
bigsplit = (BD_VALUE)split << (BD_VALUE_SIZE - CHAR_BIT);
|
||||
|
||||
range = split;
|
||||
|
||||
if (value >= bigsplit) {
|
||||
range = r->range - split;
|
||||
value = value - bigsplit;
|
||||
bit = 1;
|
||||
}
|
||||
|
||||
{
|
||||
register int shift = aom_norm[range];
|
||||
range <<= shift;
|
||||
value <<= shift;
|
||||
count -= shift;
|
||||
}
|
||||
r->value = value;
|
||||
r->count = count;
|
||||
r->range = range;
|
||||
|
||||
#if CONFIG_BITSTREAM_DEBUG
|
||||
{
|
||||
int ref_bit, ref_prob;
|
||||
const int queue_r = bitstream_queue_get_read();
|
||||
const int frame_idx = bitstream_queue_get_frame_read();
|
||||
bitstream_queue_pop(&ref_bit, &ref_prob);
|
||||
if (prob != ref_prob) {
|
||||
fprintf(
|
||||
stderr,
|
||||
"\n *** prob error, frame_idx_r %d prob %d ref_prob %d queue_r %d\n",
|
||||
frame_idx, prob, ref_prob, queue_r);
|
||||
assert(0);
|
||||
}
|
||||
if ((int)bit != ref_bit) {
|
||||
fprintf(stderr, "\n *** bit error, frame_idx_r %d bit %d ref_bit %d\n",
|
||||
frame_idx, bit, ref_bit);
|
||||
assert(0);
|
||||
}
|
||||
}
|
||||
#endif // CONFIG_BITSTREAM_DEBUG
|
||||
|
||||
return bit;
|
||||
}
|
||||
|
||||
#ifdef __cplusplus
|
||||
} // extern "C"
|
||||
#endif
|
||||
|
||||
#endif // AOM_DSP_DKBOOLREADER_H_
|
||||
@@ -1,44 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2016, Alliance for Open Media. All rights reserved
|
||||
*
|
||||
* This source code is subject to the terms of the BSD 2 Clause License and
|
||||
* the Alliance for Open Media Patent License 1.0. If the BSD 2 Clause License
|
||||
* was not distributed with this source code in the LICENSE file, you can
|
||||
* obtain it at www.aomedia.org/license/software. If the Alliance for Open
|
||||
* Media Patent License 1.0 was not distributed with this source code in the
|
||||
* PATENTS file, you can obtain it at www.aomedia.org/license/patent.
|
||||
*/
|
||||
|
||||
#include <assert.h>
|
||||
|
||||
#include "./dkboolwriter.h"
|
||||
|
||||
static INLINE void aom_dk_write_bit(aom_dk_writer *w, int bit) {
|
||||
aom_dk_write(w, bit, 128); // aom_prob_half
|
||||
}
|
||||
|
||||
void aom_dk_start_encode(aom_dk_writer *br, uint8_t *source) {
|
||||
br->lowvalue = 0;
|
||||
br->range = 255;
|
||||
br->count = -24;
|
||||
br->buffer = source;
|
||||
br->pos = 0;
|
||||
aom_dk_write_bit(br, 0);
|
||||
}
|
||||
|
||||
void aom_dk_stop_encode(aom_dk_writer *br) {
|
||||
int i;
|
||||
|
||||
#if CONFIG_BITSTREAM_DEBUG
|
||||
bitstream_queue_set_skip_write(1);
|
||||
#endif // CONFIG_BITSTREAM_DEBUG
|
||||
|
||||
for (i = 0; i < 32; i++) aom_dk_write_bit(br, 0);
|
||||
|
||||
#if CONFIG_BITSTREAM_DEBUG
|
||||
bitstream_queue_set_skip_write(0);
|
||||
#endif // CONFIG_BITSTREAM_DEBUG
|
||||
|
||||
// Ensure there's no ambigous collision with any index marker bytes
|
||||
if ((br->buffer[br->pos - 1] & 0xe0) == 0xc0) br->buffer[br->pos++] = 0;
|
||||
}
|
||||
@@ -1,104 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2016, Alliance for Open Media. All rights reserved
|
||||
*
|
||||
* This source code is subject to the terms of the BSD 2 Clause License and
|
||||
* the Alliance for Open Media Patent License 1.0. If the BSD 2 Clause License
|
||||
* was not distributed with this source code in the LICENSE file, you can
|
||||
* obtain it at www.aomedia.org/license/software. If the Alliance for Open
|
||||
* Media Patent License 1.0 was not distributed with this source code in the
|
||||
* PATENTS file, you can obtain it at www.aomedia.org/license/patent.
|
||||
*/
|
||||
|
||||
#ifndef AOM_DSP_DKBOOLWRITER_H_
|
||||
#define AOM_DSP_DKBOOLWRITER_H_
|
||||
|
||||
#include "./aom_config.h"
|
||||
|
||||
#if CONFIG_BITSTREAM_DEBUG
|
||||
#include <stdio.h>
|
||||
#include "aom_util/debug_util.h"
|
||||
#endif // CONFIG_BITSTREAM_DEBUG
|
||||
|
||||
#include "aom_dsp/prob.h"
|
||||
#include "aom_ports/mem.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
typedef struct aom_dk_writer {
|
||||
unsigned int lowvalue;
|
||||
unsigned int range;
|
||||
int count;
|
||||
unsigned int pos;
|
||||
uint8_t *buffer;
|
||||
} aom_dk_writer;
|
||||
|
||||
void aom_dk_start_encode(aom_dk_writer *bc, uint8_t *buffer);
|
||||
void aom_dk_stop_encode(aom_dk_writer *bc);
|
||||
|
||||
static INLINE void aom_dk_write(aom_dk_writer *br, int bit, int probability) {
|
||||
unsigned int split;
|
||||
int count = br->count;
|
||||
unsigned int range = br->range;
|
||||
unsigned int lowvalue = br->lowvalue;
|
||||
register int shift;
|
||||
|
||||
#if CONFIG_BITSTREAM_DEBUG
|
||||
// int queue_r = 0;
|
||||
// int frame_idx_r = 0;
|
||||
// int queue_w = bitstream_queue_get_write();
|
||||
// int frame_idx_w = bitstream_queue_get_frame_write();
|
||||
// if (frame_idx_w == frame_idx_r && queue_w == queue_r) {
|
||||
// fprintf(stderr, "\n *** bitstream queue at frame_idx_w %d queue_w %d\n",
|
||||
// frame_idx_w, queue_w);
|
||||
// }
|
||||
bitstream_queue_push(bit, probability);
|
||||
#endif // CONFIG_BITSTREAM_DEBUG
|
||||
|
||||
split = 1 + (((range - 1) * probability) >> 8);
|
||||
|
||||
range = split;
|
||||
|
||||
if (bit) {
|
||||
lowvalue += split;
|
||||
range = br->range - split;
|
||||
}
|
||||
|
||||
shift = aom_norm[range];
|
||||
|
||||
range <<= shift;
|
||||
count += shift;
|
||||
|
||||
if (count >= 0) {
|
||||
int offset = shift - count;
|
||||
|
||||
if ((lowvalue << (offset - 1)) & 0x80000000) {
|
||||
int x = br->pos - 1;
|
||||
|
||||
while (x >= 0 && br->buffer[x] == 0xff) {
|
||||
br->buffer[x] = 0;
|
||||
x--;
|
||||
}
|
||||
|
||||
br->buffer[x] += 1;
|
||||
}
|
||||
|
||||
br->buffer[br->pos++] = (lowvalue >> (24 - offset));
|
||||
lowvalue <<= offset;
|
||||
shift = count;
|
||||
lowvalue &= 0xffffff;
|
||||
count -= 8;
|
||||
}
|
||||
|
||||
lowvalue <<= shift;
|
||||
br->count = count;
|
||||
br->lowvalue = lowvalue;
|
||||
br->range = range;
|
||||
}
|
||||
|
||||
#ifdef __cplusplus
|
||||
} // extern "C"
|
||||
#endif
|
||||
|
||||
#endif // AOM_DSP_DKBOOLWRITER_H_
|
||||
@@ -1,80 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2001-2016, Alliance for Open Media. All rights reserved
|
||||
*
|
||||
* This source code is subject to the terms of the BSD 2 Clause License and
|
||||
* the Alliance for Open Media Patent License 1.0. If the BSD 2 Clause License
|
||||
* was not distributed with this source code in the LICENSE file, you can
|
||||
* obtain it at www.aomedia.org/license/software. If the Alliance for Open
|
||||
* Media Patent License 1.0 was not distributed with this source code in the
|
||||
* PATENTS file, you can obtain it at www.aomedia.org/license/patent.
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "./config.h"
|
||||
#endif
|
||||
|
||||
#include "aom_dsp/entcode.h"
|
||||
|
||||
/*CDFs for uniform probability distributions of small sizes (2 through 16,
|
||||
inclusive).*/
|
||||
// clang-format off
|
||||
const uint16_t OD_UNIFORM_CDFS_Q15[135] = {
|
||||
16384, 32768,
|
||||
10923, 21845, 32768,
|
||||
8192, 16384, 24576, 32768,
|
||||
6554, 13107, 19661, 26214, 32768,
|
||||
5461, 10923, 16384, 21845, 27307, 32768,
|
||||
4681, 9362, 14043, 18725, 23406, 28087, 32768,
|
||||
4096, 8192, 12288, 16384, 20480, 24576, 28672, 32768,
|
||||
3641, 7282, 10923, 14564, 18204, 21845, 25486, 29127, 32768,
|
||||
3277, 6554, 9830, 13107, 16384, 19661, 22938, 26214, 29491, 32768,
|
||||
2979, 5958, 8937, 11916, 14895, 17873, 20852, 23831, 26810, 29789, 32768,
|
||||
2731, 5461, 8192, 10923, 13653, 16384, 19115, 21845, 24576, 27307, 30037,
|
||||
32768,
|
||||
2521, 5041, 7562, 10082, 12603, 15124, 17644, 20165, 22686, 25206, 27727,
|
||||
30247, 32768,
|
||||
2341, 4681, 7022, 9362, 11703, 14043, 16384, 18725, 21065, 23406, 25746,
|
||||
28087, 30427, 32768,
|
||||
2185, 4369, 6554, 8738, 10923, 13107, 15292, 17476, 19661, 21845, 24030,
|
||||
26214, 28399, 30583, 32768,
|
||||
2048, 4096, 6144, 8192, 10240, 12288, 14336, 16384, 18432, 20480, 22528,
|
||||
24576, 26624, 28672, 30720, 32768
|
||||
};
|
||||
// clang-format on
|
||||
|
||||
/*Given the current total integer number of bits used and the current value of
|
||||
rng, computes the fraction number of bits used to OD_BITRES precision.
|
||||
This is used by od_ec_enc_tell_frac() and od_ec_dec_tell_frac().
|
||||
nbits_total: The number of whole bits currently used, i.e., the value
|
||||
returned by od_ec_enc_tell() or od_ec_dec_tell().
|
||||
rng: The current value of rng from either the encoder or decoder state.
|
||||
Return: The number of bits scaled by 2**OD_BITRES.
|
||||
This will always be slightly larger than the exact value (e.g., all
|
||||
rounding error is in the positive direction).*/
|
||||
uint32_t od_ec_tell_frac(uint32_t nbits_total, uint32_t rng) {
|
||||
uint32_t nbits;
|
||||
int l;
|
||||
int i;
|
||||
/*To handle the non-integral number of bits still left in the encoder/decoder
|
||||
state, we compute the worst-case number of bits of val that must be
|
||||
encoded to ensure that the value is inside the range for any possible
|
||||
subsequent bits.
|
||||
The computation here is independent of val itself (the decoder does not
|
||||
even track that value), even though the real number of bits used after
|
||||
od_ec_enc_done() may be 1 smaller if rng is a power of two and the
|
||||
corresponding trailing bits of val are all zeros.
|
||||
If we did try to track that special case, then coding a value with a
|
||||
probability of 1/(1 << n) might sometimes appear to use more than n bits.
|
||||
This may help explain the surprising result that a newly initialized
|
||||
encoder or decoder claims to have used 1 bit.*/
|
||||
nbits = nbits_total << OD_BITRES;
|
||||
l = 0;
|
||||
for (i = OD_BITRES; i-- > 0;) {
|
||||
int b;
|
||||
rng = rng * rng >> 15;
|
||||
b = (int)(rng >> 16);
|
||||
l = l << 1 | b;
|
||||
rng >>= b;
|
||||
}
|
||||
return nbits - l;
|
||||
}
|
||||
@@ -1,105 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2001-2016, Alliance for Open Media. All rights reserved
|
||||
*
|
||||
* This source code is subject to the terms of the BSD 2 Clause License and
|
||||
* the Alliance for Open Media Patent License 1.0. If the BSD 2 Clause License
|
||||
* was not distributed with this source code in the LICENSE file, you can
|
||||
* obtain it at www.aomedia.org/license/software. If the Alliance for Open
|
||||
* Media Patent License 1.0 was not distributed with this source code in the
|
||||
* PATENTS file, you can obtain it at www.aomedia.org/license/patent.
|
||||
*/
|
||||
|
||||
#if !defined(_entcode_H)
|
||||
#define _entcode_H (1)
|
||||
#include <limits.h>
|
||||
#include <stddef.h>
|
||||
#include "av1/common/odintrin.h"
|
||||
|
||||
/*Set this flag 1 to enable a "reduced overhead" version of the entropy coder.
|
||||
This uses a partition function that more accurately follows the input
|
||||
probability estimates at the expense of some additional CPU cost (though
|
||||
still an order of magnitude less than a full division).
|
||||
|
||||
In classic arithmetic coding, the partition function maps a value x in the
|
||||
range [0, ft] to a value in y in [0, r] with 0 < ft <= r via
|
||||
y = x*r/ft.
|
||||
Any deviation from this value increases coding inefficiency.
|
||||
|
||||
To avoid divisions, we require ft <= r < 2*ft (enforcing it by shifting up
|
||||
ft if necessary), and replace that function with
|
||||
y = x + OD_MINI(x, r - ft).
|
||||
This counts values of x smaller than r - ft double compared to values larger
|
||||
than r - ft, which over-estimates the probability of symbols at the start of
|
||||
the alphabet, and under-estimates the probability of symbols at the end of
|
||||
the alphabet.
|
||||
The overall coding inefficiency assuming accurate probability models and
|
||||
independent symbols is in the 1% range, which is similar to that of CABAC.
|
||||
|
||||
To reduce overhead even further, we split this into two cases:
|
||||
1) r - ft > ft - (r - ft).
|
||||
That is, we have more values of x that are double-counted than
|
||||
single-counted.
|
||||
In this case, we still double-count the first 2*r - 3*ft values of x, but
|
||||
after that we alternate between single-counting and double-counting for
|
||||
the rest.
|
||||
2) r - ft < ft - (r - ft).
|
||||
That is, we have more values of x that are single-counted than
|
||||
double-counted.
|
||||
In this case, we alternate between single-counting and double-counting for
|
||||
the first 2*(r - ft) values of x, and single-count the rest.
|
||||
For two equiprobable symbols in different places in the alphabet, this
|
||||
reduces the maximum ratio of over-estimation to under-estimation from 2:1
|
||||
for the previous partition function to either 4:3 or 3:2 (for each of the
|
||||
two cases above, respectively), assuming symbol probabilities significantly
|
||||
greater than 1/32768.
|
||||
That reduces the worst-case per-symbol overhead from 1 bit to 0.58 bits.
|
||||
|
||||
The resulting function is
|
||||
e = OD_MAXI(2*r - 3*ft, 0);
|
||||
y = x + OD_MINI(x, e) + OD_MINI(OD_MAXI(x - e, 0) >> 1, r - ft).
|
||||
Here, e is a value that is greater than 0 in case 1, and 0 in case 2.
|
||||
This function is about 3 times as expensive to evaluate as the high-overhead
|
||||
version, but still an order of magnitude cheaper than a division, since it
|
||||
is composed only of very simple operations.
|
||||
Because we want to fit in 16-bit registers and must use unsigned values to do
|
||||
so, we use saturating subtraction to enforce the maximums with 0.
|
||||
|
||||
Enabling this reduces the measured overhead in ectest from 0.805% to 0.621%
|
||||
(vs. 0.022% for the division-based partition function with r much greater
|
||||
than ft).
|
||||
It improves performance on ntt-short-1 by about 0.3%.*/
|
||||
#define OD_EC_REDUCED_OVERHEAD (1)
|
||||
|
||||
/*OPT: od_ec_window must be at least 32 bits, but if you have fast arithmetic
|
||||
on a larger type, you can speed up the decoder by using it here.*/
|
||||
typedef uint32_t od_ec_window;
|
||||
|
||||
#define OD_EC_WINDOW_SIZE ((int)sizeof(od_ec_window) * CHAR_BIT)
|
||||
|
||||
/*Unsigned subtraction with unsigned saturation.
|
||||
This implementation of the macro is intentionally chosen to increase the
|
||||
number of common subexpressions in the reduced-overhead partition function.
|
||||
This matters for C code, but it would not for hardware with a saturating
|
||||
subtraction instruction.*/
|
||||
#define OD_SUBSATU(a, b) ((a)-OD_MINI(a, b))
|
||||
|
||||
/*The number of bits to use for the range-coded part of unsigned integers.*/
|
||||
#define OD_EC_UINT_BITS (4)
|
||||
|
||||
/*The resolution of fractional-precision bit usage measurements, i.e.,
|
||||
3 => 1/8th bits.*/
|
||||
#define OD_BITRES (3)
|
||||
|
||||
extern const uint16_t OD_UNIFORM_CDFS_Q15[135];
|
||||
|
||||
/*Returns a Q15 CDF for a uniform probability distribution of the given size.
|
||||
n: The size of the distribution.
|
||||
This must be at least 2, and no more than 16.*/
|
||||
#define OD_UNIFORM_CDF_Q15(n) (OD_UNIFORM_CDFS_Q15 + ((n) * ((n)-1) >> 1) - 1)
|
||||
|
||||
/*See entcode.c for further documentation.*/
|
||||
|
||||
OD_WARN_UNUSED_RESULT uint32_t od_ec_tell_frac(uint32_t nbits_total,
|
||||
uint32_t rng);
|
||||
|
||||
#endif
|
||||
494
aom_dsp/entdec.c
494
aom_dsp/entdec.c
@@ -1,494 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2001-2016, Alliance for Open Media. All rights reserved
|
||||
*
|
||||
* This source code is subject to the terms of the BSD 2 Clause License and
|
||||
* the Alliance for Open Media Patent License 1.0. If the BSD 2 Clause License
|
||||
* was not distributed with this source code in the LICENSE file, you can
|
||||
* obtain it at www.aomedia.org/license/software. If the Alliance for Open
|
||||
* Media Patent License 1.0 was not distributed with this source code in the
|
||||
* PATENTS file, you can obtain it at www.aomedia.org/license/patent.
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "./config.h"
|
||||
#endif
|
||||
|
||||
#include "aom_dsp/entdec.h"
|
||||
|
||||
/*A range decoder.
|
||||
This is an entropy decoder based upon \cite{Mar79}, which is itself a
|
||||
rediscovery of the FIFO arithmetic code introduced by \cite{Pas76}.
|
||||
It is very similar to arithmetic encoding, except that encoding is done with
|
||||
digits in any base, instead of with bits, and so it is faster when using
|
||||
larger bases (i.e.: a byte).
|
||||
The author claims an average waste of $\frac{1}{2}\log_b(2b)$ bits, where $b$
|
||||
is the base, longer than the theoretical optimum, but to my knowledge there
|
||||
is no published justification for this claim.
|
||||
This only seems true when using near-infinite precision arithmetic so that
|
||||
the process is carried out with no rounding errors.
|
||||
|
||||
An excellent description of implementation details is available at
|
||||
http://www.arturocampos.com/ac_range.html
|
||||
A recent work \cite{MNW98} which proposes several changes to arithmetic
|
||||
encoding for efficiency actually re-discovers many of the principles
|
||||
behind range encoding, and presents a good theoretical analysis of them.
|
||||
|
||||
End of stream is handled by writing out the smallest number of bits that
|
||||
ensures that the stream will be correctly decoded regardless of the value of
|
||||
any subsequent bits.
|
||||
od_ec_dec_tell() can be used to determine how many bits were needed to decode
|
||||
all the symbols thus far; other data can be packed in the remaining bits of
|
||||
the input buffer.
|
||||
@PHDTHESIS{Pas76,
|
||||
author="Richard Clark Pasco",
|
||||
title="Source coding algorithms for fast data compression",
|
||||
school="Dept. of Electrical Engineering, Stanford University",
|
||||
address="Stanford, CA",
|
||||
month=May,
|
||||
year=1976,
|
||||
URL="http://www.richpasco.org/scaffdc.pdf"
|
||||
}
|
||||
@INPROCEEDINGS{Mar79,
|
||||
author="Martin, G.N.N.",
|
||||
title="Range encoding: an algorithm for removing redundancy from a digitised
|
||||
message",
|
||||
booktitle="Video & Data Recording Conference",
|
||||
year=1979,
|
||||
address="Southampton",
|
||||
month=Jul,
|
||||
URL="http://www.compressconsult.com/rangecoder/rngcod.pdf.gz"
|
||||
}
|
||||
@ARTICLE{MNW98,
|
||||
author="Alistair Moffat and Radford Neal and Ian H. Witten",
|
||||
title="Arithmetic Coding Revisited",
|
||||
journal="{ACM} Transactions on Information Systems",
|
||||
year=1998,
|
||||
volume=16,
|
||||
number=3,
|
||||
pages="256--294",
|
||||
month=Jul,
|
||||
URL="http://researchcommons.waikato.ac.nz/bitstream/handle/10289/78/content.pdf"
|
||||
}*/
|
||||
|
||||
/*This is meant to be a large, positive constant that can still be efficiently
|
||||
loaded as an immediate (on platforms like ARM, for example).
|
||||
Even relatively modest values like 100 would work fine.*/
|
||||
#define OD_EC_LOTS_OF_BITS (0x4000)
|
||||
|
||||
static void od_ec_dec_refill(od_ec_dec *dec) {
|
||||
int s;
|
||||
od_ec_window dif;
|
||||
int16_t cnt;
|
||||
const unsigned char *bptr;
|
||||
const unsigned char *end;
|
||||
dif = dec->dif;
|
||||
cnt = dec->cnt;
|
||||
bptr = dec->bptr;
|
||||
end = dec->end;
|
||||
s = OD_EC_WINDOW_SIZE - 9 - (cnt + 15);
|
||||
for (; s >= 0 && bptr < end; s -= 8, bptr++) {
|
||||
OD_ASSERT(s <= OD_EC_WINDOW_SIZE - 8);
|
||||
dif |= (od_ec_window)bptr[0] << s;
|
||||
cnt += 8;
|
||||
}
|
||||
if (bptr >= end) {
|
||||
dec->tell_offs += OD_EC_LOTS_OF_BITS - cnt;
|
||||
cnt = OD_EC_LOTS_OF_BITS;
|
||||
}
|
||||
dec->dif = dif;
|
||||
dec->cnt = cnt;
|
||||
dec->bptr = bptr;
|
||||
}
|
||||
|
||||
/*Takes updated dif and range values, renormalizes them so that
|
||||
32768 <= rng < 65536 (reading more bytes from the stream into dif if
|
||||
necessary), and stores them back in the decoder context.
|
||||
dif: The new value of dif.
|
||||
rng: The new value of the range.
|
||||
ret: The value to return.
|
||||
Return: ret.
|
||||
This allows the compiler to jump to this function via a tail-call.*/
|
||||
static int od_ec_dec_normalize(od_ec_dec *dec, od_ec_window dif, unsigned rng,
|
||||
int ret) {
|
||||
int d;
|
||||
OD_ASSERT(rng <= 65535U);
|
||||
d = 16 - OD_ILOG_NZ(rng);
|
||||
dec->cnt -= d;
|
||||
dec->dif = dif << d;
|
||||
dec->rng = rng << d;
|
||||
if (dec->cnt < 0) od_ec_dec_refill(dec);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*Initializes the decoder.
|
||||
buf: The input buffer to use.
|
||||
Return: 0 on success, or a negative value on error.*/
|
||||
void od_ec_dec_init(od_ec_dec *dec, const unsigned char *buf,
|
||||
uint32_t storage) {
|
||||
dec->buf = buf;
|
||||
dec->eptr = buf + storage;
|
||||
dec->end_window = 0;
|
||||
dec->nend_bits = 0;
|
||||
dec->tell_offs = 10 - (OD_EC_WINDOW_SIZE - 8);
|
||||
dec->end = buf + storage;
|
||||
dec->bptr = buf;
|
||||
dec->dif = 0;
|
||||
dec->rng = 0x8000;
|
||||
dec->cnt = -15;
|
||||
dec->error = 0;
|
||||
od_ec_dec_refill(dec);
|
||||
}
|
||||
|
||||
/*Decode a bit that has an fz/ft probability of being a zero.
|
||||
fz: The probability that the bit is zero, scaled by _ft.
|
||||
ft: The total probability.
|
||||
This must be at least 16384 and no more than 32768.
|
||||
Return: The value decoded (0 or 1).*/
|
||||
int od_ec_decode_bool(od_ec_dec *dec, unsigned fz, unsigned ft) {
|
||||
od_ec_window dif;
|
||||
od_ec_window vw;
|
||||
unsigned r;
|
||||
int s;
|
||||
unsigned v;
|
||||
int ret;
|
||||
OD_ASSERT(0 < fz);
|
||||
OD_ASSERT(fz < ft);
|
||||
OD_ASSERT(16384 <= ft);
|
||||
OD_ASSERT(ft <= 32768U);
|
||||
dif = dec->dif;
|
||||
r = dec->rng;
|
||||
OD_ASSERT(dif >> (OD_EC_WINDOW_SIZE - 16) < r);
|
||||
OD_ASSERT(ft <= r);
|
||||
s = r - ft >= ft;
|
||||
ft <<= s;
|
||||
fz <<= s;
|
||||
OD_ASSERT(r - ft < ft);
|
||||
#if OD_EC_REDUCED_OVERHEAD
|
||||
{
|
||||
unsigned d;
|
||||
unsigned e;
|
||||
d = r - ft;
|
||||
e = OD_SUBSATU(2 * d, ft);
|
||||
v = fz + OD_MINI(fz, e) + OD_MINI(OD_SUBSATU(fz, e) >> 1, d);
|
||||
}
|
||||
#else
|
||||
v = fz + OD_MINI(fz, r - ft);
|
||||
#endif
|
||||
vw = (od_ec_window)v << (OD_EC_WINDOW_SIZE - 16);
|
||||
ret = dif >= vw;
|
||||
if (ret) dif -= vw;
|
||||
r = ret ? r - v : v;
|
||||
return od_ec_dec_normalize(dec, dif, r, ret);
|
||||
}
|
||||
|
||||
/*Decode a bit that has an fz probability of being a zero in Q15.
|
||||
This is a simpler, lower overhead version of od_ec_decode_bool() for use when
|
||||
ft == 32768.
|
||||
To be decoded properly by this function, symbols cannot have been encoded by
|
||||
od_ec_encode(), but must have been encoded with one of the equivalent _q15()
|
||||
or _dyadic() functions instead.
|
||||
fz: The probability that the bit is zero, scaled by 32768.
|
||||
Return: The value decoded (0 or 1).*/
|
||||
int od_ec_decode_bool_q15(od_ec_dec *dec, unsigned fz) {
|
||||
od_ec_window dif;
|
||||
od_ec_window vw;
|
||||
unsigned r;
|
||||
unsigned r_new;
|
||||
unsigned v;
|
||||
int ret;
|
||||
OD_ASSERT(0 < fz);
|
||||
OD_ASSERT(fz < 32768U);
|
||||
dif = dec->dif;
|
||||
r = dec->rng;
|
||||
OD_ASSERT(dif >> (OD_EC_WINDOW_SIZE - 16) < r);
|
||||
OD_ASSERT(32768U <= r);
|
||||
v = fz * (uint32_t)r >> 15;
|
||||
vw = (od_ec_window)v << (OD_EC_WINDOW_SIZE - 16);
|
||||
ret = 0;
|
||||
r_new = v;
|
||||
if (dif >= vw) {
|
||||
r_new = r - v;
|
||||
dif -= vw;
|
||||
ret = 1;
|
||||
}
|
||||
return od_ec_dec_normalize(dec, dif, r_new, ret);
|
||||
}
|
||||
|
||||
/*Decodes a symbol given a cumulative distribution function (CDF) table.
|
||||
cdf: The CDF, such that symbol s falls in the range
|
||||
[s > 0 ? cdf[s - 1] : 0, cdf[s]).
|
||||
The values must be monotonically non-increasing, and cdf[nsyms - 1]
|
||||
must be at least 16384, and no more than 32768.
|
||||
nsyms: The number of symbols in the alphabet.
|
||||
This should be at most 16.
|
||||
Return: The decoded symbol s.*/
|
||||
int od_ec_decode_cdf(od_ec_dec *dec, const uint16_t *cdf, int nsyms) {
|
||||
od_ec_window dif;
|
||||
unsigned r;
|
||||
unsigned c;
|
||||
unsigned d;
|
||||
#if OD_EC_REDUCED_OVERHEAD
|
||||
unsigned e;
|
||||
#endif
|
||||
int s;
|
||||
unsigned u;
|
||||
unsigned v;
|
||||
unsigned q;
|
||||
unsigned fl;
|
||||
unsigned fh;
|
||||
unsigned ft;
|
||||
int ret;
|
||||
dif = dec->dif;
|
||||
r = dec->rng;
|
||||
OD_ASSERT(dif >> (OD_EC_WINDOW_SIZE - 16) < r);
|
||||
OD_ASSERT(nsyms > 0);
|
||||
ft = cdf[nsyms - 1];
|
||||
OD_ASSERT(16384 <= ft);
|
||||
OD_ASSERT(ft <= 32768U);
|
||||
OD_ASSERT(ft <= r);
|
||||
s = r - ft >= ft;
|
||||
ft <<= s;
|
||||
d = r - ft;
|
||||
OD_ASSERT(d < ft);
|
||||
c = (unsigned)(dif >> (OD_EC_WINDOW_SIZE - 16));
|
||||
q = OD_MAXI((int)(c >> 1), (int)(c - d));
|
||||
#if OD_EC_REDUCED_OVERHEAD
|
||||
e = OD_SUBSATU(2 * d, ft);
|
||||
/*The correctness of this inverse partition function is not obvious, but it
|
||||
was checked exhaustively for all possible values of r, ft, and c.
|
||||
TODO: It should be possible to optimize this better than the compiler,
|
||||
given that we do not care about the accuracy of negative results (as we
|
||||
will not use them).
|
||||
It would also be nice to get rid of the 32-bit dividend, as it requires a
|
||||
32x32->64 bit multiply to invert.*/
|
||||
q = OD_MAXI((int)q, (int)((2 * (int32_t)c + 1 - (int32_t)e) / 3));
|
||||
#endif
|
||||
q >>= s;
|
||||
OD_ASSERT(q<ft>> s);
|
||||
fl = 0;
|
||||
ret = 0;
|
||||
for (fh = cdf[ret]; fh <= q; fh = cdf[++ret]) fl = fh;
|
||||
OD_ASSERT(fh <= ft >> s);
|
||||
fl <<= s;
|
||||
fh <<= s;
|
||||
#if OD_EC_REDUCED_OVERHEAD
|
||||
u = fl + OD_MINI(fl, e) + OD_MINI(OD_SUBSATU(fl, e) >> 1, d);
|
||||
v = fh + OD_MINI(fh, e) + OD_MINI(OD_SUBSATU(fh, e) >> 1, d);
|
||||
#else
|
||||
u = fl + OD_MINI(fl, d);
|
||||
v = fh + OD_MINI(fh, d);
|
||||
#endif
|
||||
r = v - u;
|
||||
dif -= (od_ec_window)u << (OD_EC_WINDOW_SIZE - 16);
|
||||
return od_ec_dec_normalize(dec, dif, r, ret);
|
||||
}
|
||||
|
||||
/*Decodes a symbol given a cumulative distribution function (CDF) table.
|
||||
cdf: The CDF, such that symbol s falls in the range
|
||||
[s > 0 ? cdf[s - 1] : 0, cdf[s]).
|
||||
The values must be monotonically non-increasing, and cdf[nsyms - 1]
|
||||
must be at least 2, and no more than 32768.
|
||||
nsyms: The number of symbols in the alphabet.
|
||||
This should be at most 16.
|
||||
Return: The decoded symbol s.*/
|
||||
int od_ec_decode_cdf_unscaled(od_ec_dec *dec, const uint16_t *cdf, int nsyms) {
|
||||
od_ec_window dif;
|
||||
unsigned r;
|
||||
unsigned c;
|
||||
unsigned d;
|
||||
#if OD_EC_REDUCED_OVERHEAD
|
||||
unsigned e;
|
||||
#endif
|
||||
int s;
|
||||
unsigned u;
|
||||
unsigned v;
|
||||
unsigned q;
|
||||
unsigned fl;
|
||||
unsigned fh;
|
||||
unsigned ft;
|
||||
int ret;
|
||||
dif = dec->dif;
|
||||
r = dec->rng;
|
||||
OD_ASSERT(dif >> (OD_EC_WINDOW_SIZE - 16) < r);
|
||||
OD_ASSERT(nsyms > 0);
|
||||
ft = cdf[nsyms - 1];
|
||||
OD_ASSERT(2 <= ft);
|
||||
OD_ASSERT(ft <= 32768U);
|
||||
s = 15 - OD_ILOG_NZ(ft - 1);
|
||||
ft <<= s;
|
||||
OD_ASSERT(ft <= r);
|
||||
if (r - ft >= ft) {
|
||||
ft <<= 1;
|
||||
s++;
|
||||
}
|
||||
d = r - ft;
|
||||
OD_ASSERT(d < ft);
|
||||
c = (unsigned)(dif >> (OD_EC_WINDOW_SIZE - 16));
|
||||
q = OD_MAXI((int)(c >> 1), (int)(c - d));
|
||||
#if OD_EC_REDUCED_OVERHEAD
|
||||
e = OD_SUBSATU(2 * d, ft);
|
||||
/*TODO: See TODO above.*/
|
||||
q = OD_MAXI((int)q, (int)((2 * (int32_t)c + 1 - (int32_t)e) / 3));
|
||||
#endif
|
||||
q >>= s;
|
||||
OD_ASSERT(q<ft>> s);
|
||||
fl = 0;
|
||||
ret = 0;
|
||||
for (fh = cdf[ret]; fh <= q; fh = cdf[++ret]) fl = fh;
|
||||
OD_ASSERT(fh <= ft >> s);
|
||||
fl <<= s;
|
||||
fh <<= s;
|
||||
#if OD_EC_REDUCED_OVERHEAD
|
||||
u = fl + OD_MINI(fl, e) + OD_MINI(OD_SUBSATU(fl, e) >> 1, d);
|
||||
v = fh + OD_MINI(fh, e) + OD_MINI(OD_SUBSATU(fh, e) >> 1, d);
|
||||
#else
|
||||
u = fl + OD_MINI(fl, d);
|
||||
v = fh + OD_MINI(fh, d);
|
||||
#endif
|
||||
r = v - u;
|
||||
dif -= (od_ec_window)u << (OD_EC_WINDOW_SIZE - 16);
|
||||
return od_ec_dec_normalize(dec, dif, r, ret);
|
||||
}
|
||||
|
||||
/*Decodes a symbol given a cumulative distribution function (CDF) table that
|
||||
sums to a power of two.
|
||||
This is a simpler, lower overhead version of od_ec_decode_cdf() for use when
|
||||
cdf[nsyms - 1] is a power of two.
|
||||
To be decoded properly by this function, symbols cannot have been encoded by
|
||||
od_ec_encode(), but must have been encoded with one of the equivalent _q15()
|
||||
functions instead.
|
||||
cdf: The CDF, such that symbol s falls in the range
|
||||
[s > 0 ? cdf[s - 1] : 0, cdf[s]).
|
||||
The values must be monotonically non-increasing, and cdf[nsyms - 1]
|
||||
must be exactly 1 << ftb.
|
||||
nsyms: The number of symbols in the alphabet.
|
||||
This should be at most 16.
|
||||
ftb: The number of bits of precision in the cumulative distribution.
|
||||
This must be no more than 15.
|
||||
Return: The decoded symbol s.*/
|
||||
int od_ec_decode_cdf_unscaled_dyadic(od_ec_dec *dec, const uint16_t *cdf,
|
||||
int nsyms, unsigned ftb) {
|
||||
od_ec_window dif;
|
||||
unsigned r;
|
||||
unsigned c;
|
||||
unsigned u;
|
||||
unsigned v;
|
||||
int ret;
|
||||
(void)nsyms;
|
||||
dif = dec->dif;
|
||||
r = dec->rng;
|
||||
OD_ASSERT(dif >> (OD_EC_WINDOW_SIZE - 16) < r);
|
||||
OD_ASSERT(ftb <= 15);
|
||||
OD_ASSERT(cdf[nsyms - 1] == 1U << ftb);
|
||||
OD_ASSERT(32768U <= r);
|
||||
c = (unsigned)(dif >> (OD_EC_WINDOW_SIZE - 16));
|
||||
v = 0;
|
||||
ret = -1;
|
||||
do {
|
||||
u = v;
|
||||
v = cdf[++ret] * (uint32_t)r >> ftb;
|
||||
} while (v <= c);
|
||||
OD_ASSERT(v <= r);
|
||||
r = v - u;
|
||||
dif -= (od_ec_window)u << (OD_EC_WINDOW_SIZE - 16);
|
||||
return od_ec_dec_normalize(dec, dif, r, ret);
|
||||
}
|
||||
|
||||
/*Decodes a symbol given a cumulative distribution function (CDF) table in Q15.
|
||||
This is a simpler, lower overhead version of od_ec_decode_cdf() for use when
|
||||
cdf[nsyms - 1] == 32768.
|
||||
To be decoded properly by this function, symbols cannot have been encoded by
|
||||
od_ec_encode(), but must have been encoded with one of the equivalent _q15()
|
||||
or dyadic() functions instead.
|
||||
cdf: The CDF, such that symbol s falls in the range
|
||||
[s > 0 ? cdf[s - 1] : 0, cdf[s]).
|
||||
The values must be monotonically non-increasing, and cdf[nsyms - 1]
|
||||
must be 32768.
|
||||
nsyms: The number of symbols in the alphabet.
|
||||
This should be at most 16.
|
||||
Return: The decoded symbol s.*/
|
||||
int od_ec_decode_cdf_q15(od_ec_dec *dec, const uint16_t *cdf, int nsyms) {
|
||||
return od_ec_decode_cdf_unscaled_dyadic(dec, cdf, nsyms, 15);
|
||||
}
|
||||
|
||||
/*Extracts a raw unsigned integer with a non-power-of-2 range from the stream.
|
||||
The integer must have been encoded with od_ec_enc_uint().
|
||||
ft: The number of integers that can be decoded (one more than the max).
|
||||
This must be at least 2, and no more than 2**29.
|
||||
Return: The decoded bits.*/
|
||||
uint32_t od_ec_dec_uint(od_ec_dec *dec, uint32_t ft) {
|
||||
OD_ASSERT(ft >= 2);
|
||||
OD_ASSERT(ft <= (uint32_t)1 << (25 + OD_EC_UINT_BITS));
|
||||
if (ft > 1U << OD_EC_UINT_BITS) {
|
||||
uint32_t t;
|
||||
int ft1;
|
||||
int ftb;
|
||||
ft--;
|
||||
ftb = OD_ILOG_NZ(ft) - OD_EC_UINT_BITS;
|
||||
ft1 = (int)(ft >> ftb) + 1;
|
||||
t = od_ec_decode_cdf_q15(dec, OD_UNIFORM_CDF_Q15(ft1), ft1);
|
||||
t = t << ftb | od_ec_dec_bits(dec, ftb, "");
|
||||
if (t <= ft) return t;
|
||||
dec->error = 1;
|
||||
return ft;
|
||||
}
|
||||
return od_ec_decode_cdf_q15(dec, OD_UNIFORM_CDF_Q15(ft), (int)ft);
|
||||
}
|
||||
|
||||
/*Extracts a sequence of raw bits from the stream.
|
||||
The bits must have been encoded with od_ec_enc_bits().
|
||||
ftb: The number of bits to extract.
|
||||
This must be between 0 and 25, inclusive.
|
||||
Return: The decoded bits.*/
|
||||
uint32_t od_ec_dec_bits_(od_ec_dec *dec, unsigned ftb) {
|
||||
od_ec_window window;
|
||||
int available;
|
||||
uint32_t ret;
|
||||
OD_ASSERT(ftb <= 25);
|
||||
window = dec->end_window;
|
||||
available = dec->nend_bits;
|
||||
if ((unsigned)available < ftb) {
|
||||
const unsigned char *buf;
|
||||
const unsigned char *eptr;
|
||||
buf = dec->buf;
|
||||
eptr = dec->eptr;
|
||||
OD_ASSERT(available <= OD_EC_WINDOW_SIZE - 8);
|
||||
do {
|
||||
if (eptr <= buf) {
|
||||
dec->tell_offs += OD_EC_LOTS_OF_BITS - available;
|
||||
available = OD_EC_LOTS_OF_BITS;
|
||||
break;
|
||||
}
|
||||
window |= (od_ec_window) * --eptr << available;
|
||||
available += 8;
|
||||
} while (available <= OD_EC_WINDOW_SIZE - 8);
|
||||
dec->eptr = eptr;
|
||||
}
|
||||
ret = (uint32_t)window & (((uint32_t)1 << ftb) - 1);
|
||||
window >>= ftb;
|
||||
available -= ftb;
|
||||
dec->end_window = window;
|
||||
dec->nend_bits = available;
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*Returns the number of bits "used" by the decoded symbols so far.
|
||||
This same number can be computed in either the encoder or the decoder, and is
|
||||
suitable for making coding decisions.
|
||||
Return: The number of bits.
|
||||
This will always be slightly larger than the exact value (e.g., all
|
||||
rounding error is in the positive direction).*/
|
||||
int od_ec_dec_tell(const od_ec_dec *dec) {
|
||||
return ((dec->end - dec->eptr) + (dec->bptr - dec->buf)) * 8 - dec->cnt -
|
||||
dec->nend_bits + dec->tell_offs;
|
||||
}
|
||||
|
||||
/*Returns the number of bits "used" by the decoded symbols so far.
|
||||
This same number can be computed in either the encoder or the decoder, and is
|
||||
suitable for making coding decisions.
|
||||
Return: The number of bits scaled by 2**OD_BITRES.
|
||||
This will always be slightly larger than the exact value (e.g., all
|
||||
rounding error is in the positive direction).*/
|
||||
uint32_t od_ec_dec_tell_frac(const od_ec_dec *dec) {
|
||||
return od_ec_tell_frac(od_ec_dec_tell(dec), dec->rng);
|
||||
}
|
||||
101
aom_dsp/entdec.h
101
aom_dsp/entdec.h
@@ -1,101 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2001-2016, Alliance for Open Media. All rights reserved
|
||||
*
|
||||
* This source code is subject to the terms of the BSD 2 Clause License and
|
||||
* the Alliance for Open Media Patent License 1.0. If the BSD 2 Clause License
|
||||
* was not distributed with this source code in the LICENSE file, you can
|
||||
* obtain it at www.aomedia.org/license/software. If the Alliance for Open
|
||||
* Media Patent License 1.0 was not distributed with this source code in the
|
||||
* PATENTS file, you can obtain it at www.aomedia.org/license/patent.
|
||||
*/
|
||||
|
||||
#if !defined(_entdec_H)
|
||||
#define _entdec_H (1)
|
||||
#include <limits.h>
|
||||
#include "aom_dsp/entcode.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
typedef struct od_ec_dec od_ec_dec;
|
||||
|
||||
#if OD_ACCOUNTING
|
||||
#define OD_ACC_STR , char *acc_str
|
||||
#define od_ec_dec_bits(dec, ftb, str) od_ec_dec_bits_(dec, ftb, str)
|
||||
#else
|
||||
#define OD_ACC_STR
|
||||
#define od_ec_dec_bits(dec, ftb, str) od_ec_dec_bits_(dec, ftb)
|
||||
#endif
|
||||
|
||||
/*The entropy decoder context.*/
|
||||
struct od_ec_dec {
|
||||
/*The start of the current input buffer.*/
|
||||
const unsigned char *buf;
|
||||
/*The read pointer for the raw bits.*/
|
||||
const unsigned char *eptr;
|
||||
/*Bits that will be read from/written at the end.*/
|
||||
od_ec_window end_window;
|
||||
/*Number of valid bits in end_window.*/
|
||||
int nend_bits;
|
||||
/*An offset used to keep track of tell after reaching the end of the stream.
|
||||
This is constant throughout most of the decoding process, but becomes
|
||||
important once we hit the end of the buffer and stop incrementing pointers
|
||||
(and instead pretend cnt/nend_bits have lots of bits).*/
|
||||
int32_t tell_offs;
|
||||
/*The end of the current input buffer.*/
|
||||
const unsigned char *end;
|
||||
/*The read pointer for the entropy-coded bits.*/
|
||||
const unsigned char *bptr;
|
||||
/*The difference between the coded value and the low end of the current
|
||||
range.*/
|
||||
od_ec_window dif;
|
||||
/*The number of values in the current range.*/
|
||||
uint16_t rng;
|
||||
/*The number of bits of data in the current value.*/
|
||||
int16_t cnt;
|
||||
/*Nonzero if an error occurred.*/
|
||||
int error;
|
||||
};
|
||||
|
||||
/*See entdec.c for further documentation.*/
|
||||
|
||||
void od_ec_dec_init(od_ec_dec *dec, const unsigned char *buf, uint32_t storage)
|
||||
OD_ARG_NONNULL(1) OD_ARG_NONNULL(2);
|
||||
|
||||
OD_WARN_UNUSED_RESULT int od_ec_decode_bool(od_ec_dec *dec, unsigned fz,
|
||||
unsigned ft) OD_ARG_NONNULL(1);
|
||||
OD_WARN_UNUSED_RESULT int od_ec_decode_bool_q15(od_ec_dec *dec, unsigned fz)
|
||||
OD_ARG_NONNULL(1);
|
||||
OD_WARN_UNUSED_RESULT int od_ec_decode_cdf(od_ec_dec *dec, const uint16_t *cdf,
|
||||
int nsyms) OD_ARG_NONNULL(1)
|
||||
OD_ARG_NONNULL(2);
|
||||
OD_WARN_UNUSED_RESULT int od_ec_decode_cdf_q15(od_ec_dec *dec,
|
||||
const uint16_t *cdf, int nsyms)
|
||||
OD_ARG_NONNULL(1) OD_ARG_NONNULL(2);
|
||||
OD_WARN_UNUSED_RESULT int od_ec_decode_cdf_unscaled(od_ec_dec *dec,
|
||||
const uint16_t *cdf,
|
||||
int nsyms) OD_ARG_NONNULL(1)
|
||||
OD_ARG_NONNULL(2);
|
||||
OD_WARN_UNUSED_RESULT int od_ec_decode_cdf_unscaled_dyadic(od_ec_dec *dec,
|
||||
const uint16_t *cdf,
|
||||
int nsyms,
|
||||
unsigned _ftb)
|
||||
OD_ARG_NONNULL(1) OD_ARG_NONNULL(2);
|
||||
|
||||
OD_WARN_UNUSED_RESULT uint32_t od_ec_dec_uint(od_ec_dec *dec, uint32_t ft)
|
||||
OD_ARG_NONNULL(1);
|
||||
|
||||
OD_WARN_UNUSED_RESULT uint32_t od_ec_dec_bits_(od_ec_dec *dec, unsigned ftb)
|
||||
OD_ARG_NONNULL(1);
|
||||
|
||||
OD_WARN_UNUSED_RESULT int od_ec_dec_tell(const od_ec_dec *dec)
|
||||
OD_ARG_NONNULL(1);
|
||||
OD_WARN_UNUSED_RESULT uint32_t od_ec_dec_tell_frac(const od_ec_dec *dec)
|
||||
OD_ARG_NONNULL(1);
|
||||
|
||||
#ifdef __cplusplus
|
||||
} // extern "C"
|
||||
#endif
|
||||
|
||||
#endif
|
||||
686
aom_dsp/entenc.c
686
aom_dsp/entenc.c
@@ -1,686 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2001-2016, Alliance for Open Media. All rights reserved
|
||||
*
|
||||
* This source code is subject to the terms of the BSD 2 Clause License and
|
||||
* the Alliance for Open Media Patent License 1.0. If the BSD 2 Clause License
|
||||
* was not distributed with this source code in the LICENSE file, you can
|
||||
* obtain it at www.aomedia.org/license/software. If the Alliance for Open
|
||||
* Media Patent License 1.0 was not distributed with this source code in the
|
||||
* PATENTS file, you can obtain it at www.aomedia.org/license/patent.
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "./config.h"
|
||||
#endif
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include "aom_dsp/entenc.h"
|
||||
|
||||
/*A range encoder.
|
||||
See entdec.c and the references for implementation details \cite{Mar79,MNW98}.
|
||||
|
||||
@INPROCEEDINGS{Mar79,
|
||||
author="Martin, G.N.N.",
|
||||
title="Range encoding: an algorithm for removing redundancy from a digitised
|
||||
message",
|
||||
booktitle="Video \& Data Recording Conference",
|
||||
year=1979,
|
||||
address="Southampton",
|
||||
month=Jul,
|
||||
URL="http://www.compressconsult.com/rangecoder/rngcod.pdf.gz"
|
||||
}
|
||||
@ARTICLE{MNW98,
|
||||
author="Alistair Moffat and Radford Neal and Ian H. Witten",
|
||||
title="Arithmetic Coding Revisited",
|
||||
journal="{ACM} Transactions on Information Systems",
|
||||
year=1998,
|
||||
volume=16,
|
||||
number=3,
|
||||
pages="256--294",
|
||||
month=Jul,
|
||||
URL="http://researchcommons.waikato.ac.nz/bitstream/handle/10289/78/content.pdf"
|
||||
}*/
|
||||
|
||||
/*Takes updated low and range values, renormalizes them so that
|
||||
32768 <= rng < 65536 (flushing bytes from low to the pre-carry buffer if
|
||||
necessary), and stores them back in the encoder context.
|
||||
low: The new value of low.
|
||||
rng: The new value of the range.*/
|
||||
static void od_ec_enc_normalize(od_ec_enc *enc, od_ec_window low,
|
||||
unsigned rng) {
|
||||
int d;
|
||||
int c;
|
||||
int s;
|
||||
c = enc->cnt;
|
||||
OD_ASSERT(rng <= 65535U);
|
||||
d = 16 - OD_ILOG_NZ(rng);
|
||||
s = c + d;
|
||||
/*TODO: Right now we flush every time we have at least one byte available.
|
||||
Instead we should use an od_ec_window and flush right before we're about to
|
||||
shift bits off the end of the window.
|
||||
For a 32-bit window this is about the same amount of work, but for a 64-bit
|
||||
window it should be a fair win.*/
|
||||
if (s >= 0) {
|
||||
uint16_t *buf;
|
||||
uint32_t storage;
|
||||
uint32_t offs;
|
||||
unsigned m;
|
||||
buf = enc->precarry_buf;
|
||||
storage = enc->precarry_storage;
|
||||
offs = enc->offs;
|
||||
if (offs + 2 > storage) {
|
||||
storage = 2 * storage + 2;
|
||||
buf = (uint16_t *)realloc(buf, sizeof(*buf) * storage);
|
||||
if (buf == NULL) {
|
||||
enc->error = -1;
|
||||
enc->offs = 0;
|
||||
return;
|
||||
}
|
||||
enc->precarry_buf = buf;
|
||||
enc->precarry_storage = storage;
|
||||
}
|
||||
c += 16;
|
||||
m = (1 << c) - 1;
|
||||
if (s >= 8) {
|
||||
OD_ASSERT(offs < storage);
|
||||
buf[offs++] = (uint16_t)(low >> c);
|
||||
low &= m;
|
||||
c -= 8;
|
||||
m >>= 8;
|
||||
}
|
||||
OD_ASSERT(offs < storage);
|
||||
buf[offs++] = (uint16_t)(low >> c);
|
||||
s = c + d - 24;
|
||||
low &= m;
|
||||
enc->offs = offs;
|
||||
}
|
||||
enc->low = low << d;
|
||||
enc->rng = rng << d;
|
||||
enc->cnt = s;
|
||||
}
|
||||
|
||||
/*Initializes the encoder.
|
||||
size: The initial size of the buffer, in bytes.*/
|
||||
void od_ec_enc_init(od_ec_enc *enc, uint32_t size) {
|
||||
od_ec_enc_reset(enc);
|
||||
enc->buf = (unsigned char *)malloc(sizeof(*enc->buf) * size);
|
||||
enc->storage = size;
|
||||
if (size > 0 && enc->buf == NULL) {
|
||||
enc->storage = 0;
|
||||
enc->error = -1;
|
||||
}
|
||||
enc->precarry_buf = (uint16_t *)malloc(sizeof(*enc->precarry_buf) * size);
|
||||
enc->precarry_storage = size;
|
||||
if (size > 0 && enc->precarry_buf == NULL) {
|
||||
enc->precarry_storage = 0;
|
||||
enc->error = -1;
|
||||
}
|
||||
}
|
||||
|
||||
/*Reinitializes the encoder.*/
|
||||
void od_ec_enc_reset(od_ec_enc *enc) {
|
||||
enc->end_offs = 0;
|
||||
enc->end_window = 0;
|
||||
enc->nend_bits = 0;
|
||||
enc->offs = 0;
|
||||
enc->low = 0;
|
||||
enc->rng = 0x8000;
|
||||
/*This is initialized to -9 so that it crosses zero after we've accumulated
|
||||
one byte + one carry bit.*/
|
||||
enc->cnt = -9;
|
||||
enc->error = 0;
|
||||
#if OD_MEASURE_EC_OVERHEAD
|
||||
enc->entropy = 0;
|
||||
enc->nb_symbols = 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
/*Frees the buffers used by the encoder.*/
|
||||
void od_ec_enc_clear(od_ec_enc *enc) {
|
||||
free(enc->precarry_buf);
|
||||
free(enc->buf);
|
||||
}
|
||||
|
||||
/*Encodes a symbol given its scaled frequency information.
|
||||
The frequency information must be discernable by the decoder, assuming it
|
||||
has read only the previous symbols from the stream.
|
||||
You can change the frequency information, or even the entire source alphabet,
|
||||
so long as the decoder can tell from the context of the previously encoded
|
||||
information that it is supposed to do so as well.
|
||||
fl: The cumulative frequency of all symbols that come before the one to be
|
||||
encoded.
|
||||
fh: The cumulative frequency of all symbols up to and including the one to
|
||||
be encoded.
|
||||
Together with fl, this defines the range [fl, fh) in which the decoded
|
||||
value will fall.
|
||||
ft: The sum of the frequencies of all the symbols.
|
||||
This must be at least 16384, and no more than 32768.*/
|
||||
static void od_ec_encode(od_ec_enc *enc, unsigned fl, unsigned fh,
|
||||
unsigned ft) {
|
||||
od_ec_window l;
|
||||
unsigned r;
|
||||
int s;
|
||||
unsigned d;
|
||||
unsigned u;
|
||||
unsigned v;
|
||||
OD_ASSERT(fl < fh);
|
||||
OD_ASSERT(fh <= ft);
|
||||
OD_ASSERT(16384 <= ft);
|
||||
OD_ASSERT(ft <= 32768U);
|
||||
l = enc->low;
|
||||
r = enc->rng;
|
||||
OD_ASSERT(ft <= r);
|
||||
s = r - ft >= ft;
|
||||
ft <<= s;
|
||||
fl <<= s;
|
||||
fh <<= s;
|
||||
d = r - ft;
|
||||
OD_ASSERT(d < ft);
|
||||
#if OD_EC_REDUCED_OVERHEAD
|
||||
{
|
||||
unsigned e;
|
||||
e = OD_SUBSATU(2 * d, ft);
|
||||
u = fl + OD_MINI(fl, e) + OD_MINI(OD_SUBSATU(fl, e) >> 1, d);
|
||||
v = fh + OD_MINI(fh, e) + OD_MINI(OD_SUBSATU(fh, e) >> 1, d);
|
||||
}
|
||||
#else
|
||||
u = fl + OD_MINI(fl, d);
|
||||
v = fh + OD_MINI(fh, d);
|
||||
#endif
|
||||
r = v - u;
|
||||
l += u;
|
||||
od_ec_enc_normalize(enc, l, r);
|
||||
#if OD_MEASURE_EC_OVERHEAD
|
||||
enc->entropy -= OD_LOG2((double)(fh - fl) / ft);
|
||||
enc->nb_symbols++;
|
||||
#endif
|
||||
}
|
||||
|
||||
/*Encodes a symbol given its frequency in Q15.
|
||||
This is like od_ec_encode() when ft == 32768, but is simpler and has lower
|
||||
overhead.
|
||||
Symbols encoded with this function cannot be properly decoded with
|
||||
od_ec_decode(), and must be decoded with one of the equivalent _q15()
|
||||
functions instead.
|
||||
fl: The cumulative frequency of all symbols that come before the one to be
|
||||
encoded.
|
||||
fh: The cumulative frequency of all symbols up to and including the one to
|
||||
be encoded.*/
|
||||
static void od_ec_encode_q15(od_ec_enc *enc, unsigned fl, unsigned fh) {
|
||||
od_ec_window l;
|
||||
unsigned r;
|
||||
unsigned u;
|
||||
unsigned v;
|
||||
OD_ASSERT(fl < fh);
|
||||
OD_ASSERT(fh <= 32768U);
|
||||
l = enc->low;
|
||||
r = enc->rng;
|
||||
OD_ASSERT(32768U <= r);
|
||||
u = fl * (uint32_t)r >> 15;
|
||||
v = fh * (uint32_t)r >> 15;
|
||||
r = v - u;
|
||||
l += u;
|
||||
od_ec_enc_normalize(enc, l, r);
|
||||
#if OD_MEASURE_EC_OVERHEAD
|
||||
enc->entropy -= OD_LOG2((double)(fh - fl) / 32768.);
|
||||
enc->nb_symbols++;
|
||||
#endif
|
||||
}
|
||||
|
||||
/*Encodes a symbol given its frequency information with an arbitrary scale.
|
||||
This operates just like od_ec_encode(), but does not require that ft be at
|
||||
least 16384.
|
||||
fl: The cumulative frequency of all symbols that come before the one to be
|
||||
encoded.
|
||||
fh: The cumulative frequency of all symbols up to and including the one to
|
||||
be encoded.
|
||||
ft: The sum of the frequencies of all the symbols.
|
||||
This must be at least 2 and no more than 32768.*/
|
||||
static void od_ec_encode_unscaled(od_ec_enc *enc, unsigned fl, unsigned fh,
|
||||
unsigned ft) {
|
||||
int s;
|
||||
OD_ASSERT(fl < fh);
|
||||
OD_ASSERT(fh <= ft);
|
||||
OD_ASSERT(2 <= ft);
|
||||
OD_ASSERT(ft <= 32768U);
|
||||
s = 15 - OD_ILOG_NZ(ft - 1);
|
||||
od_ec_encode(enc, fl << s, fh << s, ft << s);
|
||||
}
|
||||
|
||||
/*Encode a bit that has an fz/ft probability of being a zero.
|
||||
val: The value to encode (0 or 1).
|
||||
fz: The probability that val is zero, scaled by ft.
|
||||
ft: The total probability.
|
||||
This must be at least 16384 and no more than 32768.*/
|
||||
void od_ec_encode_bool(od_ec_enc *enc, int val, unsigned fz, unsigned ft) {
|
||||
od_ec_window l;
|
||||
unsigned r;
|
||||
int s;
|
||||
unsigned v;
|
||||
OD_ASSERT(0 < fz);
|
||||
OD_ASSERT(fz < ft);
|
||||
OD_ASSERT(16384 <= ft);
|
||||
OD_ASSERT(ft <= 32768U);
|
||||
l = enc->low;
|
||||
r = enc->rng;
|
||||
OD_ASSERT(ft <= r);
|
||||
s = r - ft >= ft;
|
||||
ft <<= s;
|
||||
fz <<= s;
|
||||
OD_ASSERT(r - ft < ft);
|
||||
#if OD_EC_REDUCED_OVERHEAD
|
||||
{
|
||||
unsigned d;
|
||||
unsigned e;
|
||||
d = r - ft;
|
||||
e = OD_SUBSATU(2 * d, ft);
|
||||
v = fz + OD_MINI(fz, e) + OD_MINI(OD_SUBSATU(fz, e) >> 1, d);
|
||||
}
|
||||
#else
|
||||
v = fz + OD_MINI(fz, r - ft);
|
||||
#endif
|
||||
if (val) l += v;
|
||||
r = val ? r - v : v;
|
||||
od_ec_enc_normalize(enc, l, r);
|
||||
#if OD_MEASURE_EC_OVERHEAD
|
||||
enc->entropy -= OD_LOG2((double)(val ? ft - fz : fz) / ft);
|
||||
enc->nb_symbols++;
|
||||
#endif
|
||||
}
|
||||
|
||||
/*Encode a bit that has an fz probability of being a zero in Q15.
|
||||
This is a simpler, lower overhead version of od_ec_encode_bool() for use when
|
||||
ft == 32768.
|
||||
Symbols encoded with this function cannot be properly decoded with
|
||||
od_ec_decode(), and must be decoded with one of the equivalent _q15()
|
||||
functions instead.
|
||||
val: The value to encode (0 or 1).
|
||||
fz: The probability that val is zero, scaled by 32768.*/
|
||||
void od_ec_encode_bool_q15(od_ec_enc *enc, int val, unsigned fz) {
|
||||
od_ec_window l;
|
||||
unsigned r;
|
||||
unsigned v;
|
||||
OD_ASSERT(0 < fz);
|
||||
OD_ASSERT(fz < 32768U);
|
||||
l = enc->low;
|
||||
r = enc->rng;
|
||||
OD_ASSERT(32768U <= r);
|
||||
v = fz * (uint32_t)r >> 15;
|
||||
if (val) l += v;
|
||||
r = val ? r - v : v;
|
||||
od_ec_enc_normalize(enc, l, r);
|
||||
#if OD_MEASURE_EC_OVERHEAD
|
||||
enc->entropy -= OD_LOG2((double)(val ? 32768 - fz : fz) / 32768.);
|
||||
enc->nb_symbols++;
|
||||
#endif
|
||||
}
|
||||
|
||||
/*Encodes a symbol given a cumulative distribution function (CDF) table.
|
||||
s: The index of the symbol to encode.
|
||||
cdf: The CDF, such that symbol s falls in the range
|
||||
[s > 0 ? cdf[s - 1] : 0, cdf[s]).
|
||||
The values must be monotonically non-decreasing, and the last value
|
||||
must be at least 16384, and no more than 32768.
|
||||
nsyms: The number of symbols in the alphabet.
|
||||
This should be at most 16.*/
|
||||
void od_ec_encode_cdf(od_ec_enc *enc, int s, const uint16_t *cdf, int nsyms) {
|
||||
OD_ASSERT(s >= 0);
|
||||
OD_ASSERT(s < nsyms);
|
||||
od_ec_encode(enc, s > 0 ? cdf[s - 1] : 0, cdf[s], cdf[nsyms - 1]);
|
||||
}
|
||||
|
||||
/*Encodes a symbol given a cumulative distribution function (CDF) table in Q15.
|
||||
This is a simpler, lower overhead version of od_ec_encode_cdf() for use when
|
||||
cdf[nsyms - 1] == 32768.
|
||||
Symbols encoded with this function cannot be properly decoded with
|
||||
od_ec_decode(), and must be decoded with one of the equivalent _q15()
|
||||
functions instead.
|
||||
s: The index of the symbol to encode.
|
||||
cdf: The CDF, such that symbol s falls in the range
|
||||
[s > 0 ? cdf[s - 1] : 0, cdf[s]).
|
||||
The values must be monotonically non-decreasing, and the last value
|
||||
must be exactly 32768.
|
||||
nsyms: The number of symbols in the alphabet.
|
||||
This should be at most 16.*/
|
||||
void od_ec_encode_cdf_q15(od_ec_enc *enc, int s, const uint16_t *cdf,
|
||||
int nsyms) {
|
||||
(void)nsyms;
|
||||
OD_ASSERT(s >= 0);
|
||||
OD_ASSERT(s < nsyms);
|
||||
OD_ASSERT(cdf[nsyms - 1] == 32768U);
|
||||
od_ec_encode_q15(enc, s > 0 ? cdf[s - 1] : 0, cdf[s]);
|
||||
}
|
||||
|
||||
/*Encodes a symbol given a cumulative distribution function (CDF) table.
|
||||
s: The index of the symbol to encode.
|
||||
cdf: The CDF, such that symbol s falls in the range
|
||||
[s > 0 ? cdf[s - 1] : 0, cdf[s]).
|
||||
The values must be monotonically non-decreasing, and the last value
|
||||
must be at least 2, and no more than 32768.
|
||||
nsyms: The number of symbols in the alphabet.
|
||||
This should be at most 16.*/
|
||||
void od_ec_encode_cdf_unscaled(od_ec_enc *enc, int s, const uint16_t *cdf,
|
||||
int nsyms) {
|
||||
OD_ASSERT(s >= 0);
|
||||
OD_ASSERT(s < nsyms);
|
||||
od_ec_encode_unscaled(enc, s > 0 ? cdf[s - 1] : 0, cdf[s], cdf[nsyms - 1]);
|
||||
}
|
||||
|
||||
/*Equivalent to od_ec_encode_cdf_q15() with the cdf scaled by
|
||||
(1 << (15 - ftb)).
|
||||
s: The index of the symbol to encode.
|
||||
cdf: The CDF, such that symbol s falls in the range
|
||||
[s > 0 ? cdf[s - 1] : 0, cdf[s]).
|
||||
The values must be monotonically non-decreasing, and the last value
|
||||
must be exactly 1 << ftb.
|
||||
nsyms: The number of symbols in the alphabet.
|
||||
This should be at most 16.
|
||||
ftb: The number of bits of precision in the cumulative distribution.
|
||||
This must be no more than 15.*/
|
||||
void od_ec_encode_cdf_unscaled_dyadic(od_ec_enc *enc, int s,
|
||||
const uint16_t *cdf, int nsyms,
|
||||
unsigned ftb) {
|
||||
(void)nsyms;
|
||||
OD_ASSERT(s >= 0);
|
||||
OD_ASSERT(s < nsyms);
|
||||
OD_ASSERT(ftb <= 15);
|
||||
OD_ASSERT(cdf[nsyms - 1] == 1U << ftb);
|
||||
od_ec_encode_q15(enc, s > 0 ? cdf[s - 1] << (15 - ftb) : 0,
|
||||
cdf[s] << (15 - ftb));
|
||||
}
|
||||
|
||||
/*Encodes a raw unsigned integer in the stream.
|
||||
fl: The integer to encode.
|
||||
ft: The number of integers that can be encoded (one more than the max).
|
||||
This must be at least 2, and no more than 2**29.*/
|
||||
void od_ec_enc_uint(od_ec_enc *enc, uint32_t fl, uint32_t ft) {
|
||||
OD_ASSERT(ft >= 2);
|
||||
OD_ASSERT(fl < ft);
|
||||
OD_ASSERT(ft <= (uint32_t)1 << (25 + OD_EC_UINT_BITS));
|
||||
if (ft > 1U << OD_EC_UINT_BITS) {
|
||||
int ft1;
|
||||
int ftb;
|
||||
ft--;
|
||||
ftb = OD_ILOG_NZ(ft) - OD_EC_UINT_BITS;
|
||||
ft1 = (int)(ft >> ftb) + 1;
|
||||
od_ec_encode_cdf_q15(enc, (int)(fl >> ftb), OD_UNIFORM_CDF_Q15(ft1), ft1);
|
||||
od_ec_enc_bits(enc, fl & (((uint32_t)1 << ftb) - 1), ftb);
|
||||
} else {
|
||||
od_ec_encode_cdf_q15(enc, (int)fl, OD_UNIFORM_CDF_Q15(ft), (int)ft);
|
||||
}
|
||||
}
|
||||
|
||||
/*Encodes a sequence of raw bits in the stream.
|
||||
fl: The bits to encode.
|
||||
ftb: The number of bits to encode.
|
||||
This must be between 0 and 25, inclusive.*/
|
||||
void od_ec_enc_bits(od_ec_enc *enc, uint32_t fl, unsigned ftb) {
|
||||
od_ec_window end_window;
|
||||
int nend_bits;
|
||||
OD_ASSERT(ftb <= 25);
|
||||
OD_ASSERT(fl < (uint32_t)1 << ftb);
|
||||
#if OD_MEASURE_EC_OVERHEAD
|
||||
enc->entropy += ftb;
|
||||
#endif
|
||||
end_window = enc->end_window;
|
||||
nend_bits = enc->nend_bits;
|
||||
if (nend_bits + ftb > OD_EC_WINDOW_SIZE) {
|
||||
unsigned char *buf;
|
||||
uint32_t storage;
|
||||
uint32_t end_offs;
|
||||
buf = enc->buf;
|
||||
storage = enc->storage;
|
||||
end_offs = enc->end_offs;
|
||||
if (end_offs + (OD_EC_WINDOW_SIZE >> 3) >= storage) {
|
||||
unsigned char *new_buf;
|
||||
uint32_t new_storage;
|
||||
new_storage = 2 * storage + (OD_EC_WINDOW_SIZE >> 3);
|
||||
new_buf = (unsigned char *)malloc(sizeof(*new_buf) * new_storage);
|
||||
if (new_buf == NULL) {
|
||||
enc->error = -1;
|
||||
enc->end_offs = 0;
|
||||
return;
|
||||
}
|
||||
OD_COPY(new_buf + new_storage - end_offs, buf + storage - end_offs,
|
||||
end_offs);
|
||||
storage = new_storage;
|
||||
free(buf);
|
||||
enc->buf = buf = new_buf;
|
||||
enc->storage = storage;
|
||||
}
|
||||
do {
|
||||
OD_ASSERT(end_offs < storage);
|
||||
buf[storage - ++end_offs] = (unsigned char)end_window;
|
||||
end_window >>= 8;
|
||||
nend_bits -= 8;
|
||||
} while (nend_bits >= 8);
|
||||
enc->end_offs = end_offs;
|
||||
}
|
||||
OD_ASSERT(nend_bits + ftb <= OD_EC_WINDOW_SIZE);
|
||||
end_window |= (od_ec_window)fl << nend_bits;
|
||||
nend_bits += ftb;
|
||||
enc->end_window = end_window;
|
||||
enc->nend_bits = nend_bits;
|
||||
}
|
||||
|
||||
/*Overwrites a few bits at the very start of an existing stream, after they
|
||||
have already been encoded.
|
||||
This makes it possible to have a few flags up front, where it is easy for
|
||||
decoders to access them without parsing the whole stream, even if their
|
||||
values are not determined until late in the encoding process, without having
|
||||
to buffer all the intermediate symbols in the encoder.
|
||||
In order for this to work, at least nbits bits must have already been encoded
|
||||
using probabilities that are an exact power of two.
|
||||
The encoder can verify the number of encoded bits is sufficient, but cannot
|
||||
check this latter condition.
|
||||
val: The bits to encode (in the least nbits significant bits).
|
||||
They will be decoded in order from most-significant to least.
|
||||
nbits: The number of bits to overwrite.
|
||||
This must be no more than 8.*/
|
||||
void od_ec_enc_patch_initial_bits(od_ec_enc *enc, unsigned val, int nbits) {
|
||||
int shift;
|
||||
unsigned mask;
|
||||
OD_ASSERT(nbits >= 0);
|
||||
OD_ASSERT(nbits <= 8);
|
||||
OD_ASSERT(val < 1U << nbits);
|
||||
shift = 8 - nbits;
|
||||
mask = ((1U << nbits) - 1) << shift;
|
||||
if (enc->offs > 0) {
|
||||
/*The first byte has been finalized.*/
|
||||
enc->precarry_buf[0] =
|
||||
(uint16_t)((enc->precarry_buf[0] & ~mask) | val << shift);
|
||||
} else if (9 + enc->cnt + (enc->rng == 0x8000) > nbits) {
|
||||
/*The first byte has yet to be output.*/
|
||||
enc->low = (enc->low & ~((od_ec_window)mask << (16 + enc->cnt))) |
|
||||
(od_ec_window)val << (16 + enc->cnt + shift);
|
||||
} else {
|
||||
/*The encoder hasn't even encoded _nbits of data yet.*/
|
||||
enc->error = -1;
|
||||
}
|
||||
}
|
||||
|
||||
#if OD_MEASURE_EC_OVERHEAD
|
||||
#include <stdio.h>
|
||||
#endif
|
||||
|
||||
/*Indicates that there are no more symbols to encode.
|
||||
All remaining output bytes are flushed to the output buffer.
|
||||
od_ec_enc_reset() should be called before using the encoder again.
|
||||
bytes: Returns the size of the encoded data in the returned buffer.
|
||||
Return: A pointer to the start of the final buffer, or NULL if there was an
|
||||
encoding error.*/
|
||||
unsigned char *od_ec_enc_done(od_ec_enc *enc, uint32_t *nbytes) {
|
||||
unsigned char *out;
|
||||
uint32_t storage;
|
||||
uint16_t *buf;
|
||||
uint32_t offs;
|
||||
uint32_t end_offs;
|
||||
int nend_bits;
|
||||
od_ec_window m;
|
||||
od_ec_window e;
|
||||
od_ec_window l;
|
||||
unsigned r;
|
||||
int c;
|
||||
int s;
|
||||
if (enc->error) return NULL;
|
||||
#if OD_MEASURE_EC_OVERHEAD
|
||||
{
|
||||
uint32_t tell;
|
||||
/* Don't count the 1 bit we lose to raw bits as overhead. */
|
||||
tell = od_ec_enc_tell(enc) - 1;
|
||||
fprintf(stderr, "overhead: %f%%\n",
|
||||
100 * (tell - enc->entropy) / enc->entropy);
|
||||
fprintf(stderr, "efficiency: %f bits/symbol\n",
|
||||
(double)tell / enc->nb_symbols);
|
||||
}
|
||||
#endif
|
||||
/*We output the minimum number of bits that ensures that the symbols encoded
|
||||
thus far will be decoded correctly regardless of the bits that follow.*/
|
||||
l = enc->low;
|
||||
r = enc->rng;
|
||||
c = enc->cnt;
|
||||
s = 9;
|
||||
m = 0x7FFF;
|
||||
e = (l + m) & ~m;
|
||||
while ((e | m) >= l + r) {
|
||||
s++;
|
||||
m >>= 1;
|
||||
e = (l + m) & ~m;
|
||||
}
|
||||
s += c;
|
||||
offs = enc->offs;
|
||||
buf = enc->precarry_buf;
|
||||
if (s > 0) {
|
||||
unsigned n;
|
||||
storage = enc->precarry_storage;
|
||||
if (offs + ((s + 7) >> 3) > storage) {
|
||||
storage = storage * 2 + ((s + 7) >> 3);
|
||||
buf = (uint16_t *)realloc(buf, sizeof(*buf) * storage);
|
||||
if (buf == NULL) {
|
||||
enc->error = -1;
|
||||
return NULL;
|
||||
}
|
||||
enc->precarry_buf = buf;
|
||||
enc->precarry_storage = storage;
|
||||
}
|
||||
n = (1 << (c + 16)) - 1;
|
||||
do {
|
||||
OD_ASSERT(offs < storage);
|
||||
buf[offs++] = (uint16_t)(e >> (c + 16));
|
||||
e &= n;
|
||||
s -= 8;
|
||||
c -= 8;
|
||||
n >>= 8;
|
||||
} while (s > 0);
|
||||
}
|
||||
/*Make sure there's enough room for the entropy-coded bits and the raw
|
||||
bits.*/
|
||||
out = enc->buf;
|
||||
storage = enc->storage;
|
||||
end_offs = enc->end_offs;
|
||||
e = enc->end_window;
|
||||
nend_bits = enc->nend_bits;
|
||||
s = -s;
|
||||
c = OD_MAXI((nend_bits - s + 7) >> 3, 0);
|
||||
if (offs + end_offs + c > storage) {
|
||||
storage = offs + end_offs + c;
|
||||
out = (unsigned char *)realloc(out, sizeof(*out) * storage);
|
||||
if (out == NULL) {
|
||||
enc->error = -1;
|
||||
return NULL;
|
||||
}
|
||||
OD_MOVE(out + storage - end_offs, out + enc->storage - end_offs, end_offs);
|
||||
enc->buf = out;
|
||||
enc->storage = storage;
|
||||
}
|
||||
/*If we have buffered raw bits, flush them as well.*/
|
||||
while (nend_bits > s) {
|
||||
OD_ASSERT(end_offs < storage);
|
||||
out[storage - ++end_offs] = (unsigned char)e;
|
||||
e >>= 8;
|
||||
nend_bits -= 8;
|
||||
}
|
||||
*nbytes = offs + end_offs;
|
||||
/*Perform carry propagation.*/
|
||||
OD_ASSERT(offs + end_offs <= storage);
|
||||
out = out + storage - (offs + end_offs);
|
||||
c = 0;
|
||||
end_offs = offs;
|
||||
while (offs-- > 0) {
|
||||
c = buf[offs] + c;
|
||||
out[offs] = (unsigned char)c;
|
||||
c >>= 8;
|
||||
}
|
||||
/*Add any remaining raw bits to the last byte.
|
||||
There is guaranteed to be enough room, because nend_bits <= s.*/
|
||||
OD_ASSERT(nend_bits <= 0 || end_offs > 0);
|
||||
if (nend_bits > 0) out[end_offs - 1] |= (unsigned char)e;
|
||||
/*Note: Unless there's an allocation error, if you keep encoding into the
|
||||
current buffer and call this function again later, everything will work
|
||||
just fine (you won't get a new packet out, but you will get a single
|
||||
buffer with the new data appended to the old).
|
||||
However, this function is O(N) where N is the amount of data coded so far,
|
||||
so calling it more than once for a given packet is a bad idea.*/
|
||||
return out;
|
||||
}
|
||||
|
||||
/*Returns the number of bits "used" by the encoded symbols so far.
|
||||
This same number can be computed in either the encoder or the decoder, and is
|
||||
suitable for making coding decisions.
|
||||
Warning: The value returned by this function can decrease compared to an
|
||||
earlier call, even after encoding more data, if there is an encoding error
|
||||
(i.e., a failure to allocate enough space for the output buffer).
|
||||
Return: The number of bits.
|
||||
This will always be slightly larger than the exact value (e.g., all
|
||||
rounding error is in the positive direction).*/
|
||||
int od_ec_enc_tell(const od_ec_enc *enc) {
|
||||
/*The 10 here counteracts the offset of -9 baked into cnt, and adds 1 extra
|
||||
bit, which we reserve for terminating the stream.*/
|
||||
return (enc->offs + enc->end_offs) * 8 + enc->cnt + enc->nend_bits + 10;
|
||||
}
|
||||
|
||||
/*Returns the number of bits "used" by the encoded symbols so far.
|
||||
This same number can be computed in either the encoder or the decoder, and is
|
||||
suitable for making coding decisions.
|
||||
Warning: The value returned by this function can decrease compared to an
|
||||
earlier call, even after encoding more data, if there is an encoding error
|
||||
(i.e., a failure to allocate enough space for the output buffer).
|
||||
Return: The number of bits scaled by 2**OD_BITRES.
|
||||
This will always be slightly larger than the exact value (e.g., all
|
||||
rounding error is in the positive direction).*/
|
||||
uint32_t od_ec_enc_tell_frac(const od_ec_enc *enc) {
|
||||
return od_ec_tell_frac(od_ec_enc_tell(enc), enc->rng);
|
||||
}
|
||||
|
||||
/*Saves a entropy coder checkpoint to dst.
|
||||
This allows an encoder to reverse a series of entropy coder
|
||||
decisions if it decides that the information would have been
|
||||
better coded some other way.*/
|
||||
void od_ec_enc_checkpoint(od_ec_enc *dst, const od_ec_enc *src) {
|
||||
OD_COPY(dst, src, 1);
|
||||
}
|
||||
|
||||
/*Restores an entropy coder checkpoint saved by od_ec_enc_checkpoint.
|
||||
This can only be used to restore from checkpoints earlier in the target
|
||||
state's history: you can not switch backwards and forwards or otherwise
|
||||
switch to a state which isn't a casual ancestor of the current state.
|
||||
Restore is also incompatible with patching the initial bits, as the
|
||||
changes will remain in the restored version.*/
|
||||
void od_ec_enc_rollback(od_ec_enc *dst, const od_ec_enc *src) {
|
||||
unsigned char *buf;
|
||||
uint32_t storage;
|
||||
uint16_t *precarry_buf;
|
||||
uint32_t precarry_storage;
|
||||
OD_ASSERT(dst->storage >= src->storage);
|
||||
OD_ASSERT(dst->precarry_storage >= src->precarry_storage);
|
||||
buf = dst->buf;
|
||||
storage = dst->storage;
|
||||
precarry_buf = dst->precarry_buf;
|
||||
precarry_storage = dst->precarry_storage;
|
||||
OD_COPY(dst, src, 1);
|
||||
dst->buf = buf;
|
||||
dst->storage = storage;
|
||||
dst->precarry_buf = precarry_buf;
|
||||
dst->precarry_storage = precarry_storage;
|
||||
}
|
||||
103
aom_dsp/entenc.h
103
aom_dsp/entenc.h
@@ -1,103 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2001-2016, Alliance for Open Media. All rights reserved
|
||||
*
|
||||
* This source code is subject to the terms of the BSD 2 Clause License and
|
||||
* the Alliance for Open Media Patent License 1.0. If the BSD 2 Clause License
|
||||
* was not distributed with this source code in the LICENSE file, you can
|
||||
* obtain it at www.aomedia.org/license/software. If the Alliance for Open
|
||||
* Media Patent License 1.0 was not distributed with this source code in the
|
||||
* PATENTS file, you can obtain it at www.aomedia.org/license/patent.
|
||||
*/
|
||||
|
||||
#if !defined(_entenc_H)
|
||||
#define _entenc_H (1)
|
||||
#include <stddef.h>
|
||||
#include "aom_dsp/entcode.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
typedef struct od_ec_enc od_ec_enc;
|
||||
|
||||
#define OD_MEASURE_EC_OVERHEAD (0)
|
||||
|
||||
/*The entropy encoder context.*/
|
||||
struct od_ec_enc {
|
||||
/*Buffered output.
|
||||
This contains only the raw bits until the final call to od_ec_enc_done(),
|
||||
where all the arithmetic-coded data gets prepended to it.*/
|
||||
unsigned char *buf;
|
||||
/*The size of the buffer.*/
|
||||
uint32_t storage;
|
||||
/*The offset at which the last byte containing raw bits was written.*/
|
||||
uint32_t end_offs;
|
||||
/*Bits that will be read from/written at the end.*/
|
||||
od_ec_window end_window;
|
||||
/*Number of valid bits in end_window.*/
|
||||
int nend_bits;
|
||||
/*A buffer for output bytes with their associated carry flags.*/
|
||||
uint16_t *precarry_buf;
|
||||
/*The size of the pre-carry buffer.*/
|
||||
uint32_t precarry_storage;
|
||||
/*The offset at which the next entropy-coded byte will be written.*/
|
||||
uint32_t offs;
|
||||
/*The low end of the current range.*/
|
||||
od_ec_window low;
|
||||
/*The number of values in the current range.*/
|
||||
uint16_t rng;
|
||||
/*The number of bits of data in the current value.*/
|
||||
int16_t cnt;
|
||||
/*Nonzero if an error occurred.*/
|
||||
int error;
|
||||
#if OD_MEASURE_EC_OVERHEAD
|
||||
double entropy;
|
||||
int nb_symbols;
|
||||
#endif
|
||||
};
|
||||
|
||||
/*See entenc.c for further documentation.*/
|
||||
|
||||
void od_ec_enc_init(od_ec_enc *enc, uint32_t size) OD_ARG_NONNULL(1);
|
||||
void od_ec_enc_reset(od_ec_enc *enc) OD_ARG_NONNULL(1);
|
||||
void od_ec_enc_clear(od_ec_enc *enc) OD_ARG_NONNULL(1);
|
||||
|
||||
void od_ec_encode_bool(od_ec_enc *enc, int val, unsigned fz, unsigned _ft)
|
||||
OD_ARG_NONNULL(1);
|
||||
void od_ec_encode_bool_q15(od_ec_enc *enc, int val, unsigned fz_q15)
|
||||
OD_ARG_NONNULL(1);
|
||||
void od_ec_encode_cdf(od_ec_enc *enc, int s, const uint16_t *cdf, int nsyms)
|
||||
OD_ARG_NONNULL(1) OD_ARG_NONNULL(3);
|
||||
void od_ec_encode_cdf_q15(od_ec_enc *enc, int s, const uint16_t *cdf, int nsyms)
|
||||
OD_ARG_NONNULL(1) OD_ARG_NONNULL(3);
|
||||
void od_ec_encode_cdf_unscaled(od_ec_enc *enc, int s, const uint16_t *cdf,
|
||||
int nsyms) OD_ARG_NONNULL(1) OD_ARG_NONNULL(3);
|
||||
void od_ec_encode_cdf_unscaled_dyadic(od_ec_enc *enc, int s,
|
||||
const uint16_t *cdf, int nsyms,
|
||||
unsigned ftb) OD_ARG_NONNULL(1)
|
||||
OD_ARG_NONNULL(3);
|
||||
|
||||
void od_ec_enc_uint(od_ec_enc *enc, uint32_t fl, uint32_t ft) OD_ARG_NONNULL(1);
|
||||
|
||||
void od_ec_enc_bits(od_ec_enc *enc, uint32_t fl, unsigned ftb)
|
||||
OD_ARG_NONNULL(1);
|
||||
|
||||
void od_ec_enc_patch_initial_bits(od_ec_enc *enc, unsigned val, int nbits)
|
||||
OD_ARG_NONNULL(1);
|
||||
OD_WARN_UNUSED_RESULT unsigned char *od_ec_enc_done(od_ec_enc *enc,
|
||||
uint32_t *nbytes)
|
||||
OD_ARG_NONNULL(1) OD_ARG_NONNULL(2);
|
||||
|
||||
OD_WARN_UNUSED_RESULT int od_ec_enc_tell(const od_ec_enc *enc)
|
||||
OD_ARG_NONNULL(1);
|
||||
OD_WARN_UNUSED_RESULT uint32_t od_ec_enc_tell_frac(const od_ec_enc *enc)
|
||||
OD_ARG_NONNULL(1);
|
||||
|
||||
void od_ec_enc_checkpoint(od_ec_enc *dst, const od_ec_enc *src);
|
||||
void od_ec_enc_rollback(od_ec_enc *dst, const od_ec_enc *src);
|
||||
|
||||
#ifdef __cplusplus
|
||||
} // extern "C"
|
||||
#endif
|
||||
|
||||
#endif
|
||||
@@ -1,26 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2016, Alliance for Open Media. All rights reserved
|
||||
*
|
||||
* This source code is subject to the terms of the BSD 2 Clause License and
|
||||
* the Alliance for Open Media Patent License 1.0. If the BSD 2 Clause License
|
||||
* was not distributed with this source code in the LICENSE file, you can
|
||||
* obtain it at www.aomedia.org/license/software. If the Alliance for Open
|
||||
* Media Patent License 1.0 was not distributed with this source code in the
|
||||
* PATENTS file, you can obtain it at www.aomedia.org/license/patent.
|
||||
*/
|
||||
|
||||
#ifndef AOM_DSP_FWD_TXFM_H_
|
||||
#define AOM_DSP_FWD_TXFM_H_
|
||||
|
||||
#include "aom_dsp/txfm_common.h"
|
||||
|
||||
static INLINE tran_high_t fdct_round_shift(tran_high_t input) {
|
||||
tran_high_t rv = ROUND_POWER_OF_TWO(input, DCT_CONST_BITS);
|
||||
// TODO(debargha, peter.derivaz): Find new bounds for this assert
|
||||
// and make the bounds consts.
|
||||
// assert(INT16_MIN <= rv && rv <= INT16_MAX);
|
||||
return rv;
|
||||
}
|
||||
|
||||
void aom_fdct32(const tran_high_t *input, tran_high_t *output, int round);
|
||||
#endif // AOM_DSP_FWD_TXFM_H_
|
||||
@@ -1,59 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2015 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 "./macros_msa.h"
|
||||
|
||||
void aom_plane_add_noise_msa(uint8_t *start_ptr, char *noise,
|
||||
char blackclamp[16], char whiteclamp[16],
|
||||
char bothclamp[16], uint32_t width,
|
||||
uint32_t height, int32_t pitch) {
|
||||
uint32_t i, j;
|
||||
|
||||
for (i = 0; i < height / 2; ++i) {
|
||||
uint8_t *pos0_ptr = start_ptr + (2 * i) * pitch;
|
||||
int8_t *ref0_ptr = (int8_t *)(noise + (rand() & 0xff));
|
||||
uint8_t *pos1_ptr = start_ptr + (2 * i + 1) * pitch;
|
||||
int8_t *ref1_ptr = (int8_t *)(noise + (rand() & 0xff));
|
||||
for (j = width / 16; j--;) {
|
||||
v16i8 temp00_s, temp01_s;
|
||||
v16u8 temp00, temp01, black_clamp, white_clamp;
|
||||
v16u8 pos0, ref0, pos1, ref1;
|
||||
v16i8 const127 = __msa_ldi_b(127);
|
||||
|
||||
pos0 = LD_UB(pos0_ptr);
|
||||
ref0 = LD_UB(ref0_ptr);
|
||||
pos1 = LD_UB(pos1_ptr);
|
||||
ref1 = LD_UB(ref1_ptr);
|
||||
black_clamp = (v16u8)__msa_fill_b(blackclamp[0]);
|
||||
white_clamp = (v16u8)__msa_fill_b(whiteclamp[0]);
|
||||
temp00 = (pos0 < black_clamp);
|
||||
pos0 = __msa_bmnz_v(pos0, black_clamp, temp00);
|
||||
temp01 = (pos1 < black_clamp);
|
||||
pos1 = __msa_bmnz_v(pos1, black_clamp, temp01);
|
||||
XORI_B2_128_UB(pos0, pos1);
|
||||
temp00_s = __msa_adds_s_b((v16i8)white_clamp, const127);
|
||||
temp00 = (v16u8)(temp00_s < pos0);
|
||||
pos0 = (v16u8)__msa_bmnz_v((v16u8)pos0, (v16u8)temp00_s, temp00);
|
||||
temp01_s = __msa_adds_s_b((v16i8)white_clamp, const127);
|
||||
temp01 = (temp01_s < pos1);
|
||||
pos1 = (v16u8)__msa_bmnz_v((v16u8)pos1, (v16u8)temp01_s, temp01);
|
||||
XORI_B2_128_UB(pos0, pos1);
|
||||
pos0 += ref0;
|
||||
ST_UB(pos0, pos0_ptr);
|
||||
pos1 += ref1;
|
||||
ST_UB(pos1, pos1_ptr);
|
||||
pos0_ptr += 16;
|
||||
pos1_ptr += 16;
|
||||
ref0_ptr += 16;
|
||||
ref1_ptr += 16;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,31 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2016, Alliance for Open Media. All rights reserved
|
||||
*
|
||||
* This source code is subject to the terms of the BSD 2 Clause License and
|
||||
* the Alliance for Open Media Patent License 1.0. If the BSD 2 Clause License
|
||||
* was not distributed with this source code in the LICENSE file, you can
|
||||
* obtain it at www.aomedia.org/license/software. If the Alliance for Open
|
||||
* Media Patent License 1.0 was not distributed with this source code in the
|
||||
* PATENTS file, you can obtain it at www.aomedia.org/license/patent.
|
||||
*/
|
||||
|
||||
#include "aom_dsp/mips/common_dspr2.h"
|
||||
|
||||
#if HAVE_DSPR2
|
||||
uint8_t aom_ff_cropTbl_a[256 + 2 * CROP_WIDTH];
|
||||
uint8_t *aom_ff_cropTbl;
|
||||
|
||||
void aom_dsputil_static_init(void) {
|
||||
int i;
|
||||
|
||||
for (i = 0; i < 256; i++) aom_ff_cropTbl_a[i + CROP_WIDTH] = i;
|
||||
|
||||
for (i = 0; i < CROP_WIDTH; i++) {
|
||||
aom_ff_cropTbl_a[i] = 0;
|
||||
aom_ff_cropTbl_a[i + CROP_WIDTH + 256] = 255;
|
||||
}
|
||||
|
||||
aom_ff_cropTbl = &aom_ff_cropTbl_a[CROP_WIDTH];
|
||||
}
|
||||
|
||||
#endif
|
||||
226
aom_dsp/prob.c
226
aom_dsp/prob.c
@@ -1,226 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2016, Alliance for Open Media. All rights reserved
|
||||
*
|
||||
* This source code is subject to the terms of the BSD 2 Clause License and
|
||||
* the Alliance for Open Media Patent License 1.0. If the BSD 2 Clause License
|
||||
* was not distributed with this source code in the LICENSE file, you can
|
||||
* obtain it at www.aomedia.org/license/software. If the Alliance for Open
|
||||
* Media Patent License 1.0 was not distributed with this source code in the
|
||||
* PATENTS file, you can obtain it at www.aomedia.org/license/patent.
|
||||
*/
|
||||
|
||||
#include "./aom_config.h"
|
||||
|
||||
#if CONFIG_EC_MULTISYMBOL
|
||||
#include <string.h>
|
||||
#endif
|
||||
|
||||
#include "aom_dsp/prob.h"
|
||||
|
||||
#if CONFIG_DAALA_EC
|
||||
#include "aom_dsp/entcode.h"
|
||||
#endif
|
||||
|
||||
const uint8_t aom_norm[256] = {
|
||||
0, 7, 6, 6, 5, 5, 5, 5, 4, 4, 4, 4, 4, 4, 4, 4, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
|
||||
3, 3, 3, 3, 3, 3, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
|
||||
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
|
||||
};
|
||||
|
||||
static unsigned int tree_merge_probs_impl(unsigned int i,
|
||||
const aom_tree_index *tree,
|
||||
const aom_prob *pre_probs,
|
||||
const unsigned int *counts,
|
||||
aom_prob *probs) {
|
||||
const int l = tree[i];
|
||||
const unsigned int left_count =
|
||||
(l <= 0) ? counts[-l]
|
||||
: tree_merge_probs_impl(l, tree, pre_probs, counts, probs);
|
||||
const int r = tree[i + 1];
|
||||
const unsigned int right_count =
|
||||
(r <= 0) ? counts[-r]
|
||||
: tree_merge_probs_impl(r, tree, pre_probs, counts, probs);
|
||||
const unsigned int ct[2] = { left_count, right_count };
|
||||
probs[i >> 1] = mode_mv_merge_probs(pre_probs[i >> 1], ct);
|
||||
return left_count + right_count;
|
||||
}
|
||||
|
||||
void aom_tree_merge_probs(const aom_tree_index *tree, const aom_prob *pre_probs,
|
||||
const unsigned int *counts, aom_prob *probs) {
|
||||
tree_merge_probs_impl(0, tree, pre_probs, counts, probs);
|
||||
}
|
||||
|
||||
#if CONFIG_EC_MULTISYMBOL
|
||||
typedef struct tree_node tree_node;
|
||||
|
||||
struct tree_node {
|
||||
aom_tree_index index;
|
||||
uint8_t probs[16];
|
||||
uint8_t prob;
|
||||
int path;
|
||||
int len;
|
||||
int l;
|
||||
int r;
|
||||
aom_cdf_prob pdf;
|
||||
};
|
||||
|
||||
/* Compute the probability of this node in Q23 */
|
||||
static uint32_t tree_node_prob(tree_node n, int i) {
|
||||
uint32_t prob;
|
||||
/* 1.0 in Q23 */
|
||||
prob = 16777216;
|
||||
for (; i < n.len; i++) {
|
||||
prob = prob * n.probs[i] >> 8;
|
||||
}
|
||||
return prob;
|
||||
}
|
||||
|
||||
static int tree_node_cmp(tree_node a, tree_node b) {
|
||||
int i;
|
||||
uint32_t pa;
|
||||
uint32_t pb;
|
||||
for (i = 0; i < AOMMIN(a.len, b.len) && a.probs[i] == b.probs[i]; i++) {
|
||||
}
|
||||
pa = tree_node_prob(a, i);
|
||||
pb = tree_node_prob(b, i);
|
||||
return pa > pb ? 1 : pa < pb ? -1 : 0;
|
||||
}
|
||||
|
||||
/* Given a Q15 probability for symbol subtree rooted at tree[n], this function
|
||||
computes the probability of each symbol (defined as a node that has no
|
||||
children). */
|
||||
static aom_cdf_prob tree_node_compute_probs(tree_node *tree, int n,
|
||||
aom_cdf_prob pdf) {
|
||||
if (tree[n].l == 0) {
|
||||
/* This prevents probability computations in Q15 that underflow from
|
||||
producing a symbol that has zero probability. */
|
||||
if (pdf == 0) pdf = 1;
|
||||
tree[n].pdf = pdf;
|
||||
return pdf;
|
||||
} else {
|
||||
/* We process the smaller probability first, */
|
||||
if (tree[n].prob < 128) {
|
||||
aom_cdf_prob lp;
|
||||
aom_cdf_prob rp;
|
||||
lp = (((uint32_t)pdf) * tree[n].prob + 128) >> 8;
|
||||
lp = tree_node_compute_probs(tree, tree[n].l, lp);
|
||||
rp = tree_node_compute_probs(tree, tree[n].r, lp > pdf ? 0 : pdf - lp);
|
||||
return lp + rp;
|
||||
} else {
|
||||
aom_cdf_prob rp;
|
||||
aom_cdf_prob lp;
|
||||
rp = (((uint32_t)pdf) * (256 - tree[n].prob) + 128) >> 8;
|
||||
rp = tree_node_compute_probs(tree, tree[n].r, rp);
|
||||
lp = tree_node_compute_probs(tree, tree[n].l, rp > pdf ? 0 : pdf - rp);
|
||||
return lp + rp;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static int tree_node_extract(tree_node *tree, int n, int symb,
|
||||
aom_cdf_prob *pdf, aom_tree_index *index,
|
||||
int *path, int *len) {
|
||||
if (tree[n].l == 0) {
|
||||
pdf[symb] = tree[n].pdf;
|
||||
if (index != NULL) index[symb] = tree[n].index;
|
||||
if (path != NULL) path[symb] = tree[n].path;
|
||||
if (len != NULL) len[symb] = tree[n].len;
|
||||
return symb + 1;
|
||||
} else {
|
||||
symb = tree_node_extract(tree, tree[n].l, symb, pdf, index, path, len);
|
||||
return tree_node_extract(tree, tree[n].r, symb, pdf, index, path, len);
|
||||
}
|
||||
}
|
||||
|
||||
int tree_to_cdf(const aom_tree_index *tree, const aom_prob *probs,
|
||||
aom_tree_index root, aom_cdf_prob *cdf, aom_tree_index *index,
|
||||
int *path, int *len) {
|
||||
tree_node symb[2 * 16 - 1];
|
||||
int nodes;
|
||||
int next[16];
|
||||
int size;
|
||||
int nsymbs;
|
||||
int i;
|
||||
/* Create the root node with probability 1 in Q15. */
|
||||
symb[0].index = root;
|
||||
symb[0].path = 0;
|
||||
symb[0].len = 0;
|
||||
symb[0].l = symb[0].r = 0;
|
||||
nodes = 1;
|
||||
next[0] = 0;
|
||||
size = 1;
|
||||
nsymbs = 1;
|
||||
while (size > 0 && nsymbs < 16) {
|
||||
int m;
|
||||
tree_node n;
|
||||
aom_tree_index j;
|
||||
uint8_t prob;
|
||||
m = 0;
|
||||
/* Find the internal node with the largest probability. */
|
||||
for (i = 1; i < size; i++) {
|
||||
if (tree_node_cmp(symb[next[i]], symb[next[m]]) > 0) m = i;
|
||||
}
|
||||
i = next[m];
|
||||
memmove(&next[m], &next[m + 1], sizeof(*next) * (size - (m + 1)));
|
||||
size--;
|
||||
/* Split this symbol into two symbols */
|
||||
n = symb[i];
|
||||
j = n.index;
|
||||
prob = probs[j >> 1];
|
||||
/* Left */
|
||||
n.index = tree[j];
|
||||
n.path <<= 1;
|
||||
n.len++;
|
||||
n.probs[n.len - 1] = prob;
|
||||
symb[nodes] = n;
|
||||
if (n.index > 0) {
|
||||
next[size++] = nodes;
|
||||
}
|
||||
/* Right */
|
||||
n.index = tree[j + 1];
|
||||
n.path += 1;
|
||||
n.probs[n.len - 1] = 256 - prob;
|
||||
symb[nodes + 1] = n;
|
||||
if (n.index > 0) {
|
||||
next[size++] = nodes + 1;
|
||||
}
|
||||
symb[i].prob = prob;
|
||||
symb[i].l = nodes;
|
||||
symb[i].r = nodes + 1;
|
||||
nodes += 2;
|
||||
nsymbs++;
|
||||
}
|
||||
/* Compute the probabilities of each symbol in Q15 */
|
||||
tree_node_compute_probs(symb, 0, 32768);
|
||||
/* Extract the cdf, index, path and length */
|
||||
tree_node_extract(symb, 0, 0, cdf, index, path, len);
|
||||
/* Convert to CDF */
|
||||
for (i = 1; i < nsymbs; i++) {
|
||||
cdf[i] = cdf[i - 1] + cdf[i];
|
||||
}
|
||||
return nsymbs;
|
||||
}
|
||||
|
||||
/* This code assumes that tree contains as unique leaf nodes the integer values
|
||||
0 to len - 1 and produces the forward and inverse mapping tables in ind[]
|
||||
and inv[] respectively. */
|
||||
void av1_indices_from_tree(int *ind, int *inv, int len,
|
||||
const aom_tree_index *tree) {
|
||||
int i;
|
||||
int index;
|
||||
for (i = index = 0; i < TREE_SIZE(len); i++) {
|
||||
const aom_tree_index j = tree[i];
|
||||
if (j <= 0) {
|
||||
inv[index] = -j;
|
||||
ind[-j] = index++;
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
158
aom_dsp/prob.h
158
aom_dsp/prob.h
@@ -1,158 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2016, Alliance for Open Media. All rights reserved
|
||||
*
|
||||
* This source code is subject to the terms of the BSD 2 Clause License and
|
||||
* the Alliance for Open Media Patent License 1.0. If the BSD 2 Clause License
|
||||
* was not distributed with this source code in the LICENSE file, you can
|
||||
* obtain it at www.aomedia.org/license/software. If the Alliance for Open
|
||||
* Media Patent License 1.0 was not distributed with this source code in the
|
||||
* PATENTS file, you can obtain it at www.aomedia.org/license/patent.
|
||||
*/
|
||||
|
||||
#ifndef AOM_DSP_PROB_H_
|
||||
#define AOM_DSP_PROB_H_
|
||||
|
||||
#include "./aom_config.h"
|
||||
#include "./aom_dsp_common.h"
|
||||
|
||||
#include "aom_ports/bitops.h"
|
||||
#include "aom_ports/mem.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
typedef uint8_t aom_prob;
|
||||
|
||||
// TODO(negge): Rename this aom_prob once we remove vpxbool.
|
||||
typedef uint16_t aom_cdf_prob;
|
||||
|
||||
#define MAX_PROB 255
|
||||
|
||||
#define aom_prob_half ((aom_prob)128)
|
||||
|
||||
typedef int8_t aom_tree_index;
|
||||
|
||||
#define TREE_SIZE(leaf_count) (-2 + 2 * (leaf_count))
|
||||
|
||||
#define aom_complement(x) (255 - x)
|
||||
|
||||
#define MODE_MV_COUNT_SAT 20
|
||||
|
||||
/* We build coding trees compactly in arrays.
|
||||
Each node of the tree is a pair of aom_tree_indices.
|
||||
Array index often references a corresponding probability table.
|
||||
Index <= 0 means done encoding/decoding and value = -Index,
|
||||
Index > 0 means need another bit, specification at index.
|
||||
Nonnegative indices are always even; processing begins at node 0. */
|
||||
|
||||
typedef const aom_tree_index aom_tree[];
|
||||
|
||||
static INLINE aom_prob clip_prob(int p) {
|
||||
return (p > 255) ? 255 : (p < 1) ? 1 : p;
|
||||
}
|
||||
|
||||
static INLINE aom_prob get_prob(int num, int den) {
|
||||
return (den == 0) ? 128u : clip_prob(((int64_t)num * 256 + (den >> 1)) / den);
|
||||
}
|
||||
|
||||
static INLINE aom_prob get_binary_prob(int n0, int n1) {
|
||||
return get_prob(n0, n0 + n1);
|
||||
}
|
||||
|
||||
/* This function assumes prob1 and prob2 are already within [1,255] range. */
|
||||
static INLINE aom_prob weighted_prob(int prob1, int prob2, int factor) {
|
||||
return ROUND_POWER_OF_TWO(prob1 * (256 - factor) + prob2 * factor, 8);
|
||||
}
|
||||
|
||||
static INLINE aom_prob merge_probs(aom_prob pre_prob, const unsigned int ct[2],
|
||||
unsigned int count_sat,
|
||||
unsigned int max_update_factor) {
|
||||
const aom_prob prob = get_binary_prob(ct[0], ct[1]);
|
||||
const unsigned int count = AOMMIN(ct[0] + ct[1], count_sat);
|
||||
const unsigned int factor = max_update_factor * count / count_sat;
|
||||
return weighted_prob(pre_prob, prob, factor);
|
||||
}
|
||||
|
||||
// MODE_MV_MAX_UPDATE_FACTOR (128) * count / MODE_MV_COUNT_SAT;
|
||||
static const int count_to_update_factor[MODE_MV_COUNT_SAT + 1] = {
|
||||
0, 6, 12, 19, 25, 32, 38, 44, 51, 57, 64,
|
||||
70, 76, 83, 89, 96, 102, 108, 115, 121, 128
|
||||
};
|
||||
|
||||
static INLINE aom_prob mode_mv_merge_probs(aom_prob pre_prob,
|
||||
const unsigned int ct[2]) {
|
||||
const unsigned int den = ct[0] + ct[1];
|
||||
if (den == 0) {
|
||||
return pre_prob;
|
||||
} else {
|
||||
const unsigned int count = AOMMIN(den, MODE_MV_COUNT_SAT);
|
||||
const unsigned int factor = count_to_update_factor[count];
|
||||
const aom_prob prob =
|
||||
clip_prob(((int64_t)(ct[0]) * 256 + (den >> 1)) / den);
|
||||
return weighted_prob(pre_prob, prob, factor);
|
||||
}
|
||||
}
|
||||
|
||||
void aom_tree_merge_probs(const aom_tree_index *tree, const aom_prob *pre_probs,
|
||||
const unsigned int *counts, aom_prob *probs);
|
||||
|
||||
#if CONFIG_EC_MULTISYMBOL
|
||||
int tree_to_cdf(const aom_tree_index *tree, const aom_prob *probs,
|
||||
aom_tree_index root, aom_cdf_prob *cdf, aom_tree_index *ind,
|
||||
int *pth, int *len);
|
||||
|
||||
static INLINE void av1_tree_to_cdf(const aom_tree_index *tree,
|
||||
const aom_prob *probs, aom_cdf_prob *cdf) {
|
||||
aom_tree_index index[16];
|
||||
int path[16];
|
||||
int dist[16];
|
||||
tree_to_cdf(tree, probs, 0, cdf, index, path, dist);
|
||||
}
|
||||
|
||||
#define av1_tree_to_cdf_1D(tree, probs, cdf, u) \
|
||||
do { \
|
||||
int i; \
|
||||
for (i = 0; i < u; i++) { \
|
||||
av1_tree_to_cdf(tree, probs[i], cdf[i]); \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
#define av1_tree_to_cdf_2D(tree, probs, cdf, v, u) \
|
||||
do { \
|
||||
int j; \
|
||||
int i; \
|
||||
for (j = 0; j < v; j++) { \
|
||||
for (i = 0; i < u; i++) { \
|
||||
av1_tree_to_cdf(tree, probs[j][i], cdf[j][i]); \
|
||||
} \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
void av1_indices_from_tree(int *ind, int *inv, int len,
|
||||
const aom_tree_index *tree);
|
||||
#endif
|
||||
|
||||
DECLARE_ALIGNED(16, extern const uint8_t, aom_norm[256]);
|
||||
|
||||
#if CONFIG_EC_ADAPT
|
||||
static INLINE void update_cdf(aom_cdf_prob *cdf, int val, int nsymbs) {
|
||||
const int rate = 4 + get_msb(nsymbs);
|
||||
int i, diff, tmp;
|
||||
for (i = 0; i < nsymbs; ++i) {
|
||||
tmp = (i + 1) << (12 - rate);
|
||||
cdf[i] -= ((cdf[i] - tmp) >> rate);
|
||||
}
|
||||
diff = 32768 - cdf[nsymbs - 1];
|
||||
|
||||
for (i = val; i < nsymbs; ++i) {
|
||||
cdf[i] += diff;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
} // extern "C"
|
||||
#endif
|
||||
|
||||
#endif // AOM_DSP_PROB_H_
|
||||
@@ -1,67 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2016, Alliance for Open Media. All rights reserved
|
||||
*
|
||||
* This source code is subject to the terms of the BSD 2 Clause License and
|
||||
* the Alliance for Open Media Patent License 1.0. If the BSD 2 Clause License
|
||||
* was not distributed with this source code in the LICENSE file, you can
|
||||
* obtain it at www.aomedia.org/license/software. If the Alliance for Open
|
||||
* Media Patent License 1.0 was not distributed with this source code in the
|
||||
* PATENTS file, you can obtain it at www.aomedia.org/license/patent.
|
||||
*/
|
||||
|
||||
#ifndef AOM_DSP_PSNR_H_
|
||||
#define AOM_DSP_PSNR_H_
|
||||
|
||||
#include "aom_scale/yv12config.h"
|
||||
|
||||
#define MAX_PSNR 100.0
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
typedef struct {
|
||||
double psnr[4]; // total/y/u/v
|
||||
uint64_t sse[4]; // total/y/u/v
|
||||
uint32_t samples[4]; // total/y/u/v
|
||||
} PSNR_STATS;
|
||||
|
||||
/*!\brief Converts SSE to PSNR
|
||||
*
|
||||
* Converts sum of squared errros (SSE) to peak signal-to-noise ratio (PNSR).
|
||||
*
|
||||
* \param[in] samples Number of samples
|
||||
* \param[in] peak Max sample value
|
||||
* \param[in] sse Sum of squared errors
|
||||
*/
|
||||
double aom_sse_to_psnr(double samples, double peak, double sse);
|
||||
int64_t aom_get_y_sse_part(const YV12_BUFFER_CONFIG *a,
|
||||
const YV12_BUFFER_CONFIG *b, int hstart, int width,
|
||||
int vstart, int height);
|
||||
int64_t aom_get_y_sse(const YV12_BUFFER_CONFIG *a, const YV12_BUFFER_CONFIG *b);
|
||||
int64_t aom_get_u_sse(const YV12_BUFFER_CONFIG *a, const YV12_BUFFER_CONFIG *b);
|
||||
int64_t aom_get_v_sse(const YV12_BUFFER_CONFIG *a, const YV12_BUFFER_CONFIG *b);
|
||||
#if CONFIG_AOM_HIGHBITDEPTH
|
||||
int64_t aom_highbd_get_y_sse_part(const YV12_BUFFER_CONFIG *a,
|
||||
const YV12_BUFFER_CONFIG *b, int hstart,
|
||||
int width, int vstart, int height);
|
||||
int64_t aom_highbd_get_y_sse(const YV12_BUFFER_CONFIG *a,
|
||||
const YV12_BUFFER_CONFIG *b);
|
||||
int64_t aom_highbd_get_u_sse(const YV12_BUFFER_CONFIG *a,
|
||||
const YV12_BUFFER_CONFIG *b);
|
||||
int64_t aom_highbd_get_v_sse(const YV12_BUFFER_CONFIG *a,
|
||||
const YV12_BUFFER_CONFIG *b);
|
||||
void aom_calc_highbd_psnr(const YV12_BUFFER_CONFIG *a,
|
||||
const YV12_BUFFER_CONFIG *b, PSNR_STATS *psnr,
|
||||
unsigned int bit_depth, unsigned int in_bit_depth);
|
||||
#endif
|
||||
void aom_calc_psnr(const YV12_BUFFER_CONFIG *a, const YV12_BUFFER_CONFIG *b,
|
||||
PSNR_STATS *psnr);
|
||||
|
||||
double aom_psnrhvs(const YV12_BUFFER_CONFIG *source,
|
||||
const YV12_BUFFER_CONFIG *dest, double *phvs_y,
|
||||
double *phvs_u, double *phvs_v, uint32_t bd, uint32_t in_bd);
|
||||
#ifdef __cplusplus
|
||||
} // extern "C"
|
||||
#endif
|
||||
#endif // AOM_DSP_PSNR_H_
|
||||
@@ -1,686 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2016, Alliance for Open Media. All rights reserved
|
||||
*
|
||||
* This source code is subject to the terms of the BSD 2 Clause License and
|
||||
* the Alliance for Open Media Patent License 1.0. If the BSD 2 Clause License
|
||||
* was not distributed with this source code in the LICENSE file, you can
|
||||
* obtain it at www.aomedia.org/license/software. If the Alliance for Open
|
||||
* Media Patent License 1.0 was not distributed with this source code in the
|
||||
* PATENTS file, you can obtain it at www.aomedia.org/license/patent.
|
||||
*/
|
||||
|
||||
#include "aom_dsp/quantize.h"
|
||||
#include "aom_mem/aom_mem.h"
|
||||
|
||||
#if CONFIG_AOM_QM
|
||||
void aom_quantize_dc(const tran_low_t *coeff_ptr, int n_coeffs, int skip_block,
|
||||
const int16_t *round_ptr, const int16_t quant,
|
||||
tran_low_t *qcoeff_ptr, tran_low_t *dqcoeff_ptr,
|
||||
const int16_t dequant_ptr, uint16_t *eob_ptr,
|
||||
const qm_val_t *qm_ptr, const qm_val_t *iqm_ptr) {
|
||||
const int rc = 0;
|
||||
const int coeff = coeff_ptr[rc];
|
||||
const int coeff_sign = (coeff >> 31);
|
||||
const int abs_coeff = (coeff ^ coeff_sign) - coeff_sign;
|
||||
int64_t tmp, eob = -1;
|
||||
int32_t tmp32;
|
||||
int dequant =
|
||||
(dequant_ptr * iqm_ptr[rc] + (1 << (AOM_QM_BITS - 1))) >> AOM_QM_BITS;
|
||||
|
||||
memset(qcoeff_ptr, 0, n_coeffs * sizeof(*qcoeff_ptr));
|
||||
memset(dqcoeff_ptr, 0, n_coeffs * sizeof(*dqcoeff_ptr));
|
||||
|
||||
if (!skip_block) {
|
||||
tmp = clamp(abs_coeff + round_ptr[rc != 0], INT16_MIN, INT16_MAX);
|
||||
tmp32 = (int32_t)((tmp * qm_ptr[rc] * quant) >> (16 + AOM_QM_BITS));
|
||||
qcoeff_ptr[rc] = (tmp32 ^ coeff_sign) - coeff_sign;
|
||||
dqcoeff_ptr[rc] = qcoeff_ptr[rc] * dequant;
|
||||
if (tmp32) eob = 0;
|
||||
}
|
||||
*eob_ptr = eob + 1;
|
||||
}
|
||||
|
||||
#if CONFIG_AOM_HIGHBITDEPTH
|
||||
void aom_highbd_quantize_dc(const tran_low_t *coeff_ptr, int n_coeffs,
|
||||
int skip_block, const int16_t *round_ptr,
|
||||
const int16_t quant, tran_low_t *qcoeff_ptr,
|
||||
tran_low_t *dqcoeff_ptr, const int16_t dequant_ptr,
|
||||
uint16_t *eob_ptr, const qm_val_t *qm_ptr,
|
||||
const qm_val_t *iqm_ptr) {
|
||||
int eob = -1;
|
||||
int dequant =
|
||||
(dequant_ptr * iqm_ptr[0] + (1 << (AOM_QM_BITS - 1))) >> AOM_QM_BITS;
|
||||
|
||||
memset(qcoeff_ptr, 0, n_coeffs * sizeof(*qcoeff_ptr));
|
||||
memset(dqcoeff_ptr, 0, n_coeffs * sizeof(*dqcoeff_ptr));
|
||||
|
||||
if (!skip_block) {
|
||||
const int coeff = coeff_ptr[0];
|
||||
const int coeff_sign = (coeff >> 31);
|
||||
const int abs_coeff = (coeff ^ coeff_sign) - coeff_sign;
|
||||
const int64_t tmp = abs_coeff + round_ptr[0];
|
||||
const uint32_t abs_qcoeff =
|
||||
(uint32_t)((tmp * qm_ptr[0] * quant) >> (16 + AOM_QM_BITS));
|
||||
qcoeff_ptr[0] = (tran_low_t)((abs_qcoeff ^ coeff_sign) - coeff_sign);
|
||||
dqcoeff_ptr[0] = qcoeff_ptr[0] * dequant;
|
||||
if (abs_qcoeff) eob = 0;
|
||||
}
|
||||
*eob_ptr = eob + 1;
|
||||
}
|
||||
#endif
|
||||
|
||||
void aom_quantize_dc_32x32(const tran_low_t *coeff_ptr, int skip_block,
|
||||
const int16_t *round_ptr, const int16_t quant,
|
||||
tran_low_t *qcoeff_ptr, tran_low_t *dqcoeff_ptr,
|
||||
const int16_t dequant_ptr, uint16_t *eob_ptr,
|
||||
const qm_val_t *qm_ptr, const qm_val_t *iqm_ptr) {
|
||||
const int n_coeffs = 1024;
|
||||
const int rc = 0;
|
||||
const int coeff = coeff_ptr[rc];
|
||||
const int coeff_sign = (coeff >> 31);
|
||||
const int abs_coeff = (coeff ^ coeff_sign) - coeff_sign;
|
||||
int64_t tmp, eob = -1;
|
||||
int32_t tmp32;
|
||||
int dequant;
|
||||
|
||||
memset(qcoeff_ptr, 0, n_coeffs * sizeof(*qcoeff_ptr));
|
||||
memset(dqcoeff_ptr, 0, n_coeffs * sizeof(*dqcoeff_ptr));
|
||||
|
||||
if (!skip_block) {
|
||||
tmp = clamp(abs_coeff + ROUND_POWER_OF_TWO(round_ptr[rc != 0], 1),
|
||||
INT16_MIN, INT16_MAX);
|
||||
tmp32 = (int32_t)((tmp * qm_ptr[rc] * quant) >> (15 + AOM_QM_BITS));
|
||||
qcoeff_ptr[rc] = (tmp32 ^ coeff_sign) - coeff_sign;
|
||||
dequant =
|
||||
(dequant_ptr * iqm_ptr[rc] + (1 << (AOM_QM_BITS - 1))) >> AOM_QM_BITS;
|
||||
dqcoeff_ptr[rc] = (qcoeff_ptr[rc] * dequant) / 2;
|
||||
if (tmp32) eob = 0;
|
||||
}
|
||||
*eob_ptr = eob + 1;
|
||||
}
|
||||
|
||||
#if CONFIG_AOM_HIGHBITDEPTH
|
||||
void aom_highbd_quantize_dc_32x32(const tran_low_t *coeff_ptr, int skip_block,
|
||||
const int16_t *round_ptr, const int16_t quant,
|
||||
tran_low_t *qcoeff_ptr,
|
||||
tran_low_t *dqcoeff_ptr,
|
||||
const int16_t dequant_ptr, uint16_t *eob_ptr,
|
||||
const qm_val_t *qm_ptr,
|
||||
const qm_val_t *iqm_ptr) {
|
||||
const int n_coeffs = 1024;
|
||||
int eob = -1;
|
||||
int dequant;
|
||||
|
||||
memset(qcoeff_ptr, 0, n_coeffs * sizeof(*qcoeff_ptr));
|
||||
memset(dqcoeff_ptr, 0, n_coeffs * sizeof(*dqcoeff_ptr));
|
||||
|
||||
if (!skip_block) {
|
||||
const int coeff = coeff_ptr[0];
|
||||
const int coeff_sign = (coeff >> 31);
|
||||
const int abs_coeff = (coeff ^ coeff_sign) - coeff_sign;
|
||||
const int64_t tmp = abs_coeff + ROUND_POWER_OF_TWO(round_ptr[0], 1);
|
||||
const uint32_t abs_qcoeff =
|
||||
(uint32_t)((tmp * qm_ptr[0] * quant) >> (15 + AOM_QM_BITS));
|
||||
qcoeff_ptr[0] = (tran_low_t)((abs_qcoeff ^ coeff_sign) - coeff_sign);
|
||||
dequant =
|
||||
(dequant_ptr * iqm_ptr[0] + (1 << (AOM_QM_BITS - 1))) >> AOM_QM_BITS;
|
||||
dqcoeff_ptr[0] = (qcoeff_ptr[0] * dequant) / 2;
|
||||
if (abs_qcoeff) eob = 0;
|
||||
}
|
||||
*eob_ptr = eob + 1;
|
||||
}
|
||||
#endif
|
||||
|
||||
void aom_quantize_b_c(const tran_low_t *coeff_ptr, intptr_t n_coeffs,
|
||||
int skip_block, const int16_t *zbin_ptr,
|
||||
const int16_t *round_ptr, const int16_t *quant_ptr,
|
||||
const int16_t *quant_shift_ptr, tran_low_t *qcoeff_ptr,
|
||||
tran_low_t *dqcoeff_ptr, const int16_t *dequant_ptr,
|
||||
uint16_t *eob_ptr, const int16_t *scan,
|
||||
const int16_t *iscan, const qm_val_t *qm_ptr,
|
||||
const qm_val_t *iqm_ptr) {
|
||||
int i, non_zero_count = (int)n_coeffs, eob = -1;
|
||||
const int zbins[2] = { zbin_ptr[0], zbin_ptr[1] };
|
||||
const int nzbins[2] = { zbins[0] * -1, zbins[1] * -1 };
|
||||
(void)iscan;
|
||||
|
||||
memset(qcoeff_ptr, 0, n_coeffs * sizeof(*qcoeff_ptr));
|
||||
memset(dqcoeff_ptr, 0, n_coeffs * sizeof(*dqcoeff_ptr));
|
||||
|
||||
if (!skip_block) {
|
||||
// Pre-scan pass
|
||||
for (i = (int)n_coeffs - 1; i >= 0; i--) {
|
||||
const int rc = scan[i];
|
||||
const qm_val_t wt = qm_ptr[rc];
|
||||
const int coeff = coeff_ptr[rc] * wt;
|
||||
|
||||
if (coeff < (zbins[rc != 0] << AOM_QM_BITS) &&
|
||||
coeff > (nzbins[rc != 0] << AOM_QM_BITS))
|
||||
non_zero_count--;
|
||||
else
|
||||
break;
|
||||
}
|
||||
|
||||
// Quantization pass: All coefficients with index >= zero_flag are
|
||||
// skippable. Note: zero_flag can be zero.
|
||||
for (i = 0; i < non_zero_count; i++) {
|
||||
const int rc = scan[i];
|
||||
const qm_val_t wt = qm_ptr[rc];
|
||||
const int coeff = coeff_ptr[rc];
|
||||
const int coeff_sign = (coeff >> 31);
|
||||
const int abs_coeff = (coeff ^ coeff_sign) - coeff_sign;
|
||||
int dequant;
|
||||
|
||||
if (abs_coeff * wt >= (zbins[rc != 0] << AOM_QM_BITS)) {
|
||||
int32_t tmp32;
|
||||
int64_t tmp =
|
||||
clamp(abs_coeff + round_ptr[rc != 0], INT16_MIN, INT16_MAX);
|
||||
tmp = tmp * wt;
|
||||
tmp32 = ((((tmp * quant_ptr[rc != 0]) >> 16) + tmp) *
|
||||
quant_shift_ptr[rc != 0]) >>
|
||||
(16 + AOM_QM_BITS); // quantization
|
||||
dequant =
|
||||
(dequant_ptr[rc != 0] * iqm_ptr[rc] + (1 << (AOM_QM_BITS - 1))) >>
|
||||
AOM_QM_BITS;
|
||||
qcoeff_ptr[rc] = (tmp32 ^ coeff_sign) - coeff_sign;
|
||||
dqcoeff_ptr[rc] = qcoeff_ptr[rc] * dequant;
|
||||
|
||||
if (tmp32) eob = i;
|
||||
}
|
||||
}
|
||||
}
|
||||
*eob_ptr = eob + 1;
|
||||
}
|
||||
|
||||
#if CONFIG_AOM_HIGHBITDEPTH
|
||||
void aom_highbd_quantize_b_c(const tran_low_t *coeff_ptr, intptr_t n_coeffs,
|
||||
int skip_block, const int16_t *zbin_ptr,
|
||||
const int16_t *round_ptr, const int16_t *quant_ptr,
|
||||
const int16_t *quant_shift_ptr,
|
||||
tran_low_t *qcoeff_ptr, tran_low_t *dqcoeff_ptr,
|
||||
const int16_t *dequant_ptr, uint16_t *eob_ptr,
|
||||
const int16_t *scan, const int16_t *iscan,
|
||||
const qm_val_t *qm_ptr, const qm_val_t *iqm_ptr) {
|
||||
int i, non_zero_count = (int)n_coeffs, eob = -1;
|
||||
const int zbins[2] = { zbin_ptr[0], zbin_ptr[1] };
|
||||
const int nzbins[2] = { zbins[0] * -1, zbins[1] * -1 };
|
||||
int dequant;
|
||||
(void)iscan;
|
||||
|
||||
memset(qcoeff_ptr, 0, n_coeffs * sizeof(*qcoeff_ptr));
|
||||
memset(dqcoeff_ptr, 0, n_coeffs * sizeof(*dqcoeff_ptr));
|
||||
|
||||
if (!skip_block) {
|
||||
// Pre-scan pass
|
||||
for (i = (int)n_coeffs - 1; i >= 0; i--) {
|
||||
const int rc = scan[i];
|
||||
const qm_val_t wt = qm_ptr[rc];
|
||||
const int coeff = coeff_ptr[rc] * wt;
|
||||
|
||||
if (coeff < (zbins[rc != 0] << AOM_QM_BITS) &&
|
||||
coeff > (nzbins[rc != 0] << AOM_QM_BITS))
|
||||
non_zero_count--;
|
||||
else
|
||||
break;
|
||||
}
|
||||
|
||||
// Quantization pass: All coefficients with index >= zero_flag are
|
||||
// skippable. Note: zero_flag can be zero.
|
||||
for (i = 0; i < non_zero_count; i++) {
|
||||
const int rc = scan[i];
|
||||
const int coeff = coeff_ptr[rc];
|
||||
const qm_val_t wt = qm_ptr[rc];
|
||||
const int coeff_sign = (coeff >> 31);
|
||||
const int abs_coeff = (coeff ^ coeff_sign) - coeff_sign;
|
||||
|
||||
if (abs_coeff * wt >= (zbins[rc != 0] << AOM_QM_BITS)) {
|
||||
const int64_t tmp1 = abs_coeff + round_ptr[rc != 0];
|
||||
const int64_t tmpw = tmp1 * wt;
|
||||
const int64_t tmp2 = ((tmpw * quant_ptr[rc != 0]) >> 16) + tmpw;
|
||||
const uint32_t abs_qcoeff =
|
||||
(uint32_t)((tmp2 * quant_shift_ptr[rc != 0]) >> (16 + AOM_QM_BITS));
|
||||
qcoeff_ptr[rc] = (tran_low_t)((abs_qcoeff ^ coeff_sign) - coeff_sign);
|
||||
dequant =
|
||||
(dequant_ptr[rc != 0] * iqm_ptr[rc] + (1 << (AOM_QM_BITS - 1))) >>
|
||||
AOM_QM_BITS;
|
||||
dqcoeff_ptr[rc] = qcoeff_ptr[rc] * dequant;
|
||||
if (abs_qcoeff) eob = i;
|
||||
}
|
||||
}
|
||||
}
|
||||
*eob_ptr = eob + 1;
|
||||
}
|
||||
#endif
|
||||
|
||||
void aom_quantize_b_32x32_c(const tran_low_t *coeff_ptr, intptr_t n_coeffs,
|
||||
int skip_block, const int16_t *zbin_ptr,
|
||||
const int16_t *round_ptr, const int16_t *quant_ptr,
|
||||
const int16_t *quant_shift_ptr,
|
||||
tran_low_t *qcoeff_ptr, tran_low_t *dqcoeff_ptr,
|
||||
const int16_t *dequant_ptr, uint16_t *eob_ptr,
|
||||
const int16_t *scan, const int16_t *iscan,
|
||||
const qm_val_t *qm_ptr, const qm_val_t *iqm_ptr) {
|
||||
const int zbins[2] = { ROUND_POWER_OF_TWO(zbin_ptr[0], 1),
|
||||
ROUND_POWER_OF_TWO(zbin_ptr[1], 1) };
|
||||
const int nzbins[2] = { zbins[0] * -1, zbins[1] * -1 };
|
||||
|
||||
int idx = 0;
|
||||
int idx_arr[1024];
|
||||
int i, eob = -1;
|
||||
int dequant;
|
||||
(void)iscan;
|
||||
|
||||
memset(qcoeff_ptr, 0, n_coeffs * sizeof(*qcoeff_ptr));
|
||||
memset(dqcoeff_ptr, 0, n_coeffs * sizeof(*dqcoeff_ptr));
|
||||
|
||||
if (!skip_block) {
|
||||
// Pre-scan pass
|
||||
for (i = 0; i < n_coeffs; i++) {
|
||||
const int rc = scan[i];
|
||||
const qm_val_t wt = qm_ptr[rc];
|
||||
const int coeff = coeff_ptr[rc] * wt;
|
||||
|
||||
// If the coefficient is out of the base ZBIN range, keep it for
|
||||
// quantization.
|
||||
if (coeff >= (zbins[rc != 0] << AOM_QM_BITS) ||
|
||||
coeff <= (nzbins[rc != 0] << AOM_QM_BITS))
|
||||
idx_arr[idx++] = i;
|
||||
}
|
||||
|
||||
// Quantization pass: only process the coefficients selected in
|
||||
// pre-scan pass. Note: idx can be zero.
|
||||
for (i = 0; i < idx; i++) {
|
||||
const int rc = scan[idx_arr[i]];
|
||||
const int coeff = coeff_ptr[rc];
|
||||
const int coeff_sign = (coeff >> 31);
|
||||
const qm_val_t wt = qm_ptr[rc];
|
||||
int64_t tmp;
|
||||
int tmp32;
|
||||
int abs_coeff = (coeff ^ coeff_sign) - coeff_sign;
|
||||
abs_coeff += ROUND_POWER_OF_TWO(round_ptr[rc != 0], 1);
|
||||
tmp = clamp(abs_coeff, INT16_MIN, INT16_MAX);
|
||||
tmp = tmp * wt;
|
||||
tmp32 = ((((tmp * quant_ptr[rc != 0]) >> 16) + tmp) *
|
||||
quant_shift_ptr[rc != 0]) >>
|
||||
(15 + AOM_QM_BITS);
|
||||
|
||||
qcoeff_ptr[rc] = (tmp32 ^ coeff_sign) - coeff_sign;
|
||||
dequant =
|
||||
(dequant_ptr[rc != 0] * iqm_ptr[rc] + (1 << (AOM_QM_BITS - 1))) >>
|
||||
AOM_QM_BITS;
|
||||
dqcoeff_ptr[rc] = (qcoeff_ptr[rc] * dequant) / 2;
|
||||
|
||||
if (tmp32) eob = idx_arr[i];
|
||||
}
|
||||
}
|
||||
*eob_ptr = eob + 1;
|
||||
}
|
||||
|
||||
#if CONFIG_AOM_HIGHBITDEPTH
|
||||
void aom_highbd_quantize_b_32x32_c(
|
||||
const tran_low_t *coeff_ptr, intptr_t n_coeffs, int skip_block,
|
||||
const int16_t *zbin_ptr, const int16_t *round_ptr, const int16_t *quant_ptr,
|
||||
const int16_t *quant_shift_ptr, tran_low_t *qcoeff_ptr,
|
||||
tran_low_t *dqcoeff_ptr, const int16_t *dequant_ptr, uint16_t *eob_ptr,
|
||||
const int16_t *scan, const int16_t *iscan, const qm_val_t *qm_ptr,
|
||||
const qm_val_t *iqm_ptr) {
|
||||
const int zbins[2] = { ROUND_POWER_OF_TWO(zbin_ptr[0], 1),
|
||||
ROUND_POWER_OF_TWO(zbin_ptr[1], 1) };
|
||||
const int nzbins[2] = { zbins[0] * -1, zbins[1] * -1 };
|
||||
|
||||
int idx = 0;
|
||||
int idx_arr[1024];
|
||||
int i, eob = -1;
|
||||
int dequant;
|
||||
(void)iscan;
|
||||
|
||||
memset(qcoeff_ptr, 0, n_coeffs * sizeof(*qcoeff_ptr));
|
||||
memset(dqcoeff_ptr, 0, n_coeffs * sizeof(*dqcoeff_ptr));
|
||||
|
||||
if (!skip_block) {
|
||||
// Pre-scan pass
|
||||
for (i = 0; i < n_coeffs; i++) {
|
||||
const int rc = scan[i];
|
||||
const qm_val_t wt = qm_ptr[rc];
|
||||
const int coeff = coeff_ptr[rc] * wt;
|
||||
|
||||
// If the coefficient is out of the base ZBIN range, keep it for
|
||||
// quantization.
|
||||
if (coeff >= (zbins[rc != 0] << AOM_QM_BITS) ||
|
||||
coeff <= (nzbins[rc != 0] << AOM_QM_BITS))
|
||||
idx_arr[idx++] = i;
|
||||
}
|
||||
|
||||
// Quantization pass: only process the coefficients selected in
|
||||
// pre-scan pass. Note: idx can be zero.
|
||||
for (i = 0; i < idx; i++) {
|
||||
const int rc = scan[idx_arr[i]];
|
||||
const int coeff = coeff_ptr[rc];
|
||||
const int coeff_sign = (coeff >> 31);
|
||||
const qm_val_t wt = qm_ptr[rc];
|
||||
const int abs_coeff = (coeff ^ coeff_sign) - coeff_sign;
|
||||
const int64_t tmp1 =
|
||||
abs_coeff + ROUND_POWER_OF_TWO(round_ptr[rc != 0], 1);
|
||||
const int64_t tmpw = tmp1 * wt;
|
||||
const int64_t tmp2 = ((tmpw * quant_ptr[rc != 0]) >> 16) + tmpw;
|
||||
const uint32_t abs_qcoeff =
|
||||
(uint32_t)((tmp2 * quant_shift_ptr[rc != 0]) >> (15 + AOM_QM_BITS));
|
||||
qcoeff_ptr[rc] = (tran_low_t)((abs_qcoeff ^ coeff_sign) - coeff_sign);
|
||||
dequant =
|
||||
(dequant_ptr[rc != 0] * iqm_ptr[rc] + (1 << (AOM_QM_BITS - 1))) >>
|
||||
AOM_QM_BITS;
|
||||
dqcoeff_ptr[rc] = (qcoeff_ptr[rc] * dequant) / 2;
|
||||
if (abs_qcoeff) eob = idx_arr[i];
|
||||
}
|
||||
}
|
||||
*eob_ptr = eob + 1;
|
||||
}
|
||||
#endif
|
||||
#else
|
||||
void aom_quantize_dc(const tran_low_t *coeff_ptr, int n_coeffs, int skip_block,
|
||||
const int16_t *round_ptr, const int16_t quant,
|
||||
tran_low_t *qcoeff_ptr, tran_low_t *dqcoeff_ptr,
|
||||
const int16_t dequant_ptr, uint16_t *eob_ptr) {
|
||||
const int rc = 0;
|
||||
const int coeff = coeff_ptr[rc];
|
||||
const int coeff_sign = (coeff >> 31);
|
||||
const int abs_coeff = (coeff ^ coeff_sign) - coeff_sign;
|
||||
int tmp, eob = -1;
|
||||
|
||||
memset(qcoeff_ptr, 0, n_coeffs * sizeof(*qcoeff_ptr));
|
||||
memset(dqcoeff_ptr, 0, n_coeffs * sizeof(*dqcoeff_ptr));
|
||||
|
||||
if (!skip_block) {
|
||||
tmp = clamp(abs_coeff + round_ptr[rc != 0], INT16_MIN, INT16_MAX);
|
||||
tmp = (tmp * quant) >> 16;
|
||||
qcoeff_ptr[rc] = (tmp ^ coeff_sign) - coeff_sign;
|
||||
dqcoeff_ptr[rc] = qcoeff_ptr[rc] * dequant_ptr;
|
||||
if (tmp) eob = 0;
|
||||
}
|
||||
*eob_ptr = eob + 1;
|
||||
}
|
||||
|
||||
#if CONFIG_AOM_HIGHBITDEPTH
|
||||
void aom_highbd_quantize_dc(const tran_low_t *coeff_ptr, int n_coeffs,
|
||||
int skip_block, const int16_t *round_ptr,
|
||||
const int16_t quant, tran_low_t *qcoeff_ptr,
|
||||
tran_low_t *dqcoeff_ptr, const int16_t dequant_ptr,
|
||||
uint16_t *eob_ptr) {
|
||||
int eob = -1;
|
||||
|
||||
memset(qcoeff_ptr, 0, n_coeffs * sizeof(*qcoeff_ptr));
|
||||
memset(dqcoeff_ptr, 0, n_coeffs * sizeof(*dqcoeff_ptr));
|
||||
|
||||
if (!skip_block) {
|
||||
const int coeff = coeff_ptr[0];
|
||||
const int coeff_sign = (coeff >> 31);
|
||||
const int abs_coeff = (coeff ^ coeff_sign) - coeff_sign;
|
||||
const int64_t tmp = abs_coeff + round_ptr[0];
|
||||
const uint32_t abs_qcoeff = (uint32_t)((tmp * quant) >> 16);
|
||||
qcoeff_ptr[0] = (tran_low_t)((abs_qcoeff ^ coeff_sign) - coeff_sign);
|
||||
dqcoeff_ptr[0] = qcoeff_ptr[0] * dequant_ptr;
|
||||
if (abs_qcoeff) eob = 0;
|
||||
}
|
||||
*eob_ptr = eob + 1;
|
||||
}
|
||||
#endif
|
||||
|
||||
void aom_quantize_dc_32x32(const tran_low_t *coeff_ptr, int skip_block,
|
||||
const int16_t *round_ptr, const int16_t quant,
|
||||
tran_low_t *qcoeff_ptr, tran_low_t *dqcoeff_ptr,
|
||||
const int16_t dequant_ptr, uint16_t *eob_ptr) {
|
||||
const int n_coeffs = 1024;
|
||||
const int rc = 0;
|
||||
const int coeff = coeff_ptr[rc];
|
||||
const int coeff_sign = (coeff >> 31);
|
||||
const int abs_coeff = (coeff ^ coeff_sign) - coeff_sign;
|
||||
int tmp, eob = -1;
|
||||
|
||||
memset(qcoeff_ptr, 0, n_coeffs * sizeof(*qcoeff_ptr));
|
||||
memset(dqcoeff_ptr, 0, n_coeffs * sizeof(*dqcoeff_ptr));
|
||||
|
||||
if (!skip_block) {
|
||||
tmp = clamp(abs_coeff + ROUND_POWER_OF_TWO(round_ptr[rc != 0], 1),
|
||||
INT16_MIN, INT16_MAX);
|
||||
tmp = (tmp * quant) >> 15;
|
||||
qcoeff_ptr[rc] = (tmp ^ coeff_sign) - coeff_sign;
|
||||
dqcoeff_ptr[rc] = qcoeff_ptr[rc] * dequant_ptr / 2;
|
||||
if (tmp) eob = 0;
|
||||
}
|
||||
*eob_ptr = eob + 1;
|
||||
}
|
||||
|
||||
#if CONFIG_AOM_HIGHBITDEPTH
|
||||
void aom_highbd_quantize_dc_32x32(const tran_low_t *coeff_ptr, int skip_block,
|
||||
const int16_t *round_ptr, const int16_t quant,
|
||||
tran_low_t *qcoeff_ptr,
|
||||
tran_low_t *dqcoeff_ptr,
|
||||
const int16_t dequant_ptr,
|
||||
uint16_t *eob_ptr) {
|
||||
const int n_coeffs = 1024;
|
||||
int eob = -1;
|
||||
|
||||
memset(qcoeff_ptr, 0, n_coeffs * sizeof(*qcoeff_ptr));
|
||||
memset(dqcoeff_ptr, 0, n_coeffs * sizeof(*dqcoeff_ptr));
|
||||
|
||||
if (!skip_block) {
|
||||
const int coeff = coeff_ptr[0];
|
||||
const int coeff_sign = (coeff >> 31);
|
||||
const int abs_coeff = (coeff ^ coeff_sign) - coeff_sign;
|
||||
const int64_t tmp = abs_coeff + ROUND_POWER_OF_TWO(round_ptr[0], 1);
|
||||
const uint32_t abs_qcoeff = (uint32_t)((tmp * quant) >> 15);
|
||||
qcoeff_ptr[0] = (tran_low_t)((abs_qcoeff ^ coeff_sign) - coeff_sign);
|
||||
dqcoeff_ptr[0] = qcoeff_ptr[0] * dequant_ptr / 2;
|
||||
if (abs_qcoeff) eob = 0;
|
||||
}
|
||||
*eob_ptr = eob + 1;
|
||||
}
|
||||
#endif
|
||||
|
||||
void aom_quantize_b_c(const tran_low_t *coeff_ptr, intptr_t n_coeffs,
|
||||
int skip_block, const int16_t *zbin_ptr,
|
||||
const int16_t *round_ptr, const int16_t *quant_ptr,
|
||||
const int16_t *quant_shift_ptr, tran_low_t *qcoeff_ptr,
|
||||
tran_low_t *dqcoeff_ptr, const int16_t *dequant_ptr,
|
||||
uint16_t *eob_ptr, const int16_t *scan,
|
||||
const int16_t *iscan) {
|
||||
int i, non_zero_count = (int)n_coeffs, eob = -1;
|
||||
const int zbins[2] = { zbin_ptr[0], zbin_ptr[1] };
|
||||
const int nzbins[2] = { zbins[0] * -1, zbins[1] * -1 };
|
||||
(void)iscan;
|
||||
|
||||
memset(qcoeff_ptr, 0, n_coeffs * sizeof(*qcoeff_ptr));
|
||||
memset(dqcoeff_ptr, 0, n_coeffs * sizeof(*dqcoeff_ptr));
|
||||
|
||||
if (!skip_block) {
|
||||
// Pre-scan pass
|
||||
for (i = (int)n_coeffs - 1; i >= 0; i--) {
|
||||
const int rc = scan[i];
|
||||
const int coeff = coeff_ptr[rc];
|
||||
|
||||
if (coeff < zbins[rc != 0] && coeff > nzbins[rc != 0])
|
||||
non_zero_count--;
|
||||
else
|
||||
break;
|
||||
}
|
||||
|
||||
// Quantization pass: All coefficients with index >= zero_flag are
|
||||
// skippable. Note: zero_flag can be zero.
|
||||
for (i = 0; i < non_zero_count; i++) {
|
||||
const int rc = scan[i];
|
||||
const int coeff = coeff_ptr[rc];
|
||||
const int coeff_sign = (coeff >> 31);
|
||||
const int abs_coeff = (coeff ^ coeff_sign) - coeff_sign;
|
||||
|
||||
if (abs_coeff >= zbins[rc != 0]) {
|
||||
int tmp = clamp(abs_coeff + round_ptr[rc != 0], INT16_MIN, INT16_MAX);
|
||||
tmp = ((((tmp * quant_ptr[rc != 0]) >> 16) + tmp) *
|
||||
quant_shift_ptr[rc != 0]) >>
|
||||
16; // quantization
|
||||
qcoeff_ptr[rc] = (tmp ^ coeff_sign) - coeff_sign;
|
||||
dqcoeff_ptr[rc] = qcoeff_ptr[rc] * dequant_ptr[rc != 0];
|
||||
|
||||
if (tmp) eob = i;
|
||||
}
|
||||
}
|
||||
}
|
||||
*eob_ptr = eob + 1;
|
||||
}
|
||||
|
||||
#if CONFIG_AOM_HIGHBITDEPTH
|
||||
void aom_highbd_quantize_b_c(const tran_low_t *coeff_ptr, intptr_t n_coeffs,
|
||||
int skip_block, const int16_t *zbin_ptr,
|
||||
const int16_t *round_ptr, const int16_t *quant_ptr,
|
||||
const int16_t *quant_shift_ptr,
|
||||
tran_low_t *qcoeff_ptr, tran_low_t *dqcoeff_ptr,
|
||||
const int16_t *dequant_ptr, uint16_t *eob_ptr,
|
||||
const int16_t *scan, const int16_t *iscan) {
|
||||
int i, non_zero_count = (int)n_coeffs, eob = -1;
|
||||
const int zbins[2] = { zbin_ptr[0], zbin_ptr[1] };
|
||||
const int nzbins[2] = { zbins[0] * -1, zbins[1] * -1 };
|
||||
(void)iscan;
|
||||
|
||||
memset(qcoeff_ptr, 0, n_coeffs * sizeof(*qcoeff_ptr));
|
||||
memset(dqcoeff_ptr, 0, n_coeffs * sizeof(*dqcoeff_ptr));
|
||||
|
||||
if (!skip_block) {
|
||||
// Pre-scan pass
|
||||
for (i = (int)n_coeffs - 1; i >= 0; i--) {
|
||||
const int rc = scan[i];
|
||||
const int coeff = coeff_ptr[rc];
|
||||
|
||||
if (coeff < zbins[rc != 0] && coeff > nzbins[rc != 0])
|
||||
non_zero_count--;
|
||||
else
|
||||
break;
|
||||
}
|
||||
|
||||
// Quantization pass: All coefficients with index >= zero_flag are
|
||||
// skippable. Note: zero_flag can be zero.
|
||||
for (i = 0; i < non_zero_count; i++) {
|
||||
const int rc = scan[i];
|
||||
const int coeff = coeff_ptr[rc];
|
||||
const int coeff_sign = (coeff >> 31);
|
||||
const int abs_coeff = (coeff ^ coeff_sign) - coeff_sign;
|
||||
|
||||
if (abs_coeff >= zbins[rc != 0]) {
|
||||
const int64_t tmp1 = abs_coeff + round_ptr[rc != 0];
|
||||
const int64_t tmp2 = ((tmp1 * quant_ptr[rc != 0]) >> 16) + tmp1;
|
||||
const uint32_t abs_qcoeff =
|
||||
(uint32_t)((tmp2 * quant_shift_ptr[rc != 0]) >> 16);
|
||||
qcoeff_ptr[rc] = (tran_low_t)((abs_qcoeff ^ coeff_sign) - coeff_sign);
|
||||
dqcoeff_ptr[rc] = qcoeff_ptr[rc] * dequant_ptr[rc != 0];
|
||||
if (abs_qcoeff) eob = i;
|
||||
}
|
||||
}
|
||||
}
|
||||
*eob_ptr = eob + 1;
|
||||
}
|
||||
#endif
|
||||
|
||||
void aom_quantize_b_32x32_c(const tran_low_t *coeff_ptr, intptr_t n_coeffs,
|
||||
int skip_block, const int16_t *zbin_ptr,
|
||||
const int16_t *round_ptr, const int16_t *quant_ptr,
|
||||
const int16_t *quant_shift_ptr,
|
||||
tran_low_t *qcoeff_ptr, tran_low_t *dqcoeff_ptr,
|
||||
const int16_t *dequant_ptr, uint16_t *eob_ptr,
|
||||
const int16_t *scan, const int16_t *iscan) {
|
||||
const int zbins[2] = { ROUND_POWER_OF_TWO(zbin_ptr[0], 1),
|
||||
ROUND_POWER_OF_TWO(zbin_ptr[1], 1) };
|
||||
const int nzbins[2] = { zbins[0] * -1, zbins[1] * -1 };
|
||||
|
||||
int idx = 0;
|
||||
int idx_arr[1024];
|
||||
int i, eob = -1;
|
||||
(void)iscan;
|
||||
|
||||
memset(qcoeff_ptr, 0, n_coeffs * sizeof(*qcoeff_ptr));
|
||||
memset(dqcoeff_ptr, 0, n_coeffs * sizeof(*dqcoeff_ptr));
|
||||
|
||||
if (!skip_block) {
|
||||
// Pre-scan pass
|
||||
for (i = 0; i < n_coeffs; i++) {
|
||||
const int rc = scan[i];
|
||||
const int coeff = coeff_ptr[rc];
|
||||
|
||||
// If the coefficient is out of the base ZBIN range, keep it for
|
||||
// quantization.
|
||||
if (coeff >= zbins[rc != 0] || coeff <= nzbins[rc != 0])
|
||||
idx_arr[idx++] = i;
|
||||
}
|
||||
|
||||
// Quantization pass: only process the coefficients selected in
|
||||
// pre-scan pass. Note: idx can be zero.
|
||||
for (i = 0; i < idx; i++) {
|
||||
const int rc = scan[idx_arr[i]];
|
||||
const int coeff = coeff_ptr[rc];
|
||||
const int coeff_sign = (coeff >> 31);
|
||||
int tmp;
|
||||
int abs_coeff = (coeff ^ coeff_sign) - coeff_sign;
|
||||
abs_coeff += ROUND_POWER_OF_TWO(round_ptr[rc != 0], 1);
|
||||
abs_coeff = clamp(abs_coeff, INT16_MIN, INT16_MAX);
|
||||
tmp = ((((abs_coeff * quant_ptr[rc != 0]) >> 16) + abs_coeff) *
|
||||
quant_shift_ptr[rc != 0]) >>
|
||||
15;
|
||||
|
||||
qcoeff_ptr[rc] = (tmp ^ coeff_sign) - coeff_sign;
|
||||
dqcoeff_ptr[rc] = qcoeff_ptr[rc] * dequant_ptr[rc != 0] / 2;
|
||||
|
||||
if (tmp) eob = idx_arr[i];
|
||||
}
|
||||
}
|
||||
*eob_ptr = eob + 1;
|
||||
}
|
||||
|
||||
#if CONFIG_AOM_HIGHBITDEPTH
|
||||
void aom_highbd_quantize_b_32x32_c(
|
||||
const tran_low_t *coeff_ptr, intptr_t n_coeffs, int skip_block,
|
||||
const int16_t *zbin_ptr, const int16_t *round_ptr, const int16_t *quant_ptr,
|
||||
const int16_t *quant_shift_ptr, tran_low_t *qcoeff_ptr,
|
||||
tran_low_t *dqcoeff_ptr, const int16_t *dequant_ptr, uint16_t *eob_ptr,
|
||||
const int16_t *scan, const int16_t *iscan) {
|
||||
const int zbins[2] = { ROUND_POWER_OF_TWO(zbin_ptr[0], 1),
|
||||
ROUND_POWER_OF_TWO(zbin_ptr[1], 1) };
|
||||
const int nzbins[2] = { zbins[0] * -1, zbins[1] * -1 };
|
||||
|
||||
int idx = 0;
|
||||
int idx_arr[1024];
|
||||
int i, eob = -1;
|
||||
(void)iscan;
|
||||
|
||||
memset(qcoeff_ptr, 0, n_coeffs * sizeof(*qcoeff_ptr));
|
||||
memset(dqcoeff_ptr, 0, n_coeffs * sizeof(*dqcoeff_ptr));
|
||||
|
||||
if (!skip_block) {
|
||||
// Pre-scan pass
|
||||
for (i = 0; i < n_coeffs; i++) {
|
||||
const int rc = scan[i];
|
||||
const int coeff = coeff_ptr[rc];
|
||||
|
||||
// If the coefficient is out of the base ZBIN range, keep it for
|
||||
// quantization.
|
||||
if (coeff >= zbins[rc != 0] || coeff <= nzbins[rc != 0])
|
||||
idx_arr[idx++] = i;
|
||||
}
|
||||
|
||||
// Quantization pass: only process the coefficients selected in
|
||||
// pre-scan pass. Note: idx can be zero.
|
||||
for (i = 0; i < idx; i++) {
|
||||
const int rc = scan[idx_arr[i]];
|
||||
const int coeff = coeff_ptr[rc];
|
||||
const int coeff_sign = (coeff >> 31);
|
||||
const int abs_coeff = (coeff ^ coeff_sign) - coeff_sign;
|
||||
const int64_t tmp1 =
|
||||
abs_coeff + ROUND_POWER_OF_TWO(round_ptr[rc != 0], 1);
|
||||
const int64_t tmp2 = ((tmp1 * quant_ptr[rc != 0]) >> 16) + tmp1;
|
||||
const uint32_t abs_qcoeff =
|
||||
(uint32_t)((tmp2 * quant_shift_ptr[rc != 0]) >> 15);
|
||||
qcoeff_ptr[rc] = (tran_low_t)((abs_qcoeff ^ coeff_sign) - coeff_sign);
|
||||
dqcoeff_ptr[rc] = qcoeff_ptr[rc] * dequant_ptr[rc != 0] / 2;
|
||||
if (abs_qcoeff) eob = idx_arr[i];
|
||||
}
|
||||
}
|
||||
*eob_ptr = eob + 1;
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
@@ -1,91 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2016, Alliance for Open Media. All rights reserved
|
||||
*
|
||||
* This source code is subject to the terms of the BSD 2 Clause License and
|
||||
* the Alliance for Open Media Patent License 1.0. If the BSD 2 Clause License
|
||||
* was not distributed with this source code in the LICENSE file, you can
|
||||
* obtain it at www.aomedia.org/license/software. If the Alliance for Open
|
||||
* Media Patent License 1.0 was not distributed with this source code in the
|
||||
* PATENTS file, you can obtain it at www.aomedia.org/license/patent.
|
||||
*/
|
||||
|
||||
#ifndef AOM_DSP_QUANTIZE_H_
|
||||
#define AOM_DSP_QUANTIZE_H_
|
||||
|
||||
#include "./aom_config.h"
|
||||
#include "aom_dsp/aom_dsp_common.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#if CONFIG_AOM_QM
|
||||
void aom_quantize_dc(const tran_low_t *coeff_ptr, int n_coeffs, int skip_block,
|
||||
const int16_t *round_ptr, const int16_t quant_ptr,
|
||||
tran_low_t *qcoeff_ptr, tran_low_t *dqcoeff_ptr,
|
||||
const int16_t dequant_ptr, uint16_t *eob_ptr,
|
||||
const qm_val_t *qm_ptr, const qm_val_t *iqm_ptr);
|
||||
void aom_quantize_dc_32x32(const tran_low_t *coeff_ptr, int skip_block,
|
||||
const int16_t *round_ptr, const int16_t quant_ptr,
|
||||
tran_low_t *qcoeff_ptr, tran_low_t *dqcoeff_ptr,
|
||||
const int16_t dequant_ptr, uint16_t *eob_ptr,
|
||||
const qm_val_t *qm_ptr, const qm_val_t *iqm_ptr);
|
||||
void aom_quantize_b_c(const tran_low_t *coeff_ptr, intptr_t n_coeffs,
|
||||
int skip_block, const int16_t *zbin_ptr,
|
||||
const int16_t *round_ptr, const int16_t *quant_ptr,
|
||||
const int16_t *quant_shift_ptr, tran_low_t *qcoeff_ptr,
|
||||
tran_low_t *dqcoeff_ptr, const int16_t *dequant_ptr,
|
||||
uint16_t *eob_ptr, const int16_t *scan,
|
||||
const int16_t *iscan, const qm_val_t *qm_ptr,
|
||||
const qm_val_t *iqm_ptr);
|
||||
#if CONFIG_AOM_HIGHBITDEPTH
|
||||
void aom_highbd_quantize_dc(const tran_low_t *coeff_ptr, int n_coeffs,
|
||||
int skip_block, const int16_t *round_ptr,
|
||||
const int16_t quant_ptr, tran_low_t *qcoeff_ptr,
|
||||
tran_low_t *dqcoeff_ptr, const int16_t dequant_ptr,
|
||||
uint16_t *eob_ptr, const qm_val_t *qm_ptr,
|
||||
const qm_val_t *iqm_ptr);
|
||||
void aom_highbd_quantize_dc_32x32(
|
||||
const tran_low_t *coeff_ptr, int skip_block, const int16_t *round_ptr,
|
||||
const int16_t quant_ptr, tran_low_t *qcoeff_ptr, tran_low_t *dqcoeff_ptr,
|
||||
const int16_t dequant_ptr, uint16_t *eob_ptr, const qm_val_t *qm_ptr,
|
||||
const qm_val_t *iqm_ptr);
|
||||
void aom_highbd_quantize_b_c(const tran_low_t *coeff_ptr, intptr_t n_coeffs,
|
||||
int skip_block, const int16_t *zbin_ptr,
|
||||
const int16_t *round_ptr, const int16_t *quant_ptr,
|
||||
const int16_t *quant_shift_ptr,
|
||||
tran_low_t *qcoeff_ptr, tran_low_t *dqcoeff_ptr,
|
||||
const int16_t *dequant_ptr, uint16_t *eob_ptr,
|
||||
const int16_t *scan, const int16_t *iscan,
|
||||
const qm_val_t *qm_ptr, const qm_val_t *iqm_ptr);
|
||||
#endif
|
||||
#else
|
||||
void aom_quantize_dc(const tran_low_t *coeff_ptr, int n_coeffs, int skip_block,
|
||||
const int16_t *round_ptr, const int16_t quant_ptr,
|
||||
tran_low_t *qcoeff_ptr, tran_low_t *dqcoeff_ptr,
|
||||
const int16_t dequant_ptr, uint16_t *eob_ptr);
|
||||
void aom_quantize_dc_32x32(const tran_low_t *coeff_ptr, int skip_block,
|
||||
const int16_t *round_ptr, const int16_t quant_ptr,
|
||||
tran_low_t *qcoeff_ptr, tran_low_t *dqcoeff_ptr,
|
||||
const int16_t dequant_ptr, uint16_t *eob_ptr);
|
||||
|
||||
#if CONFIG_AOM_HIGHBITDEPTH
|
||||
void aom_highbd_quantize_dc(const tran_low_t *coeff_ptr, int n_coeffs,
|
||||
int skip_block, const int16_t *round_ptr,
|
||||
const int16_t quant_ptr, tran_low_t *qcoeff_ptr,
|
||||
tran_low_t *dqcoeff_ptr, const int16_t dequant_ptr,
|
||||
uint16_t *eob_ptr);
|
||||
void aom_highbd_quantize_dc_32x32(const tran_low_t *coeff_ptr, int skip_block,
|
||||
const int16_t *round_ptr,
|
||||
const int16_t quant_ptr,
|
||||
tran_low_t *qcoeff_ptr,
|
||||
tran_low_t *dqcoeff_ptr,
|
||||
const int16_t dequant_ptr, uint16_t *eob_ptr);
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
} // extern "C"
|
||||
#endif
|
||||
|
||||
#endif // AOM_DSP_QUANTIZE_H_
|
||||
512
aom_dsp/sad.c
512
aom_dsp/sad.c
@@ -1,512 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2016, Alliance for Open Media. All rights reserved
|
||||
*
|
||||
* This source code is subject to the terms of the BSD 2 Clause License and
|
||||
* the Alliance for Open Media Patent License 1.0. If the BSD 2 Clause License
|
||||
* was not distributed with this source code in the LICENSE file, you can
|
||||
* obtain it at www.aomedia.org/license/software. If the Alliance for Open
|
||||
* Media Patent License 1.0 was not distributed with this source code in the
|
||||
* PATENTS file, you can obtain it at www.aomedia.org/license/patent.
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "./aom_config.h"
|
||||
#include "./aom_dsp_rtcd.h"
|
||||
|
||||
#include "aom/aom_integer.h"
|
||||
#include "aom_ports/mem.h"
|
||||
|
||||
/* Sum the difference between every corresponding element of the buffers. */
|
||||
static INLINE unsigned int sad(const uint8_t *a, int a_stride, const uint8_t *b,
|
||||
int b_stride, int width, int height) {
|
||||
int y, x;
|
||||
unsigned int sad = 0;
|
||||
|
||||
for (y = 0; y < height; y++) {
|
||||
for (x = 0; x < width; x++) sad += abs(a[x] - b[x]);
|
||||
|
||||
a += a_stride;
|
||||
b += b_stride;
|
||||
}
|
||||
return sad;
|
||||
}
|
||||
|
||||
#define sadMxN(m, n) \
|
||||
unsigned int aom_sad##m##x##n##_c(const uint8_t *src, int src_stride, \
|
||||
const uint8_t *ref, int ref_stride) { \
|
||||
return sad(src, src_stride, ref, ref_stride, m, n); \
|
||||
} \
|
||||
unsigned int aom_sad##m##x##n##_avg_c(const uint8_t *src, int src_stride, \
|
||||
const uint8_t *ref, int ref_stride, \
|
||||
const uint8_t *second_pred) { \
|
||||
uint8_t comp_pred[m * n]; \
|
||||
aom_comp_avg_pred_c(comp_pred, second_pred, m, n, ref, ref_stride); \
|
||||
return sad(src, src_stride, comp_pred, m, m, n); \
|
||||
}
|
||||
|
||||
// depending on call sites, pass **ref_array to avoid & in subsequent call and
|
||||
// de-dup with 4D below.
|
||||
#define sadMxNxK(m, n, k) \
|
||||
void aom_sad##m##x##n##x##k##_c(const uint8_t *src, int src_stride, \
|
||||
const uint8_t *ref_array, int ref_stride, \
|
||||
uint32_t *sad_array) { \
|
||||
int i; \
|
||||
for (i = 0; i < k; ++i) \
|
||||
sad_array[i] = \
|
||||
aom_sad##m##x##n##_c(src, src_stride, &ref_array[i], ref_stride); \
|
||||
}
|
||||
|
||||
// This appears to be equivalent to the above when k == 4 and refs is const
|
||||
#define sadMxNx4D(m, n) \
|
||||
void aom_sad##m##x##n##x4d_c(const uint8_t *src, int src_stride, \
|
||||
const uint8_t *const ref_array[], \
|
||||
int ref_stride, uint32_t *sad_array) { \
|
||||
int i; \
|
||||
for (i = 0; i < 4; ++i) \
|
||||
sad_array[i] = \
|
||||
aom_sad##m##x##n##_c(src, src_stride, ref_array[i], ref_stride); \
|
||||
}
|
||||
|
||||
/* clang-format off */
|
||||
#if CONFIG_AV1 && CONFIG_EXT_PARTITION
|
||||
// 128x128
|
||||
sadMxN(128, 128)
|
||||
sadMxNxK(128, 128, 3)
|
||||
sadMxNxK(128, 128, 8)
|
||||
sadMxNx4D(128, 128)
|
||||
|
||||
// 128x64
|
||||
sadMxN(128, 64)
|
||||
sadMxNx4D(128, 64)
|
||||
|
||||
// 64x128
|
||||
sadMxN(64, 128)
|
||||
sadMxNx4D(64, 128)
|
||||
#endif // CONFIG_AV1 && CONFIG_EXT_PARTITION
|
||||
|
||||
// 64x64
|
||||
sadMxN(64, 64)
|
||||
sadMxNxK(64, 64, 3)
|
||||
sadMxNxK(64, 64, 8)
|
||||
sadMxNx4D(64, 64)
|
||||
|
||||
// 64x32
|
||||
sadMxN(64, 32)
|
||||
sadMxNx4D(64, 32)
|
||||
|
||||
// 32x64
|
||||
sadMxN(32, 64)
|
||||
sadMxNx4D(32, 64)
|
||||
|
||||
// 32x32
|
||||
sadMxN(32, 32)
|
||||
sadMxNxK(32, 32, 3)
|
||||
sadMxNxK(32, 32, 8)
|
||||
sadMxNx4D(32, 32)
|
||||
|
||||
// 32x16
|
||||
sadMxN(32, 16)
|
||||
sadMxNx4D(32, 16)
|
||||
|
||||
// 16x32
|
||||
sadMxN(16, 32)
|
||||
sadMxNx4D(16, 32)
|
||||
|
||||
// 16x16
|
||||
sadMxN(16, 16)
|
||||
sadMxNxK(16, 16, 3)
|
||||
sadMxNxK(16, 16, 8)
|
||||
sadMxNx4D(16, 16)
|
||||
|
||||
// 16x8
|
||||
sadMxN(16, 8)
|
||||
sadMxNxK(16, 8, 3)
|
||||
sadMxNxK(16, 8, 8)
|
||||
sadMxNx4D(16, 8)
|
||||
|
||||
// 8x16
|
||||
sadMxN(8, 16)
|
||||
sadMxNxK(8, 16, 3)
|
||||
sadMxNxK(8, 16, 8)
|
||||
sadMxNx4D(8, 16)
|
||||
|
||||
// 8x8
|
||||
sadMxN(8, 8)
|
||||
sadMxNxK(8, 8, 3)
|
||||
sadMxNxK(8, 8, 8)
|
||||
sadMxNx4D(8, 8)
|
||||
|
||||
// 8x4
|
||||
sadMxN(8, 4)
|
||||
sadMxNxK(8, 4, 8)
|
||||
sadMxNx4D(8, 4)
|
||||
|
||||
// 4x8
|
||||
sadMxN(4, 8)
|
||||
sadMxNxK(4, 8, 8)
|
||||
sadMxNx4D(4, 8)
|
||||
|
||||
// 4x4
|
||||
sadMxN(4, 4)
|
||||
sadMxNxK(4, 4, 3)
|
||||
sadMxNxK(4, 4, 8)
|
||||
sadMxNx4D(4, 4)
|
||||
/* clang-format on */
|
||||
|
||||
#if CONFIG_AOM_HIGHBITDEPTH
|
||||
static INLINE
|
||||
unsigned int highbd_sad(const uint8_t *a8, int a_stride, const uint8_t *b8,
|
||||
int b_stride, int width, int height) {
|
||||
int y, x;
|
||||
unsigned int sad = 0;
|
||||
const uint16_t *a = CONVERT_TO_SHORTPTR(a8);
|
||||
const uint16_t *b = CONVERT_TO_SHORTPTR(b8);
|
||||
for (y = 0; y < height; y++) {
|
||||
for (x = 0; x < width; x++) sad += abs(a[x] - b[x]);
|
||||
|
||||
a += a_stride;
|
||||
b += b_stride;
|
||||
}
|
||||
return sad;
|
||||
}
|
||||
|
||||
static INLINE unsigned int highbd_sadb(const uint8_t *a8, int a_stride,
|
||||
const uint16_t *b, int b_stride,
|
||||
int width, int height) {
|
||||
int y, x;
|
||||
unsigned int sad = 0;
|
||||
const uint16_t *a = CONVERT_TO_SHORTPTR(a8);
|
||||
for (y = 0; y < height; y++) {
|
||||
for (x = 0; x < width; x++) sad += abs(a[x] - b[x]);
|
||||
|
||||
a += a_stride;
|
||||
b += b_stride;
|
||||
}
|
||||
return sad;
|
||||
}
|
||||
|
||||
#define highbd_sadMxN(m, n) \
|
||||
unsigned int aom_highbd_sad##m##x##n##_c(const uint8_t *src, int src_stride, \
|
||||
const uint8_t *ref, \
|
||||
int ref_stride) { \
|
||||
return highbd_sad(src, src_stride, ref, ref_stride, m, n); \
|
||||
} \
|
||||
unsigned int aom_highbd_sad##m##x##n##_avg_c( \
|
||||
const uint8_t *src, int src_stride, const uint8_t *ref, int ref_stride, \
|
||||
const uint8_t *second_pred) { \
|
||||
uint16_t comp_pred[m * n]; \
|
||||
aom_highbd_comp_avg_pred_c(comp_pred, second_pred, m, n, ref, ref_stride); \
|
||||
return highbd_sadb(src, src_stride, comp_pred, m, m, n); \
|
||||
}
|
||||
|
||||
#define highbd_sadMxNxK(m, n, k) \
|
||||
void aom_highbd_sad##m##x##n##x##k##_c( \
|
||||
const uint8_t *src, int src_stride, const uint8_t *ref_array, \
|
||||
int ref_stride, uint32_t *sad_array) { \
|
||||
int i; \
|
||||
for (i = 0; i < k; ++i) { \
|
||||
sad_array[i] = aom_highbd_sad##m##x##n##_c(src, src_stride, \
|
||||
&ref_array[i], ref_stride); \
|
||||
} \
|
||||
}
|
||||
|
||||
#define highbd_sadMxNx4D(m, n) \
|
||||
void aom_highbd_sad##m##x##n##x4d_c(const uint8_t *src, int src_stride, \
|
||||
const uint8_t *const ref_array[], \
|
||||
int ref_stride, uint32_t *sad_array) { \
|
||||
int i; \
|
||||
for (i = 0; i < 4; ++i) { \
|
||||
sad_array[i] = aom_highbd_sad##m##x##n##_c(src, src_stride, \
|
||||
ref_array[i], ref_stride); \
|
||||
} \
|
||||
}
|
||||
|
||||
/* clang-format off */
|
||||
#if CONFIG_AV1 && CONFIG_EXT_PARTITION
|
||||
// 128x128
|
||||
highbd_sadMxN(128, 128)
|
||||
highbd_sadMxNxK(128, 128, 3)
|
||||
highbd_sadMxNxK(128, 128, 8)
|
||||
highbd_sadMxNx4D(128, 128)
|
||||
|
||||
// 128x64
|
||||
highbd_sadMxN(128, 64)
|
||||
highbd_sadMxNx4D(128, 64)
|
||||
|
||||
// 64x128
|
||||
highbd_sadMxN(64, 128)
|
||||
highbd_sadMxNx4D(64, 128)
|
||||
#endif // CONFIG_AV1 && CONFIG_EXT_PARTITION
|
||||
|
||||
// 64x64
|
||||
highbd_sadMxN(64, 64)
|
||||
highbd_sadMxNxK(64, 64, 3)
|
||||
highbd_sadMxNxK(64, 64, 8)
|
||||
highbd_sadMxNx4D(64, 64)
|
||||
|
||||
// 64x32
|
||||
highbd_sadMxN(64, 32)
|
||||
highbd_sadMxNx4D(64, 32)
|
||||
|
||||
// 32x64
|
||||
highbd_sadMxN(32, 64)
|
||||
highbd_sadMxNx4D(32, 64)
|
||||
|
||||
// 32x32
|
||||
highbd_sadMxN(32, 32)
|
||||
highbd_sadMxNxK(32, 32, 3)
|
||||
highbd_sadMxNxK(32, 32, 8)
|
||||
highbd_sadMxNx4D(32, 32)
|
||||
|
||||
// 32x16
|
||||
highbd_sadMxN(32, 16)
|
||||
highbd_sadMxNx4D(32, 16)
|
||||
|
||||
// 16x32
|
||||
highbd_sadMxN(16, 32)
|
||||
highbd_sadMxNx4D(16, 32)
|
||||
|
||||
// 16x16
|
||||
highbd_sadMxN(16, 16)
|
||||
highbd_sadMxNxK(16, 16, 3)
|
||||
highbd_sadMxNxK(16, 16, 8)
|
||||
highbd_sadMxNx4D(16, 16)
|
||||
|
||||
// 16x8
|
||||
highbd_sadMxN(16, 8)
|
||||
highbd_sadMxNxK(16, 8, 3)
|
||||
highbd_sadMxNxK(16, 8, 8)
|
||||
highbd_sadMxNx4D(16, 8)
|
||||
|
||||
// 8x16
|
||||
highbd_sadMxN(8, 16)
|
||||
highbd_sadMxNxK(8, 16, 3)
|
||||
highbd_sadMxNxK(8, 16, 8)
|
||||
highbd_sadMxNx4D(8, 16)
|
||||
|
||||
// 8x8
|
||||
highbd_sadMxN(8, 8)
|
||||
highbd_sadMxNxK(8, 8, 3)
|
||||
highbd_sadMxNxK(8, 8, 8)
|
||||
highbd_sadMxNx4D(8, 8)
|
||||
|
||||
// 8x4
|
||||
highbd_sadMxN(8, 4)
|
||||
highbd_sadMxNxK(8, 4, 8)
|
||||
highbd_sadMxNx4D(8, 4)
|
||||
|
||||
// 4x8
|
||||
highbd_sadMxN(4, 8)
|
||||
highbd_sadMxNxK(4, 8, 8)
|
||||
highbd_sadMxNx4D(4, 8)
|
||||
|
||||
// 4x4
|
||||
highbd_sadMxN(4, 4)
|
||||
highbd_sadMxNxK(4, 4, 3)
|
||||
highbd_sadMxNxK(4, 4, 8)
|
||||
highbd_sadMxNx4D(4, 4)
|
||||
/* clang-format on */
|
||||
#endif // CONFIG_AOM_HIGHBITDEPTH
|
||||
|
||||
#if CONFIG_AV1 && CONFIG_EXT_INTER
|
||||
static INLINE
|
||||
unsigned int masked_sad(const uint8_t *a, int a_stride, const uint8_t *b,
|
||||
int b_stride, const uint8_t *m, int m_stride,
|
||||
int width, int height) {
|
||||
int y, x;
|
||||
unsigned int sad = 0;
|
||||
|
||||
for (y = 0; y < height; y++) {
|
||||
for (x = 0; x < width; x++) sad += m[x] * abs(a[x] - b[x]);
|
||||
|
||||
a += a_stride;
|
||||
b += b_stride;
|
||||
m += m_stride;
|
||||
}
|
||||
sad = (sad + 31) >> 6;
|
||||
|
||||
return sad;
|
||||
}
|
||||
|
||||
#define MASKSADMxN(m, n) \
|
||||
unsigned int aom_masked_sad##m##x##n##_c( \
|
||||
const uint8_t *src, int src_stride, const uint8_t *ref, int ref_stride, \
|
||||
const uint8_t *msk, int msk_stride) { \
|
||||
return masked_sad(src, src_stride, ref, ref_stride, msk, msk_stride, m, \
|
||||
n); \
|
||||
}
|
||||
|
||||
/* clang-format off */
|
||||
#if CONFIG_EXT_PARTITION
|
||||
MASKSADMxN(128, 128)
|
||||
MASKSADMxN(128, 64)
|
||||
MASKSADMxN(64, 128)
|
||||
#endif // CONFIG_EXT_PARTITION
|
||||
MASKSADMxN(64, 64)
|
||||
MASKSADMxN(64, 32)
|
||||
MASKSADMxN(32, 64)
|
||||
MASKSADMxN(32, 32)
|
||||
MASKSADMxN(32, 16)
|
||||
MASKSADMxN(16, 32)
|
||||
MASKSADMxN(16, 16)
|
||||
MASKSADMxN(16, 8)
|
||||
MASKSADMxN(8, 16)
|
||||
MASKSADMxN(8, 8)
|
||||
MASKSADMxN(8, 4)
|
||||
MASKSADMxN(4, 8)
|
||||
MASKSADMxN(4, 4)
|
||||
/* clang-format on */
|
||||
|
||||
#if CONFIG_AOM_HIGHBITDEPTH
|
||||
static INLINE
|
||||
unsigned int highbd_masked_sad(const uint8_t *a8, int a_stride,
|
||||
const uint8_t *b8, int b_stride,
|
||||
const uint8_t *m, int m_stride, int width,
|
||||
int height) {
|
||||
int y, x;
|
||||
unsigned int sad = 0;
|
||||
const uint16_t *a = CONVERT_TO_SHORTPTR(a8);
|
||||
const uint16_t *b = CONVERT_TO_SHORTPTR(b8);
|
||||
|
||||
for (y = 0; y < height; y++) {
|
||||
for (x = 0; x < width; x++) sad += m[x] * abs(a[x] - b[x]);
|
||||
|
||||
a += a_stride;
|
||||
b += b_stride;
|
||||
m += m_stride;
|
||||
}
|
||||
sad = (sad + 31) >> 6;
|
||||
|
||||
return sad;
|
||||
}
|
||||
|
||||
#define HIGHBD_MASKSADMXN(m, n) \
|
||||
unsigned int aom_highbd_masked_sad##m##x##n##_c( \
|
||||
const uint8_t *src, int src_stride, const uint8_t *ref, int ref_stride, \
|
||||
const uint8_t *msk, int msk_stride) { \
|
||||
return highbd_masked_sad(src, src_stride, ref, ref_stride, msk, \
|
||||
msk_stride, m, n); \
|
||||
}
|
||||
|
||||
#if CONFIG_EXT_PARTITION
|
||||
HIGHBD_MASKSADMXN(128, 128)
|
||||
HIGHBD_MASKSADMXN(128, 64)
|
||||
HIGHBD_MASKSADMXN(64, 128)
|
||||
#endif // CONFIG_EXT_PARTITION
|
||||
HIGHBD_MASKSADMXN(64, 64)
|
||||
HIGHBD_MASKSADMXN(64, 32)
|
||||
HIGHBD_MASKSADMXN(32, 64)
|
||||
HIGHBD_MASKSADMXN(32, 32)
|
||||
HIGHBD_MASKSADMXN(32, 16)
|
||||
HIGHBD_MASKSADMXN(16, 32)
|
||||
HIGHBD_MASKSADMXN(16, 16)
|
||||
HIGHBD_MASKSADMXN(16, 8)
|
||||
HIGHBD_MASKSADMXN(8, 16)
|
||||
HIGHBD_MASKSADMXN(8, 8)
|
||||
HIGHBD_MASKSADMXN(8, 4)
|
||||
HIGHBD_MASKSADMXN(4, 8)
|
||||
HIGHBD_MASKSADMXN(4, 4)
|
||||
#endif // CONFIG_AOM_HIGHBITDEPTH
|
||||
#endif // CONFIG_AV1 && CONFIG_EXT_INTER
|
||||
|
||||
#if CONFIG_AV1 && CONFIG_MOTION_VAR
|
||||
// pre: predictor being evaluated
|
||||
// wsrc: target weighted prediction (has been *4096 to keep precision)
|
||||
// mask: 2d weights (scaled by 4096)
|
||||
static INLINE unsigned int obmc_sad(const uint8_t *pre, int pre_stride,
|
||||
const int32_t *wsrc, const int32_t *mask,
|
||||
int width, int height) {
|
||||
int y, x;
|
||||
unsigned int sad = 0;
|
||||
|
||||
for (y = 0; y < height; y++) {
|
||||
for (x = 0; x < width; x++)
|
||||
sad += ROUND_POWER_OF_TWO(abs(wsrc[x] - pre[x] * mask[x]), 12);
|
||||
|
||||
pre += pre_stride;
|
||||
wsrc += width;
|
||||
mask += width;
|
||||
}
|
||||
|
||||
return sad;
|
||||
}
|
||||
|
||||
#define OBMCSADMxN(m, n) \
|
||||
unsigned int aom_obmc_sad##m##x##n##_c(const uint8_t *ref, int ref_stride, \
|
||||
const int32_t *wsrc, \
|
||||
const int32_t *mask) { \
|
||||
return obmc_sad(ref, ref_stride, wsrc, mask, m, n); \
|
||||
}
|
||||
|
||||
/* clang-format off */
|
||||
#if CONFIG_EXT_PARTITION
|
||||
OBMCSADMxN(128, 128)
|
||||
OBMCSADMxN(128, 64)
|
||||
OBMCSADMxN(64, 128)
|
||||
#endif // CONFIG_EXT_PARTITION
|
||||
OBMCSADMxN(64, 64)
|
||||
OBMCSADMxN(64, 32)
|
||||
OBMCSADMxN(32, 64)
|
||||
OBMCSADMxN(32, 32)
|
||||
OBMCSADMxN(32, 16)
|
||||
OBMCSADMxN(16, 32)
|
||||
OBMCSADMxN(16, 16)
|
||||
OBMCSADMxN(16, 8)
|
||||
OBMCSADMxN(8, 16)
|
||||
OBMCSADMxN(8, 8)
|
||||
OBMCSADMxN(8, 4)
|
||||
OBMCSADMxN(4, 8)
|
||||
OBMCSADMxN(4, 4)
|
||||
/* clang-format on */
|
||||
|
||||
#if CONFIG_AOM_HIGHBITDEPTH
|
||||
static INLINE
|
||||
unsigned int highbd_obmc_sad(const uint8_t *pre8, int pre_stride,
|
||||
const int32_t *wsrc, const int32_t *mask,
|
||||
int width, int height) {
|
||||
int y, x;
|
||||
unsigned int sad = 0;
|
||||
const uint16_t *pre = CONVERT_TO_SHORTPTR(pre8);
|
||||
|
||||
for (y = 0; y < height; y++) {
|
||||
for (x = 0; x < width; x++)
|
||||
sad += ROUND_POWER_OF_TWO(abs(wsrc[x] - pre[x] * mask[x]), 12);
|
||||
|
||||
pre += pre_stride;
|
||||
wsrc += width;
|
||||
mask += width;
|
||||
}
|
||||
|
||||
return sad;
|
||||
}
|
||||
|
||||
#define HIGHBD_OBMCSADMXN(m, n) \
|
||||
unsigned int aom_highbd_obmc_sad##m##x##n##_c( \
|
||||
const uint8_t *ref, int ref_stride, const int32_t *wsrc, \
|
||||
const int32_t *mask) { \
|
||||
return highbd_obmc_sad(ref, ref_stride, wsrc, mask, m, n); \
|
||||
}
|
||||
|
||||
/* clang-format off */
|
||||
#if CONFIG_EXT_PARTITION
|
||||
HIGHBD_OBMCSADMXN(128, 128)
|
||||
HIGHBD_OBMCSADMXN(128, 64)
|
||||
HIGHBD_OBMCSADMXN(64, 128)
|
||||
#endif // CONFIG_EXT_PARTITION
|
||||
HIGHBD_OBMCSADMXN(64, 64)
|
||||
HIGHBD_OBMCSADMXN(64, 32)
|
||||
HIGHBD_OBMCSADMXN(32, 64)
|
||||
HIGHBD_OBMCSADMXN(32, 32)
|
||||
HIGHBD_OBMCSADMXN(32, 16)
|
||||
HIGHBD_OBMCSADMXN(16, 32)
|
||||
HIGHBD_OBMCSADMXN(16, 16)
|
||||
HIGHBD_OBMCSADMXN(16, 8)
|
||||
HIGHBD_OBMCSADMXN(8, 16)
|
||||
HIGHBD_OBMCSADMXN(8, 8)
|
||||
HIGHBD_OBMCSADMXN(8, 4)
|
||||
HIGHBD_OBMCSADMXN(4, 8)
|
||||
HIGHBD_OBMCSADMXN(4, 4)
|
||||
/* clang-format on */
|
||||
#endif // CONFIG_AOM_HIGHBITDEPTH
|
||||
#endif // CONFIG_AV1 && CONFIG_MOTION_VAR
|
||||
@@ -1,259 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2016, Alliance for Open Media. All rights reserved
|
||||
*
|
||||
* This source code is subject to the terms of the BSD 2 Clause License and
|
||||
* the Alliance for Open Media Patent License 1.0. If the BSD 2 Clause License
|
||||
* was not distributed with this source code in the LICENSE file, you can
|
||||
* obtain it at www.aomedia.org/license/software. If the Alliance for Open
|
||||
* Media Patent License 1.0 was not distributed with this source code in the
|
||||
* PATENTS file, you can obtain it at www.aomedia.org/license/patent.
|
||||
*/
|
||||
|
||||
#ifndef _V128_INTRINSICS_H
|
||||
#define _V128_INTRINSICS_H
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include "./v128_intrinsics_c.h"
|
||||
#include "./v64_intrinsics.h"
|
||||
|
||||
/* Fallback to plain, unoptimised C. */
|
||||
|
||||
typedef c_v128 v128;
|
||||
|
||||
SIMD_INLINE uint32_t v128_low_u32(v128 a) { return c_v128_low_u32(a); }
|
||||
SIMD_INLINE v64 v128_low_v64(v128 a) { return c_v128_low_v64(a); }
|
||||
SIMD_INLINE v64 v128_high_v64(v128 a) { return c_v128_high_v64(a); }
|
||||
SIMD_INLINE v128 v128_from_64(uint64_t hi, uint64_t lo) {
|
||||
return c_v128_from_64(hi, lo);
|
||||
}
|
||||
SIMD_INLINE v128 v128_from_v64(v64 hi, v64 lo) {
|
||||
return c_v128_from_v64(hi, lo);
|
||||
}
|
||||
SIMD_INLINE v128 v128_from_32(uint32_t a, uint32_t b, uint32_t c, uint32_t d) {
|
||||
return c_v128_from_32(a, b, c, d);
|
||||
}
|
||||
|
||||
SIMD_INLINE v128 v128_load_unaligned(const void *p) {
|
||||
return c_v128_load_unaligned(p);
|
||||
}
|
||||
SIMD_INLINE v128 v128_load_aligned(const void *p) {
|
||||
return c_v128_load_aligned(p);
|
||||
}
|
||||
|
||||
SIMD_INLINE void v128_store_unaligned(void *p, v128 a) {
|
||||
c_v128_store_unaligned(p, a);
|
||||
}
|
||||
SIMD_INLINE void v128_store_aligned(void *p, v128 a) {
|
||||
c_v128_store_aligned(p, a);
|
||||
}
|
||||
|
||||
SIMD_INLINE v128 v128_align(v128 a, v128 b, const unsigned int c) {
|
||||
return c_v128_align(a, b, c);
|
||||
}
|
||||
|
||||
SIMD_INLINE v128 v128_zero() { return c_v128_zero(); }
|
||||
SIMD_INLINE v128 v128_dup_8(uint8_t x) { return c_v128_dup_8(x); }
|
||||
SIMD_INLINE v128 v128_dup_16(uint16_t x) { return c_v128_dup_16(x); }
|
||||
SIMD_INLINE v128 v128_dup_32(uint32_t x) { return c_v128_dup_32(x); }
|
||||
|
||||
typedef uint32_t sad128_internal;
|
||||
SIMD_INLINE sad128_internal v128_sad_u8_init() { return c_v128_sad_u8_init(); }
|
||||
SIMD_INLINE sad128_internal v128_sad_u8(sad128_internal s, v128 a, v128 b) {
|
||||
return c_v128_sad_u8(s, a, b);
|
||||
}
|
||||
SIMD_INLINE uint32_t v128_sad_u8_sum(sad128_internal s) {
|
||||
return c_v128_sad_u8_sum(s);
|
||||
}
|
||||
typedef uint32_t ssd128_internal;
|
||||
SIMD_INLINE ssd128_internal v128_ssd_u8_init() { return c_v128_ssd_u8_init(); }
|
||||
SIMD_INLINE ssd128_internal v128_ssd_u8(ssd128_internal s, v128 a, v128 b) {
|
||||
return c_v128_ssd_u8(s, a, b);
|
||||
}
|
||||
SIMD_INLINE uint32_t v128_ssd_u8_sum(ssd128_internal s) {
|
||||
return c_v128_ssd_u8_sum(s);
|
||||
}
|
||||
SIMD_INLINE int64_t v128_dotp_s16(v128 a, v128 b) {
|
||||
return c_v128_dotp_s16(a, b);
|
||||
}
|
||||
SIMD_INLINE uint64_t v128_hadd_u8(v128 a) { return c_v128_hadd_u8(a); }
|
||||
|
||||
SIMD_INLINE v128 v128_or(v128 a, v128 b) { return c_v128_or(a, b); }
|
||||
SIMD_INLINE v128 v128_xor(v128 a, v128 b) { return c_v128_xor(a, b); }
|
||||
SIMD_INLINE v128 v128_and(v128 a, v128 b) { return c_v128_and(a, b); }
|
||||
SIMD_INLINE v128 v128_andn(v128 a, v128 b) { return c_v128_andn(a, b); }
|
||||
|
||||
SIMD_INLINE v128 v128_add_8(v128 a, v128 b) { return c_v128_add_8(a, b); }
|
||||
SIMD_INLINE v128 v128_add_16(v128 a, v128 b) { return c_v128_add_16(a, b); }
|
||||
SIMD_INLINE v128 v128_sadd_s16(v128 a, v128 b) { return c_v128_sadd_s16(a, b); }
|
||||
SIMD_INLINE v128 v128_add_32(v128 a, v128 b) { return c_v128_add_32(a, b); }
|
||||
SIMD_INLINE v128 v128_padd_s16(v128 a) { return c_v128_padd_s16(a); }
|
||||
SIMD_INLINE v128 v128_sub_8(v128 a, v128 b) { return c_v128_sub_8(a, b); }
|
||||
SIMD_INLINE v128 v128_ssub_u8(v128 a, v128 b) { return c_v128_ssub_u8(a, b); }
|
||||
SIMD_INLINE v128 v128_ssub_s8(v128 a, v128 b) { return c_v128_ssub_s8(a, b); }
|
||||
SIMD_INLINE v128 v128_sub_16(v128 a, v128 b) { return c_v128_sub_16(a, b); }
|
||||
SIMD_INLINE v128 v128_ssub_s16(v128 a, v128 b) { return c_v128_ssub_s16(a, b); }
|
||||
SIMD_INLINE v128 v128_sub_32(v128 a, v128 b) { return c_v128_sub_32(a, b); }
|
||||
SIMD_INLINE v128 v128_abs_s16(v128 a) { return c_v128_abs_s16(a); }
|
||||
|
||||
SIMD_INLINE v128 v128_mul_s16(v64 a, v64 b) { return c_v128_mul_s16(a, b); }
|
||||
SIMD_INLINE v128 v128_mullo_s16(v128 a, v128 b) {
|
||||
return c_v128_mullo_s16(a, b);
|
||||
}
|
||||
SIMD_INLINE v128 v128_mulhi_s16(v128 a, v128 b) {
|
||||
return c_v128_mulhi_s16(a, b);
|
||||
}
|
||||
SIMD_INLINE v128 v128_mullo_s32(v128 a, v128 b) {
|
||||
return c_v128_mullo_s32(a, b);
|
||||
}
|
||||
SIMD_INLINE v128 v128_madd_s16(v128 a, v128 b) { return c_v128_madd_s16(a, b); }
|
||||
SIMD_INLINE v128 v128_madd_us8(v128 a, v128 b) { return c_v128_madd_us8(a, b); }
|
||||
|
||||
SIMD_INLINE v128 v128_avg_u8(v128 a, v128 b) { return c_v128_avg_u8(a, b); }
|
||||
SIMD_INLINE v128 v128_rdavg_u8(v128 a, v128 b) { return c_v128_rdavg_u8(a, b); }
|
||||
SIMD_INLINE v128 v128_avg_u16(v128 a, v128 b) { return c_v128_avg_u16(a, b); }
|
||||
SIMD_INLINE v128 v128_min_u8(v128 a, v128 b) { return c_v128_min_u8(a, b); }
|
||||
SIMD_INLINE v128 v128_max_u8(v128 a, v128 b) { return c_v128_max_u8(a, b); }
|
||||
SIMD_INLINE v128 v128_min_s8(v128 a, v128 b) { return c_v128_min_s8(a, b); }
|
||||
SIMD_INLINE v128 v128_max_s8(v128 a, v128 b) { return c_v128_max_s8(a, b); }
|
||||
SIMD_INLINE v128 v128_min_s16(v128 a, v128 b) { return c_v128_min_s16(a, b); }
|
||||
SIMD_INLINE v128 v128_max_s16(v128 a, v128 b) { return c_v128_max_s16(a, b); }
|
||||
|
||||
SIMD_INLINE v128 v128_ziplo_8(v128 a, v128 b) { return c_v128_ziplo_8(a, b); }
|
||||
SIMD_INLINE v128 v128_ziphi_8(v128 a, v128 b) { return c_v128_ziphi_8(a, b); }
|
||||
SIMD_INLINE v128 v128_ziplo_16(v128 a, v128 b) { return c_v128_ziplo_16(a, b); }
|
||||
SIMD_INLINE v128 v128_ziphi_16(v128 a, v128 b) { return c_v128_ziphi_16(a, b); }
|
||||
SIMD_INLINE v128 v128_ziplo_32(v128 a, v128 b) { return c_v128_ziplo_32(a, b); }
|
||||
SIMD_INLINE v128 v128_ziphi_32(v128 a, v128 b) { return c_v128_ziphi_32(a, b); }
|
||||
SIMD_INLINE v128 v128_ziplo_64(v128 a, v128 b) { return c_v128_ziplo_64(a, b); }
|
||||
SIMD_INLINE v128 v128_ziphi_64(v128 a, v128 b) { return c_v128_ziphi_64(a, b); }
|
||||
SIMD_INLINE v128 v128_zip_8(v64 a, v64 b) { return c_v128_zip_8(a, b); }
|
||||
SIMD_INLINE v128 v128_zip_16(v64 a, v64 b) { return c_v128_zip_16(a, b); }
|
||||
SIMD_INLINE v128 v128_zip_32(v64 a, v64 b) { return c_v128_zip_32(a, b); }
|
||||
SIMD_INLINE v128 v128_unziplo_8(v128 a, v128 b) {
|
||||
return c_v128_unziplo_8(a, b);
|
||||
}
|
||||
SIMD_INLINE v128 v128_unziphi_8(v128 a, v128 b) {
|
||||
return c_v128_unziphi_8(a, b);
|
||||
}
|
||||
SIMD_INLINE v128 v128_unziplo_16(v128 a, v128 b) {
|
||||
return c_v128_unziplo_16(a, b);
|
||||
}
|
||||
SIMD_INLINE v128 v128_unziphi_16(v128 a, v128 b) {
|
||||
return c_v128_unziphi_16(a, b);
|
||||
}
|
||||
SIMD_INLINE v128 v128_unziplo_32(v128 a, v128 b) {
|
||||
return c_v128_unziplo_32(a, b);
|
||||
}
|
||||
SIMD_INLINE v128 v128_unziphi_32(v128 a, v128 b) {
|
||||
return c_v128_unziphi_32(a, b);
|
||||
}
|
||||
SIMD_INLINE v128 v128_unpack_u8_s16(v64 a) { return c_v128_unpack_u8_s16(a); }
|
||||
SIMD_INLINE v128 v128_unpacklo_u8_s16(v128 a) {
|
||||
return c_v128_unpacklo_u8_s16(a);
|
||||
}
|
||||
SIMD_INLINE v128 v128_unpackhi_u8_s16(v128 a) {
|
||||
return c_v128_unpackhi_u8_s16(a);
|
||||
}
|
||||
SIMD_INLINE v128 v128_pack_s32_s16(v128 a, v128 b) {
|
||||
return c_v128_pack_s32_s16(a, b);
|
||||
}
|
||||
SIMD_INLINE v128 v128_pack_s16_u8(v128 a, v128 b) {
|
||||
return c_v128_pack_s16_u8(a, b);
|
||||
}
|
||||
SIMD_INLINE v128 v128_pack_s16_s8(v128 a, v128 b) {
|
||||
return c_v128_pack_s16_s8(a, b);
|
||||
}
|
||||
SIMD_INLINE v128 v128_unpack_u16_s32(v64 a) { return c_v128_unpack_u16_s32(a); }
|
||||
SIMD_INLINE v128 v128_unpack_s16_s32(v64 a) { return c_v128_unpack_s16_s32(a); }
|
||||
SIMD_INLINE v128 v128_unpacklo_u16_s32(v128 a) {
|
||||
return c_v128_unpacklo_u16_s32(a);
|
||||
}
|
||||
SIMD_INLINE v128 v128_unpacklo_s16_s32(v128 a) {
|
||||
return c_v128_unpacklo_s16_s32(a);
|
||||
}
|
||||
SIMD_INLINE v128 v128_unpackhi_u16_s32(v128 a) {
|
||||
return c_v128_unpackhi_u16_s32(a);
|
||||
}
|
||||
SIMD_INLINE v128 v128_unpackhi_s16_s32(v128 a) {
|
||||
return c_v128_unpackhi_s16_s32(a);
|
||||
}
|
||||
SIMD_INLINE v128 v128_shuffle_8(v128 a, v128 pattern) {
|
||||
return c_v128_shuffle_8(a, pattern);
|
||||
}
|
||||
|
||||
SIMD_INLINE v128 v128_cmpgt_s8(v128 a, v128 b) { return c_v128_cmpgt_s8(a, b); }
|
||||
SIMD_INLINE v128 v128_cmplt_s8(v128 a, v128 b) { return c_v128_cmplt_s8(a, b); }
|
||||
SIMD_INLINE v128 v128_cmpeq_8(v128 a, v128 b) { return c_v128_cmpeq_8(a, b); }
|
||||
SIMD_INLINE v128 v128_cmpgt_s16(v128 a, v128 b) {
|
||||
return c_v128_cmpgt_s16(a, b);
|
||||
}
|
||||
SIMD_INLINE v128 v128_cmplt_s16(v128 a, v128 b) {
|
||||
return c_v128_cmplt_s16(a, b);
|
||||
}
|
||||
SIMD_INLINE v128 v128_cmpeq_16(v128 a, v128 b) { return c_v128_cmpeq_16(a, b); }
|
||||
|
||||
SIMD_INLINE v128 v128_shl_8(v128 a, unsigned int c) {
|
||||
return c_v128_shl_8(a, c);
|
||||
}
|
||||
SIMD_INLINE v128 v128_shr_u8(v128 a, unsigned int c) {
|
||||
return c_v128_shr_u8(a, c);
|
||||
}
|
||||
SIMD_INLINE v128 v128_shr_s8(v128 a, unsigned int c) {
|
||||
return c_v128_shr_s8(a, c);
|
||||
}
|
||||
SIMD_INLINE v128 v128_shl_16(v128 a, unsigned int c) {
|
||||
return c_v128_shl_16(a, c);
|
||||
}
|
||||
SIMD_INLINE v128 v128_shr_u16(v128 a, unsigned int c) {
|
||||
return c_v128_shr_u16(a, c);
|
||||
}
|
||||
SIMD_INLINE v128 v128_shr_s16(v128 a, unsigned int c) {
|
||||
return c_v128_shr_s16(a, c);
|
||||
}
|
||||
SIMD_INLINE v128 v128_shl_32(v128 a, unsigned int c) {
|
||||
return c_v128_shl_32(a, c);
|
||||
}
|
||||
SIMD_INLINE v128 v128_shr_u32(v128 a, unsigned int c) {
|
||||
return c_v128_shr_u32(a, c);
|
||||
}
|
||||
SIMD_INLINE v128 v128_shr_s32(v128 a, unsigned int c) {
|
||||
return c_v128_shr_s32(a, c);
|
||||
}
|
||||
|
||||
SIMD_INLINE v128 v128_shr_n_byte(v128 a, const unsigned int n) {
|
||||
return c_v128_shr_n_byte(a, n);
|
||||
}
|
||||
SIMD_INLINE v128 v128_shl_n_byte(v128 a, const unsigned int n) {
|
||||
return c_v128_shl_n_byte(a, n);
|
||||
}
|
||||
SIMD_INLINE v128 v128_shl_n_8(v128 a, const unsigned int n) {
|
||||
return c_v128_shl_n_8(a, n);
|
||||
}
|
||||
SIMD_INLINE v128 v128_shl_n_16(v128 a, const unsigned int n) {
|
||||
return c_v128_shl_n_16(a, n);
|
||||
}
|
||||
SIMD_INLINE v128 v128_shl_n_32(v128 a, const unsigned int n) {
|
||||
return c_v128_shl_n_32(a, n);
|
||||
}
|
||||
SIMD_INLINE v128 v128_shr_n_u8(v128 a, const unsigned int n) {
|
||||
return c_v128_shr_n_u8(a, n);
|
||||
}
|
||||
SIMD_INLINE v128 v128_shr_n_u16(v128 a, const unsigned int n) {
|
||||
return c_v128_shr_n_u16(a, n);
|
||||
}
|
||||
SIMD_INLINE v128 v128_shr_n_u32(v128 a, const unsigned int n) {
|
||||
return c_v128_shr_n_u32(a, n);
|
||||
}
|
||||
SIMD_INLINE v128 v128_shr_n_s8(v128 a, const unsigned int n) {
|
||||
return c_v128_shr_n_s8(a, n);
|
||||
}
|
||||
SIMD_INLINE v128 v128_shr_n_s16(v128 a, const unsigned int n) {
|
||||
return c_v128_shr_n_s16(a, n);
|
||||
}
|
||||
SIMD_INLINE v128 v128_shr_n_s32(v128 a, const unsigned int n) {
|
||||
return c_v128_shr_n_s32(a, n);
|
||||
}
|
||||
|
||||
#endif /* _V128_INTRINSICS_H */
|
||||
@@ -1,655 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2016, Alliance for Open Media. All rights reserved
|
||||
*
|
||||
* This source code is subject to the terms of the BSD 2 Clause License and
|
||||
* the Alliance for Open Media Patent License 1.0. If the BSD 2 Clause License
|
||||
* was not distributed with this source code in the LICENSE file, you can
|
||||
* obtain it at www.aomedia.org/license/software. If the Alliance for Open
|
||||
* Media Patent License 1.0 was not distributed with this source code in the
|
||||
* PATENTS file, you can obtain it at www.aomedia.org/license/patent.
|
||||
*/
|
||||
|
||||
#ifndef _V128_INTRINSICS_H
|
||||
#define _V128_INTRINSICS_H
|
||||
|
||||
#include <arm_neon.h>
|
||||
#include "./v64_intrinsics_arm.h"
|
||||
|
||||
typedef int64x2_t v128;
|
||||
|
||||
SIMD_INLINE uint32_t v128_low_u32(v128 a) {
|
||||
return v64_low_u32(vget_low_s64(a));
|
||||
}
|
||||
|
||||
SIMD_INLINE v64 v128_low_v64(v128 a) { return vget_low_s64(a); }
|
||||
|
||||
SIMD_INLINE v64 v128_high_v64(v128 a) { return vget_high_s64(a); }
|
||||
|
||||
SIMD_INLINE v128 v128_from_v64(v64 a, v64 b) { return vcombine_s64(b, a); }
|
||||
|
||||
SIMD_INLINE v128 v128_from_64(uint64_t a, uint64_t b) {
|
||||
return vcombine_s64((uint64x1_t)b, (uint64x1_t)a);
|
||||
}
|
||||
|
||||
SIMD_INLINE v128 v128_from_32(uint32_t a, uint32_t b, uint32_t c, uint32_t d) {
|
||||
return vcombine_s64(v64_from_32(c, d), v64_from_32(a, b));
|
||||
}
|
||||
|
||||
SIMD_INLINE v128 v128_load_aligned(const void *p) {
|
||||
return vreinterpretq_s64_u8(vld1q_u8((const uint8_t *)p));
|
||||
}
|
||||
|
||||
SIMD_INLINE v128 v128_load_unaligned(const void *p) {
|
||||
return v128_load_aligned(p);
|
||||
}
|
||||
|
||||
SIMD_INLINE void v128_store_aligned(void *p, v128 r) {
|
||||
vst1q_u8((uint8_t *)p, vreinterpretq_u8_s64(r));
|
||||
}
|
||||
|
||||
SIMD_INLINE void v128_store_unaligned(void *p, v128 r) {
|
||||
vst1q_u8((uint8_t *)p, vreinterpretq_u8_s64(r));
|
||||
}
|
||||
|
||||
SIMD_INLINE v128 v128_align(v128 a, v128 b, const unsigned int c) {
|
||||
// The following functions require an immediate.
|
||||
// Some compilers will check this during optimisation, others wont.
|
||||
#if __OPTIMIZE__ && !__clang__
|
||||
return c ? vreinterpretq_s64_s8(
|
||||
vextq_s8(vreinterpretq_s8_s64(b), vreinterpretq_s8_s64(a), c))
|
||||
: b;
|
||||
#else
|
||||
return c < 8 ? v128_from_v64(v64_align(v128_low_v64(a), v128_high_v64(b), c),
|
||||
v64_align(v128_high_v64(b), v128_low_v64(b), c))
|
||||
: v128_from_v64(
|
||||
v64_align(v128_high_v64(a), v128_low_v64(a), c - 8),
|
||||
v64_align(v128_low_v64(a), v128_high_v64(b), c - 8));
|
||||
#endif
|
||||
}
|
||||
|
||||
SIMD_INLINE v128 v128_zero() { return vreinterpretq_s64_u8(vdupq_n_u8(0)); }
|
||||
|
||||
SIMD_INLINE v128 v128_ones() { return vreinterpretq_s64_u8(vdupq_n_u8(-1)); }
|
||||
|
||||
SIMD_INLINE v128 v128_dup_8(uint8_t x) {
|
||||
return vreinterpretq_s64_u8(vdupq_n_u8(x));
|
||||
}
|
||||
|
||||
SIMD_INLINE v128 v128_dup_16(uint16_t x) {
|
||||
return vreinterpretq_s64_u16(vdupq_n_u16(x));
|
||||
}
|
||||
|
||||
SIMD_INLINE v128 v128_dup_32(uint32_t x) {
|
||||
return vreinterpretq_s64_u32(vdupq_n_u32(x));
|
||||
}
|
||||
|
||||
SIMD_INLINE int64_t v128_dotp_s16(v128 a, v128 b) {
|
||||
return v64_dotp_s16(vget_high_s64(a), vget_high_s64(b)) +
|
||||
v64_dotp_s16(vget_low_s64(a), vget_low_s64(b));
|
||||
}
|
||||
|
||||
SIMD_INLINE uint64_t v128_hadd_u8(v128 x) {
|
||||
uint64x2_t t = vpaddlq_u32(vpaddlq_u16(vpaddlq_u8(vreinterpretq_u8_s64(x))));
|
||||
return vget_lane_s32(
|
||||
vreinterpret_s32_u64(vadd_u64(vget_high_u64(t), vget_low_u64(t))), 0);
|
||||
}
|
||||
|
||||
SIMD_INLINE v128 v128_padd_s16(v128 a) {
|
||||
return vreinterpretq_s64_s32(vpaddlq_s16(vreinterpretq_s16_s64(a)));
|
||||
}
|
||||
|
||||
typedef struct { sad64_internal hi, lo; } sad128_internal;
|
||||
|
||||
SIMD_INLINE sad128_internal v128_sad_u8_init() {
|
||||
sad128_internal s;
|
||||
s.hi = s.lo = vdupq_n_u16(0);
|
||||
return s;
|
||||
}
|
||||
|
||||
/* Implementation dependent return value. Result must be finalised with
|
||||
v128_sad_u8_sum().
|
||||
The result for more than 32 v128_sad_u8() calls is undefined. */
|
||||
SIMD_INLINE sad128_internal v128_sad_u8(sad128_internal s, v128 a, v128 b) {
|
||||
sad128_internal r;
|
||||
r.hi = v64_sad_u8(s.hi, vget_high_s64(a), vget_high_s64(b));
|
||||
r.lo = v64_sad_u8(s.lo, vget_low_s64(a), vget_low_s64(b));
|
||||
return r;
|
||||
}
|
||||
|
||||
SIMD_INLINE uint32_t v128_sad_u8_sum(sad128_internal s) {
|
||||
return (uint32_t)(v64_sad_u8_sum(s.hi) + v64_sad_u8_sum(s.lo));
|
||||
}
|
||||
|
||||
typedef struct { ssd64_internal hi, lo; } ssd128_internal;
|
||||
|
||||
SIMD_INLINE ssd128_internal v128_ssd_u8_init() {
|
||||
ssd128_internal s;
|
||||
s.hi = s.lo = (ssd64_internal)(uint64_t)0;
|
||||
return s;
|
||||
}
|
||||
|
||||
/* Implementation dependent return value. Result must be finalised with
|
||||
* v128_ssd_u8_sum(). */
|
||||
SIMD_INLINE ssd128_internal v128_ssd_u8(ssd128_internal s, v128 a, v128 b) {
|
||||
ssd128_internal r;
|
||||
r.hi = v64_ssd_u8(s.hi, vget_high_s64(a), vget_high_s64(b));
|
||||
r.lo = v64_ssd_u8(s.lo, vget_low_s64(a), vget_low_s64(b));
|
||||
return r;
|
||||
}
|
||||
|
||||
SIMD_INLINE uint32_t v128_ssd_u8_sum(ssd128_internal s) {
|
||||
return (uint32_t)(v64_ssd_u8_sum(s.hi) + v64_ssd_u8_sum(s.lo));
|
||||
}
|
||||
|
||||
SIMD_INLINE v128 v128_or(v128 x, v128 y) { return vorrq_s64(x, y); }
|
||||
|
||||
SIMD_INLINE v128 v128_xor(v128 x, v128 y) { return veorq_s64(x, y); }
|
||||
|
||||
SIMD_INLINE v128 v128_and(v128 x, v128 y) { return vandq_s64(x, y); }
|
||||
|
||||
SIMD_INLINE v128 v128_andn(v128 x, v128 y) { return vbicq_s64(x, y); }
|
||||
|
||||
SIMD_INLINE v128 v128_add_8(v128 x, v128 y) {
|
||||
return vreinterpretq_s64_u8(
|
||||
vaddq_u8(vreinterpretq_u8_s64(x), vreinterpretq_u8_s64(y)));
|
||||
}
|
||||
|
||||
SIMD_INLINE v128 v128_add_16(v128 x, v128 y) {
|
||||
return vreinterpretq_s64_s16(
|
||||
vaddq_s16(vreinterpretq_s16_s64(x), vreinterpretq_s16_s64(y)));
|
||||
}
|
||||
|
||||
SIMD_INLINE v128 v128_sadd_s16(v128 x, v128 y) {
|
||||
return vreinterpretq_s64_s16(
|
||||
vqaddq_s16(vreinterpretq_s16_s64(x), vreinterpretq_s16_s64(y)));
|
||||
}
|
||||
|
||||
SIMD_INLINE v128 v128_add_32(v128 x, v128 y) {
|
||||
return vreinterpretq_s64_u32(
|
||||
vaddq_u32(vreinterpretq_u32_s64(x), vreinterpretq_u32_s64(y)));
|
||||
}
|
||||
|
||||
SIMD_INLINE v128 v128_sub_8(v128 x, v128 y) {
|
||||
return vreinterpretq_s64_u8(
|
||||
vsubq_u8(vreinterpretq_u8_s64(x), vreinterpretq_u8_s64(y)));
|
||||
}
|
||||
|
||||
SIMD_INLINE v128 v128_sub_u8(v128 x, v128 y) {
|
||||
return vreinterpretq_s64_u8(
|
||||
vqsubq_u8(vreinterpretq_u8_s64(x), vreinterpretq_u8_s64(y)));
|
||||
}
|
||||
|
||||
SIMD_INLINE v128 v128_sub_16(v128 x, v128 y) {
|
||||
return vreinterpretq_s64_s16(
|
||||
vsubq_s16(vreinterpretq_s16_s64(x), vreinterpretq_s16_s64(y)));
|
||||
}
|
||||
|
||||
SIMD_INLINE v128 v128_ssub_s16(v128 x, v128 y) {
|
||||
return vreinterpretq_s64_s16(
|
||||
vqsubq_s16(vreinterpretq_s16_s64(x), vreinterpretq_s16_s64(y)));
|
||||
}
|
||||
|
||||
SIMD_INLINE v128 v128_ssub_u8(v128 x, v128 y) {
|
||||
return vreinterpretq_s64_u8(
|
||||
vqsubq_u8(vreinterpretq_u8_s64(x), vreinterpretq_u8_s64(y)));
|
||||
}
|
||||
|
||||
SIMD_INLINE v128 v128_ssub_s8(v128 x, v128 y) {
|
||||
return vreinterpretq_s64_s8(
|
||||
vqsubq_s8(vreinterpretq_s8_s64(x), vreinterpretq_s8_s64(y)));
|
||||
}
|
||||
|
||||
SIMD_INLINE v128 v128_sub_32(v128 x, v128 y) {
|
||||
return vreinterpretq_s64_s32(
|
||||
vsubq_s32(vreinterpretq_s32_s64(x), vreinterpretq_s32_s64(y)));
|
||||
}
|
||||
|
||||
SIMD_INLINE v128 v128_abs_s16(v128 x) {
|
||||
return vreinterpretq_s64_s16(vabsq_s16(vreinterpretq_s16_s64(x)));
|
||||
}
|
||||
|
||||
SIMD_INLINE v128 v128_mul_s16(v64 a, v64 b) {
|
||||
return vreinterpretq_s64_s32(
|
||||
vmull_s16(vreinterpret_s16_s64(a), vreinterpret_s16_s64(b)));
|
||||
}
|
||||
|
||||
SIMD_INLINE v128 v128_mullo_s16(v128 a, v128 b) {
|
||||
return vreinterpretq_s64_s16(
|
||||
vmulq_s16(vreinterpretq_s16_s64(a), vreinterpretq_s16_s64(b)));
|
||||
}
|
||||
|
||||
SIMD_INLINE v128 v128_mulhi_s16(v128 a, v128 b) {
|
||||
return v128_from_v64(v64_mulhi_s16(vget_high_s64(a), vget_high_s64(b)),
|
||||
v64_mulhi_s16(vget_low_s64(a), vget_low_s64(b)));
|
||||
}
|
||||
|
||||
SIMD_INLINE v128 v128_mullo_s32(v128 a, v128 b) {
|
||||
return vreinterpretq_s64_s32(
|
||||
vmulq_s32(vreinterpretq_s32_s64(a), vreinterpretq_s32_s64(b)));
|
||||
}
|
||||
|
||||
SIMD_INLINE v128 v128_madd_s16(v128 a, v128 b) {
|
||||
return v128_from_v64(v64_madd_s16(vget_high_s64(a), vget_high_s64(b)),
|
||||
v64_madd_s16(vget_low_s64(a), vget_low_s64(b)));
|
||||
}
|
||||
|
||||
SIMD_INLINE v128 v128_madd_us8(v128 a, v128 b) {
|
||||
return v128_from_v64(v64_madd_us8(vget_high_s64(a), vget_high_s64(b)),
|
||||
v64_madd_us8(vget_low_s64(a), vget_low_s64(b)));
|
||||
}
|
||||
|
||||
SIMD_INLINE v128 v128_avg_u8(v128 x, v128 y) {
|
||||
return vreinterpretq_s64_u8(
|
||||
vrhaddq_u8(vreinterpretq_u8_s64(x), vreinterpretq_u8_s64(y)));
|
||||
}
|
||||
|
||||
SIMD_INLINE v128 v128_rdavg_u8(v128 x, v128 y) {
|
||||
return vreinterpretq_s64_u8(
|
||||
vhaddq_u8(vreinterpretq_u8_s64(x), vreinterpretq_u8_s64(y)));
|
||||
}
|
||||
|
||||
SIMD_INLINE v128 v128_avg_u16(v128 x, v128 y) {
|
||||
return vreinterpretq_s64_u16(
|
||||
vrhaddq_u16(vreinterpretq_u16_s64(x), vreinterpretq_u16_s64(y)));
|
||||
}
|
||||
|
||||
SIMD_INLINE v128 v128_min_u8(v128 x, v128 y) {
|
||||
return vreinterpretq_s64_u8(
|
||||
vminq_u8(vreinterpretq_u8_s64(x), vreinterpretq_u8_s64(y)));
|
||||
}
|
||||
|
||||
SIMD_INLINE v128 v128_max_u8(v128 x, v128 y) {
|
||||
return vreinterpretq_s64_u8(
|
||||
vmaxq_u8(vreinterpretq_u8_s64(x), vreinterpretq_u8_s64(y)));
|
||||
}
|
||||
|
||||
SIMD_INLINE v128 v128_min_s8(v128 x, v128 y) {
|
||||
return vreinterpretq_s64_s8(
|
||||
vminq_s8(vreinterpretq_s8_s64(x), vreinterpretq_s8_s64(y)));
|
||||
}
|
||||
|
||||
SIMD_INLINE v128 v128_max_s8(v128 x, v128 y) {
|
||||
return vreinterpretq_s64_s8(
|
||||
vmaxq_s8(vreinterpretq_s8_s64(x), vreinterpretq_s8_s64(y)));
|
||||
}
|
||||
|
||||
SIMD_INLINE v128 v128_min_s16(v128 x, v128 y) {
|
||||
return vreinterpretq_s64_s16(
|
||||
vminq_s16(vreinterpretq_s16_s64(x), vreinterpretq_s16_s64(y)));
|
||||
}
|
||||
|
||||
SIMD_INLINE v128 v128_max_s16(v128 x, v128 y) {
|
||||
return vreinterpretq_s64_s16(
|
||||
vmaxq_s16(vreinterpretq_s16_s64(x), vreinterpretq_s16_s64(y)));
|
||||
}
|
||||
|
||||
SIMD_INLINE v128 v128_ziplo_8(v128 x, v128 y) {
|
||||
uint8x16x2_t r = vzipq_u8(vreinterpretq_u8_s64(y), vreinterpretq_u8_s64(x));
|
||||
return vreinterpretq_s64_u8(r.val[0]);
|
||||
}
|
||||
|
||||
SIMD_INLINE v128 v128_ziphi_8(v128 x, v128 y) {
|
||||
uint8x16x2_t r = vzipq_u8(vreinterpretq_u8_s64(y), vreinterpretq_u8_s64(x));
|
||||
return vreinterpretq_s64_u8(r.val[1]);
|
||||
}
|
||||
|
||||
SIMD_INLINE v128 v128_zip_8(v64 x, v64 y) {
|
||||
uint8x8x2_t r = vzip_u8(vreinterpret_u8_s64(y), vreinterpret_u8_s64(x));
|
||||
return vreinterpretq_s64_u8(vcombine_u8(r.val[0], r.val[1]));
|
||||
}
|
||||
|
||||
SIMD_INLINE v128 v128_ziplo_16(v128 x, v128 y) {
|
||||
int16x8x2_t r = vzipq_s16(vreinterpretq_s16_s64(y), vreinterpretq_s16_s64(x));
|
||||
return vreinterpretq_s64_s16(r.val[0]);
|
||||
}
|
||||
|
||||
SIMD_INLINE v128 v128_ziphi_16(v128 x, v128 y) {
|
||||
int16x8x2_t r = vzipq_s16(vreinterpretq_s16_s64(y), vreinterpretq_s16_s64(x));
|
||||
return vreinterpretq_s64_s16(r.val[1]);
|
||||
}
|
||||
|
||||
SIMD_INLINE v128 v128_zip_16(v64 x, v64 y) {
|
||||
uint16x4x2_t r = vzip_u16(vreinterpret_u16_s64(y), vreinterpret_u16_s64(x));
|
||||
return vreinterpretq_s64_u16(vcombine_u16(r.val[0], r.val[1]));
|
||||
}
|
||||
|
||||
SIMD_INLINE v128 v128_ziplo_32(v128 x, v128 y) {
|
||||
int32x4x2_t r = vzipq_s32(vreinterpretq_s32_s64(y), vreinterpretq_s32_s64(x));
|
||||
return vreinterpretq_s64_s32(r.val[0]);
|
||||
}
|
||||
|
||||
SIMD_INLINE v128 v128_ziphi_32(v128 x, v128 y) {
|
||||
int32x4x2_t r = vzipq_s32(vreinterpretq_s32_s64(y), vreinterpretq_s32_s64(x));
|
||||
return vreinterpretq_s64_s32(r.val[1]);
|
||||
}
|
||||
|
||||
SIMD_INLINE v128 v128_zip_32(v64 x, v64 y) {
|
||||
uint32x2x2_t r = vzip_u32(vreinterpret_u32_s64(y), vreinterpret_u32_s64(x));
|
||||
return vreinterpretq_s64_u32(vcombine_u32(r.val[0], r.val[1]));
|
||||
}
|
||||
|
||||
SIMD_INLINE v128 v128_ziplo_64(v128 a, v128 b) {
|
||||
return v128_from_v64(vget_low_u64((uint64x2_t)a),
|
||||
vget_low_u64((uint64x2_t)b));
|
||||
}
|
||||
|
||||
SIMD_INLINE v128 v128_ziphi_64(v128 a, v128 b) {
|
||||
return v128_from_v64(vget_high_u64((uint64x2_t)a),
|
||||
vget_high_u64((uint64x2_t)b));
|
||||
}
|
||||
|
||||
SIMD_INLINE v128 v128_unziplo_8(v128 x, v128 y) {
|
||||
uint8x16x2_t r = vuzpq_u8(vreinterpretq_u8_s64(y), vreinterpretq_u8_s64(x));
|
||||
return vreinterpretq_s64_u8(r.val[0]);
|
||||
}
|
||||
|
||||
SIMD_INLINE v128 v128_unziphi_8(v128 x, v128 y) {
|
||||
uint8x16x2_t r = vuzpq_u8(vreinterpretq_u8_s64(y), vreinterpretq_u8_s64(x));
|
||||
return vreinterpretq_s64_u8(r.val[1]);
|
||||
}
|
||||
|
||||
SIMD_INLINE v128 v128_unziplo_16(v128 x, v128 y) {
|
||||
uint16x8x2_t r =
|
||||
vuzpq_u16(vreinterpretq_u16_s64(y), vreinterpretq_u16_s64(x));
|
||||
return vreinterpretq_s64_u16(r.val[0]);
|
||||
}
|
||||
|
||||
SIMD_INLINE v128 v128_unziphi_16(v128 x, v128 y) {
|
||||
uint16x8x2_t r =
|
||||
vuzpq_u16(vreinterpretq_u16_s64(y), vreinterpretq_u16_s64(x));
|
||||
return vreinterpretq_s64_u16(r.val[1]);
|
||||
}
|
||||
|
||||
SIMD_INLINE v128 v128_unziplo_32(v128 x, v128 y) {
|
||||
uint32x4x2_t r =
|
||||
vuzpq_u32(vreinterpretq_u32_s64(y), vreinterpretq_u32_s64(x));
|
||||
return vreinterpretq_s64_u32(r.val[0]);
|
||||
}
|
||||
|
||||
SIMD_INLINE v128 v128_unziphi_32(v128 x, v128 y) {
|
||||
uint32x4x2_t r =
|
||||
vuzpq_u32(vreinterpretq_u32_s64(y), vreinterpretq_u32_s64(x));
|
||||
return vreinterpretq_s64_u32(r.val[1]);
|
||||
}
|
||||
|
||||
SIMD_INLINE v128 v128_unpack_u8_s16(v64 a) {
|
||||
return vreinterpretq_s64_u16(vmovl_u8(vreinterpret_u8_s64(a)));
|
||||
}
|
||||
|
||||
SIMD_INLINE v128 v128_unpacklo_u8_s16(v128 a) {
|
||||
return vreinterpretq_s64_u16(vmovl_u8(vreinterpret_u8_s64(vget_low_s64(a))));
|
||||
}
|
||||
|
||||
SIMD_INLINE v128 v128_unpackhi_u8_s16(v128 a) {
|
||||
return vreinterpretq_s64_u16(vmovl_u8(vreinterpret_u8_s64(vget_high_s64(a))));
|
||||
}
|
||||
|
||||
SIMD_INLINE v128 v128_pack_s32_s16(v128 a, v128 b) {
|
||||
return v128_from_v64(
|
||||
vreinterpret_s64_s16(vqmovn_s32(vreinterpretq_s32_s64(a))),
|
||||
vreinterpret_s64_s16(vqmovn_s32(vreinterpretq_s32_s64(b))));
|
||||
}
|
||||
|
||||
SIMD_INLINE v128 v128_pack_s16_u8(v128 a, v128 b) {
|
||||
return v128_from_v64(
|
||||
vreinterpret_s64_u8(vqmovun_s16(vreinterpretq_s16_s64(a))),
|
||||
vreinterpret_s64_u8(vqmovun_s16(vreinterpretq_s16_s64(b))));
|
||||
}
|
||||
|
||||
SIMD_INLINE v128 v128_pack_s16_s8(v128 a, v128 b) {
|
||||
return v128_from_v64(
|
||||
vreinterpret_s64_s8(vqmovn_s16(vreinterpretq_s16_s64(a))),
|
||||
vreinterpret_s64_s8(vqmovn_s16(vreinterpretq_s16_s64(b))));
|
||||
}
|
||||
|
||||
SIMD_INLINE v128 v128_unpack_u16_s32(v64 a) {
|
||||
return vreinterpretq_s64_u32(vmovl_u16(vreinterpret_u16_s64(a)));
|
||||
}
|
||||
|
||||
SIMD_INLINE v128 v128_unpack_s16_s32(v64 a) {
|
||||
return vreinterpretq_s64_s32(vmovl_s16(vreinterpret_s16_s64(a)));
|
||||
}
|
||||
|
||||
SIMD_INLINE v128 v128_unpacklo_u16_s32(v128 a) {
|
||||
return vreinterpretq_s64_u32(
|
||||
vmovl_u16(vreinterpret_u16_s64(vget_low_s64(a))));
|
||||
}
|
||||
|
||||
SIMD_INLINE v128 v128_unpacklo_s16_s32(v128 a) {
|
||||
return vreinterpretq_s64_s32(
|
||||
vmovl_s16(vreinterpret_s16_s64(vget_low_s64(a))));
|
||||
}
|
||||
|
||||
SIMD_INLINE v128 v128_unpackhi_u16_s32(v128 a) {
|
||||
return vreinterpretq_s64_u32(
|
||||
vmovl_u16(vreinterpret_u16_s64(vget_high_s64(a))));
|
||||
}
|
||||
|
||||
SIMD_INLINE v128 v128_unpackhi_s16_s32(v128 a) {
|
||||
return vreinterpretq_s64_s32(
|
||||
vmovl_s16(vreinterpret_s16_s64(vget_high_s64(a))));
|
||||
}
|
||||
|
||||
SIMD_INLINE v128 v128_shuffle_8(v128 x, v128 pattern) {
|
||||
return v128_from_64(
|
||||
(uint64_t)vreinterpret_s64_u8(
|
||||
vtbl2_u8((uint8x8x2_t){ { vget_low_u8(vreinterpretq_u8_s64(x)),
|
||||
vget_high_u8(vreinterpretq_u8_s64(x)) } },
|
||||
vreinterpret_u8_s64(vget_high_s64(pattern)))),
|
||||
(uint64_t)vreinterpret_s64_u8(
|
||||
vtbl2_u8((uint8x8x2_t){ { vget_low_u8(vreinterpretq_u8_s64(x)),
|
||||
vget_high_u8(vreinterpretq_u8_s64(x)) } },
|
||||
vreinterpret_u8_s64(vget_low_s64(pattern)))));
|
||||
}
|
||||
|
||||
SIMD_INLINE v128 v128_cmpgt_s8(v128 x, v128 y) {
|
||||
return vreinterpretq_s64_u8(
|
||||
vcgtq_s8(vreinterpretq_s8_s64(x), vreinterpretq_s8_s64(y)));
|
||||
}
|
||||
|
||||
SIMD_INLINE v128 v128_cmplt_s8(v128 x, v128 y) {
|
||||
return vreinterpretq_s64_u8(
|
||||
vcltq_s8(vreinterpretq_s8_s64(x), vreinterpretq_s8_s64(y)));
|
||||
}
|
||||
|
||||
SIMD_INLINE v128 v128_cmpeq_8(v128 x, v128 y) {
|
||||
return vreinterpretq_s64_u8(
|
||||
vceqq_u8(vreinterpretq_u8_s64(x), vreinterpretq_u8_s64(y)));
|
||||
}
|
||||
|
||||
SIMD_INLINE v128 v128_cmpgt_s16(v128 x, v128 y) {
|
||||
return vreinterpretq_s64_u16(
|
||||
vcgtq_s16(vreinterpretq_s16_s64(x), vreinterpretq_s16_s64(y)));
|
||||
}
|
||||
|
||||
SIMD_INLINE v128 v128_cmplt_s16(v128 x, v128 y) {
|
||||
return vreinterpretq_s64_u16(
|
||||
vcltq_s16(vreinterpretq_s16_s64(x), vreinterpretq_s16_s64(y)));
|
||||
}
|
||||
|
||||
SIMD_INLINE v128 v128_cmpeq_16(v128 x, v128 y) {
|
||||
return vreinterpretq_s64_u16(
|
||||
vceqq_s16(vreinterpretq_s16_s64(x), vreinterpretq_s16_s64(y)));
|
||||
}
|
||||
|
||||
SIMD_INLINE v128 v128_shl_8(v128 a, unsigned int c) {
|
||||
return (c > 7) ? v128_zero() : vreinterpretq_s64_u8(vshlq_u8(
|
||||
vreinterpretq_u8_s64(a), vdupq_n_s8(c)));
|
||||
}
|
||||
|
||||
SIMD_INLINE v128 v128_shr_u8(v128 a, unsigned int c) {
|
||||
return (c > 7) ? v128_zero() : vreinterpretq_s64_u8(vshlq_u8(
|
||||
vreinterpretq_u8_s64(a), vdupq_n_s8(-c)));
|
||||
}
|
||||
|
||||
SIMD_INLINE v128 v128_shr_s8(v128 a, unsigned int c) {
|
||||
return (c > 7) ? v128_ones() : vreinterpretq_s64_s8(vshlq_s8(
|
||||
vreinterpretq_s8_s64(a), vdupq_n_s8(-c)));
|
||||
}
|
||||
|
||||
SIMD_INLINE v128 v128_shl_16(v128 a, unsigned int c) {
|
||||
return (c > 15) ? v128_zero()
|
||||
: vreinterpretq_s64_u16(
|
||||
vshlq_u16(vreinterpretq_u16_s64(a), vdupq_n_s16(c)));
|
||||
}
|
||||
|
||||
SIMD_INLINE v128 v128_shr_u16(v128 a, unsigned int c) {
|
||||
return (c > 15) ? v128_zero()
|
||||
: vreinterpretq_s64_u16(
|
||||
vshlq_u16(vreinterpretq_u16_s64(a), vdupq_n_s16(-c)));
|
||||
}
|
||||
|
||||
SIMD_INLINE v128 v128_shr_s16(v128 a, unsigned int c) {
|
||||
return (c > 15) ? v128_ones()
|
||||
: vreinterpretq_s64_s16(
|
||||
vshlq_s16(vreinterpretq_s16_s64(a), vdupq_n_s16(-c)));
|
||||
}
|
||||
|
||||
SIMD_INLINE v128 v128_shl_32(v128 a, unsigned int c) {
|
||||
return (c > 31) ? v128_zero()
|
||||
: vreinterpretq_s64_u32(
|
||||
vshlq_u32(vreinterpretq_u32_s64(a), vdupq_n_s32(c)));
|
||||
}
|
||||
|
||||
SIMD_INLINE v128 v128_shr_u32(v128 a, unsigned int c) {
|
||||
return (c > 31) ? v128_zero()
|
||||
: vreinterpretq_s64_u32(
|
||||
vshlq_u32(vreinterpretq_u32_s64(a), vdupq_n_s32(-c)));
|
||||
}
|
||||
|
||||
SIMD_INLINE v128 v128_shr_s32(v128 a, unsigned int c) {
|
||||
return (c > 31) ? v128_ones()
|
||||
: vreinterpretq_s64_s32(
|
||||
vshlq_s32(vreinterpretq_s32_s64(a), vdupq_n_s32(-c)));
|
||||
}
|
||||
|
||||
#if __OPTIMIZE__ && !__clang__
|
||||
|
||||
SIMD_INLINE v128 v128_shl_n_byte(v128 a, const unsigned int n) {
|
||||
return n < 8
|
||||
? v128_from_64(
|
||||
(uint64_t)vorr_u64(
|
||||
vshl_n_u64(vreinterpret_u64_s64(vget_high_s64(a)),
|
||||
n * 8),
|
||||
vshr_n_u64(vreinterpret_u64_s64(vget_low_s64(a)),
|
||||
(8 - n) * 8)),
|
||||
(uint64_t)vshl_n_u64(vreinterpret_u64_s64(vget_low_s64(a)),
|
||||
n * 8))
|
||||
: (n == 8 ? v128_from_64(
|
||||
(uint64_t)vreinterpret_u64_s64(vget_low_s64(a)), 0)
|
||||
: v128_from_64((uint64_t)vshl_n_u64(
|
||||
vreinterpret_u64_s64(vget_low_s64(a)),
|
||||
(n - 8) * 8),
|
||||
0));
|
||||
}
|
||||
|
||||
SIMD_INLINE v128 v128_shr_n_byte(v128 a, const unsigned int n) {
|
||||
return n < 8
|
||||
? v128_from_64(
|
||||
vshr_n_u64(vreinterpret_u64_s64(vget_high_s64(a)), n * 8),
|
||||
vorr_u64(
|
||||
vshr_n_u64(vreinterpret_u64_s64(vget_low_s64(a)), n * 8),
|
||||
vshl_n_u64(vreinterpret_u64_s64(vget_high_s64(a)),
|
||||
(8 - n) * 8)))
|
||||
: (n == 8
|
||||
? v128_from_64(0, vreinterpret_u64_s64(vget_high_s64(a)))
|
||||
: v128_from_64(
|
||||
0, vshr_n_u64(vreinterpret_u64_s64(vget_high_s64(a)),
|
||||
(n - 8) * 8)));
|
||||
}
|
||||
|
||||
SIMD_INLINE v128 v128_shl_n_8(v128 a, const unsigned int c) {
|
||||
return vreinterpretq_s64_u8(vshlq_n_u8(vreinterpretq_u8_s64(a), c));
|
||||
}
|
||||
|
||||
SIMD_INLINE v128 v128_shr_n_u8(v128 a, const unsigned int c) {
|
||||
return vreinterpretq_s64_u8(vshrq_n_u8(vreinterpretq_u8_s64(a), c));
|
||||
}
|
||||
|
||||
SIMD_INLINE v128 v128_shr_n_s8(v128 a, const unsigned int c) {
|
||||
return vreinterpretq_s64_s8(vshrq_n_s8(vreinterpretq_s8_s64(a), c));
|
||||
}
|
||||
|
||||
SIMD_INLINE v128 v128_shl_n_16(v128 a, const unsigned int c) {
|
||||
return vreinterpretq_s64_u16(vshlq_n_u16(vreinterpretq_u16_s64(a), c));
|
||||
}
|
||||
|
||||
SIMD_INLINE v128 v128_shr_n_u16(v128 a, const unsigned int c) {
|
||||
return vreinterpretq_s64_u16(vshrq_n_u16(vreinterpretq_u16_s64(a), c));
|
||||
}
|
||||
|
||||
SIMD_INLINE v128 v128_shr_n_s16(v128 a, const unsigned int c) {
|
||||
return vreinterpretq_s64_s16(vshrq_n_s16(vreinterpretq_s16_s64(a), c));
|
||||
}
|
||||
|
||||
SIMD_INLINE v128 v128_shl_n_32(v128 a, const unsigned int c) {
|
||||
return vreinterpretq_s64_u32(vshlq_n_u32(vreinterpretq_u32_s64(a), c));
|
||||
}
|
||||
|
||||
SIMD_INLINE v128 v128_shr_n_u32(v128 a, const unsigned int c) {
|
||||
return vreinterpretq_s64_u32(vshrq_n_u32(vreinterpretq_u32_s64(a), c));
|
||||
}
|
||||
|
||||
SIMD_INLINE v128 v128_shr_n_s32(v128 a, const unsigned int c) {
|
||||
return vreinterpretq_s64_s32(vshrq_n_s32(vreinterpretq_s32_s64(a), c));
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
SIMD_INLINE v128 v128_shl_n_byte(v128 a, const unsigned int n) {
|
||||
if (n < 8)
|
||||
return v128_from_v64(v64_or(v64_shl_n_byte(v128_high_v64(a), n),
|
||||
v64_shr_n_byte(v128_low_v64(a), 8 - n)),
|
||||
v64_shl_n_byte(v128_low_v64(a), n));
|
||||
else
|
||||
return v128_from_v64(v64_shl_n_byte(v128_low_v64(a), n - 8), v64_zero());
|
||||
}
|
||||
|
||||
SIMD_INLINE v128 v128_shr_n_byte(v128 a, const unsigned int n) {
|
||||
if (n < 8)
|
||||
return v128_from_v64(v64_shr_n_byte(v128_high_v64(a), n),
|
||||
v64_or(v64_shr_n_byte(v128_low_v64(a), n),
|
||||
v64_shl_n_byte(v128_high_v64(a), 8 - n)));
|
||||
else
|
||||
return v128_from_v64(v64_zero(), v64_shr_n_byte(v128_high_v64(a), n - 8));
|
||||
}
|
||||
|
||||
SIMD_INLINE v128 v128_shl_n_8(v128 a, const unsigned int c) {
|
||||
return v128_shl_8(a, c);
|
||||
}
|
||||
|
||||
SIMD_INLINE v128 v128_shr_n_u8(v128 a, const unsigned int c) {
|
||||
return v128_shr_u8(a, c);
|
||||
}
|
||||
|
||||
SIMD_INLINE v128 v128_shr_n_s8(v128 a, const unsigned int c) {
|
||||
return v128_shr_s8(a, c);
|
||||
}
|
||||
|
||||
SIMD_INLINE v128 v128_shl_n_16(v128 a, const unsigned int c) {
|
||||
return v128_shl_16(a, c);
|
||||
}
|
||||
|
||||
SIMD_INLINE v128 v128_shr_n_u16(v128 a, const unsigned int c) {
|
||||
return v128_shr_u16(a, c);
|
||||
}
|
||||
|
||||
SIMD_INLINE v128 v128_shr_n_s16(v128 a, const unsigned int c) {
|
||||
return v128_shr_s16(a, c);
|
||||
}
|
||||
|
||||
SIMD_INLINE v128 v128_shl_n_32(v128 a, const unsigned int c) {
|
||||
return v128_shl_32(a, c);
|
||||
}
|
||||
|
||||
SIMD_INLINE v128 v128_shr_n_u32(v128 a, const unsigned int c) {
|
||||
return v128_shr_u32(a, c);
|
||||
}
|
||||
|
||||
SIMD_INLINE v128 v128_shr_n_s32(v128 a, const unsigned int c) {
|
||||
return v128_shr_s32(a, c);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#endif /* _V128_INTRINSICS_H */
|
||||
@@ -1,684 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2016, Alliance for Open Media. All rights reserved
|
||||
*
|
||||
* This source code is subject to the terms of the BSD 2 Clause License and
|
||||
* the Alliance for Open Media Patent License 1.0. If the BSD 2 Clause License
|
||||
* was not distributed with this source code in the LICENSE file, you can
|
||||
* obtain it at www.aomedia.org/license/software. If the Alliance for Open
|
||||
* Media Patent License 1.0 was not distributed with this source code in the
|
||||
* PATENTS file, you can obtain it at www.aomedia.org/license/patent.
|
||||
*/
|
||||
|
||||
#ifndef _V128_INTRINSICS_C_H
|
||||
#define _V128_INTRINSICS_C_H
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include "./v64_intrinsics_c.h"
|
||||
#include "./aom_config.h"
|
||||
|
||||
typedef union {
|
||||
uint8_t u8[16];
|
||||
uint16_t u16[8];
|
||||
uint32_t u32[4];
|
||||
uint64_t u64[2];
|
||||
int8_t s8[16];
|
||||
int16_t s16[8];
|
||||
int32_t s32[4];
|
||||
int64_t s64[2];
|
||||
c_v64 v64[2];
|
||||
} c_v128;
|
||||
|
||||
SIMD_INLINE uint32_t c_v128_low_u32(c_v128 a) { return a.u32[0]; }
|
||||
|
||||
SIMD_INLINE c_v64 c_v128_low_v64(c_v128 a) { return a.v64[0]; }
|
||||
|
||||
SIMD_INLINE c_v64 c_v128_high_v64(c_v128 a) { return a.v64[1]; }
|
||||
|
||||
SIMD_INLINE c_v128 c_v128_from_64(uint64_t hi, uint64_t lo) {
|
||||
c_v128 t;
|
||||
t.u64[1] = hi;
|
||||
t.u64[0] = lo;
|
||||
return t;
|
||||
}
|
||||
|
||||
SIMD_INLINE c_v128 c_v128_from_v64(c_v64 hi, c_v64 lo) {
|
||||
c_v128 t;
|
||||
t.v64[1] = hi;
|
||||
t.v64[0] = lo;
|
||||
return t;
|
||||
}
|
||||
|
||||
SIMD_INLINE c_v128 c_v128_from_32(uint32_t a, uint32_t b, uint32_t c,
|
||||
uint32_t d) {
|
||||
c_v128 t;
|
||||
t.u32[3] = a;
|
||||
t.u32[2] = b;
|
||||
t.u32[1] = c;
|
||||
t.u32[0] = d;
|
||||
return t;
|
||||
}
|
||||
|
||||
SIMD_INLINE c_v128 c_v128_load_unaligned(const void *p) {
|
||||
c_v128 t;
|
||||
uint8_t *pp = (uint8_t *)p;
|
||||
uint8_t *q = (uint8_t *)&t;
|
||||
int c;
|
||||
for (c = 0; c < 16; c++) q[c] = pp[c];
|
||||
return t;
|
||||
}
|
||||
|
||||
SIMD_INLINE c_v128 c_v128_load_aligned(const void *p) {
|
||||
if (simd_check && (uintptr_t)p & 15) {
|
||||
fprintf(stderr, "Error: unaligned v128 load at %p\n", p);
|
||||
abort();
|
||||
}
|
||||
return c_v128_load_unaligned(p);
|
||||
}
|
||||
|
||||
SIMD_INLINE void c_v128_store_unaligned(void *p, c_v128 a) {
|
||||
uint8_t *pp = (uint8_t *)p;
|
||||
uint8_t *q = (uint8_t *)&a;
|
||||
int c;
|
||||
for (c = 0; c < 16; c++) pp[c] = q[c];
|
||||
}
|
||||
|
||||
SIMD_INLINE void c_v128_store_aligned(void *p, c_v128 a) {
|
||||
if (simd_check && (uintptr_t)p & 15) {
|
||||
fprintf(stderr, "Error: unaligned v128 store at %p\n", p);
|
||||
abort();
|
||||
}
|
||||
c_v128_store_unaligned(p, a);
|
||||
}
|
||||
|
||||
SIMD_INLINE c_v128 c_v128_zero() {
|
||||
c_v128 t;
|
||||
t.u64[1] = t.u64[0] = 0;
|
||||
return t;
|
||||
}
|
||||
|
||||
SIMD_INLINE c_v128 c_v128_dup_8(uint8_t x) {
|
||||
c_v128 t;
|
||||
t.v64[1] = t.v64[0] = c_v64_dup_8(x);
|
||||
return t;
|
||||
}
|
||||
|
||||
SIMD_INLINE c_v128 c_v128_dup_16(uint16_t x) {
|
||||
c_v128 t;
|
||||
t.v64[1] = t.v64[0] = c_v64_dup_16(x);
|
||||
return t;
|
||||
}
|
||||
|
||||
SIMD_INLINE c_v128 c_v128_dup_32(uint32_t x) {
|
||||
c_v128 t;
|
||||
t.v64[1] = t.v64[0] = c_v64_dup_32(x);
|
||||
return t;
|
||||
}
|
||||
|
||||
SIMD_INLINE int64_t c_v128_dotp_s16(c_v128 a, c_v128 b) {
|
||||
return c_v64_dotp_s16(a.v64[1], b.v64[1]) +
|
||||
c_v64_dotp_s16(a.v64[0], b.v64[0]);
|
||||
}
|
||||
|
||||
SIMD_INLINE uint64_t c_v128_hadd_u8(c_v128 a) {
|
||||
return c_v64_hadd_u8(a.v64[1]) + c_v64_hadd_u8(a.v64[0]);
|
||||
}
|
||||
|
||||
typedef uint32_t c_sad128_internal;
|
||||
|
||||
SIMD_INLINE c_sad128_internal c_v128_sad_u8_init() { return 0; }
|
||||
|
||||
/* Implementation dependent return value. Result must be finalised with
|
||||
v128_sad_u8_sum().
|
||||
The result for more than 32 v128_sad_u8() calls is undefined. */
|
||||
SIMD_INLINE c_sad128_internal c_v128_sad_u8(c_sad128_internal s, c_v128 a,
|
||||
c_v128 b) {
|
||||
int c;
|
||||
for (c = 0; c < 16; c++)
|
||||
s += a.u8[c] > b.u8[c] ? a.u8[c] - b.u8[c] : b.u8[c] - a.u8[c];
|
||||
return s;
|
||||
}
|
||||
|
||||
SIMD_INLINE uint32_t c_v128_sad_u8_sum(c_sad128_internal s) { return s; }
|
||||
|
||||
typedef uint32_t c_ssd128_internal;
|
||||
|
||||
SIMD_INLINE c_ssd128_internal c_v128_ssd_u8_init() { return 0; }
|
||||
|
||||
/* Implementation dependent return value. Result must be finalised with
|
||||
* v128_ssd_u8_sum(). */
|
||||
SIMD_INLINE c_ssd128_internal c_v128_ssd_u8(c_ssd128_internal s, c_v128 a,
|
||||
c_v128 b) {
|
||||
int c;
|
||||
for (c = 0; c < 16; c++) s += (a.u8[c] - b.u8[c]) * (a.u8[c] - b.u8[c]);
|
||||
return s;
|
||||
}
|
||||
|
||||
SIMD_INLINE uint32_t c_v128_ssd_u8_sum(c_ssd128_internal s) { return s; }
|
||||
|
||||
SIMD_INLINE c_v128 c_v128_or(c_v128 a, c_v128 b) {
|
||||
return c_v128_from_v64(c_v64_or(a.v64[1], b.v64[1]),
|
||||
c_v64_or(a.v64[0], b.v64[0]));
|
||||
}
|
||||
|
||||
SIMD_INLINE c_v128 c_v128_xor(c_v128 a, c_v128 b) {
|
||||
return c_v128_from_v64(c_v64_xor(a.v64[1], b.v64[1]),
|
||||
c_v64_xor(a.v64[0], b.v64[0]));
|
||||
}
|
||||
|
||||
SIMD_INLINE c_v128 c_v128_and(c_v128 a, c_v128 b) {
|
||||
return c_v128_from_v64(c_v64_and(a.v64[1], b.v64[1]),
|
||||
c_v64_and(a.v64[0], b.v64[0]));
|
||||
}
|
||||
|
||||
SIMD_INLINE c_v128 c_v128_andn(c_v128 a, c_v128 b) {
|
||||
return c_v128_from_v64(c_v64_andn(a.v64[1], b.v64[1]),
|
||||
c_v64_andn(a.v64[0], b.v64[0]));
|
||||
}
|
||||
|
||||
SIMD_INLINE c_v128 c_v128_add_8(c_v128 a, c_v128 b) {
|
||||
return c_v128_from_v64(c_v64_add_8(a.v64[1], b.v64[1]),
|
||||
c_v64_add_8(a.v64[0], b.v64[0]));
|
||||
}
|
||||
|
||||
SIMD_INLINE c_v128 c_v128_add_16(c_v128 a, c_v128 b) {
|
||||
return c_v128_from_v64(c_v64_add_16(a.v64[1], b.v64[1]),
|
||||
c_v64_add_16(a.v64[0], b.v64[0]));
|
||||
}
|
||||
|
||||
SIMD_INLINE c_v128 c_v128_sadd_s16(c_v128 a, c_v128 b) {
|
||||
return c_v128_from_v64(c_v64_sadd_s16(a.v64[1], b.v64[1]),
|
||||
c_v64_sadd_s16(a.v64[0], b.v64[0]));
|
||||
}
|
||||
|
||||
SIMD_INLINE c_v128 c_v128_add_32(c_v128 a, c_v128 b) {
|
||||
return c_v128_from_v64(c_v64_add_32(a.v64[1], b.v64[1]),
|
||||
c_v64_add_32(a.v64[0], b.v64[0]));
|
||||
}
|
||||
|
||||
SIMD_INLINE c_v128 c_v128_padd_s16(c_v128 a) {
|
||||
c_v128 t;
|
||||
t.s32[0] = (int32_t)a.s16[0] + (int32_t)a.s16[1];
|
||||
t.s32[1] = (int32_t)a.s16[2] + (int32_t)a.s16[3];
|
||||
t.s32[2] = (int32_t)a.s16[4] + (int32_t)a.s16[5];
|
||||
t.s32[3] = (int32_t)a.s16[6] + (int32_t)a.s16[7];
|
||||
return t;
|
||||
}
|
||||
|
||||
SIMD_INLINE c_v128 c_v128_sub_8(c_v128 a, c_v128 b) {
|
||||
return c_v128_from_v64(c_v64_sub_8(a.v64[1], b.v64[1]),
|
||||
c_v64_sub_8(a.v64[0], b.v64[0]));
|
||||
}
|
||||
|
||||
SIMD_INLINE c_v128 c_v128_ssub_u8(c_v128 a, c_v128 b) {
|
||||
return c_v128_from_v64(c_v64_ssub_u8(a.v64[1], b.v64[1]),
|
||||
c_v64_ssub_u8(a.v64[0], b.v64[0]));
|
||||
}
|
||||
|
||||
SIMD_INLINE c_v128 c_v128_ssub_s8(c_v128 a, c_v128 b) {
|
||||
return c_v128_from_v64(c_v64_ssub_s8(a.v64[1], b.v64[1]),
|
||||
c_v64_ssub_s8(a.v64[0], b.v64[0]));
|
||||
}
|
||||
|
||||
SIMD_INLINE c_v128 c_v128_sub_16(c_v128 a, c_v128 b) {
|
||||
return c_v128_from_v64(c_v64_sub_16(a.v64[1], b.v64[1]),
|
||||
c_v64_sub_16(a.v64[0], b.v64[0]));
|
||||
}
|
||||
|
||||
SIMD_INLINE c_v128 c_v128_ssub_s16(c_v128 a, c_v128 b) {
|
||||
return c_v128_from_v64(c_v64_ssub_s16(a.v64[1], b.v64[1]),
|
||||
c_v64_ssub_s16(a.v64[0], b.v64[0]));
|
||||
}
|
||||
|
||||
SIMD_INLINE c_v128 c_v128_sub_32(c_v128 a, c_v128 b) {
|
||||
return c_v128_from_v64(c_v64_sub_32(a.v64[1], b.v64[1]),
|
||||
c_v64_sub_32(a.v64[0], b.v64[0]));
|
||||
}
|
||||
|
||||
SIMD_INLINE c_v128 c_v128_abs_s16(c_v128 a) {
|
||||
return c_v128_from_v64(c_v64_abs_s16(a.v64[1]), c_v64_abs_s16(a.v64[0]));
|
||||
}
|
||||
|
||||
SIMD_INLINE c_v128 c_v128_mul_s16(c_v64 a, c_v64 b) {
|
||||
c_v64 lo_bits = c_v64_mullo_s16(a, b);
|
||||
c_v64 hi_bits = c_v64_mulhi_s16(a, b);
|
||||
return c_v128_from_v64(c_v64_ziphi_16(hi_bits, lo_bits),
|
||||
c_v64_ziplo_16(hi_bits, lo_bits));
|
||||
}
|
||||
|
||||
SIMD_INLINE c_v128 c_v128_mullo_s16(c_v128 a, c_v128 b) {
|
||||
return c_v128_from_v64(c_v64_mullo_s16(a.v64[1], b.v64[1]),
|
||||
c_v64_mullo_s16(a.v64[0], b.v64[0]));
|
||||
}
|
||||
|
||||
SIMD_INLINE c_v128 c_v128_mulhi_s16(c_v128 a, c_v128 b) {
|
||||
return c_v128_from_v64(c_v64_mulhi_s16(a.v64[1], b.v64[1]),
|
||||
c_v64_mulhi_s16(a.v64[0], b.v64[0]));
|
||||
}
|
||||
|
||||
SIMD_INLINE c_v128 c_v128_mullo_s32(c_v128 a, c_v128 b) {
|
||||
return c_v128_from_v64(c_v64_mullo_s32(a.v64[1], b.v64[1]),
|
||||
c_v64_mullo_s32(a.v64[0], b.v64[0]));
|
||||
}
|
||||
|
||||
SIMD_INLINE c_v128 c_v128_madd_s16(c_v128 a, c_v128 b) {
|
||||
return c_v128_from_v64(c_v64_madd_s16(a.v64[1], b.v64[1]),
|
||||
c_v64_madd_s16(a.v64[0], b.v64[0]));
|
||||
}
|
||||
|
||||
SIMD_INLINE c_v128 c_v128_madd_us8(c_v128 a, c_v128 b) {
|
||||
return c_v128_from_v64(c_v64_madd_us8(a.v64[1], b.v64[1]),
|
||||
c_v64_madd_us8(a.v64[0], b.v64[0]));
|
||||
}
|
||||
|
||||
SIMD_INLINE c_v128 c_v128_avg_u8(c_v128 a, c_v128 b) {
|
||||
return c_v128_from_v64(c_v64_avg_u8(a.v64[1], b.v64[1]),
|
||||
c_v64_avg_u8(a.v64[0], b.v64[0]));
|
||||
}
|
||||
|
||||
SIMD_INLINE c_v128 c_v128_rdavg_u8(c_v128 a, c_v128 b) {
|
||||
return c_v128_from_v64(c_v64_rdavg_u8(a.v64[1], b.v64[1]),
|
||||
c_v64_rdavg_u8(a.v64[0], b.v64[0]));
|
||||
}
|
||||
|
||||
SIMD_INLINE c_v128 c_v128_avg_u16(c_v128 a, c_v128 b) {
|
||||
return c_v128_from_v64(c_v64_avg_u16(a.v64[1], b.v64[1]),
|
||||
c_v64_avg_u16(a.v64[0], b.v64[0]));
|
||||
}
|
||||
|
||||
SIMD_INLINE c_v128 c_v128_min_u8(c_v128 a, c_v128 b) {
|
||||
return c_v128_from_v64(c_v64_min_u8(a.v64[1], b.v64[1]),
|
||||
c_v64_min_u8(a.v64[0], b.v64[0]));
|
||||
}
|
||||
|
||||
SIMD_INLINE c_v128 c_v128_max_u8(c_v128 a, c_v128 b) {
|
||||
return c_v128_from_v64(c_v64_max_u8(a.v64[1], b.v64[1]),
|
||||
c_v64_max_u8(a.v64[0], b.v64[0]));
|
||||
}
|
||||
|
||||
SIMD_INLINE c_v128 c_v128_min_s8(c_v128 a, c_v128 b) {
|
||||
return c_v128_from_v64(c_v64_min_s8(a.v64[1], b.v64[1]),
|
||||
c_v64_min_s8(a.v64[0], b.v64[0]));
|
||||
}
|
||||
|
||||
SIMD_INLINE c_v128 c_v128_max_s8(c_v128 a, c_v128 b) {
|
||||
return c_v128_from_v64(c_v64_max_s8(a.v64[1], b.v64[1]),
|
||||
c_v64_max_s8(a.v64[0], b.v64[0]));
|
||||
}
|
||||
|
||||
SIMD_INLINE c_v128 c_v128_min_s16(c_v128 a, c_v128 b) {
|
||||
return c_v128_from_v64(c_v64_min_s16(a.v64[1], b.v64[1]),
|
||||
c_v64_min_s16(a.v64[0], b.v64[0]));
|
||||
}
|
||||
|
||||
SIMD_INLINE c_v128 c_v128_max_s16(c_v128 a, c_v128 b) {
|
||||
return c_v128_from_v64(c_v64_max_s16(a.v64[1], b.v64[1]),
|
||||
c_v64_max_s16(a.v64[0], b.v64[0]));
|
||||
}
|
||||
|
||||
SIMD_INLINE c_v128 c_v128_ziplo_8(c_v128 a, c_v128 b) {
|
||||
return c_v128_from_v64(c_v64_ziphi_8(a.v64[0], b.v64[0]),
|
||||
c_v64_ziplo_8(a.v64[0], b.v64[0]));
|
||||
}
|
||||
|
||||
SIMD_INLINE c_v128 c_v128_ziphi_8(c_v128 a, c_v128 b) {
|
||||
return c_v128_from_v64(c_v64_ziphi_8(a.v64[1], b.v64[1]),
|
||||
c_v64_ziplo_8(a.v64[1], b.v64[1]));
|
||||
}
|
||||
|
||||
SIMD_INLINE c_v128 c_v128_ziplo_16(c_v128 a, c_v128 b) {
|
||||
return c_v128_from_v64(c_v64_ziphi_16(a.v64[0], b.v64[0]),
|
||||
c_v64_ziplo_16(a.v64[0], b.v64[0]));
|
||||
}
|
||||
|
||||
SIMD_INLINE c_v128 c_v128_ziphi_16(c_v128 a, c_v128 b) {
|
||||
return c_v128_from_v64(c_v64_ziphi_16(a.v64[1], b.v64[1]),
|
||||
c_v64_ziplo_16(a.v64[1], b.v64[1]));
|
||||
}
|
||||
|
||||
SIMD_INLINE c_v128 c_v128_ziplo_32(c_v128 a, c_v128 b) {
|
||||
return c_v128_from_v64(c_v64_ziphi_32(a.v64[0], b.v64[0]),
|
||||
c_v64_ziplo_32(a.v64[0], b.v64[0]));
|
||||
}
|
||||
|
||||
SIMD_INLINE c_v128 c_v128_ziphi_32(c_v128 a, c_v128 b) {
|
||||
return c_v128_from_v64(c_v64_ziphi_32(a.v64[1], b.v64[1]),
|
||||
c_v64_ziplo_32(a.v64[1], b.v64[1]));
|
||||
}
|
||||
|
||||
SIMD_INLINE c_v128 c_v128_ziplo_64(c_v128 a, c_v128 b) {
|
||||
return c_v128_from_v64(a.v64[0], b.v64[0]);
|
||||
}
|
||||
|
||||
SIMD_INLINE c_v128 c_v128_ziphi_64(c_v128 a, c_v128 b) {
|
||||
return c_v128_from_v64(a.v64[1], b.v64[1]);
|
||||
}
|
||||
|
||||
SIMD_INLINE c_v128 c_v128_zip_8(c_v64 a, c_v64 b) {
|
||||
return c_v128_from_v64(c_v64_ziphi_8(a, b), c_v64_ziplo_8(a, b));
|
||||
}
|
||||
|
||||
SIMD_INLINE c_v128 c_v128_zip_16(c_v64 a, c_v64 b) {
|
||||
return c_v128_from_v64(c_v64_ziphi_16(a, b), c_v64_ziplo_16(a, b));
|
||||
}
|
||||
|
||||
SIMD_INLINE c_v128 c_v128_zip_32(c_v64 a, c_v64 b) {
|
||||
return c_v128_from_v64(c_v64_ziphi_32(a, b), c_v64_ziplo_32(a, b));
|
||||
}
|
||||
|
||||
SIMD_INLINE c_v128 _c_v128_unzip_8(c_v128 a, c_v128 b, int mode) {
|
||||
c_v128 t;
|
||||
if (mode) {
|
||||
t.u8[15] = b.u8[15];
|
||||
t.u8[14] = b.u8[13];
|
||||
t.u8[13] = b.u8[11];
|
||||
t.u8[12] = b.u8[9];
|
||||
t.u8[11] = b.u8[7];
|
||||
t.u8[10] = b.u8[5];
|
||||
t.u8[9] = b.u8[3];
|
||||
t.u8[8] = b.u8[1];
|
||||
t.u8[7] = a.u8[15];
|
||||
t.u8[6] = a.u8[13];
|
||||
t.u8[5] = a.u8[11];
|
||||
t.u8[4] = a.u8[9];
|
||||
t.u8[3] = a.u8[7];
|
||||
t.u8[2] = a.u8[5];
|
||||
t.u8[1] = a.u8[3];
|
||||
t.u8[0] = a.u8[1];
|
||||
} else {
|
||||
t.u8[15] = a.u8[14];
|
||||
t.u8[14] = a.u8[12];
|
||||
t.u8[13] = a.u8[10];
|
||||
t.u8[12] = a.u8[8];
|
||||
t.u8[11] = a.u8[6];
|
||||
t.u8[10] = a.u8[4];
|
||||
t.u8[9] = a.u8[2];
|
||||
t.u8[8] = a.u8[0];
|
||||
t.u8[7] = b.u8[14];
|
||||
t.u8[6] = b.u8[12];
|
||||
t.u8[5] = b.u8[10];
|
||||
t.u8[4] = b.u8[8];
|
||||
t.u8[3] = b.u8[6];
|
||||
t.u8[2] = b.u8[4];
|
||||
t.u8[1] = b.u8[2];
|
||||
t.u8[0] = b.u8[0];
|
||||
}
|
||||
return t;
|
||||
}
|
||||
|
||||
SIMD_INLINE c_v128 c_v128_unziplo_8(c_v128 a, c_v128 b) {
|
||||
return CONFIG_BIG_ENDIAN ? _c_v128_unzip_8(a, b, 1)
|
||||
: _c_v128_unzip_8(a, b, 0);
|
||||
}
|
||||
|
||||
SIMD_INLINE c_v128 c_v128_unziphi_8(c_v128 a, c_v128 b) {
|
||||
return CONFIG_BIG_ENDIAN ? _c_v128_unzip_8(b, a, 0)
|
||||
: _c_v128_unzip_8(b, a, 1);
|
||||
}
|
||||
|
||||
SIMD_INLINE c_v128 _c_v128_unzip_16(c_v128 a, c_v128 b, int mode) {
|
||||
c_v128 t;
|
||||
if (mode) {
|
||||
t.u16[7] = b.u16[7];
|
||||
t.u16[6] = b.u16[5];
|
||||
t.u16[5] = b.u16[3];
|
||||
t.u16[4] = b.u16[1];
|
||||
t.u16[3] = a.u16[7];
|
||||
t.u16[2] = a.u16[5];
|
||||
t.u16[1] = a.u16[3];
|
||||
t.u16[0] = a.u16[1];
|
||||
} else {
|
||||
t.u16[7] = a.u16[6];
|
||||
t.u16[6] = a.u16[4];
|
||||
t.u16[5] = a.u16[2];
|
||||
t.u16[4] = a.u16[0];
|
||||
t.u16[3] = b.u16[6];
|
||||
t.u16[2] = b.u16[4];
|
||||
t.u16[1] = b.u16[2];
|
||||
t.u16[0] = b.u16[0];
|
||||
}
|
||||
return t;
|
||||
}
|
||||
|
||||
SIMD_INLINE c_v128 c_v128_unziplo_16(c_v128 a, c_v128 b) {
|
||||
return CONFIG_BIG_ENDIAN ? _c_v128_unzip_16(a, b, 1)
|
||||
: _c_v128_unzip_16(a, b, 0);
|
||||
}
|
||||
|
||||
SIMD_INLINE c_v128 c_v128_unziphi_16(c_v128 a, c_v128 b) {
|
||||
return CONFIG_BIG_ENDIAN ? _c_v128_unzip_16(b, a, 0)
|
||||
: _c_v128_unzip_16(b, a, 1);
|
||||
}
|
||||
|
||||
SIMD_INLINE c_v128 _c_v128_unzip_32(c_v128 a, c_v128 b, int mode) {
|
||||
c_v128 t;
|
||||
if (mode) {
|
||||
t.u32[3] = b.u32[3];
|
||||
t.u32[2] = b.u32[1];
|
||||
t.u32[1] = a.u32[3];
|
||||
t.u32[0] = a.u32[1];
|
||||
} else {
|
||||
t.u32[3] = a.u32[2];
|
||||
t.u32[2] = a.u32[0];
|
||||
t.u32[1] = b.u32[2];
|
||||
t.u32[0] = b.u32[0];
|
||||
}
|
||||
return t;
|
||||
}
|
||||
|
||||
SIMD_INLINE c_v128 c_v128_unziplo_32(c_v128 a, c_v128 b) {
|
||||
return CONFIG_BIG_ENDIAN ? _c_v128_unzip_32(a, b, 1)
|
||||
: _c_v128_unzip_32(a, b, 0);
|
||||
}
|
||||
|
||||
SIMD_INLINE c_v128 c_v128_unziphi_32(c_v128 a, c_v128 b) {
|
||||
return CONFIG_BIG_ENDIAN ? _c_v128_unzip_32(b, a, 0)
|
||||
: _c_v128_unzip_32(b, a, 1);
|
||||
}
|
||||
|
||||
SIMD_INLINE c_v128 c_v128_unpack_u8_s16(c_v64 a) {
|
||||
return c_v128_from_v64(c_v64_unpackhi_u8_s16(a), c_v64_unpacklo_u8_s16(a));
|
||||
}
|
||||
|
||||
SIMD_INLINE c_v128 c_v128_unpacklo_u8_s16(c_v128 a) {
|
||||
return c_v128_from_v64(c_v64_unpackhi_u8_s16(a.v64[0]),
|
||||
c_v64_unpacklo_u8_s16(a.v64[0]));
|
||||
}
|
||||
|
||||
SIMD_INLINE c_v128 c_v128_unpackhi_u8_s16(c_v128 a) {
|
||||
return c_v128_from_v64(c_v64_unpackhi_u8_s16(a.v64[1]),
|
||||
c_v64_unpacklo_u8_s16(a.v64[1]));
|
||||
}
|
||||
|
||||
SIMD_INLINE c_v128 c_v128_pack_s32_s16(c_v128 a, c_v128 b) {
|
||||
return c_v128_from_v64(c_v64_pack_s32_s16(a.v64[1], a.v64[0]),
|
||||
c_v64_pack_s32_s16(b.v64[1], b.v64[0]));
|
||||
}
|
||||
|
||||
SIMD_INLINE c_v128 c_v128_pack_s16_u8(c_v128 a, c_v128 b) {
|
||||
return c_v128_from_v64(c_v64_pack_s16_u8(a.v64[1], a.v64[0]),
|
||||
c_v64_pack_s16_u8(b.v64[1], b.v64[0]));
|
||||
}
|
||||
|
||||
SIMD_INLINE c_v128 c_v128_pack_s16_s8(c_v128 a, c_v128 b) {
|
||||
return c_v128_from_v64(c_v64_pack_s16_s8(a.v64[1], a.v64[0]),
|
||||
c_v64_pack_s16_s8(b.v64[1], b.v64[0]));
|
||||
}
|
||||
|
||||
SIMD_INLINE c_v128 c_v128_unpack_u16_s32(c_v64 a) {
|
||||
return c_v128_from_v64(c_v64_unpackhi_u16_s32(a), c_v64_unpacklo_u16_s32(a));
|
||||
}
|
||||
|
||||
SIMD_INLINE c_v128 c_v128_unpack_s16_s32(c_v64 a) {
|
||||
return c_v128_from_v64(c_v64_unpackhi_s16_s32(a), c_v64_unpacklo_s16_s32(a));
|
||||
}
|
||||
|
||||
SIMD_INLINE c_v128 c_v128_unpacklo_u16_s32(c_v128 a) {
|
||||
return c_v128_from_v64(c_v64_unpackhi_u16_s32(a.v64[0]),
|
||||
c_v64_unpacklo_u16_s32(a.v64[0]));
|
||||
}
|
||||
|
||||
SIMD_INLINE c_v128 c_v128_unpacklo_s16_s32(c_v128 a) {
|
||||
return c_v128_from_v64(c_v64_unpackhi_s16_s32(a.v64[0]),
|
||||
c_v64_unpacklo_s16_s32(a.v64[0]));
|
||||
}
|
||||
|
||||
SIMD_INLINE c_v128 c_v128_unpackhi_u16_s32(c_v128 a) {
|
||||
return c_v128_from_v64(c_v64_unpackhi_u16_s32(a.v64[1]),
|
||||
c_v64_unpacklo_u16_s32(a.v64[1]));
|
||||
}
|
||||
|
||||
SIMD_INLINE c_v128 c_v128_unpackhi_s16_s32(c_v128 a) {
|
||||
return c_v128_from_v64(c_v64_unpackhi_s16_s32(a.v64[1]),
|
||||
c_v64_unpacklo_s16_s32(a.v64[1]));
|
||||
}
|
||||
|
||||
SIMD_INLINE c_v128 c_v128_shuffle_8(c_v128 a, c_v128 pattern) {
|
||||
c_v128 t;
|
||||
int c;
|
||||
for (c = 0; c < 16; c++) {
|
||||
if (pattern.u8[c] & ~15) {
|
||||
fprintf(stderr, "Undefined v128_shuffle_8 index %d/%d\n", pattern.u8[c],
|
||||
c);
|
||||
abort();
|
||||
}
|
||||
t.u8[c] = a.u8[CONFIG_BIG_ENDIAN ? 15 - (pattern.u8[c] & 15)
|
||||
: pattern.u8[c] & 15];
|
||||
}
|
||||
return t;
|
||||
}
|
||||
|
||||
SIMD_INLINE c_v128 c_v128_cmpgt_s8(c_v128 a, c_v128 b) {
|
||||
return c_v128_from_v64(c_v64_cmpgt_s8(a.v64[1], b.v64[1]),
|
||||
c_v64_cmpgt_s8(a.v64[0], b.v64[0]));
|
||||
}
|
||||
|
||||
SIMD_INLINE c_v128 c_v128_cmplt_s8(c_v128 a, c_v128 b) {
|
||||
return c_v128_from_v64(c_v64_cmplt_s8(a.v64[1], b.v64[1]),
|
||||
c_v64_cmplt_s8(a.v64[0], b.v64[0]));
|
||||
}
|
||||
|
||||
SIMD_INLINE c_v128 c_v128_cmpeq_8(c_v128 a, c_v128 b) {
|
||||
return c_v128_from_v64(c_v64_cmpeq_8(a.v64[1], b.v64[1]),
|
||||
c_v64_cmpeq_8(a.v64[0], b.v64[0]));
|
||||
}
|
||||
|
||||
SIMD_INLINE c_v128 c_v128_cmpgt_s16(c_v128 a, c_v128 b) {
|
||||
return c_v128_from_v64(c_v64_cmpgt_s16(a.v64[1], b.v64[1]),
|
||||
c_v64_cmpgt_s16(a.v64[0], b.v64[0]));
|
||||
}
|
||||
|
||||
SIMD_INLINE c_v128 c_v128_cmplt_s16(c_v128 a, c_v128 b) {
|
||||
return c_v128_from_v64(c_v64_cmplt_s16(a.v64[1], b.v64[1]),
|
||||
c_v64_cmplt_s16(a.v64[0], b.v64[0]));
|
||||
}
|
||||
|
||||
SIMD_INLINE c_v128 c_v128_cmpeq_16(c_v128 a, c_v128 b) {
|
||||
return c_v128_from_v64(c_v64_cmpeq_16(a.v64[1], b.v64[1]),
|
||||
c_v64_cmpeq_16(a.v64[0], b.v64[0]));
|
||||
}
|
||||
|
||||
SIMD_INLINE c_v128 c_v128_shl_n_byte(c_v128 a, const unsigned int n) {
|
||||
if (n < 8)
|
||||
return c_v128_from_v64(c_v64_or(c_v64_shl_n_byte(a.v64[1], n),
|
||||
c_v64_shr_n_byte(a.v64[0], 8 - n)),
|
||||
c_v64_shl_n_byte(a.v64[0], n));
|
||||
else
|
||||
return c_v128_from_v64(c_v64_shl_n_byte(a.v64[0], n - 8), c_v64_zero());
|
||||
}
|
||||
|
||||
SIMD_INLINE c_v128 c_v128_shr_n_byte(c_v128 a, const unsigned int n) {
|
||||
if (n < 8)
|
||||
return c_v128_from_v64(c_v64_shr_n_byte(a.v64[1], n),
|
||||
c_v64_or(c_v64_shr_n_byte(a.v64[0], n),
|
||||
c_v64_shl_n_byte(a.v64[1], 8 - n)));
|
||||
else
|
||||
return c_v128_from_v64(c_v64_zero(), c_v64_shr_n_byte(a.v64[1], n - 8));
|
||||
}
|
||||
|
||||
SIMD_INLINE c_v128 c_v128_align(c_v128 a, c_v128 b, const unsigned int c) {
|
||||
if (simd_check && c > 15) {
|
||||
fprintf(stderr, "Error: undefined alignment %d\n", c);
|
||||
abort();
|
||||
}
|
||||
return c ? c_v128_or(c_v128_shr_n_byte(b, c), c_v128_shl_n_byte(a, 16 - c))
|
||||
: b;
|
||||
}
|
||||
|
||||
SIMD_INLINE c_v128 c_v128_shl_8(c_v128 a, const unsigned int c) {
|
||||
return c_v128_from_v64(c_v64_shl_8(a.v64[1], c), c_v64_shl_8(a.v64[0], c));
|
||||
}
|
||||
|
||||
SIMD_INLINE c_v128 c_v128_shr_u8(c_v128 a, const unsigned int c) {
|
||||
return c_v128_from_v64(c_v64_shr_u8(a.v64[1], c), c_v64_shr_u8(a.v64[0], c));
|
||||
}
|
||||
|
||||
SIMD_INLINE c_v128 c_v128_shr_s8(c_v128 a, const unsigned int c) {
|
||||
return c_v128_from_v64(c_v64_shr_s8(a.v64[1], c), c_v64_shr_s8(a.v64[0], c));
|
||||
}
|
||||
|
||||
SIMD_INLINE c_v128 c_v128_shl_16(c_v128 a, const unsigned int c) {
|
||||
return c_v128_from_v64(c_v64_shl_16(a.v64[1], c), c_v64_shl_16(a.v64[0], c));
|
||||
}
|
||||
|
||||
SIMD_INLINE c_v128 c_v128_shr_u16(c_v128 a, const unsigned int c) {
|
||||
return c_v128_from_v64(c_v64_shr_u16(a.v64[1], c),
|
||||
c_v64_shr_u16(a.v64[0], c));
|
||||
}
|
||||
|
||||
SIMD_INLINE c_v128 c_v128_shr_s16(c_v128 a, const unsigned int c) {
|
||||
return c_v128_from_v64(c_v64_shr_s16(a.v64[1], c),
|
||||
c_v64_shr_s16(a.v64[0], c));
|
||||
}
|
||||
|
||||
SIMD_INLINE c_v128 c_v128_shl_32(c_v128 a, const unsigned int c) {
|
||||
return c_v128_from_v64(c_v64_shl_32(a.v64[1], c), c_v64_shl_32(a.v64[0], c));
|
||||
}
|
||||
|
||||
SIMD_INLINE c_v128 c_v128_shr_u32(c_v128 a, const unsigned int c) {
|
||||
return c_v128_from_v64(c_v64_shr_u32(a.v64[1], c),
|
||||
c_v64_shr_u32(a.v64[0], c));
|
||||
}
|
||||
|
||||
SIMD_INLINE c_v128 c_v128_shr_s32(c_v128 a, const unsigned int c) {
|
||||
return c_v128_from_v64(c_v64_shr_s32(a.v64[1], c),
|
||||
c_v64_shr_s32(a.v64[0], c));
|
||||
}
|
||||
|
||||
SIMD_INLINE c_v128 c_v128_shl_n_8(c_v128 a, const unsigned int n) {
|
||||
return c_v128_shl_8(a, n);
|
||||
}
|
||||
|
||||
SIMD_INLINE c_v128 c_v128_shl_n_16(c_v128 a, const unsigned int n) {
|
||||
return c_v128_shl_16(a, n);
|
||||
}
|
||||
|
||||
SIMD_INLINE c_v128 c_v128_shl_n_32(c_v128 a, const unsigned int n) {
|
||||
return c_v128_shl_32(a, n);
|
||||
}
|
||||
|
||||
SIMD_INLINE c_v128 c_v128_shr_n_u8(c_v128 a, const unsigned int n) {
|
||||
return c_v128_shr_u8(a, n);
|
||||
}
|
||||
|
||||
SIMD_INLINE c_v128 c_v128_shr_n_u16(c_v128 a, const unsigned int n) {
|
||||
return c_v128_shr_u16(a, n);
|
||||
}
|
||||
|
||||
SIMD_INLINE c_v128 c_v128_shr_n_u32(c_v128 a, const unsigned int n) {
|
||||
return c_v128_shr_u32(a, n);
|
||||
}
|
||||
|
||||
SIMD_INLINE c_v128 c_v128_shr_n_s8(c_v128 a, const unsigned int n) {
|
||||
return c_v128_shr_s8(a, n);
|
||||
}
|
||||
|
||||
SIMD_INLINE c_v128 c_v128_shr_n_s16(c_v128 a, const unsigned int n) {
|
||||
return c_v128_shr_s16(a, n);
|
||||
}
|
||||
|
||||
SIMD_INLINE c_v128 c_v128_shr_n_s32(c_v128 a, const unsigned int n) {
|
||||
return c_v128_shr_s32(a, n);
|
||||
}
|
||||
|
||||
#endif /* _V128_INTRINSICS_C_H */
|
||||
@@ -1,488 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2016, Alliance for Open Media. All rights reserved
|
||||
*
|
||||
* This source code is subject to the terms of the BSD 2 Clause License and
|
||||
* the Alliance for Open Media Patent License 1.0. If the BSD 2 Clause License
|
||||
* was not distributed with this source code in the LICENSE file, you can
|
||||
* obtain it at www.aomedia.org/license/software. If the Alliance for Open
|
||||
* Media Patent License 1.0 was not distributed with this source code in the
|
||||
* PATENTS file, you can obtain it at www.aomedia.org/license/patent.
|
||||
*/
|
||||
|
||||
#ifndef _V128_INTRINSICS_H
|
||||
#define _V128_INTRINSICS_H
|
||||
|
||||
#include "./v64_intrinsics_x86.h"
|
||||
|
||||
typedef __m128i v128;
|
||||
|
||||
SIMD_INLINE uint32_t v128_low_u32(v128 a) {
|
||||
return (uint32_t)_mm_cvtsi128_si32(a);
|
||||
}
|
||||
|
||||
SIMD_INLINE v64 v128_low_v64(v128 a) {
|
||||
return _mm_unpacklo_epi64(a, v64_zero());
|
||||
}
|
||||
|
||||
SIMD_INLINE v64 v128_high_v64(v128 a) { return _mm_srli_si128(a, 8); }
|
||||
|
||||
SIMD_INLINE v128 v128_from_v64(v64 a, v64 b) {
|
||||
return _mm_unpacklo_epi64(b, a);
|
||||
}
|
||||
|
||||
SIMD_INLINE v128 v128_from_64(uint64_t a, uint64_t b) {
|
||||
return v128_from_v64(v64_from_64(a), v64_from_64(b));
|
||||
}
|
||||
|
||||
SIMD_INLINE v128 v128_from_32(uint32_t a, uint32_t b, uint32_t c, uint32_t d) {
|
||||
return _mm_set_epi32(a, b, c, d);
|
||||
}
|
||||
|
||||
SIMD_INLINE v128 v128_load_aligned(const void *p) {
|
||||
return _mm_load_si128((__m128i *)p);
|
||||
}
|
||||
|
||||
SIMD_INLINE v128 v128_load_unaligned(const void *p) {
|
||||
#if defined(__SSSE3__)
|
||||
return (__m128i)_mm_lddqu_si128((__m128i *)p);
|
||||
#else
|
||||
return _mm_loadu_si128((__m128i *)p);
|
||||
#endif
|
||||
}
|
||||
|
||||
SIMD_INLINE void v128_store_aligned(void *p, v128 a) {
|
||||
_mm_store_si128((__m128i *)p, a);
|
||||
}
|
||||
|
||||
SIMD_INLINE void v128_store_unaligned(void *p, v128 a) {
|
||||
_mm_storeu_si128((__m128i *)p, a);
|
||||
}
|
||||
|
||||
// The following function requires an immediate.
|
||||
// Some compilers will check this during optimisation, others wont.
|
||||
#if __OPTIMIZE__ && !__clang__
|
||||
#if defined(__SSSE3__)
|
||||
SIMD_INLINE v128 v128_align(v128 a, v128 b, const unsigned int c) {
|
||||
return c ? _mm_alignr_epi8(a, b, c) : b;
|
||||
}
|
||||
#else
|
||||
#define v128_align(a, b, c) \
|
||||
((c) ? _mm_or_si128(_mm_srli_si128(b, c), _mm_slli_si128(a, 16 - (c))) : (b))
|
||||
#endif
|
||||
#else
|
||||
#if defined(__SSSE3__)
|
||||
#define v128_align(a, b, c) ((c) ? _mm_alignr_epi8(a, b, c) : (b))
|
||||
#else
|
||||
#define v128_align(a, b, c) \
|
||||
((c) ? _mm_or_si128(_mm_srli_si128(b, c), _mm_slli_si128(a, 16 - (c))) : (b))
|
||||
#endif
|
||||
#endif
|
||||
|
||||
SIMD_INLINE v128 v128_zero() { return _mm_setzero_si128(); }
|
||||
|
||||
SIMD_INLINE v128 v128_dup_8(uint8_t x) { return _mm_set1_epi8(x); }
|
||||
|
||||
SIMD_INLINE v128 v128_dup_16(uint16_t x) { return _mm_set1_epi16(x); }
|
||||
|
||||
SIMD_INLINE v128 v128_dup_32(uint32_t x) { return _mm_set1_epi32(x); }
|
||||
|
||||
SIMD_INLINE v128 v128_add_8(v128 a, v128 b) { return _mm_add_epi8(a, b); }
|
||||
|
||||
SIMD_INLINE v128 v128_add_16(v128 a, v128 b) { return _mm_add_epi16(a, b); }
|
||||
|
||||
SIMD_INLINE v128 v128_sadd_s16(v128 a, v128 b) { return _mm_adds_epi16(a, b); }
|
||||
|
||||
SIMD_INLINE v128 v128_add_32(v128 a, v128 b) { return _mm_add_epi32(a, b); }
|
||||
|
||||
SIMD_INLINE v128 v128_padd_s16(v128 a) {
|
||||
return _mm_madd_epi16(a, _mm_set1_epi16(1));
|
||||
}
|
||||
|
||||
SIMD_INLINE v128 v128_sub_8(v128 a, v128 b) { return _mm_sub_epi8(a, b); }
|
||||
|
||||
SIMD_INLINE v128 v128_ssub_u8(v128 a, v128 b) { return _mm_subs_epu8(a, b); }
|
||||
|
||||
SIMD_INLINE v128 v128_ssub_s8(v128 a, v128 b) { return _mm_subs_epi8(a, b); }
|
||||
|
||||
SIMD_INLINE v128 v128_sub_16(v128 a, v128 b) { return _mm_sub_epi16(a, b); }
|
||||
|
||||
SIMD_INLINE v128 v128_ssub_s16(v128 a, v128 b) { return _mm_subs_epi16(a, b); }
|
||||
|
||||
SIMD_INLINE v128 v128_sub_32(v128 a, v128 b) { return _mm_sub_epi32(a, b); }
|
||||
|
||||
SIMD_INLINE v128 v128_abs_s16(v128 a) {
|
||||
#if defined(__SSSE3__)
|
||||
return _mm_abs_epi16(a);
|
||||
#else
|
||||
return _mm_max_epi16(a, _mm_sub_epi16(_mm_setzero_si128(), a));
|
||||
#endif
|
||||
}
|
||||
|
||||
SIMD_INLINE v128 v128_ziplo_8(v128 a, v128 b) {
|
||||
return _mm_unpacklo_epi8(b, a);
|
||||
}
|
||||
|
||||
SIMD_INLINE v128 v128_ziphi_8(v128 a, v128 b) {
|
||||
return _mm_unpackhi_epi8(b, a);
|
||||
}
|
||||
|
||||
SIMD_INLINE v128 v128_ziplo_16(v128 a, v128 b) {
|
||||
return _mm_unpacklo_epi16(b, a);
|
||||
}
|
||||
|
||||
SIMD_INLINE v128 v128_ziphi_16(v128 a, v128 b) {
|
||||
return _mm_unpackhi_epi16(b, a);
|
||||
}
|
||||
|
||||
SIMD_INLINE v128 v128_ziplo_32(v128 a, v128 b) {
|
||||
return _mm_unpacklo_epi32(b, a);
|
||||
}
|
||||
|
||||
SIMD_INLINE v128 v128_ziphi_32(v128 a, v128 b) {
|
||||
return _mm_unpackhi_epi32(b, a);
|
||||
}
|
||||
|
||||
SIMD_INLINE v128 v128_ziplo_64(v128 a, v128 b) {
|
||||
return _mm_unpacklo_epi64(b, a);
|
||||
}
|
||||
|
||||
SIMD_INLINE v128 v128_ziphi_64(v128 a, v128 b) {
|
||||
return _mm_unpackhi_epi64(b, a);
|
||||
}
|
||||
|
||||
SIMD_INLINE v128 v128_zip_8(v64 a, v64 b) { return _mm_unpacklo_epi8(b, a); }
|
||||
|
||||
SIMD_INLINE v128 v128_zip_16(v64 a, v64 b) { return _mm_unpacklo_epi16(b, a); }
|
||||
|
||||
SIMD_INLINE v128 v128_zip_32(v64 a, v64 b) { return _mm_unpacklo_epi32(b, a); }
|
||||
|
||||
SIMD_INLINE v128 v128_unziphi_8(v128 a, v128 b) {
|
||||
return _mm_packs_epi16(_mm_srai_epi16(b, 8), _mm_srai_epi16(a, 8));
|
||||
}
|
||||
|
||||
SIMD_INLINE v128 v128_unziplo_8(v128 a, v128 b) {
|
||||
#if defined(__SSSE3__)
|
||||
#ifdef __x86_64__
|
||||
v128 order = _mm_cvtsi64_si128(0x0e0c0a0806040200LL);
|
||||
#else
|
||||
v128 order = _mm_set_epi32(0, 0, 0x0e0c0a08, 0x06040200);
|
||||
#endif
|
||||
return _mm_unpacklo_epi64(_mm_shuffle_epi8(b, order),
|
||||
_mm_shuffle_epi8(a, order));
|
||||
#else
|
||||
return v128_unziphi_8(_mm_slli_si128(a, 1), _mm_slli_si128(b, 1));
|
||||
#endif
|
||||
}
|
||||
|
||||
SIMD_INLINE v128 v128_unziphi_16(v128 a, v128 b) {
|
||||
return _mm_packs_epi32(_mm_srai_epi32(b, 16), _mm_srai_epi32(a, 16));
|
||||
}
|
||||
|
||||
SIMD_INLINE v128 v128_unziplo_16(v128 a, v128 b) {
|
||||
#if defined(__SSSE3__)
|
||||
#ifdef __x86_64__
|
||||
v128 order = _mm_cvtsi64_si128(0x0d0c090805040100LL);
|
||||
#else
|
||||
v128 order = _mm_set_epi32(0, 0, 0x0d0c0908, 0x05040100);
|
||||
#endif
|
||||
return _mm_unpacklo_epi64(_mm_shuffle_epi8(b, order),
|
||||
_mm_shuffle_epi8(a, order));
|
||||
#else
|
||||
return v128_unziphi_16(_mm_slli_si128(a, 2), _mm_slli_si128(b, 2));
|
||||
#endif
|
||||
}
|
||||
|
||||
SIMD_INLINE v128 v128_unziphi_32(v128 a, v128 b) {
|
||||
return _mm_castps_si128(_mm_shuffle_ps(
|
||||
_mm_castsi128_ps(b), _mm_castsi128_ps(a), _MM_SHUFFLE(3, 1, 3, 1)));
|
||||
}
|
||||
|
||||
SIMD_INLINE v128 v128_unziplo_32(v128 a, v128 b) {
|
||||
return _mm_castps_si128(_mm_shuffle_ps(
|
||||
_mm_castsi128_ps(b), _mm_castsi128_ps(a), _MM_SHUFFLE(2, 0, 2, 0)));
|
||||
}
|
||||
|
||||
SIMD_INLINE v128 v128_unpack_u8_s16(v64 a) {
|
||||
return _mm_unpacklo_epi8(a, _mm_setzero_si128());
|
||||
}
|
||||
|
||||
SIMD_INLINE v128 v128_unpacklo_u8_s16(v128 a) {
|
||||
return _mm_unpacklo_epi8(a, _mm_setzero_si128());
|
||||
}
|
||||
|
||||
SIMD_INLINE v128 v128_unpackhi_u8_s16(v128 a) {
|
||||
return _mm_unpackhi_epi8(a, _mm_setzero_si128());
|
||||
}
|
||||
|
||||
SIMD_INLINE v128 v128_pack_s32_s16(v128 a, v128 b) {
|
||||
return _mm_packs_epi32(b, a);
|
||||
}
|
||||
|
||||
SIMD_INLINE v128 v128_pack_s16_u8(v128 a, v128 b) {
|
||||
return _mm_packus_epi16(b, a);
|
||||
}
|
||||
|
||||
SIMD_INLINE v128 v128_pack_s16_s8(v128 a, v128 b) {
|
||||
return _mm_packs_epi16(b, a);
|
||||
}
|
||||
|
||||
SIMD_INLINE v128 v128_unpack_u16_s32(v64 a) {
|
||||
return _mm_unpacklo_epi16(a, _mm_setzero_si128());
|
||||
}
|
||||
|
||||
SIMD_INLINE v128 v128_unpack_s16_s32(v64 a) {
|
||||
return _mm_srai_epi32(_mm_unpacklo_epi16(a, a), 16);
|
||||
}
|
||||
|
||||
SIMD_INLINE v128 v128_unpacklo_u16_s32(v128 a) {
|
||||
return _mm_unpacklo_epi16(a, _mm_setzero_si128());
|
||||
}
|
||||
|
||||
SIMD_INLINE v128 v128_unpacklo_s16_s32(v128 a) {
|
||||
return _mm_srai_epi32(_mm_unpacklo_epi16(a, a), 16);
|
||||
}
|
||||
|
||||
SIMD_INLINE v128 v128_unpackhi_u16_s32(v128 a) {
|
||||
return _mm_unpackhi_epi16(a, _mm_setzero_si128());
|
||||
}
|
||||
|
||||
SIMD_INLINE v128 v128_unpackhi_s16_s32(v128 a) {
|
||||
return _mm_srai_epi32(_mm_unpackhi_epi16(a, a), 16);
|
||||
}
|
||||
|
||||
SIMD_INLINE v128 v128_shuffle_8(v128 x, v128 pattern) {
|
||||
#if defined(__SSSE3__)
|
||||
return _mm_shuffle_epi8(x, pattern);
|
||||
#else
|
||||
v128 output;
|
||||
unsigned char *input = (unsigned char *)&x;
|
||||
unsigned char *index = (unsigned char *)&pattern;
|
||||
char *selected = (char *)&output;
|
||||
int counter;
|
||||
|
||||
for (counter = 0; counter < 16; counter++) {
|
||||
selected[counter] = input[index[counter] & 15];
|
||||
}
|
||||
|
||||
return output;
|
||||
#endif
|
||||
}
|
||||
|
||||
SIMD_INLINE int64_t v128_dotp_s16(v128 a, v128 b) {
|
||||
v128 r = _mm_madd_epi16(a, b);
|
||||
#if defined(__SSE4_1__) && defined(__x86_64__)
|
||||
v128 c = _mm_add_epi64(_mm_cvtepi32_epi64(r),
|
||||
_mm_cvtepi32_epi64(_mm_srli_si128(r, 8)));
|
||||
return _mm_cvtsi128_si64(_mm_add_epi64(c, _mm_srli_si128(c, 8)));
|
||||
#else
|
||||
return (int64_t)_mm_cvtsi128_si32(r) +
|
||||
(int64_t)_mm_cvtsi128_si32(_mm_srli_si128(r, 4)) +
|
||||
(int64_t)_mm_cvtsi128_si32(_mm_srli_si128(r, 8)) +
|
||||
(int64_t)_mm_cvtsi128_si32(_mm_srli_si128(r, 12));
|
||||
#endif
|
||||
}
|
||||
|
||||
SIMD_INLINE uint64_t v128_hadd_u8(v128 a) {
|
||||
v128 t = _mm_sad_epu8(a, _mm_setzero_si128());
|
||||
return v64_low_u32(v128_low_v64(t)) + v64_low_u32(v128_high_v64(t));
|
||||
}
|
||||
|
||||
typedef v128 sad128_internal;
|
||||
|
||||
SIMD_INLINE sad128_internal v128_sad_u8_init() { return _mm_setzero_si128(); }
|
||||
|
||||
/* Implementation dependent return value. Result must be finalised with
|
||||
v128_sad_sum().
|
||||
The result for more than 32 v128_sad_u8() calls is undefined. */
|
||||
SIMD_INLINE sad128_internal v128_sad_u8(sad128_internal s, v128 a, v128 b) {
|
||||
return _mm_add_epi64(s, _mm_sad_epu8(a, b));
|
||||
}
|
||||
|
||||
SIMD_INLINE uint32_t v128_sad_u8_sum(sad128_internal s) {
|
||||
return v128_low_u32(_mm_add_epi32(s, _mm_unpackhi_epi64(s, s)));
|
||||
}
|
||||
|
||||
typedef v128 ssd128_internal;
|
||||
|
||||
SIMD_INLINE ssd128_internal v128_ssd_u8_init() { return _mm_setzero_si128(); }
|
||||
|
||||
/* Implementation dependent return value. Result must be finalised with
|
||||
* v128_ssd_sum(). */
|
||||
SIMD_INLINE ssd128_internal v128_ssd_u8(ssd128_internal s, v128 a, v128 b) {
|
||||
v128 l = _mm_sub_epi16(_mm_unpacklo_epi8(a, _mm_setzero_si128()),
|
||||
_mm_unpacklo_epi8(b, _mm_setzero_si128()));
|
||||
v128 h = _mm_sub_epi16(_mm_unpackhi_epi8(a, _mm_setzero_si128()),
|
||||
_mm_unpackhi_epi8(b, _mm_setzero_si128()));
|
||||
v128 rl = _mm_madd_epi16(l, l);
|
||||
v128 rh = _mm_madd_epi16(h, h);
|
||||
v128 c = _mm_cvtsi32_si128(32);
|
||||
rl = _mm_add_epi32(rl, _mm_srli_si128(rl, 8));
|
||||
rl = _mm_add_epi32(rl, _mm_srli_si128(rl, 4));
|
||||
rh = _mm_add_epi32(rh, _mm_srli_si128(rh, 8));
|
||||
rh = _mm_add_epi32(rh, _mm_srli_si128(rh, 4));
|
||||
return _mm_add_epi64(
|
||||
s, _mm_srl_epi64(_mm_sll_epi64(_mm_unpacklo_epi64(rl, rh), c), c));
|
||||
}
|
||||
|
||||
SIMD_INLINE uint32_t v128_ssd_u8_sum(ssd128_internal s) {
|
||||
return v128_low_u32(_mm_add_epi32(s, _mm_unpackhi_epi64(s, s)));
|
||||
}
|
||||
|
||||
SIMD_INLINE v128 v128_or(v128 a, v128 b) { return _mm_or_si128(a, b); }
|
||||
|
||||
SIMD_INLINE v128 v128_xor(v128 a, v128 b) { return _mm_xor_si128(a, b); }
|
||||
|
||||
SIMD_INLINE v128 v128_and(v128 a, v128 b) { return _mm_and_si128(a, b); }
|
||||
|
||||
SIMD_INLINE v128 v128_andn(v128 a, v128 b) { return _mm_andnot_si128(b, a); }
|
||||
|
||||
SIMD_INLINE v128 v128_mul_s16(v64 a, v64 b) {
|
||||
v64 lo_bits = v64_mullo_s16(a, b);
|
||||
v64 hi_bits = v64_mulhi_s16(a, b);
|
||||
return v128_from_v64(v64_ziphi_16(hi_bits, lo_bits),
|
||||
v64_ziplo_16(hi_bits, lo_bits));
|
||||
}
|
||||
|
||||
SIMD_INLINE v128 v128_mullo_s16(v128 a, v128 b) {
|
||||
return _mm_mullo_epi16(a, b);
|
||||
}
|
||||
|
||||
SIMD_INLINE v128 v128_mulhi_s16(v128 a, v128 b) {
|
||||
return _mm_mulhi_epi16(a, b);
|
||||
}
|
||||
|
||||
SIMD_INLINE v128 v128_mullo_s32(v128 a, v128 b) {
|
||||
#if defined(__SSE4_1__)
|
||||
return _mm_mullo_epi32(a, b);
|
||||
#else
|
||||
return _mm_unpacklo_epi32(
|
||||
_mm_shuffle_epi32(_mm_mul_epu32(a, b), 8),
|
||||
_mm_shuffle_epi32(
|
||||
_mm_mul_epu32(_mm_srli_si128(a, 4), _mm_srli_si128(b, 4)), 8));
|
||||
#endif
|
||||
}
|
||||
|
||||
SIMD_INLINE v128 v128_madd_s16(v128 a, v128 b) { return _mm_madd_epi16(a, b); }
|
||||
|
||||
SIMD_INLINE v128 v128_madd_us8(v128 a, v128 b) {
|
||||
#if defined(__SSSE3__)
|
||||
return _mm_maddubs_epi16(a, b);
|
||||
#else
|
||||
return _mm_packs_epi32(
|
||||
_mm_madd_epi16(_mm_unpacklo_epi8(a, _mm_setzero_si128()),
|
||||
_mm_srai_epi16(_mm_unpacklo_epi8(b, b), 8)),
|
||||
_mm_madd_epi16(_mm_unpackhi_epi8(a, _mm_setzero_si128()),
|
||||
_mm_srai_epi16(_mm_unpackhi_epi8(b, b), 8)));
|
||||
#endif
|
||||
}
|
||||
|
||||
SIMD_INLINE v128 v128_avg_u8(v128 a, v128 b) { return _mm_avg_epu8(a, b); }
|
||||
|
||||
SIMD_INLINE v128 v128_rdavg_u8(v128 a, v128 b) {
|
||||
return _mm_sub_epi8(_mm_avg_epu8(a, b),
|
||||
_mm_and_si128(_mm_xor_si128(a, b), v128_dup_8(1)));
|
||||
}
|
||||
|
||||
SIMD_INLINE v128 v128_avg_u16(v128 a, v128 b) { return _mm_avg_epu16(a, b); }
|
||||
|
||||
SIMD_INLINE v128 v128_min_u8(v128 a, v128 b) { return _mm_min_epu8(a, b); }
|
||||
|
||||
SIMD_INLINE v128 v128_max_u8(v128 a, v128 b) { return _mm_max_epu8(a, b); }
|
||||
|
||||
SIMD_INLINE v128 v128_min_s8(v128 a, v128 b) {
|
||||
#if defined(__SSE4_1__)
|
||||
return _mm_min_epi8(a, b);
|
||||
#else
|
||||
v128 mask = _mm_cmplt_epi8(a, b);
|
||||
return _mm_or_si128(_mm_andnot_si128(mask, b), _mm_and_si128(mask, a));
|
||||
#endif
|
||||
}
|
||||
|
||||
SIMD_INLINE v128 v128_max_s8(v128 a, v128 b) {
|
||||
#if defined(__SSE4_1__)
|
||||
return _mm_max_epi8(a, b);
|
||||
#else
|
||||
v128 mask = _mm_cmplt_epi8(b, a);
|
||||
return _mm_or_si128(_mm_andnot_si128(mask, b), _mm_and_si128(mask, a));
|
||||
#endif
|
||||
}
|
||||
|
||||
SIMD_INLINE v128 v128_min_s16(v128 a, v128 b) { return _mm_min_epi16(a, b); }
|
||||
|
||||
SIMD_INLINE v128 v128_max_s16(v128 a, v128 b) { return _mm_max_epi16(a, b); }
|
||||
|
||||
SIMD_INLINE v128 v128_cmpgt_s8(v128 a, v128 b) { return _mm_cmpgt_epi8(a, b); }
|
||||
|
||||
SIMD_INLINE v128 v128_cmplt_s8(v128 a, v128 b) { return _mm_cmplt_epi8(a, b); }
|
||||
|
||||
SIMD_INLINE v128 v128_cmpeq_8(v128 a, v128 b) { return _mm_cmpeq_epi8(a, b); }
|
||||
|
||||
SIMD_INLINE v128 v128_cmpgt_s16(v128 a, v128 b) {
|
||||
return _mm_cmpgt_epi16(a, b);
|
||||
}
|
||||
|
||||
SIMD_INLINE v128 v128_cmplt_s16(v128 a, v128 b) {
|
||||
return _mm_cmplt_epi16(a, b);
|
||||
}
|
||||
|
||||
SIMD_INLINE v128 v128_cmpeq_16(v128 a, v128 b) { return _mm_cmpeq_epi16(a, b); }
|
||||
|
||||
SIMD_INLINE v128 v128_shl_8(v128 a, unsigned int c) {
|
||||
return _mm_and_si128(_mm_set1_epi8((uint8_t)(0xff << c)),
|
||||
_mm_sll_epi16(a, _mm_cvtsi32_si128(c)));
|
||||
}
|
||||
|
||||
SIMD_INLINE v128 v128_shr_u8(v128 a, unsigned int c) {
|
||||
return _mm_and_si128(_mm_set1_epi8(0xff >> c),
|
||||
_mm_srl_epi16(a, _mm_cvtsi32_si128(c)));
|
||||
}
|
||||
|
||||
SIMD_INLINE v128 v128_shr_s8(v128 a, unsigned int c) {
|
||||
__m128i x = _mm_cvtsi32_si128(c + 8);
|
||||
return _mm_packs_epi16(_mm_sra_epi16(_mm_unpacklo_epi8(a, a), x),
|
||||
_mm_sra_epi16(_mm_unpackhi_epi8(a, a), x));
|
||||
}
|
||||
|
||||
SIMD_INLINE v128 v128_shl_16(v128 a, unsigned int c) {
|
||||
return _mm_sll_epi16(a, _mm_cvtsi32_si128(c));
|
||||
}
|
||||
|
||||
SIMD_INLINE v128 v128_shr_u16(v128 a, unsigned int c) {
|
||||
return _mm_srl_epi16(a, _mm_cvtsi32_si128(c));
|
||||
}
|
||||
|
||||
SIMD_INLINE v128 v128_shr_s16(v128 a, unsigned int c) {
|
||||
return _mm_sra_epi16(a, _mm_cvtsi32_si128(c));
|
||||
}
|
||||
|
||||
SIMD_INLINE v128 v128_shl_32(v128 a, unsigned int c) {
|
||||
return _mm_sll_epi32(a, _mm_cvtsi32_si128(c));
|
||||
}
|
||||
|
||||
SIMD_INLINE v128 v128_shr_u32(v128 a, unsigned int c) {
|
||||
return _mm_srl_epi32(a, _mm_cvtsi32_si128(c));
|
||||
}
|
||||
|
||||
SIMD_INLINE v128 v128_shr_s32(v128 a, unsigned int c) {
|
||||
return _mm_sra_epi32(a, _mm_cvtsi32_si128(c));
|
||||
}
|
||||
|
||||
/* These intrinsics require immediate values, so we must use #defines
|
||||
to enforce that. */
|
||||
#define v128_shl_n_byte(a, c) _mm_slli_si128(a, c)
|
||||
#define v128_shr_n_byte(a, c) _mm_srli_si128(a, c)
|
||||
#define v128_shl_n_8(a, c) \
|
||||
_mm_and_si128(_mm_set1_epi8((uint8_t)(0xff << (c))), _mm_slli_epi16(a, c))
|
||||
#define v128_shr_n_u8(a, c) \
|
||||
_mm_and_si128(_mm_set1_epi8(0xff >> (c)), _mm_srli_epi16(a, c))
|
||||
#define v128_shr_n_s8(a, c) \
|
||||
_mm_packs_epi16(_mm_srai_epi16(_mm_unpacklo_epi8(a, a), (c) + 8), \
|
||||
_mm_srai_epi16(_mm_unpackhi_epi8(a, a), (c) + 8))
|
||||
#define v128_shl_n_16(a, c) _mm_slli_epi16(a, c)
|
||||
#define v128_shr_n_u16(a, c) _mm_srli_epi16(a, c)
|
||||
#define v128_shr_n_s16(a, c) _mm_srai_epi16(a, c)
|
||||
#define v128_shl_n_32(a, c) _mm_slli_epi32(a, c)
|
||||
#define v128_shr_n_u32(a, c) _mm_srli_epi32(a, c)
|
||||
#define v128_shr_n_s32(a, c) _mm_srai_epi32(a, c)
|
||||
|
||||
#endif /* _V128_INTRINSICS_H */
|
||||
@@ -1,274 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2016, Alliance for Open Media. All rights reserved
|
||||
*
|
||||
* This source code is subject to the terms of the BSD 2 Clause License and
|
||||
* the Alliance for Open Media Patent License 1.0. If the BSD 2 Clause License
|
||||
* was not distributed with this source code in the LICENSE file, you can
|
||||
* obtain it at www.aomedia.org/license/software. If the Alliance for Open
|
||||
* Media Patent License 1.0 was not distributed with this source code in the
|
||||
* PATENTS file, you can obtain it at www.aomedia.org/license/patent.
|
||||
*/
|
||||
|
||||
#ifndef _V256_INTRINSICS_H
|
||||
#define _V256_INTRINSICS_H
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include "./v256_intrinsics_c.h"
|
||||
#include "./v128_intrinsics.h"
|
||||
#include "./v64_intrinsics.h"
|
||||
|
||||
/* Fallback to plain, unoptimised C. */
|
||||
|
||||
typedef c_v256 v256;
|
||||
|
||||
SIMD_INLINE uint32_t v256_low_u32(v256 a) { return c_v256_low_u32(a); }
|
||||
SIMD_INLINE v64 v256_low_v64(v256 a) { return c_v256_low_v64(a); }
|
||||
SIMD_INLINE v128 v256_low_v128(v256 a) { return c_v256_low_v128(a); }
|
||||
SIMD_INLINE v128 v256_high_v128(v256 a) { return c_v256_high_v128(a); }
|
||||
SIMD_INLINE v256 v256_from_v128(v128 hi, v128 lo) {
|
||||
return c_v256_from_v128(hi, lo);
|
||||
}
|
||||
SIMD_INLINE v256 v256_from_64(uint64_t a, uint64_t b, uint64_t c, uint64_t d) {
|
||||
return c_v256_from_64(a, b, c, d);
|
||||
}
|
||||
SIMD_INLINE v256 v256_from_v64(v64 a, v64 b, v64 c, v64 d) {
|
||||
return c_v256_from_v64(a, b, c, d);
|
||||
}
|
||||
|
||||
SIMD_INLINE v256 v256_load_unaligned(const void *p) {
|
||||
return c_v256_load_unaligned(p);
|
||||
}
|
||||
SIMD_INLINE v256 v256_load_aligned(const void *p) {
|
||||
return c_v256_load_aligned(p);
|
||||
}
|
||||
|
||||
SIMD_INLINE void v256_store_unaligned(void *p, v256 a) {
|
||||
c_v256_store_unaligned(p, a);
|
||||
}
|
||||
SIMD_INLINE void v256_store_aligned(void *p, v256 a) {
|
||||
c_v256_store_aligned(p, a);
|
||||
}
|
||||
|
||||
SIMD_INLINE v256 v256_align(v256 a, v256 b, const unsigned int c) {
|
||||
return c_v256_align(a, b, c);
|
||||
}
|
||||
|
||||
SIMD_INLINE v256 v256_zero() { return c_v256_zero(); }
|
||||
SIMD_INLINE v256 v256_dup_8(uint8_t x) { return c_v256_dup_8(x); }
|
||||
SIMD_INLINE v256 v256_dup_16(uint16_t x) { return c_v256_dup_16(x); }
|
||||
SIMD_INLINE v256 v256_dup_32(uint32_t x) { return c_v256_dup_32(x); }
|
||||
|
||||
typedef uint32_t sad256_internal;
|
||||
SIMD_INLINE sad256_internal v256_sad_u8_init() { return c_v256_sad_u8_init(); }
|
||||
SIMD_INLINE sad256_internal v256_sad_u8(sad256_internal s, v256 a, v256 b) {
|
||||
return c_v256_sad_u8(s, a, b);
|
||||
}
|
||||
SIMD_INLINE uint32_t v256_sad_u8_sum(sad256_internal s) {
|
||||
return c_v256_sad_u8_sum(s);
|
||||
}
|
||||
typedef uint32_t ssd256_internal;
|
||||
SIMD_INLINE ssd256_internal v256_ssd_u8_init() { return c_v256_ssd_u8_init(); }
|
||||
SIMD_INLINE ssd256_internal v256_ssd_u8(ssd256_internal s, v256 a, v256 b) {
|
||||
return c_v256_ssd_u8(s, a, b);
|
||||
}
|
||||
SIMD_INLINE uint32_t v256_ssd_u8_sum(ssd256_internal s) {
|
||||
return c_v256_ssd_u8_sum(s);
|
||||
}
|
||||
SIMD_INLINE int64_t v256_dotp_s16(v256 a, v256 b) {
|
||||
return c_v256_dotp_s16(a, b);
|
||||
}
|
||||
SIMD_INLINE uint64_t v256_hadd_u8(v256 a) { return c_v256_hadd_u8(a); }
|
||||
|
||||
SIMD_INLINE v256 v256_or(v256 a, v256 b) { return c_v256_or(a, b); }
|
||||
SIMD_INLINE v256 v256_xor(v256 a, v256 b) { return c_v256_xor(a, b); }
|
||||
SIMD_INLINE v256 v256_and(v256 a, v256 b) { return c_v256_and(a, b); }
|
||||
SIMD_INLINE v256 v256_andn(v256 a, v256 b) { return c_v256_andn(a, b); }
|
||||
|
||||
SIMD_INLINE v256 v256_add_8(v256 a, v256 b) { return c_v256_add_8(a, b); }
|
||||
SIMD_INLINE v256 v256_add_16(v256 a, v256 b) { return c_v256_add_16(a, b); }
|
||||
SIMD_INLINE v256 v256_sadd_s16(v256 a, v256 b) { return c_v256_sadd_s16(a, b); }
|
||||
SIMD_INLINE v256 v256_add_32(v256 a, v256 b) { return c_v256_add_32(a, b); }
|
||||
SIMD_INLINE v256 v256_padd_s16(v256 a) { return c_v256_padd_s16(a); }
|
||||
SIMD_INLINE v256 v256_sub_8(v256 a, v256 b) { return c_v256_sub_8(a, b); }
|
||||
SIMD_INLINE v256 v256_ssub_u8(v256 a, v256 b) { return c_v256_ssub_u8(a, b); }
|
||||
SIMD_INLINE v256 v256_ssub_s8(v256 a, v256 b) { return c_v256_ssub_s8(a, b); }
|
||||
SIMD_INLINE v256 v256_sub_16(v256 a, v256 b) { return c_v256_sub_16(a, b); }
|
||||
SIMD_INLINE v256 v256_ssub_s16(v256 a, v256 b) { return c_v256_ssub_s16(a, b); }
|
||||
SIMD_INLINE v256 v256_sub_32(v256 a, v256 b) { return c_v256_sub_32(a, b); }
|
||||
SIMD_INLINE v256 v256_abs_s16(v256 a) { return c_v256_abs_s16(a); }
|
||||
|
||||
SIMD_INLINE v256 v256_mul_s16(v128 a, v128 b) { return c_v256_mul_s16(a, b); }
|
||||
SIMD_INLINE v256 v256_mullo_s16(v256 a, v256 b) {
|
||||
return c_v256_mullo_s16(a, b);
|
||||
}
|
||||
SIMD_INLINE v256 v256_mulhi_s16(v256 a, v256 b) {
|
||||
return c_v256_mulhi_s16(a, b);
|
||||
}
|
||||
SIMD_INLINE v256 v256_mullo_s32(v256 a, v256 b) {
|
||||
return c_v256_mullo_s32(a, b);
|
||||
}
|
||||
SIMD_INLINE v256 v256_madd_s16(v256 a, v256 b) { return c_v256_madd_s16(a, b); }
|
||||
SIMD_INLINE v256 v256_madd_us8(v256 a, v256 b) { return c_v256_madd_us8(a, b); }
|
||||
|
||||
SIMD_INLINE v256 v256_avg_u8(v256 a, v256 b) { return c_v256_avg_u8(a, b); }
|
||||
SIMD_INLINE v256 v256_rdavg_u8(v256 a, v256 b) { return c_v256_rdavg_u8(a, b); }
|
||||
SIMD_INLINE v256 v256_avg_u16(v256 a, v256 b) { return c_v256_avg_u16(a, b); }
|
||||
SIMD_INLINE v256 v256_min_u8(v256 a, v256 b) { return c_v256_min_u8(a, b); }
|
||||
SIMD_INLINE v256 v256_max_u8(v256 a, v256 b) { return c_v256_max_u8(a, b); }
|
||||
SIMD_INLINE v256 v256_min_s8(v256 a, v256 b) { return c_v256_min_s8(a, b); }
|
||||
SIMD_INLINE v256 v256_max_s8(v256 a, v256 b) { return c_v256_max_s8(a, b); }
|
||||
SIMD_INLINE v256 v256_min_s16(v256 a, v256 b) { return c_v256_min_s16(a, b); }
|
||||
SIMD_INLINE v256 v256_max_s16(v256 a, v256 b) { return c_v256_max_s16(a, b); }
|
||||
|
||||
SIMD_INLINE v256 v256_ziplo_8(v256 a, v256 b) { return c_v256_ziplo_8(a, b); }
|
||||
SIMD_INLINE v256 v256_ziphi_8(v256 a, v256 b) { return c_v256_ziphi_8(a, b); }
|
||||
SIMD_INLINE v256 v256_ziplo_16(v256 a, v256 b) { return c_v256_ziplo_16(a, b); }
|
||||
SIMD_INLINE v256 v256_ziphi_16(v256 a, v256 b) { return c_v256_ziphi_16(a, b); }
|
||||
SIMD_INLINE v256 v256_ziplo_32(v256 a, v256 b) { return c_v256_ziplo_32(a, b); }
|
||||
SIMD_INLINE v256 v256_ziphi_32(v256 a, v256 b) { return c_v256_ziphi_32(a, b); }
|
||||
SIMD_INLINE v256 v256_ziplo_64(v256 a, v256 b) { return c_v256_ziplo_64(a, b); }
|
||||
SIMD_INLINE v256 v256_ziphi_64(v256 a, v256 b) { return c_v256_ziphi_64(a, b); }
|
||||
SIMD_INLINE v256 v256_ziplo_128(v256 a, v256 b) {
|
||||
return c_v256_ziplo_128(a, b);
|
||||
}
|
||||
SIMD_INLINE v256 v256_ziphi_128(v256 a, v256 b) {
|
||||
return c_v256_ziphi_128(a, b);
|
||||
}
|
||||
SIMD_INLINE v256 v256_zip_8(v128 a, v128 b) { return c_v256_zip_8(a, b); }
|
||||
SIMD_INLINE v256 v256_zip_16(v128 a, v128 b) { return c_v256_zip_16(a, b); }
|
||||
SIMD_INLINE v256 v256_zip_32(v128 a, v128 b) { return c_v256_zip_32(a, b); }
|
||||
SIMD_INLINE v256 v256_unziplo_8(v256 a, v256 b) {
|
||||
return c_v256_unziplo_8(a, b);
|
||||
}
|
||||
SIMD_INLINE v256 v256_unziphi_8(v256 a, v256 b) {
|
||||
return c_v256_unziphi_8(a, b);
|
||||
}
|
||||
SIMD_INLINE v256 v256_unziplo_16(v256 a, v256 b) {
|
||||
return c_v256_unziplo_16(a, b);
|
||||
}
|
||||
SIMD_INLINE v256 v256_unziphi_16(v256 a, v256 b) {
|
||||
return c_v256_unziphi_16(a, b);
|
||||
}
|
||||
SIMD_INLINE v256 v256_unziplo_32(v256 a, v256 b) {
|
||||
return c_v256_unziplo_32(a, b);
|
||||
}
|
||||
SIMD_INLINE v256 v256_unziphi_32(v256 a, v256 b) {
|
||||
return c_v256_unziphi_32(a, b);
|
||||
}
|
||||
SIMD_INLINE v256 v256_unpack_u8_s16(v128 a) { return c_v256_unpack_u8_s16(a); }
|
||||
SIMD_INLINE v256 v256_unpacklo_u8_s16(v256 a) {
|
||||
return c_v256_unpacklo_u8_s16(a);
|
||||
}
|
||||
SIMD_INLINE v256 v256_unpackhi_u8_s16(v256 a) {
|
||||
return c_v256_unpackhi_u8_s16(a);
|
||||
}
|
||||
SIMD_INLINE v256 v256_pack_s32_s16(v256 a, v256 b) {
|
||||
return c_v256_pack_s32_s16(a, b);
|
||||
}
|
||||
SIMD_INLINE v256 v256_pack_s16_u8(v256 a, v256 b) {
|
||||
return c_v256_pack_s16_u8(a, b);
|
||||
}
|
||||
SIMD_INLINE v256 v256_pack_s16_s8(v256 a, v256 b) {
|
||||
return c_v256_pack_s16_s8(a, b);
|
||||
}
|
||||
SIMD_INLINE v256 v256_unpack_u16_s32(v128 a) {
|
||||
return c_v256_unpack_u16_s32(a);
|
||||
}
|
||||
SIMD_INLINE v256 v256_unpack_s16_s32(v128 a) {
|
||||
return c_v256_unpack_s16_s32(a);
|
||||
}
|
||||
SIMD_INLINE v256 v256_unpacklo_u16_s32(v256 a) {
|
||||
return c_v256_unpacklo_u16_s32(a);
|
||||
}
|
||||
SIMD_INLINE v256 v256_unpacklo_s16_s32(v256 a) {
|
||||
return c_v256_unpacklo_s16_s32(a);
|
||||
}
|
||||
SIMD_INLINE v256 v256_unpackhi_u16_s32(v256 a) {
|
||||
return c_v256_unpackhi_u16_s32(a);
|
||||
}
|
||||
SIMD_INLINE v256 v256_unpackhi_s16_s32(v256 a) {
|
||||
return c_v256_unpackhi_s16_s32(a);
|
||||
}
|
||||
SIMD_INLINE v256 v256_shuffle_8(v256 a, v256 pattern) {
|
||||
return c_v256_shuffle_8(a, pattern);
|
||||
}
|
||||
SIMD_INLINE v256 v256_pshuffle_8(v256 a, v256 pattern) {
|
||||
return c_v256_pshuffle_8(a, pattern);
|
||||
}
|
||||
|
||||
SIMD_INLINE v256 v256_cmpgt_s8(v256 a, v256 b) { return c_v256_cmpgt_s8(a, b); }
|
||||
SIMD_INLINE v256 v256_cmplt_s8(v256 a, v256 b) { return c_v256_cmplt_s8(a, b); }
|
||||
SIMD_INLINE v256 v256_cmpeq_8(v256 a, v256 b) { return c_v256_cmpeq_8(a, b); }
|
||||
SIMD_INLINE v256 v256_cmpgt_s16(v256 a, v256 b) {
|
||||
return c_v256_cmpgt_s16(a, b);
|
||||
}
|
||||
SIMD_INLINE v256 v256_cmplt_s16(v256 a, v256 b) {
|
||||
return c_v256_cmplt_s16(a, b);
|
||||
}
|
||||
SIMD_INLINE v256 v256_cmpeq_16(v256 a, v256 b) { return c_v256_cmpeq_16(a, b); }
|
||||
|
||||
SIMD_INLINE v256 v256_shl_8(v256 a, unsigned int c) {
|
||||
return c_v256_shl_8(a, c);
|
||||
}
|
||||
SIMD_INLINE v256 v256_shr_u8(v256 a, unsigned int c) {
|
||||
return c_v256_shr_u8(a, c);
|
||||
}
|
||||
SIMD_INLINE v256 v256_shr_s8(v256 a, unsigned int c) {
|
||||
return c_v256_shr_s8(a, c);
|
||||
}
|
||||
SIMD_INLINE v256 v256_shl_16(v256 a, unsigned int c) {
|
||||
return c_v256_shl_16(a, c);
|
||||
}
|
||||
SIMD_INLINE v256 v256_shr_u16(v256 a, unsigned int c) {
|
||||
return c_v256_shr_u16(a, c);
|
||||
}
|
||||
SIMD_INLINE v256 v256_shr_s16(v256 a, unsigned int c) {
|
||||
return c_v256_shr_s16(a, c);
|
||||
}
|
||||
SIMD_INLINE v256 v256_shl_32(v256 a, unsigned int c) {
|
||||
return c_v256_shl_32(a, c);
|
||||
}
|
||||
SIMD_INLINE v256 v256_shr_u32(v256 a, unsigned int c) {
|
||||
return c_v256_shr_u32(a, c);
|
||||
}
|
||||
SIMD_INLINE v256 v256_shr_s32(v256 a, unsigned int c) {
|
||||
return c_v256_shr_s32(a, c);
|
||||
}
|
||||
|
||||
SIMD_INLINE v256 v256_shr_n_byte(v256 a, const unsigned int n) {
|
||||
return c_v256_shr_n_byte(a, n);
|
||||
}
|
||||
SIMD_INLINE v256 v256_shl_n_byte(v256 a, const unsigned int n) {
|
||||
return c_v256_shl_n_byte(a, n);
|
||||
}
|
||||
SIMD_INLINE v256 v256_shl_n_8(v256 a, const unsigned int n) {
|
||||
return c_v256_shl_n_8(a, n);
|
||||
}
|
||||
SIMD_INLINE v256 v256_shl_n_16(v256 a, const unsigned int n) {
|
||||
return c_v256_shl_n_16(a, n);
|
||||
}
|
||||
SIMD_INLINE v256 v256_shl_n_32(v256 a, const unsigned int n) {
|
||||
return c_v256_shl_n_32(a, n);
|
||||
}
|
||||
SIMD_INLINE v256 v256_shr_n_u8(v256 a, const unsigned int n) {
|
||||
return c_v256_shr_n_u8(a, n);
|
||||
}
|
||||
SIMD_INLINE v256 v256_shr_n_u16(v256 a, const unsigned int n) {
|
||||
return c_v256_shr_n_u16(a, n);
|
||||
}
|
||||
SIMD_INLINE v256 v256_shr_n_u32(v256 a, const unsigned int n) {
|
||||
return c_v256_shr_n_u32(a, n);
|
||||
}
|
||||
SIMD_INLINE v256 v256_shr_n_s8(v256 a, const unsigned int n) {
|
||||
return c_v256_shr_n_s8(a, n);
|
||||
}
|
||||
SIMD_INLINE v256 v256_shr_n_s16(v256 a, const unsigned int n) {
|
||||
return c_v256_shr_n_s16(a, n);
|
||||
}
|
||||
SIMD_INLINE v256 v256_shr_n_s32(v256 a, const unsigned int n) {
|
||||
return c_v256_shr_n_s32(a, n);
|
||||
}
|
||||
|
||||
#endif /* _V256_INTRINSICS_H */
|
||||
@@ -1,17 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2016, Alliance for Open Media. All rights reserved
|
||||
*
|
||||
* This source code is subject to the terms of the BSD 2 Clause License and
|
||||
* the Alliance for Open Media Patent License 1.0. If the BSD 2 Clause License
|
||||
* was not distributed with this source code in the LICENSE file, you can
|
||||
* obtain it at www.aomedia.org/license/software. If the Alliance for Open
|
||||
* Media Patent License 1.0 was not distributed with this source code in the
|
||||
* PATENTS file, you can obtain it at www.aomedia.org/license/patent.
|
||||
*/
|
||||
|
||||
#ifndef _V256_INTRINSICS_H
|
||||
#define _V256_INTRINSICS_H
|
||||
|
||||
#include "./v256_intrinsics_v128.h"
|
||||
|
||||
#endif /* _V256_INTRINSICS_H */
|
||||
@@ -1,701 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2016, Alliance for Open Media. All rights reserved
|
||||
*
|
||||
* This source code is subject to the terms of the BSD 2 Clause License and
|
||||
* the Alliance for Open Media Patent License 1.0. If the BSD 2 Clause License
|
||||
* was not distributed with this source code in the LICENSE file, you can
|
||||
* obtain it at www.aomedia.org/license/software. If the Alliance for Open
|
||||
* Media Patent License 1.0 was not distributed with this source code in the
|
||||
* PATENTS file, you can obtain it at www.aomedia.org/license/patent.
|
||||
*/
|
||||
|
||||
#ifndef _V256_INTRINSICS_C_H
|
||||
#define _V256_INTRINSICS_C_H
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include "./v128_intrinsics_c.h"
|
||||
#include "./aom_config.h"
|
||||
|
||||
typedef union {
|
||||
uint8_t u8[32];
|
||||
uint16_t u16[16];
|
||||
uint32_t u32[8];
|
||||
uint64_t u64[4];
|
||||
int8_t s8[32];
|
||||
int16_t s16[16];
|
||||
int32_t s32[8];
|
||||
int64_t s64[4];
|
||||
c_v64 v64[4];
|
||||
c_v128 v128[2];
|
||||
} c_v256;
|
||||
|
||||
SIMD_INLINE uint32_t c_v256_low_u32(c_v256 a) { return a.u32[0]; }
|
||||
|
||||
SIMD_INLINE c_v64 c_v256_low_v64(c_v256 a) { return a.v64[0]; }
|
||||
|
||||
SIMD_INLINE c_v128 c_v256_low_v128(c_v256 a) { return a.v128[0]; }
|
||||
|
||||
SIMD_INLINE c_v128 c_v256_high_v128(c_v256 a) { return a.v128[1]; }
|
||||
|
||||
SIMD_INLINE c_v256 c_v256_from_v128(c_v128 hi, c_v128 lo) {
|
||||
c_v256 t;
|
||||
t.v128[1] = hi;
|
||||
t.v128[0] = lo;
|
||||
return t;
|
||||
}
|
||||
|
||||
SIMD_INLINE c_v256 c_v256_from_64(uint64_t a, uint64_t b, uint64_t c,
|
||||
uint64_t d) {
|
||||
c_v256 t;
|
||||
t.u64[3] = a;
|
||||
t.u64[2] = b;
|
||||
t.u64[1] = c;
|
||||
t.u64[0] = d;
|
||||
return t;
|
||||
}
|
||||
|
||||
SIMD_INLINE c_v256 c_v256_from_v64(c_v64 a, c_v64 b, c_v64 c, c_v64 d) {
|
||||
c_v256 t;
|
||||
t.u64[3] = a.u64;
|
||||
t.u64[2] = b.u64;
|
||||
t.u64[1] = c.u64;
|
||||
t.u64[0] = d.u64;
|
||||
return t;
|
||||
}
|
||||
|
||||
SIMD_INLINE c_v256 c_v256_load_unaligned(const void *p) {
|
||||
c_v256 t;
|
||||
uint8_t *pp = (uint8_t *)p;
|
||||
uint8_t *q = (uint8_t *)&t;
|
||||
int c;
|
||||
for (c = 0; c < 32; c++) q[c] = pp[c];
|
||||
return t;
|
||||
}
|
||||
|
||||
SIMD_INLINE c_v256 c_v256_load_aligned(const void *p) {
|
||||
if (simd_check && (uintptr_t)p & 31) {
|
||||
fprintf(stderr, "Error: unaligned v256 load at %p\n", p);
|
||||
abort();
|
||||
}
|
||||
return c_v256_load_unaligned(p);
|
||||
}
|
||||
|
||||
SIMD_INLINE void c_v256_store_unaligned(void *p, c_v256 a) {
|
||||
uint8_t *pp = (uint8_t *)p;
|
||||
uint8_t *q = (uint8_t *)&a;
|
||||
int c;
|
||||
for (c = 0; c < 32; c++) pp[c] = q[c];
|
||||
}
|
||||
|
||||
SIMD_INLINE void c_v256_store_aligned(void *p, c_v256 a) {
|
||||
if (simd_check && (uintptr_t)p & 31) {
|
||||
fprintf(stderr, "Error: unaligned v256 store at %p\n", p);
|
||||
abort();
|
||||
}
|
||||
c_v256_store_unaligned(p, a);
|
||||
}
|
||||
|
||||
SIMD_INLINE c_v256 c_v256_zero() {
|
||||
c_v256 t;
|
||||
t.u64[3] = t.u64[2] = t.u64[1] = t.u64[0] = 0;
|
||||
return t;
|
||||
}
|
||||
|
||||
SIMD_INLINE c_v256 c_v256_dup_8(uint8_t x) {
|
||||
c_v256 t;
|
||||
t.v64[3] = t.v64[2] = t.v64[1] = t.v64[0] = c_v64_dup_8(x);
|
||||
return t;
|
||||
}
|
||||
|
||||
SIMD_INLINE c_v256 c_v256_dup_16(uint16_t x) {
|
||||
c_v256 t;
|
||||
t.v64[3] = t.v64[2] = t.v64[1] = t.v64[0] = c_v64_dup_16(x);
|
||||
return t;
|
||||
}
|
||||
|
||||
SIMD_INLINE c_v256 c_v256_dup_32(uint32_t x) {
|
||||
c_v256 t;
|
||||
t.v64[3] = t.v64[2] = t.v64[1] = t.v64[0] = c_v64_dup_32(x);
|
||||
return t;
|
||||
}
|
||||
|
||||
SIMD_INLINE int64_t c_v256_dotp_s16(c_v256 a, c_v256 b) {
|
||||
return c_v128_dotp_s16(a.v128[1], b.v128[1]) +
|
||||
c_v128_dotp_s16(a.v128[0], b.v128[0]);
|
||||
}
|
||||
|
||||
SIMD_INLINE uint64_t c_v256_hadd_u8(c_v256 a) {
|
||||
return c_v128_hadd_u8(a.v128[1]) + c_v128_hadd_u8(a.v128[0]);
|
||||
}
|
||||
|
||||
typedef uint32_t c_sad256_internal;
|
||||
|
||||
SIMD_INLINE c_sad128_internal c_v256_sad_u8_init() { return 0; }
|
||||
|
||||
/* Implementation dependent return value. Result must be finalised with
|
||||
v256_sad_u8_sum().
|
||||
The result for more than 16 v256_sad_u8() calls is undefined. */
|
||||
SIMD_INLINE c_sad128_internal c_v256_sad_u8(c_sad256_internal s, c_v256 a,
|
||||
c_v256 b) {
|
||||
int c;
|
||||
for (c = 0; c < 32; c++)
|
||||
s += a.u8[c] > b.u8[c] ? a.u8[c] - b.u8[c] : b.u8[c] - a.u8[c];
|
||||
return s;
|
||||
}
|
||||
|
||||
SIMD_INLINE uint32_t c_v256_sad_u8_sum(c_sad256_internal s) { return s; }
|
||||
|
||||
typedef uint32_t c_ssd256_internal;
|
||||
|
||||
SIMD_INLINE c_ssd256_internal c_v256_ssd_u8_init() { return 0; }
|
||||
|
||||
/* Implementation dependent return value. Result must be finalised with
|
||||
* v256_ssd_u8_sum(). */
|
||||
SIMD_INLINE c_ssd256_internal c_v256_ssd_u8(c_ssd256_internal s, c_v256 a,
|
||||
c_v256 b) {
|
||||
int c;
|
||||
for (c = 0; c < 32; c++) s += (a.u8[c] - b.u8[c]) * (a.u8[c] - b.u8[c]);
|
||||
return s;
|
||||
}
|
||||
|
||||
SIMD_INLINE uint32_t c_v256_ssd_u8_sum(c_ssd256_internal s) { return s; }
|
||||
|
||||
SIMD_INLINE c_v256 c_v256_or(c_v256 a, c_v256 b) {
|
||||
return c_v256_from_v128(c_v128_or(a.v128[1], b.v128[1]),
|
||||
c_v128_or(a.v128[0], b.v128[0]));
|
||||
}
|
||||
|
||||
SIMD_INLINE c_v256 c_v256_xor(c_v256 a, c_v256 b) {
|
||||
return c_v256_from_v128(c_v128_xor(a.v128[1], b.v128[1]),
|
||||
c_v128_xor(a.v128[0], b.v128[0]));
|
||||
}
|
||||
|
||||
SIMD_INLINE c_v256 c_v256_and(c_v256 a, c_v256 b) {
|
||||
return c_v256_from_v128(c_v128_and(a.v128[1], b.v128[1]),
|
||||
c_v128_and(a.v128[0], b.v128[0]));
|
||||
}
|
||||
|
||||
SIMD_INLINE c_v256 c_v256_andn(c_v256 a, c_v256 b) {
|
||||
return c_v256_from_v128(c_v128_andn(a.v128[1], b.v128[1]),
|
||||
c_v128_andn(a.v128[0], b.v128[0]));
|
||||
}
|
||||
|
||||
SIMD_INLINE c_v256 c_v256_add_8(c_v256 a, c_v256 b) {
|
||||
return c_v256_from_v128(c_v128_add_8(a.v128[1], b.v128[1]),
|
||||
c_v128_add_8(a.v128[0], b.v128[0]));
|
||||
}
|
||||
|
||||
SIMD_INLINE c_v256 c_v256_add_16(c_v256 a, c_v256 b) {
|
||||
return c_v256_from_v128(c_v128_add_16(a.v128[1], b.v128[1]),
|
||||
c_v128_add_16(a.v128[0], b.v128[0]));
|
||||
}
|
||||
|
||||
SIMD_INLINE c_v256 c_v256_sadd_s16(c_v256 a, c_v256 b) {
|
||||
return c_v256_from_v128(c_v128_sadd_s16(a.v128[1], b.v128[1]),
|
||||
c_v128_sadd_s16(a.v128[0], b.v128[0]));
|
||||
}
|
||||
|
||||
SIMD_INLINE c_v256 c_v256_add_32(c_v256 a, c_v256 b) {
|
||||
return c_v256_from_v128(c_v128_add_32(a.v128[1], b.v128[1]),
|
||||
c_v128_add_32(a.v128[0], b.v128[0]));
|
||||
}
|
||||
|
||||
SIMD_INLINE c_v256 c_v256_padd_s16(c_v256 a) {
|
||||
c_v256 t;
|
||||
t.s32[0] = (int32_t)a.s16[0] + (int32_t)a.s16[1];
|
||||
t.s32[1] = (int32_t)a.s16[2] + (int32_t)a.s16[3];
|
||||
t.s32[2] = (int32_t)a.s16[4] + (int32_t)a.s16[5];
|
||||
t.s32[3] = (int32_t)a.s16[6] + (int32_t)a.s16[7];
|
||||
t.s32[4] = (int32_t)a.s16[8] + (int32_t)a.s16[9];
|
||||
t.s32[5] = (int32_t)a.s16[10] + (int32_t)a.s16[11];
|
||||
t.s32[6] = (int32_t)a.s16[12] + (int32_t)a.s16[13];
|
||||
t.s32[7] = (int32_t)a.s16[14] + (int32_t)a.s16[15];
|
||||
return t;
|
||||
}
|
||||
|
||||
SIMD_INLINE c_v256 c_v256_sub_8(c_v256 a, c_v256 b) {
|
||||
return c_v256_from_v128(c_v128_sub_8(a.v128[1], b.v128[1]),
|
||||
c_v128_sub_8(a.v128[0], b.v128[0]));
|
||||
}
|
||||
|
||||
SIMD_INLINE c_v256 c_v256_ssub_u8(c_v256 a, c_v256 b) {
|
||||
return c_v256_from_v128(c_v128_ssub_u8(a.v128[1], b.v128[1]),
|
||||
c_v128_ssub_u8(a.v128[0], b.v128[0]));
|
||||
}
|
||||
|
||||
SIMD_INLINE c_v256 c_v256_ssub_s8(c_v256 a, c_v256 b) {
|
||||
return c_v256_from_v128(c_v128_ssub_s8(a.v128[1], b.v128[1]),
|
||||
c_v128_ssub_s8(a.v128[0], b.v128[0]));
|
||||
}
|
||||
|
||||
SIMD_INLINE c_v256 c_v256_sub_16(c_v256 a, c_v256 b) {
|
||||
return c_v256_from_v128(c_v128_sub_16(a.v128[1], b.v128[1]),
|
||||
c_v128_sub_16(a.v128[0], b.v128[0]));
|
||||
}
|
||||
|
||||
SIMD_INLINE c_v256 c_v256_ssub_s16(c_v256 a, c_v256 b) {
|
||||
return c_v256_from_v128(c_v128_ssub_s16(a.v128[1], b.v128[1]),
|
||||
c_v128_ssub_s16(a.v128[0], b.v128[0]));
|
||||
}
|
||||
|
||||
SIMD_INLINE c_v256 c_v256_sub_32(c_v256 a, c_v256 b) {
|
||||
return c_v256_from_v128(c_v128_sub_32(a.v128[1], b.v128[1]),
|
||||
c_v128_sub_32(a.v128[0], b.v128[0]));
|
||||
}
|
||||
|
||||
SIMD_INLINE c_v256 c_v256_abs_s16(c_v256 a) {
|
||||
return c_v256_from_v128(c_v128_abs_s16(a.v128[1]), c_v128_abs_s16(a.v128[0]));
|
||||
}
|
||||
|
||||
SIMD_INLINE c_v256 c_v256_mul_s16(c_v128 a, c_v128 b) {
|
||||
c_v128 lo_bits = c_v128_mullo_s16(a, b);
|
||||
c_v128 hi_bits = c_v128_mulhi_s16(a, b);
|
||||
return c_v256_from_v128(c_v128_ziphi_16(hi_bits, lo_bits),
|
||||
c_v128_ziplo_16(hi_bits, lo_bits));
|
||||
}
|
||||
|
||||
SIMD_INLINE c_v256 c_v256_mullo_s16(c_v256 a, c_v256 b) {
|
||||
return c_v256_from_v128(c_v128_mullo_s16(a.v128[1], b.v128[1]),
|
||||
c_v128_mullo_s16(a.v128[0], b.v128[0]));
|
||||
}
|
||||
|
||||
SIMD_INLINE c_v256 c_v256_mulhi_s16(c_v256 a, c_v256 b) {
|
||||
return c_v256_from_v128(c_v128_mulhi_s16(a.v128[1], b.v128[1]),
|
||||
c_v128_mulhi_s16(a.v128[0], b.v128[0]));
|
||||
}
|
||||
|
||||
SIMD_INLINE c_v256 c_v256_mullo_s32(c_v256 a, c_v256 b) {
|
||||
return c_v256_from_v128(c_v128_mullo_s32(a.v128[1], b.v128[1]),
|
||||
c_v128_mullo_s32(a.v128[0], b.v128[0]));
|
||||
}
|
||||
|
||||
SIMD_INLINE c_v256 c_v256_madd_s16(c_v256 a, c_v256 b) {
|
||||
return c_v256_from_v128(c_v128_madd_s16(a.v128[1], b.v128[1]),
|
||||
c_v128_madd_s16(a.v128[0], b.v128[0]));
|
||||
}
|
||||
|
||||
SIMD_INLINE c_v256 c_v256_madd_us8(c_v256 a, c_v256 b) {
|
||||
return c_v256_from_v128(c_v128_madd_us8(a.v128[1], b.v128[1]),
|
||||
c_v128_madd_us8(a.v128[0], b.v128[0]));
|
||||
}
|
||||
|
||||
SIMD_INLINE c_v256 c_v256_avg_u8(c_v256 a, c_v256 b) {
|
||||
return c_v256_from_v128(c_v128_avg_u8(a.v128[1], b.v128[1]),
|
||||
c_v128_avg_u8(a.v128[0], b.v128[0]));
|
||||
}
|
||||
|
||||
SIMD_INLINE c_v256 c_v256_rdavg_u8(c_v256 a, c_v256 b) {
|
||||
return c_v256_from_v128(c_v128_rdavg_u8(a.v128[1], b.v128[1]),
|
||||
c_v128_rdavg_u8(a.v128[0], b.v128[0]));
|
||||
}
|
||||
|
||||
SIMD_INLINE c_v256 c_v256_avg_u16(c_v256 a, c_v256 b) {
|
||||
return c_v256_from_v128(c_v128_avg_u16(a.v128[1], b.v128[1]),
|
||||
c_v128_avg_u16(a.v128[0], b.v128[0]));
|
||||
}
|
||||
|
||||
SIMD_INLINE c_v256 c_v256_min_u8(c_v256 a, c_v256 b) {
|
||||
return c_v256_from_v128(c_v128_min_u8(a.v128[1], b.v128[1]),
|
||||
c_v128_min_u8(a.v128[0], b.v128[0]));
|
||||
}
|
||||
|
||||
SIMD_INLINE c_v256 c_v256_max_u8(c_v256 a, c_v256 b) {
|
||||
return c_v256_from_v128(c_v128_max_u8(a.v128[1], b.v128[1]),
|
||||
c_v128_max_u8(a.v128[0], b.v128[0]));
|
||||
}
|
||||
|
||||
SIMD_INLINE c_v256 c_v256_min_s8(c_v256 a, c_v256 b) {
|
||||
return c_v256_from_v128(c_v128_min_s8(a.v128[1], b.v128[1]),
|
||||
c_v128_min_s8(a.v128[0], b.v128[0]));
|
||||
}
|
||||
|
||||
SIMD_INLINE c_v256 c_v256_max_s8(c_v256 a, c_v256 b) {
|
||||
return c_v256_from_v128(c_v128_max_s8(a.v128[1], b.v128[1]),
|
||||
c_v128_max_s8(a.v128[0], b.v128[0]));
|
||||
}
|
||||
|
||||
SIMD_INLINE c_v256 c_v256_min_s16(c_v256 a, c_v256 b) {
|
||||
return c_v256_from_v128(c_v128_min_s16(a.v128[1], b.v128[1]),
|
||||
c_v128_min_s16(a.v128[0], b.v128[0]));
|
||||
}
|
||||
|
||||
SIMD_INLINE c_v256 c_v256_max_s16(c_v256 a, c_v256 b) {
|
||||
return c_v256_from_v128(c_v128_max_s16(a.v128[1], b.v128[1]),
|
||||
c_v128_max_s16(a.v128[0], b.v128[0]));
|
||||
}
|
||||
|
||||
SIMD_INLINE c_v256 c_v256_ziplo_8(c_v256 a, c_v256 b) {
|
||||
return c_v256_from_v128(c_v128_ziphi_8(a.v128[0], b.v128[0]),
|
||||
c_v128_ziplo_8(a.v128[0], b.v128[0]));
|
||||
}
|
||||
|
||||
SIMD_INLINE c_v256 c_v256_ziphi_8(c_v256 a, c_v256 b) {
|
||||
return c_v256_from_v128(c_v128_ziphi_8(a.v128[1], b.v128[1]),
|
||||
c_v128_ziplo_8(a.v128[1], b.v128[1]));
|
||||
}
|
||||
|
||||
SIMD_INLINE c_v256 c_v256_ziplo_16(c_v256 a, c_v256 b) {
|
||||
return c_v256_from_v128(c_v128_ziphi_16(a.v128[0], b.v128[0]),
|
||||
c_v128_ziplo_16(a.v128[0], b.v128[0]));
|
||||
}
|
||||
|
||||
SIMD_INLINE c_v256 c_v256_ziphi_16(c_v256 a, c_v256 b) {
|
||||
return c_v256_from_v128(c_v128_ziphi_16(a.v128[1], b.v128[1]),
|
||||
c_v128_ziplo_16(a.v128[1], b.v128[1]));
|
||||
}
|
||||
|
||||
SIMD_INLINE c_v256 c_v256_ziplo_32(c_v256 a, c_v256 b) {
|
||||
return c_v256_from_v128(c_v128_ziphi_32(a.v128[0], b.v128[0]),
|
||||
c_v128_ziplo_32(a.v128[0], b.v128[0]));
|
||||
}
|
||||
|
||||
SIMD_INLINE c_v256 c_v256_ziphi_32(c_v256 a, c_v256 b) {
|
||||
return c_v256_from_v128(c_v128_ziphi_32(a.v128[1], b.v128[1]),
|
||||
c_v128_ziplo_32(a.v128[1], b.v128[1]));
|
||||
}
|
||||
|
||||
SIMD_INLINE c_v256 c_v256_ziplo_64(c_v256 a, c_v256 b) {
|
||||
return c_v256_from_v128(c_v128_ziphi_64(a.v128[0], b.v128[0]),
|
||||
c_v128_ziplo_64(a.v128[0], b.v128[0]));
|
||||
}
|
||||
|
||||
SIMD_INLINE c_v256 c_v256_ziphi_64(c_v256 a, c_v256 b) {
|
||||
return c_v256_from_v128(c_v128_ziphi_64(a.v128[1], b.v128[1]),
|
||||
c_v128_ziplo_64(a.v128[1], b.v128[1]));
|
||||
}
|
||||
|
||||
SIMD_INLINE c_v256 c_v256_ziplo_128(c_v256 a, c_v256 b) {
|
||||
return c_v256_from_v128(a.v128[0], b.v128[0]);
|
||||
}
|
||||
|
||||
SIMD_INLINE c_v256 c_v256_ziphi_128(c_v256 a, c_v256 b) {
|
||||
return c_v256_from_v128(a.v128[1], b.v128[1]);
|
||||
}
|
||||
|
||||
SIMD_INLINE c_v256 c_v256_zip_8(c_v128 a, c_v128 b) {
|
||||
return c_v256_from_v128(c_v128_ziphi_8(a, b), c_v128_ziplo_8(a, b));
|
||||
}
|
||||
|
||||
SIMD_INLINE c_v256 c_v256_zip_16(c_v128 a, c_v128 b) {
|
||||
return c_v256_from_v128(c_v128_ziphi_16(a, b), c_v128_ziplo_16(a, b));
|
||||
}
|
||||
|
||||
SIMD_INLINE c_v256 c_v256_zip_32(c_v128 a, c_v128 b) {
|
||||
return c_v256_from_v128(c_v128_ziphi_32(a, b), c_v128_ziplo_32(a, b));
|
||||
}
|
||||
|
||||
SIMD_INLINE c_v256 _c_v256_unzip_8(c_v256 a, c_v256 b, int mode) {
|
||||
c_v256 t;
|
||||
int i;
|
||||
if (mode) {
|
||||
for (i = 0; i < 16; i++) {
|
||||
t.u8[i] = a.u8[i * 2 + 1];
|
||||
t.u8[i + 16] = b.u8[i * 2 + 1];
|
||||
}
|
||||
} else {
|
||||
for (i = 0; i < 16; i++) {
|
||||
t.u8[i] = b.u8[i * 2];
|
||||
t.u8[i + 16] = a.u8[i * 2];
|
||||
}
|
||||
}
|
||||
return t;
|
||||
}
|
||||
|
||||
SIMD_INLINE c_v256 c_v256_unziplo_8(c_v256 a, c_v256 b) {
|
||||
return CONFIG_BIG_ENDIAN ? _c_v256_unzip_8(a, b, 1)
|
||||
: _c_v256_unzip_8(a, b, 0);
|
||||
}
|
||||
|
||||
SIMD_INLINE c_v256 c_v256_unziphi_8(c_v256 a, c_v256 b) {
|
||||
return CONFIG_BIG_ENDIAN ? _c_v256_unzip_8(b, a, 0)
|
||||
: _c_v256_unzip_8(b, a, 1);
|
||||
}
|
||||
|
||||
SIMD_INLINE c_v256 _c_v256_unzip_16(c_v256 a, c_v256 b, int mode) {
|
||||
c_v256 t;
|
||||
int i;
|
||||
if (mode) {
|
||||
for (i = 0; i < 8; i++) {
|
||||
t.u16[i] = a.u16[i * 2 + 1];
|
||||
t.u16[i + 8] = b.u16[i * 2 + 1];
|
||||
}
|
||||
} else {
|
||||
for (i = 0; i < 8; i++) {
|
||||
t.u16[i] = b.u16[i * 2];
|
||||
t.u16[i + 8] = a.u16[i * 2];
|
||||
}
|
||||
}
|
||||
return t;
|
||||
}
|
||||
|
||||
SIMD_INLINE c_v256 c_v256_unziplo_16(c_v256 a, c_v256 b) {
|
||||
return CONFIG_BIG_ENDIAN ? _c_v256_unzip_16(a, b, 1)
|
||||
: _c_v256_unzip_16(a, b, 0);
|
||||
}
|
||||
|
||||
SIMD_INLINE c_v256 c_v256_unziphi_16(c_v256 a, c_v256 b) {
|
||||
return CONFIG_BIG_ENDIAN ? _c_v256_unzip_16(b, a, 0)
|
||||
: _c_v256_unzip_16(b, a, 1);
|
||||
}
|
||||
|
||||
SIMD_INLINE c_v256 _c_v256_unzip_32(c_v256 a, c_v256 b, int mode) {
|
||||
c_v256 t;
|
||||
if (mode) {
|
||||
t.u32[7] = b.u32[7];
|
||||
t.u32[6] = b.u32[5];
|
||||
t.u32[5] = b.u32[3];
|
||||
t.u32[4] = b.u32[1];
|
||||
t.u32[3] = a.u32[7];
|
||||
t.u32[2] = a.u32[5];
|
||||
t.u32[1] = a.u32[3];
|
||||
t.u32[0] = a.u32[1];
|
||||
} else {
|
||||
t.u32[7] = a.u32[6];
|
||||
t.u32[6] = a.u32[4];
|
||||
t.u32[5] = a.u32[2];
|
||||
t.u32[4] = a.u32[0];
|
||||
t.u32[3] = b.u32[6];
|
||||
t.u32[2] = b.u32[4];
|
||||
t.u32[1] = b.u32[2];
|
||||
t.u32[0] = b.u32[0];
|
||||
}
|
||||
return t;
|
||||
}
|
||||
|
||||
SIMD_INLINE c_v256 c_v256_unziplo_32(c_v256 a, c_v256 b) {
|
||||
return CONFIG_BIG_ENDIAN ? _c_v256_unzip_32(a, b, 1)
|
||||
: _c_v256_unzip_32(a, b, 0);
|
||||
}
|
||||
|
||||
SIMD_INLINE c_v256 c_v256_unziphi_32(c_v256 a, c_v256 b) {
|
||||
return CONFIG_BIG_ENDIAN ? _c_v256_unzip_32(b, a, 0)
|
||||
: _c_v256_unzip_32(b, a, 1);
|
||||
}
|
||||
|
||||
SIMD_INLINE c_v256 c_v256_unpack_u8_s16(c_v128 a) {
|
||||
return c_v256_from_v128(c_v128_unpackhi_u8_s16(a), c_v128_unpacklo_u8_s16(a));
|
||||
}
|
||||
|
||||
SIMD_INLINE c_v256 c_v256_unpacklo_u8_s16(c_v256 a) {
|
||||
return c_v256_from_v128(c_v128_unpackhi_u8_s16(a.v128[0]),
|
||||
c_v128_unpacklo_u8_s16(a.v128[0]));
|
||||
}
|
||||
|
||||
SIMD_INLINE c_v256 c_v256_unpackhi_u8_s16(c_v256 a) {
|
||||
return c_v256_from_v128(c_v128_unpackhi_u8_s16(a.v128[1]),
|
||||
c_v128_unpacklo_u8_s16(a.v128[1]));
|
||||
}
|
||||
|
||||
SIMD_INLINE c_v256 c_v256_pack_s32_s16(c_v256 a, c_v256 b) {
|
||||
return c_v256_from_v128(c_v128_pack_s32_s16(a.v128[1], a.v128[0]),
|
||||
c_v128_pack_s32_s16(b.v128[1], b.v128[0]));
|
||||
}
|
||||
|
||||
SIMD_INLINE c_v256 c_v256_pack_s16_u8(c_v256 a, c_v256 b) {
|
||||
return c_v256_from_v128(c_v128_pack_s16_u8(a.v128[1], a.v128[0]),
|
||||
c_v128_pack_s16_u8(b.v128[1], b.v128[0]));
|
||||
}
|
||||
|
||||
SIMD_INLINE c_v256 c_v256_pack_s16_s8(c_v256 a, c_v256 b) {
|
||||
return c_v256_from_v128(c_v128_pack_s16_s8(a.v128[1], a.v128[0]),
|
||||
c_v128_pack_s16_s8(b.v128[1], b.v128[0]));
|
||||
}
|
||||
|
||||
SIMD_INLINE c_v256 c_v256_unpack_u16_s32(c_v128 a) {
|
||||
return c_v256_from_v128(c_v128_unpackhi_u16_s32(a),
|
||||
c_v128_unpacklo_u16_s32(a));
|
||||
}
|
||||
|
||||
SIMD_INLINE c_v256 c_v256_unpack_s16_s32(c_v128 a) {
|
||||
return c_v256_from_v128(c_v128_unpackhi_s16_s32(a),
|
||||
c_v128_unpacklo_s16_s32(a));
|
||||
}
|
||||
|
||||
SIMD_INLINE c_v256 c_v256_unpacklo_u16_s32(c_v256 a) {
|
||||
return c_v256_from_v128(c_v128_unpackhi_u16_s32(a.v128[0]),
|
||||
c_v128_unpacklo_u16_s32(a.v128[0]));
|
||||
}
|
||||
|
||||
SIMD_INLINE c_v256 c_v256_unpacklo_s16_s32(c_v256 a) {
|
||||
return c_v256_from_v128(c_v128_unpackhi_s16_s32(a.v128[0]),
|
||||
c_v128_unpacklo_s16_s32(a.v128[0]));
|
||||
}
|
||||
|
||||
SIMD_INLINE c_v256 c_v256_unpackhi_u16_s32(c_v256 a) {
|
||||
return c_v256_from_v128(c_v128_unpackhi_u16_s32(a.v128[1]),
|
||||
c_v128_unpacklo_u16_s32(a.v128[1]));
|
||||
}
|
||||
|
||||
SIMD_INLINE c_v256 c_v256_unpackhi_s16_s32(c_v256 a) {
|
||||
return c_v256_from_v128(c_v128_unpackhi_s16_s32(a.v128[1]),
|
||||
c_v128_unpacklo_s16_s32(a.v128[1]));
|
||||
}
|
||||
|
||||
SIMD_INLINE c_v256 c_v256_shuffle_8(c_v256 a, c_v256 pattern) {
|
||||
c_v256 t;
|
||||
int c;
|
||||
for (c = 0; c < 32; c++) {
|
||||
if (pattern.u8[c] & ~31) {
|
||||
fprintf(stderr, "Undefined v256_shuffle_8 index %d/%d\n", pattern.u8[c],
|
||||
c);
|
||||
abort();
|
||||
}
|
||||
t.u8[c] = a.u8[CONFIG_BIG_ENDIAN ? 31 - (pattern.u8[c] & 31)
|
||||
: pattern.u8[c] & 31];
|
||||
}
|
||||
return t;
|
||||
}
|
||||
|
||||
// Pairwise / dual-lane shuffle: shuffle two 128 bit lates.
|
||||
SIMD_INLINE c_v256 c_v256_pshuffle_8(c_v256 a, c_v256 pattern) {
|
||||
return c_v256_from_v128(
|
||||
c_v128_shuffle_8(c_v256_high_v128(a), c_v256_high_v128(pattern)),
|
||||
c_v128_shuffle_8(c_v256_low_v128(a), c_v256_low_v128(pattern)));
|
||||
}
|
||||
|
||||
SIMD_INLINE c_v256 c_v256_cmpgt_s8(c_v256 a, c_v256 b) {
|
||||
return c_v256_from_v128(c_v128_cmpgt_s8(a.v128[1], b.v128[1]),
|
||||
c_v128_cmpgt_s8(a.v128[0], b.v128[0]));
|
||||
}
|
||||
|
||||
SIMD_INLINE c_v256 c_v256_cmplt_s8(c_v256 a, c_v256 b) {
|
||||
return c_v256_from_v128(c_v128_cmplt_s8(a.v128[1], b.v128[1]),
|
||||
c_v128_cmplt_s8(a.v128[0], b.v128[0]));
|
||||
}
|
||||
|
||||
SIMD_INLINE c_v256 c_v256_cmpeq_8(c_v256 a, c_v256 b) {
|
||||
return c_v256_from_v128(c_v128_cmpeq_8(a.v128[1], b.v128[1]),
|
||||
c_v128_cmpeq_8(a.v128[0], b.v128[0]));
|
||||
}
|
||||
|
||||
SIMD_INLINE c_v256 c_v256_cmpgt_s16(c_v256 a, c_v256 b) {
|
||||
return c_v256_from_v128(c_v128_cmpgt_s16(a.v128[1], b.v128[1]),
|
||||
c_v128_cmpgt_s16(a.v128[0], b.v128[0]));
|
||||
}
|
||||
|
||||
SIMD_INLINE c_v256 c_v256_cmplt_s16(c_v256 a, c_v256 b) {
|
||||
return c_v256_from_v128(c_v128_cmplt_s16(a.v128[1], b.v128[1]),
|
||||
c_v128_cmplt_s16(a.v128[0], b.v128[0]));
|
||||
}
|
||||
|
||||
SIMD_INLINE c_v256 c_v256_cmpeq_16(c_v256 a, c_v256 b) {
|
||||
return c_v256_from_v128(c_v128_cmpeq_16(a.v128[1], b.v128[1]),
|
||||
c_v128_cmpeq_16(a.v128[0], b.v128[0]));
|
||||
}
|
||||
|
||||
SIMD_INLINE c_v256 c_v256_shl_n_byte(c_v256 a, const unsigned int n) {
|
||||
if (n < 16)
|
||||
return c_v256_from_v128(c_v128_or(c_v128_shl_n_byte(a.v128[1], n),
|
||||
c_v128_shr_n_byte(a.v128[0], 16 - n)),
|
||||
c_v128_shl_n_byte(a.v128[0], n));
|
||||
else if (n > 16)
|
||||
return c_v256_from_v128(c_v128_shl_n_byte(a.v128[0], n - 16),
|
||||
c_v128_zero());
|
||||
else
|
||||
return c_v256_from_v128(c_v256_low_v128(a), c_v128_zero());
|
||||
}
|
||||
|
||||
SIMD_INLINE c_v256 c_v256_shr_n_byte(c_v256 a, const unsigned int n) {
|
||||
if (n < 16)
|
||||
return c_v256_from_v128(c_v128_shr_n_byte(a.v128[1], n),
|
||||
c_v128_or(c_v128_shr_n_byte(a.v128[0], n),
|
||||
c_v128_shl_n_byte(a.v128[1], 16 - n)));
|
||||
else if (n > 16)
|
||||
return c_v256_from_v128(c_v128_zero(),
|
||||
c_v128_shr_n_byte(a.v128[1], n - 16));
|
||||
else
|
||||
return c_v256_from_v128(c_v128_zero(), c_v256_high_v128(a));
|
||||
}
|
||||
|
||||
SIMD_INLINE c_v256 c_v256_align(c_v256 a, c_v256 b, const unsigned int c) {
|
||||
if (simd_check && c > 31) {
|
||||
fprintf(stderr, "Error: undefined alignment %d\n", c);
|
||||
abort();
|
||||
}
|
||||
return c ? c_v256_or(c_v256_shr_n_byte(b, c), c_v256_shl_n_byte(a, 32 - c))
|
||||
: b;
|
||||
}
|
||||
|
||||
SIMD_INLINE c_v256 c_v256_shl_8(c_v256 a, const unsigned int c) {
|
||||
return c_v256_from_v128(c_v128_shl_8(a.v128[1], c),
|
||||
c_v128_shl_8(a.v128[0], c));
|
||||
}
|
||||
|
||||
SIMD_INLINE c_v256 c_v256_shr_u8(c_v256 a, const unsigned int c) {
|
||||
return c_v256_from_v128(c_v128_shr_u8(a.v128[1], c),
|
||||
c_v128_shr_u8(a.v128[0], c));
|
||||
}
|
||||
|
||||
SIMD_INLINE c_v256 c_v256_shr_s8(c_v256 a, const unsigned int c) {
|
||||
return c_v256_from_v128(c_v128_shr_s8(a.v128[1], c),
|
||||
c_v128_shr_s8(a.v128[0], c));
|
||||
}
|
||||
|
||||
SIMD_INLINE c_v256 c_v256_shl_16(c_v256 a, const unsigned int c) {
|
||||
return c_v256_from_v128(c_v128_shl_16(a.v128[1], c),
|
||||
c_v128_shl_16(a.v128[0], c));
|
||||
}
|
||||
|
||||
SIMD_INLINE c_v256 c_v256_shr_u16(c_v256 a, const unsigned int c) {
|
||||
return c_v256_from_v128(c_v128_shr_u16(a.v128[1], c),
|
||||
c_v128_shr_u16(a.v128[0], c));
|
||||
}
|
||||
|
||||
SIMD_INLINE c_v256 c_v256_shr_s16(c_v256 a, const unsigned int c) {
|
||||
return c_v256_from_v128(c_v128_shr_s16(a.v128[1], c),
|
||||
c_v128_shr_s16(a.v128[0], c));
|
||||
}
|
||||
|
||||
SIMD_INLINE c_v256 c_v256_shl_32(c_v256 a, const unsigned int c) {
|
||||
return c_v256_from_v128(c_v128_shl_32(a.v128[1], c),
|
||||
c_v128_shl_32(a.v128[0], c));
|
||||
}
|
||||
|
||||
SIMD_INLINE c_v256 c_v256_shr_u32(c_v256 a, const unsigned int c) {
|
||||
return c_v256_from_v128(c_v128_shr_u32(a.v128[1], c),
|
||||
c_v128_shr_u32(a.v128[0], c));
|
||||
}
|
||||
|
||||
SIMD_INLINE c_v256 c_v256_shr_s32(c_v256 a, const unsigned int c) {
|
||||
return c_v256_from_v128(c_v128_shr_s32(a.v128[1], c),
|
||||
c_v128_shr_s32(a.v128[0], c));
|
||||
}
|
||||
|
||||
SIMD_INLINE c_v256 c_v256_shl_n_8(c_v256 a, const unsigned int n) {
|
||||
return c_v256_shl_8(a, n);
|
||||
}
|
||||
|
||||
SIMD_INLINE c_v256 c_v256_shl_n_16(c_v256 a, const unsigned int n) {
|
||||
return c_v256_shl_16(a, n);
|
||||
}
|
||||
|
||||
SIMD_INLINE c_v256 c_v256_shl_n_32(c_v256 a, const unsigned int n) {
|
||||
return c_v256_shl_32(a, n);
|
||||
}
|
||||
|
||||
SIMD_INLINE c_v256 c_v256_shr_n_u8(c_v256 a, const unsigned int n) {
|
||||
return c_v256_shr_u8(a, n);
|
||||
}
|
||||
|
||||
SIMD_INLINE c_v256 c_v256_shr_n_u16(c_v256 a, const unsigned int n) {
|
||||
return c_v256_shr_u16(a, n);
|
||||
}
|
||||
|
||||
SIMD_INLINE c_v256 c_v256_shr_n_u32(c_v256 a, const unsigned int n) {
|
||||
return c_v256_shr_u32(a, n);
|
||||
}
|
||||
|
||||
SIMD_INLINE c_v256 c_v256_shr_n_s8(c_v256 a, const unsigned int n) {
|
||||
return c_v256_shr_s8(a, n);
|
||||
}
|
||||
|
||||
SIMD_INLINE c_v256 c_v256_shr_n_s16(c_v256 a, const unsigned int n) {
|
||||
return c_v256_shr_s16(a, n);
|
||||
}
|
||||
|
||||
SIMD_INLINE c_v256 c_v256_shr_n_s32(c_v256 a, const unsigned int n) {
|
||||
return c_v256_shr_s32(a, n);
|
||||
}
|
||||
|
||||
#endif /* _V256_INTRINSICS_C_H */
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user